Sleep and What We Are

I hope everyone is having a good Memorial Day weekend! As there’s no rest for the wicked (and money doesn’t grow on trees), I’ve been working a bit, trying to wrap up the new Super Win content, fix whatever bugs may still be lingering, and hopefully make some improvements to perf and stability while I’m in there.

In case you missed it, our latest game NEON STRUCT came out last Wednesday. Since it’s David’s game, I’ll let him talk more about its reception when it’s time, but I will say it’s interesting to watch how it’s been trending relative to both Eldritch and Super Win, especially in light of the amount of mainstream coverage each game has received. It certainly calls into question some of the ideas I’ve had about how to approach Gunmetal‘s launch when that time comes.

I’m 99% done with the speedrun courses for Super Win. On Saturday night, I took about three hours and did a complete playthrough of the game looking for bugs in the minimap system or speedrun courses. There’s still a lot of stuff left to fix, and a few unsolved problems with regards to how to treat certain secret areas on the map. I’ve been aiming for the end of May or start of June for a launch date (June 1 in particular has been my ideal target), and I believe I’m still on track to hit that date, but in light of some other obligations and circumstances (which for one reason or another I can’t elaborate on here), I’ve been leaning towards either delaying this update or decoupling it from the price drop. I still have a little while to figure this out, so we’ll see which way it goes.

This week has been strange in that I’ve spent a lot of time working on various programming tasks which I’ve ended up reverting. I’ve had an idea for while to try to add support for a callback system that would use (non-static) member function pointers and a target object to circumvent a common pattern that I find myself running into in which I have to make a callback to a static function, passing in the target object as a parameter and then running a function on it. Although this feels like a simple process on the surface, C++’s handling of member function pointers makes it somewhat difficult. The crux of it is that member function pointers are typed differently depending on the class they belong to, which means that, barring any sort of trickery, the thing that makes the callback needs to know the class of the thing that receives the callback, and that defeats the purposes of the system, which is to be flexible and generic; the caller shouldn’t need to know anything about the callee. I prototyped an initial implementation of this a few weeks ago before going on vacation to Nebraska, rejected that version, and recently came back to the problem, believing I’d found a solution. After a few days of off-and-on work, though, I’m not really sure there’s a way to do exactly what I’m trying here, and in the absence of a really strong need for such a feature, it’s probably not worth pursuing further.

I had another similar experience this weekend. I ran into a case where it felt like it would be nice to be able to chain together any number of fullscreen postprocess effects, each a separate draw call, without having to set up the corresponding data in my render pipeline, which has historically been cumbersome to deal with when draw calls must happen in a specific order, as these would. The trouble in this case is that my renderer has been very specifically built to perform optimally in one way, and circumventing that behavior to make it act differently without breaking or losing the perf gains of the normal path turns out to be a rabbit hole of special case behavior. Eventually, I spending a few hours poking around in this code, I had to ask myself whether the motivation was strong enough, and in this case, it wasn’t. So I reverted that work.

I’ve had to discard or roll back work before, but it is unusual that I’ve had cases like these in such rapid succession. I think I’m itching to get back to work on core features after spending a couple weeks doing primarily content creation work on Super Win. That work just isn’t as satisfying, and it’s also weirdly emotionally draining. Even after just a week or two or level building and writing for Super Win, I’m already starting to feel the funk that loomed over the last few months of development on the original release. I’m hoping the procedural content generation scheme and loftier game systems design I have planned for Gunmetal will help stave off that mood, since it means I should be spending more time in code and less time building content that might only be seen once.

A Tendency to Dream

Last week’s mystery Polaroids are courtesy of a week David and I spent on the road visiting Lincoln and Omaha, Nebraska. It’s been ten years since we graduated from UNL, and it felt like a good time to see how the cities have changed, visit some old haunts, and mostly be glad that I don’t have to worry about classes and grades anymore.

I’m continuing to make progress on Super Win speedrun courses. Three of the five courses have been fully grayboxed and need to be tweaked and arted up. One is in the process of being grayboxed, and the last one I haven’t started building at all yet.

oldarcadia

The first course is Old Arcadia. This course requires some long jumps and wall climbing that are only possible with the new coffee cup powerup, which grants a temporary speed boost.

bonehoard

The next course is the Bonehoard. If you’ve finished the campaign, you’ll recognize this tileset from one of the last areas of the game. There are a couple of branching paths throughout this course; the trick will be figuring out which one is the fastest.

dreamcycle

The Dreamscape Nightmare course winds back and forth around a central tower. You’ll have to climb to the pinnacle to find the gear you need to plummet back down to the bottom and reach your goal.

schadenfreude

The Caverns of Legacy will be familiar to fans of the original You Have to Win the Game. This course contains reworked versions of some iconic rooms from that game. This has been an interesting challenge on account of the difference in scale between the two games. I rely almost entirely on 16×16 tiles in Super Win, and coupled with the narrower dimensions (256 pixels across vs 320 in You Have to Win), I’m having to simplify the geometry of these rooms and try to evoke the originals rather than rebuild them 1:1.

Finally, there’s the King’s Gallery, which isn’t pictured here because I have yet to start building it. My idea is to play around with the concept of traversing the outside of a space that was previously encountered, a sort of deliberate breaking out of the world. It’s an idea I’ve had at the back of my mind since the first YHtWtG, but I’ve never really explored it. Hopefully it’ll turn out how I’m imagining.

swtg_flyer_1 swtg_flyer_2

Hey, remember these flyers I did for Super Win that were designed to look like an original NES “black box” release? I’m working on something similar for Gunmetal Arcadia, this time in the vein of ’90s video game ads — white backdrop, serif font, etc. This is obviously still a pretty early mockup, but it’s a good example of the sort of thing I’m going for.

new_flyer_lo_con_for_blog

Reusing the same MIDI-to-proprietary-synth tech in Gunmetal Arcadia as I did in Super Win the Game has put me in a good place to be able to write music off and on for the entire duration of the project rather than having to worry about composing a whole soundtrack all at once close to launch. I’ve already written easily 50% more music for this game than I did for Super Win, and I plan to keep on writing as long as the melodies keep coming to me. Here are a couple of the more recent tunes I’ve written.

I guess this next bit might not be super interesting to non-devs, but since I like to talk about some of the aspects of development that sometimes go unnoticed, here’s a fun thing that happened. While I was out of town, a thunderstorm took out my modem/router. For some reason, this was the one device that wasn’t behind a surge protector, so I guess that’s what I get. To their credit, my ISP replaced it immediately, no questions asked, although I also had to put a new ethernet card in my PC because apparently the surge also blew out the ethernet port on my motherboard.

Anyway, the point is, along with a new modem and router came a new IP address. That’s nothing new; when I was living at my previous apartment and using a different ISP, my IP address would change at least once a year for no reason at all. It’s always been a minor irritant, though, because it means I need to update the URLs on all my local SVN working copies. (As I’ve discussed before, I keep each project in a separate repository, so I’ve ended up with quite a few working copies checked out.) Historically, I’ve always just dealt with this by relocating each working copy whenever I touch it next, but this time, I finally decided to simplify the process. I wrote a script to output the URL of each working copy in a given directory, and if its address differs from a provided target IP, it will automatically be relocated to the new one.

Grab Bag 27

This week marks another special guest appearance from Super Win the Game. I know, I know, I want to go back to writing about Gunmetal Arcadia, but I’m full time on Super Win for now, so that’s what I’m covering. But hey, at least there’s a shiny new header image! I got the random urge to paint a scene from Gunmetal over the weekend, and that’s what I came up with.

valk_leaderboards

Last week, I mentioned that I had prototyped attachment of player ghost data to leaderboard entries. This week, I wrapped up that work and implemented a leaderboard UI. Your fastest time will be recorded for each speedrun course. When playing offline or in non-Steam builds, you can view your own personal best times and race against your own ghost. When connected to Steam, you can view all players’ time and race against any other player’s ghost. All the usual  Steam leaderboard modes (global rankings, personal ranking, and friends’ rankings) are supported.

valk_speedrun_courses

I’m making slow but steady progress on the courses. Level design was one of the most tedious parts of making Super Win the first time around, and I’m definitely starting to feel that slog again, but I’m excited about the new challenges I’ve built. I sort of expected to feel like I had already done everything I could do with the content available, but I’m finding some interesting new ways to piece things together.

I’m continuing to support the anaglyph 3D mode going forward, so I fixed up the minimap to play nice with this feature. Depending on whether I foresee doing any more major updates for Super Win in the future, it may be worth refactoring this feature to clean up a lot of copy/paste code that exists across the codebase.

valk_anaglyph_map

Last month, I updated Super Win to include a language option in the menu. The game only supports English by default, but additional languages can be added by players, and a Russian translation is currently available in the link above. I realized shortly after publishing this update that some strings which had already been retrieved in one language were not updating immediately after changing the language. In most cases, continuing to play as normal would fix the problem, and at worst, exiting and restarting the game would always fix it, but I wanted a real solution and not a workaround. To that end, I’ve written a language-sensitive interface that classes may implement if they need to respond to the game language being changed. So far, I’m only using this in one place, for updating key prompts that had already been cached, but in the event that more of these bugs pop up, I’ll have a better way of handling them in the future.

As I’ve been writing music for Gunmetal Arcadia, I’ve rejected a few pieces for sounding too much like they belong in Super Win. I want Gunmetal to have its own unique sound, and even though I’m reusing the same synthesizer tools I wrote last year, I’m trying to lean more on minor key melodies and weird, chaotic compositions. Not everything I’ve written has fit that bill, and a few tunes have been cut. But as I was thinking about new content I could add to this Super Win update, a couple of these felt like they’d be a perfect fit.

This short loop plays inside the Hall of Speedruns, located in the Town of Lakewood. This is where you can access the speedrun courses and view the leaderboards.

This is probably going to be the background music for the “Old Arcadia” course, or possibly one other that I haven’t started building yet. Or both. We’ll see. It’ll go somewhere.

valk_volver_3

This Wednesday marks the third birthday of the original You Have to Win the Game and one year since it landed on Steam. I poked around in the source code a day or two ago to remind myself what state it was in. Last June, as part of the neverending struggle to support a wider set of Linux installs, I attempted to merge in some then-recent engine changes and build a 32-bit executable. It failed, I rolled back the version on Steam, and ever since then, the code in my repository has been out of sync with any published version and not really in a good place to rebuild the game if I had to. So I finally took the opportunity to roll back some of the more problematic changes and at least get back to a state where I can build the game as it appears on Steam today. I don’t know whether that will go anywhere. A few months ago, I considered adding a Super Win upsell screen when starting or exiting the game, in essence to frame it as sort of a demo for Super Win, and I suppose this puts me in a better place to do that, but I’m still on the fence there. On the one hand, it’s kind of tacky. On the other hand, YHtWtG is about two orders of magnitude more successful than Super Win but doesn’t generate any revenue, so it feels like a wasted opportunity.

I’ll be out of town next week as David and I are taking a trip to Nebraska to gather ideas for a future title and visit our college on the ten-year anniversary of our graduation, but I’ll be sure to have something ready by next Monday, even if it’s just Polaroids from the road.