night14: #137 fix write-up + close

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018SgmXGNMXavXiafKXf9MDC
This commit is contained in:
Joe DiPrima
2026-08-09 16:20:19 -05:00
co-authored by Claude Opus 5
parent 0d6ed40db9
commit 84f8b1c415
+69
View File
@@ -0,0 +1,69 @@
"""#137: post the fix write-up. ASCII only."""
import sys
sys.path.insert(0, r"C:\git\bt411\scratchpad\night7")
import gitea
BODY = """**FIXED** (`0d6ed40`) -- and my previous two analyses of this ticket were both wrong, so here is
the final, measured story.
## The fix is ONE LINE, and it is the binary's own
The binary Reset's SECOND instruction is `FUN_00408440(mech+0x58c, param_2)` -- re-seed the
Point3D at `+0x58c` to the new origin. `+0x58c` is the **previous-position memory** of the
AccelerationLastFrame ring feed (`+0x81c/0x824/0x828/0x82c`). The port reconstructed the ring
faithfully but its Reset never got that line. Restored as:
```cpp
accelPrevPos = origin.linearPosition; // binary +0x58c re-seed
```
## What actually happened at a respawn
1. The respawn TELEPORTS the mech; `accelPrevPos` still held the death position.
2. First post-respawn sample: `|newPos - prevPos| / dt` = **teleport distance / dt ~ 1e5** enters
the velocity ring; the ring-mean derivative spikes `AccelerationLastFrame` (pure forward, with
an opposite-sign echo ~15 frames later as the sample rotates out of the 15-ring).
3. The myomer drive-heat integrator `@004b8d18`:
`termAccel = (1-accEff) * |v| * |a| * m * dt = 0.2 * 40 * 1.04e5 * 75000 * 0.044 = 2.75e9`
-- one tick deposits ~3e9 into `pendingHeat -> heatEnergy`.
4. The freshly-reset myomers snaps 77 -> ~9000 against `failT=2000` -> `speedEffect 0` ->
`speedDemand *= 0` -> **"respawned with heat maxed, unable to move until it cools"**. The
excess then sheds into Condenser5 and GeneratorD -- Oracle's "loop 5 and generator D heating
up" clause, literally.
**Why ~8% and why it eluded everyone:** the deposit needs `|v|` in the same 1-2 frames, so only
pilots whose throttle was still forward at the respawn (physical lever / HOTAS -- exactly who
reported it) got the freeze. Idle-throttle respawns deposit nothing. That is also why frozen
respawns were a strict subset of died-hot ones: died hot = was running hard = lever still forward.
## Measured (same abusive bench: 0.95 throttle, continuous autofire)
| | before | after |
|---|---|---|
| deposits >1e7 near resets | up to **3.35e9**, every one 3-4 lines after a reset | **0** |
| frozen respawns | 4-6 of 7 | **0 of 7** |
| post-reset myomers T | 7,700-12,100 | 77-178 (degradeT is 1000) |
## For the record: what it was NOT (each killed by operand data)
Not the reset (T=77 at every reset, roster-wide). Not stale pendingHeat (1-frame bound, +1.2K).
Not death-window accumulation (consumers tick the wreck). Not conduction (roster snapshot: all
partners at 77; flow trap: zero e6 flows into the myomers). Not drag or impulses (both trapped:
never fired). And not my earlier "players accelerate to top speed" close -- arithmetically
impossible (input ceiling ~60 deg/s vs the observed 1,100-21,000 deg/s snap); the KB paragraph
carrying that claim is corrected.
The in-life governor is untouched and authentic: sustained top-speed running still derates the
myomers (constants byte-verified). What is gone is the respawn injecting a teleport-sized heat
slug.
Credit where due: the operator called the shape of this from the start -- *"maybe the math gets
screwy in respawning while some systems are ticking while values are being reset."*
**Unreleased; needs a build cut. Field-verify:** respawn while holding the throttle forward on a
HOTAS -- the mech should drive off cleanly with a cold heat bar every time. Gotcha #30 records the
class so the next dropped re-seed gets caught in review."""
gitea.comment(137, BODY)
gitea.call("/issues/137", method="PATCH", payload={"state": "closed"})
print("posted + closed #137")