Entity Construction

Last week, I wrote about an animation tool I had just begun developing. I’ve continued to iterate on this tool over the past week, extending its scope to encompass not only animation, but entity construction at large. Currently, it is capable of exporting animation and collision data, and I plan to continue adding specialized editor tools to handle component data as necessary throughout development.

In order to better understand my needs here, I wrote a tool to analyze every piece of entity markup from Super Win the Game and output a spreadsheet to help me identify problem areas. The best contenders for promotion to full-fledged editor features would be components that appeared very frequently or contained large amounts of markup text. I knew intuitively that animation and dialog components would meet both of these criteria, but I was curious which other elements I might have overlooked. Collision showed up very high in this profile, as did general scripting. Collision seemed closely related to animation, so it felt like an appropriate thing to tackle first. I will likely take on dialog and scripting around the same time, as those two are frequently intertwined as well. Another element I hadn’t considered prior to seeing these results was AI — in Super Win, AI was extremely simple to the point of being essentially non-existent, but what was there still showed up fairly high in the profile. My ambitions for AI in Gunmetal Arcadia are higher, so it’s likely I’ll want some custom tools for that, too.

The other half of tools work is getting the output hooked up and functioning correctly in the game. Once the editor features came online, I built a set of placeholder content to test these features and began implementing them on the game side. This included some fairly simple changes such as checking flags to indicate that an animation is intended to play not only by time but by velocity, as for a walk cycle or jump. A larger change came in the form of allowing multiple prioritized animations to run at once, where the highest priority one is seen on the screen. My hope is that this functionality will allow for more robust, expressive animations without the need for large sets of hardcoded cases and conditions.

As an example, consider the case where the player runs forward, jumps, attacks while in the air, then lands and stands still. In this case, I would loop a low priority idle animation throughout the entire process, but it would initially be trumped by a higher priority walk cycle. Upon jumping, the walk cycle would end and a jump animation would be played which would also trump the idle. The attack animation would take priority over the jump. (As an aside, the attack animation would also trigger code related to combat such as testing collision between the weapon and enemy entities. This will likely be one of my next tasks.) Finally, after the player lands and comes to a standstill, all other animations would cease and the idle loop would become the topmost item, making it visible at last.

Screenshot 2014-11-24 18.09.48

In fact, this example is exactly how my placeholder test content is working at the moment. This is exciting because it means I’m able to author animations for the player character in the editor and quickly see them in action. Historically, I’ve handled player animation separately from all other entities, because it has typically been a little more expressive, and my tools were not sufficient to meet my needs. In the Win the Game series, player animations were hardcoded (literally, in C++ code) based on a number of conditions. With the improvements I’ve been making to my tools, I’m much closer to being able to recreate that same behavior without having to write any specialized code, and that is a huge win.

Animation Tools

Now that I’m more or less moved out of my old place, I’ve commenced regular development on Gunmetal Arcadia, starting with some of the things I perceived as particular weaknesses on Super Win the Game.

In You Have to Win the Game, I had some fairly limited rules for authoring the hazards and powerups that appear in the world. These were written in XML markup, often using hardcoded tags that the code could interpret in a few known ways. These looked something like this:

<entity name="cash" type="treasure"
texfile="cash.bmp" texname="Texture_Cash"
width="8" height="8"
boxwidth="8" boxheight="8"
x="4" y="4" z="4"
/>

When I began working on Super Win, I wanted to move away from hardcoded rules and towards a more full-fledged method of authoring every component that describes an entity. This took the form of an entity composition tool in my editor. This tool still relied heavily on XML markup, but it gave me greater access to each component, which allowed me to create a richer set of game entities.

xan_animtool_valk

This was sufficient for shipping Super Win, but it came with its own set of difficulties. Animations in particular required some esoteric knowledge of how sprite sheets were intended to be laid out. For instance, the below example illustrates how the animation for the heart beacons that appear inside the Hollow King were written.

xan_animtool_heart

These beacons have two states (off and on), each accompanied by a looping animation, and there is also a transitional animation to go from the off state to the on state. The markup only specifies a single frame of animation for each of these sequences, but each <frame> tag contains a “dx” attribute that indicates an additional number of frames are to be added under the hood. This is convenient in that it required me to write less error-prone copy/paste markup, but it’s not exactly clear at a glance how it’s supposed to work.

Super Win also enforced a few restrictions on animated sprites that were especially annoying when I was animating the player character. The sprite’s quad were allowed to be a different size and shape than its collision box, but neither were allowed to change at runtime, and they were also required to be centered about the same point. In the below picture, the dark magenta around the sprite is the excess image data required to fill the entire quad, and the white box in the center is the collision box. Each frame of the player’s animation contains blank space beneath the feet because of this requirement.

xan_animtool_quads

Lastly, I had no support for mirroring sprites in Super Win, so characters who could face either left or right required twice as much sprite sheet data.

I’m attempting to address all of these problems in Gunmetal Arcadia with the introduction of an animation tool. This tool allows me to visually select the region for each frame, adjust its location relative to the origin and the collision box, and preview the sequence.

xan_animtool

Under the hood, this tool will produce the same sort of XML markup that Super Win utilized (plus some new elements to specify offsets and such), but ideally, I should never have to think about that side of things once I start producing game content.

I’m hoping to continue improving my tools in this way across the entire development process. Animation felt like a natural place to start insofar as it would push me to break some hardcoded assumptions I’ve been making for years, but it’s easy to imagine applying the same mentality to other systems, from dialog scripting (a nightmarishly error-prone system on Super Win) to random level prefabs for Gunmetal Arcadia.

Grab Bag

Just a quick update today, as I’m in the process of cleaning my old apartment, but I did find a little time this week to poke at some Gunmetal Arcadia tasks.

Building off the collision work I discussed a few weeks ago, I’ve made some improvements to how collision surfaces are generated from tiles. I now have the capability to insert “hint walls” at the edges of platforms. These are invisible surfaces which the player does not collide against, but which serve to notify enemies or NPCs that they’ve reached the end of a walkable space and should turn around. This is a huge improvement over Super Win the Game, which required me to place these invisible blockers by hand.

I’ve been prototyping some visual improvements for players who prefer to disable the CRT effects. There’s very little reason from a technical standpoint why the visible viewing area should be limited to a 4:3 aspect ratio in this mode. I’ve made a local change which extends the viewing space to fill the screen when CRT effects are disabled. It’s not shippable yet, but it’s feeling fairly promising. It does raise some interesting design questions, however. How should rooms that do not fill the complete horizontal space be displayed? Is it acceptable to leave blank space on the sides of the screen in these cases? What happens when you reach the edge of the room and transition to the next one? Does the adjacent room suddenly pop into existence? These are questions that I’ll have to answer before this can be a real shipping feature.

I made some changes to my Windows build process shortly after launching Super Win the Game to facilitate side-by-side Steam and non-Steam builds, and I’ve continued improving this process in order to automate it as much as I can. The dream would be to have a one-button process that can build and deploy all configurations on all platforms (six at this point: Steam and non-Steam builds on Windows, Mac, and Linux), but I’m not there yet, and I likely won’t put too much effort into solving that problem for Gunmetal Arcadia.

That’s all for this week. Next Monday’s entry may be another conceptual high-level design one depending on how much work I’m able to get done over the next few days. If you’re just seeing this blog for the first time, I’d encourage you to check it out from the start. I’ll have more specific development details to share once I begin working on this game in earnest, of course, but I’ll probably continue sharing abstract design thoughts throughout the duration of the project, as well. Those are fun to write, and, I suspect, often more interesting to read.

Rogue Souls

I’ve been in the process of moving to a new apartment over the last couple of weeks, and my development PCs have been unplugged for the last few days in particular, so I haven’t made any tangible progress on Gunmetal Arcadia this week. (That is to say, no checkins.) But I’ve been playing a lot of Spelunky and Isaac recently, among other 2D platformers and roguelikes, and I’ve been looking for things I can borrow and places where I can do something different and unique. I’m trying to figure out what it is, beyond the surface level bullet point features, that makes the idea of developing a roguelike seem so appealing to me right now.

See, I wasn’t always a fan of roguelikes. If we jump back in time ten years to my undergrad days, I was fairly averse to the genre. David had recently discovered NetHack, and despite my best efforts, I couldn’t bring myself to play it more than once or twice. Death was too punishing, too final. When I died, it felt like my time had been wasted. I remember saying that if I ever made a game like that, I’d find a way to make permadeath less frustrating.

Fast forward ten years and roguelikes are now the genre du jour among indie games. Not only that, but the genre has grown, tacking on a “-like” or two and reaching far beyond the top-down ASCII dungeon crawls from which it originated. In the same way that “X but with RPG elements” has become shorthand for “the player can earn experience points and level up,” “X but with roguelike elements” now indicates the presence of features such as permadeath and randomly generated levels.

With the explosion of roguelikes, it’s not surprising that others have attempted to temper the frustration of permadeath, often with the addition of unlockables which can improve your odds of survival. I’ll be honest, ten years ago, I probably would have thought this was a great idea, but having seen it in practice across a number of games, I’m not a fan of this solution. In some cases, I feel like it ruins the feasibility of “vanilla” runs (or cheapens their purity, perhaps), and it can force the player to grind in order to be realistically capable of finishing the game. This solution serves to mitigate beginners’ frustrations, sure, but it does so at the expense of long-time players. There has to be a better way.

Dark Souls isn’t a roguelike, but it handles death in a similarly unforgiving manner. When you die, you lose all the unspent souls you’ve collected, souls being the game’s primary currency, used both for buying goods and for leveling up. Dark Souls offers a silver lining, however: if you can reach the place where you died without dying again, you can recover these souls, effectively eliminating any punishment. This is often not as easy as it sounds, as enemies respawn each time, while items are not replenished and weapons continue to degrade. This “one shot at redemption” model works so well because it is both a carrot and a stick. The game first deprives the player of something they’ve earned, then it offers them a chance to reclaim that loss, with the caveat that one false move may cost them not only their earnings from the last round, but potentially the ones from this round too. This creates a wondefully tense dynamic. “Maybe I made a mistake, but I can still salvage this.” I love that.

So that’s how I’m approaching permadeath in Gunmetal Arcadia. Not wholly irreversible, still recoverable in some way, but not so forgiving as to be exploitable or without tension. What exactly that means is still up for grabs. Procedural level generation means that stealing Dark Souls‘s mechanic verbatim is out of the question, as retreading the same ground to find the place where you died will be impossible. (Not that I’d want to do that, right? I’m a professional game developer fully capable of inventing his own designs! Yeah!) But I’d like to find a solution that creates the same sort of dynamic, where losses incurred by a previous failure effectively raise the stakes on the next run.

In fact, I think the notion of each run being informed by its predecessor is likely going to be a consistent high-level theme throughout much of Gunmetal Arcadia. I like the idea that choices you make during one session could influence the next in subtle ways. Maybe you eschewed technology in favor of magic, so on the next go-round, warlocks are friendlier and apothecaries offer discounts on spells. Balancing this in a way that preserves the viability of vanilla runs will be important, of course. I would liken this concept more to Demon’s Souls‘s world tendency system than a grindable series of unlockable upgrades in that regard.

Historically, I’ve always a little wary of making design thoughts public too early, not because I’m afraid they’ll be stolen (ideas are cheap), but because I don’t like to run the risk of overpromising and underdelivering. (An early design for Super Win included coffee cup powerups that would make you temporarily run faster and jump higher. It didn’t fit that game’s Metroidvania nature, so I cut it.) It should go without saying, but everything on this blog should be taken with a grain of salt, especially at this early of a stage.

Collision Refactoring

Fair warning: This is a very programmer-y post. It’s a post about refactoring, the kind that ends with a triumphant, “And everything worked exactly as it did before!” which is perhaps not the most interesting thing to read.

In You Have to Win the Game and Super Win the Game, world geometry is completely static. Anything that can move or change its state is implemented as a separate entity, including enemies, which mostly bounce between walls, and platforms that may move, crumble when stepped on, or pop into existence when bopped from beneath. Everything else is locked in place and may never change. Some tiles may have different effects, for instance spikes can inflict damage and water can change movement physics, but these tiles can never become anything other than what they are.

This limitation is due in part to how world collision is generated. Each time the player enters a room, a static set of collision surfaces is generated for the entire room, as shown below. In order to improve performance, adjacent surfaces are merged, reducing the number of collision elements over which we must iterate each frame. This process is too expensive to repeat frequently, so we do this once at entry time only.

volver_collision_1

In Gunmetal Arcadia, I’ve made a change that will facilitate dynamic environments should I want them (e.g., for destructible walls, etc.). I now generate a small set of collision surfaces as they are needed. As the player moves through the world, we search for collision surfaces only within a box containing the entire path of the traversal. Because this is done on a per-frame basis, we are dealing with very small movements, so these search areas tend to be very small as well. In this case, there is no need to merge adjacent surfaces because the set is already so small, as shown in the example below.

xan_collision_1

xan_collision_2

(Note that I’m representing this with Super Win assets only because I have not yet begun designing sprites for Gunmetal Arcadia. To be clear, this change does not exist in Super Win; that game is bound by static geometry just as You Have to Win was.)

Because collision is generated on the fly every single frame, I now have the option to change the structure of the world at runtime, and the collision should react accordingly.

I have yet to do a proper performance test of the old and new methods, but by a naive FPS test, there is no difference. What this tells me is that collision is probably not my bottleneck in either case. In the event that generating collision surfaces for multiple moving actors every frame becomes prohibitively expensive, I could optimize the process by caching surfaces and invalidating these caches if the world structure changed.

I should mention too that I haven’t actually tried changing the structure of the world at runtime yet. There will be other problems to solve before this can be a real feature, such as updating the renderable mesh, which has also historically been static except for animated elements. This is one step of several on the road to facilitating destructible or otherwise dynamic environments. But for right now, it’s just in a place where old code was replaced with new code, and everything worked exactly as it did before!

Physics and Game Feel

Game feel is, I believe, the single most important aspect of any game, and yet it is often overlooked in favor of visuals, audio, storytelling, and any other number of easily communicated features. As today’s blog is the first to document actual development progress, hopefully that will give you some idea of the importance I place on game feel.

As I mentioned in my first entry, Gunmetal Arcadia is going to be built off the technology that I developed for Super Win the Game. That code gives me a good foundation for doing many of the sorts of things I would need to do in any 2D platformer, and it would be wasteful to write those systems again. Much of it was originally written for You Have to Win the Game, with a few subtle changes made to retain the same game feel for Super Win in the context of a different screen resolution and aspect ratio. But it’s important that Gunmetal Arcadia not be identical to those games in terms of game feel, and with that in mind, I’ve been making some adjustments to movement and jumping physics recently.

The biggest change I’ve made is to the jump height. In Super Win, you can clear three blocks in a single jump (where one block is 16×16 pixels). In Gunmetal Arcadia, I’ve lowered the jump height to just under two blocks, but you also get a small height increase while walking which allows you to clear two blocks. Increasing jump height with lateral speed is a fairly common trope among old school platformers, but it was one that I avoided in the Win the Game series because I felt it was antithetical to the precise platforming those games require.

In reducing the jump height, I also found it necessary to reduce the jump duration by nearly 30% to avoid floatiness. (I’ve blogged in the past about how the constants that govern jump physics can be derived from a number of sources; I prefer to establish height and duration and derive velocity and gravity from these.)

I’ve finally made peace with non-parabolic jumps and implemented higher gravity while falling. This is an old trick dating back at least as far as Super Mario Bros., and it serves a few purposes. It makes the character feel heavier, and it gets you back on the ground faster after you’ve peaked, which is usually what you want. It also has the side effect of reducing the horizontal distance you can jump, which isn’t necessarily good or bad as long as the levels are tuned properly.

In Super Win, there is no momentum except when walking on ice, which is to say, the character’s movement speed normally corresponds 1:1 to the player’s input. Press left and you immediately move left at full speed. Press right and you immediately change directions, regardless of whether you’re on the ground or in the air. In Gunmetal, I’ve added a little bit of momentum to grounded movement and a significant amount while in the air. This reduces the fidelity of movement relative to input, but it gives the character a more tangible, weighty feel.

Lastly, I’ve lowered the maximum walking speed by about 10%. It’s not a significantly noticeable change, but it complements the other changes I’ve made. And though I haven’t yet drawn the player character, it’s highly likely he or she will have a larger sprite and collision box than Super Win‘s Wayfarer, which will affect the character’s perceived speed and weight.

The goal of these changes is to give the player character a better sense of physicality, which is something that I hope to maintain throughout the development of Gunmetal Arcadia. This game is not about precise platforming as Super Win was; it’s about combat and adventuring, and it’s important that the moment-to-moment game feel support that premise. I’m not done tuning it yet; likely I won’t be for a very long time, but I’m confident in the direction I’m headed.

Source Control

I don’t have any real development news this week, as I’ve mostly spent the last few days patching Super Win the Game and preparing non-Steam builds on all platforms in order to sell the game via Humble Widget. As a follow-up to last week’s notes on setting up a source control repository, I thought it might be interesting to talk a little bit about how I structure my projects.

Since 2007, I’ve been developing a game engine that I’ve used for nearly every game I’ve released or prototyped in that time. It was clear from a very early point in development that it would be useful to decouple common, game-agnostic code from any one particular game’s source, but the exact nature of this relationship took a few different forms before I was happy with it. The earliest implementation involved creating projects for various subsystems such as audio and rendering, and building a game on top of these. This was a good first step, but many of the features that I put on the “game” side of the game-engine line turned out to be features that I wanted to reuse; these included windowing, fonts, UI, and so on.

The next step was to create a “base game” project which could sit between the lower-level subsystems and the actual (“derived”) game. This layer would handle the implementation of common features while also deferring to the derived game when specific content were required. A simple example is the construction of the game window: a subsystem project provides the code to create a window; the base game uses this functionality to create and manage the primary game window, and the derived game provides the text for the title of the game that appears on the window’s frame.

I’ve been using this pattern since late 2008, after finishing my first indie game Arc Aether Anomalies. In order to keep the common subsystems and base game current for all derived games, I set them up in their own repository which is then included as an external in the derived game’s own source control path.

The most recent change, and one that I’ve waited an embarrassingly long time to make, was to branch the engine for shipping a game. After I finished You Have to Win the Game and began working on my next game (the untitled and unreleased “Project Vanguard”), I ran into a few problems when I wanted to make some updates to YHtWtG and had to deal with reconciling recent engine changes that had broken that game. My solution for dealing with this problem on Super Win the Game was to create a new branch of the common engine code for shipping Super Win. Changes made to this branch as part of post-launch support work can easily be merged back into the trunk, and should I ever need to bring over future engine work for an update to Super Win, I can integrate those changes on a case-by-case basis.

If I were to start from scratch and do it all over again, I think the one change I would make is to keep everything in one repository, with separate folders for each game and for the common engine code. This is analogous to my current implementation, but there’s really no benefit to keeping each of these in its own repository. That decision was mostly born of my unfamiliarity with SVN years and years ago, and while it hasn’t hurt me, it doesn’t offer any advantages either.

I’m not yet sure what the next week will look like for actual game development, as Real Life Things are encroaching on my schedule currently, but I’ll try to find something good to talk about by then.

First steps

Tonight I’m taking the first steps towards prototyping Gunmetal Arcadia by setting up a new Subversion repository for the game and its editor. These are copied from the current version of Super Win and its editor, as I will be using that game as my starting point, in the same way that You Have to Win the Game served as the starting point for Super Win.

I give all my projects code names. This is something I picked up from my time at Gearbox Software. The thinking goes, if you choose a title in advance (as I’ve done with “Gunmetal Arcadia”), and you start using that name throughout your code, you run the risk of changing that title prior to shipping. If that happens, you’ll either have to rename all your classes and files or end up with a mish-mash of different names. Choosing an unrelated codename that can persist throughout development avoids these problems.

I don’t have a standard convention for my codenames. Typically they’re just words that I think sound cool. Sometimes they’re related to my perception of how a game should feel. Arc Aether Anomalies was “Sublime.” You Have to Win the Game was “Volver.” Super Win the Game was “Valkyrie.” Gunmetal Arcadia is “Xanadu.”

What is Gunmetal Arcadia?

Hello world! I’m J. Kyle Pittman, indie game developer and co-founder of Minor Key Games. As I write this, I’m days away from releasing my latest and greatest work, Super Win the Game. In fact, with the exception of minor tweaks and bug fixes, development on Super Win concluded several weeks ago. Since then, I’ve been toying with ideas for my next project. Gunmetal Arcadia is the result.

Gunmetal Arcadia is a roguelike, or maybe a roguelikelike. Some number of likes, or maybe a lite. Let’s get that out of the way up front. It’s also going to reuse the CRT simulation technology from Super Win, or some variation of that tech. This game is designed to answer questions like, “What would Super Win look like if it were a roguelike?” “What would Super Win look like with combat?” “Can I make a roguelike that is challenging and demanding without being frustrating and discouraging?”

Gunmetal Arcadia is an action platformer featuring permadeath and upgrade choices in a procedurally generated world of entwined technology and magic, portrayed through the lens of 8-bit games. Touchstones include The Battle of Olympus, Faxanadu, Rogue Legacy, The Binding of Isaac, and others.

As my brother and fellow Minor Key Games co-founder David is doing with his upcoming stealth title Neon Struct, I’ll be documenting the process of developing Gunmetal Arcadia in a series of weekly blogs. As of the time of writing, nothing exists of this game beyond words on paper and images in my head. Let’s see where it goes.

—J. Kyle Pittman
September 2014