Set up a game
gameConfig (required)
type GameStateConfigFn = (params: { numPlayers: number }) => GameStateConfigObject;
Called once. Deterministic : same params, same output. See v2-game-source for the config object's fields.
preGameInitialization (optional)
type PreGameInitializationFn<MetaData = Record<string, unknown>> =
((gameState: GameState<MetaData>) => void) | undefined;
Runs once, after gameConfig, before any action. May mutate. This is where randomized setup goes : shuffling a deck, dealing hands, choosing a start player : because gameConfig has to stay deterministic and this does not.
gameConfig and the config object
gameConfig({ numPlayers }) runs once and returns the table's starting layout. It must be deterministic : same params, same output : because reconnects and replays re-run it. Randomized setup (shuffling, dealing) belongs in preGameInitialization.
export const gameConfig: GameStateConfigFn = () => {
const config: GameStateConfigObject = {
startingPlayerStrategy: "Random",
scoreLabels: ["Points"],
spaces: {
"0": new GridCell({ x: 0, y: 0 }),
"1": new GridCell({ x: 135, y: 0 }),
},
pieces: {},
pieceDefs: {
"x-token": new XToken({ order: 1 }),
},
};
return config;
};
| Field | Holds |
|---|---|
spaces |
Starting spaces, keyed by spaceId. |
pieces |
Starting pieces, keyed by pieceId. May be empty if you create pieces during play. |
pieceDefs |
Every piece kind the game can ever create, keyed by kind. Registers the class so state.addPiece can resolve it at runtime. |
scoreLabels |
Names the entries in each player's publicPoints array, in order. |
startingPlayerStrategy |
How the first active player is chosen, e.g. "Random". |
player |
Optional per-player setup : spaces each player owns (a hand, a board side). |
A kind you only create at runtime must still appear in pieceDefs. state.addPiece throws if the kind isn't registered.