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,93 @@
# Proposal — game-server plugins (Wave C-1)
## Why
The `PluginManager` shipped in Wave B exposes the `EnginePlugin` lifecycle
contract but ships no concrete plugins. Wave C-1 fills that gap with seven
production-grade plugins covering A/B testing, analytics, feature flags,
logging, persistence, rules, and workflows. All seven plugins extend a new
shared `BasePlugin` abstract base that implements the `EnginePlugin`
lifecycle template-method style.
The plugins are universal-tier (zero browser / React deps). External
integrations are routed through structural-type contracts from
`@suaveplan/types` (`LoggerLike`, `StorageLike`, `Clock`, `IdGenerator`,
`Rng`) so the package keeps its lean dep footprint.
## What changes
### ADDED `BasePlugin`
Abstract base for game-server plugins. Implements the `EnginePlugin`
contract (`onInstall` / `onUninstall` / `onEnable` / `onDisable`) and
forwards to `protected` template-method hooks. Tracks lifecycle state
(`created → installed → enabled → disabled → destroyed`) and rejects any
hook after destruction.
### ADDED concrete plugins
- `ABTestPlugin` — weighted, deterministic variant assignment via injectable
`Rng`; conversion log; per-variant summary stats.
- `AnalyticsPlugin` — subscribes to `GameEventEmitter`, accumulates
per-session counters, dispatches structured `AnalyticsEvent` to an
injectable sink.
- `FeatureFlagPlugin` — thin adapter over `@suaveplan/feature-flags`
`FlagManager`; per-player evaluation context; rolling evaluation log.
- `LoggingPlugin` — subscribes to `GameEventEmitter`, forwards events to a
`LoggerLike` sink, retains a bounded ring buffer for inspection.
- `PersistencePlugin` — tracks per-session state from the emitter and
persists via injectable `StorageLike`; explicit `save`/`load`/`delete`.
- `RulesPlugin` — wraps `@suaveplan/rules` `RuleEngine`; three rule slots
(move / start / end); rolling evaluation history.
- `WorkflowPlugin` — id-keyed `WorkflowEngine` registry; `execute` records
status + duration + error; `cancel` defers to engine.
### ADDED error codes (extends `GAME_SERVER.*` registry)
- `PLUGIN_BASE_DESTROYED`
- `INVALID_PLUGIN_OPTIONS`
- `AB_TEST_INVALID_VARIANT`
- `AB_TEST_EXPERIMENT_NOT_FOUND`
- `PERSISTENCE_SAVE_FAILED`
- `PERSISTENCE_LOAD_FAILED`
- `WORKFLOW_NOT_FOUND`
- `DUPLICATE_WORKFLOW`
- `INVALID_RULE_CONTEXT`
### ADDED dependencies
- `@suaveplan/feature-flags` (`workspace:^`)
- `@suaveplan/rules` (`workspace:^`)
- `@suaveplan/workflow` (`workspace:^`)
### Subpath exports
Each plugin module gets its own subpath:
- `./plugins/base-plugin`
- `./plugins/ab-test-plugin`
- `./plugins/analytics-plugin`
- `./plugins/feature-flag-plugin`
- `./plugins/logging-plugin`
- `./plugins/persistence-plugin`
- `./plugins/rules-plugin`
- `./plugins/workflow-plugin`
## Source mapping
| Requirement | Upstream | Notes |
| --- | --- | --- |
| BasePlugin lifecycle | `BasePlugin.ts` (1-50) | Adapted to genesis `EnginePlugin` contract; tracks state machine |
| AnalyticsPlugin per-session counters | `AnalyticsPlugin.ts` (35-280) | Sink-based dispatch instead of OTel coupling |
| ABTestPlugin variant bucketing | `ABTestPlugin.ts` (28-190) | Self-contained — no `@suaveplan/ab-testing` dep |
| FeatureFlagPlugin evaluation | `FeatureFlagPlugin.ts` (30-160) | Wraps `@suaveplan/feature-flags` `FlagManager` |
| LoggingPlugin event forwarding | `LoggingPlugin.ts` (35-430) | Bounded ring buffer; granular toggles |
| PersistencePlugin save/load | `PersistencePlugin.ts` (30-380) | Zod-validated load; `StorageLike` injection |
| RulesPlugin evaluation | `RulesPlugin.ts` (28-195) | Wraps `@suaveplan/rules` `RuleEngine` |
| WorkflowPlugin orchestration | `WorkflowPlugin.ts` (35-210) | Id-keyed registry; history; cancel |
## Scope guard
This change does NOT touch `src/core/`, `src/engine/`, `src/state/`,
`src/network/`, `src/matchmaking/`, `src/performance/`, `src/types/`, or
`src/observability/`. `src/index.ts` is also untouched — orchestrator
consolidation handles the unified barrel.