Browser-targeted. The React layer. The runtime is declared once inDocumentation Index
Fetch the complete documentation index at: https://openturn.io/docs/llms.txt
Use this file to discover all available pages before exploring further.
createOpenturnBindings, and a zero-prop <OpenturnProvider> auto-resolves transport so the same component runs unchanged under openturn dev and openturn-cloud.
Install
Authoring surface
createOpenturnBindings(game, options)
Turns a game definition into a typed binding bundle. The runtime + initial match are declared once at the call site.
options is required on the first call for a given game definition. Subsequent calls (e.g. an experience component sharing the same game import) may omit options and reuse the cached bindings.
CreateOpenturnBindingsOptions<TGame>
OpenturnBindings<TGame>
The return type. Exposes the provider, the match-store factory, the consolidated hooks, and the resolved runtime literal.
The consolidated API
<OpenturnProvider>
Zero-prop in normal app code:
runtime declared in createOpenturnBindings:
runtime: "local"→ in-process session backed by the bindings’match.runtime: "multiplayer"→ connects via the#openturn-bridge=…URL fragment that the host shell injects (openturn devlocally, openturn-cloud in production).
match — pass an OpenturnMatchStore to override the in-process session for tests, Storybook, or a load-saved-game flow:
runtime: "multiplayer" is declared but no bridge fragment is present (and no hosted.readInit was set), the provider throws — so “I forgot to launch under a host shell” surfaces at mount instead of silently doing nothing.
useMatch()
Returns a mode-discriminated MatchView<TGame> for the active match:
view.mode and read the right fields without knowing the transport. Throws if no match is active yet (pre-connect in hosted mode); call useRoom() instead if you need to render a pre-game UI.
useRoom()
In runtime: "multiplayer" bindings rendered under a host shell, returns the full HostedRoomState — phase, lobby, game, bridge handle, invite URL. Throws when called outside a multiplayer provider.
room.bridge.shellControl.on(({ control, phase }) => …) — see BridgeShellControlChannel. Shell controls (save, load, reset, return-to-lobby, …) are declared in the deployment manifest and implemented by the host adapter; games subscribe to react (e.g. clear local UI on reset) but do not register them.
useInspector(options?)
Build the inspector timeline + interaction state for the active match. Returns UseInspectorResult | null (null when no match is connected yet). The result is structurally compatible with InspectorContextValue from @openturn/inspector-ui, so it can drive any custom inspector UI.
useMatch().
useReplayInspector(source, options?)
Standalone replay viewer. Takes either a saved-replay envelope or a pre-materialized timeline; returns the same shape as useInspector. No live match required:
UseInspectorResult
Shape returned by useInspector/useReplayInspector:
InspectorContextValue from @openturn/inspector-ui.
Local match store
createLocalMatch(options)
Build an OpenturnMatchStore<TGame> from a match and session options. Wrap the store in <OpenturnProvider match={store} /> and read it with useMatch().
OpenturnMatchStore<TGame, TMatch>
The underlying store. { dispatch, getLastBatch, getReplayData, getSnapshot, getPlayerView, getStatus, subscribe, reset? }. You typically do not touch it; useMatch() wraps it.
OpenturnMatchState<TGame>
Shape of useMatch().state when match.mode === "local":
Hosted state types
HostedMatchState<TGame, TPublicState, TResult>
Surfaced via useMatch() (hosted/dev mode) and useRoom().game.
HostedDispatchMap<TGame> / HostedCanDispatchMap<TGame>
Typed dispatch map and per-event availability flags. Each dispatcher returns Promise<HostedDispatchResult> — awaiting it surfaces the server’s real ack or rejection, matching the { ok, error } shape from the local session:
HostedMatchStatus
"idle" | "connecting" | "connected" | "disconnected" | "error".
HostedLastAction<TGame>
A discriminated shortcut on hostedMatch.lastAction that carries the most recent player-authored action in a form that narrows by event name:
lastBatch.steps.find(s => s.kind === "action")?.event.payload. Narrow on lastAction.event to type the payload:
null when the match has not produced a player action yet (initial connect, or last batch contained only internal events).
HostedDispatchResult
The resolved value of dispatch.<event>(payload) promises: { ok: true; clientActionID } on ack, or { ok: false; error; reason?; details?; clientActionID? } on rejection, disconnect, or send failure.
SessionStatus
"ready" | "syncing" | "disconnected" | "error". The status field on OpenturnMatchState (local mode).
DispatchResult / DispatchSuccessResult
DispatchResult = DispatchSuccessResult | GameErrorResult where DispatchSuccessResult = { ok: true }. The resolved value of a local-mode dispatch.<event>(payload) promise.
LocalSavedSnapshot<TGame>
Snapshot shape accepted by createLocalMatch({ initialSavedSnapshot }) to warm-start a local session from a decoded save envelope.
UseInspectorOptions<TGame> / UseReplayInspectorSource<TGame>
Option shapes accepted by useInspector(options?) and useReplayInspector(source, options?). UseReplayInspectorSource is { envelope } | { timeline }.
HostedMatchOptions
CreateGameBridgeOptions & { retainBatchHistory?, inspector? }. Passed as hosted: {...} on createOpenturnBindings. inspector: "deny" opts out of shell-owned inspector batch streaming.
HostedMatchOverride<TGame> / HostedMatchOverrideContext
Advanced: inject a synthetic HostedMatchState for testing or inspector previews. createFrozenHostedMatchState(...) builds a read-only state. Used internally by the HostedInspector component in @openturn/inspector-ui.
createFrozenHostedMatchState(...)
Build a frozen state object from a snapshot and history. Used by the hosted replay inspector.
Dispatch errors
formatDispatchError(outcome, options?)
Map a rejected dispatch outcome to a user-facing string. Covers the common ProtocolErrorCodes (game_over, inactive_player, invalid_event, stale_revision, disconnected, …) out of the box and lets you override per-reason.
options.byReason[reason] → options.byError[error] → built-in default → options.fallback ("That move was rejected.").
DispatchErrorLike / FormatDispatchErrorOptions
Hosted room UI
<HostedRoom>
Phase-routing component that handles the standard missing_backend / connecting / lobby / game / closed / error tree. Pass render functions per phase; defaults fall through to a shared fallback.
room, lobby, and game are required; everything else falls back to fallback or null. Use HostedRoom whenever a component renders a full hosted-room shell — it keeps the phase-branching logic out of your game UI.
HostedRoomProps<TGame, TPublicState, TResult>
Full prop shape — see the IDE hover for each slot.
Rooms with lobbies
HostedRoomState<TGame, TPublicState, TResult>
Returned by useRoom(). Phase-aware — a single shape covering connecting, lobby, live game, closed.
HostedRoomPhase
"idle" | "missing_backend" | "connecting" | "lobby" | "transitioning" | "game" | "closed" | "error".
Lobby
Opinionated lobby UI component. Pass it room.lobby. Hosted shells render their own invite-share affordance via the copyInvite shell control rather than embedding it inside the lobby UI.
useLobbyChannel(options)
Low-level lobby WebSocket hook. Use when building a custom lobby UI.
buildLobbyView(channel)
Turn a raw lobby channel into a LobbyView (the same shape useRoom() exposes).
LobbyChannelHandle / LobbyChannelStatus
The handle returned by useLobbyChannel and its connection status ("idle" | "connecting" | "connected" | "disconnected" | "error"). Use buildLobbyView(handle) to project into the same shape useRoom() exposes.
Shell integration
Advanced — for dev shells and outer hosts that need to observe the hosted match state rendered by an inner user-authored<Page> without threading it through the page’s tree.
<HostedMatchShellObserver>
Wrap the user’s subtree. Activates the observer channel so hosted match state is published into a shared WeakMap keyed by the game definition.
useShellHostedMatch(game)
Call from outside the wrapped subtree to read the observed HostedMatchState<TGame> | null. Null until the inner subtree mounts a hosted provider. Normal app code should reach for useMatch() or useRoom() instead — this hook is for shell wrappers only.
openturn dev to render the dev-shell inspector alongside the user page.
Re-exports
For convenience,@openturn/react re-exports common types from its dependencies:
- From
@openturn/client:HostedConnectionDescriptor,HostedDispatchOutcome,HostedSnapshot,ProtocolValue. - From
@openturn/protocol:BatchApplied. - From
@openturn/core:MatchInput. - From
./lobby:Lobby,useLobbyChannel,buildLobbyView,LobbyChannelHandle,LobbyChannelStatus,LobbyView.
See also
- How-to: bind a game to React is the recipe.
- Tutorial: tic-tac-toe with gamekit uses the local binding.
- Tutorial: tic-tac-toe multiplayer uses
useRoom().