# game-server-engine-core — GameEngine + GameLoop + PluginManager **Package**: `@suaveplan/game-server` **Status**: PROPOSED **Type**: feature (Wave B-1 migration slice) - **Design**: see this file (no separate design.md required for a thin orchestrator slice) - **Spec delta**: ./specs/game-server/spec.md ## Why Wave A landed the foundations (`errors`, `types`, `engine/di-container`). The broader package still has no engine top-level — there is no `GameEngine` to orchestrate services, no `GameLoop` to drive deterministic ticks, and no `PluginManager` to wire third-party extensions. Without these the package is unusable for actual game work. This slice (Wave B-1) ships the three engine primitives in dependency order so Wave B-2 (sessions/player-manager) and later state/network/matchmaking slices have a stable top-level to bind to. The migration is verbatim in intent (preserve upstream lifecycle + statistics surface) but recast at genesis bar — injectable `Clock`/`TimersLike`/`IdGenerator`, typed `GameServerError` codes, Zod-validated boundaries, OTel counters and histograms with real `MeterProvider` assertions, kebab-case `/` layout, 100/100/100/100 coverage. ## What changes - ADDED: `GameEngine` (in `./engine/game-engine`) — top-level orchestrator wiring DI-injected services with `start`/`stop`/`tick`/`dispose` lifecycle. - ADDED: `GameLoop` (in `./engine/game-loop`) — deterministic fixed-step loop with `Clock`/`TimersLike` injection, `tick-based`/`event-driven`/`hybrid` modes, pause/resume, `tick()` manual driver. - ADDED: `PluginManager` (in `./engine/plugin-manager`) — typed `EnginePlugin` registry with `install`/`uninstall`/`enable`/`disable`/`get` + lifecycle-hook execution wrapped in `PLUGIN_LIFECYCLE_FAILED`. - ADDED: `GAME_SERVER.*` codes — `ENGINE_NOT_STARTED`, `ENGINE_ALREADY_STARTED`, `ENGINE_DISPOSED`, `INVALID_ENGINE_OPTIONS`, `INVALID_GAME_LOOP_OPTIONS`, `GAME_LOOP_NOT_RUNNING`, `GAME_LOOP_ALREADY_RUNNING`, `PLUGIN_NOT_FOUND`, `DUPLICATE_PLUGIN`, `PLUGIN_LIFECYCLE_FAILED`. - ADDED: subpath exports `./engine/game-engine`, `./engine/game-loop`, `./engine/plugin-manager`. ## Out of scope - `SessionManager`, `PlayerManager`, `SessionTree` (Wave B-2 — orchestrator consumes them as opaque structural service interfaces only). - `StateManager`, `NetworkAdapter`, `MatchmakingEngine`, `QueueManager` (later waves). - Game-logic strategy concretes (`AbstractGameLogic`) — the engine accepts an opaque `IGameLogicLike` slot per upstream contract. ## Source mapping This change derives from upstream files on `/mnt/s/web/suaveplan`: | Requirement | Source lines | Notes | |---|---|---| | GameEngine orchestrator | `packages/universal/game-server/src/engine/GameEngine.ts` L60–L497 | Recast — drops session/state/network constructor wiring (Wave B-2+ scope); preserves DI-service registration + start/stop/dispose lifecycle. | | GameLoop deterministic ticks | `packages/universal/game-server/src/engine/GameLoop.ts` L36–L358 | Recast — `Date.now()` replaced by injectable `Clock`; `setInterval/clearInterval` replaced by `TimersLike`. | | PluginManager lifecycle | `packages/universal/game-server/src/engine/PluginManager.ts` L27–L355 | Recast — plain `Error` → `GameServerError`; dependency-aware topo sort preserved. | ### Requirements with no source line | Requirement | Justification | |---|---| | OTel counters + histograms | Genesis bar — upstream had no OTel; this slice adds `game_server.engine.lifecycle_total`, `game_server.loop.tick_duration_ms`, `game_server.plugin.lifecycle_total` to match the package quality bar (mirrors `@suaveplan/ecs`). | | Zod-validated option boundaries | Genesis bar — every public option boundary parses through Zod before reaching state. | | Typed `GameServerError` everywhere | Genesis bar — upstream threw plain `Error` for lifecycle violations. | ## Verification approach - `src/engine/game-engine/game-engine.test.ts` — covers GameEngine lifecycle, DI wiring, plugin handoff, OTel emission. - `src/engine/game-loop/game-loop.test.ts` — covers loop modes, deterministic ticking via injected Clock/TimersLike, pause/resume, error propagation. - `src/engine/plugin-manager/plugin-manager.test.ts` — covers install/uninstall/enable/disable, duplicate detection, dependency topo sort, hook execution. - `src/errors/game-server-error.test.ts` — extended to assert every new code. ## Impact ### Affected dependents Run `bunx turbo ls --filter=...@suaveplan/game-server` to enumerate. The package has no shipped dependents on genesis at the time of this change (verified: `bunx turbo ls --filter=...@suaveplan/game-server` returns only the package itself). - No dependents — additive surface only. ## Migration impact None — additive only. Existing `./errors`, `./types`, `./engine/di-container` surfaces are unchanged. The `GAME_SERVER_CODES` registry is **extended**; the existing 4 codes are preserved.