Category Archives: Devlogs

Grab Bag 2

This has been a productive week, but also a scattered one. It’s difficult to pinpoint any one thing to blog about, as I spent most of the time jumping from one engine or platform task to another. So I guess I’ll just do another “Grab Bag” entry and write a series of mini-blogs about each of these.

As I was revisiting Super Win the Game for an upcoming update, I took the opportunity to make some much-needed improvements to my Mac and Linux build processes. I use Visual Studio on Windows, Code::Blocks with gcc on Linux, and Xcode with Clang on Mac, and each of these has its own quirks. For instance, Code::Blocks requires that libraries be linked in a specific order, while VS and Xcode can sort these out for themselves. (This is presumably a gcc issue and not a Code::Blocks issue specifically, but as I’m using the two together exclusively, it has only presented itself in this particular environment.) C::B also does not automatically re-link the executable when dependent libraries have changed; these libraries must be explicitly specified as external dependencies. Meanwhile, Xcode defaults to producing intermediate content in a jargon-named external path that is difficult to utilize and searching for libraries in paths that are not relative to the current configuration. For the last year, I’ve been working around these quirks in awkward, cumbersome, and often time-consuming ways, and I finally took the time to understand and address these issues. As a result, making iterative builds on Mac and Linux should be a much less painful process on Gunmetal Arcadia than it was for the Win the Game titles.

autocomplete

I made a small but worthwhile improvement to the autocomplete feature of my game console. It will now display any console command that contains the specified text, as opposed to only commands that start with that text. For instance, in the above example, only the first command would have been found previously. Now it finds four other potential matches. I’ve been relying on the console more and more over the course of the last few games for in-game debugging, and as the set of commands grows, this change will be useful for helping me find what I’m looking for without resorting to searching through code.

button_glyphs

I’ve supported Xbox 360 button glyphs in my engine since early 2011, and I added generic numbered glyphs for DirectInput devices for Super Win, but with the recent prevalence of the DualShock 4 as a PC gaming controller, I figured it was high time to add those glyphs as well. Initially, this was only going to be a user setting to allow the player to optionally override the default glyphs at their own discretion, but as I started reading more about USB vendor and product IDs, I realized it would be easy to identify a DualShock controller and default to these glyphs. I also took this opportunity to provide nicer strings for commonly used controllers. By default, the DualShock 4 identifies itself as “Wireless Controller” on a PC. My engine will now recognize the GUID and change this to “Sony DualShock 4” as seen above. I’m a little wary of whether these changes will behave consistently on Mac and Linux due to the way SDL handles device GUIDs, but I can cross that bridge when and if I come to it.

Finally, I did some server backend work to support two separate features that I hope to utilize in Gunmetal Arcadia. The first is a daily challenge mode a la Spelunky. This allows the game to retrieve a random number once per day which may be used to seed a session. This number will be the same for all users on any given day, so players can attempt the same session as their friends.

dailies

The second backend feature is one that I began working on last summer, brought to a more or less finished state, and have been sitting on ever since. It’s sort of an asynchronous multiplayer component that will harness social media to enrich the game experience. The pitch goes, as you play Gunmetal Arcadia, you may trigger events which are tagged in some way as social events. This could be anything from unlocking a new level to opening a rare treasure chest to being killed by the final boss. When this happens, you’ll have the opportunity to post a URL to social media. When your friends visit this URL, they’ll receive a code that they can enter in the game to receive a reward or an optional challenge or whatever else may be appropriate.

As an example of how this could have worked in a previous game, recall the Twitter button from Eldritch. This would launch a web browser and author a tweet telling how the player died. Now imagine that same thing, but it goes on to say, “When I died, I dropped 50 gold pieces. Use code ‘ABC-123-FOO’ to retrieve them!” Now someone else could launch their copy of the game, enter the code ‘ABC-123-FOO,’ and start a session with 50 extra gold pieces.

I’ve left some of the specifics of this system deliberately vague because I want to leave it open to whatever possibilities I may dream up. These will always follow the paradigm of one player’s in-game event creating a code that another player can use to affect their game, but beyond that, it could be just about anything, depending on how ambitious I want to get and how well early playtesters respond to the concept.

Theft

I’ve been playing a bunch of roguelikes recently — as one does when one is making a roguelike — looking for interesting elements to deconstruct and possibly adapt for Gunmetal Arcadia. Today I’ll be talking about shops and shoplifting.

Item shops are a staple of RPG and adventure games, and roguelikes are no exception. The opportunity to exchange currency for new abilities, upgrades, or other resources can offer the player a number of interesting choices. An item shop should present the player with a multitude of potential upgrade paths. In a typical situation, assuming a well-balanced economy, the player should not feel that they can afford everything for sale, as that would not be an interesting choice. There are exceptions, of course; the player may not have collected any money prior to visiting a shop early in the game, or they may choose to amass a fortune before spending anything. But in the general case, we want to feel like we can choose at most one, maybe two of the items available. In essence, we are making a bet based on the information available that these items will improve our chances over the course of the run.

In being presented multiple options, we have a choice to make, but a more subtle benefit is that we have tangible evidence that the remainder of the session could take a different form depending on this choice. This gets to the core of what makes roguelikes appealing to me, and it is vastly preferable to leaving the shape of the session entirely in the hands of the random number generator or hidden knowledge, although those can have their places too.

Seeing items you can’t afford may be frustrating for beginners who want to experiment with every possible option right off the bat, but there are benefits to this experience as well. It offers a glimpse of future opportunities, the proverbial carrot to permadeath’s stick. It also imparts value to the in-game currency. Shiny money pickups may be fun and moderately compelling to collect on their own merits, but if we find that we always have enough cash to buy everything in stock, then these pickups are rendered useless.

That’s my rough baseline for what I would expect an item shop to be, and practically every example I can find meets these goals. Things get more interesting when we look at the interactions involved in the shopping experience and the alternate paths these afford the player. I’ll be looking at a few cases from recent games, not all of them roguelikes, as I home in on the appropriate interface for Gunmetal Arcadia.

theft_spelunky

In Spelunky, shop inventory is present in the world. It can be picked up and carried just like any object in the game. Doing so will prompt the shopkeeper to approach the player, and if the item is carried out of the store, the shopkeeper will become aggressive.

These shops are intuitive and well integrated with the rest of the game. They reuse familiar controls and don’t interrupt gameplay with a modal menu. Using the RB button to purchase items is a little strange insofar as it is also the button used to enter doors, but as these actions can never occur simultaneously, there is little chance of confusion.

This implementation is thoughtful in that it makes accidental theft difficult. The button prompt encourages a purchase, and shoplifting is not clearly made an option. In order to steal an item, the player must choose to deliberately pick it up and carry it outside the shop, ignoring the shopkeeper’s attracted attention.

The player may also choose to kill the shopkeeper, in which case the items will no longer be purchasable but may simply be collected as if they had been encountered outside a shop. Any aggressive action towards the shopkeeper will instantly make him hostile, however, and as all shopkeepers are armed with shotguns, they are dangerous foes. Whether by design or coincidence, it is also easy to accidentally anger shopkeepers, e.g., by detonating bombs near a shop or by allowing a shopkeeper to be injured by another enemy’s attacks.

theft_eldritch

Shops in Eldritch were largely modeled after those in Spelunky. A lone shopkeeper oversees his inventory, which may be bought or stolen. These items do not behave exactly the same as others in the world, however. Ordinarily, items may be collected with a single button press. Within shops, interacting with items will instead launch a modal menu prompting the player to buy or steal the item.

It’s interesting to note that the game pauses while this menu is open, but the interruption is minimal. All shops in Eldritch are placed behind closed doors, so they tend to feel like safe spaces, isolated from the hostile outside environment.

theft_skyrim_2

Although not roguelikes, I want to bring up the Elder Scrolls games because they have an interesting and unusual implementation of shops and shoplifting. Stores are manned by shopkeepers who serve as the interface for making purchases. This is done through a modal menu which does not have an option for theft. What is particularly interesting is that some, but not all, of a store’s inventory is also reflected in the environment. These items can be stolen, and the normal “Take” prompt becomes “Steal,” written in red letters to indicate that it will draw the ire of onlookers.

theft_skyrim_alt

These in-world items are linked to the entries in the shopkeeper’s menu; purchasing an item from the menu will remove its representation from the world if it has one. However, some items in the world do not correspond to menu entries. These may be stolen, but they cannot be legitimately purchased. These tend to be decorative items like cups and plates that serve no functional purpose but still have some small monetary value.

theft_isaac

The Binding of Isaac does not have a shoplifting feature, but it is worth mentioning here because its shops have some other merits that could be relevant to Gunmetal Arcadia. Shops in Isaac are safe spaces. They do not contain enemies, and although a statue is present as a sort of symbolic shopkeeper, it serves little functional purpose. As with all items in Isaac, shop items may be picked up by walking over them. If the player can’t afford the iteam, it simply remains on the ground.

Every shop is found behind a locked door, and the majority of locked doors lead to shops. However, some locked doors lead to a mini-boss fight instead. Therefore, making the decision to spend a key unlocking a door serves as a risk-reward gamble. Pricing also comes into play here. As keys may be rare in the early game and throughout, the decision to unlock a shop is often made based on how much money the player is carrying. Shops will always contain a major item priced at 15 cents, but there is a chance it will be marked down by 50%, so it is sometimes worth entering a shop even without the requisite 15 cents.

New to the Rebirth remake of The Binding of Isaac is a donation box that appears within shops. Money donated to this box persists across sessions (a notable exception to the rule in this game) and can unlock additional features once it has collected enough coins. It can also dispense coins if a bomb is detonated next to it. The offers a little more flexibility in play without completely upending the sense that every run is viable.

theft_superwin

Finally, shopping in my own Super Win the Game occurs entirely within menus, with no ability to steal. I bring this up not because it is particularly interesting or relevant to the discussion of shops and shoplifting, but because, as the technological predecessor to Gunmetal Arcadia, it represents the path of least resistance in what I could choose to implement for that game.

There are things I love about all of these implementations, and it’s easy to imagine that bits and pieces of any of them could find their way into Gunmetal. At the moment, I’m imagining shops to be single-screen rooms branching off from the critical path. I like the idea that every door in the background is a gamble. Maybe it leads to a tech shop with an assortment of shiny implants to make you run faster and jump higher. Or maybe it leads to a pit of dire wyrmvipers that want to eat your face.

For as much as I’ve talked about it here, I don’t yet know for sure whether Gunmetal Arcadia will actually support shoplifting at all. One of my goals with this game is to follow the mantra of “say yes to the player,” and in that regard, it feels like an obvious win. But I suspect whether it makes the cut and what form it takes will depend in large part on how the economy is balanced (i.e., does shoplifting feel worth the risk?), what sort of persistent narrative elements exist (how will the bad karma affect future runs?), and so on.

I should be back to normal development this week, so next week’s blog will probably be a big long technical rant about entity refactoring or somesuch. We’ll see.

Palettes

This week was an exciting one, as a number of systems in progress coalesced and I saw the promise of what Gunmetal Arcadia will become begin to appear.

As I showed in last week’s video, I’ve been getting animations for melee attacks wired up using sprites from Zelda II as placeholder content. I continued working on melee combat this week, adding collision checks and knockback in response to hits. This prompted me to migrate a system of inertia and friction which had previously been roughed out specifically for the player character in Super Win the Game up into the base game engine so that any entity can take advantage of it. In Super Win, the player normally has no inertia; movement is instantaneous and corresponds 1:1 with player input with no ramp-up or ramp-down time. The one exception is for walking on ice, in which case there is a great deal of inertia to make surfaces feel slippery. For Gunmetal Arcadia, I want a slight amount of inertia on normal surfaces, not only for the player character but also for enemies and NPCs. Surfaces can now define a friction scalar relative to a default value, and any entity with a physics component will react to this friction and set its inertia accordingly.

The next big feature I worked on last week is one that’s been cooking in my head for a while, and that is palette swapping. This is a feature I wanted for Super Win, and I did some rudimentary prototyping of it for the NPCs in that game, but I’ve now made it a real first-class feature with editor integration and everything.

The process begins with source art authored as I intend it to appear in the game. In this example, I’m using the Wayfarer sprites from Super Win.

capman_source

This content is drawn using the standard 56-color NES palette with an additional palette entry for transparency.

palette_default

When I load a bitmap into the editor, it is analyzed for validity; it should contain no more than four colors, and one of these should usually be the transparent color. The opaque colors are then sorted by brightness and reassigned indices 0, 16, and 32, which are the top three entries in the leftmost column.

palette_grayscale

The editor then resaves the bitmap with these indices. It will remain in this state all the way until it is loaded into the game.

capman_grayscale

When the bitmap is converted to grayscale, the original color palette is also saved to editor data, where it may be previewed and updated.

Screenshot 2014-12-08 14.10.44

Screenshot 2014-12-08 14.13.46

These changes are also reflected in the entity construction tool.

Screenshot 2014-12-08 14.11.58

editor

When packaging content into a format the game can use, the editor saves the bitmap with the grayscale indices alongside the colors for the palettes specified in editor data.

When the bitmap is loaded into the game at runtime, the palette is altered to swap the grayscale entries (indices 0, 16, and 32) to be pure red, green, and blue colors.

palette_runtime

This allows the sprite shader to isolate each color of the sprite by looking only at the red, green, or blue channel. These components can then be multiplied by the palette colors provided by the editor, and the end result is the recolored sprite as we expect to see it.

capman_shader

output

A couple of notes on this: the grayscale version isn’t actually necessary. I could just as easily alter the palette to include the red, green, and blue entries within the editor so that the bitmap could be used exactly as it is when loaded into the game. However, doing this at runtime is trivially cheap, and leaving the bitmap in a grayscale form makes it easier to view and modify in case I need to go back and make changes to the sprite. Another alternative would be to leave the source art intact and map the original palette indices to new palette indices, but I kind of like altering it because it helps me to think of my source art as not being associated with any one true color palette.

It’s also worth noting that as I am strictly enforcing four color sprites, I could minimize file size by saving the bitmaps as 2-bits-per-pixel, but at the resolution I’m dealing with, reducing file size is a non-issue at this time.

This feature is exciting for a number of reasons. Along with sprite mirroring in shaders and various other changes I’ve been making recently, it represents a better, fuller, more robust implementation of a feature that was hacked into Super Win. It opens the door to a number of cool features that are evocative of retro games: rapid palette swapping to produce a flashing effect when taking damage, altering enemies’ palettes to represent variations on similar archetypes or “champions,” possibly even doing some fullscreen palette swapping trickery to “fade” screens in and out in discrete increments as was often seen on the NES. It may even be the first step on the road to character customization, which is something I wanted to do in Super Win but had to abandon because it was beyond the scope of that game.

The last thing I’ve done this week is to split out the player character entity into separate representations for the side-view action scenes and the top-down overworld map scenes. This was done in the interest of code legibility. This player character implementation began its life in You Have to Win the Game and grew out of control throughout Super Win to incorporate a number of disparate features. By using separate entities to represent these different states, I can manage the code more easily and also avoid some of the hassle associated with keeping a single entity alive throughout transitions to and from the overworld map. In Super Win, the player entity is constructed once when the game launches and destroyed when the game is closed. All changes to the player’s state, from saving and loading games to moving between levels, are represented in that one object. I’m moving away from that pattern in favor of one where the player entity is destroyed and rebuilt with relative frequency and persistent data is maintained external to that entity.

Implicit to this change is the notion that an overworld map will be part of Gunmetal Arcadia, and indeed, that’s something I’ve been considering. I haven’t decided exactly what this will look like; it’s possible I’ll go for more of a “board game” sort of map a la Super Mario Bros. 3, but in any case, I do expect that individual levels will be connected via an overworld map. I’ll figure out exactly what this means as I get deeper into the roguelike design of Gunmetal, but some of the questions that I’ve been pondering are whether to allow backtracking, how many branching paths may appear, whether or not some branches are clearly labeled as easier or harder, and so on.

The next few weeks are going to be spent on some tasks unrelated to Gunmetal Arcadia, so I’m not sure what next week’s blog will look like — it might be a good opportunity to ramble about high-level design a little more as I did last month. Stay tuned!

Contextual Cues

Even in the midst of Turkey Day and Consumerism Weekend, last week managed to be highly productive, so I have a lot of ground to cover in today’s blog.

I kicked off the week with a task to help facilitate these devlogs. As I mentioned in an earlier blog, I keep each of my projects in a separate Subversion repository for legacy reasons. This can make it difficult to review commit logs for the previous week, as I have to check each repository separately. What I really need is a way to view a list of all commits made to all repositories for the entire week, sorted by commit time. So I wrote a script to do exactly that. You can see the output here. This script runs every morning and prints out messages from all commits made in the last week for easy review. As this is publicly visible, it’s also a good reason to step up the quality of my commit messages. “Yurp,” “whatever,” and “this” are probably not terribly useful messages.

I’ve talked a little bit in the past about how visuals can affect game feel. Animation can have a huge impact on how we perceive a player character’s weight and movement. Art can also provide visual cues that subconsciously affect our expectations of how characters should move, and developers can harness this phenomenon in order to better tune game feel.

Way back when I was starting to write the jumping physics code for You Have to Win the Game (code which I’ve continued to improve and reuse to this day), I found that by replacing my placeholder sprite with a picture of Mario from Super Mario Bros., I immediately recognized the failings of my physics settings. My foot speed was too slow, my jump height was too low, and gravity was too light. Of course, my goal was not to recreate Mario’s physics exactly, but these observations helped me move in the right direction.

I recently had an opportunity to exploit this phenomenon again, and to a much greater extent. I’ve been making some big changes to my animation system recently, and I had the realization that I now had all the tools necessary to drop in an existing sprite sheet from a different game, and — fingers crossed — it should just work. I didn’t mention it explicitly, but when I was initially tuning the physics settings for Gunmetal Arcadia a few weeks ago, I was modeling it after Zelda II and The Battle of Olympus. Naturally, I chose to use a Link sprite from Zelda II as my test content. This time, however, instead of a single static image, I could imitate an entire suite of animations.

I haven’t changed any of the physics settings in Gunmetal Arcadia since adding this test content. I haven’t felt the need. A side-by-side comparison will reveal some clear, if subtle, differences between Zelda II and Gunmetal Arcadia, and that’s a good thing; I’m not trying to remake Zelda II here, but I do want to evoke it. This puts me in a really good position to understand other needs beyond physics. Now that I have Link running around in my test map, I have expectations related to melee combat, which is the next big system I’ll be tackling. I’ve been deconstructing the intersection of movement and melee combat in a number of games, not just Zelda II, but also The Battle of Olympus, Faxanadu, Castlevania, and others. There are some interesting subtleties that arise when you look closely at how melee attacks work in conjunction with walking, jumping, crouching, and I want to be sure I capture those subtleties to the best of my ability, maximizing good game feel as well as retro authenticity.

I woke up early Thanksgiving morning with the sudden desire to implement input recording and playback. I’ve had that feature at the back of my mind for a while now, most recently after demoing Super Win the Game. I noticed that the game tended to attract a crowd while it was being played. While it was idling at the title screen, most people would pass it by. This is an old problem and a solved one; arcade games have used attract modes for years for exactly this reason. An attract loop in which the game plays itself for a short time is an easy solution to this problem and is relatively low cost, at least in theory. You load a particular level and provide faked player input to move the character as if they were being controlled by a human player. Where this gets interesting is in making sure it behaves reliably when played back on every machine, as even a small change in the game state can dramatically throw off the rest of the simulation. Fortunately, the confluence of multiple existing systems helped solve many of these problems for me.

About two years ago, I implemented an option for using a fixed delta time for updating the game state in my engine as explained by Glenn Fiedler here. Historically, I’d always used a variable delta time, and this is still the default behavior in my engine, but I recognized that in certain situations, the determinism provided by a fixed delta in desirable. My use case at the time was integrating shots in a bullet hell shooter; I never made that game, but I did get as far as refactoring my entire engine ticking process to allow the game state’s delta time to be fixed.

My input system handles control bindings, which allows me to ignore details about individual input devices and focus on high-level controls as they would appear to the player. Consider the case of polling for input to move the player character. Rather than needing to explicitly query the state of individual arrow keys and joystick axes from game code, my control binding system abstracts these specific devices away so I can just ask, e.g., “Is the ‘move left’ control active?” Additionally, controls may be flagged as relevant to the game simulation or the engine, which affects when and how they are polled.

Having these features at my disposal made input recording a fairly simple process. Rather than having to record the complete input state of every device connected to the PC, I could reduce my data set to the states of the high-level controls defined by the game. I could further reduce the data set by only recording control states when they actually changed, as opposed to every single tick. Finally, I could ensure that the playback would match the recording exactly by dynamically toggling a fixed 60 Hz tick in both cases. (I should note I’m making the assumption here that the initial state is the same for playback.)

Eventually, this will become a real attract mode for Gunmetal Arcadia. There will other problems to solve along the way, including making random level generation and events deterministic (another solved problem, thanks to the Mersenne Twister). Another potential use case, and one that I’m extremely excited about, is the ability to automatically record and upload whole replayable sessions from playtest builds (or Early Access builds, should I choose to go that route). I learned so much and made so many improvements to Super Win the Game just from watching people play it at events, and being able to collect that information from any number of players across the internet would be absolutely awesome.

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.