mirror of
https://github.com/jcreek/CosmicClash.git
synced 2026-09-11 08:23:45 +00:00
docs(multiplayer): mark identity and launch gates
This commit is contained in:
+3
-5
@@ -12,7 +12,7 @@ those tasks assume; read them before picking up work in Phase 2 or later. §9
|
||||
is a running gotchas list — check it before debugging something that looks
|
||||
like a Godot/Jolt engine quirk, and add to it when you find a new one.
|
||||
|
||||
**Status: every task in Phases 0–6 is implemented and verified locally.** Both multiplayer milestones still need human verification — a playtest at ~100 ms RTT (Phase 4) and a real 3v3 session (Phase 5). Phase 6's public-internet gate is deliberately blocked by the display-name reclaim defect until Phase 7 identity work lands; its export, Docker, rotation/drain, and CI work are complete. Phase 7's Steam foundation is in progress. **Phase 8 — matchmaking, ranked, and per-match server autoscaling — remains a 1.0 launch blocker and is partially implemented:** the Go domain policy, store boundaries, migration, supervisor, hardened Fleet baseline, testkit and offline end-to-end path are in place, while production API/DB/Redis/Steam/Agones wiring and runtime gates remain. It is the first phase to add a component outside the Godot project, and its design lives in [`docs/MATCHMAKING.md`](docs/MATCHMAKING.md). The client has local-ship delta-rebase reconciliation, client-only ball touch prediction, adaptive input-depth signalling, and experimental remote present-time visuals; all server simulation, bot action/observation behaviour, collision resources, and tick rate remain unchanged. See the outstanding list immediately below for what is left and why, §7 for the implemented work and its evidence, and §11 for what is deliberately deferred.
|
||||
**Status: every task in Phases 0–6 is implemented and verified locally.** Both multiplayer milestones still need human verification — a playtest at ~100 ms RTT (Phase 4) and a real 3v3 session (Phase 5). Phase 6's public-internet gate is no longer blocked by the former display-name reclaim defect: allocated reconnects now use the signed identity, while the export, Docker, rotation/drain, and CI work remain complete. Phase 7's Steam foundation is in progress. **Phase 8 — matchmaking, ranked, and per-match server autoscaling — remains a 1.0 launch blocker and is partially implemented:** the Go domain policy, store boundaries, migration, supervisor, hardened Fleet baseline, testkit and offline end-to-end path are in place, while production API/DB/Redis/Steam/Agones wiring and runtime gates remain. It is the first phase to add a component outside the Godot project, and its design lives in [`docs/MATCHMAKING.md`](docs/MATCHMAKING.md). The client has local-ship delta-rebase reconciliation, client-only ball touch prediction, adaptive input-depth signalling, and experimental remote present-time visuals; all server simulation, bot action/observation behaviour, collision resources, and tick rate remain unchanged. See the outstanding list immediately below for what is left and why, §7 for the implemented work and its evidence, and §11 for what is deliberately deferred.
|
||||
|
||||
---
|
||||
|
||||
@@ -25,7 +25,7 @@ The one place to look before planning. Everything here is also written up where
|
||||
| # | Finding | Why it bites |
|
||||
|---|---|---|
|
||||
| Task 8.28 | ~~Godot's stdout is block-buffered off a TTY — a detached container logs *nothing*, so `server_started` never appears~~ **Fixed**: `deploy/cosmic-clash-server` now wraps the exec in `stdbuf -oL -eL`. Verified live — a real `docker run -d` container showed zero log output for 20+ seconds, including the startup line, and `docker stop`'s SIGTERM lost it permanently rather than delaying it (Godot has no SIGTERM hook); the wrapped launcher shows the startup line within 3s of the same scenario. This affected the already-shipped community server (Docker *and* native systemd both route through this script), not only the not-yet-built Agones path | Process-ready must be an explicit Agones call after static validation/listen, independent of this fix — the API/registration boundary never depended on log output either way, so this was a real operational bug (silent `docker logs`/`journalctl`), not a correctness gap in the process-ready design |
|
||||
| Task 8.29 | `--port` defaults to 7777 and the Dockerfile hardcodes `EXPOSE 7777/udp` | Several matches need Agones dynamic UDP/SDR ports; L7 ingress does not route this traffic |
|
||||
| Task 8.29 | ~~`--port` defaults to 7777 and the Dockerfile hardcodes `EXPOSE 7777/udp`~~ **Fixed locally**: the allocated supervisor replaces the child port with the Agones-assigned endpoint and exports SDR variables only for Hosted-SDR | Live Agones passthrough/NAT and multi-match validation remain infrastructure gates |
|
||||
| Task 8.48 | `compose.phase6-smoke.yml` hardcodes the port, first-come slots and `--max-matches=2` | The allocated flow needs its own fixture so Phase 6 behavior and invocations stay unchanged |
|
||||
|
||||
### Blocking sign-off — the work exists, the verification does not
|
||||
@@ -1376,9 +1376,7 @@ godot --path Game -- --connect 127.0.0.1:27015 --name Alice
|
||||
|
||||
## 11. Flagged, not solved
|
||||
|
||||
**Slot reservation and takeover are keyed on display name alone — item C of §0, and the only open item here with a security character.** `_try_reclaim_slot` matches a joining peer against a departed slot on `slot.player_name == player_name` and nothing else. There is no secret, no token, and no uniqueness constraint on names anywhere in `MatchNet`, so any peer that connects during the 30 s reservation window using a departed player's display name is handed their slot, their ship (mid-flight, at whatever pose it holds), and their team. Demonstrated with a real three-process run, not reasoned about. §6.3's late-joiner queue inherits the same weakness for the name it records, though the queue itself is ordered by arrival and cannot be jumped, so the reservation reclaim is the exploitable path.
|
||||
|
||||
Bounded, but not by much: the attacker must race a genuine disconnect, and they must know the name — which is displayed to everyone in the lobby. The right fix is the one §6.2 step 1 already specifies and Phase 7 already schedules: `hello` carries an `auth_ticket`, and the reservation is keyed to the resulting verified identity rather than to a string the client chooses. **Building a bespoke token now would be inventing half of task 7.4 and then throwing it away**, so this is deliberately left for that task — with the consequence stated plainly: this build must not be exposed to strangers before 7.4 lands, and it is a listed precondition of Phase 6's "connect from another machine over the internet" gate rather than a footnote to it.
|
||||
**Former item C — display-name slot takeover — RESOLVED locally.** `_try_reclaim_slot` now compares the verified signed `PlayerID` retained in the server roster and slot; late-join promotion carries the same identity. A changed display name can reconnect, but a same-name peer with a different identity cannot. Direct unauthenticated servers retain a documented display-name fallback for backwards-compatible community hosting. Live public-internet verification still remains a separate Phase 6 gate.
|
||||
|
||||
**Low-latency present and graphics presets** — *now specified*, see §5.4, §5.5 and tasks 0.17/0.17b. Left here as a pointer because they are the largest wins in the document per line of code changed, and they are video settings rather than netcode.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user