Loading...

Every Mistake From My Latest Software Deployment

By Bhushan Thumsi • 2024-11-25
A post-mortem of the release of Freezai's Mountain, a GBA ROM written in C.

I released Freezai's Mountain, a puzzle game and a Game Boy Advance ROM hack, on November 23rd, 2024. The launch was largely successful: no major bugs surfaced, distribution went smoothly, and player feedback was overwhelmingly positive. Download numbers were only slightly above par and obviously, there's always room for improvement. This post-mortem examines several technical and strategic challenges I encountered along the way.

As Newton once said, "If I have seen further, it is by standing on the shoulders of giants." In that spirit, I hope sharing these lessons helps future ROM hack developers avoid similar pitfalls.

Lessons Learned

1. Sloppiness and Testing

Development speed was one of the highest priorities for this project, and strategic decisions were taken with this idea in mind. For example, I set the release date for the ROM and scheduled beta testing around that release date, instead of the other way around. Core functionalities were sufficiently tested, but several edge cases slipped through the cracks. Most egregiously, one of the debug menus was left in the final version of the ROM. You can't test everything, and players will contort themselves to break your game, but some of these errors were inexcusable. Furthermore, after the public release, I was given feedback that I genuinely found insightful and would've implemented it if I had thought about it beforehand.

"Move fast and break things" is a great ideology for velocity, but it does have some inherent sloppiness. Simply "don't be careless" is good advice but ultimately an aphorism, I'm more interested in the systemic and structural ways that I can minimize mistakes.

Treat testing as part of the development process, not a separate activity. This development cycle rushed through testing in order to meet a deadline. Why was that the plan? Testing was treated as an afterthought, something you do to prevent something catastrophic between the first iteration and the release date.

A focus on unit testing individual functions. Realistically, it is tough to conceptualize an entire testing suite for a video game because you can never truly predict what players are capable of and what methods they'd use to break your game. However, I can unit test the building blocks that serve as the foundation of the game. In the context of this game, several custom Attacks did not behave correctly in certain edge cases. For any custom function or behavior, I need to set up my own unit tests to make sure that it works as intended. The ideal pipeline is to use unit tests for functions and leave enough time for beta testers to create as much havoc as possible in order to test the robustness of the game. I was doing neither of these things.

2. Images and the GBA Hardware

While this was ultimately solved before release, I did face numerous challenges inserting custom images into the game. The GBA is extremely creative in how it handles space and colors, which is to be expected from an early 2000s console. Many people more experienced than me have written in depth guides on the topic, so I'll defer to their expertise here, but I will walkthrough the workflow that troubled me the most.

Inserting a GBA Title Screen using a modern image:

  1. Use GraphicsGale to downgrade your image (most modern images are 24bpp) to 4bpp. This can be done automatically or manually, but I've found that the automatic downgrade is usually sufficient.

  2. 4bpp supports 16 colors, but the GBA does not! Instead, it uses the first color as it's transparency color, leaving you 15 colors to work with. Use graphicsgale to convert your image from 6 colors to 15 colors. Again, i've found the automatic downgrade to work well enough. Select an unused color for the color pallete and move that to the 0th index. This step was the biggest pain point for me, I didn't realize that the color pallete was fixed at 16 colors and that the first color was the transparency color. Save this palette.

  3. Use TileMap Studio to generate both a tileset and a tilemap. Importantly, the tileset here is a png file. This png file is what you need from here on out, not the original png.

  4. You should now have a tilesetpng file, a palette file, and a tilemap file. Insert these files into your rom.

After numerous attempts, and several images with incorrect color palletes, orientations,etc I was able to successfully insert images and hope this guide could be of use to the reader.

3. Decision Paralysis

This is not referring to a technical aspect of the code, but more about the design of the game. My game intentionally had a lot of options and potential decisions for players. I didn't want players to be able to brute force their way through the puzzles, trying every possible combination of moves. Instead, I wanted players to have to think about the puzzle and try to understand the underlying mechanics.

The problem is that I gave players too many options. There were too many paths to the solution, and from a psychological perspective, players often continue down paths that are incorrect, if the first step appeared to be right. With so many options, players found incorrect solutions that got them 50% of the way there before getting stymied. Instead of reevaulating, they kept trying to force the other 50% to no avail. This led to player frustration as they were unable to make progress. This is an interesting problem to me. This game was intended to be difficult, but how do you draw the line between difficult and miserable? Is it a good thing that players can't solve your puzzles, or a bad thing? My gut feeling tells me that it is a good thing, but puzzles should be structured to give people the feeling that they're making progress. Difficulty doesn't lead to a gut-wrenching feeling of frustration, what leads to that frustration is when you chase a solution only to find out you've made zero progress the whole time. In future games, I will structure puzzles to maintain the level of difficulty while giving players the feeling that they're making progress.

Conclusion

This list will be further updated as I gather my thoughts. I hope this was useful to the reader and offered some insight into the challenges I faced.