# EnhancedGameServer _(no submodules)_ ## Purpose `EnhancedGameServer` is the top-of-stack integration layer for `@suaveplan/game-server`. Waves B and C-1 shipped the engine, plugin manager, and eight concrete plugins, but consumers still had to wire the loop, manager, engine, and every plugin by hand on each boot. This module collapses that boilerplate behind a single `bootstrap(options)` entry point and returns a typed handle exposing both the wired `GameEngine` and the bundle of installed plugins for direct access. The integration is deliberately universal — zero browser, React, or DOM dependencies. The upstream React lobby shell is explicitly deferred to a future `react-game-server` package. All collaborators are injected through the structural contracts in `@suaveplan/types` (`Clock`, `IdGenerator`, `LoggerLike`, `TimersLike`, `EventBusLike`, `Rng`, `StorageLike`) plus the public APIs of `@suaveplan/feature-flags`, `@suaveplan/rules`, and `@suaveplan/workflow`. ## Features - Single `bootstrap(options)` entry point — no manual wiring. - Pre-installs every built-in plugin (`logging`, `analytics`, `persistence`, `feature-flags`, `rules`, `workflow`, `ab-test`) via `PluginManager.installAll` so dependency order is honoured. - Enables every plugin after install so callers can opt-out by disabling individual plugins post-bootstrap rather than skipping them entirely. - Caller-supplied `extraPlugins` are installed last and enabled in the same pass. - `BOOTSTRAP_FAILED` wraps any plugin install failure with the original `cause` chain intact. - `ALREADY_BOOTSTRAPPED` prevents accidental double-wiring. - `start()` / `tick()` / `stop()` / `dispose()` delegate to the underlying `GameEngine` so existing engine codes (`ENGINE_NOT_STARTED`, `ENGINE_DISPOSED`) propagate unchanged. ## Usage: Basic ```ts import { EnhancedGameServer } from "@suaveplan/game-server/integrations/enhanced-server"; const server = new EnhancedGameServer({ clock: () => Date.now(), timers, idGenerator, logger, events, emitter, flagManager, ruleEngine, rng, storage, analyticsSink: (event) => console.log(event), }); const { engine, plugins } = await server.bootstrap(); server.start(); await server.tick(); server.stop(); await server.dispose(); ``` ## Usage: Advanced Install extra plugins after the canonical seven and configure tick rate: ```ts class TelemetryPlugin extends BasePlugin { public readonly name = "telemetry"; public readonly version = "1.0.0"; } const handle = await server.bootstrap({ autoStartLoop: false, tickRate: 30, extraPlugins: [new TelemetryPlugin()], }); // Disable analytics without uninstalling the rest. await handle.engine.getPlugin("analytics"); // Direct typed access for per-plugin configuration: handle.plugins.featureFlag.evaluate("dark-mode", "player-1"); ``` ## API Reference - `class EnhancedGameServer(deps: EnhancedGameServerDeps)` — constructor. - `bootstrap(options?: EnhancedServerBootstrapOptions)` — returns `Promise`. Throws `ALREADY_BOOTSTRAPPED` on the second call and wraps install failures in `BOOTSTRAP_FAILED`. - `start()` — delegates to `GameEngine.start()`. - `tick()` — delegates to `GameEngine.tick()`. - `stop()` — delegates to `GameEngine.stop()`. - `dispose()` — idempotent; safe before bootstrap. - `isBootstrapped()` — predicate. - `getHandle()` — returns the typed handle; throws if not bootstrapped. `EnhancedServerHandle` exposes the wired `engine` and a strongly-typed `plugins` bundle (`{ abTest, analytics, featureFlag, logging, persistence, rules, workflow, extras }`). ## Implementation Notes - Plugins are installed in an order that satisfies their declared `dependencies`. The current canonical set declares none, so the order is determined by the integration: log-first so subsequent installs are recorded, analytics next to capture session events, then persistence, feature-flags, rules, workflow, and finally A/B-test. - Bootstrap calls `PluginManager.installAll` (which `topoSort`s its argument) for an atomic batch install. After install, each plugin is individually enabled — `PluginManager.enable` is idempotent so the second-pass loop is safe. - The shared `EventBusLike` is intersection-typed across the loop, manager, and engine maps so a single bus services all three subsystems without per-subsystem adapters. - All error wrapping preserves the original `cause` so consumers can walk the cause chain via `@suaveplan/error`'s utilities. - The class never holds React or DOM references; every concrete dependency is injected through a structural contract, keeping the package universal.