107 lines
7.0 KiB
Markdown
107 lines
7.0 KiB
Markdown
# 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<string, any>` 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`.
|