This guide takes you from zero to a working React game you can click in a browser. It uses the CLIDocumentation Index
Fetch the complete documentation index at: https://openturn.io/docs/llms.txt
Use this file to discover all available pages before exploring further.
local template, so you do not need a server, an account, or any cloud setup. If you would rather skim the API reference, jump to how-to: author with gamekit.
1. Scaffold the project
app/game.ts— exportsgame, the authored game definition.app/page.tsx— the React UI.app/openturn.ts— metadata that the CLI and deploy pipeline read.
package.json and tsconfig.json are conventional TypeScript plumbing — you will rarely touch them.
2. Read the starter game
Openapp/game.ts. The template ships a two-player increment counter:
playerIDsdeclares the seat pool: which players the game can seat. Here, two seats with IDs"0"and"1"(every seat must fill — setminPlayerslower to declare a variable-player range like 2–4).setupreturns the authoritative stateGat the start of the match.Gis plain JSON-serializable data — no functions, no class instances.moves.incrementis a pure function from state and args to an outcome. Outcomes are built with themovehelper:move.endTurn(...),move.finish(...),move.invalid(...), etc. You never mutateGdirectly — you return a patch describing what changed. See moves and outcomes for the full set.views.publicprojects the state into the shape the client receives. You can also addviews.playerto hand different data to each seat (useful for hidden info).
3. Run the game
http://localhost:3000. You should see a counter showing 0, an Increment button, and a label saying whose turn it is. Click Increment to bump the counter; the turn flips to the other player. The first player to push the counter past 5 wins, and the UI displays the winner’s seat ID.
4. Make your first edit
Change the target from 5 to 3 so the game ends sooner. Save the file; the dev server hot-reloads. Play a round.5. Add a second move
Give each player a way to zero the counter at the cost of skipping their turn.app/page.tsx, the React hook gives you a dispatch map with one method per move (dispatch.increment, dispatch.resetBoard, …) and an activePlayer derived from the current snapshot. Add a button next to the existing Increment button:
0 and play passes to the other player.
What just happened
You wrote a pure data-and-functions game definition, ran it through@openturn/gamekit (which turned your moves into a small state machine), and bound it to React with createOpenturnBindings. No state is stored outside the authored reducer, so the engine can already replay the match, hand you a timeline, or move you to hosted multiplayer by switching the bindings’ runtime from "local" to "multiplayer" — without changing your game code.
Where to go from here
- Tutorial: tic-tac-toe with gamekit takes a richer game end to end, including a CLI and replay capture.
- Concepts: mental model explains why the authoring contract is the way it is.
- How-to: author with gamekit is the recipe book when you want to extend your game.