Files
CosmicClash/docs/ADR-001-matchmaking-platform.md
2026-08-31 20:06:45 +01:00

3.6 KiB

ADR-001: Matchmaking control-plane platform

  • Status: Accepted
  • Date: 2026-08-31
  • Scope: Phase 8 matchmaking, ranked play, and per-match server allocation

Decision

Build the matchmaking control plane as independently runnable Go roles backed by PostgreSQL and Redis, deployed on provider-portable Kubernetes:

  • API: authenticated REST and revisioned WebSocket state delivery.
  • Matcher: queue candidate selection and proposal creation.
  • Allocator: Agones GameServerAllocation and assignment delivery.
  • Maintenance: expiry, repair, outbox delivery, rating and result processing.
  • PostgreSQL: durable identities, sessions, queue ownership, proposals, participants, matches, ratings, results, penalties, audits and outbox.
  • Redis: expiring presence and candidate indexes only; it is never an ownership or allocation fence.
  • Agones: game-server readiness, allocation and lifecycle.
  • Steam Hosted Dedicated Server SDR: production player-to-server routing.

EU and NA are the first regions. Provider-specific networking, edge, secrets, SDR POPs and certificates live in deployment overlays. Application code must not call a cloud-provider allocation API directly.

The existing Godot ENet server remains a supported direct-IP/community-server path. Allocated matches use the same authoritative simulation, but are a separate lifecycle: one match per server process, assignment only after the server is genuinely ready, and shutdown after result delivery.

Boundaries and invariants

  1. PostgreSQL is the source of truth for ownership, participation fences, legal state transitions and idempotency. Redis indexes may be rebuilt.
  2. Steam identity is verified by the secure backend. A client-supplied name or Steam ID is never an identity or rating key.
  3. The backend issues match-scoped, expiring authorisations bound to identity, match, server, slot, protocol and connection generation.
  4. Agones Ready means process-ready only. Assignment-ready additionally requires the allocated manifest, signed roster and backend registration.
  5. ENet/SDR carries simulation traffic; REST/WebSocket carries control-plane traffic. No simulation state is routed through the backend.
  6. Provider failure must not be represented as a player fault. Result delivery and match-integrity failure remain separate states.

Rejected alternatives

  • C#/.NET backend: not consistent with the shipped GDScript-only project and adds no required capability over Go.
  • Redis as the durable queue fence: Redis failover can lose an acknowledged write; using it as authority can split a player across proposals.
  • Provider-specific allocation SDKs in application code: couples matching policy and correctness to one cloud and prevents the second-provider migration gate.
  • A custom game-server scheduler instead of Agones: duplicates readiness, allocation, drain and lifecycle behavior that the project needs to verify.
  • Replacing the community ENet path: direct-IP ENet remains necessary for LAN, CI and self-hosted servers and must not become a silent fallback for a failed production SDR assignment.

Consequences

This introduces the first non-Godot service in the project and requires versioned API contracts, database migrations, operational security and concurrency testing. It also gives queue ownership, ratings, reconnects and allocation a durable authority instead of extending the Godot server with cross-match responsibilities. SLOs and wire contracts are separate follow-up decisions (tasks 8.2 and 8.3).

References