3.2 KiB
3.2 KiB
RulesPlugin
(no submodules)
Purpose
RulesPlugin integrates @suaveplan/rules with the game-server engine. It
maintains three rule sets — move validation, game start, and game end — and
exposes evaluateMove, evaluateGameStart, and evaluateGameEnd so the
engine can apply declarative checks without leaking the underlying engine
abstraction into game logic.
The plugin's role is integration glue: it does not interpret rules itself,
it just hands them to the injected RuleEngine and records the pass/fail
outcomes in a rolling history. Callers compose rule sets at construction
time or replace them at runtime via setMoveRules / addMoveRules.
Features
- Three named rule slots (move / start / end) plus an ad-hoc
evaluatehelper. - Empty rule sets are treated as a "passed" no-op (recorded in history).
- Rolling evaluation history with a configurable cap (default 1 000).
- Mutable move rule set: append (
addMoveRules) or replace (setMoveRules) at runtime. - Zod-validated
historyCapoption. - Lifecycle-safe: clears rule sets and history on uninstall.
Usage: Basic
import { RuleEngine } from "@suaveplan/rules";
import { RulesPlugin } from "@suaveplan/game-server/plugins/rules-plugin";
const engine = new RuleEngine();
const plugin = new RulesPlugin({ engine });
await plugin.evaluateMove("p1", { kind: "attack" }, { hp: 10 });
Usage: Advanced
import { RuleEngine, type Rule } from "@suaveplan/rules";
import { RulesPlugin } from "@suaveplan/game-server/plugins/rules-plugin";
const engine = new RuleEngine();
const damageCap: Rule = /* ... discriminated rule ... */ ({} as Rule);
const plugin = new RulesPlugin({
engine,
moveValidationRules: [damageCap],
historyCap: 50,
clock: () => 1_700_000_000_000,
});
plugin.addMoveRules(/* another rule */);
const results = await plugin.evaluateMove("p1", { dmg: 5 }, { hp: 10 });
const history = plugin.getHistory();
API Reference
class RulesPlugin extends BasePluginconstructor(options: RulesPluginOptions)evaluateMove(playerId, move, gameState): Promise<readonly EvaluationResult[]>evaluateGameStart(sessionId): Promise<readonly EvaluationResult[]>evaluateGameEnd(sessionId): Promise<readonly EvaluationResult[]>evaluate(rules, context): Promise<readonly EvaluationResult[]>addMoveRules(...rules): voidsetMoveRules(rules): voidgetHistory(): readonly EvaluationHistoryEntry[]clearHistory(): void
Implementation Notes
- The engine API used here is
evaluateAll(rules, context), which returns an array ofEvaluationResult(one per rule). The plugin records a single history entry per evaluation, withpassedreflecting the conjunction over the result set. evaluate(rules, ctx)rejects non-object contexts withGAME_SERVER.INVALID_RULE_CONTEXTso callers cannot silently pass primitives through to the rule engine.- Empty rule sets short-circuit before hitting the engine — they record
a
passed: true, resultCount: 0history entry so callers still see the checkpoint was reached. - The history is bounded; once the length exceeds
historyCap, the oldest entries are dropped viaslice(-historyCap).