Initial Commit

This commit is contained in:
2026-05-27 23:29:53 +01:00
commit fbc70f96e6
10000 changed files with 1102152 additions and 0 deletions

View File

@@ -0,0 +1,105 @@
# Wave A — `@suaveplan/game-server` core foundation
**Package**: `@suaveplan/game-server`
**Status**: PROPOSED
**Type**: extends existing genesis package (0.1.0)
**Design**: ./design.md (inline below)
**Spec delta**: ./specs/game-server/spec.md
## Why
Wave A ships the core foundation of `@suaveplan/game-server` that every
later wave (engine, session, state, matchmaking, transport) depends on:
the four core interfaces (`IGameLogic`, `IPlayerManager`,
`ISessionManager`, `IStateManager`) with runtime conformance harnesses,
the `GameEvents` typed payload map plus its `GAME_EVENT_KEYS` registry,
the `GameEventEmitter` typed pub/sub with ergonomic helpers
(`safeEmit`, `waitFor`, `onN`, `onMultiple`), and the
`AbstractGameLogic` Template-Method base class for concrete games. The
package already shipped `DIContainer`, the `GameServerError` registry,
and the Zod-validated core types in the prior change
`enterprise-game-server-core`; Wave A is an additive extension that
fills the interfaces / events / abstract-base layer behind a single
0.1.0 publish.
Without this Wave the downstream waves (B: session manager + player
manager, C: state manager + replay, D: matchmaking + transport plugins)
have no contract to implement against. Shipping it as one isolated wave
keeps the surface reviewable, the coverage gate enforceable on the
whole package, and the dependent slices unblocked.
## What changes
- ADDED: `core/types/core.types.ts` — `ConnectionStatus`,
`PlayerConnection`, `SessionNode`, `SessionData`, `StateChangeEvent`,
`GameEvents` map.
- ADDED: `core/interfaces/i-game-logic/` — `IGameLogic<TState, TMove>`
interface and `runIGameLogicConformance` harness.
- ADDED: `core/interfaces/i-player-manager/` — `IPlayerManager` and
`runIPlayerManagerConformance`.
- ADDED: `core/interfaces/i-session-manager/` — `ISessionManager` and
`runISessionManagerConformance`.
- ADDED: `core/interfaces/i-state-manager/` — `IStateManager<TState>`
and `runIStateManagerConformance`.
- ADDED: `core/events/game-events/` — `GAME_EVENT_KEYS` array +
`isGameEventKey` predicate.
- ADDED: `core/events/game-event-emitter/` — `GameEventEmitter` typed
pub/sub with `safeEmit` / `waitFor` / `onN` / `onMultiple` / per-key
listener cap.
- ADDED: `core/abstract-game-logic/` — `AbstractGameLogic<TState, TMove>`
Template-Method base class with injected `Clock` + `IdGenerator` and
OTel instrumentation.
- EXTENDED: `errors/game-server-error.ts` — six new codes
(`INVALID_MOVE`, `PLAYER_ALREADY_EXISTS`, `PLAYER_NOT_FOUND`,
`LISTENER_LIMIT_EXCEEDED`, `INVALID_LISTENER_COUNT`,
`EVENT_WAIT_TIMEOUT`) raised by the new core surface.
- EXTENDED: root `src/index.ts` — additive named re-exports for the new
Wave A surface.
- EXTENDED: `package.json` exports map — 8 new subpath entries, one per
feature module.
## Impact
### Affected dependents
`bunx turbo ls --filter=...@suaveplan/game-server` enumerates dependents
of this package. As of Wave A landing, no genesis package consumes
`@suaveplan/game-server` yet — this is a foundation wave for
`@suaveplan/game-loop`, `@suaveplan/game-state-schemas`, and the
`api-plugin-game-server` family that will land in Waves B–D.
- `@suaveplan/game-server` (self) — [x] tests run / [x] docs reviewed /
[ ] no action needed.
- No external dependents — verified by `bunx turbo ls
--filter=...@suaveplan/game-server`.
## Parity Checklist
| Capability | Upstream | Migrated | Notes |
| --- | --- | --- | --- |
| `IGameLogic` interface | YES | YES | Genesis tightens `any` → generic `TState`/`TMove`. |
| Inline `AbstractGameLogic` in `IGameLogic.ts` | YES | UP | Genesis splits to its own feature dir. |
| `IPlayerManager` interface | YES | YES | Returns `ReadonlyArray<PlayerConnection>`. |
| `ISessionManager` interface | YES | YES | Returns `ReadonlyArray<SessionNode>`. |
| `IStateManager` interface | YES | YES | `Readonly<TState>` instead of `DeepReadonly`. |
| `GameEvents` map | YES | UP | Variadic tuples collapsed to single-payload objects. |
| `GameEventEmitter` extending Node `EventEmitter` | YES | UP | Self-contained typed emitter; same surface +typed errors. |
| Wildcard `[key: string]: any[]` index signature | YES | NO | Scoped out: closed map keeps lint/type safety; downstream needing wildcard analytics can subscribe to `GAME_EVENT_KEYS` directly. |
| `AbstractGameLogic` Template Method | YES | UP | Adds injected `Clock` + `IdGenerator`, typed errors, OTel instruments. |
| `cloneState` JSON round-trip | YES | YES | |
| Hook methods (`beforeMoveProcessing`, etc.) | YES | YES | |
| Player roster (`addPlayer` / `removePlayer`) | YES | UP | Throws `GameServerError` not plain `Error`. |
| Conformance harnesses | NO | UP | Genesis-original — makes interfaces runtime-testable. |
Rationale for the single scope-out (`wildcard analytics:*`): the
upstream signature `[key: symbol]: any[]` defeats type safety and is
unused inside the `core/` slice; downstream analytics packages can
extend `GameEvents` via module augmentation if needed.
## Migration
Wave A is additive — no existing public-surface item is renamed or
removed. Consumers of the prior `0.1.0` surface (`DIContainer`,
`GameServerError`, Zod parsers, types) keep working unchanged. The new
error codes extend the registry; pattern-match consumers should not
care because none of the new codes were thrown previously.