Documentation

Game logic

v1 · Deprecated

Framework v1 is deprecated for new games. Existing games remain playable and editable.

Set up a game

gameConfig (required)

type GameStateConfigFn = (params: { numPlayers: number }) => GameStateConfigObject;
export const gameConfig: GameStateConfigFn = ({ numPlayers }) => ({ /* ... */ });

Called once per game. Returns the initial config object : see source-files for the field list. Deterministic: same params → same output (so reconnects and replays match).

preGameInitialization (optional)

type PreGameInitializationFn<MetaData = Record<string, unknown>> =
  ((gameState: GameState<MetaData>) => void) | undefined;

export const preGameInitialization: PreGameInitializationFn = (state) => {
  state.activePlayerIds = [state.players()[0].playerId];
};

Called once, after gameConfig and before any action. May mutate gameState. Use for randomized setup (deck shuffle, hand draw) : gameConfig runs in a deterministic builder context, preGameInitialization runs in the same mutating context as applyActions.

gameConfig return shape

GameStateConfigFn is (params: { numPlayers: number }) => GameStateConfigObject. The returned object:

type GameStateConfigObject = {
  startingPlayerStrategy: "Random" | "All";
  pieces: Record<string, PieceDef>;          // top-level pieces, instantiated at game start
  spaces: Record<string, SpaceDef>;          // top-level spaces, instantiated at game start
  player?: {
    spaces?: Record<string, SpaceDef>;       // per-player spaces (one set per seat)
    publicState?: Record<string, unknown>;   // default per-player public state
    privateState?: Record<string, unknown>;  // default per-player private state
    def?: PlayerDef;                         // optional per-player Def (rare)
  };
  pieceDefs?: Record<string, PieceDef>;      // register kinds used only via state.addPiece
  spaceDefs?: Record<string, SpaceDef>;      // register kinds used only via state.addSpace
  metaData?: Record<string, unknown>;        // initial gameState.metaData
  scoreLabels?: string[];                    // labels for the score columns shown in UI
};

Map keys ("0", "1", ...) become the initial pieceId / spaceId. Per-player spaces synthesize ids ${playerId}/space/${key}.

Need a hand with this?

Join our Discord