Getting started
Create handles, register listeners, call ready() once, then read, write, and
send throughout your game.
Install with npm
Import the shared Plot object. Create any state
views and register their listeners before calling ready():
That is the standard startup order:
- Create typed state views and channels.
- Register lifecycle, focused state, and channel listeners.
await Plot.ready().- Read state, write state, and send messages.
Calling ready() tells Plot that this game copy is ready to participate. Plot
may already have admitted the player with a stable ID that other copies see as
joining; calling ready() does not add or renumber them. The promise resolves
only when:
Plot.partycontains the complete current party andparty.selfisconnected;- Game State and every player's Player Data are installed;
- the synchronized clock is ready; and
- state changes and realtime messages can be exchanged.
This is SDK readiness. It does not wait for your framework to render or for optional assets to load. Call it at the point where your game is prepared to participate.
ready() returns no client object. After it resolves, reads such as
Plot.party.get(), Game State and Player
Data getters, and Plot.time.now() return
immediately from the latest local snapshot.
Before ready(), you may create typed or schema-backed state views, create
channels, register any listener, and inspect Plot.connection. Those local
setup calls do not start readiness. The connected lifecycle callback runs after
all state is installed, just before ready() resolves. It runs again after
recovery has installed current state, before retained channel messages. It does
not run for ordinary data changes; focused change listeners handle those.
Complete per-domain snapshot subscriptions remain available as an alternative
for a view that follows just one domain.
Reads and channel sends made too early throw
PlotNotReadyError; state writes return
a rejected promise. Inside a connected lifecycle callback, readiness-dependent
APIs are already available. Most games call ready() without options; the
optional parentOrigin is only for Plot-provided preview and test tooling.
Pick the right data surface
After readiness, choose the API by how long the information matters:
Game State and Player Data are synchronized session state, not high-frequency streams. While the session remains active, startup and recovery install their current synchronized values. They are not permanent account or saved-progress storage. Use channels for movement, pointer samples, effects, and button presses; keep state that belongs only to one screen in your own app.
If the host coordinates game rules, start that coordinator after Plot.ready()
on every page load and derive its next action from current Game State and Player
Data. See How Plot games work for reload and session
lifetime behavior.
Handle startup failure
Opening a game URL directly is useful for standalone UI work, but Plot.ready()
needs a game session launched by Plot. Catch
PlotError when you can offer a useful retry or
exit choice:
Use error.code for program logic; message
text is diagnostic and may change. See Error handling for
retry guidance and optional Plot.connection
status. Game code never creates a reconnect loop.
Use a browser script
A game without a package manager can load the browser build from a CDN. Pin the complete version so a published game never changes underneath you:
Every release includes dist/integrity.json; copy its SHA-384 value when
updating the pinned version.
Next, learn about party and players, then choose Game State or Player Data for synchronized state and realtime channels for transient messages. Use synchronized time whenever screens must agree on a deadline.