Files
suaveplan/openspec/archive/2026-05-24-game-server-enhanced-content/proposal.md
2026-05-27 23:29:53 +01:00

3.8 KiB

Wave C-3: @suaveplan/game-server enhanced content slice

Package: @suaveplan/game-server Status: PROPOSED Type: feature-add (additive to existing 0.1.0 package)

Why

Waves A and B landed the core foundation, engine, sessions, state, networking, matchmaking, and performance subsystems of @suaveplan/game-server. Wave C extends the package along the content axis with the four subsystems game operators consume directly: leaderboards, save persistence, replay capture, and tournament brackets.

The upstream reference (/mnt/s/web/suaveplan/packages/universal/game-server/src/enhanced/) ships these as EventEmitter-backed managers coupled to upstream Date.now calls, hand-rolled id generators, and an upstream-specific StorageAdapter contract. This slice ports the algorithms, replaces the couplings with the genesis-canonical Clock, IdGenerator, Rng, and StorageLike abstractions from @suaveplan/types, and adds Zod-validated boundaries + OTel-native instrumentation that the upstream lacked.

What changes

  • ADDED: src/enhanced/leaderboard/leaderboard-manager/ — multi-board manager with score / wins / elo ranking modes, per-board maxEntries rank-based eviction, injectable Clock, two OTel counters, four typed errors (LEADERBOARD_NOT_FOUND, LEADERBOARD_ENTRY_INVALID, INVALID_LEADERBOARD_CONFIG, INVALID_SCORE_SUBMISSION).
  • ADDED: src/enhanced/persistence/game-persistence/ — JSON-over-StorageLike save manager with bounded snapshots and audit-trail history, injectable Clock + IdGenerator, two OTel counters + duration histogram, four typed errors (PERSISTENCE_SAVE_FAILED, PERSISTENCE_LOAD_FAILED, PERSISTENCE_NOT_FOUND, INVALID_SAVE_RECORD).
  • ADDED: src/enhanced/replay/replay-recorder/ — tick-driven input + snapshot recorder with pause/resume, configurable auto-snapshot interval, capped input buffer, injectable Clock + IdGenerator, two OTel counters, four typed errors (REPLAY_NOT_LOADED, REPLAY_PARSE_FAILED, REPLAY_RECORDING_STATE_INVALID, REPLAY_INVALID_SPEED).
  • ADDED: src/enhanced/replay/replay-player/ — tick-driven replay player with step/seek/speed controls, snapshot-aware backward step, loop mode, observer-style listeners, two OTel counters.
  • ADDED: src/enhanced/tournament/tournament-manager/ — single-elim + round-robin brackets with bye propagation, deterministic seeded shuffling via injectable Rng, standings table with stable tie-break, one OTel counter (tagged), eight typed errors (TOURNAMENT_INVALID_STATE, TOURNAMENT_FULL, TOURNAMENT_DUPLICATE_PARTICIPANT, TOURNAMENT_INSUFFICIENT_PARTICIPANTS, TOURNAMENT_MATCH_NOT_FOUND, TOURNAMENT_INVALID_RESULT, INVALID_BRACKET_SIZE, INVALID_BRACKET_TYPE).
  • ADDED: 22 new GAME_SERVER.* error codes registered in defineCodes.
  • ADDED: five package.json subpath exports.

Out of scope

  • Double-elimination brackets — not requested by the dispatch spec and excluded to keep the manager under the 300-line hard limit. Can be added later as a sibling change without touching the public surface.
  • Wire serialisation (Replay export/compression, persistence CDC) — caller-side concern; the ReplayData document is JSON-clean.
  • React companion hooks — separate package (@suaveplan/react-game-server).

Risks

  • None new. All five subsystems are leaf modules that consume only the existing errors/ + types/ foundations plus the @suaveplan/types cross-cutting contracts.

Verification

  • bunx turbo lint typecheck test --filter=@suaveplan/game-server green.
  • bunx turbo test:coverage --filter=@suaveplan/game-server at 100/100/100/100.
  • Zero vitest/bun:test direct imports under src/enhanced/.
  • Zero // biome-ignore, TODO, FIXME, XXX under src/enhanced/.