It’s been a bit of a slow week getting back to normal development habits after GDC, but I did manage to start prototyping some features that I’ve been wanting for a while.
Continuing with the serialization work that I started a couple weeks ago, I implemented a method of preserving a record of the existence of entities that have been dynamically spawned at runtime. Previously, I was keeping track of the GUID and data definition file associated with any entity that were dynamically spawned in each room of the current map. This data is now written to the serial resource for each room of each map in order to preserve these records across map transitions and saving/loading. This is the final piece of the puzzle needed to facilitate complete saving and loading of any game state. In the future, once levels are randomly generated, some additional data will probably be required to ensure the level is correctly rebuilt when loading (e.g., a random seed or complete Mersenne twister state), but for the test maps I’m working with right now, this gets me pretty far.
I don’t know for sure whether I’ll want any instant death traps in Gunmetal Arcadia (it will depend, I suspect, on finding the right balance between challenge and frustration when tuning difficulty), but in case I do, I added a pair of features that should be familiar to Zelda II fans: bottomless pits and crumbling blocks. In Super Win, I used entities as crumbling platforms, but what I really wanted for this game was to be able to paint tiles on the map as I normally do and have some of those automatically crumble in response to the player stepping on them. Since I already tackled the issue of altering and rebuilding the world’s collision and renderable mesh while working on destructible terrain, it was a short leap to repurpose that code to support crumbling tiles.
The second half of that feature is the bottomless pit. In Super Win, I had a few cases where the player could jump off the top of the screen without automatically scrolling to the next room, when no room data were available in that direction. To support bottomless pits, I simply made this change also affect falling off the bottom of the screen, and then I added a new type of tile which does not block movement but which automatically kills the player when they cross it while traveling in a specified direction. Lining the edge of the screen with these tiles ensure that the player dies when falling off the screen.
I was able to repurpose this new tile type for another instant death trap which may or may not make the cut: Spelunky-esque walkable spikes. In the Win the Game series, spikes are implemented as solid blocks that cause damage regardless of which direction the player is traveling. Now I have the option to implement spikes which the player can safely walk through and which only cause damage if the player falls onto them from above (or whichever way they are oriented). I’ve been wanting to avoid leaning too heavily on features from the Win the Game series like spikes, but this feels like a good way to come up with some new and interesting scenarios rather than simply retreading the same ground.
As soon as I started implementing destructible terrain, I knew that I would want to hide loot inside walls. I threw together a quick prototype of what this might look like earlier this week. Right now, every tile has a 100% chance to drop loot, which is silly and obviously not what I’m going to ship, but it’s fun to see in action. There are still a number of unanswered questions here, e.g., will I want a global drop rate for random loot, or does it make more sense to place loot drops inside tiles by hand. (Or both?) In any case, this gets me one step closer to having wall chickens, so that’s cool.
The last couple of things I’ve done this week have been super quick prototypes just to make sure things will work as I expect. I threw together a test of what a dialog-driven NPC shopkeeper might look like based on the jeweller from Super Win. As it turned out, my dialog system had been broken since late last year when I made a change to decouple core game data from campaign-specific data, and this gave me a chance to find and fix that issue.
I’m not sure yet what the complete shopping loop will look like; there are a number of dependencies that I haven’t solved yet (e.g., what does the player’s inventory look like?), but that’s becoming one of my top priorities. I’ve done a little bit of work on figuring out how upgrades to variables like jump height can be applied to the player based on collectable items, and I’m hoping to be able to generalize those patterns in a way that is conducive to building a wide variety of upgrade items very quickly.
The most recent feature I’ve been working on is one that’s been looming at the back of my mind for a while: bosses. Exactly how ambitious I get with bosses remains to be seen, but at the very least, they need to have weak points. I’ve prototyped a boss monster using two separate entities, one for the body and one for the head (the weak point). Even in this relatively simple case, trying to get these two entities to look and feel like one cohesive thing has introduced a number of complications, and I’m not yet sure whether this pattern will hold up in other cases. But for a first stab at it, I’m pretty happy with how this has turned out, and I feel more confident that bosses will be a feature I can ship with.