The technique in one box
Every earlier rung hosts new bytes inside something the game already loads - the executable's gap (tier E), an overlay's dead space (tier F). A payload that targets free RAM no overlay covers has no host, so the disc must gain a loader: the payload is parked in annex sectors the game never reads, and a small injected stub streams it to its address at load time using the game's own CD reader. The payload itself ships verbatim - nothing is reassembled or relocated - which is also what makes this the rung for carrying someone else's mod.

At a glance

Payload
ZetaPhoenix's 3,764-byte block at 0x801FD000: trigger tables, fifteen names, four MIPS routines, 34 animation edit-lists
Parking
Two 2,048-byte sectors in the DMY.DAT annex (dev-fixture space the game never reads); disc size unchanged, PPF-safe
Loader
12-instruction stub in verified-dead arena 1 (0x8007AE00), entered from battle init; calls the game's own reader FUN_8005E4D4, then BIOS FlushCache
Hooks
Fourteen same-size words across ten sites - the author's own hook set, installed verbatim; the battle-load detour is the carrier's one addition
Edit class
In place throughout (annex sectors already exist)
Confidence
Confirmed - interpreter oracle over all 30 trigger chains + emulator probe of the live CD read
Oracle
super_arts_pack_real.rs

What the payload does

A retail Super Art is a find-and-replace: the queue builder tokenizes your arrow chain into a byte queue of action constants on the battle actor (actor+0x1DF), and the applier (FUN_801EF9E4) scans a five-row-per-character trigger table over the finished queue - a matching tail is overwritten with that row's replace string, the 0x1A special starter plus the Super's finisher constants. The pack widens exactly this mechanism: its own tables carry ten rows per character (rows 0-4 are the retail rows byte-for-byte; 5-9 are new), plus routines that give the new rows names, hit counts and animations. The cleverest part is the animation scheme: the added Supers reuse seventeen existing action constants, and a routine applies a per-constant (offset, values) edit-list over the live art record on the way in - and its inverse on the way out. A self-reversing patch over game state, carrying no copied game data.

Free RAM is a claim that needs evidence

The payload's home, 0x801FD000, is above everything the game loads - and "above everything" is exactly the kind of claim this project has been burned by before ("zero is not dead"). Three measurements back it:

  • No overlay covers it: slot A - where the battle overlay PROT 0898 loads - ends at 0x801F7018, and nothing loads higher.
  • Across the project's save-state library - 60 states, battles included - 0x801FD000..0x801FE000 is all-zero in every one.
  • The deepest observed stack use is 0x801FE420, still 1,388 bytes above the block's end.
The top of RAM: the payload sits in a gap no overlay covers and no observed state touches top of main RAM, 0x801C0000 .. 0x80200000 battle overlay - PROT 0898 (slot A) 0x801C0000 0x801CE818 0x801F7018 payload · 0x801FD000 (+3,764 B) persistent effect / world state (must never be zeroed) deepest stack use seen: 0x801FE420 (60 states)
The rejected alternative - growing PROT 0898 to cover the address - would zero 0x801F7018..0x801FD000 at every battle load, wiping the persistent effect state the field overlay leaves there.

The loader: annex sectors plus a streaming stub

The payload is written into the DMY.DAT annex - a bump allocator over sectors of dev-fixture data the retail game never reads, so the disc keeps its exact size and the whole install stays a PPF. A 12-instruction stub in the executable's verified-dead arena streams it in at every battle load:

The delivery path: annex sectors, the battle-load stub, and the resident payload DISC SCUS_942.54 + stub + 4 hook words PROT 0898 overlay + 10 hook words DMY.DAT annex payload · 2 sectors RAM, at battle load battle init FUN_80055B6C detour @ 0x80055DBC - after the overlay's own CD read loader stub @ 0x8007AE00 (dead arena) FUN_8005E4D4(2, lba, 0x801FD000) + FlushCache payload, resident @ 0x801FD000 tables · names · routines · animation edit-lists CD read in battle: the hooked retail sites jump into the payload's routines, each returning to the word after its hook
The stub runs in the same idle-drive, between-frames context as every retail load - it is entered one instruction after battle init's own wait for the overlay CD read. FlushCache matters: the payload is code, and the R3000's instruction cache is not DMA-coherent.

The hooks: reading them out of the payload

The pack's fourteen hook words across ten sites are the author's own, installed verbatim. Before he published them, though, most were reconstructed from the payload alone - and the method generalises to any payload written in his style. Each routine replays the exact retail instruction it displaces and ends with a jump back to the instruction after its hook, so the routine pins its own site; the stride retarget is forced by the payload's table strides meeting the applier's own address arithmetic (one doubled register turns t5×65 / t5×80 into the 10-row strides).

The instructive part is where reconstruction and author differed. Everywhere the payload could pin a word, the two matched. The deltas sat exactly where the payload is silent - and one was a genuine miss: the row loop's exit seed, a li a1,5 the match arm uses to fall out of the scan, which must widen to 10 alongside the loop bound. Neither word is referenced by any routine, so the payload cannot pin them; without the seed, every match resumed scanning against the already-rewritten queue (end-state identical on his tables, a third more work per match). The law this leaves behind: when reconstructing hooks from a payload, every un-pinned loop immediate is a place to suspect a paired edit.

The full hook table, the delay-slot relocation trick his queue hook uses, and the loop-immediate pairing are laid out in the randomizer reference.

The authorship boundary

Carrying a third-party mod draws a line the earlier rungs never needed: the payload is the author's work, and the carrier's whole job is delivery without alteration. The block ships as a data file installed byte-for-byte; the hook words are his; the loader stub is the carrier's one addition, because a RAM cheat had nothing to load. The patcher refuses rather than adapts: every hook site must carry its exact retail word, the payload's retail rows must match the disc's own trigger tables byte-for-byte, and the embedded block's size, routine entries and baked return addresses are checked against the hook map - so a swapped-out blob can never install against hooks derived from a different one.

The same boundary governs his follow-up arts name-length fix (shipped as part of the pack), with one documented exception that proves the rule: his fix parks its routine in an all-zero run inside the executable's SsAPI sound-table window - the exact cluster where this project once learned that zero padding between live tables is not dead space. The carrier installs his instruction stream unchanged but parks it in read-watch-verified arena space, moving only the hook's jump target.

How we know

ClaimEvidenceReference
0x801FD000 is free RAMAll-zero across the 60-state save library; slot A extent from the based overlay images; stack low-water from the same statesstatic-overlay-pipeline
Every hook site carries its known retail wordApplier + queue builder + banner routines disassembled at their recovered bases; the plan fingerprints all ten sites before writingbattle-action
The pack actually firesDisc-gated oracle: the patched applier's real instructions, with the payload read back out of the annex, run in a MIPS interpreter over all 30 trigger chains - added chains rewrite the queue and index the right name; retail chains come out untouchedsuper_arts_pack_real.rs
The CD read works livePCSX-Redux probe: boot the patched disc, walk into a random encounter, check 0x801FD000 was clear before and holds the payload at the stub's returnpcsx-redux-automation
Nothing else movedByte-diff oracle: only the planned words and the annex sectors differ from the clean image, every touched sector stays EDC-valid, and a rerun is byte-identicalsuper_arts_pack_real.rs
Details: adding a tier-G mod

Park the payload with DiscPatcher::annex_blob (whole sectors, returns the LBA the stub bakes in). Prove the target RAM free the same three ways: no overlay covers it, all-zero across the save-state library, clear of the observed stack floor. Enter the loader from a load path that already waited for its own CD read, call the game's own reader, and FlushCache if the payload is code. Fingerprint every hook word; if the payload is someone else's, install it verbatim, check any rows it duplicates against the disc's own tables, and keep the authorship boundary in the docs as well as the code.

See also