night14: tracker housekeeping for the 4.11.857 playtest

Closed 5 confirmed-fixed (#52 #108 #140 #141 #142), commented 3 (#135 #146
#147), REOPENED #137, filed #149-#158.

#137 reopened because I closed it wrongly.  Field scan of all four logs: 5 of
61 respawns froze (throttle up, speedDemand pinned at 0) across THREE machines
-- ~8%, which is why a bench that reset cleanly every time never saw it.  The
myomers come up Overheating in the same breath as Mech::Reset, before any
running could earn the heat.  Oracle's 'unable to move' was the detail that
disproved my 'it earns the heat by respawning under throttle' explanation.

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 11:20:21 -05:00
co-authored by Claude Opus 5
parent 0961a0b3f3
commit 92783b9935
+299
View File
@@ -0,0 +1,299 @@
"""Night 14 (build 4.11.857) housekeeping: close what the field confirmed, reopen
#137 with evidence, and file the new reports. ASCII only."""
import sys
sys.path.insert(0, r"C:\git\bt411\scratchpad\night7")
import gitea
FIELD = ("Field-verified on **4.11.857** (playtest 2026-08-08, 4 testers: Oracle/SCREECH, "
"Sauron/XIAOLONG, santo/MS-FIREFLY, RajelAran/GAMERSLAB).")
# ---------------------------------------------------------------- CLOSE ----
CLOSE = {
52: "**CONFIRMED FIXED.** " + FIELD + "\n\nOracle: *\"no skating observed\"*.\n\n"
"Cross-check: the `[skate]` detector fires zero times across all four logs.\n\n"
"**#130 (Vulture skating) should be re-tested against this build** -- it was always "
"suspected to be the same defect.",
108: "**CONFIRMED FIXED.** " + FIELD + "\n\nOracle: *\"Lynx panic ejected and didn't ghost\"*.\n\n"
"The eject path now runs the full death tail, so the respawn trigger fires.",
142: "**CONFIRMED FIXED.** " + FIELD + "\n\nOracle: *\"Fixed, button indicating state and mech "
"is standing after respawn\"* -- both halves: the indicator animates, and the "
"`Mech::Reset` posture clear brings you back standing.",
140: "**CONFIRMED FIXED.** " + FIELD + "\n\nOracle: *\"It is not overwriting the saved settings\"*.",
141: "**CONFIRMED FIXED.** " + FIELD + "\n\nOracle: *\"Fixed\"*. VGL Lynx, independently and "
"before seeing the notes: *\"Missiles seem to be launching from weapon ports\"* -- which is "
"the symptom stated positively.\n\n"
"Worth noting the same stale-segment-cache defect was fixed on the **beam muzzle** path in "
"the same sweep; nobody had reported that one, and a peer's beams would have had the "
"identical wrong origin whenever the shooter was twisted.",
}
# --------------------------------------------------------------- COMMENT ----
COMMENT = {
147: "**Not reproduced on 4.11.857** -- Oracle: *\"I have been unable to recreate the range caret "
"issue today ... but only tried in Solo\"*, and later *\"Not observed\"*.\n\n"
"Cross-check: zero `NaN TRAPPED` receipts in any of the four field logs, so the trap never "
"had to fire either.\n\n"
"**Keeping this OPEN.** One clean night is not proof for a defect whose whole signature is "
"'rare, and sticky once it happens' -- and solo exercises far less of the targeting path "
"than a 4-way drop. If the caret dies again, `BT_RANGE_LOG=1` now names the frame.",
146: "**Working on 4.11.857, with a nuance worth recording.** Oracle: *\"Initial spawn/respawn "
"throttle is idle and then begins to respond to match my throttle position on my X56 "
"without moving it.\"* That is the fix behaving correctly on a PHYSICAL throttle: the "
"virtual lever is released at respawn, then re-syncs to where the hardware lever actually "
"sits.\n\n"
"**But see the new report about being unable to move after respawn until the throttle is "
"cycled.** A HOTAS user who respawns with the lever already forward now gets no motion "
"until the axis next changes -- that may be this fix's side effect rather than a separate "
"bug, and the two need separating before either is 'fixed'.",
135: "**Related field report on 4.11.857** (Oracle): *\"buttons for gens are not flashing when "
"they leak\"* -- observed in GLASS mode this time, where this ticket was originally about "
"the normal (non-glass) screen path. Same annunciator chain, so treat them together: the "
"coolant-leak condition (cond 2) is supposed to light the per-generator lamps.",
}
# ------------------------------------------------------------------ NEW ----
NEW = [
("REOPEN #137 -- placeholder", None), # handled separately below
]
def main():
for num, body in CLOSE.items():
gitea.close(num, body)
for num, body in COMMENT.items():
gitea.comment(num, body)
# ---- #137: reopen. I closed this wrongly; the field disproved my analysis.
gitea.comment(137,
"**REOPENING -- I closed this incorrectly, and the field data disproves my analysis.**\n\n"
"I closed it as 'not a bug: the mech respawns still under throttle and earns the heat "
"honestly'. Oracle pushed back: *\"not sure if the bug report was understood ... the mech "
"is initially unable to move until it cools off sufficiently to start moving. This is "
"abnormal.\"* He is right, and 'unable to move' is the detail that kills my explanation -- "
"a mech that cannot move cannot be earning heat by running.\n\n"
"## Measured on 4.11.857, all four field logs\n\n"
"Scanning every respawn for the freeze signature (throttle up, speedDemand pinned at 0):\n\n"
"| player | respawns | FROZE |\n|---|---|---|\n"
"| Oracle / SCREECH | 16 | **2** |\n| Sauron / XIAOLONG | 19 | **2** |\n"
"| RajelAran / GAMERSLAB | 16 | **1** |\n| santo / MS-FIREFLY | 10 | 0 |\n\n"
"**5 of 61 respawns (~8%)**, across three independent machines.\n\n"
"The sequence at one of them (Oracle, log line 48584) is unambiguous:\n\n"
"```\n"
"[mppr] thr=0.847 -> speedDemand=44.87 <- moving normally, pre-death\n"
"[respawn] Mech::Reset 2:21 healed+moved\n"
"[techstat] Myomers condition 1 CLEARED <- Damaged cleared OK\n"
"[techstat] Myomers condition 2 CLEARED <- Leaking cleared OK\n"
"[techstat] Myomers condition 3 SET <- OVERHEATING, AT the reset\n"
"[mppr] thr=0.762 -> speedDemand=0 <- FROZEN\n"
"```\n\n"
"The reset clears the damage and leak flags correctly and then the myomers come up "
"**already overheating**, in the same breath as the reset -- before any running could have "
"happened. The myomer heat-freeze (`speedEffect` -> `speedDemand *= it`) then pins speed "
"at zero, which is exactly the reported 'cannot move until it cools'.\n\n"
"## Why my bench missed it\n\n"
"It is **intermittent (~8%)**. My synthetic bench reset cleanly every single time and "
"reported `T=77 start=77` for every heat-bearing subsystem including all six Condensers -- "
"so I concluded the reset path was correct and closed the ticket. A bench that never "
"reproduces the failure is not evidence the failure does not exist; I treated it as such.\n\n"
"## Next\n\n"
"The temperature is NOT logged in the field (`BT_HEAT_LOG` is off), so the next step is a "
"bench that reproduces the freeze rather than the happy path -- repeated death/respawn "
"under load until a reset lands hot -- and then reads `[heat-reset]` on the failing one. "
"The ~8% rate suggests a race or an ordering dependency rather than a plain missing reset, "
"since the plain path demonstrably works.")
gitea.call("/issues/137", method="PATCH", payload={"state": "open"})
print("REOPENED #137")
made = []
def new(title, body, ):
i = gitea.create(title, body)
made.append(i["number"])
new("PERFORMANCE REGRESSION 817 -> 857: hard stalls at mission load (glass)",
"Oracle: *\"frame rate very poor with glass cockpit starting with this build. Only "
"observed by Oracle, Sauron using glass had no issue. Oracle had no performance issues in "
"past with glass.\"*\n\n"
"**Confirmed, and it is a real regression -- but it is STUTTER, not low framerate.**\n\n"
"## Same machine, previous build vs this one (Oracle / SCREECH)\n\n"
"| build | median frame | stalls >50ms | worst |\n|---|---|---|---|\n"
"| 4.11.817 (Aug 6) | 5.79 ms | **0** (0.00%) | 15.4 ms |\n"
"| 4.11.857 (Aug 8) | 5.87 ms | **97** (6.70%) | 103.7 ms |\n\n"
"His steady state is **identical** (5.79 -> 5.87 ms). 817 had literally zero stalls; 857 "
"has 97, and the worst frame went 15 ms -> 104 ms.\n\n"
"## Why only Oracle noticed\n\n"
"| player | median | stalls >50ms |\n|---|---|---|\n"
"| Oracle | 5.87 ms (170 fps) | 97 |\n| santo | 3.55 ms | 0 |\n"
"| Sauron | 12.53 ms (80 fps) | 0 |\n| RajelAran | 6.70 ms | 0 |\n\n"
"Oracle has the **best median of the group** and Sauron -- who reported no problem -- has "
"the worst. Smooth-but-slower reads as fine; fast-with-hitches reads as broken. The "
"distribution is bimodal: **all 97 of Oracle's slow blocks are >50 ms**, nothing in "
"between.\n\n"
"## Where\n\n"
"All 97 stalls are one contiguous window (log lines 30307-32979, 30-32% through the "
"session), and it begins exactly at **mission load**, as peer mechs stream in:\n\n"
"```\n"
"[clipfix] mech 15A1FF38 -> EXTERIOR (lean)\n"
"[loadclips] end: fScale=0.8 ...\n"
"[spike] dt=0.356 turn=0 thr=0\n"
"[rstat] frames=10 avg=103.713ms maxDraw=518.497 maxPresent=7.046 batches=547 culled=226\n"
"```\n\n"
"`maxDraw=518ms` against `maxPresent=7ms` -- it is **draw time**, not vsync/present.\n\n"
"## NOT the instrumentation\n\n"
"The standing theory was that accumulated logging is slowing things down. The data says "
"no: the **median frame time is unchanged between builds** (5.79 -> 5.87 ms) and log "
"volumes are comparable across players (6.1-6.9 MB). Logging would raise the floor "
"everywhere, not add isolated 100 ms draw spikes in one window.\n\n"
"## Prime suspect\n\n"
"The #141 stale-segment-cache fix in this same build. It routes muzzle/beam queries "
"through `JointedMover::GetSegmentToWorld`, which -- when joints are modified, i.e. every "
"animating frame -- walks the whole segment table and marks every segment dirty, forcing "
"the hierarchy to re-derive. That is now on per-frame paths (`BTResolveWeaponMuzzle`, and "
"the energy-beam gun-port loop which runs per weapon per mech per frame). With several "
"mechs newly loaded it multiplies out. Faithful to the binary, but the binary was not "
"calling it this often.\n\n"
"**Next:** time `GetSegmentToWorld` per frame and count calls per mech; if it is the "
"cause, cache the resolved frame per (mech, segment) for the duration of a frame rather "
"than re-deriving per weapon.")
new("Double KILL credit: one kill counted twice",
"Two independent reports on 4.11.857:\n\n"
"* RajelAran: *\"in match beginning 20:33, I got a double kill on Oracle. One kill, "
"counted twice\"*\n"
"* Oracle: *\"12:12AM ET - Oracle killed Conn Man and got 2 kills credited. Rajel also "
"the same when killing me.\"*\n\n"
"Log cross-check (Oracle/SCREECH): the scoreboard `kills=` reading jumps **2 -> 4**, "
"skipping 3.\n\n"
"## Suspect (identified 2026-08-07, never fixed)\n\n"
"In the type-2 (Kill) arm of the score handler:\n\n"
"```c\n"
"++killCount; // this player\n"
"if (sender_owner) ++sender_owner->killCount; // the mech named by senderMechID\n"
"```\n\n"
"For type 2, `senderMechID` is the **victim**. The second increment is justified in the "
"comment by the SOLO case, where the dummy target has no owning player -- but in MP the "
"victim *does* have an owner, so the credit lands twice. In a 1v1 exchange both "
"increments can even land on the same scoreboard row, which is what 'one kill counted "
"twice' looks like.\n\n"
"Needs a 2-node bench confirming the victim's `killCount` moves on a kill.")
new("PANIC eject scores -499 instead of 0 (double-charged)",
"Oracle, 4.11.857, **confirmed twice**: *\"Had 1000 points, leaked out all coolant, hit "
"'panic' and ended up with -499 points. Should it have been zero points because "
"1000 - 1000 = 0 for ejecting? Why the extra -499 points?\"*\n\n"
"The shipped `Role::Default` carries `deathPenalty=500`, and the death tail applies "
"`-specialCaseDeathPenalty`. 1000 - 500 = 500, so -499 is roughly **1000 - 500 - 999**, "
"i.e. the penalty looks like it is being applied more than once, or the eject path "
"charges both the normal death cost and a separate panic cost.\n\n"
"Note this is the tail of **#134** (panic eject carried NO score penalty) -- that fix "
"landed and now over-charges. The two should be read together.\n\n"
"Also from the same report, lower confidence / subjective: *\"Missiles seem to be scoring "
"a little low (twin LRM15s scored ~30-40 points)\"* -- worth a damage-vs-score comparison "
"rather than a code change on its own.")
new("REGRESSION: torso no longer auto-recentres in ANY control mode",
"Oracle, 4.11.857: *\"Torso is no longer recentering on its own in any mode "
"Bas/Mid/Adv.\"*\n\n"
"**This is a regression from the control-mode fix in this build.** That change replaced "
"the Basic-mode re-centre write from `centerCommand` (@0x208, the HELD-button cell that "
"nothing released -- the bug where the centering *fought* the pilot) with "
"`recenterActive` (@0x274), a ONE-SHOT that self-clears on settle, matching @004afbe0.\n\n"
"The one-shot is what the binary does on the mode CHANGE. What it does not do is provide "
"the CONTINUOUS auto-centring that Basic mode is supposed to have per the 1995 manual "
"(BAS = joystick turns the mech, **no torso twist**). So the fix removed a behaviour that "
"was previously coming -- incorrectly, but coming -- from the stuck cell.\n\n"
"Both halves need to be true at once: Basic must hold the torso centred, without the "
"held-cell latch that made it fight the stick in Standard/Veteran.\n\n"
"The original complaint (Sauron: cycling to advanced and back made the centering fight "
"the controls) is fixed and should stay fixed -- verify any change against both.")
new("Basic-mode elevation limit does not clamp the CURRENT view",
"Oracle, 4.11.857: *\"Basic mode does limit downward view to 'half', but only after "
"cycling off 'Basic' and then back to 'Basic'. If in Mid or Advanced and move view past "
"'half' down and then switch to Basic, nothing happens until I move the control stick in "
"the pitch axis and then the view immediately snaps up to 'half' limit.\"*\n\n"
"The elevation-limit swap (Basic gets @0x228/@0x22C = full top, HALF bottom; "
"Standard/Veteran get @0x230/@0x234) is new in this build and previously was never "
"implemented at all. It writes the LIMITS but does not re-clamp `currentElevation`, so an "
"already-out-of-range view stays until the next pitch input clamps it.\n\n"
"Small fix: clamp current elevation into the new pair at the moment of the swap. Worth "
"checking against the binary whether it clamps on switch or leaves it to the sim -- the "
"snap-on-next-input behaviour may be authentic.\n\n"
"Also: Oracle asked what 'settles the HUD horizon' meant in the release note -- that was "
"my wording for Basic raising the HUD's `flickerActive` (@0x2A0) so the horizon "
"re-settles with the re-centred torso. Needs a plainer description for testers.")
new("Overheated generator never came back online; no generator-out alarm on thermal trip",
"Oracle, 4.11.857: *\"Noticed a generator that overheated never came back online even "
"after cooling off completely. Also noticed the generator out message doesn't sound after "
"a generator fails due to overheat. The second and third time I overheated a generator "
"for the test it did come back online after cooling halfway, and I heard the generator "
"out warning upon the generator coming back online.\"*\n\n"
"Two defects, and the intermittency is the interesting part -- the same test gave a stuck "
"generator once and a recovering one twice.\n\n"
"1. **Stuck offline after thermal trip.** The thermal breaker in `GeneratorSimulation` "
"produces `stateAlarm 4` (GeneratorOut); recovery should re-arm once temperature falls. "
"Related known nuance (context/decomp-reference.md): the generator sim has NO Ready-case "
"recompute, so a generator can hold stale state until *some* transition recomputes it.\n"
"2. **Alarm timing.** The generator-out warning did not sound on the trip, but DID sound "
"later on the way back online -- so the annunciator appears tied to the wrong edge.\n\n"
"Cross-check available: `[techstat] GeneratorX condition 3` (Overheating) transitions are "
"in the field logs and are balanced overall, so this is about the stateAlarm/voltage path "
"rather than the heat flag.")
new("PANIC lamp lit: rapid flicker, and engineering + weapon MFD buttons stop responding",
"Oracle, 4.11.857: *\"When the panic button lights it flickers very rapidly and the "
"engineering and weapon MFDs buttons stop responding. Other MFDs continue to respond to "
"button presses (using mouse). I also have mapped controls on my HOTAS for some of those "
"MFD buttons and they also stop working when the panic button is lit. Radar, Scoring and "
"coolant MFDs keep working.\"*\n\n"
"Two symptoms, probably one cause. Arming eject raises the panic-armed mode "
"**0x200000**, which drives the physical PANIC lamp (`MakeLinkedLamp`), the eject-mode "
"gauge elements, **and keypad routing** -- so eng/weapon buttons going dead while radar/"
"scoring/coolant keep working is consistent with the eject mode capturing exactly those "
"banks. That part may well be AUTHENTIC (the pod wants your hand on the eject decision, "
"not the weapon page).\n\n"
"The **rapid flicker is not** authentic: per the decode, the panic lamp is SOLID on arm "
"(engine linked-lamp semantic); FLASH is the GaugeAlarm `SetAlertState` overlay, which is "
"not authored for panic. A flickering panic lamp suggests the arm state is oscillating -- "
"and if it is oscillating, the keypad routing is being torn down and rebuilt repeatedly, "
"which would also explain buttons that 'stop responding' rather than cleanly switching.\n\n"
"Check `EvaluateEjectPermission` for a condition that chatters at the threshold "
"(coolantFrac < 0.05 is a likely candidate while coolant is draining).")
new("Fade-to-black at mission end is not happening",
"Oracle, 4.11.857: *\"Fade to black effect when mission ends is not happening\"*.\n\n"
"No log signature to cross-check against -- filing on the report. Worth confirming "
"whether this ever worked in a recent build or has been absent for a while.")
new("Crash at drop end (~23:59 ET, MS-FIREFLY / santo)",
"Conn Man / santo, 4.11.857: *\"Did not exit cleanly\"*, and Oracle: *\"Conn Man crashed "
"when drop ended ~11:59PM ET\"*.\n\n"
"`lastrun_steam.txt` is staged with the field logs. The launch bracketing shows the "
"process reaching WinMain normally, so this is a crash at teardown rather than a blocked "
"launch.\n\n"
"Teardown crashes have bitten this project before (the P5 teardown path). Needs the log "
"tail read against the mission-end sequence; the field log for that machine is staged as "
"`scratchpad/night14/steam_20260808_b_santo_MSFIREFLY.log`.\n\n"
"Also reported for the same player: *\"Conn Man was lagging sometimes during drops and "
"that caused the effect of missiles or direct fire exploding/hitting empty space\"* -- "
"likely a separate networking symptom, noted here only so the two are not conflated.")
new("Cannot move after respawn until the throttle is cycled (Abandoned Arena)",
"Sauron, 4.11.857: *\"respawned several times in Abandoned Arena and couldn't move until "
"throttle down/up or reversing out. Was near map edge and structure.\"*\n\n"
"**Two candidate causes, and they must be separated before either is called fixed:**\n\n"
"1. **A side effect of the #146 throttle fix in this build.** The virtual lever is now "
"released at respawn; a pilot whose PHYSICAL throttle is already forward gets no motion "
"until the axis next changes -- i.e. exactly 'couldn't move until throttle down/up'. "
"Oracle described the same mechanic positively (*\"throttle is idle and then begins to "
"respond to match my throttle position\"*), so the behaviour is real; the question is "
"whether it should re-sync immediately instead of on next change.\n"
"2. **Geometry.** 'Near map edge and structure' suggests spawning into or against "
"collision, which would also read as being stuck.\n\n"
"Note this is NOT the same as #137: there the mech is frozen by myomer heat with the "
"throttle up, and cycling the throttle does not help. Here cycling the throttle DOES "
"free it. The two will look identical to a player, so keep the distinguishing test in "
"mind: does throttle-cycling free it (this) or not (#137)?")
print("created:", made)
main()