re: partial field map inside the live definition object, and why the automation failed
Anchoring on a unit whose disc record sets a field locates it in the live object: Size_X/Y/Z (+0x30/34/38) and HP (+0x54) confirmed across five capital ships and the player fighter; +0x74 (0.8) and +0x84 (0.97) are probable ThrusterRatio and ResistanceParalyze but rest on a single anchoring unit; +0x40 varies per unit and is unidentified. live_offsets.rs automates the correlation and currently produces one hit which is false -- YawDragFactor 2.0 collided with the integer 2 at +0x0c stored as a denormal. Causes recorded: get_f32 is unreliable on default-heavy IDXD records because the value-before-key pairing shifts, and 96 words only reaches +0x180 while RadarRange/FCSRange sit beyond it. Next run dumps 512 words. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -114,3 +114,42 @@ not addressed. And this run only reaches the units Stage 02 instantiates: the
|
||||
**not** resolved here, because those fields' offsets in the live object are not
|
||||
yet known. Finding them is the next run: dump deeper than 96 words and look for
|
||||
the constants the disc *does* set on the records that set them.
|
||||
|
||||
## Locating fields inside the live object
|
||||
|
||||
The next step — reading the `…Ratio` / `…Count` family — needs to know *where*
|
||||
each field sits in the live object. The method is to anchor on a unit whose disc
|
||||
record **sets** a field and look for that value in its dumped words. Anchoring on
|
||||
`UN_f106_TCAF_Destroyer` (disc sets `Size_Radius 0.1`, `ThrusterRatio 0.8`,
|
||||
`ResistanceParalyze 0.97`) and then checking the same offsets across five capital
|
||||
ships and the player's fighter:
|
||||
|
||||
| offset | reading | `f106` | `f105` | `e105` | `e106` | `f101` | Delta Saber |
|
||||
|---|---|---|---|---|---|---|---|
|
||||
| `+0x30` | `Size_X` ✅ | 200 | 700 | 600 | 300 | 400 | 10 |
|
||||
| `+0x34` | `Size_Y` ✅ | 200 | 700 | 600 | 300 | 400 | 7 |
|
||||
| `+0x38` | `Size_Z` ✅ | 2000 | 3800 | 3800 | 2100 | 1400 | 29 |
|
||||
| `+0x54` | `HP` ✅ | 10000 | 30000 | 30000 | 10000 | 25000 | 1500 |
|
||||
| `+0x74` | 🟡 `ThrusterRatio` | 0.8 | 0.8 | 0.8 | 0.8 | 0.8 | 1 |
|
||||
| `+0x84` | 🟡 `ResistanceParalyze` | 0.97 | 0.97 | 0.97 | 0.97 | 0.97 | 0.97 |
|
||||
| `+0x40` | ❔ | 0.1 | 0.1 | 1 | 1 | 1 | 0.1 |
|
||||
|
||||
`+0x74` and `+0x84` are marked 🟡 because they rest on one anchoring unit: the
|
||||
value is right for the Destroyer and constant across the others, which is
|
||||
consistent with a field the rest default, but a second anchoring unit that sets
|
||||
them to something *different* is what would prove it. `+0x40` is 0.1 on two units
|
||||
and 1 on three, so it is a real per-unit field — just not identified.
|
||||
|
||||
⚠️ **The automated version of this does not work yet.** `examples/live_offsets.rs`
|
||||
correlates every `get_f32(key)` against every dumped word and keeps offsets all
|
||||
units agree on; over five units it produced exactly **one** hit
|
||||
(`YawDragFactor → +0x0c`), and that hit is **wrong** — `+0x0c` holds the integer
|
||||
2 (as a denormal float, `2.8e-45`), which collided with `YawDragFactor = 2.0`.
|
||||
Two causes, both fixable: the IDXD pool's value-before-key interleaving makes
|
||||
`get_f32` unreliable on records that default many fields (the pairing shifts), so
|
||||
most keys yield nothing; and 96 words only reaches `+0x180`, while `RadarRange
|
||||
60000` / `FCSRange 45000` — both set on the Destroyer — appear nowhere in that
|
||||
window, so much of the record lies beyond it.
|
||||
|
||||
So the next run dumps **512 words** per object, and the disc side needs a reader
|
||||
that walks the pool with the default-aware rule rather than `get_f32` per key.
|
||||
|
||||
Reference in New Issue
Block a user