Postmortem: Black Hole Battle

This year, I participated in Global Game Jam. In preparation for it, I decided to make a game in 16 hours, or one week’s worth of my game development time. What I wanted to focus on, in particular, was scoping the game accurately; in other words, I wanted the game’s scope to only encompass what I thought would be feasible within a week.

16 hours is the amount of time I’ve estimated spending doing game development during a typical week.

How did I do? Read on to find out!

The various notes I scribbled roughing out game ideas.

Planning Phase

Day 1 (Saturday)

I spent a couple of hours on Saturday roughing out the game idea. I wanted to make a top-down space shooter, and I wanted the player to fight against a black hole’s pull and escape its gravity well. This theme was meant to be both literal and figurative, with game elements hinting an allegory of a fight against depression. To save myself the trouble of coming up with a good name right away, I used the working title Black Hole Game.

There would be two kinds of movement: rotational, where the player’s ship rotates and moves forward; and slide, which emulates classic top-down space shooter movement, such as Space Invaders or Galaga. There would also be shooting combat, with multiple guns for the player to collect, obstacles to shoot down, and enemies to dogfight and defeat.

A direct influence was a game called Laser Age, but I doubt that one is familiar to most people; I played it a lot when I was a kid.

This was a solo project, so I decided that there would be no custom art made for the game; everything had to be found in pre-existing art packs. I spent some time searching, and eventually purchased a few packs from an artist in a style that I liked (the Void packs from FoozleCC on Itch.io). For sound effects, I wouldn’t do any recording myself; either I’d find the effects online or I’d generate them with BFXR.

I chose to compose and mix the music. I had an idea of mashing the themes from two songs together: Rush’s Cygnus X-1 (Book 1: The Voyage) and Orden Ogan’s Black Hole. Both of these songs are themed around black holes, representing the dual literal/figurative theme I sought to represent. Although it would have been simpler to relegate this to external sourcing (as I did the art), I enjoy making music, so wanted to keep this part for myself.

I’d use Godot 4 to make the game. My long-term project, Dice Tower, is being built with Godot 3.5, so I wanted to get more experience using the latest version of Godot, particularly since that’s what I’d be using for Global Game Jam.

Finally, I set a deadline for the entire endeavour: Saturday, January 20th, 2023 at 5:00pm CST. In the spirit of a game jam, I wanted a clear, strict end time to force me to complete the project.

With my ideas set, I spent Sunday and Monday engaged in other activities. Come Tuesday, I was raring to go.

Part of the game design document I created for the game.

Day 2 (Tuesday)

My work period was in the evening. My only task this day was to create a game design document and a timeline for when I was going to work on certain tasks. I gave myself a one-hour time limit for doing all of it; the idea was that limiting how much time I had to plan would keep me from adding scope creep.

I used a modified version of the Pomodoro technique for consuming that hour of time. I’d do fifteen minutes of work, then take five minutes of break time. For the first block of work time, I spilled out as many ideas about Black Hole Game as I could. After the five-minute break, I spent the next fifteen minutes going through six randomly-drawn cards from my Deck of Lenses, writing down answers to how Black Hole Game might be seen through each lens. The final fifteen minute block was spent furiously typing out the actual game design document, or what was actually going to make it into the game. That brought me to 55 minutes of work; the final five minutes were spent taking my game design document and scheduling out which tasks would be worked on when.

I think timeboxing the game design period proved useful. Only a small amount of the many ideas I’d come up with made it into the design doc, and that was solely because I didn’t have enough time to write them all down. Since there were fewer things, it limited the scope of what Black Hole Game was going to be. All that remained was to see whether or not that small amount of scope was achievable.

Some of the ideas that were left on the planning room floor included the guns and shooting-oriented mechanics; the gameplay would solely focus on movement.

Yes, the background is a noise texture.

Development Phase

Day 3 (Wednesday)

My time period was both morning and evening. Accordingly, I focused on roughing out the core of the game: movement mechanics and endgame triggers. My goal for the end of the day was to have a playable minimum viable product.

After creating the Godot project, I started implementing the player spaceship. I added the rotation-based movement first, spending a bit of time trudging through trigonometry (and the CharacterBody documentation) to figure out a simple implementation. Once this was mostly functioning as desired, I added the alternative sliding movement style, as well as the ability for the game to switch between the two movement styles seamlessly. Finally, I added constant downward velocity, simulating the pull of a black hole.

I added a debug key to let me freely toggle back and forth between the two styles of movement, even though my ultimate goal was to trigger this change through a pickup. I didn’t remember to take it out of the final build, so any player that figures out what the bind is can cheat the game. ;P

Once the player movement was working, I fleshed out my test game world into a fuller experience. I created some simple asteroid platforms for the player to rest their ship upon. I also made a couple of debug endgame zones: a red one for the black hole bottom, signifying defeat; and a green one to indicate where victory would be given to the player. In both cases, I showed a rudimentary test popup to communicate this endgame state. At this stage, the loss and victory zones were not too far away, for ease of testing.

With a game world in place, I worked on creating the Fuel mechanic. This limited how long the player was able to use their forward thrust, and with it the ability to drive against the black hole’s pull, and would create the game loop of moving from resting place to resting place without running out of fuel along the way. The implementation itself was simple: I made a custom resource that tracked how much fuel was in a given fuel tank, how long it took for the fuel to recharge, and signals to indicate when fuel was depleted or replenished. I then gated the player’s forward movement behind whether they had fuel in the fuel tank; if the player ran out of fuel, they couldn’t thrust forward until the tank recharged to full.

The last thing I tried was an experiment to render a black hole through Godot’s shader system. I tried a few shaders I found online, but none of them worked with initial implementation. Eventually, I decided that this wasn’t worth continued pursuit, and I axed it from my todo list.

By the end of the day, I had my MVP working: the player ship moved as designed, they had a fuel resource to manage, and places where they would trigger defeat or victory upon touching. I was feeling good about my chances meeting the planned scope.

The rocket flame is a basic Godot particle effect.

Day 4 (Thursday)

Today, I only had a couple of hours in the morning to do game development work. Knowing this ahead of time, the only work I scheduled for that day was implementing a UI display for the fuel gauge and a Pickup system with three implementations: Fuel Tanks (instant refuel), Tank Expansions (refuel and expand the player’s tank capacity) and Stabilize (temporarily activate the Slide movement style). The day went as planned, and I implemented all of those thing by the end of my game development time. Once again, my confidence in the game scope increased.

The “black hole” is a giant Godot particle effect.

Day 5 (Friday)

Once again, I only had a morning’s couple hours to work. Originally, my plan was to implement sound effects, but I changed my schedule to work on music, instead; I figured the timeboxing would be more useful for roughing out a composition than figuring out sound effects and how to implement them.

This time, I encountered difficulty. I had specific ideas for how I wanted to make the music, and I spent an hour messing around with various virtual instruments to try and get better sounds. Ultimately, most of that time was wasted, as I reverted to using the sounds I’d had in the first place.

Because of that wasted time, I rushed my way through a composition, and at the end of my gamedev work period I still didn’t have a fully composed piece of music, let alone the victory and defeat variants and the actual in-game implementation.

At this point, I became worried about whether I could still meet my planned scope. Were it not for my strict limit on when I would be allowed to work, I probably would have forced myself to finish the music on Friday night, against my work-life balance needs; instead, I forced myself to stick to the plan, and resolved to finish things as soon as I could on Saturday.

I kept the UI minimal, but took the trouble to find custom fonts on Google Font; not using the engine default font looks more polished.

The Final Push

Day 6 (Saturday)

This was the final day for developing Black Hole Battle (the final title of Black Hole Game). I had ten hours, from 7am to 5pm, to finish development. By my self-imposed standards, this included publishing the game and making it available for people to play.

First, I had to catch myself up from where I’d gone off-plan. I spent about an hour finishing the music composition; ultimately, I was very pleased with it, and it decently accomplished my composition goal of merging Rush and Orden Ogan. I also threw together some short themes to play during defeat and victory.

With the music composed, I started work on implementing the music into the game. I thought I’d save some time by stealing some code from Dice Tower’s sound management system and converting it to work in Godot 4; the reality was that this system was built on top of a number of internal systems which I also had to port over to make the entire system work. Altogether, that was another two hours spent. Once the foundational systems were in place, it didn’t take too long to wire up the logic for when each piece of music should play.

Next, I jumped into creating and integrating sound effects. With time being compressed, I opted for using BFXR to create almost all of the needed sound effects (the lone exception being an ambient background noise, which I wound up stealing from Dice Tower). I worked my way down the list of planned effects, crossing out any which I felt I could do without. By early afternoon, all the necessary sound effects were created and implemented.

At this point, I needed to add the bare minimum requirements for UI, menus and game restart logic. I spent 20 minutes finding and adding two fonts: one for stylistic display, like headings, and one for button and paragraph text. Next, I created a Theme resource and added just enough customization to reduce the cost of duplication (like consistently styled buttons). With that theme, I created and styled my main menu, pause menu, and endgame menu popups. Once the menus were made, I added logic for when they would appear. Finally, I created proper game start and restart logic and integrated that with my menus. Once these things were finished, I had a fully functional and minimally polished game. To confirm I had a functional build, I did a test export of the game and proved that it still worked.

Fortunately, I only had one screen resolution to worry about; my experience supporting multiple resolutions in Dice Tower cautioned me against making the effort to do more than that.

By this time, I had about an hour left to add whatever content and polish I could muster. I threw together some simple game objects (based around the asteroids and planet from the purchased art packs) and tossed them into an expanded game world, along with generous placement of player pickups. I also adjusted the player movement mechanics slightly, to make them feel more responsive. Finally, I hid the debug graphics for the endgame zones, and, for the black hole bottom, I added a particle effect to indicate some kind of churn and swirl; hardly a realistic representation of what a black hole would actually look like, but it felt cool and only took a minute to spin up.

With minutes to spare, I created the final export and uploaded Black Hole Battle to a hosting service. The project was finished, and precisely at 5pm! I shared the project with a few friends, then went upstairs to have supper with my family.

I created a single asteroid scene, then created other scenes that let me reuse that one asteroid scene in groups. For these big clusters, I added a script that let the game randomly pick an amount of asteroids to show, adding easy variety.

Takeaways

The primary goal for Black Hole Battle was to practice scoping for a specific amount of time. Given this, I was successful: I accomplished all of the features I’d set out in the game design document.

Did I complete every single task? No, but that was never the goal; it’s impossible to complete a project exactly as drawn up, and there must be room alotted for adjustments. What I was expecting of myself was to implement all the planned game features and to release them in a polished state; in this effort, I succeeded.

Was the game itself perfect? No; the audio balance between SFX and Music was off, I didn’t really nail the planned thematic duality of black holes and crippling depression, and the small amount of gameplay means it doesn’t take long to fully explore what the game offers. My focus wasn’t on making Black Hole Game the best game it could be, but on making it good enough to be releasable. The game isn’t perfect, but it’s “good enough” to feel like a complete game.

At no point did I force myself to work longer than the hours I’d planned. I resisted the urge to crunch when I felt like I was falling behind, and I still found a way to deliver a completed project. This was a rare success, as previous projects have either ran horrifically over scope or had significant cuts to features and quality to release them on time. Hopefully, I can use this as a standard to plan other projects by.

Conclusion

I wanted to prepare for Global Game Jam by making a one-week, precisely-scoped project. With Black Hole Battle, I successfully achieved this goal, and it left me feeling confident going into Global Game Jam.

How did the jam itself turn out? You’ll find out soon, when the IGDA Twin Cities Global Game Jam postmortem meeting is uploaded to YouTube! That said, I consider the work I did on Black Hole Battle an important factor in how my time at Global Game Jam went.

Here is the final result for Black Hole Battle, for those who wish to try it out. I have no plans to make further changes for it, but feel free to leave feedback so I can apply it to future projects.

Design Dive: Dome Keeper

I discovered the game Dome Keeper in October of 2022. It’s a Godot game, and it had a cool premise—tower defense mixed with resource mining in a sci-fi atmosphere—so I bought it. Since then, I’ve played Dome Keeper on a near-daily basis, and I haven’t gotten tired of it yet.

Why do I like it so much? I decided to analyze the gameplay and try to figure that out. If I can understand why I like playing a particular game, that will help me figure out how to better design my own games.

I decided to focus on two categories: the gameplay of Dome Keeper itself, and the “environment” surrounding how and when I play Dome Keeper. Both impact my overall feeling for the game and why it’s so much fun for me to play.

I totally didn’t get distracted playing Dome Keeper while writing the blog post, I was doing field research!

The Gameplay

There are three parts to Dome Keeper’s gameplay: mine digging, resource management, and monster fighting. Additionally, there are a number of “rush moments” where these three systems come together to create awesome moments.

All runs start with carving out your initial tunnel.

Mine Digging

Digging a mine is simple: move down below the dome and start drilling into the nearest block (if you’re the Engineer character, anyway). This feels like digging mines in Minecraft (another activity I’ve done a lot). Why do I like it? I think it has to do with being able to structure a plan for what an “ideal” mine shaft looks like and then imprint that pattern onto the pixelated rock tiles.

I’ll be ignoring the Assessor character for this post because I almost solely play as Engineer; it just fits my preferred style of play better.

I’m not content with just digging tunnels, though; I need a goal in doing so. That objective is finding new resources: iron, water, and cobalt. These resources all contribute to improving my capabilities (more on that in a bit), so they have endogenous value within the game. Because of that value, they’re worth finding, so it gives me a small burst of dopamine when I find them. The way I dig my tunnels allows me to ensure I don’t miss finding anything.

I don’t know why digging optimal patterns to find resources is so soothing to me…but it is.

Finding iron, water, and cobalt is only part of the mining story; I also have to carry those resources back through the mine shafts to my dome, where they are processed for use. At the beginning, the game limits how many resource units I can carry, resulting in a cap to how quickly I can mine. Over time, I can upgrade this carry limit, so the efficiency improves. That visible sense of progress feels good as I play, and it further feeds into the value resources have.

There’s other things which can be found underground, too. The other main discoverable items are gadgets, which you have to dig out and carry back to your dome. Once there, they provide some beneficial functionality, including the ability to teleport between your base and a movable portal (Teleporter), a gravity lift which pulls resources in it up to the dome (Lift), and high-powered explosives you can drop to destroy lots of rocks at once (Blast). There are also other minor things to discover under the rocks which aren’t directly part of the dome, like a small creature that ferries one resource at a time, a seed which you can plant on a resource to create a “tree” growing that resource, and a device that, when activated with two iron cubes, gives you X-ray vision to see through two layers of rock. These things add a touch of surprise when you come across them in your digging, and the variety which can be found keeps things interesting.

I’m not sure what this called, but picking it up gives you a massive speed boost. That’s fun to randomly find!

Finding resources and helpful items is only one facet of Dome Keeper’s gameplay. Once you bring those things back to your base, you need to do something with them.

Once your resources have been brought back for processing, you get to choose where to spend them. There are multiple things you can upgrade, and making the right choices about which upgrades to get when is important.

Resource Management

You are underpowered when you start a new run of Dome Keeper; it takes quite a few hits for your drill to break apart the rock, and even longer when that rock contains a resource. The first thing I always do is to mine enough iron to increase my drill’s power so I can dig faster. Immediately this provides visible feedback in the form of faster digging, and passive feedback in that I can get future upgrades sooner. This kind of tangible feedback feels great, and it keeps building up with each upgrade you purchase.

The upgrade UI is nice and clean, so it’s obvious what you’re getting and what it leads to in the progression tree.

I didn’t have to choose upgrading the drill first, though; I could also have chosen to upgrade my mining speed, or the power of the laser weapon on my dome, or even the ability to see how much time I have before monsters come within firing range of the dome. There’s a plethora of choices to make, and strategizing to buy upgrades at the right time in order to maximize my chances of survival is enthralling. Even choices which feel worthless (like buying an indicator that tells me how many waves I’ve survived) feed into the thrill of strategic decision making; by having some options that are obviously worthless, it gives me the thrill of knowing I’m making a correct choice by avoiding them.

The dome and the keeper aren’t the only things to upgrade, either. The gadgets you find buried under the dome also have their own small upgrade tree, which makes them even more fun to use. Some of the upgrades improve efficiency, like adding additional orbs to the Lift to bring more resources back faster. Others change gameplay entirely, like the Teleporter gaining the ability to teleport resources and providing an alternate means of getting resources back to your base. As I play, I also develop partiality towards certain gadgets based on how I like to play (teleporter and lift are go-to gadgets) while others have less value (like the probe and the Drillbert robot). If I bring back a gadget and it turns out to be something I don’t want, I get to choose to shred it for cobalt, which helps prevent me from feeling like I brought back something worthless.

Spending resources on upgrades is important for improving my ability to mine more effectively. Just as important, however, is improving the ability to defend my dome.

Turns out we weren’t alone, after all.

Monster Fighting

The final element of Dome Keeper’s gameplay trifecta is base defense. Every so often, monsters will approach from across the surface of the planet you’ve landed on and attempt to destroy your dome. Losing your dome means losing the game, so you have to prevent this from happening at all costs. Fortunately, this part of gameplay feels fun, and the combat introduces further opportunities for strategic thinking.

Firing a laser feels so darn fun! It’s a straightforward beam of light that melts the health of any monster it hits for as long as you keep it trained on said monster. The effects feel nice and juicy, from the wavy effects of the beam to the small particles that shoot from along the beam trail, from the satisfying shoom sound of the laser to the small controller rumble that happens while I’m opening fire.

Over time, bigger and bigger monsters approach, in greater numbers, so you must upgrade in order to survive. The laser can be made more powerful, and the dome can be improved with greater health and resistance to damage. These upgrades cost the same resources that you use to build up your mining efficacy, so there is a constant tug and pull of when to upgrade your mining to get resource faster and when to upgrade your defense so you can continue to survive.

Time to upgrade my laser. That means it’ll be awhile before I can afford upgrading other things, but I need to start killing monsters faster to reduce time to kill, and with it base damage.

There’s even strategic gameplay in the moment to moment of battle. You can’t move your laser instantaneously, so where you move it to impacts how much damage you take. If you move it to the side with fewer monsters, then that’s more damage coming your way before you can shift the laser back to the other side. If you take enough damage, you need to pop out of laser mode to make repairs (done simply with a payment of cobalt), so you need to make sure you stay on top of how much health you have.

A recent update to Dome Keeper added an upgrade that automatically fixes your dome when it runs out of health, if you have the resources to afford it. It’s something I always get because of how convenient it is, but having it definitely removes a lot of that tension which previously came from managing health in battle.

Overall, fighting the monsters feels good, and figuring out the optimal times to upgrade and the best battlefield tactics for minimizing damage feels continuously interesting. The best moments of Dome Keeper, however, come from when these three tenets of gameplay interact with one another to create thrilling results.

I like to keep my laser in the center of the dome prior to starting the battle, so I can pivot quicker to whichever side spews monsters first.

Rush Moments

I’ve already explored some of the ways Dome Keeper’s systems come together to create good gameplay, but there are some more subtle thrills to be had.

While you’re mining underground, you have to keep a constant eye on the monster proximity countdown. Come back too early, and you’ve wasted precious time you could’ve spent doing more digging; come back too late, and you’re going to take some hits and get behind in your defense. If you get things exactly right and dash back into the base just as an attack wave starts, it creates an incredible rush.

Even in failure to calculate things correctly, it still results in powerful feelings, from the panicked adrenaline burst as you scramble back to the tune of the proximity alarm’s beeping to the relief you feel as you exterminate the last monster in a wave with a sliver of health remaining, able to fight another day. Importantly, you aren’t left with the taste of defeat from these moments; you feel as though some bad decision you made was your near downfall, and formulate solutions to prevent yourself from falling into the same bad situation again.

Whoops, didn’t play that one right. I’ll do better on the next one.

Finally, reaching an endgame moment provides its own thrill. Whether it’s the relic from Relic Hunt mode, to making the decision that you have enough score to trigger the sendoff in Prestige mode, reaching the end goal feels powerful in that the end is in sight, if only you can hold out and play well just a few moments longer. It can even turn into a bit of mastery, where you know you can win right now, but choose to try and play as long as you can, betting on being able to squeak out a win just before becoming overwhelmed.

My Environment

The gameplay itself is enjoyable, but just as important for me is how well it fits my lifestyle. I don’t get much time to play games, I don’t enjoy spending lots of time learning how to play them, and short and sweet games usually don’t feel cool enough for me to enjoy playing them. Dome Keeper manages to hit a sweet spot for all three of those metrics, and I’ll explain how.

Hmm…find resources more easily, or improve my base defense? Or, perhaps, take the cobalt to repair my base? Choices, choices.

Time Spent

I don’t have much spare time. In addition to spending 40 hours a week doing my day job, I spend at least 16 hours a week on developing my own games, and at least half of the remaining time in various family activities. I simply don’t have time anymore for epic games that cost me dozens of hours of gameplay, like I did as a teenager and in my early twenties.

The gameplay of Dome Keeper is such that I can easily fit a meaningful gameplay session in roughly 20 minutes. It doesn’t feel like I’m hard pressed to end the session, either; a full cycle takes roughly 2-3 minutes, so it’s not hard to find a natural stopping point.

I do confess to sometimes finding it hard to stop because of that “just one more thing” mentality, though. Gotta find out what that gadget is before I quit my session, right?

Completing a full round of Dome Keeper takes, at most, a couple of hours. That’s enough time for me to finish a run at least once each week. Game completion gives me a great sense of resolution, even if said run ends in defeat. Comparatively, games with a massive story and lots of content can easily take me months to reach a completion point, and playing the same game that long without resolution leaves me feeling frustrated. Thus, Dome Keeper’s short run time is something I enjoy a lot.

As someone who has a life to live and games to develop, it’s easier for me to enjoy games that have short core sessions and modest run times; in those regards, Dome Keeper’s timing fits my sweet spot almost perfectly.

Don’t mind me, I’m just hauling some iron.

Simplicity

Similarly to how I have less time to play games, I have less time to understand the complexity of a game’s loop. If something takes a lot of time for me to learn, I have a lot less fun playing it; at the same time, if the gameplay is too simple, then it’s boring. Once again, Dome Keeper manages to hit a perfect balance for my tastes.

Having only a small number of resources to manage helps keep the complexity down. The fewer compounding interactions I have to keep track of, the easier it is for me to understand those resource interactions. I think the number three, in particular, is just right. Having only two resources would make for not much challenge at all, and having more than three, while not impossibly complex, would add more information for me to comprehend, and make the game slightly more difficult to get into.

Relic found! Time to dig it out and bring it back to the base…

Speaking of complex interactions, Dome Keeper has a lot of them. It may not be obvious at first, though, because those complexities arise from the combination of simple interactions. Buying a drill upgrade? Easy to understand the value. Buying a more powerful laser? Also easy to understand. But what if you only have the resources to buy one upgrade or the other? Less powerful drill means it’ll take longer to get more resources for upgrading, but less powerful laser means you might not have enough firepower to prevent the next wave from doing a lot of damage. Those two simple interactions (upgrading the drill and the laser) combine to form a complex strategic decision, one that changes from run to run depending on the situation I’m in. I love simple ideas that combine to form deep strategies, and Dome Keeper is full of such interactions.

Playing the game almost feels like routine to me at this point. That may sound like a weird thing to speak of in a positive light, but it makes sense for someone in my position. A routine is something I can measure myself against easily to see how well I’m doing. Following the patterns I’ve established are good feels rewarding when I carry them out with maximal efficiency. Finally, that comfy feeling of following a routine is a pleasant break from the stressful challenges I face in my day job, game development efforts, and family life.

Dome Keeper may seem like a simple game to play, with not much time spent doing it. For me, that’s a good combination, and everything feels just complex enough that I don’t get bored of playing it the way that I do.

One sec, trying to survive the final fight.

Fun Atmosphere

Finally, the style Dome Keeper is presented in appeals to me. The pixel art is crisp, and easy to read, so it doesn’t take me much effort to read the information I need; it also conveys a good sci-fi atmosphere without needing too much detail. The sound design is great, from the tings of the drill to the crumbling of the rocks to the screams of the monsters as they die. And the music is chill enough to fit well in the background and not pull me out of my mine-digging reverie.

Conclusion

I like Dome Keeper a lot. In studying the game, I’ve realized that its gameplay is a great fit for my interests, and the way it fits into my busy lifestyle makes it easy for me to make small amounts of time to play it.

As a game designer, still working on crafting an enjoyable game, these insights are valuable to keep in mind. I don’t want to design another Dome Keeper, but understanding why I enjoy that game so much aids my own efforts to create games that, hopefully, are just as enjoyable.

The aftermath of the final battle. I survive, victorious once again.

Anchors and Margins and Containers, Godot My!

Note that the title’s joke only works if you use the correct pronunciation of Godot. 😉

As much as I’ve loved using Godot over the years, one of my biggest pain points had been grappling with positioning UI nodes. I work as a web developer for my day job, so I work regularly with CSS. Compared to that, Godot’s UI didn’t feel intuitive, and anything more complex than full-screen positioning frequently resulted in nodes placing themselves in ways I didn’t expect, and it felt like I spent hours duct-taping an interface together. I scoured whatever documentation I could get my hands on, but nothing seemed to help much in the end.

Recently, however, I’ve had some tremendous breakthroughs in my understanding of how Godot’s UI positioning system works. The result is that I now understand that Godot’s UI is actually very simple to use, almost brilliantly so. Suddenly, I was able to put together complex UI scenes easily, and comprehend why my UI looked the way it did. Given all the frustration I’ve felt over the years, these realizations have felt almost miraculous.

I wanted to codify my newfound knowledge in this blog post. Not only will this be a reference I can look back on to refresh my memory, it will help people struggling with Godot’s UI to gain the perspective I have, and thus make UI work a breeze instead of a hurricane.

This is not a tutorial on how to make good UI, but an explanation of how Godot positions UI nodes. That said, I made a Godot project to help illustrate my points, and I’ve made it available for you to download and reference for your own edification.

The project was originally created in Godot 3.5, but I tested opening it in 4.0 and nothing seems to have changed for the worse. The UI around anchors/margins is different, as called out on Twitter by Jaysen Huculak, but the underlying principles are still the same.

Anchors

Let’s start with the first of the foundational elements of UI positioning: Anchors.

Anchors control the boundaries of where a node and its content are drawn on the screen. The unit of measurement is literally, that: a unit, from 0 to 1. What is the unit’s reference? The parent node’s size, which starts from the pivot (which is the 2D coordinate where the node is “located” in UI coordinate space) and extends across horizontal and vertical axes to the full size of the parent node. 0 means you are at the start of the axis (horizontal for left/right, vertical for top/bottom) and 1 means you are at the end of the axis.

That’s tricky to parse with words alone, so let’s look at some images to illustrate how this positioning system works.

Note that this is the Godot 3.5 interface. In Godot 4.0, these properties are nested under the Layout dropdown section.

The above is a simple Control node that is the child of another node that fills the entire viewport. Note that all the anchor values have been set to 0. Correspondingly, the node’s size is also zeroed out, so you can’t see anything of that node’s contents.

If you create a Control node with Godot’s editor interface, it will not look like this despite also having 0’s set for the anchors. I’ll explain why later in the article.

Let’s see what happens when we set the right and bottom values to 1 (or 100% of the parent’s size horizontally and vertically).

Suddenly, our node stretches fully across the available viewport space. By setting right to 1, we told Godot to expand the right edge of the node all the way across the parent node’s bounding rectangle, across the horizontal axis; it’s the same story with setting bottom to 1, but on the vertical axis of the bounding rectangle, instead.

In Godot 4, the anchors are abstracted behind a helper menu interface. To change the values manually, you have to set the anchors preset to “custom”, which exposes the raw numbers. Thanks to Rob for the comment pointing this out!

Just for fun, let’s change the left and top values to 0.5 and see what happens.

Now our Control node looks like it’s in the lower-right corner of the viewport. Essentially, we told Godot to move the left and top edges of our node 50% away from the parent’s pivot origin.

I’m not showing this in the screenshots, but I placed a ColorRect within the Control to make it more obvious how much space it’s taking up. It’s essentially just filling whatever space our Control node is, and isn’t needed in any functional way.

Anchors are just one part of Godot’s UI placement equation. Another critical part of that equation is Margins.

Margins

Margin controls the amount of spacing used from the specified edge. Where Anchors are placed using percentile units, Margins use pixel units.

In Godot 4, margins are called “offsets”. Same concept, different name. Thanks again to Rob for pointing that out!

Let’s take another example Control node, with anchor values right and bottom set to 1.

Currently, the viewport is completely filled. Let’s try adding some margin around the Control so that there’s 16px of space around it.

…wait, that doesn’t look right. There’s 16px of space around the top and left of the Control, as we expected, but the bottom and right sides got pushed outside of the viewport’s visible area.

Why did that happen? It’s simple: Godot doesn’t treat margin as distance into the bounding rectangle. Instead, Margin gets applied along an axis of direction; positive margin is to the right/bottom of the specified edge, while negative margin is to the left/top of that edge.

This is different from how margins work in CSS, and is a big reason why I misunderstood Godot’s UI for so long.

To get the spacing effect we want, we need to apply negative margin values to the bottom and right margins.

That’s more like it.

Just for fun, though, what if we wanted to have our Control’s width exceed the bounding rectangle of the containing node? Simple, we just make the left and top margins negative, and the right and bottom margins positive.

Earlier, I glossed over the fact that creating a new Control node in Godot’s editor doesn’t actually create a node with no size, despite anchors being set to 0. That’s because Godot defaults the new Control’s right and bottom margins to 40px, which results in giving them a default rect_size of Vector2(40, 40). I don’t know of official documentation explaining why, but my guess is that this is to try and minimize confusion around why new controls have no size.

Wait, what’s rect_size? How is that related to margin values? Good questions!

How Anchors and Margins Impact Other Control Properties

While Anchors and Margins are the core aspects that determine a node’s position and size, they do so in coordination with other node properties. Changing the anchors and margins of a node will usually automatically adjust these tangential properties, and vice versa.

Let’s go over what these properties are.

Rect Size

The rect_size property is the actual size of the control node. This can be set directly, but often this gets readjusted based on the settings of the anchors and margins. The important thing to remember is that this value always represents the node’s actual size in-game.

Rect Position

rect_position is the point where the control “is” in the game’s UI space (aka it’s point of origin). Like rect_size, this can be set manually, and is also automatically adjusted based on interactions with anchors and margins.

See how the right margin for this control is 80, but the left margin is -20. This makes the control’s size 100 (80 + 20) and its X coordinate -20.

Rect Min Size

The rect_min_size property forces Godot to never shrink this particular node below the specified size. Unlike rect_size and rect_position, this is never adjusted automatically by Godot. It’s useful for when you absolutely need to have a control not shrink below a certain size, but be careful: it’s easy to abuse this property to hack around badly-set UI properties. (I certainly used it this way!)

Layout Presets

At this point, if you’ve worked with Godot’s UI before, you may have realized something: “This feels awfully similar to what happens when I use the Layouts button!”

That’s because those Layouts are nothing more than common presets for the anchor and margin values. For example, “Full Rect” is the exact same thing as setting top and left anchors to 0, right and bottom anchors to 1, and all margins to 0. Meanwhile, the “Center” preset sets all anchors to 0.5 (aka 50%) and then automatically calculates the margin values such that they are half of the node’s minimum size, resulting in a centered node.

This is the same 100×60 rectangle from the previous image, but with the center preset applied. Note the difference in not just anchor and margin values, but the rect_position as well.

The presets specified were common enough that Godot’s developers decided to make a convenient way to set them, but it can be confusing when you try to use them without understanding how the underlying system works. I’ve definitely had confusion about why a previously “centered” control wasn’t updated automatically when I did something which changed the node’s size. The reason why is because the presets don’t automatically update in response to changes; they just act on whatever you have architected at the time they get used. Thus, if I change something which affects the node’s size, I need to reapply the “Center” preset to get the node to look centered again.

Child Control Nodes

What happens if you change anchors and margins for a child node? Exactly the same thing as changing those values for its parent! All the examples I’ve used to this point have had nodes be children to a root node that matches the size of the viewport, but the viewport itself is completely irrelevant to the sizing of nodes. If you have a sized control, and adjust the anchor and margin values of its children, they will fit within that parent control’s space.

This control has it’s anchors and margins set relative to the viewport-filling parent…
…while its child’s anchors and margins are relative to its own bounding rectangle, instead.

That’s incredibly powerful and predictable, to have a UI system which functions the same for every Control-based node in Godot.

Well, almost all nodes…

Container Nodes are Exceptions

There is a class of node in Godot called a Container. Container nodes themselves can be sized with anchors and margins, just like any other node. However, the children of container nodes get automatically sized and positioned by that container’s internal logic, ignoring (and overwriting) any manually-set size and position values.

You can position and size container nodes within control nodes via the editor…
…however, if you try to change the anchors, margins, or rect_size of nodes within a Container-based node, those values will be automatically adjusted by the container node.

There are multiple kinds of Container nodes, each with their own internal logic for how children size and position are handled. To give a few examples:

  • HBoxContainer aligns its children horizontally.
  • VBoxContainer aligns its children vertically.
  • GridContainer aligns its children within a set grid of columns.
  • CenterContainer centers all direct children to its own center.

Godot’s documentation does call out this behavior, and the layout presets are disabled when working within container nodes (the latter behavior to prevent developers from using them in places where they simply won’t work). If you hadn’t understand how the UI system works overall, like me, then these explanations and behaviors may have felt more like descriptions rather than elucidations.

Size Flags

You do still have some control over the placement and sizing of nodes within a Container, through size flags. Size flags have four types of behavior, for both horizontal and vertical axes (all of which can individually be turned on or off).

fill causes the node to fill the space given to it. That space is governed by both the parent container’s size and the node’s own calculated size.

expand causes the node to fill any space within the parent container not already used by another node. If neighboring nodes are not set to expand, they get pushed by ones that do. If adjacent nodes both expand, they split the space between them.

shrink center causes the node to occupy only its minimum possible size, while also centering its own position relative to its neighbors and its parent container.

shrink end is the same as shrink center, but with the position at the end of the available space instead of the center.

Not setting any of the above flags makes the node act as though a shrink begin property existed.

Here, the first and last child nodes only have their fill flags set. The second and third child both expand horizontally, while the third child also shrinks to center vertically. (Since there are no child nodes of fixed size for that third child, a minimum height of 10px needed to be set)

The important thing to remember with positioning nodes within containers is to not worry about getting the nodes in a specific position or size, but to get them aligned according to whatever ratio you’re trying to achieve. The advantage of this approach is that you can place container nodes anywhere within the UI, and they will automatically take care of placing and sizing their children to match that same ratio.

Why Won’t My Control Node Behave in a Container

Have you ever tried to put a Control node in a Container node and it behaved like this?

You might need to squint to see the white text that’s out of place.

At first glance, it seems like the Container isn’t size-managing the Control, but that’s not actually the case. The truth is that Control nodes, by default, do not adjust themselves based on the size of their own children. (In other words, Control nodes are not Containers!) In fact, the Control node is resized by the Container, but since the Control isn’t expanding to the size of its children its own size is getting set to 0.

There are two ways to get more expected behavior. One is to put a rect_min_size on the Control node so there is something for the Container to resize.

The other way is to use the Control node’s size flags.

Which one should be used? It will depend on the effect you’re trying to achieve. If you just need the node to occupy space, a rect_min_size should do the trick. For more dynamic size adjustment, changing the size flags works best.

Conclusion

This is how Godot’s UI sizing and positioning system works: Anchors, Margins, and Containers. Now that I understand this, I’ve had a much easier time crafting UI that is placed exactly how I want it to be. The system is simple, but until I grokked how it works it felt confusing and unintuitive.

Hopefully, this post helps you better understand Godot’s UI as well!

I used this color palette for the ColorRect nodes I used for visualization throughout the examples. It doubles as a nifty display of what you can accomplish with Godot’s UI!

Postmortem: Belle Bubb’s Sand-Witch Shop

Rebecca and I have spent the last half year working on the same game: Dice Tower (the full release). We hit a milestone of getting the game ready enough to show at a local playtest livestream, and I really wanted to take a break from Dice Tower development. The two of us decided to participate in another game jam; it would let us try making something different, and possibly something that would be worth continuing after Dice Tower was finished.

Participating in more game jams was something we’d intended to do after GMTK Game Jam last year, but we spent so much time focused on Dice Tower that we never made time for it.

After some research into game jams happening at the time, we chose to enter Godot Wild Jam 54. It’s a game jam where only Godot engine-made games were allowed, so we’d get a chance to see other games made in that engine. It was a smaller size game jam than others we’d entered in the past, so the odds that people would play our game (and leave feedback) was higher. Finally, the length of the jam was nine days, and we thought that would allow us to better fit jam work in alongside our normal day job and family responsibilities without taking too much time off.

The game we created was Belle Bubb’s Sand-Witch Shop, and it was about working in a sandwich shop making “cursed sandwiches” (fitting the jam’s theme of “curses”) through 2D drag-and-drop gameplay. Sadly, we were unable to finish the game due to a convergence of multiple major issues; that said, those issues provided great insight into how to get better at making games, so I don’t think our efforts were wasted.

I’ll identify what those issues were, explain why they were problematic, and explain how I’m going to learn from them to become a better game developer.

Even though our game was incomplete, we still uploaded what we had to the jam anyway, so we could get feedback.

Issue: Isolated Tests

The gameplay for Belle Bubb’s Sand-Witch Shop involved doing new kinds of things that I was less familiar with, like drag and drop mechanics, evaluating what constituted a “sandwich”, and having ingredients that could interact with one another both during sandwich assembly and during sandwich consumption (aka “eating”). I chose to try and build each system in isolation and test that each worked well enough before moving on to others.

Creating all the systems in isolation meant there was no gameplay loop for the majority of the game’s development, so there couldn’t be any testing around whether the game was actually fun. Sure, dragging ingredients around and having them interact with one another was cool, but without evaluating them it was just an aimless sandbox experience. Testing the systems independently also meant I couldn’t see how well they’d interface with one another. This had catastrophic consequences when I encountered fatal issues with those systems once they were brought together.

Lesson Learned: No More Isolated Tests

I like making isolated tests because it’s simpler for me to wrap my head around them; I also don’t have to immediately worry about making them work as part of a whole. However, this is twice now that waiting to integrate systems until later in the project has resulted in slower progress. The jam version of Dice Tower was able to recover from this; Belle Bubb’s Sand-Witch Shop was not. Therefore, for games I’m working on the future, I need to build all the systems together at once. That should help me identify integration problems much sooner, and come up with better fixes for them.

Gameplay was to drag ingredients from their containers onto the sandwich being assembled on the countertop. The taste profile on the right would update as each ingredient was added to the sandwich.

Issue: Badly-Designed Resource System

The foundation of evaluating the sandwich structure was a system that made heavy use of Godot’s customizable Resource nodes to store data in complex ways. This was somewhat similar to resource-based work that I’d created for Dice Tower, so I thought it wouldn’t be too much work to do the same kind of thing here. The architecture I came up with involved having the Ingredient resource store references to its UI model, and then the UI model also referencing its own Ingredient resource.

This dual-reference approach led to horrible issues with resource uniqueness. I was treating each Ingredient resource as a unique entity, but Godot treats resources as shared entities; anything holding a reference to a resource refers to the same instance of that resource. Since each ingredient, in design, could have its own unique set of curses and effects, I had to do a lot of duplication when creating new Ingredients and assigning them to models. This created all kinds of bugs where the stored data on a model or resource didn’t match what the game systems expected, and the massive amount of nesting took hours for me to debug.

All that stemmed from one complex resource system. I built multiple such architectures, and then had them all reference each other… The bugs stemming from that hell were the reason we wound up not being able to fully complete the game.

Lesson Learned: Don’t Abuse Resources

Working with Godot’s resources allows for creating powerful customizable systems, but it is incredibly easy to abuse that power to the point of making things insanely difficult to troubleshoot. I need to not use resources so much for the data solutions. At the very least, I need to minimize how much nested resource storage I’m doing, and make sure the architectures I’m coming up with aren’t fatally flawed before building on top of them.

Bringing in a cursed ingredient had an effect on ingredients around it. For instance, the tomatoes were cursed to repel lettuce.

Issue: Too Much Undetected Complexity

I had no idea how complex the game we were trying to make actually was. To illustrate, these are the features which we managed to get into the game. At the time of planning, I thought they were simple:

  • Sandwiches have ingredients
  • Ingredients have curses
  • Curses have effects
  • Ingredients can also have effects
  • The same effects can be assigned to both curses and ingredients
  • Ingredients have individual tastes
  • Sandwich ingredients are combined together to form a recipe
  • They also come together to form the actual sandwich
  • Both of these have a “taste profile” that is the amalgamation of all ingredient tastes
  • They also have an “effects profile” that is the amalgamation of all curse and ingredient effects
  • Recipe and food need to be compared to each other to determine if they are “close enough”
  • All of the above needs to be represented in-game and in UI

That wasn’t even the full scope of what we had originally planned to put into the game. Other ideas include:

  • Randomizing which ingredients have what curses
  • Getting paid for making sandwiches
  • Using earned money to choose what ingredients to buy
  • Having a story about how you sold your soul to keep your sandwich shop alive
  • Post-sandwich order review that included descriptions of what effects your curses had

That was a lot of complexity. It didn’t feel that way at the beginning because I didn’t think things through. The further we got into making the game, the more I realized the amount of effort needed to make all these systems and interactions work was insane.

And, because I waited so long to bring systems together, I didn’t experience this revelation until it became too late to pivot to something simpler.

Lesson Learned: Work Through Systems Implications in Advance

I need to have much better insight ahead of time where potential complexities will arise. The best way I can think about doing that is diagramming them somewhere, on paper or in a whitescreen board app, so I can visualize what systems need to interact with one another. If there’s too much complexity, then it’s a clear sign that I need to scale things back. I’ve been worried in the past that this will make the process take longer, but the consequence of not trying to do so is having things take longer anyway and not realize it until it’s too late.

Other ingredients had effects that could cancel out curses. The cheese, in this instance, cancelled out any Repulsive curse on any other ingredient.

Issue: There Was No Planned Endgame

We came up with an idea for interesting gameplay, but had no concept of what the goal of the game was going to be. I kept putting a pin in it to “come back to” after the other systems were developed. Since none of the other systems were ever fully completed, we never got a chance to figure out what happens at the end.

Lacking this conceptualization of the player’s goal contributed to the underestimation of how much work was needed. There was no way to test the player could play through a core gameplay loop because we didn’t know what said loop was beyond “make a sandwich”. Without that guiding star, it was too easy to fall into a pattern of perfecting the systems with no plan for whether those systems would work well together to create a satisfying resolution.

Lesson Learned: Define the Goal at the Outset

Knowing what the player’s in-game goal is from the beginning not only gives a development target to shoot for in terms of minimum viability, but it also makes it clear what systems really need to be kept to make a fun gameplay experience. That doesn’t mean the goal has to be immutable; in fact, the goal will likely need to be simplified further as development roadblocks cut into available development time. If the goal is known in advance, though, then figuring out how to juggle all the necessary concerns should become much simpler.

To build a sandwich, you would have to account for the curses each ingredient had. You would then have to be careful to make sure the taste profile of those combined ingredients fit close enough to the profile of the sandwich recipe.

Issue: I Was Overworked

As mentioned previously, we’d spent a long time before this working on Dice Tower. In that entire time, I hadn’t really taken a break, and this caught up with me during the jam.

I’m no stranger to pushing through burnout—I don’t think I’ve ever fully recovered from burning myself out nearly a decade ago—but I underestimated how much easier it is to work through burnout when on a consistent, slow grind. When I needed to work fast and come up with good ideas quickly, my brain refused to cooperate. That’s one of the reasons I didn’t have a good grasp on how complex the ideas were: I couldn’t think far enough ahead to evaluate the consequences of those ideas, so I instead ignored that part of the process to work on the next thing necessary. The consequence of working through major burnout was significantly slowed progress, much too slow for a game jam. Subsequently, since I fell behind pace, I didn’t give myself time to rest during the jam, which only further exacerbated the mental problems I was dealing with. It was a nasty negative feedback loop.

Lesson Learned: Take a Break!

I’m bad at taking time off to actually take time off. I also know that it’s easier for me to push through tiredness and make progress if I do it consistently. But there’s a limit to how much grind I can endure, and I need to respect that. At the very least, I should take some time off from game development and other project work prior to starting a new game jam, to give myself time to recharge properly. That should hopefully make it easier for me to work and plan properly, and thus also make it easier to not feel like I’m falling behind, resulting in pacing my work schedule appropriately.

There were lots of possibilities to work with, both for ingredients and for effects.

Conclusion

I entered a game jam with the intent of working on a different project which might become future inspiration. Instead, I endured an experience that revealed multiple flaws with how I approach game development. Though the experience was painful, the lessons I learned from it are valuable, and that makes me glad for having gone through it.

Lest this postmortem post make it seem like the entire project was a disaster, let me highlight some of the things that did go right:

  • People liked messing around with making the sandwiches, so there is an idea there which might be worth future exploration.
  • While the resource system was buggy, it did allow for relatively easy creation of ingredients, curses, and effects.
  • Of all the things that got cut, at least sound and music weren’t among them this time!

Our focus is going back to Dice Tower, but we definitely intend to enter game jams more frequently in the future. Even when the projects don’t succeed in being good games, they succeed in being great teachers.

…and that’s a wrap! (Please clap.)

Postmortem: Dice Tower

This July, Rebecca and I took part in Game Maker’s Toolkit Game Jam 2022 (an annual game jam hosted by the creator of YouTube channel Game Maker’s Toolkit, Mark Brown), making a game called Dice Tower in only fifty hours. It was our first game jam in a long time, having spent the last three years focusing (and failing) on making our “first big release”. Those fifty hours proved to be an intense, fulfilling experience, and I want to examine how things went. I’ll start with the goals that Rebecca and I made, continue into what happened during the jam, and conclude with whether I felt our goals were met and what we’ll do in the future.

Our Goals

First and foremost, Rebecca and I wanted to actually release the game! Our last jam effort, Rabbit Trails, never saw the light of day because we didn’t get the build submitted in time, and we were determined to avoid making that mistake again.

I wrote briefly about this experience as part of my retrospective on 2019.

To that end, we explicitly wanted to scope our game small enough that it had a realistic chance of being completed by jam’s end. Further supporting that goal, we also decided that we would avoid trying to come up with something “clever”; we would be fine with coming up with feasible and fun ideas, even if they might be ideas that other people were likely to come up with. Finally, we determined that we would specifically make a 2D side-scrolling platformer, because that was the genre we were most familiar with; we didn’t want to waste time figuring out how to do a genre that we lacked experience in making.

Based on what had happened in previous jams, we had a few other goals we wanted to meet. Given that our previous games felt bland, we wanted to make sure whatever we made felt more polished and juicy, thereby increasing how good it felt to play. Previous jams had left us feeling burnt out and exhausted, and, while that is a traditional hallmark of game jams, we strongly wanted to avoid feeling that way at this jam’s end, so we made plans to limit how many hours we’d work per day so that we’d have time to relax and get our normal amount of sleep.

Separate from the in-jam goals, we had one ulterior objective: we wanted to see if the idea we came up with was good enough to develop further into a small release. The game we’d been working on, code-named “Squirrel Project”, was still very much in the early prototyping stage; we’d built and tried a lot of things, but made little progress in actually putting together a full game experience. Both of us felt concerned with how much time we were taking in making a “small game”, so we were interested in seeing if doing game jams might give us smaller concepts that would be easier to develop and release quickly. This jam would serve as a proof of concept for this theory.

Day One (Friday, 7/15/22)

The day of the jam arrived. Our son was off spending the weekend with relatives, we’d prepared our meal plan for the next couple of days, and I’d taken time off from my day job. We sat around my laptop, awaiting Mark Brown’s announcement of the theme. At noon, the video was released, and we saw the theme emblazoned on the screen:

Roll of the Dice

Initial Planning

I hated the theme at first impression. One of my takeaways from working on Sanity Wars Reimagined (our first-ever full release) was that working with randomness in game design was hard, and now we had a game theme which strongly implied designing a game focusing around randomness. In my mind, it would be harder to design a game around dice that wasn’t random in some way. Concerned now with whether we would have enough time to make a good game, I started brainstorming ideas with Rebecca.

We spent that first hour working out an idea; the first idea we hit upon wound up dominating the rest of our brainstorming session, to the point that we didn’t seriously entertain anything else. The game would be a rogue-lite platformer, where you moved to various stations and rolled dice to determine which ability you got to use for the next section of gameplay. Throughout the level would be enemies that you could defeat to collect more dice, which would then give you a better chance to roll higher at the ability checkpoints, thereby increasing your odds of getting the “good” abilities.

I intentionally wanted to minimize the randomness of our game so that players felt they had some level of control over the outcomes of dice rolls, and I liked the idea of using dice quantity to achieve this outcome. The more dice you add to a roll, the more likely you are to get certain number totals. This is known as a probability distribution.

At the end of that hour, we formally determined that this was the idea we wanted to work with. Rebecca started crunching out pixel art, and I got to work making a prototype for our envisioned mechanics.

That Old, Familiar Foe

The next few hours of my life were spent working on the various elements that would serve as a foundation for our mechanics. I threw together some simple dice code, along with dice containers that could roll all the dice they were given. I also pilfered my player character and enemy AI code from Squirrel Project, to jumpstart development in those areas.

But something happened as I started trying to work out how I was going to make the player’s abilities work: my brain began to freeze up. This was a frighteningly familiar sensation: I’d felt this way near the end of developing the original Sanity Wars (for Ludum Dare 43). Dark thoughts started clouding my mind:

There’s not enough time to make this game.

You’re going to fail to finish it, just like your last game jam.

Is what you’re feeling proof that you’re not really good enough to be a game developer?

Slowly, I forced myself to work through this debilitating state of mind. After several more hours, I came up with a janky prototype for firing projectiles, and a broken prototype for imparting status effects on the player (like a shield). It occurred to me that if I was having this much trouble making something as simple (cough cough) as player abilities, then how was I going to have time to fix my glitchy enemy AI, and develop the core mechanic of rolling dice to gain one of multiple abilities, and make enough content to make this game feel adequate, let alone good. Oh, and then there was still bugfixing, sound and music creation, playtesting…

It finally hit me: This idea wasn’t going to work. There was simply too much complexity that was not yet done, and I was struggling with the foundational aspects that needed to be built just to try out our idea. There was no way I would be able to finish this vision of our game on time.

My mind in shambles and my body exhausted, I shared my feelings and concerns with Rebecca, and she agreed that we needed to pivot to a new idea. We tried to come up with something, but we were both too tired to think clearly. Therefore, we decided to be done for the evening, get some supper, and head to bed.

Note the lack of planned relaxation time.

As I lay in bed, I fretted about whether we could actually come up with a new idea. That first idea was by far the best of what few ideas we’d been able to come up with during our brainstorming session; how were we going to suddenly come up with an idea that was good enough and simpler? With these worries exhausting my mind, I fell asleep.

This is the first thing I made, a simple test with a dice container and N number of dice. It felt oddly satisfying to keep pressing the “Roll Dice” button.

Day Two (Saturday, 7/16/22)

The next morning, at 6am, I woke up, took a shower, and played a video game briefly. This was my normal morning routine during the workday, and I was determined to keep to it. At 7am, I grabbed a cup of coffee and sprawled out on the couch, pad of paper and pen resting upon an adjacent TV tray, prepared to try and come up with a new idea.

Rebecca joined me at 7:30am, after she did her own waking routines.

The New Idea

I wrote down the elements we already had: Rebecca’s character art and tileset from her previous day’s work, some dice and dice containers, and a player entity that was decently functional as a platformer character. If our new idea could incorporate those elements, then at least not all of yesterday’s work would go to waste.

After thinking about it for a long while, I hit upon an idea: what if you rolled dice to determine how much time you had to complete a level? As you moved through each level, you could collect dice and spend them at the end-of-level checkpoints to increase your odds of getting more time to complete the next level. If that were combined with a scoring system involving finding treasure collectibles that were also scattered throughout each level, then there’d be potentially interesting gameplay around gambling how many dice you’d need to collect to guarantee that you had enough time in each level to collect enough treasure to get a high score.

I pitched the idea to Rebecca, and after some discussion about that and a few other ideas, we decided this was the simplest idea, and therefore had the best chance of being completed before the deadline. Fortunately, this idea also did successfully incorporate most of the elements that we’d worked on yesterday, so we didn’t have to waste time recreating assets. On the other hand, this idea needed to work; there was likely not going to be any time to come up with another plan if we spent time on this one and it failed.

Our idea and stakes in mind, Rebecca and I once more commenced our work.

Slogging Through the Day

I created various test scenes in Godot. Slowly, I began to amass the individual systems and entities that I’d eventually put together to form the gameplay. Throughout the day, I felt very sluggish and lethargic mentally; this was likely a side effect of the burnout I’d put myself through yesterday. I kept reminding myself that some amount of progress was better than none at all, but it still didn’t feel great.

By the start of that evening, I had a bunch of systems, but nothing that fully integrated them. Taking a break, I went outside for a walk and some breaths of fresh air. As I trod the trails in our neighborhood, I worked out the game’s next steps. I reasoned that if I continued to put each system and entity together in isolation and test them, I stood a realistic chance of running out of time to put everything together into a cohesive game. Therefore, I decided to forgo this approach, and simply put everything together now, and build the remaining systems as I went along. This flew in the face of how I traditionally prefer to program things, but I resolved to set aside my clean code concerns and focus simply on getting the game working.

This might look like a game level, but it was really just a single test scene that I was throwing my creations into. There was no logic connecting any of these things together to form a gameplay loop.

The Late Evening Dash

Not long after I returned from my walk, it became 7pm. This was the twelve-hour mark, and in our pre-jam plans I’d determined that I wouldn’t work more than twelve hours on Saturday. Yet I still didn’t have much that was actually put together. I was now faced with a conundrum: should I commit to stopping work now, and risk not having enough time tomorrow to finish the minimum viable product?

Ultimately, I decided that I would try to get an MVP done tonight, or at least keep working until I felt ready to stop. Three hours later, while that MVP was still incomplete, I had put together the vast majority of what was needed to make the game playable: a level loading system, the dice-rolling checkpoints, dice collection (though said dice weren’t yet connected to the checkpoints), the level timer and having it set from rolling the checkpoint dice, rudimentary menu UI, and player death. At this point, I felt that continuing to work would just cut into my sleeping time, and I was still determined to get a proper amount of sleep. At the least, those few hours had produced enough progress that I felt confident that I could finish things up tomorrow morning.

I quickly prepared for bed, and after watching some YouTube to wind down I fell asleep.

One of three tutorial levels I’d created that night. This one is to teach the player that they can pick up dice; when they advance to the next checkpoint, they’ll see that newly-collected die in their dice pool, and hopefully make the connection between the two actions without having to explicitly spell it out.

Day Three (Sunday, 7/17/22)

That morning, I woke up at 6am, as usual, but this time I skipped all of my morning routine save the shower. By 6:30am, I was at my computer and raring to go.

Blazing Speed and Fury

The first thing I did was export the game as it currently was. I’d been burned enough times by last-minute exports that I was determined to make sure that didn’t bite me in the butt this time. Fortunately, this time there were no export-specific crashes or bugs, so I resumed work on the game proper.

For the next several hours, my mind singularly focused on getting this game done. I finally made the checkpoints accept the dice you collected, thus completing the core loop of rolling dice to determine the time you had to make it through the level. I added game restart logic, added transition logic for when the player was moving between levels, added endgame conditions and win/loss logic, and fix various bugs encountered along the way. I also realized that I wouldn’t have time to implement a scoring system, so I unceremoniously cut it from the MVP features.

Cutting the scoring system also meant cutting the third tutorial level, which would have taught the player about the treasure collectible. Additionally, it would’ve served as a prelude to the intended tension of collecting treasure to increase your score and collecting enough dice to have more time in the next level.

Around noon, I finally had the game fully working. I could boot the application, start a new game from the main menu, play through all the designated levels, and successfully reach the victory level to win the game (or run out of time and lose). If nothing else, we at least had a playable game!

Final Push

The game jam started at noon on Friday, and as it was now noon on Sunday that meant 48 hours had passed. Thankfully, the jam had a two-hour grace period for uploading and submitting games to Itch.io. That meant I had less than two hours to jam as much content and polish into the game as I could before release!

I blazed my way through creating six levels, spending less than an hour to do so. Of course, that meant I had little time to balance the levels properly, beyond ensuring they could be completed in an average amount of time. One thing I did spend time on was adding the various pieces of decorative art Rebecca made to each level. It might seem frivolous to add decorations, but I think having a nicely-decorated level goes a long way towards breaking up level monotony and sameness, and honestly it didn’t take that long for me to add those things.

After a few trials, I hit upon a solution for balancing the randomness for the dice checkpoints: I’d give the player six free seconds at the start of each level, and a single die at each checkpoint (in addition to the ones collected through gameplay). As I playtested the level, that at least felt long enough that, using probability curves, the average player could have a decent chance of finishing each level.

Intentionally, I chose to not focus at all on adding sound effects and music. My reasoning went thusly: players would probably prefer to have more content to play through than have sound and music with very little content. It made me remorseful, because sound can make an okay game feel great, but there just wasn’t enough time to do a good job of it, so I decided it was better to just cut audio entirely.

Finally, at 1:30pm, I looked at what we had and determined it was good enough. Rebecca had been working on setting up our Itch.io page, and I gave her the final game build export to upload to the store page. We submitted the game just in the nick of time; shortly after our submission was processed, Itch.io crashed under the weight of thousands of last-minute uploads. While this server strain prevented us from adding images for our game page (we got them in later), at least we already had the game uploaded and submitted, so we weren’t in danger of missing the deadline.

Rebecca and I looked at each other. We’d done it! We’d successfully made a game and submitted it! We spent the rest of the afternoon out and about on a date, taking advantage of our last bits of free time before returning to parenthood the next day.

Feedback

Over the next week, our game was played and rated by people. We received multiple comments about how people enjoyed the core idea, which was encouraging.

A couple of our friends from the IGDA Twin Cities community took it upon themselves to speedrun our game. This surprised me, because I thought the inherently random nature of our game would be a discouragement from speedrunning. They told me they enjoyed it a lot, however, and over the course of that week they posted videos of ridiculously speedy runs and provided good feedback.

By happenstance, the Twin Cities Playtest session for July was that same week, so Rebecca and I submitted Dice Tower to be played as part of that stream. Mark LaCroix, Lane Davis, and Patrick Yang all enjoyed the game’s core concept, and gave us tremendous feedback on where they felt improvements could be made, as well as different directions we could go to further expand and elaborate on the core mechanic. It was a great session, and we are greatly indebted to them for their awesome feedback.

After the play-and-review week had passed, Mark Brown made his video announcing the winners of the jam, and we got to see our final results online (we did not make it into the video, which only featured the top one-hundred games).

For a game jam with over six thousand entries, we did surprisingly well, placing in the top 50% in overall score. Our creativity score was in the top third, which pleased me greatly; it felt like further validation that our core concept was good enough to build on.

Reflection

I want to circle back to those goals Rebecca and I set before the jam, and see how we did in meeting them. There were a couple of other takeaways I had as well, which I’ll present after looking at the goals.

Did We Meet Our Goals?

First and foremost, we wanted to release a game, and we did! That was huge for us, given our last effort died in development. In particular, to release this game after the mental fracturing I endured on Friday night, and having to pivot to a new idea, shows that, perhaps, we’re decent game developers, after all.

Did we scope our game properly? At the beginning, no, definitely not. Fortunately, we recognized this (albeit after spending a day on it), and decided to change to a more feasible idea. Even though we had to cut scope from the new idea as well, the core was small enough that we were able to make it in the time allotted. It gives us a new baseline for how much work we can fit in a given amount of time, which should serve us well in future endeavors.

It’s a similar story for our theme interpretation. Our first idea seemed simple, but turned out to be complex under the hood, as it’s a lot of work to not only add lots of different player abilities, but game entities (such as enemies) to use those abilities on. In hindsight, I laugh at how we thought that kind of game was feasible in 48 hours, with not nearly enough foundation in place beforehand. That said, once again, we pivoted from the complex to the simple, and the new theme interpretation was simple enough to be doable.

Ironically, I thought this would be a common enough idea that plenty of other people would do it, but I actually never encountered a mechanic similar to this during my plays of other jam games, and multiple people commented on the novelty of the idea. Perhaps our focus on coming up with a good idea instead of a unique one managed to get us the best of both worlds!

We stuck to our guns and made a 2D side-scrolling platformer, even though at times I felt like that made it more difficult to find a good theme interpretation. Because we knew how to work in that genre, it made our mid-development pivot possible; I don’t think we could have been successful in doing that if we’d tried to make something unfamiliar to us. Additionally, I think using a genre where dice are less commonly used led to coming up with something more unique than we might’ve if we’d done an RPG or top-down game (two genres I thought would be easier fits for the theme).

One area we did miss on was making this a polished release. The missing audio was sorely felt. That said, I really like the art that Rebecca came up with, especially the decorations, and I don’t regret the decision to cut sound in favor of making levels and placing her doodads. Honestly, despite the missing audio, the fact that this game was fun and playable made this jam release feel more polished than our previous jam efforts.

That dice banner and the dice family portraits were particularly fun to place throughout the levels.

A big success we had was in self-care management. Even though we didn’t stick to the maximum hours per day we set before the jam, we took care to make sure we got enough sleep each night. The end result is that this is the first jam we’ve done that both of us didn’t feel utterly spent at the end of it. That allowed us to enjoy a lovely afternoon and evening together as a couple, and we didn’t feel totally shot for days thereafter. I think that also helped us have the energy needed to push us through to the finish line.

One final goal remains to be evaluated: was our game good enough to base a future release upon? The answer is “yes”. Based on the enthusiastic feedback we received, plus our own thoughts about where the concept could go, we’ve decided to put Squirrel Project aside and focus on making a full, but small, release out of Dice Tower. With some more features and polish, and maybe a dollop of background story to tie things together, we think Dice Tower could make a good starting point for our first paid release.

Additionally, we plan to take part in future game jams, and further explore the concept of making quick games to find small ideas with good potential.

Other Takeaways

There were some additional things we learned from the jam. These emerged as byproducts of the things we tried during the jam.

Our initial thoughts were that we’d spend our brainstorming session coming up with multiple ideas, and then make small prototypes for each of them and decide which of them was the one we wanted to make. It didn’t turn out that way; both our first and second attempts settled early on a single idea, to the point where we didn’t really have many other ideas that we seriously considered. I think that perhaps that’s just how Rebecca and I work; it’s easier for us to jump into an idea and try it rather than piece a bunch of ideas together and flesh all of them out on paper. Perhaps in our next jam, then, we’ll deliberately settle on an idea right away and just go for it, making explicit allowance for pivoting if it starts feeling like too big an idea to work with.

Personally, I also learned that I need to let go of trying to test every little thing in isolation. That may be a good approach for building long-lived, stable systems, but for something as volatile as game prototyping it just slows the process down too much, with no game to show for it. By putting things together as early as possible, it makes things feel more real because it is the real game! I’ll keep this in mind for future projects, to just make a go of it right off the bat, and save my efforts to make things nice and tidy for when the ideas are codified and made official.

Conclusion

Ultimately, I’m glad Rebecca and I decided to participate in GMTK Game Jam 2022. It feels exhilarating to not only finish a game in that short amount of time, but to defeat some of my internal demons from previous jams in the process. We feel more confident in our ability to develop and release games, and we’re excited to tackle making the full release of Dice Tower.

It’ll be interesting to compare this postmortem with the postmortem for whatever that game becomes!

In the meantime, though, feel free to try out our jam release of Dice Tower and let us know what you think!

Dice Tower (Game Jam version) released!

Over the last three days, PixelLunatic and I worked on a game for Game Maker’s Tool Kit Game Jam 2022. Our entry is Dice Tower, and you can play it here!

Keep in mind that this is a game jam game, so this is far from perfect (for example, there is no audio), but we think the end result would up being pretty fun to play! We might decide to develop this further in the future, though we haven’t officially committed to doing so yet.

Enjoy!

How Donkey Kong Country 2’s Movement Feels Amazing (Part 3)

This is Part 3 of a 3-part series. Check out all the parts here!

Part 1: Here!
Part 2: Here!
Part 3: This post.

As a child, I loved to play Donkey Kong Country 2: Diddy’s Kong Quest; as an adult in my early thirties, I still love playing it. One of the reasons, among many, why is the game’s character movement feels almost perfect. Never do I feel as though I can’t adequately control Diddy or Dixie Kong as I navigate them through many levels of perilous adventure. As a game designer, I found myself wondering: what is it, exactly, that makes me love DKC2’s movement so much?

To answer that question, I’ll take a close look at the action verbs DKC2 employs related to the player characters. It’s not just a matter of analyzing the actions and movements in and of themselves, however; the level and enemy design of DKC2 are intentionally crafted to augment those basic and special actions. As is undoubtedly true for many games, it is the whole package together which creates that feel I love so much.

In the first part of this blog series, we looked at the many abilities and forms of movement the Kongs can do; in the second part, we examined the design of the levels those actions are performed in, and how it compliments them. Now, we’ll look at the final segment of the movement equation: the foes the Kongs must fight throughout the levels. We’ll review the types of enemies that get included in the game, relative to how you are expected to deal with them; next, we’ll examine a few foes that implement some special mechanics on top of their base type; finally, we’ll look at a few levels to see how enemies are placed to take advantage of the Kongs’ movement, their movement, and the level’s design to create compelling, challenging gameplay experiences.

Kantankerous Kharacteristics

When asked about what kinds of enemies are present in Donkey Kong Country 2, one might say “there’s some ground enemies, flying enemies, swimming enemies, some bosses”. That isn’t wrong at all, but I want to approach this from a different perspective; I want to examine enemies by how they are designed to be defeated. This approaches helps us focus on what moves you need to employ to defeat a baddie, which makes it well-suited for this design dive.

Basic Baddies

Many of the baddies are designed to be beaten with one or more of the regular moves in the Kongs’ arsenal. Some specifically protect themselves against particular kinds of moves, forcing you to be more strategic about how you approach them. Let’s break those types down.

Stomp Enemies

As is true in many platforming games, there are many baddies which can be defeated by jumping on their heads and knocking them off the stage; I’ll call this “stomping”. It’s usually pretty obvious which foes can be stomped; they lack any sort of visible protection to their heads which might discourage you from jumping upon them. That doesn’t mean all stompable enemies are the same; there’s plenty of variety to enemy widths, which affects how easy it is to land within their hurtbox. For example, Sneeks and Flitters have quite wide hurtboxes (and they are visually long-looking characters to communicate this), making them relatively easy to land on; other foes, like the Klomp, stand upright and present a smaller hurtbox, and thus are more of a challenge to land on precisely.

I use the term “hurtbox” to mean the collision area where contact results in hurting the entity possessing it.

Stompable enemies are sometimes placed in such a way that you can chain jumping on multiple of them in a row. As discussed before, this is used in some places as the required means of progressing through the level, but it’s also included in less critical areas as a fun thing to do. Jumping as you land on top of an enemy provides a boost to your jump height, which adds to the thrill of the action. Since jumping on enemies is a core part of the game, adding elements like this to increase the fun factor goes a long way to making the game feel good to play.

Spin Enemies

The spin move is also usable as an attack, careening into enemies to knock them away. Unlike falling on a baddie from above, using a spin requires knowing how much time you spend in the spin animation before breaking out into a run, as otherwise you’ll instead run into the enemy (and thus take damage and lose the Kong you control). This makes the spin attack more challenging to pull off, but subsequently it feels a little more satisfying to use than a simple jump attack.

When you successfully spin into a baddie, it actually resets the spin to the initial frame of the spin move; since the camera stops moving forward as part of this, it adds some weight to how the spin attack feels, contributing to the fun of using it. To compliment this, some parts of the game place multiple enemies close enough to each other that you can easily spin through the entire group, which is tremendously entertaining!

This is actually something I don’t think is done as well in Donkey Kong Country: Tropical Freeze. There’s been a lot of times in that game where I’ve tried to pull off a spin attack through a group of enemies that seem close enough to spin fully through, only for my spin to come up short in the middle of the combo through no perceived fault of my own. It makes it such that I trust the use of that attack less than the jump. That’s a shame, since I think DKC games are at their best when the player is able to use both forms of attack equally well.

Many of the ground baddies which can be stomped on can also be spun into; some, however, specifically prescribe whether or not the spin attack should be used. The Spiny is designed to resemble a porcupine, bristling with sharp quills all over its body except for the exposed head area; spinning into this foe from the front is thus strongly encouraged. The Klampon, an alligator-esque foe with big, nasty teeth, communicates the opposite; spinning into those jaws means your death, so you must instead stomp them. This adds a level of depth beyond simply defeating these baddies; you need to understand what they are vulnerable to and specifically use the move which targets that vulnerability.

Protected Enemies

There are a few foes which are explicitly immune to the spin and stomp attacks the Kongs possess, meaning you can only defeat them with a projectile or an animal buddy’s attack. As mentioned in previous parts, that means when you are given access to a projectile or a buddy, you’ll need to keep them around long enough to deal with any protected enemies in your path.

What if you don’t have a projectile or an animal buddy? Then these protected baddies become obstacles which you must avoid. There are plenty of places in the game where this is what you are expected to do. For example, many climbing sections are littered with Zingers, forcing you to climb quickly or make well-timed jumps to avoid their patrols. On the ground, protected foes are often placed in ways that force you to perform a clever move (like a spin jump) to get through (or, alternatively, to access some form of reward that you’d otherwise have to pass on).

Enemies which are protected from spins and stomps are given a visual design that communicates this. The hornet-like Zinger is covered in sharp, triangular stingers, making it quite clear that death awaits those who try to spin or jump into it. Klubba is big and muscular, and the Kongs simply don’t have enough mass to do any damage to him; instead, when you try to jump on or spin into him, you bounce off him, and he turns red, making the next time you touch him cause damage. Kutlass sports a pair of oversized cutlass swords, and carries them in such a way that it makes it clear that he can cut you down from any angle you choose to try and attack. Identifying which enemies are protected from spins and stomps is an important part of gameplay, and forces clever use of your moves to either avoid them or keep projectiles and animal buddies alive long enough to get to those baddies and defeat them.

Komplex Kharacters

We’ve examined the basic archetypes of enemies by how they are intended to be defeated. There are a few special cases which differ enough from the basic types, which we’ll look into now.

Ranged Enemies

Most of the baddies in DKC2 use their brawn to try and hurt you, but a few fellows got the clever idea of shooting projectiles at you, instead. That forces you to keep your eyes peeled for when such baddies appear in the level, and react quickly to the projectiles they shoot at you to avoid them. Sometimes, these ranged foes are positioned such that they shoot projectiles through an area of the level you must pass through to make progress, requiring you to time your moves to the pattern of the projectiles so you pass while the baddie is reloading. Thanks to how responsive your basic movement is, dodging the projectiles, while a challenge, is rarely a frustration.

Even within the ranged archetype, there is variety to be found in what projectiles they shoot. The Kannon baddie (not to be confused with the samely-named Kannon that shoots you into bonus areas) sometimes shoots simple wooden barrels, which you can bounce on top of if you aim your jumps correctly; this is used in some levels as a required means of progression, bouncing across from barrel to barrel over a gap until you get to the other side. Other times, they fire iron cannonballs which hurt you irregardless of how they touch you, and you must simply avoid them. The Krook, meanwhile, fires its metal hook hands when you pass within line of sight; the twist is that those hooks function like boomerangs, returning to the Krook after reaching maximum distance, forcing you to not only keep an eye for the initial shot, but be prepared to avoid the projectile as it traverses its return trajectory. Finally, the Kloak hovers around and is capable of throwing many kinds of projectiles, from barrels and chests to Spinies and Zingers; sometimes, if you wait long enough and dodge the projectiles, a Kloak will throw out some form of goodie, like a banana coin or a chest with a 1-up balloon, so it’s not always in your best interests to kill them right away.

Swimming Enemies

While swimming, the Kongs cannot jump, spin, or throw; this makes all the foes underwater a protected enemy, because touching them means death. Thus, underwater sections tend to evoke avoidance gameplay, where you swim carefully through rooms of patrolling baddies. Not every foe is content with simply patrolling, however; the Lockjaw, an orange piranha, will charge towards you if it catches you within its line of sight, while the Shuri, a spinning starfish, will wait for you to enter an area, then attempt to launch themselves in your general direction. The Puftup, a bloated pufferfish, will sometimes explode when you get within range, launching its sharp spikes in predetermined directions and forcing you to dodge to avoid them.

Both the Shuri and the Puftup also have variants which simply patrol an area, so you have to identify which variant you’re facing when they appear on-screen!

A lot of times, in swimming levels, Enguarde the swordfish is hidden somewhere, and using him makes the underwater sections far easier. Instead of having to avoid every enemy you see, you can instead line up Enguarde’s sword bill to stab them and take them out. As mentioned before, it’s a reward for players who explore levels carefully and check the nooks and crannies for hidden passages.

Bosses

Boss fights are the apex stage of every world, the final challenge that you must overcome to progress to the next world area. All bosses are immune to stomps and spins, being vulnerable only to projectile attacks. Often, the projectiles you need aren’t immediately available to you, requiring you to wait for them to appear. These big baddies aren’t content with sitting around and letting you get those projectiles freely, however; they have many forms of attack in their arsenal to use on you. These attacks are patterned, so you can learn how a boss is going to attack you and develop strategies for dodging them. Even when you acquire the projectile, however, you still have to aim correctly to get the projectile to hit the baddie, or you’ll have wasted your shot and made the boss fight take longer, increasing the odds that you’ll make a mistake and take a hit.

The stages you fight each boss on ask for the use of different abilities as part of the pattern avoidance. Krow, the foe of the first world, flies around the stage and tries to drop eggs on you, some of which can later be picked up and thrown back at him. Kudgel, the gatekeeper of World 3, jumps around the stage and tries to land on top of you; when he hits the ground, anything standing on it is paralyzed, so you not only have to run around to avoid getting landed on, you also have to jump in the air to get off the ground to avoid being unable to respond to his next jump. To fight King Zing, the defender of the fourth world, you transform into Squawks and must not only dodge the king’s flight path, you must hit a specific part of his body (the tail stinger) with your egg projectiles in order to cause damage. Even though the underlying pattern of dodge-the-boss-until-you-can-use-your-projectile is the same for all boss stages, the different takes on that pattern keep the gameplay fresh and interesting, while requiring you to make good use of your movement to win.

This was a notable issue with bosses in the original Donkey Kong Country, where nearly every boss had to be fought in the exact same way, by simply jumping on them.

Special Shenanigans

There’s more to a good foe than simply meandering around a level. A few simple stooges like that are useful for establishing a baseline to gameplay, but often, as game designers, we want to make enemies that take expected archetypes and add an unique twist for the player to deal with.

Donkey Kong Country 2 does this with many of its foes; even though the baddies can be classified into a small set types of how they can be beaten, most still get one or more unique traits that make it more interesting to deal with them beyond a simple spin or stomp. We’ll examine a small subset of DKC2’s roster of baddies, observing the mechanics which make them function and how they engage with the moves given to the player.

Neek

We’ll start with the humble Neek. A small, bandana-bearing vulture, Neek hovers at a predetermined area in the level and waits for you to get near. Once you enter his threat radius, he lets out a screeching cry and dives down a planned flightpath, starting with an arced curve and flattening out into a straight line. You need to quickly predict where that flight path is going, and whether you’re in it. If you are, you’ll need to duck or jump to get out of the way. If you want to remove the Neek, you can jump up and stomp on its head as it flies by.

As far as special mechanics go, this one is relatively simple. Even so, it adds an element of intrigue to how you plan to deal with him. Until you enter the threat radius, he doesn’t move, so you can’t wait him out; on the other hand, since it won’t attack right away, you have time to prepare for your reaction. While all Neeks perform some form of dive and flatten out maneuver, the angles involved can vary with each Neek, so you have to figure out quickly what kind of pattern it’s going to adopt. Thus, even though the dive isn’t that complex a behavior, the Neek’s simple mechanic is still enough to provide interesting, fun gameplay.

Click-Clack

A small, yet oversized, dung beetle, the Click-Clack has a small hitbox to accompany its tiny frame. This makes it so that you have to be more precise with your jumps in order to land on them. Additionally, when you jump on one, it flips onto its back instead of becoming defeated; you’ll also get knocked back a little bit. If you ignore that Click-Clack, it’ll revive and move around faster than before; only a second jump will dispatch it for good. On the other hand, while it’s flipped over, you can pick it up and throw it as though it were a projectile (although throwing it down to the ground will cause it to revive). Finally, if you spin into it, you defeat it instantly.

There’s all sorts of interesting gameplay that arises from the Click-Clack’s mechanics. The knockback force you experience when you jump on a Click-Clack can make the stomp a little risky; that force could push you into another enemy, or into a pit. Spinning into it, where you have room to do so, is certainly the safest way to dispatch them. On the other hand, it can be used as a projectile; if you’re about to face a horde of enemies, particularly ones that are protected from your other attacks, it’s well worth your while to stomp on a Click-Clack for the purpose of carrying it around as ammunition (or a shield, since holding projectiles protect you from damaging attacks to your front). You can’t sit around and wait while it’s on its back, however; you have to decide whether you’re going to kill it or carry it, or it’s just going to get up again, and since it now moves faster it’ll will be more deadly to deal with.

If you look at the Click-Clack in terms of how it is beaten, it’s a spinnable, stompable foe. The small hitbox and unique mechanics around what happens when you stomp on it make it a much more interesting, versatile foe to fight than it might otherwise be.

Klobber

The Klobber is a Kremling that hides in normal-looking barrels. When you get close enough to it, the Klobber will pop up and try to run into you, knocking you around if it succeeds in doing so. The fact that baddies in barrels exist means you have to be cautious whenever you see a barrel; is it only a barrel, or is a Klobber hiding within? Oftentimes, Klobbers are placed around other enemies or hazards, making it easy for you to get shoved into a source of damage.

How do you stop the Klobber? You have to leap into the air and stomp on its head; spin attacks do nothing against it. Once it’s been stomped, it hides inside its barrel for awhile before popping back out to charge after you anew. The only way to prevent it from returning is to pick it up and throw it into something and break, or offscreen into the bottomless void. You don’t need to throw it right away, though; you can carry the Klobber’s barrel around, and it functions exactly like a regular barrel. Like the Click-Clack, that makes the Klobber a source of projectiles, making it worthwhile to deal with one.

There’s more than one kind of Klobber, too. Different-colored Klobbers have different effects when they hit you. The green Klobber just knocks you around; the yellow Klobber steals bananas from you, which disappear if you wait too long to recollect them; the black Klobber takes away life balloons, which float away if you leave them alone. The red Klobber hides in TNT barrels—with the special name Kaboom—and blows up if it runs into you. These increasingly deadly side effects heighten the stakes of engaging with them; be careless, and you could lose valuable life-giving resources (or, in the case of Kaboom, your life).

Kutlass

Finally, we’ll bring up Kutlass. We’ve briefly mentioned it already; it’s the double-cutlass-wielding Kremling. Those oversized swords, as mentioned before, make it clear that jumping on the Kutlass is a suicidal maneuver. What about spinning into it from behind? It’s too smart; as soon as you get close, it’ll turn to face you and charge at you. If you don’t move out of the way, those massive cleavers will come down on your Kong’s head and take them out of the picture. The only option you have, if you don’t have a projectile, is to dodge out of the way. When you do this, the force of Kutlass’ swing gets its cutlasses stuck into the ground for a few moments, exposing an opportunity to strike and defeat it, either by stomp or spin.

This enemy is an unique blend of the protected and basic types, and this makes it interesting to engage with. You need some amount of space where you can get near the Kutlass without getting immediately into its threat radius; otherwise, you have nowhere to dodge when it swings the swords at you. Even if you do have enough room to dodge, you have to react quickly, making the Kutlass a test of how well you’ve mastered using your movement over the course of playing the game.

Level Design Kase Studies

Having baddies, no matter how interesting they may be, is nothing without creating level designs that take advantage of how they behave, just like having good movement is nothing without a level design that makes those moves fun and entertaining. As with many other aspects, Donkey Kong Country 2 does a great job with enemy placements in its levels, starting with simple schemes to ease new players in and ramping up to complex challenges that truly test a player’s mastery of their moves.

There are a total of 40 levels in the game, each with enough depth to go many thousands of words into. For the sake of brevity, however, we’ll restrict our gaze to portions of a few levels. Even these microcosmic glimpses should prove illuminating as to how well DKC2 uses enemies in its level design.

Pirate Panic

We’ll begin at the beginning: the first level of the game, Pirate Panic. As is typical of the first level of many games, Pirate Panic is designed to introduce you to the many mechanics you’ll be using for the rest of the game. Fittingly, the first enemy you come across is a Sneek, who is easy to jump on and moves slowly; he’s just begging for you to jump on him or spin into him.

Having the first enemy you encounter be simple, easy, and uncomplicated gives the player less to worry about. The Sneek isn’t going to suddenly rev up speed and charge into you, or jump super high out of nowhere; he’ll just keep moving your way until you either deal with him with your moves or let him run into you. It’s a great way to introduce the basic moves to you.

You encounter a pair of Sneeks as your next foes; you’ve already learned how to deal with one, so now the game asks you to deal with two of them. Hopefully, knowing what to do, this proves to be an easy task for you.

Afterwards, the next foe you see is the plodding Klomp. This is a new baddie, with a differently-shaped profile (and hurtbox), but the way you deal with him is the same as how you dealt with the Sneek; the jump just needs to be a little bit higher. Alternatively, if you’ve happened to learn how to hold down the Y button to run, you’ll pick up a crate projectile right before you see the Klomp. It’s not far-fetched to think from there that you might be able to throw this at the Klomp, or even hold it to run into him.

This Klomp is also on top of a row of platforming barrels, so you could even choose to run underneath him if you don’t feel like engaging him. It’s also an introduction to enemies on different height levels, something you’ll encounter often throughout the rest of the game.

Once you pass the Klomp, the next baddies you have to contend with are a row of Sneeks, but this time there’s a twist: the foes are advancing beneath a bunch of stacked platform barrels (so named to distinguish them from projectile barrels). If you try to jump on them, you’ll most likely land on top of a barrel instead of the Sneeks, avoiding them entirely. If you just want to progress, that might be good enough; for many players, though, it’s irking to leave any foe undefeated, if it was within their power to handle. That row of barrels serves as a discouragement against jumping, in that case. The way to defeat these Sneeks is spinning into them; hitting the first one will result in demonstrating the fun art of spinning through all the nearby enemies, exposing a new strategy for you to use and cementing it in your brain with a rush of fun gameplay.

By now, you’ve had multiple chances to practice your basic moves. The rest of Pirate Panic continues in much the same way, introducing slightly more challenging scenarios and foes, giving you a great taste of the gameplay to come.

Lava Lagoon

Next, we visit Level 3 of World 2, Lava Lagoon. This is the first time a level gimmick gets introduced: the water is, literally, lava, and you must jump on the back of an all-powerful, almighty seal named Clapper to convince him to turn this lava into water, making it safe for you to traverse. You can’t stay in the water too long, however; after a brief period of time the water will start heating up, until it once again becomes lava.

If Clapper is powerful enough to turn lava into water, why doesn’t he help the Kongs out in more substantial ways? Good question.

The way this level gimmick is introduced is clever. You are presented with a small branching path. At the start of this fork sits Clapper, waiting for you. The path above is patrolled by a Klampon; the path below is lava-logged and, at the moment, impassible. Earlier in the level, you had to contend with a Sneek approaching you from a higher platform, so that jump to the upper platform feels dangerous. Meanwhile, Clapper the seal is barking at you, and, given how often jumping on things solves problems in this game, you’ll probably feel inclined to do the same here, just to see what happens. Thus, you discover Clapper’s magical powers of liquid and temperature transmutation, making the lower path accessible to you. It is far easier to swim through this area, so you’ll likely take it over the upper path.

This fork in the road thusly introduces the level’s gimmick to you in an intuitive way, inviting you to figure it out on your own. Even if you ignore Clapper entirely and brave the upper platform, it’s not a big deal; you’ll soon reach a point where you cannot progress further without using Clapper. Seeing him multiple times increases the odds that you’ll engage with him and figure out his shtick.

One other thing that underwater path teaches you: that you’ll have swimming enemies to contend with underwater, as a lowly Flotsam patrols the floor of the lower path. It’s easy enough to swim above him, but it prepares your expectations for what kind of gameplay is to come.

The rest of Lava Lagoon is an increasing progression of a simple pattern: introduce lava-water sections that you need to cool down with Clapper, then travel through before the water heats back up to the point of damaging temperatures. In each water section, you have a cadre of underwater foes to swim past and dodge; the combinations become trickier and trickier to navigate the deeper you get into the level, ending with a mad dash through a maze of puffing Puftups (the non-exploding kind) to make it to the end of the level before you run out of time. For good measure, you also get tossed a Klobber at the level’s end that you have to avoid or defeat, lest it push you back into the lava. Overall, the level is a good example of taking a level gimmick, teaching you how it works, and ramping up the challenge of that gimmick through good enemy placements.

Bramble Scramble

As you progress further into the worlds and levels of Donkey Kong Country 2, the challenges the game puts before you becoming increasingly more difficult. I think Level 3 of World 4, Bramble Scramble, is a quintessential example of the game giving you a great challenge to put all your skills to the test. This level is oriented both around climbing on ropes and flying with Squawks.

In the other two levels we’ve discussed, the opening enemy was something simple and easy to deal with. Not here; your first foe is a Krook, and you encounter him the moment you move forward in the level, needing to deal with his hook shot right away. Even if you beat him, though, he’s right on the edge of a thicket of brambles, so you have to be careful that your jump doesn’t lead you to fall into them. After a long jump to the next safe wooden platform, you’re faced with a tall, thorny vine, with a Zinger hovering on the other side waiting to sting you upside the face, assuming you manage to fly over the thorns without getting your Kongs’ butt pricked along the way. You get one DK barrel to try and take out the Zinger, and if you succeed your passage over the thorns is a little safer. The shot isn’t easy to make, however, and you only get one chance; the game is testing you to see how skilled you’ve gotten with your aim.

Skip past a climbing section patrolled by Zingers and a Krook, and another jumping section where you need to use running jumps to have any hope of making it between platforms, and you’ll encounter your first Squawks section. First, you ascend upwards, with a few Zingers floating off to the side which you can use as target practice for your egg shot. You’ll need it, too, because the next section is flooded with flying Flitters. Normally, these blue dragonflies are relatively harmless, but in such large swarms, you’ll quickly get overwhelmed if you don’t fire away your egg bullets to take them out. The eggs aren’t fired in a straight line, either, so you have to remember how the egg trajectory is arced and use that to guide your aim. While doing all that, you must also avoid flying into the brambles above and beside you as you move through the area.

Thankfully, while flying with Squawks you can rest on flat stretches of bramble without taking damage. Given how difficult it is to shoot down the Flitter swarm and keep yourself up in the air, this section might be where you learn this ability!

Eventually, you get to the no-Squawks sign and the halfway barrel, where the next climbing section starts. First, you climb upwards into the face of a squadron of waiting Neeks. Almost immediately after you see them, they dive bomb across your path. If you jump, you fall back down to the ground, so you have to shimmy up and down the rope to keep out of their way. At the top of the rope is a junction with a horizontal rope, allowing you to continue onward. Here, however, you encounter a Kannon firing a rapid burst of cannonballs; you cannot pass yet, as the rate of fire is too fast. Instead, you must wait until there is a short pause in fire, then dash across as quickly as you can before the Kannon begins firing anew.

You continue across the path of ropes, and soon you end up on another horizontal rope, square in the path of another Kannon. You don’t see the Kannon on screen, but you can hear him open fire, and soon you’ll see a cannonball flying across the length of rope, straight at you! Luckily, there’s some gaps in the brambles above that give you just enough room to jump up into in order to avoid the shot. You must advance down the rope to the next safe jumping zone, before another cannonball comes screaming across the screen to take you down. Do this a few more times and you’ll finally get close enough to the Kannon to take him out and end the threat for good.

There’s plenty more challenge left in this level, but there’s one more pattern I want to look at. At several junctions throughout this level, you’ll encounter a group of Zingers. Some of them will be red, meaning they are immune to your egg shot, while one or two will be normal yellow Zingers. With all the Zingers alive, the passage through will be near impossible; you need to shoot down the yellow Zingers to clear your path enough to make it through with relative ease. It’s a great way of presenting players with a simple, yet meaningful strategic choice that yields a tangible reward.

Castle Crush

Our final foray will be into the realm of World 6, Level 3, named Castle Crush. This is another gimmick level. This time, the floor is rising up beneath your feet, and you’ll quickly find yourself running out of head room! To stay alive, you need to keep your eye atop the screen to see where in the ceiling the continuation paths are, and position yourself to be under them before the floor smashes you into the ceiling.

I wasn’t intending for most of these examples to be Level 3s, but that’s how it shook out. 😛

As if that weren’t time pressure enough, the foes populating this level will do their best to come at you from nearly out of nowhere and force you to make quick decisions on how you’re going to handle them. The first enemy you encounter is, once again, a Sneek, dropping down on you from above; a quick and easy enemy to defeat that you’ve, by now, beaten dozens and dozens of times. It also introduces you to a pattern that will be very common in this level: small alcoves containing enemies that drop on you from above.

The next baddie you encounter is a Spiny, also falling down from above. You must defeat him with a spin attack, but you have to time it right; spin too early and you’ll finish the attack animation before the Spiny gets close enough to take damage, resulting in the Spiny landing right on top of you. Some time later in the level, you’ll encounter Klampons dropping in on you from above as well. These you cannot deal with by spin attack, so you must allow them to fall and land, then quickly jump in the air to stomp on them before they close in on you in the tight quarters you keep.

Eventually, shortly before the halfway point, you get introduced to a long hallway that contains both a Spiny and a Klampon. The Spiny is first; if you spin into him, you’ll wind up near where the Klampon patrols, so you’ll have to be careful to ensure you stop your spin in time to get airborne and stomp the Klampon. This section is specifically designed to introduce you to this particular pairing: Spiny and Klampon. It keeps it spaced wide enough that you have a good chance of surviving the encounter while teaching you how difficult it is to deal with both these foes in the same area.

Sure enough, later on in the level, you encounter your first section where a Spiny and a Klampon patrol right next to each other. The Spiny leads, with the Klampon right behind. You now have a difficult choice to make: do you try and leap over the Spiny to jump on the Klampon and defeat him first, or do you instead spin into the Spiny and try to jump right before your spin carries you into the Klampon’s gnashing teeth? Both maneuvers are equally challenging, and with the rising floor you are forced to decide quickly, lest you get squished. It’s one of the most challenging parts of the game, and it feels awesome to correctly execute whichever decision you made.

There are plenty more sections in Castle Crush where the Spiny and Klampon patrol is used. There is even one section where you have alternating Spinies and Klampons dropping on you from above, forcing you to time your attacks so you spin into the dropping Spiny, then quickly jump to stomp on the Klampon before the next Spiny falls onto your lap. All this challenge, and this is only one single part of the many myriad challenges Castle Crush throws your way. By the time you finally ascend to the top of the level and stomp that exit target, you’ll feel exhausted, yet exhilarated at having gotten through.

Kong-clusion

Whew! At last, we’ve made it to the end, not just of Part 3, but this entire series!

In this part, we dove headlong into examining the enemy design and how it was created with the aim of players using their fine-tuned moves on them. The ways each enemy can be defeated provides a framework for understanding what an enemy means in the context of the moves the player can do, from the basic stompable, spinnable baddies to the foes which embody special protections and attacks. Even enemies sharing the same defeat type can have differences in gameplay by exhibiting one or two special behaviors on top of that. Finally, each level in the game, of which we examined several, is tailored to take these enemies and place them in locations that make optimal use of what they do, all in the aim of providing a fun, challenging experience for the player.

Over this entire blog series, I’ve shown why Donkey Kong Country 2’s movement is special. The moves themselves are finely tuned and feel great to perform, and there’s a great many ways to modify the basic movement to provide fun gameplay variety. Every level is designed to take full advantage of these great movement mechanics, rewarding both skillful play and observant exploration. In each level lives enemies that are designed to make using your moves to conquer them, whether by defeating them or avoiding them, fun and exciting.

In short, I think Donkey Kong Country 2’s movement feels amazing. It’s why I loved playing the game as a kid, and it’s why I keep coming back to playing it, nearly thirty years after it was released. Nothing else I’ve played comes close to how this game feels.

As a game designer, it is my hope that I’ll one day get to make a game that pays homage to the movement mechanics of this game. After writing all these blog posts, I’ve certainly squirreled up enough techniques and ideas to take inspiration from!