Openturn runs your game as a reducer over a declared state machine. If you internalize four ideas, most of the rest of the docs becomes obvious.Documentation Index
Fetch the complete documentation index at: https://openturn.io/docs/llms.txt
Use this file to discover all available pages before exploring further.
1. The authoritative state is explicit
Every match has one source of truth: the state valueG returned by setup and updated by transitions. The client, the server, the CLI, replays, and inspector all read the same G. Hidden state is modelled inside G and projected out with views.player so only the right audience sees it.
G must be JSON-serializable. That is not a guideline, it is a guarantee the engine relies on for replay, persistence, and worker safety.
2. Events drive everything
State never changes on its own. Players dispatch events (core calls them events, gamekit calls them moves), and the engine runs the matching transition. No timers, no fetch calls, no random subscriptions mutateG behind your back. If you need randomness, you use the deterministic RNG the engine hands you. If you need the current time, you read it from the event context.
This is the determinism contract: same seed + same action log = same state, forever.
3. Progression is part of the graph
A match is always positioned at a named state (core) or phase (gamekit) plus a monotonic turn counter. The graph of possible transitions is declared up front, not discovered at runtime. That is what makes the engine capable of validating a game before it runs, rendering a state diagram, and computing which players are active without guessing. You do not chain callbacks. You declare: “from state X, on event Y, go to state Z if the reducer returns a result.”4. Views are projections, not state
What a player sees on their screen is a pure function ofG. views.public is the redacted shape any observer can see. views.player is the per-seat shape (what player 0 knows versus player 1). The engine calls them. You never cache a player view inside G, because the reducer would no longer be the single source of truth.
A tiny example
{ count: number }, accepts one move that returns a new state and ends the turn (move.endTurn is one of a small set of outcomes a move can return), and projects count to the public view. The engine turns this value into a reducer. Nothing is hidden.
What to read next
- Authoritative state and snapshots goes one level deeper on what
Gis and how snapshots work. - Events, states, and transitions explains the core authoring surface.
- Gamekit: the move-first layer shows how moves compile back to core transitions.