Heat: THE AUTHENTIC ELECTRICAL MODEL -- weapons recharge from generators (task #10)
Task #10 set out to fix "scrambled linked-sink routing"; a [heat-link] attach log proved the routing was NEVER scrambled (every subsystem links its authored condenser exactly; the "pools in Condenser1" read was the diagnostic-sampler aliasing trap). The real defect: emitter.cpp's local FUN_00417ab4 stub returned NULL, so the whole electrical model was inert and the E7 force-charge recharged every emitter in ONE frame (~0.3s cycle, 1501 fires/90s, ~1.7e9 heat/s -- the "runaway"). Landed authentically [T1: disasm + byte-verified constants]: - Emitter ctor @004bb120: seekVoltage = authored fraction x generator ratedVoltage (10000); EC = energyTotal/(seekV^2 x 0.5); voltageScale@0x310 = (RechargeRate / -ln(1 - 1e-4 x seekV)) / EC -- charge reaches seekV[rec] in EXACTLY the authored RechargeRate (PPC 5s, ERL 4s, SRM 3s, ERM 2s) cold. Owner-flags ctor gate (the usual gotcha; the this-flags read never armed). - PoweredSubsystem::ChargeTimeScale (@004b0d50, was a =1.0 stub): voltageScale x (1 + thermalResistivity x srcTempRise) -- hot generators charge slower. ("voltageScale is never read back" was wrong; corrected + swept.) - TrackSeekVoltage @004ba838: charging I^2R -> the GENERATOR's pendingHeat (~3.5e8/full PPC charge) -- generators self-heat, conduct to their authored condensers, and throttle further charging. The feedback economy closes. - FailureHeat consumers found: this+0x184 == 2 gates BOTH weapon families (@004baa88 emitter: reset firing + hold charge 0; @004bbd36 ballistic: recoil=rechargeRate + alarm 7). Emitter::GetFaultState un-stubbed. - ProjectileWeaponSimulation @004bbd04 opens with call 0x4b0bd0 (disasm) -- launchers now run the powered/heat step (their firing heat previously accumulated in pendingHeat forever). - heat.cpp: per-instance BT_HEAT_LOG census (the old shared-static 1-Hz sampler aliased); [heat-link] attach log; the stolen-else Verify restored. Verified live (120s max-rate autofire): PPC ~470-500 (was 55,000), bank plateaus ~600 and sheds to ambient, generators 1100-1400, ERMLaser self-regulates at the authored 2000 failure threshold (shutdown-cool-resume). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Fable 5
parent
4ed2bbc293
commit
4e63a7b6c3
@@ -135,6 +135,19 @@ From the weapon `.SUB` records + the charge-curve `.data` constants (PE-parsed a
|
||||
- One BLH ER-M cycle = 0.2 + 2.0 = **2.2 s**; ~12 lasers staggered → aggregate ≈ 5/s.
|
||||
- `WeaponRange` 500 (ER laser), `DamageAmount` 3.5, `PipColor` 1.0 0.0 0.0 (RED).
|
||||
- Charge constants: `_DAT_004bb3c4`=1.0, `_DAT_004bb3b8`=1e-4, `_DAT_004bb3b4`=0.5; RatedVoltage (GENRATOR.SUB)=1e4; fire threshold `seekVoltage[rec]=0.8*RatedVoltage`.
|
||||
- **The electrical chain (task #10, LANDED) [T1]:** ctor @004bb120 calibrates
|
||||
`voltageScale@0x310 = (RechargeRate / -ln(1 - 1e-4*seekV[rec])) / EC`;
|
||||
`ChargeTimeScale` @004b0d50 reads it back every tick x `(1 + thermalResistivityCoefficient
|
||||
(res+0x100, emitters 0.0024) x max(0, srcT-srcT0))` -- hot generators charge slower;
|
||||
`TrackSeekVoltage` @004ba838 puts the charging I^2R (`seekRate^2 x dtScale x dt`) into the
|
||||
GENERATOR's `pendingHeat@0x1c8` (~3.5e8/full PPC charge). `ComputeOutputVoltage` @004ba738
|
||||
snaps rechargeLevel@0x320 to 1.0 within 0.01. **FailureHeat consumers:** `this+0x184`
|
||||
(own heatAlarm level) == 2 -> emitter @004baa88 resets firing + holds charge 0; ballistic
|
||||
@004bbd36 pins `recoil=rechargeRate` + alarm 7. @004bbd04 (ProjectileWeaponSimulation)
|
||||
opens with `call 0x4b0bd0` (the powered/heat step), like @004baa88. Cockpit power-routing
|
||||
handlers @004b099c/@004b09e4/@004b0a2c/@004b0a74 (bind generator by authored id 1-4 via
|
||||
@004b0b18) + @004b0abc (auto/manual, modeAlarm@0x2CC); attach/detach @004b0dd8/@004b0e30
|
||||
(generator client capacity @0x1e4/count @0x1e8).
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -69,11 +69,14 @@ intact). The `overlay` port (SectorDisplay lives there) shares the `sec` physica
|
||||
different bit-plane (0x00C0). [T2]
|
||||
|
||||
## Authentically-static (do NOT "fix")
|
||||
`currentTemperature ~77` (huge thermalMass ~1.39e6 → a 3.5-heat shot rounds to zero);
|
||||
Degradation/Failure temps are fixed markers; AmbientTemperature 300; CoolantMassLeakRate 0 on a
|
||||
pristine mech (damage-gated); cmArmor/cmCrit all-green (undamaged solo player — BT is PvP-only);
|
||||
RANK 1 solo; MessageBoard empty (no status messages exist in bring-up). The Heat MFD is
|
||||
authentically NEAR-STATIC, not a live heat-accumulation display. [T2]
|
||||
RANK 1 solo; MessageBoard empty (no status messages exist in bring-up).
|
||||
**CORRECTION (task #10, 2026-07-11):** the old "Heat MFD is authentically NEAR-STATIC /
|
||||
currentTemperature ~77 rounds to zero" claim was computed at the DEGENERATE bring-up heat scale.
|
||||
At the authentic 1e7-unit economy (tasks #9-#10) the Heat MFD is fully dynamic: weapons run
|
||||
77→2000 (the authored failure threshold), condensers/generators run 100-1400 under sustained
|
||||
fire, and the bank plateaus ~600 — temperatures, heatLoad and the heat alarms all animate. [T2]
|
||||
|
||||
## Remaining = DATA FEEDS, not widgets (deferred systems)
|
||||
The **condenser valve CONTROL** gates on the owning **BTPlayer**'s game-mode flag (`mech+0x190`,
|
||||
|
||||
@@ -176,15 +176,44 @@ authentic path scoped.
|
||||
CoolantCapacityScale = 0.05 float80 (both prior readings wrong). Verified: heat flows,
|
||||
exits (~2/3 of a 1e10 spam run drained), weapons overheat under max-rate autofire exactly
|
||||
as the authored-constant simulation predicts (thermal spam is unsustainable BY DESIGN;
|
||||
heatLoad -> effectiveRange 0 = the authentic overheat cutout). **REMAINING DEFECT: the
|
||||
linked-sink ROUTING is scrambled** -- both PPCs' heat pools in Condenser1 (observed 6800 K)
|
||||
while their AUTHORED condensers (PPC_1->C4, PPC_2->C6) sit at 72 K; heat.hpp:186 already
|
||||
notes the heat-stream parse reading neighbouring fields for thermalMass/heatSinkIndex --
|
||||
audit the type-0x11/heat-family stream offsets + the "+2-biased" index resolve. Also
|
||||
[T4]: who reads FailureHeat to BLOCK firing; the HeatWatcher/AmmoBin cook-off watchedLink;
|
||||
the mech-level heatAlarm@0x450 producer. KB sweep pending: the "Heat MFD authentically
|
||||
NEAR-STATIC" claim (gauges-hud.md) was computed at the degenerate scale -- at authentic
|
||||
scale the MFD is dynamic.
|
||||
heatLoad -> effectiveRange 0 = the authentic overheat cutout).
|
||||
- **Task #10 -- the "scrambled routing" RESOLVED (2026-07-11) [T2].** The routing was NEVER
|
||||
scrambled: a `[heat-link]` attach log proved every subsystem links its authored sink
|
||||
exactly (bhk1: PPC_1->C4, PPC_2->C6, ERM_1/2/3->C1/C6/C4, SRM6s->C2, generators->C1/C2/C3/C5,
|
||||
condensers+reservoir->bank@slot2). The "pools in Condenser1" observation was the
|
||||
DIAGNOSTIC-SAMPLER ALIASING trap (one shared static 1-Hz timer, pendingHeat-gated); the
|
||||
census log is now per-instance. The REAL defect was the fire RATE: emitter.cpp's local
|
||||
`FUN_00417ab4` stub returned NULL, so although the PoweredSubsystem ctor attaches the
|
||||
authored generator to `voltageSource@0x1D0`, the Emitter TU could never see it -- the whole
|
||||
electrical model was inert and the E7 force-charge recharged every emitter in ONE frame
|
||||
(~0.3 s cycle, 1501 fires/90 s, ~1.7e9 heat/s input). Fixed authentically [T1, disasm +
|
||||
byte-verified constants]:
|
||||
* Emitter ctor @004bb120: seekVoltage[i] = authored fraction x generator ratedVoltage
|
||||
(authored 10000); EC = energyTotal/(seekV[rec]^2 x 0.5); **voltageScale@0x310 =
|
||||
(RechargeRate / -ln(1 - 0.0001 x seekV)) / EC** -- the exponential charge reaches
|
||||
seekV[rec] in EXACTLY the authored RechargeRate on a cold generator (PPC 5 s, ERLLaser
|
||||
4 s, SRM6 3 s, ERMLaser 2 s, LRM15 6 s). The gate reads the OWNER's simulationFlags
|
||||
(the usual ctor-gate gotcha; the old this-flags read never armed).
|
||||
* `PoweredSubsystem::ChargeTimeScale()` (@004b0d50, was a =1.0 stub): voltageScale x
|
||||
(1 + thermalResistivityCoefficient x max(0, srcT - srcT0)) -- a HOT generator charges
|
||||
slower ("voltageScale is never read back" was wrong -- this reads it every tick).
|
||||
* TrackSeekVoltage @004ba838: charging I^2R (`seekRate^2 x dtScale x dt`) lands in the
|
||||
GENERATOR's pendingHeat@0x1c8 (~3.5e8 per full PPC charge -> generators self-heat ->
|
||||
conduct to their condensers -> slow further charging). This closes the heat/firepower
|
||||
feedback economy.
|
||||
* **FailureHeat consumers found [T1, disasm]:** `this+0x184` (the weapon's own heatAlarm
|
||||
status level) == 2 gates BOTH families -- @004baa88 (emitter: ResetFiringState +
|
||||
currentLevel=0 until it cools) and @004bbd36 (ballistic: recoil pinned to rechargeRate +
|
||||
alarm state 7). Emitter::GetFaultState() now returns heatAlarm.GetLevel() (was a 0 stub).
|
||||
* ProjectileWeaponSimulation @004bbd04 opens with `call 0x4b0bd0` (disasm-verified) -- the
|
||||
launchers now run the powered/heat step (their task-#9 firing heat previously accumulated
|
||||
in pendingHeat forever; SRM6s now census at ~950 under sustained fire).
|
||||
Verified live (120 s max-rate autofire): PPC ~470-500 (was 55,000), bank plateaus ~600 and
|
||||
sheds, generators 1100-1400, ERMLaser self-regulates at the 2000 failure threshold
|
||||
(shutdown -> cool -> resume). Remaining tails: the HeatWatcher/AmmoBin cook-off
|
||||
watchedLink; the mech-level heatAlarm@0x450 producer; the cockpit power-routing message
|
||||
handlers (@004b099c..@004b0abc: assign weapon to Generator 1-4 + auto/manual toggle via
|
||||
modeAlarm@0x2CC -- wired to buttons, not yet reachable).
|
||||
|
||||
## Locomotion / combat polish (non-gating)
|
||||
- Authentic per-mech TURN-RATE constant (currently a bring-up constant rate).
|
||||
|
||||
Reference in New Issue
Block a user