re(route-b): 13 defaulted Size_Y values read out of the running game
Live definition objects carry no name, so identity comes from the values: unit_signatures.rs prints (HP, Size_X/Y/Z) for every disc unit and vessel, and a live object is the record whose known fields it reproduces. 7 of 14 match a disc record outright; the other 7 match nothing because their records default a field -- 18 of 23 vessel records are missing at least one, nearly always Size_Y. Matching each single-default record against the live object that reproduces its remaining fields resolves 13 values (Destroyer 200, Cruiser 600/700, ASFrigate 80, ADAN Destroyer 300, Acropolis 400, ISCMissile 300, plus _Inv/_EX variants). Every one equals that unit's Size_X, so the engine's own parsed definitions confirm the statically-derived inheritance rule. Limits stated: variants share one live object, and the ...Ratio/...Count family is not resolved -- their offsets in the live object are still unknown. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -66,8 +66,51 @@ with them. It also gives independent support to the **`Size_Y` inherits `Size_X`
|
||||
default rule — five of the fourteen have `+0x30 == +0x34` exactly
|
||||
(300/300, 400/400, 200/200, 600/600, 700/700) while the rest differ.
|
||||
|
||||
❔ **Not yet resolved: which unit each object is.** Nothing in the first 96 words
|
||||
is an obvious name pointer, so these cannot be matched to their disc records yet
|
||||
— and that match is what turns the snapshot into defaulted-field *values*. The
|
||||
next step is to dump further into the object (and the entity that points at it)
|
||||
looking for the id or name field, which is one more single-call run.
|
||||
## Identity without a name: match on the values
|
||||
|
||||
Nothing in the first 96 words is a name pointer, so identity comes from the
|
||||
numbers themselves. `examples/unit_signatures.rs` prints `(HP, Size_X, Size_Y,
|
||||
Size_Z)` for every craft unit and vessel on the disc; a live object is then the
|
||||
record whose *known* fields it reproduces exactly.
|
||||
|
||||
Seven of the fourteen match a disc record on all four values — the player's
|
||||
Delta Saber (`10, 7, 29`, HP 1500 in its player form and 1000 otherwise), the
|
||||
ArrowHead, an ADAN turret, an Attacker. **The other seven match nothing, and
|
||||
that is the point:** their disc records leave a field defaulted, so there is
|
||||
nothing to match against. **18 of the 23 vessel records on disc are missing at
|
||||
least one of these four fields**, nearly always `Size_Y`.
|
||||
|
||||
## ✅ Route B: 13 defaulted fields read out of the running game
|
||||
|
||||
Matching each disc record that defaults exactly one field against the live object
|
||||
that reproduces its remaining fields resolves the missing value:
|
||||
|
||||
| unit | field | runtime value | live object (sx, sy, sz, hp) |
|
||||
|---|---|---|---|
|
||||
| `UN_e201_ADAN_ISCMissile` | `Size_Y` | **300** | `0xbd3e0680` (300, 300, 2800, 3000) |
|
||||
| `UN_f106_TCAF_Destroyer` | `Size_Y` | **200** | `0xbd3ee300` (200, 200, 2000, 10000) |
|
||||
| `UN_f106_TCAF_Destroyer_Inv` | `Size_Y` | **200** | `0xbd3ee300` |
|
||||
| `UN_e105_ADAN_Cruiser` | `Size_Y` | **600** | `0xbd3fd800` (600, 600, 3800, 30000) |
|
||||
| `UN_e105_ADAN_CruiserEX` | `Size_Y` | **600** | `0xbd3fd800` |
|
||||
| `UN_f105_TCAF_Cruiser` | `Size_Y` | **700** | `0xbd40e200` (700, 700, 3800, 30000) |
|
||||
| `UN_f105_TCAF_Cruiser_EX5` | `Size_Y` | **700** | `0xbd40e200` |
|
||||
| `UN_f105_TCAF_Cruiser_Inv` | `Size_Y` | **700** | `0xbd40e200` |
|
||||
| `UN_e108_ADAN_ASFrigate` | `Size_Y` | **80** | `0xbd3d2d80` (80, 80, 350, 4000) |
|
||||
| `UN_e108_ADAN_ASFrigateEX` | `Size_Y` | **80** | `0xbd3d2d80` |
|
||||
| `UN_e106_ADAN_Destroyer` | `Size_Y` | **300** | `0xbd3e6f80` (300, 300, 2100, 10000) |
|
||||
| `UN_e106_ADAN_DestroyerEX` | `Size_Y` | **300** | `0xbd3e6f80` |
|
||||
| `UN_f101_TCAF_Acropolis` | `Size_Y` | **400** | `0xbd3e1f00` (400, 400, 1400, 25000) |
|
||||
|
||||
**Every resolved value equals that unit's `Size_X`** — so the running game
|
||||
confirms the `Size_Y` inherits `Size_X` rule that was derived statically from
|
||||
sibling records, this time from the engine's own parsed definitions.
|
||||
|
||||
Two honest limits. Variants share a live object (`_Inv`, `_EX5`, `EX` map to the
|
||||
same definition as their base), so the snapshot cannot distinguish them — the
|
||||
value is right for the class, and per-variant differences in *other* fields are
|
||||
not addressed. And this run only reaches the units Stage 02 instantiates: the
|
||||
`…Ratio` / `…Count` family (`HQRatio`, `PowerRatio`, `ShieldRatio`, `HatchCount`,
|
||||
`NodeCount`, `SequencingCount`, …) is defaulted on 5–23 records each and is
|
||||
**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.
|
||||
|
||||
Reference in New Issue
Block a user