# Enterprise migration: `@suaveplan/game-server` (core slice) **Package**: `@suaveplan/game-server` **Status**: PROPOSED **Type**: new-package ## Why `@suaveplan/game-server` on the reference branch `claude/review-game-engine-arch-Kaykr` (main repo `packages/universal/game-server/`) is a 192-file framework with session lifecycle, plugin chain, networking, state-sync, matchmaking, and an "enhanced" variant (anti-cheat / lag-compensation / interest management / replay / tournament / persistence / leaderboard / state-sync / timing). The branch's last commit (`2fb25cdb35`) made the engine generic by removing all game-specific adapters (bingo / tic-tac-toe / gem-crush). Genesis needs that engine, but porting all 192 files in one slice would either skip the genesis quality gates (100% test coverage, sibling `.md` per `.ts`, kebab-case + 5-file layout, typed errors, Zod boundaries, OTel) or land partially-built code. Six required workspace dependencies (`controller`, `keys`, `network-webrtc`, `network-websockets`, `storage-browser`, `workflow`) do not yet exist on genesis, blocking the `network/`, `plugins/`, and parts of `state/`. This change ships the **dependency-light foundation** that every later slice depends on, behind the `@suaveplan/game-server` name at `0.1.0`, and documents the remaining scope as explicitly deferred follow-on changes. The package is fully usable today by downstream code that wants typed errors, Zod-validated boundary types, or the DI container. ## What changes - ADDED: `@suaveplan/game-server` package at `packages/gaming/games/game-server/` (universal tier, `sideEffects: false`, version `0.1.0`). - ADDED: `GameServerError` + `GAME_SERVER_CODES` registry via `defineCodes` — four initial codes: `SERVICE_NOT_REGISTERED`, `INVALID_GAME_CONFIG`, `INVALID_SESSION_METADATA`, `INVALID_PLAYER_INFO`. - ADDED: `GameConfig`, `SessionMetadata`, `PlayerInfo`, `MoveValidationResult`, `GameResult`, `SessionType`, `DeepReadonly` with Zod schemas (`GameConfigSchema`, `SessionMetadataSchema`, `PlayerInfoSchema`, `MoveValidationResultSchema`, `GameResultSchema`, `SessionTypeSchema`) and validators (`parseGameConfig`, `parseSessionMetadata`, `parsePlayerInfo`, `tryParseMoveValidationResult`, `tryParseGameResult`). - ADDED: `DIContainer` with singleton/transient lifecycles, typed error on miss, and **re-register-invalidates-cache** semantics (genesis improvement over upstream). - ADDED: Subpath exports `./errors`, `./types`, `./engine/di-container` for tree-shaking. ## Out of scope (deferred) | Surface area | Why deferred | Follow-up change | |---|---|---| | `core/{AbstractGameLogic, interfaces/*, events/*}` | Each contract file needs its own 5-file layout + tests + docs; bundling all of them in one slice would force this PR over 30 files. | `enterprise-game-server-core-contracts` | | `engine/{GameEngine 487, GameLoop 355, PlayerManager 345, PluginManager 340, SessionLifecycle 295, SessionNode 173, SessionStore 128, SessionTree 429}` | Six of eight files exceed the 300-line genesis hard limit and require splitting. Each needs Zod boundary schemas, OTel instruments, typed `GAME_SERVER.*` codes, 100% coverage, ≥200-word sibling `.md`. | `enterprise-game-server-engine` | | `state/{DeltaCompressor 221, StateDiffer 280, StateManager 316, StateSync 375}` | StateManager and StateSync exceed the 300-line limit; StateSync also reaches into networking which is blocked. | `enterprise-game-server-state` | | `matchmaking/{MatchmakingEngine 152, QueueManager 169, SpectatorManager 122, skill-matcher 40, winner-stays-on 56}` | Dependency-clean but still requires the engine/state slices to be useful end-to-end. | `enterprise-game-server-matchmaking` | | `performance/{NetworkTierAdapter, ObjectPool, SessionPool}` → `telemetry/` | Folds into engine slice (`SessionPool` consumes `Session` from engine). | `enterprise-game-server-engine` | | `network/{NetworkAdapter, ReconnectionManager, WebRTCTransport, WebSocketTransport}` | BLOCKED on missing genesis deps `@suaveplan/network-webrtc` and `@suaveplan/network-websockets`. | After transport packages land. | | `plugins/{ABTest, Analytics, BasePlugin, FeatureFlag, Logging, Persistence, Rules, Workflow}` | BLOCKED on missing genesis deps `@suaveplan/workflow` and `@suaveplan/keys`. | After workflow/keys packages land. | | `enhanced/` (73 files: anti-cheat, components, interest-management, lag-compensation, leaderboard, persistence, replay, service-discovery, state-sync, timing, tournament) | Priority 2 per migration brief; the enhanced variant sits above a stable engine. Several enhanced features have transitive deps on the blocked packages. | `enterprise-game-server-enhanced` | | `integrations/components/game-lobby/*` | Priority 3 — React-coupled UI that belongs in a `react-game-lobby` package, not a universal-tier engine. | `enterprise-react-game-lobby` | | `integrations/enhanced-server/*` | Bundles every enhanced feature; depends on `enterprise-game-server-enhanced`. | `enterprise-game-server-enhanced` | | `stories/*`, `e2e/*`, `benchmarks/*` | Storybook/Playwright/bench tooling lands with the surfaces they exercise. | per-slice. | ## Source mapping This change derives from `../suaveplan/enterprise/game-server.md` (not present in the worktree's parent repo — the reference is the branch `claude/review-game-engine-arch-Kaykr` itself, since the package was under active redesign). | Requirement | Source lines | Notes | |---|---|---| | Typed error registry `GAME_SERVER.*` | `src/engine/DIContainer.ts:30` (only throw site in the migrated slice; upstream used plain `Error`) | reworded — typed error replaces plain throw. | | `GameConfig`/`SessionMetadata`/`PlayerInfo`/`MoveValidationResult`/`GameResult` types | `src/core/types/index.ts:1-47` | extended — added Zod schemas + validators (no source line). | | `DIContainer` singleton/transient resolver | `src/engine/DIContainer.ts:1-61` | extended — re-register-invalidates-cache is new in genesis. | ### Requirements with no source line | Requirement | Justification | |---|---| | Zod schemas for every boundary type | Genesis rule: every public boundary is Zod-validated. | | Typed `GameServerError` instead of plain `Error` | Genesis rule: every package throws via its own `defineCodes` registry. | | `readonly` modifiers on every interface field | Genesis lint profile rejects `Record` and prefers immutable shapes. | | Re-register-invalidates-cache on `DIContainer` | Bug-class fix: upstream silently kept stale singletons after re-register. | ## Verification approach - `src/errors/game-server-error.test.ts` — registry shape, error construction, code discrimination. - `src/types/common.test.ts` — every schema accept-path, reject-path, and validator throw-path with the matching code. - `src/engine/di-container/di-container.test.ts` — singleton, transient, symbol identifiers, fluent chaining, miss-throws-typed-error, has/unregister/clear/getRegisteredServices, re-register cache invalidation. ## Migration impact None — additive only. No consumer on genesis currently imports `@suaveplan/game-server`.