docs(multiplayer): close snapshot disconnect race note

This commit is contained in:
Josh Creek
2026-09-01 17:09:23 +01:00
parent d1bcb51225
commit c5f6c95ca5
+1 -1
View File
@@ -1388,7 +1388,7 @@ godot --path Game -- --connect 127.0.0.1:27015 --name Alice
**Split-screen.** Tracked separately in `TODO.md`; unrelated to this effort, though the camera-outside-the-ship structure that enables it is the same structure this plan relies on.
**A second, distinct source of the same "Unable to send packet on channel N, max channels: 0" stderr noise — item E of §0, in `networked_match.gd`'s `_broadcast_snapshot` rather than `match_net.gd`'s `_remove_player`.** Only reproduced via the deliberately-adversarial `client-abuse-malformed` smoke role: `_broadcast_snapshot`'s per-peer send races `match_sim.gd`'s host-forced `disconnect_peer()` (the abuse-disconnect path) against the same tick's `connected_peers.has(slot.peer_id)` snapshot, the same general shape of race as the fixed site but on a different call path (a server-initiated forced disconnect, not a normal client-initiated one) and not currently known to be reachable from ordinary play. Left for a dedicated pass — not fixed under this round's time pressure, since the fixed site (gotcha 46's neighbor, the round-2 addendum above) was the one an adversarial review actually flagged as a "clean stderr" violation in the tests this project's own conventions rely on.
**Item E of §0 — stale snapshot sends after forced disconnect — is now resolved locally.** `MatchSim.send_snapshot()` validates the live peer and `NetSim._fire()` revalidates delayed targets immediately before dispatch, covering the deliberately adversarial `client-abuse-malformed` path as well as normal disconnects. A full multi-process abuse smoke remains a useful runtime check, but the stale-target call sites no longer enter Godot's RPC path after peer teardown.
#### Deployment wiring update (2026-09-01)
The current working implementation now wires `deploy/k8s/base/fleet.yaml` to the digest-pinned `game-server` supervisor target, the in-cluster control-plane Service, workload roster materialization, signing/drain secret references, downward-API server/image identity, and the required game-server egress policy. `kubectl kustomize deploy/k8s/base` and `server/security/test_fleet_manifests.py` pass. The older 8.28 narrative above still records the pre-wiring state; live Agones, operator secret/image replacement, and real cluster readiness remain explicit gates.