diff --git a/docs/re/live-unit-definitions.md b/docs/re/live-unit-definitions.md index fa206d9..9f5df47 100644 --- a/docs/re/live-unit-definitions.md +++ b/docs/re/live-unit-definitions.md @@ -232,3 +232,27 @@ rather than one field per flight. (The `vtables`, `classes` and `methods` tables are empty in this DB build, as `CLAUDE.md` warns, so the class has to be reached through the call graph.) + +## The constructor zero-fills, so the defaults are derived, not stored + +Walking the call graph found the class: `sub_8233FAF8` (`0x8233faf8`) writes the +vtable **`0x820af844`** — the very objects dumped above — into `0(r30)` and then +initialises the instance. Every one of its 32 stores writes **zero** +(`stw r29, …` with `r29 = 0`), out to `+872` and beyond, interleaved with +string-member constructor calls. + +That kills the natural next hypothesis: **the defaults are not immediates in the +constructor.** The object starts at zero, `Idxd_Parse` writes only the fields the +text contains, and yet a defaulted `Size_Y` reads back as a *non-zero* value at +runtime (200 for the Destroyer, 700 for the `f105` Cruiser — always `Size_X`). + +So a defaulted value must be **derived after parsing**, which is exactly the shape +of the `Size_Y` inherits `Size_X` rule this project derived statically from sibling +records. Finding that fixup pass is what would yield the rest of the family. + +Two candidate sites turned up by searching for a load of `+0x30` feeding a store +to `+0x34` — `0x82217e18` (in `sub_82217A90`) and `0x823081e8` — but neither is +confirmed: the first is a *conditional* assignment (it compares `+0x30` against a +register and picks between two values before storing to `+0x34`), not a plain +copy, and offsets 48/52 are generic enough that both could belong to unrelated +structures. Recorded as leads, not findings.