Docs
Guides and references for building games on AI Chat Games.
Getting Started
- Platform overviewHow AI Chat Games works — the kinds of games you can build, how the engine runs your code, and where to look next.
- Creating gamesThe hands-on walkthrough of making a game — hit Create and describe what you want; the agent builds a working game you can play immediately; reshape it by chatting ("add a scoreboard", "make the detective more suspicious"); polish the Details (title, tagline, category, description, tags, cover art — the agent can fill these too); publish it to a public page and keep it updated; play someone else's game to get your own editable copy; and how credits and per-game spending limits fit in.
- How games workThe mental model behind every game — a React frontend in your browser plus a backend reducer running sandboxed on our servers; input events processed one at a time into a shared timeline of turns; ticks that let a game act on a clock without the player; many screens (your devices, or several players) connected to one running session; where the AI characters sit in the loop; and why cheating isn't a design consideration — players can always inspect, rewind and edit, so the designer's job is to make honest play the most fun path, not to enforce it. Ends with what the platform is and isn't good at.
- Background play, permissions & spending controlsSome games keep playing after you leave — with your permission. What background play is, how a game asks for it, how background actions spend credits, and where the controls live (game Settings — permissions, spending limit, pause). Notifications are a separate per-device permission.
Recipes
- Multi-character scenesPattern for several AI characters in a shared scene, each tracking their own perspective. One agent per character, broadcast each event via addMessages, take turns via a message-less send. Covers chat rooms, juries, panels, councils, debates, ensemble casts.
- Structured output (generative scenarios)Give an agent a Zod responseFormat in its config to get typed, parsed JSON back instead of free text. The schema's .describe() calls are the spec the LLM follows. Replies are parsed by your own schema, so .refine() and .transform() work, and a failed parse is retried with a correction. One agent, one fixed format — per-turn schemas break prompt caching, so variable options go in the message and are enforced with a .refine(). Ideal for generating a whole scenario, cast, or config once at game start, then driving the rest of the game from it.
- Custom (non-Chat) frontendsBuild a bespoke UI instead of the built-in Chat. defineFrontend gives you state, emit, and gameHistory — render whatever you want from them. Derive views (e.g. per-character threads) from gameHistory.recentBlocks rather than duplicating transcripts in state, type sub-components from the SDK's exported building blocks, and theme with the host site's CSS variables.
- Generating imagesGenerate images during gameplay with io.activities.generateImage(callId, params), which returns { mediaId } at dispatch and can still fail minutes later — so every rendering of a mediaId must handle its status (RenderMedia does; with useMedia, url is absent in every status but 'done', and silently rendering nothing is a decision you have to make deliberately). Render a mediaId with RenderMedia or useMedia, store it in state or emit it as an event, and drive prompts from an illustrator agent. Covers the model prompting guide (each model's exact size limits — generating outside them fails), idempotency, credits, and pre-authored image assets (which may be looping video clips).
- Reference images & multi-character shotsUse generateImage's referenceMediaIds to keep a character visually consistent across images and to compose several characters into one image (a two-shot of both speakers, a group scene). Generate one canonical portrait per character, keep its mediaId in state, then pass it as a reference for every later shot.
- Time, ticks & background playHow to build time-driven games — countdown timers, pets, farms, day/night, idle simulations. Pair onTick with tickInterval to run code on a fixed cadence; read the two frozen clocks state.gameTime (game-active ms, the one for timers) and state.now (a wall-clock timestamp by default, or a derived false clock in game mode); choose a clock mode ('wall' vs { start } false time) and let players fast-forward game-mode sessions; emit input events from a tick to bridge into onEvent; and opt into backgroundExecution to keep ticking up to 48h after the player leaves.
- NotificationsReach the player when something happens in your game — "your farm needs water", "the negotiation took a turn". Declare requestNotifications true in defineBackend, then call ctx.io.notify({ title, body, image?, tag? }) from onEvent (or a tool's execute) to push a notification into the player's cross-game inbox (the nav bell) and, when they're on the site, a toast. Detect a condition in onTick and bridge to onEvent with emitInputEvent. Notifications are replay-safe, free (only the content you generate spends), and coalesce by tag.
- Rolling your own composerThe built-in Chat composer (textarea + Send) is deliberately minimal and cannot be styled — no class hooks, inline styles, and none are coming. For any non-trivial input (custom width or alignment, your own styling, a single-line field, extra controls beside it) pass showInput={false} to Chat and render your own form that calls emit(...). Lock it on gameHistory.streaming || submitting || suspended; for a multiline variant, submit on Enter, newline on Shift+Enter, and guard e.nativeEvent.isComposing so an IME candidate confirmation doesn't submit mid-word.
- Agent promptsHow to prompt an in-game AI agent. Its system prompt holds who it is and its standing rules — written once, and cached. The messages of each send hold the moment — the player's input, the scene, the dice. `compaction.summarizationPrompt` says what a compaction keeps — and, with topics, what makes a topic relevant. Covers the prompt cache, persona versus situation, game facts and one-reply notes, structured agents, prompting an agent with topics, and what a custom summarization prompt must and must not say.
- Agent topicsGive an AI character knowledge that outlives its context window. Compaction topics divide an agent's compaction summary into a general summary and named topics — a person, place, thing or matter, each with a one-line description and a summary. Open topics sit in the agent's context; closed ones are listed by name and description until the agent calls `open_topic`. The compactor writes every topic, and at each compaction decides which stay open. Covers the model and what the agent sees, `AgentConfig.topics` and `maxOpenTokens`, defining relevance in the summarization prompt (with an RPG and a poker example), seeding with `initialTopics`, the `open_topic` message part, transient drafts, limits and cost.
- Remixing gamesEvery published game is readable, so a new game rarely starts from an empty tree. Point copy_files at another game's path (/games/<id>/source/**) to take its whole tree, a subtree, or one file, then adapt. Covers the path grammar, when to bulk-copy versus borrow one idea, what you can see (your own games live, everyone else's at their published version), keeping the comments you inherit, and crediting what you reuse with inspiredBy.
- Hinting (a note for one reply)Steer one reply with a note the agent must not remember — send the player's message and the note in a transient send, then keep just the message and the reply with `addMessages(user, reply)`. Covers why the note stays out of history, the `[System]` prefix, how the note rides every round of the send, what `messages` cost against kept history, and the anti-pattern of keeping every send transient and rebuilding the transcript yourself. There is no `hint` option; this is how to hint.
- Self-review (draft, check, keep)A maker-checker loop over transient sends — draft a reply without keeping it, check it with a separate structured checker agent, and keep only the accepted one with `addMessages(user, reply)`, topic opens included. Covers why the verdict needs its own agent (one agent, one format), a generate → check → revise loop that passes the draft back in `messages` (the revision sees the topics the draft opened), and what re-posting a draft costs.