API Reference
API Reference
Import everything from the engine barrel: import { … } from '../engine'.
Subsystems are namespaced: Cards, Board, Dice, Rules.
Match lifecycle
createMatch<G>(def, {
players: { id, name, isBot? }[],
matchId?, seed?, startingPlayer?,
}): MatchState<G>
applyAction<G>(def, state, action): ApplyResult<G>
// → { ok: true, state, action } | { ok: false, error, state }
nextPlayer(order, current): PlayerId
botAction<G>(def, state): GameAction | null // via def.ai
legalActions<G>(def, state): GameAction[] // via def.enumerate
GameDefinition
interface GameDefinition<G, A extends GameAction = GameAction> {
id; name; description;
category: 'card' | 'board' | 'hybrid';
minPlayers; maxPlayers; tags?; accent?; emoji?;
startingPhase?; // default 'play'
setup(ctx: SetupContext): G;
reducer(game: G, action: A, ctx: ReducerContext): G;
validate?(game, action, ctx): true | string;
enumerate?(game, ctx): A[];
endIf?(game, ctx): GameResult | null | undefined;
ai?(game, ctx): A | null;
describeAction?(action, state): string;
}
Contexts
SetupContext = { random, players, turn }
ReducerContext = { random, actor, turn, players, events }
FlowEvents = { endTurn({ next? }), setPhase(name), endGame(result) }
RNG (RandomSource)
seedRng(seed: string | number): RngState
createRandom(state: RngState): RandomSource
// .float() .int(min,max) .bool(p?) .pick(arr)
// .shuffle(arr) .dice(sides,count?) .getState()
MatchClient
new MatchClient(def, initialState)
.getState() .getLog() .getError()
.dispatch(action, { ephemeral? }) .clearError()
.undo() .redo() .canUndo .canRedo
.replaceState(remote) // newer version wins; clears local history
.subscribe(fn) → unsubscribe
Serialization
serializeMatch(state): string
deserializeMatch<G>(json): { schema, savedAt, state } // throws on corrupt/newer
SAVE_SCHEMA_VERSION: number
Registry
registerGame(def) · getGame(id) · listGames() · hasGame(id)
Cards (Cards.*)
standard52() · shuffle(deck, rng) · deal(deck, ids, perPlayer) ·
drawN(pile, n) · removeCard(zone, id) · addCard(zone, card, faceUp?) ·
topOf(pile) · flip(card, faceUp) · publicView(card) · rankValue(rank, aceHigh?)
· SUITS · RANKS · SUIT_COLOR
Board (Board.*)
makeGrid(w, h, walls?) · cellId(c) · parseCell(id) · coordsEqual(a, b) ·
inBounds · isWall · isPassable · manhattan · chebyshev ·
neighbors(grid, c, diagonal?) · reachable(grid, start, maxSteps, { diagonal?, blocked? })
· advanceOnTrack(track, index, steps)
Dice (Dice.*)
roll(rng, sides?, count?) → { dice, total } · d6(rng)
Rules (Rules.*)
all(...verdicts) · requireCurrentPlayer(ctx) · requirePhase(ctx, phase) ·
require(cond, reason) — each returns true | string.
Network (src/net)
getSyncAdapter(): SyncAdapter
getNetMode() / setNetMode('local' | 'firebase')
firebaseAvailable(): boolean
makeRoomCode(): string
interface SyncAdapter {
kind: 'local' | 'firebase';
createRoom({ gameId, host }) ; joinRoom(roomId, { id, name }) ; leaveRoom ;
setReady ; setPresence ; setStatus ;
pushState(roomId, state) ;
subscribeRoom(roomId, cb) → off ;
subscribeState(roomId, cb) → off ;
}
Storage (src/storage/local)
saveMatch(state) · loadMatch<G>(matchId) · listSaves() · deleteSave(matchId)