Skip to content

Squashing bugs, linking objects, building faster

Pre-release
Pre-release
Compare
Choose a tag to compare
@github-actions github-actions released this 30 Jul 23:27

Play this version directly in your browser

This release fixes some bugs, changes some internals, and totally replaces the build system. There's no new gameplay this time, but the structural changes from this round are necessary to keep things organized as the project gets larger.

Bugs squashed

Garbage tiles

animation showing two gameboy screenshots of kitchen. first frame shows random tiles loaded on the left side of the screen (incorrect), while the second shows the same region black (correct).

Tiles were previously loading in the blank spaces off the map to the left and right. You can see this in this gameplay quote, or you can reproduce this yourself if you play the last release: walk left until you hit the counter, walk right until you hit the other counter, then left again, then right again, then left again. You'll see some garbage tiles loaded. This was such a tricky off-by-one error that I didn't trust myself not to make it again, so I decided to change the way that the loaded parts of the map are represented (now as a signed byte for each horizontal side) so some extra accounting could be eliminated (map_oob, MAP_OOB_LEFT, and MAP_OOB_RIGHT).

Transparent white sprites

animation showing two gameboy screenshots of kitchen with a cat character with white patches. first frame shows the patches transparent (incorrect), while the second shows them opaque (correct).

Sprites with white patches started showing up as transparent shortly after I reworked the build system. I was convinced the issue was related to the way the file was being loaded into memory, but this wasn't true. It turns out I had bypassed a previous image processing step which replaces white pixels, which rgbgfx sees as transparency, with very very light grey pixels, which rgbgfx rounds up to white. The fix was simple, though hard to find.

Animation start/stop

Last but not least, the player character can now stop its walking animation when not moving. Amazing! This sets things up nicely for directional movement, which I hope to implement in the next release.

Internal changes

Linker

The linker is now responsible for bringing all the snippets of code together into the final ROM. Previously, code snippets were all being included into in one big assembly file which was just handed to the assembler, and then on to the linker. Now there are many more, smaller object file targets which are all linked together. If this project were much bigger, this would save some time otherwise spent unnecessarily re-assembling sources that haven't changed, but since this project is so small, this isn't a real consideration. Instead, as available ROM space eventually grows thinner, this will allow better use of the memory map and prepare the migration to banked ROM. Splitting into sections also allows the use of LOAD commands, which simplify loading code into RAM (necessary for DMA and for tricky inner loops that use self-modifying code).

Linker parser spec

Kaitai web IDE parsing main.o

To test and debug the object files passed to the linker, I wrote a kaitai parser spec for the rgbds(5) linker file format. Kaitai is an open-source parser generator, taking in a specification that describes a binary file format and producing code which can parse that format. One cool thing about kaitai is that you can use their Web IDE to play around with the parser and inspect object files without having to set anything up locally.

To try it out:

  1. copy the parser spec I wrote (rgblink.ksy) into the Kaitai web IDE
  2. unzip this rgbds object file and drag the resulting main.o to the kaitai browser tab
  3. poke through the "object tree" below the spec to browse the parsed contents of main.o

Kaitai can even produce graphs showing the structure of the rgblink object file format:

kaitai-generated graphviz graph showing format of rgblink object files

Build system

cropped graph showing build dependencies, jobs, inputs, and outputs

The ninja build system is now building the ROM. This open-source build system is focused on correctness and speed rather than feature completeness, and the build specification it uses is intended to be generated by a script written for the needs of the specific project. In the case of undercooked, it's a simple jinja2 template that becomes a ninja build file after some simple globbing. I've tried to avoid code generation in this project, but ninja's two step build system makes for very fast builds, easy multi-output recipes, easy dynamic dependencies, all without having to hack around the glaring limitations of something like GNU Make. As a bonus, it can spits out pretty build graphs with ninja -t graph in dotviz format (click the cropped image above to see the uncropped version).

RGBDS syntax changes

RGBDS, the open-source gameboy assembler/linker/formatting toolchain we use, pushed a surprise update which changed the syntax of labels: namely, it's a little more strict now in its v0.5.1 release than it was in v0.4.0. This used to be valid:

RUN_DMA_HRAM_SRC
        ldh [c],a

but now a colon is required after the labels:

RUN_DMA_HRAM_SRC:
        ldh [c],a

That's everything that's new in this release. Stay safe, and keep your eyes open for another undercooked update Soon™