On Game Boy development

I've been wanting to do more creative writing [1], and I thought it would be fun to do some game development too. I forget how it came up, but I ended up trying to learn game boy development. I'm (very slowly!) working through the book Game Boy Coding Adventure. It's been derailed somewhat by work, but the work I've been doing has been fun. The game I'm working on now is called Kenshi, and is something of an RPG telling the story of a would-be samurai.

I ran into a problem where the title screen I wanted to display would either just not show up, or it would show up as a garbled mess of pixels. To understand why, I need to explain how graphics work - at least, this is my understanding right now, and it's entirely based on the DMG [2] and might be different on the GBC.

[1]I have two writing projects, one sci-fi and one fantasy, that have been under perpetual development.
[2]DMG means Dot Matrix Game, and is the "proper" name for the original grey-brick Game Boy.

On Game Boy graphics

The DMG's memory includes 8K of video RAM. Part of this ram is organised around what are called tiles (which you get 384), and tilemaps. A tilemap is a list of indices into tiles, and there's some finer points about which one you select. However, to begin with, I had one background image that I wanted to show. To do this, I needed to use some tooling to break that image into 8x8 tiles. Generally this leaves you with two files: a tileset, which contains all the tiles, and a tilemap that points to those tiles.

The way that I'm doing that right now is through the use of sections and a directive to import binary data into memory during compilation (which is then copied into the VRAM as needed).

section "graphics_data", rom0[GRAPHICS_DATA_ADDRESS_START]
incbin "tileset.chr"
incbin "background.tlm"

The reason I was getting garbage on the screen is that the generated tileset.chr was too small: 384 tiles (at 8x8 2-bit palette indices means each tile is 64 bits or 16 bytes) should be 6144 bytes. For whatever reason, the tilemap was only generating 3104 bytes. The background tilemap was then being placed mostly in the tileset memory. My first hack to verify this is what was happening by creating separate sections for both. I landed on adjusting the build process to pad out short tilesets with null bytes, so the above ended up working.

Running the ROM in a gameboy emulator. Working on the game.

Tags: , , ,