Issue #21: overcharge-bricked weapons -- latent ARCADE bug, deliberate divergence
The tester's ER small laser died permanently (recharge arc + ready dot dark, no fire) after idle seek-gear clicking. Root cause, byte-verified + headless- reproduced -- a latent bug in the SHIPPED ARCADE BINARY: - The charge integrates toward the GENERATOR voltage (@004ba838), not the gear target; "full" is only detected inside the +-1% snap window around seekVoltage[idx] (@004ba738), and overcharge reads ZERO (the byte-verified _DAT_004ba830 = 0.0 clamp). - Toggle seek while a charge is in flight and the level can land ABOVE the new gear's window: rechargeLevel pins to 0, the ==1.0 Loaded test can never fire, and charging continues to the generator ceiling where EVERY gear reads overcharged. Permanent brick; generator reselect cannot help. - The arcade dodged it by circumstance (locked 60 fps, rare seek use); the port's clickable seek button hits it in seconds of casual clicking. Fix (marked divergence in the Loading tick): overcharge counts as fully charged -> Loaded. The arcade's own discharge algebra says full == the gear's seek voltage, so an overcharged weapon IS full. Verified: the same 2.5-min BT_SEEKTEST abuse that bricked the laser pre-fix now fires 38 overcharge rescues and ends Loaded/pct=1. [seek] log now also prints the per-gear voltage table + gen voltages (diagnosis instrumentation). Ruled out on the way (documented in #21): overheat fuse (no firing occurred; a 4-min autofire+coolant-abuse run wouldn't fuse), generator detach (gen cycling + healthy siblings), seek-table corruption (table {6000,7000,8000, 9900} healthy). KB: decomp-reference.md records the arcade-latent-bug analysis. 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
e9db161404
commit
21b2bfc1c9
@@ -510,6 +510,32 @@ void
|
||||
weaponAlarm.SetLevel(2); // -> Loaded
|
||||
break;
|
||||
}
|
||||
// OVERCHARGE RESCUE (issue #21, 2026-07-21) -- a DELIBERATE
|
||||
// divergence from the binary, which DEADLOCKS here: change the
|
||||
// seek gear while a charge is in flight and the level can land
|
||||
// ABOVE the new gear's snap window (level/seekV > 1.01) -- the
|
||||
// byte-verified ComputeOutputVoltage clamp then zeroes
|
||||
// rechargeLevel (_DAT_004ba830 = 0.0) and the ==1.0 Loaded test
|
||||
// can never fire again while TrackSeekVoltage keeps charging
|
||||
// toward the generator voltage: the weapon is PERMANENTLY
|
||||
// bricked (arc dark, dot dark, never fires -- reproduced
|
||||
// headless, and trivial to trigger from the clickable seek
|
||||
// button; the pod's locked 60 fps + rare seek use hid it).
|
||||
// The arcade's own math says "full == the gear's seek voltage"
|
||||
// (discharge energy computes from seekV[rec]), so an
|
||||
// overcharged weapon IS fully charged -- treat it as Loaded.
|
||||
if (currentLevel > seekVoltage[seekVoltageIndex]
|
||||
&& seekVoltage[seekVoltageIndex] > 0.0f)
|
||||
{
|
||||
rechargeLevel = 1.0f; // full (the display/damage ratio)
|
||||
weaponAlarm.SetLevel(2); // -> Loaded
|
||||
if (getenv("BT_SEEK_LOG"))
|
||||
DEBUG_STREAM << "[seek] " << GetName()
|
||||
<< " overcharge rescue: level=" << currentLevel
|
||||
<< " > seekV=" << seekVoltage[seekVoltageIndex]
|
||||
<< " -> Loaded" << std::endl;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -683,7 +709,16 @@ void
|
||||
ResetFiringState(); // @004ba9a8
|
||||
}
|
||||
if (getenv("BT_SEEK_LOG"))
|
||||
DEBUG_STREAM << "[seek] " << GetName() << " -> gear " << next << std::endl;
|
||||
{
|
||||
Generator *src = (Generator *)ResolveVoltageSource();
|
||||
DEBUG_STREAM << "[seek] " << GetName() << " -> gear " << next
|
||||
<< " seekV[" << next << "]=" << seekVoltage[next]
|
||||
<< " table={" << seekVoltage[0] << "," << seekVoltage[1] << ","
|
||||
<< seekVoltage[2] << "," << seekVoltage[3] << "," << seekVoltage[4]
|
||||
<< "} max=" << maxSeekVoltageIndex << " level=" << currentLevel
|
||||
<< " genV=" << (src ? src->MeasuredVoltage() : -1.0f)
|
||||
<< " genRated=" << (src ? src->RatedVoltageOf() : -1.0f) << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user