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:
arcattack
2026-07-11 16:59:29 -05:00
co-authored by Claude Fable 5
parent 4ed2bbc293
commit 4e63a7b6c3
10 changed files with 273 additions and 90 deletions
+13
View File
@@ -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).
---