# Multiplayer — next work Short, current checklist for online multiplayer. Historical design decisions, implementation evidence, and completed work stay in [`multiplayer-todo.md`](multiplayer-todo.md). ## Release blockers - [ ] **Phase 4 playtest:** a human playtest at roughly 100 ms RTT. Confirm that ship and ball interaction feel local and contact corrections feel like bumps rather than glitches. - [ ] **Phase 5 session:** complete a real 3v3 match with a mid-match disconnect and late joiner. - [ ] **Phase 6 external check:** run the exported Docker server and clients from separate machines over the internet, then play a full match. Keep this controlled-only until Steam identity is complete. ## Phase 7 — Steam, identity, discovery - [ ] Obtain the pinned GodotSteam client/server builds and Steamworks SDK access described in [`STEAM.md`](STEAM.md). - [ ] Run `make verify-steam-templates` with the custom executables and fix any custom-template failures. - [ ] Validate a two-account Steam SDR host/join using the existing explicit `NetworkManager` Steam transport. ENet direct-IP must keep passing its smoke test. - [ ] Build the Steam server browser: internet, LAN, favourites, and history. - [ ] Add Steam auth tickets, verified Steam identity in the roster, and a persistent ban list. This fixes the slot-reclaim security issue below. ## Phase 8 — casual and ranked matchmaking (1.0 launch blocker) Design and reasoning: [`docs/MATCHMAKING.md`](docs/MATCHMAKING.md). This is a different server model from the community-server one that exists today — players queue, a matchmaker groups them, and a server is allocated per match. Phase 7's Steam auth tickets are a hard prerequisite: a rating attached to a spoofable identity is worse than no rating. - [ ] Decide the rating algorithm (Glicko-2 recommended over Elo for a small launch population) and how a team result distributes across individuals. - [ ] Choose the backend language and hosting, and cost out allocated servers per match at expected population. - [ ] Stand up the backend: Steam auth ticket validation via the Steamworks Web API, queue, rating store, server allocator. - [ ] Add an assigned-roster server mode so only matched SteamIDs may claim a slot, replacing the first-come model. - [ ] Add server-authoritative match result reporting to the backend over a channel a client cannot forge. - [ ] Client queue UI: playlist select, estimated wait, accept/decline, connect-on-assignment, post-match rating delta. - [ ] Casual and ranked playlist rulesets (backfill, bots, abandon penalties, arena restriction — see the comparison table in the design doc). Server orchestration (same phase — the servers must autoscale and bill only for the duration of a match): - [ ] Choose the orchestrator (Agones on Kubernetes is the recommended default; it models allocation, readiness and per-match lifetime natively). - [ ] Fix readiness detection. Godot's stdout is block-buffered off a TTY, so `server_started` never appears in `docker logs` for a detached container — a log-grep readiness probe hangs forever. Probe the UDP socket, or flush. - [ ] Support more than one match per host: a per-container port from a range, or one address per match. `--port` defaults to 7777 and the Dockerfile hardcodes `EXPOSE 7777/udp`. - [ ] Add a no-show timeout so an allocated server that never fills abandons and exits instead of idling at cost. - [ ] Re-measure boot-to-listening on native x86_64 Linux. The repo's current figure is ~870 ms, measured under emulation on arm64 — a pessimistic bound. - [ ] Re-measure the SERVER.md sizing estimate (6–10 processes/core, 150–250 MB RSS) under real concurrency before it sizes a bill. - [ ] Keep `make verify-phase6` and `make verify-enet-integration` green: every allocation feature is opt-in via a `ServerConfig` flag defaulting to today's behaviour, with a second Compose file for the allocated path rather than mutating `compose.phase6-smoke.yml`. ## Known issues to resolve before public hosting - [ ] Slot reclaim is currently keyed by display name, so someone can take a disconnected player's reserved slot. Do not expose public servers before verified Steam identity lands. - [ ] Investigate occasional input loss during a long server stall; the existing sequence resync recovers it, but transport delivery is variable. - [ ] Fix the remaining `_broadcast_snapshot` packet-send stderr race. ## Decide after the latency playtest - [ ] Decide whether client-only, contact-cohort shadow physics is worthwhile for the remaining prediction weakness. ## Explicitly deferred 120 Hz simulation, latency-gap measurement, audio hooks, and split-screen are not part of the current multiplayer release path.