FIXES (compile clean; exe link pending -- a game client still holds btl4.exe):
#57 respawn latch: deathPending was released in ONE place (btplayer.cpp:343) and
only if a LATER re-post happened to find the mech alive -- so if the +5s re-post
landed before the drop-zone reply, or never arrived, the flag stayed set while
the pilot respawned and fought on, and their NEXT death hit the dedup at :391
and was swallowed whole (no warp, no tally, no hunt) for the rest of the
process. Tonight 3 of 3 deaths in the final round were swallowed, each by a
player who had respawned successfully earlier in the same process. Clear moved
to the actual completion point (after Mech::Reset at the drop zone) + the four
abandon paths that also stranded it. Cycle logging promoted to always-on
(START / RESET / SWALLOWED warning) + a RESPAWN matchlog record.
#58 reticle callsign plate drew as a SOLID RECTANGLE on some maps: my
dpl2d_DrawTexturedRect bound a texture but never set COLOROP/ALPHAOP, and
L4D3D.cpp:1085 sets both to SELECTARG1 from TFACTOR (ignores the texture, fills
with a constant). Which state was live depended on what the 3D pass drew last
-- hence 'depends on the level'. Now sets MODULATE texture x diffuse for both
channels and restores. Latent sibling noted (CameraHUDDrawQuad, same omission).
ROOT-CAUSE DOC (no code): docs/KD_SCOREBOARD_PLAN.md. Headlines:
- the port reads DEATHS from the WRONG FIELD: the binary's PilotList draws
+0x27c/+0x280; we labelled +0x280 'pad_0x280', never write it, and
substituted the engine's Player::deathCount (+0x200, the respawn identity
number seeded to -2) -> remote rows read a clamped fake 0 by construction;
- BTPlayer::VehicleDeadMessageHandler @0x4c05c4 is MISSING from our decomp
export (functions_index.tsv jumps 4c052c -> 4c083c, verified) -- that silence
is what produced the 'pad' belief. An absent function is not evidence of an
absent behaviour;
- neither counter rides an update record, so divergence never self-heals and
bystanders show 0/0 all mission; BTPlayerCountObservedDeath is unreachable
dead code;
- 'a kill I didn't earn' = last-hitter-takes-all via lastInflictingID, and
COLLISIONS count (5 of 47 deaths had a type=0 killing blow);
- the phantom kill is authentic 1995 (the kill handler bumps the victim's
killCount too);
- btplayer.cpp:453 does simulationFlags |= 0x1 where the binary does
ForceUpdate() -- bit 0 is DelayWatchersFlag and nothing clears it, so the
first death of any pilot permanently disables ExecuteWatchers on that
player's simulation. Filing separately.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0166KTsC7ADm7VXEi1HF1jNg