Connection audit: every connect/disconnect scenario handled + verified
Systematic actor-death x lifecycle-phase sweep (operator request after the WaitingForEgg zombie). New handling, all live-verified: 1. PRE-EGG console-pad loss (the real zombie phase): before the egg the pod's only link is the console pad -- the game socket doesn't exist, so the earlier RelayGameDown hook could never fire (the verification run itself caught this). Detection now lives in HostDisconnectedMessageHandler ConsoleHostType (relayMode + pre-scene -> BTRelayRejoinNow); mesh keeps 1995 behavior. 2. MID-MISSION relay loss: the STOP is relay-sent (1995: the console owned the clock), so a pod losing its relay mid-match played a peer-less FOREVER-mission. RelayGameDown (scene presented) now posts StopMissionMessage at +15s -> normal end -> lobby relaunch. 3. POST-RELEASE pod death stalled the round (survivors wait forever on the dead peer's connection gate): relay _abort_round -> route -11 REJOIN to survivors -> everyone re-seats in seconds (reset-first ordering makes the drop cascade re-trigger-proof). 4. BTRelayRejoinNow carries BT_SEAT_CLAIM (mirrored tag): without it the rejoiner's own reclaim-hold blocked assignment -> ROSTER FULL loop for the 90s window (found by verification round 2). 5. Beacon NAT keepalive (SIO_KEEPALIVE_VALS 60s/10s) so long between-rounds waits can't be silently unseated. 6. BT_LOG_APPEND=1 preserves the log across lobby-loop generations (truncation erased round-1 verification evidence). Verified non-issues: relay pods never bind the -net listener (no double-launch collision on the internet path); mesh bind-fail exits cleanly. Full matrix + evidence: context/multiplayer.md; scratchpad/audit_verify.sh is the repeatable rig. 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
56ca2f5c13
commit
c8cba8c764
@@ -468,6 +468,38 @@ phase). Plan: `~/.claude/plans/partitioned-snuggling-piglet.md`.
|
||||
per-event cost) is an OPEN perf item -- deliberately not attempted pre-8-player-night.
|
||||
Diags: `[loadphase]` markers always on; the full queue dump gates on `BT_LOAD_DIAG=1`;
|
||||
`GeneralEventQueue::DumpBlockers` + the named fallback in `Event::DumpData`.
|
||||
- **CONNECT/DISCONNECT AUDIT (2026-07-23) [T2, every cell verified]**: systematic sweep of
|
||||
actor-death x lifecycle-phase, requested by the operator after the WaitingForEgg zombie.
|
||||
VERIFIED-HANDLED (previously): relay-not-up patient retry; seated-quit seat-free+reclaim;
|
||||
pre-launch-quit trim; mid-mission peer death (frozen mech, authentic; matchcheck flags);
|
||||
normal end lobby loop; upload-fail file-keep; scanner/HELLO validation; mass-drop crash fix.
|
||||
FIXED THIS AUDIT (all live-verified via scratchpad/audit_verify.sh + focused runs):
|
||||
1. **Pre-egg console-pad loss** (the REAL zombie phase): before the egg, the pod's ONLY link
|
||||
is the console pad -- the game socket doesn't exist yet, so the first fix's RelayGameDown
|
||||
hook could never fire (caught by the verification itself). Detection now lives in
|
||||
`HostDisconnectedMessageHandler` case ConsoleHostType (relayMode && !scene-presented ->
|
||||
`BTRelayRejoinNow`); mesh keeps 1995 console-less behavior. Verified 2x in one run.
|
||||
2. **Post-egg pre-mission relay loss**: RelayGameDown -> rejoin (the original fix). ✓
|
||||
3. **Mid-mission relay loss = forever-mission**: the STOP is relay-sent (1995: console owns
|
||||
the clock), so a pod losing its relay mid-match played alone forever. Now RelayGameDown
|
||||
(scene presented) posts `StopMissionMessage` at +15s -> normal end path -> lobby relaunch
|
||||
-> patient wait. Verified: scene LIVE -> relay killed -> 15s -> clean RunMissions exit.
|
||||
4. **Post-release pod death stalls the round**: survivors wait forever on the dead peer's
|
||||
connection gate. Relay `_abort_round` (registered-conn drop while eggs_released &&
|
||||
launches<2): reset-first (re-trigger-proof), then route **-11 REJOIN** to survivors ->
|
||||
`BTRelayRejoinNow` -> everyone re-seats in seconds. Verified: kill-during-load ->
|
||||
ROUND ABORT -> survivor rejoined -> seat RECLAIMED immediately.
|
||||
5. **`BTRelayRejoinNow` carries `BT_SEAT_CLAIM`** (from the mirrored tag): without it the
|
||||
rejoiner's OWN reclaim-hold blocked generic assignment -> ROSTER FULL retry-loop for the
|
||||
whole 90s window (found by verification round 2).
|
||||
6. **Beacon NAT keepalive**: SIO_KEEPALIVE_VALS 60s/10s on the seat beacon -- long
|
||||
between-rounds waits can't be silently unseated by NAT idle timeout. [T3 -- not
|
||||
NAT-tested]
|
||||
VERIFIED NON-ISSUES: relay-mode pods never bind the -net console listener (early dial-out
|
||||
return @L4NET~900) -- no double-launch port collision on the internet path; mesh bind-fail
|
||||
exits cleanly via PostQuitMessage. TOOLING: `BT_LOG_APPEND=1` (btl4main) preserves the log
|
||||
across lobby-loop generations -- REQUIRED for multi-generation forensics (truncation erased
|
||||
the evidence in verification round 1).
|
||||
- **LOBBY LOOP + SEAT RECLAIM (2026-07-23) [T2]**: the between-rounds arcade flow. Field
|
||||
problem (first playtest night): at mission end every pod EXITED -> seats dropped -> every
|
||||
round required everyone to re-run join.bat, and the operator could not adjust the mission.
|
||||
|
||||
Reference in New Issue
Block a user