The heat economy now bites back, verified under sustained fire:
- Ballistic gate 1 (@4bbd36): destroyed-state or own-sink FailureHeat pins
full recoil + the unavailable alarm (the NoAmmo roach-motel re-asserts).
- CheckForJam (@4bbfcc): p = 0.41*T/failT clamped [minJamChance, 1.0], rolled
per granted shot against the MUNGA uniform Random. Interim heat-degraded
gate stands in for the deferred LiveFireEnabled novice switch (the exact
spurious-cold-jam trap the BT411 port documented). VERIFIED: SRM6s jam at
T~1200-1320 after riding past the authored 1000-degree threshold, and stay
jammed (mission-reset recovery only) -- authentic.
- Emitter hard gate (@4baab9): FailureHeat drops the beam state + charge each
frame; SELF-RECOVERING once conduction cools the sink below failure.
VERIFIED: the PPC settles into an emergent thermal duty cycle -- fire at
~1930K, spike to 2562K, shutdown, cool, refire -- firing exactly as fast as
its sink sheds heat; the lasers oscillate around ~2200K.
Zero Fail. Deferred: LiveFireEnabled/HeatModelOff experience gates,
mech-disabled gate halves, coolant depletion, jam recovery via mission reset.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Weapons dump firing heat into their own sinks, sinks conduct through the
Condenser bank into the central HeatSink, temperatures drive the degradation/
failure alarms, and every powered subsystem tracks its generator through the
electrical state machine. Verified: the authentic fire-discipline game -- a PPC
spikes 77->709K per shot, relaxes to 441K across its 5s reload, and sustained
fire climbs 441->674->838->960K, brushing the authored 1000K degradation
threshold. All calibration values match the BT411 audit exactly (central bank
1.39e6, PPC sink 174000, thresholds 77/1000/2000).
- HEAT: HeatSinkSimulation (@004ad924 absorb->T->load->conduct->alarm),
ConductHeat/ComputeHeatFlow (@004ad8ac/@004ad9ec two-body equilibrium
relaxation; flow==0 exactly at uniform T), UpdateHeatLoad (15-sample filter);
heat-state enum + accessors; installed by the HeatSink ctor.
- WIRE-VERIFIED: HeatSink resource gains linkedSinkIndex -- THE missing
ancestry int that shifted every descendant block +1 (voltageSourceIndex had
been reading the linked-sink index: "power sources" appeared to be
Condensers). Conduction topology wired from it at construction:
weapons->Condensers1-6->central; Generators->Condensers; Reservoir->central.
- MECHWEAP resource: authentic pip tail (pipPosition int + pipColor 3 floats +
pipExtendedRange int) per the BT411 verified overlay; with linkedSinkIndex
this closes the whole +3 alignment mystery (ProjectileWeapon pad deleted).
True bhk1 reads: PPC recharge 5.0s (not 1.0), discharge 0.99s, range 900.
- POWERSUB: ctor resolves voltageSourceIndex -> GeneratorA-D (wire-verified),
taps via Generator::TapVoltageSource (-1 when full); PoweredSubsystemSimulation
(@004b0bd0) electrical FSM (Starting/NoVoltage/Shorted/GeneratorOff/Ready);
GeneratorSimulation partial (start/short-recovery timers).
- Weapons: power step at sim head; Loading recharge gated on electrical Ready
(authentic @4bbdf5); FireWeapon dumps firing heat. HEAT UNITS: the chain is
1e7-native with TWO authoring conventions -- energy weapons store small
(PPC=11, x1e7 from the energy algebra), ballistics store native (SRM6=5.06e7,
dumped raw; double-scaling it was the bring-up runaway-temperature bug).
- SENSOR: authentic gating (@004b1c4c) -- power step, electrical-Ready gate,
heat-state switch (Degradation x0.5 / Failure 0). Verified Ready + 100%.
Deferred: coolant depletion/venting, the novice HeatModelOff gate, the charge
model (TrackSeekVoltage/voltage sag/I2R), weapon gate 1 + jam roll, the central
sink's forward-linked drain. Zero Fail across fire + neutral runs.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The energy weapons now run a live fire cycle, and the REAL trigger wiring is in
place: the 1995 MechWeapon attribute table (binary @0x511890) is published with
PINNED IDs, so the streamed per-mech fire-button mappings bind TriggerState
(0x13) -> fireImpulse and the controls push writes the trigger into the weapon.
- MECHWEAP: attribute enum + table (PercentDone 0x12, TriggerState 0x13,
DistanceToTarget 0x14, TargetWithinRange 0x15, WeaponRange 0x16,
EstimatedReadyTime 0x1A, RearFiring 0x1B, WeaponState 0x1C). Pads bridge the
chain gap 2..0x11 -- LOAD-BEARING: AttributeIndexSet::Build leaves uncovered
gap slots as uninitialized garbage, so every ID up to the max must be covered
(they shrink to the authentic 0x0F..0x11 when the parent attribute waves land;
SENSOR.HPP pins PoweredSubsystem::NextAttributeID at 0x0F).
- MECHWEAP: fire-machine members (fireImpulse/previousFireImpulse,
rechargeLevel, rangeToTarget, effectiveRange, estimatedReadyTime, recoil,
weaponAlarm 0/2/3/4); CheckFireEdge (@004b9608, BIT-PATTERN int compare --
TriggerState carries raw ControlsButton ints whose release value is a float
NaN; IEEE compare would latch the detector shut); ComputeOutputVoltage
(@004b9c9c recharge dial).
- EMITTER: EmitterSimulation (PARTIAL @004baa88) -- Firing/Loaded/Loading FSM
on the weapon alarm, viewFireEnable gate at Loaded->Firing, recoil-decay
recharge over the authored RechargeRate seconds; FireWeapon (PARTIAL
@004bace8) discharge bookkeeping; ChargeLevel re-pinned to the authentic
0x1D; index re-chained to MechWeapon's. Deferred: electrical charge model
(TrackSeekVoltage), heat dump, HasActiveTarget gate, beam/damage submission.
- BT_FORCE_FIRE dev hook: trigger pulse whenever Loaded (auto-fire cadence).
VERIFIED headlessly: forward view -- PPC_1/2 + ERMLaser_1 cycle FIRED->LOADED
at the authored 0.6s/1s cadence, rear lasers silent; BT_FORCE_LOOK=3 -- ONLY
the rear lasers (ERMLaser_2/3) fire. The view-fire x fire-FSM interlock holds
both directions. Zero Fail. (SRM6 ballistic FSM = a later increment.)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Phase-5.1 crash solved + two BTPlayer bricks reconstructed. The tree now
builds AND boots end-to-end with no staged Fail() reached, into the running
per-frame game loop.
- EMITTER.CPP: define Emitter::AttributePointers[]/AttributeIndex (ChargeLevel,
chained to Subsystem::AttributeIndex) and point Emitter::DefaultData at it.
EMITTER.HPP declared the index but the .cpp never defined it, so the surviving
PPC.CPP (PPC::DefaultData binds inherited Emitter::AttributeIndex) and
GAUSS.CPP (chains it) captured a NULL activeAttributeIndex -> GetAttributePointer
faulted on the first PPC (roster slot 22). Fix clears all 33 roster slots and
the control-mapping binding block.
- BTPLAYER.CPP InitializePlayerLink: real body -- dispatch PlayerLinkMessage
(our EntityID) to playerVehicle + replicants (mirrors engine
CameraDirector::CreateCameraShip). No staging.
- BTPLAYER.CPP VehicleDeadMessageHandler: non-death flavours (-2 drop-zone probe,
>=0 respawn re-post) delegate to the authentic Player base handler; only the
-1 death cycle stays staged (needs mech4 + scoring roles).
Verified: 516-line smoke run, zero Fail/Exception/abort; boot reaches
LBE4ControlsManager::Execute per-frame, waiting only on absent RIO hardware.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Emitter : MechWeapon -- energy-weapon (beam) base. Both surviving weapon leaves
(PPC.CPP, GAUSS.CPP/GaussRifle) derive from it and now compile against the real
base. Ctor chains MechWeapon + inits chargeLevel/dischargeTime; statics/dtor/test
real; FireWeapon (beam discharge) + CreateStreamedSubsystem staged. BT: 33 ok.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>