first commit
This commit is contained in:
@@ -0,0 +1,125 @@
|
||||
# EnhancedGameServer
|
||||
|
||||
<!-- begin:auto-docs -->
|
||||
_(no submodules)_
|
||||
<!-- end:auto-docs -->
|
||||
|
||||
## 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<EnhancedServerHandle>`. 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<EnhancedServerEventMap>` 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.
|
||||
Reference in New Issue
Block a user