24 — The Fix Was Already There

Some bugs die quietly. The investigation is the noisy part.


Still Yellow

The fix shipped. The screenshot came back yellow.

Sat with that for a moment. The palette file was correct. The ROM binary confirmed it: offset 0x469A9C, first two bytes, 00 00. Black. Not the E0 17 that was there before. The fix was in the ROM.

Still yellow.


Systematic Elimination

Started from scratch. When the answer you expect and the screen you see disagree, you trust the screen.

Wrote a Python composite renderer — offline, no emulator. Read the four BG layers from disk, applied palette data, rendered each layer, composited them in priority order, output a PNG.

The result showed black background, Pokémon logo, box art. Not yellow. Not anywhere close to yellow.

That is useful information. Either the renderer was wrong or the user was looking at something the renderer was not.


All Four Layers

Went through them one at a time.

BG3 (border): all 640 tilemap entries reference tiles 1–3. Every pixel in those tiles is zero. In 4bpp mode, pixel zero is transparent. BG3 is invisible. Not the source.

BG2 (copyright/press start): 76 non-zero tilemap entries. Small area at the bottom. Not the source.

BG1 (box art flame): 134 non-zero entries, all using palette slot 13, tiles 1–134. Flame and fire colors, dark reds and teals. Not yellow, not full-screen.

BG0 (8bpp logo, hscroll=222): the only layer that could cause full-screen color. Sky tiles at rows 5–7, tile indices 175–245. Decomposed them. Counted the pixels.

Sky tiles: 80% transparent, 6% blue, 4% yellow, 10% other dark values.

With palette entry 0 set to black, those transparent pixels show black. The non-transparent ones show a handful of blue and dark pixels mixed in with a few yellow specks from the logo palette. Nothing that produces a yellow screen.

The Python render was right. The composite looked correct.


The Answer

No new code bug. No second root cause. No hidden palette load corrupting entry 0 after init.

The fix from the previous session was complete and correct. The 21:47 build had it. The 03:47 clean build has it. Both ROMs have game_title_logo.gbapal[0] = 0x0000.

The user’s 03:18 screenshot came from a stale mGBA session. mGBA loads the ROM once — it does not watch for file changes. When the ROM on disk changes, mGBA keeps running the old copy in memory. Closing and reopening, or File → Load ROM, picks up the new build.

That is not a bug. That is how emulators work.


What the Investigation Found Anyway

The composite renderer confirmed the BG0 sky tiles (rows 5–7, approximately screen rows 40–63) contain the original FireRed sky background at tile indices 175–245. Those tiles were designed for a blue-sky palette. In our palette, the same indices contain logo yellow at entries 2–37. Four percent of sky tile pixels fall on those yellow entries.

Four percent is not full-screen yellow. It is a handful of scattered pixels in the rows below the Pokémon logo. With palette[0] = black as the backdrop, the sky area shows mostly black with a few colored specks. Acceptable.

If it ever looks wrong: zero out the sky tile references in game_title_logo.bin.lz for rows 5–7. That is the surgical fix for a problem that currently does not exist.

The existing test suite catches the things that do matter: palette[0] correct, tilemap bounds valid, defensive guard present in both init paths. Sixteen checks total, all passing.


By the Numbers

Metric Value
Commits 0 (investigation only)
Copilot requests 3
Tool executions 87
Sub-agents spawned 0

The hardest bug to find is the one that was already fixed.

Back to README