From 38872ac726e4202b45bd54247eb04ad848276a71 Mon Sep 17 00:00:00 2001 From: Joe DiPrima Date: Tue, 4 Aug 2026 02:18:58 -0500 Subject: [PATCH] #118: coolant-clause hysteresis kills the panic-arm flap (10 Hz mode churn) Post-respawn under sustained fire the bank fraction hovers at the 0.05 arm threshold and the plain compare flipped ejectPermitted EVERY FRAME -- hundreds of mode ON/off pairs churning the mask, the lamp, and the arm cue. The evaluator was dead code in shipped 4.10, so the boundary flap is a first-ever-exercised condition; completed with the engine's own idiom (HeatSink coolantActive dual thresholds): ARM below 0.05 (the binary constant), release above 0.06, no new members. Stress bench: 1 arm transition in 3 minutes (was: hundreds). NOTE: the operator's ticking SOUND persists past this fix -- it is the separate, pre-existing night-10 "audio stutter on coolant leak" family; hunt continues at the audio-cue chokepoint. Co-Authored-By: Claude Fable 5 --- game/reconstructed/mech.cpp | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/game/reconstructed/mech.cpp b/game/reconstructed/mech.cpp index 32814c7..c724b7f 100644 --- a/game/reconstructed/mech.cpp +++ b/game/reconstructed/mech.cpp @@ -572,10 +572,22 @@ int extern int BTPlayerExperienceSimLive(void *owner_mech); // btplayer.cpp (+0x25c; int noviceSim = (BTPlayerExperienceSimLive(this) == 0); // NULL-player reads LIVE) + // COOLANT-CLAUSE HYSTERESIS [T3 intent-completion, 2026-08-03]: the + // binary's clause is a plain `< 0.05` compare -- but this evaluator was + // DEAD CODE in shipped 4.10 (never called), so the boundary flap was + // never exercised. Live, a bank fraction hovering at 0.05 under fire + // flips the panic-arm mode EVERY FRAME (observed: hundreds of ON/off + // pairs), churning the mode mask, the lamp, and the arm audio cue into a + // ~10 Hz stutter tick. The engine's own idiom for exactly this is the + // dual-threshold pair (HeatSink coolantActive: 0.003 on / 0.0025 off); + // mirrored here: ARM below 0.05 (the binary constant @0049fb50), stay + // armed until the fraction RECOVERS above 0.06. No new members -- the + // current ejectPermitted is the state. + Scalar coolantGate = ejectPermitted ? 0.06f : 0.05f; ejectPermitted = (liveWeapons < ejectMinWeapons) // @0x448 floor (inert at 0) || (liveGenerators == 0) - || (coolantFrac < 0.05f) // _DAT_0049fb50 + || (coolantFrac < coolantGate) // _DAT_0049fb50 + hysteresis || (gimped && noviceSim); return ejectPermitted; }