client & server rules
the client renders the game and sends player actions to server rules, which validate each action and update the game state.
connect the client
wait for game.connected before reading state. subscribe runs on later updates, so also render once when you connect. call ready when the interface is mounted. the quickstart's client.ts includes the button, action errors and initial render; the first-change tutorial keeps that working client.
define the rules
init creates the stored game state. action validates a player command and updates that state, while view selects the fields that a player can receive. use actor and host from the context supplied by sometimes to check permissions. a player ID supplied in an action payload is untrusted input.
import { defineGame, GameError } from "@sometimes/games/server";
export default defineGame({
init: () => ({ count: 0 }),
action(state, name) {
if (name !== "increment") throw new GameError("invalid", "unknown action.");
state.count++;
},
view: state => ({ count: state.count }),
});private state
the client receives the result of view rather than the full server state. exclude answers, hidden cards and other players' drafts from that result. server rules run in an isolated environment with a 50ms CPU budget and no access to the internet, account database, cookies or native bridge.