diff --git a/docs/HARD_PROBLEMS.md b/docs/HARD_PROBLEMS.md index 05698e7..5cc22a4 100644 --- a/docs/HARD_PROBLEMS.md +++ b/docs/HARD_PROBLEMS.md @@ -197,3 +197,43 @@ would trip it). (2) The im2 scenario re-run fast: **3601 shots + 10.6 km walked* **Durable lesson (systemic checklist entry):** an owner offset `+0x128` in subsystem raw decomp is the subsystem ROSTER (`subsystemArray`), NOT the segment table — audit every `GetSegment(int)` call in reconstructed subsystem ctors (only these two existed; both fixed). + +## P7 — Heat-leaf subsystem byte-exactness (the systemic layout gap) ⭐ NEW (root-caused this session) + +The reconstruction's **heat-leaf branch** (`HeatableSubsystem:MechSubsystem` -> `HeatSink` -> `PoweredSubsystem` +-> the weapon/sensor leaves) is **NOT byte-exact to the binary** -- measured: `PoweredSubsystem::auxScreenNumber` +compiles to **0x194** but the binary has it at **0x1DC** (72 bytes short). Consequence: any code reading a +heat-leaf subsystem field at a RAW binary offset above the gap gets garbage (this is what forced the aux-screen +BRIDGE in vehicleSubSystems, and the Sensor RadarPercent gauge stub, and blocks authentic data on the +engineering-screen cluster panels' secondary lamps). Fixing it byte-exact makes ALL raw reads correct +everywhere -> a high-leverage foundational fix. + +**Root cause (measured + decompiled this session, authoritative):** +- `MechSubsystem` base + `HeatableSubsystem` (currentTemperature@0x114 / degradationTemperature@0x118 / + failureTemperature@0x11C / heatLoad@0x120) are byte-exact. +- `HeatSink` accumulates a **+16 over-allocation** from two RECONSTRUCTION LAYOUT ERRORS: + 1. HeatSink RE-DECLARES `degradationTemperature`/`failureTemperature` that already exist in HeatableSubsystem + (a shadow/duplicate, +8). + 2. `heatState`/`heatModelFlag` are modeled as SEPARATE HeatSink fields (+8) but in the binary they are + **INSIDE the heatAlarm** -- `heatState` is read at `this[0x61]==0x184 == heatAlarm@0x170 + 0x14` (the + alarm's level field). So they are modeling errors: heatState reads should be `heatAlarm.GetLevel()`. +- Then two **type-size under-allocations**: `SubsystemConnection` is 4B but the binary's is **0xC** (built by + `FUN_004af9cf`); `HeatAlarm` (heat.hpp) is 8B but the binary's alarm at 0x170 is a **0x54 `AlarmIndicator`** + (ctor `FUN_0041b9ec` @part_002.c:4767 = base `FUN_004178cc` + three 0x14-byte `FUN_0041c42c` sub-objects at + +0x18/+0x2C/+0x40, ending 0x54). `HeatFilter` is ALREADY 0xC (byte-exact -- NO reimplement needed; earlier + fear of a behavior-risk filter change was WRONG). +- Net at `PoweredSubsystem::auxScreenNumber`: +8 (dup temps) +8 (spurious heatState/heatModelFlag) -8 + (SubsystemConnection) -76 (HeatAlarm) -4 (a PoweredSubsystem delta) = **-72**. + +**The fix = a byte-exact re-base of the heat-leaf chain:** remove the duplicate temps; remove the spurious +heatState/heatModelFlag and re-point their reads to `heatAlarm.GetLevel()`; grow `SubsystemConnection` 4->0xC +and `HeatAlarm` 8->0x54 (as shared 0x54/0xC types used everywhere the binary has them, WITHOUT breaking the +already-byte-exact Watcher branch which uses separate `WatcherGaugeAlarm`/`WatchedConnection`); fix the +PoweredSubsystem -4. It touches the core classes every heat/power/weapon subsystem derives from (large blast +radius) + includes CODE changes (heatState), so it needs a full at-risk-read audit (raw `this+0xNN` reads +calibrated to the CURRENT compiled layout would break) + exhaustive combat/heat verification. Safety revert +point tagged `pre-heatleaf-rebase`. The `heat-leaf-layout-audit` workflow derives the full plan. + +MEASUREMENT TECHNIQUE (reusable): a `template struct HSOff;` + `friend struct XProbe;` + +`struct XProbe { HSOff a; ... };` -- the "uses undefined struct 'HSOff'" build +error reports each field's COMPILED offset in decimal. Compare to the binary offset from the ctor decomp.