Skip to content

perf(vapor): ship the GB font as 1bpp and expand it at upload - #393

Open
lfkdsk wants to merge 1 commit into
pocket-stack:mainfrom
lfkdsk:fleet/vapor-gb-font-1bpp
Open

perf(vapor): ship the GB font as 1bpp and expand it at upload#393
lfkdsk wants to merge 1 commit into
pocket-stack:mainfrom
lfkdsk:fleet/vapor-gb-font-1bpp

Conversation

@lfkdsk

@lfkdsk lfkdsk commented Sep 8, 2026

Copy link
Copy Markdown
Contributor

What

Same treatment as the GBA font, for the Game Boy target: emit vp_font_tiles as 1bpp and expand it into tile RAM at upload instead of shipping the expanded table in ROM.

Measured

before after delta
todo.gb occupancy 11383 B 9140 B −2243 B (−19.7%)
sdcc _CODE 9335 B 7092 B −2243 B
_DATA 1143 B 1143 B 0

5 builds per side. The saving is entirely ROM _CODE: the table shrinks 3040 → 760 B, the expansion loop costs 37 B, and no state RAM is traded.

Correctness

  • The 3040 bytes reaching GB VRAM are unchanged: a new test boots todo.gb in libmgba, reads tile data at 0x8010 off the bus, and matches a reference expansion derived from FONT8 alone. It passed on the unmodified base first, so it is a real oracle.
  • GB parity does not cover font pixels either: two single-bit runtime mutations (plane-1 flip, dropped style-1 complement) leave parity 6/6 green while failing 2 of 3 new gb-font tests.
  • Generated C is byte-identical for GBA, NES, ESP32 and Playdate (exactly one changed line in the GB output); todo.gba and todo.nes keep their baseline hashes.
  • bun test vapor/tests/: 76 pass / 0 fail (was 71), including four-way parity.

Provenance

Autonomous fleet run: Scout-measured candidate (report on the fork branch lfkdsk/pocketjs:fleet/scout-artifact-size), Builder implementation, one cross-family review that independently rebuilt and re-ran the mutations.

🤖 Generated with Claude Code

@lfkdsk
lfkdsk force-pushed the fleet/vapor-gb-font-1bpp branch 2 times, most recently from 10de1bc to 6544217 Compare September 8, 2026 21:18
The DMG bakes two glyph styles (ink shade 3 on paper 0, and its inverse)
into 2 x 95 x 16 B of 2bpp interleaved tile data, but those 3040 B hold no
bit FONT8's 760 B does not: shade 3 sets both planes and shade 0 clears
both, so every row is `bits, bits`, and style 1 is style 0 complemented.

Emit the 1bpp bitmap for gb, as esp32 and playdate already did, and let
upload_font reconstruct both styles while writing VRAM. todo.gb used bytes
11383 -> 9140 (-2243, -19.7%); sdcc _CODE 9335 -> 7092 B, _DATA unchanged.
The bytes reaching VRAM do not change.

vapor/tests/gb-font.test.ts boots a real ROM in libmgba and compares all
3040 B at 0x8010 against a reference expansion derived from FONT8 alone; it
was written and passed against the unmodified base first. Parity misses
both runtime bit-flip mutations -- the GB rig reads background-map tile
indices, never tile pixels -- so this test, not parity, guards the change.
@lfkdsk
lfkdsk force-pushed the fleet/vapor-gb-font-1bpp branch from 6544217 to e22f4bb Compare September 8, 2026 21:20
@lfkdsk

lfkdsk commented Sep 8, 2026

Copy link
Copy Markdown
Contributor Author

Rebased onto current main (061c6be) and dropped the fork-only base commits, so the PR now contains only its own commit(s). bun test vapor/tests/ on the rebased branch matches main in this environment: everything passes except the NES parity build, which fails identically on unmodified main here (local ld65/cc65 library mismatch).

@lfkdsk
lfkdsk marked this pull request as ready for review September 8, 2026 23:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant