Falsified RE readings - do not re-walk
Every reverse-engineering project accumulates readings of the bytes that looked right, were believed, and turned out wrong. This page indexes Legaia's: what each reading claimed, the verdict, and a link to the reasoning - why it was convincing and what killed it. Check here before committing to a reading that looks obvious.
What a falsified reading is, and why it is kept
A reverse engineer looks at a routine or a table and forms a story about what it does. Most stories survive the disassembly or a runtime capture. The ones here did not - but each was plausible, usually backed by real evidence read the wrong way, and the shape of the trap recurs in other subsystems. Rows are terminal: new evidence moves a row back to open RE threads, never edits it in place. The answered questions are on settled threads. Each full write-up - why it convinced, what killed it - is at its anchor in docs/reference/re-do-not-re-walk.md.
Three traps behind most rows
- VA aliasing. A bare virtual address is not an identity. The game swaps different overlays into the same RAM window (
0x801CE818for slot A,0x801F69D8for slot B), so a dump labelled by address can be a different function entirely. See the overlay band. - Ghidra's collapsed switch. A jump table's arms render in the decompiled C as bare
breaks or fakeFUN_xcalls, inventing opcode semantics the raw table does not have. The cure is the disassembly, never the C (Ghidra workflow). - The over-reading entry size. A PROT entry's size is the sector gap to the next entry. An older expression read past that end, so a "field at offset K" was really the next entry (PROT.DAT).
World map / kingdom bundles
Kingdom bundles and the slot-4 animation bank.
| The reading that looked right | Verdict | Write-up |
|---|---|---|
| The overworld walk camera slides between two zoom anchors | it is the field zone camera; the anchors were two region records | doc |
| Slot 4 is a GTE vertex pool walked by an unpinned "cluster-A command stream" | no stream exists; the entries are rigid transforms of the scene's animation bank, and the capture's return addresses sit inside the animated-mesh renderer | doc |
| Slot-4 → cluster-A converter site | falsified | doc |
| World-map outline / coastline reading | falsified | doc |
Battle / arts / level-up
Battle load, the action state machine, damage, the HUD, Muscle Dome, boss softlocks.
| The reading that looked right | Verdict | Write-up |
|---|---|---|
FUN_8004DC68 dims bodies around the acting actor | it ghosts bodies near the camera, and a caster's allies during magic | doc |
| Party animation entry 8 is a recover clip that steps backward | it is the downed kneel, with no root motion; the backward speeds belong to the knockdown, block and flinches | doc |
ctx[+0x16] has one writer, the War God Icon refill | two: the refill, and a per-stage bump that fires only once the counter is non-zero | doc |
The 0x801F0518 special-trigger store belongs to the auto-combo tail | it heads the auto-fill arm, just past the status veto | doc |
| The auto-combo pool arm halves its AP budget under the AP-Used-Down bit | the only test of that bit halves the art tail's per-arrow Spirit cost | doc |
The art insertion tail's first draw is rand() % 10 | rand() % 5: the reciprocal is shifted once more | doc |
Battle context byte +0x25 is the round counter | it counts skipped actors; the round counter is elsewhere | doc |
| A battle routine pays a captured monster's item into the bag | it refunds an item a fallen fighter had committed, and the address is a mis-based print | doc |
| The commit-confirm Reselect returns to the first party member | it steps back one member, onto the last one able to act | doc |
ctx[+0x26] is a boss phase counter and ctx[+0xD] is a dead store | the level-up banner element id and the camera angle variant | doc |
0x801E3A20..0x801E3A64 is the Miracle continuation | the War God Icon Attack x2 second pass (one of ctx[+0x16]'s two writers) | doc |
| The Miracle marker is armed by an input recognizer | no such writer; one sb in the corpus, at battle-actor seeding from an equipment byte | doc |
DAT_8007BD10 is a per-slot control-mode byte | the slot -> roster character id table | doc |
The spell record's +0x01 byte is undecoded, and the player Seru block shares 0x32 / 0 | decoded all along (a consumer gap); Vera is 00/03, Orb 01/04 | doc |
| The slot-B module band shares a library tail | mastering residue: every module image ends in another image's bytes at the same file offset, nine of them in PROT 0899's | doc |
| The world-map slot-4 landmark meshes are the consumer of the lit prim handlers | slot 4 is the animation bank, and exec breakpoints on all four handlers return zero on the overworld while its real handlers fire | doc |
The slot-B band: no capture-class jal exists; 0957's trampoline is unreached; a module is two functions with no internal jal; 0965 is a shifted 0967 | all four fell to the whole-band dump: a third entry table, arm 22, 196 functions across 25 images with internal calls, and 0965 = Doomsday | doc |
| The slot cabinet is in neither the art pack nor any prim a traced slot function emits | PROT 1200 has three descriptors; the second is the cabinet TMD, drawn by the shared renderer | doc |
| A phase-gated effect draw is the candidate for the arena's object-1 dust decal | ordinary backdrop geometry the SCUS loader trims unless _DAT_8007B64B is set | doc |
_DAT_8007BD84 is a mode word the melee kernel branches on | an effect-instance handle; its one non-zero writer is the Cort "Mystic Shield" stager, and the grunt's s7 gate is a real condition | doc |
Move-VM op 0x2F extension dispatcher - per-overlay copies? | one copy, field overlay 0897 only | doc |
"FUN_801F3894 spirit/magic damage roll" (state-0x3D chain caller) | VA-aliased dump | doc |
The battle-intro enemy-name banner is one of the top-seated 0x0303 placement records, width overwritten at runtime, slid park-to-live | the composer FUN_801D9D3C spawns its labels with immediates at y = 48; no table read, no slide; the width overwrite is record 68's | doc |
A level-up refills the live HP / MP pools (the captures' "settle" phase at +0x106 / +0x10A) | the settle write is the battle-end resync; both currents stand still | doc |
| A streamed signature-attack cast module cannot run from a party slot because "a party actor has no monster block" | it has a first-class equivalent | doc |
| An art whose attack camera films flat has the wrong arm, so the fix is to select a better-choreographed one | every arm is timed for a ~20-frame swing, and not one is spare | doc |
| Navmesh / per-scene navigation data | falsified | doc |
Op-0x4E sub-ops 4..8 "absolute jump" / "rand -> next PC" readings | all sub-ops 0..9 are the 7-byte compare-and-skip | doc |
801d58f0 / 801d63b0 as single shared port blockers | VA-aliasing artifact | doc |
Charm battle softlock = unbounded reroll in FUN_801E7320 | cannot spin from any reachable state | doc |
Gaza 2 0x51 park: clamp asymmetry as a standalone retail generator | amplifier only; its exhibit was a phased mid-action state | doc |
Gaza 2 0x51 park: the Final Heal revive lands "at the worst possible moment" (mid-drain) | on the Gaza 2 move set (12/12 revives found the accumulator already drained | doc |
| Muscle Dome as a card battle with a per-fighter "score out of 108" | it is a 4-turn battle; the readout is the opponent's HP percentage | doc |
| Muscle Dome awards a Seru on a win | a leg pays nothing; a contest pays casino coins | doc |
FUN_801DBC30 blits the party panels' name plate | its page + CLUT resolve to the etim red cross-out X | doc |
| The retail party HUD carries HP / MP gauge bars | no bar primitive in either readout's packet run | doc |
Screen-element kinds named by what sits at their seat (0x32/0x33 = "the roster panels") | naming by seat named the wrong record | doc |
| The battle message banner is "a gold border over a blue interior" | border only - no fill primitive under it | doc |
FUN_801E2524 / FUN_801E2650 are a full-screen flash / fade ramp | they are the Arts announcement banner | doc |
"The port never latches the art id, so actor[+0x1DB] reads 0x00 all fight" | it latches 0x01, then 0x0D, then 0x0C | doc |
"The port's 0x51 Done-band residency is unbounded" | bounded at ctx[+0x6D8] = 0x3C, as retail | doc |
| "The sparring tutorial reopens the command session, so the cursor cannot move" | the cursor walks 0..5; a waiting prompt box parks the tick | doc |
| An action returns its combatants to their authored formation seats | retail leaves them on the ground the action ended on | doc |
The battle per-actor draw FUN_80048A08 runs 35-64x per frame during a summon | once per live actor per rendered frame - never above 2 in the solo fight the figure came from. The group walk is inside the call | doc |
| The slot-B cast band applies damage with one shape, seat-0 hardcoded | true of PROT 0958 / 0959 / 0960 only; the capture-class ticks clamp per victim off the caster’s own +0x1DF, and two images sweep a row of seats | doc |
| PROT 0927 can never kill, so it needs no death path | 0927 is a multi-seat stager - nothing in its image subtracts HP, which is what the reading measured. The damage lands in the tick it stages, clamped with sltu at 0x801F6A84 | doc |
ctx[+0xD] variant 2 stamps a 0x400 camera roll | it is the translation TR.y. The byte is two bits, not an enum, and nothing in either arm writes a Z angle | doc |
The Spirit halving flag is a battle-actor +0x16E bit | it is the character record’s +0xF8 bit 0x800 - accessory passive 0x2B. A per-battle bit could not survive the save, and this one does | doc |
A dome direction swing takes its damage from FUN_801E09F8 → FUN_801DD0AC | that chain carries a move-power index, and the dome’s four commands 0x0C..0x0F map to row 0, whose power bytes are zero - it would deal nothing | doc |
^H is an exception to the element-badge caret bijection | the census was over shipped monster names, and no shipped name carries ^H; the decoder has no special case at all | doc |
| No dome round raises the magic bit, so magic is not forbidden on the Master course | falsified twice - the original claim was right and this page's refutation of it was wrong. Every fact in the refutation holds; they are simply not the whole writer set, because the arena seeds the restriction word whole from three story flags. Enumerating one bit's writers is not enumerating the word's | docs |
| A cast is an AP spend, so the dome pennant's AP budget pays for one | a cast costs MP. Every other dome command is an AP spend, which is what made a magic command look like one more row of the same table | docs |
| A tick body that sweeps the whole actor row is a never-kill clamp | three more sweep it with the kill-capable shape. Pairing "whole row" with "clamped" made a kill-capable body read as safe | docs |
| Past its bound, a capture-class tick body reports done | it reports busy - the saved register is seeded 1 and only a terminal arm clears it. The port keeps done deliberately, as a disclosed anti-softlock divergence | docs |
| A body belongs to the module its dump filename names | one such body belongs to the neighbouring module. A dump filename prefix is not evidence of which image a routine is in | docs |
| The one SCUS call into the slot-B band runs only when a battle ends mid-cast | it runs on ordinary in-battle frames - the arm requires the battle-running byte, and fires 123 times on one victory ladder, all before the end signal | docs |
| One module carries no spawn record because its spawn sites load the pointer from a saved register | the sites are not that module's. Both sit in its inherited tail and point at two of the neighbour's records, past its own image end. "The parser cannot see it" and "there is nothing to see" predict the same output, which is what let the first reading stand | docs |
| PROT 0910 writes no HP, because its tick body carries no damage wrapper | the wrapper is in its callee - a per-image verdict taken inside one function extent is a boundary of the measurement, not of the module | doc |
A module's phase stores are its sb writes at a literal 0x279 displacement | most store through a formed pointer, so the displacement never appears; one module reads as zero phase stores that way and has six | doc |
| The cast band uses two damage-clamp shapes, and every tick body takes the kill-capable one | three shapes; the third caps at HP - 1 with an unsigned compare and neither kills nor heals, and all seven of its sites are tick bodies | doc |
| The wrapper's return is the damage a module applies | PROT 0910 shifts it right by two before the clamp, rewriting the same register the stores use - a port folding the wrapper value applies four times retail | doc |
| Nighto's resist roll forks the module's phase | only the kill roll does; the confuse leg’s phase store is unconditional and the resist roll merely suppresses the victim writes | doc |
Monster record +0x20 is a per-monster instant-death immunity byte | it is a double-width texture-page flag - its primary reader widens the model’s VRAM rect; three summon ticks borrow it as a "big model" proxy | doc |
| PROT 0941's Steal deals damage like its band neighbours | zero damage wrappers - the outcome is an inventory consume | doc |
| PROT 0943's MP-pair writer is the routine at the slot-B load base | that VA holds the body’s head table; head tables are not pinned to the base either | doc |
PROT 0940's arm blanks the caster's +0x0C | the base register is reassigned mid-body - it blanks seat 3’s action queue; a backward-only scan for the base is what misses a reused register | doc |
| The arena’s pre-test seed of the special-battle word is zero | it is 1: course 0 with no bans, which is a different thing from no seed | doc |
| The dome tally screen draws its four lanes, then the totals | the HP accumulator sits between lanes 2 and 3, at four brightness steps rather than six | doc |
The player-Seru wrapper sites pass the caster seat in a1 | the player half bakes the literal 7; only the capture half loads the field, so the two agree in retail and diverge the moment a port seats a summon elsewhere | doc |
PROT 0941’s Steal floors its bag draw while the battle context’s +0x11 reads 4 | the register is the present-party list in that module, not the context pointer, so the gate is "seat 1 holds roster character 4" - the split-bag condition. PROT 0941 makes no +0x11 access at all | doc |
| The cast-arm countdown drains by one scratchpad product shared by the band | the multiplier is per arm - the product, twice it, or once it - so two arms measured as constants 4 and 8 were 1x and 2x a frame byte reading 4 | doc |
| PROT 0950's arm 6 is frame-gated like its siblings | it has no gate at all; the countdown simply runs out, and a run two ticks short of expiry looks exactly like a gate firing | doc |
| PROT 0905 (Vera) leaves the HP restore to the band's shared heal fold | it writes HP itself as a second owner, so running both applies the heal twice per frame | doc |
| The slot-B stage selector has no writer | an absolute-address sweep really does find none, because every access is register-relative; the register-relative sibling finds fourteen | doc |
| The cue band's arm is the state its exit store names, and a spell can reach it | the arm is the Spirit / Item wait state - its exit store is the next state, one off in the direction that hides the entry - and only an item opens the band | doc |
| The battle selectable scans test an action-state byte where 4 means removed or done | it is a seat index - the table holds roster character ids, and 4 is the AI-companion seat; the state it implied is one nothing ever writes | doc |
| The dome's per-frame controller is a Muscle Dome match state machine | it is the round state machine every battle runs - one unconditional call site disc-wide, inside the battle frame driver; a routine named from the contexts its captures came from is named after its callers | doc |
| No draw site exists for the dome panel still | the emitter never materialises the pixel column: a textured primitive addresses video memory through a page index, so the constants in the code are page numbers | doc |
| A monster drop is granted per defeated enemy | falsified - at most one item per battle, with a three-in-four veto | doc |
FUN_801E91E8 is a Miracle-command lookup, and its neighbour byte routes into the capture cinematic | falsified - both belong to the killing-blow Seru absorb | doc |
| Baka Fighter's two "sprite archives" feed a mirrored sprite pass | falsified - they are animation-clip banks, and the pass is the special attack's 3D afterimage | doc |
Audio / sound driver
Sound driver, SPU transfers, audio-level globals.
| The reading that looked right | Verdict | Write-up |
|---|---|---|
| A scene-local music id plays a track from the scene's own block | the loader computes that index only to test for a change, then loads a fixed fallback track from the shared bank | doc |
FUN_8001FF58 releases a SEQ slot | it closes a sound bank | doc |
| A cue whose bank is closed plays from the battle bank | it is silent | doc |
| The Muscle Dome hub holds the battle sound bank | it holds the field bank; the battle slot is closed | doc |
bse.dat carries a second record family with a resident consumer | a neighbouring file's VagAtr rows left in the sector; and FUN_8001FA88's 0x37A load is the retail branch, not the dev one | doc |
FUN_8003EAE4's flags are consumed by an untraced CD driver | two of the three cells are write-only; the sequencer FUN_8003D764 dispatches on gp+0x928, which only FUN_8003D53C writes | doc |
bse.dat is loaded once at sound-init and held for the session; record +4 is a u32 taking only 0 and 2; the detector's "+4 under 0x100" gate is a value bound | battle init is its only caller; +4 is a u8 category rewritten per cue; the gate is a zero-trailer test | doc |
FUN_80068D94 as "SsSepOpen / SEP loader" (with FUN_80068B98 as "SsSeqOpen") | it is the VAB-open head | doc |
The entry that matches "[u32 format == 2][u16 spu_addr[256]], every address >= 0x8000" is monster.snd | it is summon.dat; monster.snd is a multi-bank VAB two entries away | doc |
Op-0x35 sub-op 9 is a queue, triggered by the next scene entry | it is a start behind an asset-load barrier | doc |
_DAT_8007B910 is the live screen brightness | it is the live audio level | doc |
| A routine called with a small id from a compact table in a battle context is a sound-cue dispatch | it is MoveImage, and the table holds VRAM columns. Anything reading those bytes as cue ids is reading a palette | docs |
| The blocking bank for the Seru cast voice is three streamed-audio files | it is seventeen; those three are the corner of the dispatcher's remap that no occurring cue id reaches | doc |
| The XA cue-duration table has 0x40 entries | 0x110, with live rows to 0x10F and interior zero runs that make a short read look like the end; the reader bounds nothing above the threshold | doc |
| The sequencer's pause freezes sounding notes | it keys them off - only the play cursor survives, so resume restarts into silence rather than into held notes | doc |
| The developer menu's BGM row cycles the music index | it plays the row - the cursor is stepped by the input half, a different routine - and installing the row's track id makes this the fourth writer of the request word | doc |
| The developer sound-test table's row i carries track id 2000 + i | one id has no row, so above the gap the cursor and the id it installs differ by one - a reader deriving the id from the cursor names the wrong track for 27 of the 71 rows | doc |
| The audio-trace oracle can converge on a save-state comparand | structurally unreachable: a freeze reports the residue of every cue since boot while a faithful score holds single digits, so the superset rule cannot be met | doc |
| A save state reports nearly every voice live because nothing keys them off wholesale | there is no idle phase to return to - the reader was counting every voice the state had ever keyed. Against the envelope level, retail holds 4 to 9 audible voices against the engine's 4 to 8 | doc |
| Retail's per-voice reverb mask routes four voices | that word is the SPU control register - the register blob is the hardware window verbatim - and the real mask reads all 24 voices on every frame | doc |
| The engine routes no voices through the reverb tank | both shipped hosts do; the oracles built their own bare SPU, so the instrument was measuring an engine nobody runs | doc |
| The engine runs about half retail's concurrent voices | two different pieces of music - a save's scene does not decide what it is playing | doc |
| The scene-stream installer's type-2 chunk is a VRAM upload, and it decodes compressed data | falsified - a SEQ install, and no arm decompresses | doc |
Title / boot / overlays
| The reading that looked right | Verdict | Write-up |
|---|---|---|
| The title menu has an Options row | it has two rows; retail reaches Options from the pause menu | doc |
FUN_801CE9C0 draws the publisher logos | it uploads them; the quads come from the descriptor table at 0x801F369C through FUN_801CFBB8 | doc |
| SCEA unfolds as a 2x2 grid of 32-row strips | retail draws two 64-row halves (descriptors 2 and 3); PROKION's halves are 127 rows | doc |
0x801D06E0 is a SHARED_TAIL with no jr ra | in PROT 0895 it is a 22-instruction leaf with its own frame and jr ra | doc |
0x801CE9C0 is an entry point in no image, so mode 16 is a stripped dev path | VA aliasing at the slot-A base: it is PROT 0895's publisher-logo pass, a clean entry at file +0x1A8 | doc |
| The title screen is loaded before the mode table is consulted (no row is named "title") | it runs under the CARD pair 22/23; main()'s pre-loop load is the boot init.pak 0895 | doc |
FUN_801DD35C lives in an unindexed PROT.DAT gap between entries 899 and 900 | no gap exists; the prologue occurs once, inside entry 0899 at +0xEB44 | doc |
The title sub-mode word lives at 0x801DD920, and 0x02 is a screen a player can see | 0x801DD920 is the instruction that stores it; the word is 0x801F0204, and the boot image raises _DAT_8007BB00 unconditionally so 0x02 is overwritten with 0x11 every time | doc |
| The attract sequence can be armed from any title sub-mode | one arm only - the countdown’s decrement and its _DAT_8007B83C = 0x1A underflow both sit inside 0x801DDB0C..0x801DDD94, sub-mode 0x10. Sub-mode 0x11 spends a different accumulator | doc |
There is exactly one master-mode-2 writer, at 0x801DFC00 | two - LaunchGame writes it at 0x801DFC00 on NEW GAME and LaunchFade at 0x801DFAFC on the load route. A sweep that stopped at the first missed the CONTINUE path | doc |
The title slider state[-0xEB4] is clamped to [0, 0x2C] | both arms converge on 0x2C from their own side (0x801DFC78..0x801DFC98 forces up, 0x801DFCA4..0x801DFCC4 forces down); there is no 0 floor, and the seeds are 0x100 and -0x16 | doc |
| The retail title screen runs under the first mode a boot trace sees | that mode is one frame of logo init; the title runs under the card mode. The chain is six stores, each written by the handler that hands off | docs |
| The Muscle Dome is not an OTHER-game mode | true of a round, false of the hub. One answer was being applied to two different screens | docs |
A mode-change edge clears three gp words | four. Three of them sit adjacent and read as one cleared block | docs |
Containers / placeholder slots
PROT entries, placeholder slots and stream layouts - most born of the over-reading entry size.
| The reading that looked right | Verdict | Write-up |
|---|---|---|
| PROT 0892 is a 12 MB LZS container, or a truncated DATA_FIELD stream | 33 sectors, and an asset::pack whose header words the stream detector read as chunk headers | doc |
PROT 1221 / 1222 have no loader, because no image names raw TOC 0x4C7 / 0x4C8 | the index is computed (s0 + 0x4C7); a literal-only sweep cannot see it | doc |
"Field-pack" is a format: magic 0x01059B84, a 97-entry schema, a shared ~91 KB template, a per-scene preamble | a DATA_FIELD chunk header (type byte + payload length) over an asset::pack of scene TIMs; the preamble was the over-reading entry size | doc |
The prescript entry carries a per-scene secondary header at the next 0x800 boundary | it is the next PROT entry's descriptor table at offset 0; 99 of 101 carriers have no bytes at that boundary at all | doc |
| Pochi-fill slots are stale mastering scratch, and some parse as valid TIMs | every slot is one 2048-byte sector; 0 of 266 carry a TIM | doc |
The world-map kingdom bundle is PROT 0085 / 0244 / 0391 | it is 0086 / 0245 / 0392 | doc |
The battle-form character pack holds seven atlases inside PROT 1204, the last truncated, with CLUT row 496 skipped | eight whole atlases in PROT 1205; 496 is the eighth, not a gap | doc |
The title TIM ships as three multi-bank duplicates in PROT 0888 / 0889 / 0890 | one copy, in 0890 at 0x14228 | doc |
scene_tmd_stream entries can hold two or more concatenated sub-streams (the "two-list" shape) | one stream per entry; 0 of 182 hold a second | doc |
| The stage backdrop renders as half a bowl because bytes are missing - mirror it to recover them | the half is authored; 182 of 182, and nothing is unread | doc |
| ...and therefore nothing completes it, so drawing a second copy is a regression | retail links two backdrop actors; the second carries a per-stage transform | doc |
| PROT 0968 is a 4 KB module (pointer-table head, 10/11 self-pointers, 2+8 spawn calls) | its own content is 2600 bytes; the rest is stale buffer | doc |
The literal 0x801F69D8 in SCUS_942.54 is a cross-image reference naming 0968's loader callsite | it is the slot-B base constant | doc |
Battle DAT_8007BD0C == 0xB5 at 0x801E6D04 is a test on the Lapis Wave spell id | it is the formation monster id - Cort | doc |
The Muscle Dome INTERVAL screen is the (384, 0) 320x256 still | the intermission is koin1’s own scene drawn normally, and no primitive in the live ordering table samples a texture page at x = 384. The still’s consumer is still open | doc |
| The dome panel still is uploaded as 320x64 rows stepped down in y | four 64x256 columns. A neighbouring texture family really does load the other way, and the two were being described with one geometry | docs |
| The trigger-sidecar load path reads three files | that is the dev branch; retail takes one read of a fixed sector count. The tell is that the dev leg reaches a host trap | docs |
| There is no call at that address in the world-map overlay | the test read the delay slot. The call is one word earlier - and the conclusion the negative supported happens to survive, which is what makes this shape dangerous | docs |
| The character pack's second header word is a tail offset into the entry | it is 78 KB past the entry's end - the sum of the descriptors' decompressed sizes. The battle loader that looked like the other consumer of that offset is reading a different entry entirely, four TOC indices away | docs |
| The failing rebuilt character-pack container can be hand-built with a different first-section size | it cannot - the decode is length-driven by the descriptor and the loader sizes its buffers from the container header, so such a rebuild gets a truncated pack | doc |
| A scene bundle's descriptor offsets can fall outside the entry | all 668 across 102 tables are inside; the offsets were being measured against the over-reading entry-size expression | doc |
Field / locomotion
Field overlay: locomotion, move-VM opcodes, the prologue grade, phantom function entries.
| The reading that looked right | Verdict | Write-up |
|---|---|---|
| The motion-pause kick freezes NPCs while you talk | it only asks each walker for its standing clip, and a walker mid-step asks for its walk clip again before that request is read; nothing holds | doc |
FUN_801D79E8 draws dialog glyphs or starts an actor moving | it is the visibility cull; both dumps filed under its address hold other code | doc |
| Rula and Riremito are developer-menu warps with no player-facing use | they are what the Door of Wind and Door of Light items run; the handler table is indexed by value, so no address reference ever named them | doc |
| The Door of Light takes you back to the tile you last stood on | it goes to the exit the region record names, refreshed when the menu button is pressed | doc |
| The place-name banner is a panel script run by a fade actor | that script only closes panels; the scene loader spawns the banner itself, as an ordinary text balloon | doc |
| The in-scene warp walks the player to the destination | the timer only counts; the landing seats the player once | doc |
| The player walks in place through a warp | the player idles - a system routine resets the clip every tick | doc |
| An inn conversation ends because the next halt fails | it ends at the last page; the next halt succeeds | doc |
The world map's FUN_801D1344 is different code from the dialog overlay's | one routine of one image - the player's tick | doc |
Field op 0x3E below 100 arms an NPC's interaction script | it installs a scripted battle; the engine had opened dialogue where retail starts a fight | doc |
| Nothing frees the tile board's cell buffer | the walk state machine's teardown state frees it with the tile-actor table | doc |
Field-VM op 0x45 sub 0xC0 returns the operand s16 as the next PC | it falls through by 4 (j 0x801E3624 / addiu s8,s8,4); the s16 is FUN_801DE084's apply trigger. Every zero-trigger record restarted from byte 0, which held urudre2 | doc |
Op 0x43 subs 0/1/A/B resume at an operand s16 | they fall through by 8 (+2 for sub >= 0xA); the s16s are FUN_801D25EC arguments, widths 8/10 bytes | doc |
| A frontier-ladder scene that will not walk is a scene or a seat problem | one latched player-actor bit (the ledge-hop steering lock) leaking across scene entries; every "broken" scene walked fine alone | doc |
A scene with no 0x3F in its MAN has no door (uru, urudre1..3, jouine are sealed) | the ops sit past a text desync, the tile sweep and tick budget capped below the exits, and every exit is in the .PCH sidecar; jouine leaves by FMV | doc |
| "~270 undumped field-overlay functions" (recomp dispatch-entry seed list) | not a function inventory gap | doc |
| Rim Elm's reachable south-gate band force-walks the player through the wall | the record is five inert bytes | doc |
| Scene-bundle type-6 descriptors are "all small placeholders" | 12 are walker tables | doc |
Move-VM loop op 0x19 "retires past itself (size 2), loops back to the saved PC" | both halves inverted by the C rendering | doc |
Field-VM op 4C nE sub-3 "syncs the resolved actor's position to the active camera" | copy direction inverted | doc |
| Extraction-0874 §2 F-variant pixels are written by a pause-menu-path uploader (and then: are a parked wrap-scroll phase) | twice | doc |
Field-VM op 0x43 sub-3..6 is a sound register ramp: four target values, a ticks duration and a curve | on all four counts (it is a camera-register zone ramp | doc |
Prologue gold grade = per-node +0x74/+0x78 depth-cue crush | grade is a palette-space collapse; the nodes carry no IR0 | doc |
FUN_801F12D0 read from the overlay_0897 dump | falsified | doc |
A second stage-id writer "at 0x801FD514 in the 0897 band" | falsified | doc |
0x801D84B4 is inter-function padding | falsified | doc |
FUN_801dfb10 is a scripted player-turn state machine | falsified | doc |
FUN_801DD784 is a cinematic letterbox | the bars do not stop at a letterbox height - they meet in the middle and hold. It is the scene shutter blackout | doc |
0x801F27EC is the fade family | its tick writes 0x1F80035C + rung * 2, the scene elevation LUT - what oscillates is a floor height, not a brightness | doc |
FUN_801CFF3C is a second spawner for the bar template 0x801F2858 | it is FUN_801DE754 printed 0xE818 low; the two dumps match instruction for instruction, and the template has one spawn site | doc |
0x801D44CC is a per-dancer facing script | it indexes the marker actor’s +0x50 (the clip - 6 the floor pass stamps) and selects a mesh row - it flips the marker’s picture | doc |
FUN_801D414C runs on both dance edges and stages other1 | exit edge only, and it is a restore - it puts back what entering the hall displaced. Nothing in it names other1 | doc |
_DAT_8007B880 is the dance pad latch | it is written by the hall’s animation clock and read by nothing that resolves a note; the judge reads the ordinary per-frame pad edge words | doc |
0x801D518C holds the literal other1, so the dance hall is other1 | it is a BSS saved-caller name slot holding whichever venue last passed through it; the dance venue is other7, block base 0x4CC | doc |
FUN_80019D50 is a BGR555 cell-grid emitter | the halfwords are palette entries, not pixels - one LoadImage at 0x8001A030 per call and no primitives. It is the CLUT-cell HSV cycler | doc |
The world-map controller calls FUN_801D362C directly | one reference disc-wide - SCUS 0x80023AE0, the move VM’s own op-0x2F arm. Everything the world map gets from it, it gets by running a move-VM script | doc |
| teien's hedge-base cells are filled by an unpinned kind-2-cell draw channel | retail draws nothing there either. The port was byte-faithful all along; the symptom is authored cutout texels over cells the game never fills | docs |
| The camera ease is a yaw | a vertical offset - its two inputs are the camera block and the actor's Y, and a yaw is simply the camera quantity most often eased | docs |
Actor +0x16 is a heading / a facing / a footing byte | it is Y, and always was. Three pages each named the quantity from their own consumer's context, so the docs carried three readings of one halfword without ever contradicting themselves in one place | docs |
| The census field on a script instruction carries its sub-op | it is a cross-context target marker. The field is set on exactly the instructions that have a sub-op, so a census keyed on it returns a plausible-looking site list | docs |
| Nothing in 84 images references two field-overlay descriptors | both are the handler words of ledge-hop templates, spawned from four sites. The sweep was run in a mode that drops hits classed as incidental code, and these are data words - a negative from a filtered sweep is a negative about the filter | docs |
Actor +0x8A bit 0 enables the scripted motion VM | it suppresses it - a zero byte runs the bytecode | doc |
Motion op 0x06 echoes the pad | a home-relative one-tile wander off a random draw; it never leaves one tile of where the actor was placed | doc |
Motion op 0x0C is a glide channel | it fades a packed RGB tint and a draw mode; the speed halfword is one field away, which is what made a colour ramp read as movement | doc |
| The field player is seated by the cold-entry arm only at New Game | the same function’s epilogue clears the gating word, so every ordinary scene change takes it - and the quoted seat belonged to the ambient template, not the player | doc |
| The decoded motion ops all have authored carriers | a census over all 573 MAN variants finds none for the wander, the teleport or eight other ops; a consumer gap for an op no disc data reaches is not a gap in the port | doc |
_DAT_8007BACC has no writer, so the recentre-window arm is unreachable | falsified premise, surviving conclusion: the writer sits in a branch delay slot, which is the one position a call-target sweep steps over. The arm is still dead - the only store is a zero | doc |
| The fishing water class is read after the walk-grid probe reports its bit | two unrelated reads of the same point - the water gate is a cell-word bit, while the walk-grid probe's hit drifts the lure instead | doc |
| The halfword after the lure's x is its z | it is the lure's height - the store writes the spawning actor's Y less a constant; z is the halfword after that, and the 2-D readers step over the height to reach it | doc |
| The Baka Fighter editor's actor record starts where its callback was cited from - or the band is five records from the address that replaced it | wrong twice: the cited word is a record's filler field, and the corrected band start is itself inside the fourth record. Eight records tile the span, ending exactly at the name pool, and two spawn sites each take one of them | doc |
| The port's camera visible-tile window is seeded at scene entry | it was seeded once, at camera construction, so a scene that scripted a wide window handed it to the next | doc |
| The wall-slide resolver cannot be wired because its rests are pinned on the non-sliding stepper | both pinned legs are slide-neutral, so the oracle was measured where the two models agree | doc |
| The word Incense fills is a brightness ramp or a frame cooldown | falsified - it is the encounter-suppression window, counted in walking steps | doc |
| A talk's "turn to face" always targets the speaker | falsified - it names any actor; 40 of 146 placement-script cases name another | doc |
No overlay function lives below 0x801CE818
Slot A begins at 0x801CE818; a "function" printed below it belongs to no runtime image.
| The reading that looked right | Verdict | Write-up |
|---|---|---|
A FUN_801C**** / FUN_801D**** address printed below 0x801CE818 names a function in some overlay | falsified - no runtime image loads there; the address is a mis-based dump's print key | doc |
Rendering / camera
Readings about the draw path - including one where the instrument measuring a defect was producing it.
| The reading that looked right | Verdict | Write-up |
|---|---|---|
| The Muscle Dome hub draws subtractive shadows | the GPU blends only texels with the STP bit, and those palettes carry none, so they draw opaque | doc |
| A field light's size is in world units | camera space, six times larger | doc |
The field fog samples VRAM (448, 256) | (448, 0) - the page-y bit is clear | doc |
| The port's fog runs dense because the spawner compares a stale count | the stale count was modelled; the cause was feeding raw random-number state where retail's rand returns the high half | doc |
| The remaining coplanar sliver is a residue below the detection floor | the port's own repair pass makes it - the leftover strip is exactly one nudge wide, because the lift applied to that family lies inside the second plane, and zeroing the offset takes the measured overlap to zero | doc |
| The GTE setup routine zeroes the light block | its three control writes are the far-colour trio, written from registers; the routine that zeroes anything targets the translation vector, and the battle-intro swirl rolls about two axes with it | doc |
| The field follow camera's pitch, yaw and height are scene-invariant constants | each is a per-scene, per-tile output; the pins match 12, 8 and 1 of 19 walkable states, so they measure one save state | doc |
| The field view matrix is built three times every vsync | two or three times per field frame, and the first site is optional - 749 of 1800 captured vsyncs carry a build at all | doc |
| The last build before the draw wins, so its inputs are the frame's camera | of 31046 ordering-table links, 16810 were emitted under the first build's matrix and fourteen under the last | doc |
| The builder's two extra call sites are in a resident field-render module | they are one bracket in the world-map render module, which zeroes the camera yaw for a screen-fixed band and rebuilds - neither is a frame's camera | doc |
| Each landmark mesh passes once per frame through the table-driven renderer | the dispatcher names it behind a gate, and the near arm takes every landmark: 756 gate hits on one map, near arm every time, and zero entries across the whole census | doc |
| The environment-mapped renderer runs whenever its per-actor flag is set | that flag picks between the two near-arm leaves; nothing reaches either unless the outer gate is non-zero, and all 5089 sampled gate reads were zero | doc |
| Nothing on the disc raises the mesh-renderer gate | two writer families do; the 5089-zero census is a statement about the sample, not the disc | doc |
| The prologue jungle's black plants come from the sepia grade | falsified - a native-only staging step gave them the dim prologue ambient | doc |
| The drop-shadow pair is a lighting helper and a gouraud grid the rasteriser replaces | falsified - an RTPT grid and four textured quads, which neither host drew | doc |
Measurement readings
Claims about the project's own instruments. A count can be right while the story attached to it is wrong - and the story is what directs effort.
| The reading that looked right | Verdict | Write-up |
|---|---|---|
FUN_801DD088 is reached by a PC-relative branch, so it may be an interior label | that branch is in another image at an aliased VA; the leaf has no reference of any form | doc |
| A retail battle load raises an emulator exception | only a patched disc does | doc |
PROT 0977 0x801D1EF0 is data past the last jr ra | the arena settlement bring-up, truncated by the sector-granular extent; same shape in PROT 0902 and 0979 | doc |
SCUS 0x80045CB4 is interior to a body 11 128 bytes back and unreferenced | entry FUN_80045BB4, word 12 of the bank-3 primitive-handler table at 0x8007668C | doc |
overlay_0897_xxx_dat_801f138c.txt is a routine at 0x801F138C | FUN_801DABA4 printed 0x167E8 too high; only the 33 PC-relative branch operands differ | doc |
arena_init (PROT 0977) own content is about 0x4800 bytes | it is 0x3800; the extra 0x1000 is PROT 0978's two sectors | doc |
The battle overlay is 0x28800 of 0x29800 bytes with a diverging .bss tail | the entry is 0x28800; the tail is PROT 0899's first two sectors | doc |
The disc-coverage report's excluded dumps are "typically the ones that report 0 instructions and hold only decompiled C" | zero of them reported 0 instructions | doc |
| The inner of two nested overlay spans "cannot be repaired ... no amount of dumping moves it" | falsified | doc |
| The unattributable residue "is repaired by re-dumping, not by extracting another overlay" | falsified | doc |
0x8005BA38 is "not a function - the dump reports size=1 bytes, 0 instructions" | it is a complete RotTransPers | doc |
| "About 2 % of retail camera beats set a non-zero roll" | the figure was the scan's own filter | doc |
| An over-strict header regex is one instrument's bug | every instrument had its own | doc |
| A zero-reference SCUS function is a safe code cave once the five-form address scan and hours of live probing clear it | for FUN_800605C8 (boot-live | doc |
0x801D2784 is PROT 0979’s battle-intro transition tail | the bytes are PROT 0976 (Baka Fighter). 0979 and 0976 are byte-identical from file 0x3C68, so only the operands separate them - and they name addresses past 0979’s own 0x4000 | doc |
0x801DDA90 and 0x801DDB44 are two slices of one loop, neither a function entry | right about 801DDB44 only. 801DDA90 is slot 0 of the eight-entry jr table at 0x801CEC40, and that word is its only reference - which makes it an entry | doc |
FUN_801E59B0 gives its two trig tables two different angle indices | one index for both: i = (angle + 0x400) & 0xFFF is computed once and reused, the components are the other way round, and the two globals are table pointers | doc |
| The PROT 0898 entry tables resolve the slot-B attribution residue | they close 6 extents / 48 bytes and name the wrong module for 10 of 15. A table names an entry; it says nothing about which image the bytes belong to | doc |
A disc-coverage --check floor regression means coverage was lost | attribution lag - a new unattributed dump raises the denominator before the numerator, so the percentage falls while the corpus strictly grew. Re-attribute, then re-read | doc |
801D84C0 is wired because panel_anchors is called | the tag carrying that address sits on panel_labels, and the audit walks from the tagged item. The bucket is a property of the anchor, not of a neighbouring symbol | doc |
The world-map overlay’s per-prim handler table is based at 0x801F8988 | FUN_80043390 loads 0x801F8968 (lui s4,0x8020 / addiu s4,s4,-0x7698) and indexes it like the SCUS table 0x8007657C, whose words 0..7 are also zero. Re-basing by the zero prefix shifts every kind by eight | doc |
| A slot-B module carries un-dumped code above its frame partition | it is the spawn-record band. The run scores as plausible code because a record's bytecode contains an address-forming word by accident | docs |
| Two slot-B images hold a second region of their own code above the record band | it is the donor's residue. Each image is byte-identical to its neighbour from a file offset partway up, so its own content ends there and every body above it belongs to the other image. This row was itself a correction of an earlier one, which is what makes it worth keeping | docs |
| The libcd directory cache is at the address the docs carried | the routine forms no address in that range at all. How the wrong value arose is not settled - the "offset half of an instruction pair" story does not survive, because that halfword occurs at no word in the executable - and it outlived the correction in two other files' reason strings | docs |
A // PORT: tag names the routine its code implements | nothing checks it. One live port carried an address whose routine it implements nothing of, with every gate green | docs |
| A PCSX-Redux save state carries main RAM only | it also carries a hardware blob with the scratchpad in it. The repo's own reader exposed main RAM and nothing else, so the reader's surface was read as the format's | docs |
| The port-tag checkers read a tag's continuation lines | neither did. The correct rule is narrow, and the obvious fix - read to the first blank line - would add 47 port claims nobody made | docs |
| An overlay ships the same ground emitter twice | a depth-cued / flat pair. The two bodies are near-identical for hundreds of bytes and are chosen between by one global - every sign of a build duplicate - but they differ by two instructions, and those two are the feature | docs |
| The highest spawn record’s end is unbounded, because the walk lands within 4 bytes in only three quarters of images | the records are word-aligned and the walk’s end rounds up to 4 - a residual measured before the last step of the rule is a measurement of the missing step | doc |
| A build-buffer tail can only come from a same-base, strictly longer image | both restrictions are wrong - the buffer is indexed by file offset, and the length field is a sector extent | doc |
| An uncovered run in an overlay image is a code gap | the same instrument had already shape-classified most of them and counted every byte anyway, so the ranked worklist was mostly its own rejected shapes | doc |
| An image's frame partition bounds its own content | a partition can hold a donor’s whole function; what bounds own content is the record chain’s top | doc |
| A VA that appears in two neighbouring images names one routine measured twice | usually, but not always - one such pair is two different routines, and the rule is to diff the bytes | doc |
| Correcting a function's extent in the attribution CSV corrects the corpus | it orphans the body: the extent comes from the shared dump header parser, so a CSV-only edit leaves the dump claiming the short length | doc |
| A function's dump covers its body | seven dumps of one function all stop at 276 of 588 bytes - agreement across dumps of one program is agreement about the program | doc |
| A feature view's Port % is a property of the port | the ignore list sat on both sides of the fraction, so the headline also moved when an ignore row was added and nothing about the port changed | doc |
| An open-ended CDNAME block’s range is safe to use as a length | the last block runs to the end of the map, so the unclamped range reserved 64 GiB on a scene load - which overcommit granted silently. Reproduce this class under a ulimit -v cap | doc |
| Every slot-B record-end miss stalls below the measured end, so the rule cannot over-claim | half falsified - of 33 misses over 1023 extents, 14 walk past the end. What survives is narrower: no miss ever terminates above it, because only a terminator produces a claim. A direction measured on one walker is a property of that walker | doc |
| A backward scan of a function finds every source of the value it stores | the value can arrive through a pointer argument - a callee fills a stack pair the caller never names, so scanning the caller’s own bytes for the source address returns nothing | doc |
| A reach-triage cell saying a row is not driven is a measurement | it is prose beside an address - the audit resolves the addresses and says nothing about the sentence, so nine of eleven such rows were already entered | doc |
| A mode-seat parity check can compare the two hosts' mode words | an INIT mode never survives the call that enters it, and one host's exposed word was a front-end flag; the witness that works is the edge count | doc |
| The two 24-instruction tally helpers are different routines | one routine linked into two overlays - the relocated pair that materialises the gate word comes first, so a byte comparison diverges on instruction one | doc |
The archive entry labelled monster_test is a monster-test harness | it is the world-map top-view debug image; names inherit forward from the block above, so a label says which block a slot is in and nothing about its content | doc |
| The dev-menu row-string address is a phantom print from a mis-based dump | it is the field overlay's own data; the address looked unattributable only because the other slot-A occupant aliases it and the two are never resident together | doc |
| The native minigame step runs fishing and dance work the browser has no twin for | both reach the browser; exactly three sub-steps do not, and all three for one reason - only the native window owns the effects module. A waiver naming the wrong members hides the reason they are missing | doc |
| One address hosts both a Muscle Dome routine and the battle flow state machine | one routine: the hub image ends below that address entirely, and the two dumps differ only in the capture their filenames record | doc |
| The browser play page's frame path has no early exit | the early exit is in the page's own JavaScript, one language further out than the check that looked for it | doc |
| No load base makes PROT 0896 self-consistent | a resolution ratio is one-sided and cannot see the call graph, which is where the answer was | doc |
| A frame kernel paired by name does comparable work on both hosts | an empty body pairs with anything, and one of the pair was literally empty | doc |
| An overlay's long low-entropy tail is a pointer table | sparse uninitialised data - 81 % zero with a single word in it | doc |