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
- The state machine in the main ARM9 binary decides "we're now in mode X."
- It looks up overlay X in the overlay table at ROM offset
0x8DE00. - That table row says: load file
overlay/overlay_NNNN.bin, decompress if needed, and copy it to addressram_addr. - If the destination RAM slot already holds a different overlay, that overlay is overwritten.
- 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:
- Stay byte-exact in length β replace 4 bytes with exactly 4 bytes, never more β so nothing else in the overlay shifts; or
- Recompute every pointer in the overlay that pointed past the edit, which means re-resolving the relocation table by hand.
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
Related
- The overlay system β RAM slots, controller/body pattern, persistent engines.
- Per-overlay catalog β one descriptive page per overlay.
- Memory map β where overlays land in main RAM.
- BLZ & the plaintext-ARM9 trick β the executable-code compression used on ARM9 and overlays.
- ARM9 menu pool β the 52 menu-string slots embedded in ARM9 and adjacent overlay slots.
- Bubble vs window β the dialogue page renderer (overlay 157), how it picks between bubble and bottom-window styles, and the 32-character bubble cap.