Everyone has childhood dreams. Mine was to make a game for my first console: the Nintendo Game Boy. A few months ago, I fulfilled this dream, by releasing my first Game Boy game on a actual cartridge: Sheep It Up!
In this article, I'll present the tools I used, and some pitfalls a newcomer like me had to overcome to make this project a reality! Due to it's length, this article is split in two parts:
Part 2 : Audio challenges / Making Cartridges / Player Feedback
The game
"Sheep It Up!" is an arcade game where a sheep has to climb up by hanging himself to flying velcro straps. The concept is simple, but the game rapidly gets quite challenging: how high can you climb without falling down?
As a game collector myself, I wanted this game to be produced without sacrificing any vintage Game Boy titles. So everything is manufactured specifically for this game: the pcb, the rom, the shell, the protective case and even the sticker! We also tried to keep the price reasonable, so everyone can enjoy the game: $15 (+shipping). It will run on any Game Boy model, from the first one to the GBA SP, including the Super Game Boy and the Game Boy Player.
If you still own a Game Boy, you can buy a cartridge on the publisher website:
https://catskullgames.com/sheep-it-up
Sound constraints
As we’ve seen in part 1, the Game Boy comes with some obvious limitations on the CPU power and graphics sides. But same can be said for audio. Indeed, unlike modern machines, the Game Boy can’t play MP3 music or read WAV sound files. To make sounds and music with a Game Boy, you have to dynamically generate it using the 4 “sound channels” built inside the console. Each channel has a different function:
Channel 1 - Tone & Sweep: can play a sound (a tone) with a pitch moving up or down.
Channel 2 - Tone: plays a tone with no special effect.
Channel 3 - Waveform: can play very simple waveforms (encoded in 4bits).
Channel 4 - Noise: can generate explosion or engine sounds.
Let me say this again: to make a sound with a Game Boy, you have to generate it manually by directly controlling these 4 sound channels. Hopefully, this is actually quite easy to do: you simply need to modify the values of some hardware registers. Each sound channel is controlled by 4 or 5 hardware registers (8bits variables) that defines volume, pitch, special effects, etc. By setting different values on the registers that control a channel, you can make the Game Boy produce a large variety of sounds. For example, here are three sounds coming from Sheep It Up! that I created by using sound channel 1, alongside with the hardware registers values used to generate them:
Jump
NR10_REG = 0x15; NR11_REG = 0x96; NR12_REG = 0x73; NR13_REG = 0xBB; NR14_REG = 0x85;
Land on ground
NR10_REG = 0x79; NR11_REG = 0x8D; NR12_REG = 0x63; NR13_REG = 0xC8; NR14_REG = 0x80;
Falling down (game over)
NR10_REG = 0x4F; NR11_REG = 0x96; NR12_REG = 0xB7; NR13_REG = 0xBB; NR14_REG = 0x85;
As you can see, setting different values to 5 variables enables you to produce very different sounds effects. One could image that, to create sounds, you could go the trial and error route: putting random values to the registers until you find a pleasing sound to hear. But that would be really tedious and not meaningful at all. So, hopefully, modern tools are now available to make our life easier. Namely, let me introduce you to GB Sound Sample Generator.
First, you tweak user-friendly parameters to find a sound you like (press START to test current sound)
It’s a Game Boy program, fully working on real hardware, that allow you modify the values of the sound hardware registers in a user-friendly way. Instead of setting the raw value of ”NR10_REG”, you’ll now be defining a sound frequency, a volume level, a sweep time, etc. You can think of this tool as SFXR for Game Boy. But to export your sound, instead of saving a WAV file, GB Sound Sample generator will display the corresponding hardware register values. So, to play a sound in your game, now you simply have to write down these values into your source code.
then, you hold A+SELECT to display the corresponding raw hardware register values
For Sheep It Up!, I used GB Sound Sample generator on a Game Boy Advance SP (backlight screen is easier to read), with the ROM running on a Everdrive GB. I spent quite some time tweaking parameters directly on the console, and when I found a nice combination, I could easily copy the values from the GB screen to the source code on my computer.
To play this sound in your game, you simply need to copy the hardware register values in your source code
Chiptune music!
Despite limited audio capabilities, nowadays the Game Boy is used as a musical instrument. In the chiptune scene, many talented artists are making energizing tracks on Game Boy, by using programs like LSDJ or Nanoloop. For example, you may have heard of Irish chiptune legend Chipzel, who composed music for Super Hexagon, and French wizard Sidabitball who remixed many pop music hits from the 90’s.
Chipzel Sidabitball
Sadly for us game developers, LSDJ, the tool used to compose these outstanding songs, use almost 100% of the Game Boy hardware resources. So you can make outstanding music with it, but you can’t run a game while playing this music on the console. Hopefully, there are less resource-hungry alternatives to create and play Game Boy music.
1) Custom music player
The most bare bone solution is to make your own “music player”. Remember, the only way to make sounds on a Game Boy is to set values to the hardware registers that controls the 4 sound generation channels. So you can quite easily make your own “music player” by storing “notes” in an array. Each “note” is a particular combination of values for each hardware register. Then, if you define a tempo at which you run through this array to play these notes, you can have a very simple way to make music. And it’s actually how I did it in Sheep It Up! Here is a short gameplay video with sound and music so you can hear the result:
<iframe title="Embedded content" src="//www.youtube.com/embed/vYGqwgomAG4?rel=0&enablejsapi=1&origin=https%3A%2F%2Fwww.gamedeveloper.com" height="360px" width="100%" data-testid="iframe" loading="lazy" scrolling="auto" class="optanon-category-C0004 ot-vscat-C0004 " data-gtm-yt-inspected-91172384_163="true" id="176425828" data-gtm-yt-inspected-91172384_165="true" data-gtm-yt-inspected-113="true"></iframe>To be more specific, my “notes” are only played on the sound channel 2. Indeed, the 4 sound channels are shared for both sound effects and music. So, if you are playing a note on a channel, you can’t use it to play a sound effect at the same time. And, as each channel is somewhat “specific”, sometimes it may be preferable to use some channels for music only, while others channels may be reserved for sound effects. For example, the “scratching” sound that you hear whenever the sheep get attached to a flying strap is played on channel 4 (noise). As it’s a very common sound in my game, I decided to avoid using this channel for music. Same goes for channel 1 that I used for all the other sound effects. As my music skills are very limited, I choose not to use the waveforms of channel 3, and to focus on the tones of channel 2 instead.
2) GBT Player & Carillon Player
Many homebrew games use the “custom music player” solution. Hopefully, this is not the only one available. There is a library called GBT Player that can convert music modules (in Impulse Tracker “.it” format) to play them back on a Game Boy. Of course, there are a lot of limitation regarding the sample sizes, the number of channels and the notes effects that you can use. But still, it allows you to compose real music in an actual music tracker, such as OpenMPT, and play it back on a Game Boy. The cherry on the cake is that this library only consumes about 7-8% of the Game Boy CPU resources, leaving a lot of processing power to run the rest of the game. Moreover, it’s very easy to integrate it into your code, whether you choose to program your game in C with GBDK or in assembly with RGBDS. Carillon Player is a good alternative to GBT Player, although you’ll have to use Carillon Editor to compose music instead of your favorite tracker program.