Overlay knowledgebase

DS game only γ¨γ‚“γŒγ‚Šγƒœγ‚¦γ‚·γ¨γŠγ—γ‚ƒγ‚Œγͺまほう぀かい The field guide documents the DS game's internals.

The plain-English shape of the 180 ARM9 overlays β€” what they are, how they load, and why their edits are delicate. The full per-overlay catalog lives at /field-guide/how-the-game-works/overlays/.

This page is the "what's an overlay" explainer. The overlay system page covers the technical specifics (RAM slots, controller/body pattern, persistent engines). The full per-overlay catalog β€” one page per overlay, with descriptive role, notable functions, container references, and embedded JP strings β€” lives at the per-overlay catalog.

What is an overlay?

The DS has very little RAM (4 MB total) and Tongari Boushi is a fairly large game. To fit, the engine breaks its code into overlays: chunks of compiled ARM9 code that are loaded from the cartridge into a shared RAM region only when they're needed. When the player moves between game modes β€” exiting a shop, opening the mail box, entering the cooking minigame β€” the engine evicts the current overlay and loads the next one into the same address.

There are 180 overlays in this game. A handful are resident the whole time the game is running (the 2D rendering engine ov137 is the big one); the rest swap in and out.

How an overlay loads

  1. The state machine in the main ARM9 binary decides "we're now in mode X."
  2. It looks up overlay X in the overlay table at ROM offset 0x8DE00.
  3. That table row says: load file overlay/overlay_NNNN.bin, decompress if needed, and copy it to address ram_addr.
  4. If the destination RAM slot already holds a different overlay, that overlay is overwritten.
  5. The new overlay's entrypoint runs; it sets up state, registers event handlers, and yields back to the main loop.

Compression β€” BLZ for ARM9, code-LZ for overlays

The main ARM9 binary at ROM offset 0x4000 ships BLZ-compressed (Nintendo's backward-running LZ variant used for executable code). Most overlay files at overlay/overlay_NNNN.bin ship with their compressed_flag set, meaning the engine runs a code-LZ decompressor on them at load time. The BLZ & the plaintext-ARM9 trick page covers the format details, the in-place backward decompression, the NitroSDK module-params layout, and the "flip CompressedStaticEnd" trick used to load ARM9 as plaintext.

The same idea applies per overlay: flipping the per-overlay is_compressed bit in the overlay table to 0 and storing the body uncompressed makes the engine load the overlay as plaintext. Both shapes are interchangeable on-disk and the engine handles either; a re-LZ-compressed body via ndspy.codeCompression yields the closest on-disk match to the Konami original.

NitroSDK validation markers β€” none present

Retail DS binaries from some publishers carry the NitroSDK code footer markers (0xDEC00621 "NitroCodeBE", 0x2106AED5 "NitroFooter") used to validate plaintext ARM9 modules at load time. Konami stripped or never emitted them on this ROM β€” all 180 overlays scan clean for both markers, and the main ARM9 plaintext doesn't carry them either. This is normal for retail DS titles where overlays ship BLZ-compressed; the markers wouldn't survive decompression intact anyway. The patcher does not need to re-emit them.

Why editing overlays is delicate

Container files in data/* (dialog strings, item tables, magic glyphs) are read at runtime through a content cache that does not care about their precise byte layout as long as the file format is valid. Overlays are different: an overlay is compiled code. It has hard-coded addresses, fixed-stride data tables, and pointers into .rodata that were resolved at link time. Any byte-level edit to an overlay has to either:

Get either of those wrong and the game crashes the first time the overlay is loaded. That is the practical constraint behind any tool that emits new overlay bytes β€” each edit is tracked as a specific (file, offset, before-bytes, after-bytes) tuple, and the tool refuses to apply if the original bytes don't match the expected shape.

Per-overlay catalog

One descriptive page per overlay. All 180 overlays have been put through a Ghidra-based reverse-engineering pass and have their own page with the function listing Ghidra found, the container files each overlay references, and any Japanese strings baked directly into the overlay binary. Jump to the per-overlay catalog; the landing page is searchable and filterable, and each row drills into the per-overlay detail page.

Related