docs(gauge): record the gauge data-binding wave (P1 done, P2/P3/P4 plan)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
64975ec22f
commit
8379693a76
@@ -474,3 +474,86 @@ fill the gaps (bind not-yet-needed ids to a shared read-only pad member).
|
||||
bindings -- reads the mech's subsystem roster internally). Find its Make/ctor/Execute via the .data
|
||||
methodDescription table (the "vehicleSubSystems" string is a .data const, not inlined in the decomp).
|
||||
A focused effort (~250-300 lines across 3-5 functions).
|
||||
|
||||
---
|
||||
|
||||
## Gauge data-binding wave (2026-07) — publish attributes + reconstruct unbuilt widgets
|
||||
|
||||
Goal (user directive: "all of this needs to work as the game originally played. no shortcuts"): make every
|
||||
cockpit gauge read + reflect LIVE game state exactly as the 1995 pod. The `gauge-databinding-map` workflow
|
||||
(5 surface maps + 2 adversarial verifies) mapped every binding → subsystem/member → published-vs-missing →
|
||||
authentic value → fix. **KEY REFRAME (verified against the shipped .SUB data + the binary sim): the Heat MFD
|
||||
is authentically NEAR-STATIC, not a live heat-accumulation display.** `currentTemperature =
|
||||
heatEnergy/thermalMass`; ThermalMass=1.39e6, so heatEnergy_init = 1.07e8 whose float32 ULP is 8.0 — a
|
||||
3.5-heat laser shot ROUNDS TO ZERO (reaching Degradation 5000 needs ~2 billion shots). Coolant is
|
||||
DAMAGE-gated (not fire), the valve moves only on player toggle, AmbientTemperature is a hardcoded 300. So the
|
||||
wave is **"publish attributes + reconstruct unbuilt widgets + wire the 2 damage-driven formulas + the valve",
|
||||
NOT "revive a dynamic heat model"**. Diagnostic infra: `BT_GAUGE_ATTR_LOG` (GAUGREND ParseAttribute logs
|
||||
`[attr] <binding> OK/NULL` per config binding).
|
||||
|
||||
### Phase 1 — PUBLISHING (DONE; commits 070af40, 64975ec)
|
||||
Most gauges resolved NULL because the reconstructed subsystems published only a fraction of the bound
|
||||
attributes. All ids kept a dense prefix from each parent's `NextAttributeID` (AttributeIndexSet::Build
|
||||
strcmps every slot — a gap AVs). Done:
|
||||
- **HeatSink table** dense-append: DegradationTemperature@0x118 / FailureTemperature@0x11C (the condenser
|
||||
temp-bar warn/max endpoints — were NULL so the two-part bars couldn't scale), NormalizedPressure→heatLoad,
|
||||
DegradationPressure→coolantEfficiency, CoolantMassLeakRate→coolantDraw, HeatSink→linkedSinks. Condenser/
|
||||
Reservoir inherit it → all 6 condenser temp bars resolve.
|
||||
- **PoweredSubsystem::GetAttributeIndex()** (new) publishes InputVoltage→voltageSource@0x1D0 — the cluster
|
||||
power-branch gate (SubsystemCluster ctor skips the power-lamp/generator-voltage/state-lamp sub-branch when
|
||||
it resolves NULL). Flows to Sensor/Myomers/weapons automatically (they chain to it).
|
||||
- **MechWeapon::GetAttributeIndex()** (new) publishes OutputVoltage/PercentDone→rechargeLevel@0x320;
|
||||
Emitter/PPC/ProjectileWeapon/MissileLauncher/GaussRifle DefaultData re-pointed at it (they carried an
|
||||
EMPTY default-constructed index → resolved NOTHING). **VERIFIED: the ER-MED-LASER/PPC/STREAK weapon
|
||||
clusters now render live recharge dials (SegmentArc270) — were blank TEMP/STATUS.**
|
||||
- **Searchlight** publishes "LightOn"→lightState@0x1D8 (config binds the NAME "LightOn"; enum renamed
|
||||
LightOnAttributeID). **Mech::SetTargetRange** un-stubbed (radarRange=range) → radar map scale + range
|
||||
readout track the mapper's zoom.
|
||||
- **FIXED a genuine recon bug** (heat.cpp UpdateCoolant + heatfamily_reslice RefrigerationSimulation): both
|
||||
read `linkedSinks.Resolve()->heatEnergy` where the binary reads `*(this[0x38]+0x158)` = the subsystem's
|
||||
OWN DamageZone.damageLevel (@0xE0). The misread would SLAM the live CoolantMass bars to empty (coolantDraw
|
||||
= master.heatEnergy~1.3e7 * heatLoad) and clamp massScale permanently to 1.0. Now reads
|
||||
`this->Subsystem::damageZone->damageLevel` (qualified past the MechSubsystem shadow) → 0 undamaged →
|
||||
no leak / massScale 3.0 = authentic pristine. **After P1 every config-string binding resolves OK except
|
||||
HeatSink/AmbientTemperature** (needs the aggregate bank, P3).
|
||||
|
||||
### Phase 2 — WIDGET RECONSTRUCTION (TODO — the biggest remaining visible gaps)
|
||||
These config keywords are UNREGISTERED in `BTL4MethodDescription[]` (btl4grnd.cpp) so their lines are
|
||||
parse-skipped and the gauge is never built (even after publishing). Each needs a REAL Make/ctor/Execute/dtor
|
||||
(no prose — the /FORCE trap: a prose-only vtable slot AVs on first call) + registration. Grep the link log
|
||||
for `unresolved external <Widget>` before registering.
|
||||
- **VertNormalSlider** (condenser valve slider @2; vtable PTR_FUN_00518c34) + **LeakGauge** (== BitMapInverseWipe
|
||||
@4c5b7c, @6) — completes the heat panel's valve + leak columns.
|
||||
- **GeneratorCluster** (ctor @004c746c + 5 children: VertTwoPartBar @004c4724, ScalarBarGauge @004c72ac,
|
||||
LeakGauge @004c5b7c, 2× TwoState @004739d8 + real dtor @004c7778) — the 4 generator panels (buttons 9-12,
|
||||
currently blank). Publish the Generator OutputVoltage→outputVoltage@0x1DC entry (temps inherit HeatSink).
|
||||
- **PilotList** (Comm KILLS/DEATHS/SELECT-TARGET/NEAREST roster; Make @004ca90c, ctor @004ca958 reads
|
||||
DAT_0051af88 8×3 layout, BecameActive @004caba4, Execute @004cabd0, dtor @004cab10, DrawMechIcon @004cad70).
|
||||
Roster FEED is already live (MechControlsMapper::FillPilotArray). Needs DAT_0051af88 PE-parsed (24 ints).
|
||||
- **PrepEngrScreen** (Make @004c7b30/ctor @004c7bf0/Execute @004c7e48) — engineering full-screen readout.
|
||||
- **SectorDisplay** (ctor @004c9e10/Execute @004ca07c) + **MessageBoard** (Make @004cb678) — sector coords +
|
||||
message board (lower priority). **SeekVoltageGraph::Execute** (@004c6934) + real FindAttributeIndex (the
|
||||
weapon-cluster seek-voltage plot; currently an inert stub).
|
||||
|
||||
### Phase 3 — SIM/MODEL (TODO)
|
||||
- **Aggregate HeatSink-bank** (0xBBE; ctor @4ae8d0, sim @4ae73c, parser @4ae9dc — currently #if 0'd in
|
||||
heatfamily_reslice.cpp, a plain HeatSink built instead): publish HeatSinkCount + AmbientTemperature (a
|
||||
constant 300); rewire CreateHeatSinkBankSubsystem + bump the alloc. Clears the last config-binding NULL.
|
||||
- **Condenser valve**: reconstruct SetValveSetting (vtable+0x48 → coolantFlowScale@0x15C) + the real MoveValve
|
||||
msg-handler @4ae464 (the reconstructed @4afbe0 is MISLABELED = the MechControlsMapper) so a player valve
|
||||
toggle moves the slider AND changes heat flow. Add the Condenser OWN table (ValveSetting→coolantFlowScale) +
|
||||
#if 0 the heat.cpp Condenser dup-ctor stubs (the real heatfamily_reslice def currently wins by link order).
|
||||
- **Combat SCORING feed** (KILLS/SCORE/RANK): bring-up combat delivers Entity::TakeDamageMessage without
|
||||
posting BTPlayer ScoreMessages (ScoreInflicted @004c0200, ScoreMessageHandler @004c02e4, VehicleDead
|
||||
@004c012c) → killCount@0x27c/currentScore@0x278/playerRanking stay 0. Wire the weapon-death→ScoreMessage path.
|
||||
- **duckState** writer (button-4 crouch lamp; only ctor-zeroed today).
|
||||
|
||||
### Phase 4 — DEEP/DEFERRED
|
||||
Byte-exact re-base of the PoweredSubsystem:HeatSink LEAF (Sensor/Emitter/Myomers) → radarPercent heat penalty
|
||||
(delete the sensor.cpp:287-288 guard) + the raw-offset cluster reads; radar pip/name symbology + staticEntities;
|
||||
CycleDisplayMode→ModeManager mask (activates cmArmor/cmCrit/cmHeat schematic layers); numericSpeed units.
|
||||
|
||||
### Authentically-static (do NOT "fix")
|
||||
currentTemperature ~77 (huge thermalMass); Degradation/Failure temps (fixed threshold markers); AmbientTemperature
|
||||
300; MaxRunSpeed (per-mech constant); cmArmor/cmCrit all-green (undamaged solo player — BT is PvP-only);
|
||||
CoolantMassLeakRate 0 on a pristine mech (damage-gated); Player RANK 1 in solo.
|
||||
|
||||
Reference in New Issue
Block a user