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.

Sanity Wars Reimagined released!

The game PixelLunatic and I have been working on for the past seven months, Sanity Wars Reimagined, has been officially released! Download it here.

It’s been a long seven months, working on this game, and while there’s still plenty of things that could be improved, overall I’m pleased with how this game turned out. Most importantly, we learned many things that will prove useful for our future game development endeavors.

We hope you enjoy our game!