Choosing to make a game on the Game Boy is about limitations. You’re faced with them at every turn and your game gets shaped by them.
Want an extra frame in your run cycle mid way through development? Better find some details you can remove from the background tiles (potentially across every level). Choices between a second enemy type on a level or an extra collectable, with sprite, tile, and palette limits to stay under. Juggling this with the constant concern of slowdown from the ancient CPU.
When I began to plan out my current project, Fall from Space, I was aware that I could be pushing against a number of hard limits. File size is something I’ve been constantly monitoring, checking the size against my estimate of percentage left, but also the overall project’s variable count.
GB Studio allows 500 global variables to be set, so from the start I was very conscious to minimize the use of these, using flags where I could but also local variables where possible.
I thought I was doing fairly well, but I made one major mistake.
Local variables compile as global variables.
This I didn’t plan for, and if your total variable limit, global and local combined, is over 768, you can run into problems; variables can start to overwrite other variables and you may have issues with saving and loading the game.
This is something I became aware of in the QA testing of Tales of Monsterland DX, but thankfully it wasn’t far from this limit, so I could easily bring it under. However, I made a (slightly concerned) note to check how Fall from Space was shaping up and it was at – 1056/768 variables.
*screams*
1056 and the game had a lot more content to come.
So, what can you do if you’re in this situation, or even better, to avoid this situation?
Finding Your Projects Total Variable Count in GB Studio
From the GB Studio menu, choose Game > Advanced > Export Project Data.
Then from your project folder, open include/data/game_globals.h
Search for MAX_GLOBAL_VARS. This is the number of total global and local variables, combined in your project.
If you need to buy yourself a few more variables, it can apparently be bumped up to 800 without problems, although I’d recommend trying the steps later in this article to get this down as low as you can.
For this, choose Game > Advanced > Export source.
Open build/src/include/data/game_globals.i, search for MAX_GLOBAL_VARS, if the number is higher than 768, it can apparently be bumped up to 800.
Reducing Your Global Variable Count
After the sinking feeling in my stomach had subsided a little, I found two areas of the game that I thought were the main offenders, where I knew I had definitely used a ton of local variables:
Enemy AI
Perhaps unwisely for a system with limited resources, enemies, rather than travel on a set path, monitor and react to the player’s position. If the player is to the left of an enemy, it’ll turn around and head towards them. When the player is close to the enemy, it’ll telegraph and then attack.
This was all done mostly, with a set of multiple local variables and a custom script.
To improve this, 7 sets of reusable global variables were created for the enemy AI; 7 is the maximum number of enemies currently in a scene. It was tedious to replace all these across the game, but 1056 variables became 780.
Still over the limit with a lot more enemies planned, but better.
Coins
Fall from Space is an open world, non-linear game, you can visit and revisit levels to explore and find secrets. Coins operate in a similar way to XP, being used to purchase upgrades and items.
As levels can be revisited, coins needed unique variables to mark as collected or not, and there’s no way around this (if your game is linear, you can make these into reusable values and save even more).
Previously, coins neatly used their own local variable for “collected” and a custom script triggered when the coin was collected (that fed in the coin value to allow for a variety of sizes). They could then be copied and pasted quickly without modification, remaining unique. However, having just a few coins on each scene can very quickly add up to a lot of variables, and it’s simply unsustainable for a larger game.
I didn’t want to drop coins or vastly reduce them, so the best compromise I could find was to create new global variables using flags, e.g. Coins_1A (planet/set group). Each coin within that group has its own ID that I could reference in a new custom script to mark a coin collected.
Flags allow 16 on/off switches within a single global variable, so I figured it should be a sizeable (16x) reduction (all the quests in the game were already built using flags).
1056 variables, which were reduced to 780, were now reduced to 522 overall, with plenty of global variables available.
With the majority of the game engine built, quests and coins fitting 16 variables into one, and no doubt other efficiency improvements I’ll make along the way, the project in its full scope was viable again.
Conclusion
Variable counts are just as important as file size in how feasible your GB Studio project is, but somewhat of a hidden issue. This needs to be taken into account for all projects, but particularly those larger in scope.
I’m still likely to optimise further, with all the hidden nooks and crannies I’ve snuck local variables into, but the project is back on track, after a (thankfully brief) struggle. Hopefully any other GB Studio devs who weren’t aware of this hardcoded limit can take steps earlier than I did and save themselves the headache!
Thanks to Chris from Spacebot Interactive for tips on increasing the total available variables slightly, as well as how to get that combined total in the first place.
You can check out the demo of Fall from Space and follow its progress, over on my Itch page.
Independent Game Developer (part-time), Game Boy Nerd & Graphic Designer (full-time).