Repository navigation
EN Studio MCP Tools
Français · Type: reference · Audience: author, contributor · Context: local Studio · Status: ready · Applies from: 4.5.0
The local Studio · contract: stable · verified by CI (support matrix of 4.4.0, 2026-10-23): Chromium end to end (the Studio's checks); Windows: the unit suite only · automated checks: jobs
e2e,windows; CI plane2e,windows; 2 test files · people's passes:studio-hero-matrixnot run (#238) · known limits:demo-writes
Every tool an AI assistant can call on a quest-n-click game: the local MCP server, the remote MCP of a hosted Studio
and the Studio's Assistant all serve the same registry, tools/studio/tools.ts. The
tool sections below are generated from that registry (npm run wiki -- generate studio.mcp-tools): the English text is
the description an MCP client receives, word for word.
-
Local MCP server, engine repository. From the root of the engine repository,
npm run -s mcpstarts the server over stdio for the current game (GAME=<id>, orGAME_DIR=<folder>; by defaultpackage.json→config.game). Its server name isquest-n-click; it uses the SDK@modelcontextprotocol/sdk1.x (tools/mcp/server.ts). Use-sin a client's configuration: without it, npm prints its> quest-n-click mcpbanner on stdout, and strict clients reject it. Setting up each client: studio.mcp-setup. -
Local MCP server, created project. From the project's folder,
npx quest-n-click mcp(thequest-n-click mcpcommand) starts the same server for the project's game. -
A hosted Studio.
npm run mcp -- --server <url>gives the same tools on a Studio Server, through its API with the CLI's token (studio-server login --server <url>first); the Studio Server also serves them itself at/mcp. Every write meets the API's checks. See team.remote-mcp. - The Studio's Assistant runs the same tools in its own loop (dev server, or the demo in the browser).
stdout carries the protocol only; the server's logs go to stderr. A failing operation (an unknown room, a bad path, a broken edit…) is a tool error with its message, never a crash: the server keeps running.
-
Writes: whether the tool changes a file of the game. The Studio watches the files, so a person sees the change
live in
npm run studio. - Needs: an optional ability of the backend the tool runs on. A backend without it leaves the tool out of the list it gives the client.
-
MCP hints: the tool's
annotationsas the client receives them (readOnlyHint,destructiveHint,idempotentHint). - Input: the arguments, from the tool's zod schema as JSON Schema; a field marked optional can be left out.
| Backend | Tools left out |
|---|---|
Local server (npm run mcp, quest-n-click mcp, the dev server's Assistant): tools/studio/backend.ts
|
none |
A hosted Studio (npm run mcp -- --server <url>, /mcp): tools/studio/http-backend.ts
|
screenshot, search_docs, list_docs, read_doc, run_tests, asset_prompts, speedrun_verify
|
The demo's Assistant, in the browser: src/studio/assistant.ts
|
every tool that needs an ability, except the documentation tools when the demo's snapshot holds the pages; set_value answers that it needs the dev server |
Limit ·
demo-writesIn the demo, the tools write to the visitor's copy in the browser only, andset_valueis refused: structured writes edit the room's code through the TypeScript parser of the dev server.
Game overview. The current game: id, title, hero, rooms (id, name, decor), characters, items, verbs, checkpoints (named save states usable by solve and screenshot) and the image ids of the asset manifest with their size. Read-only.
- Writes: no (read-only).
- MCP hints:
readOnlyHint: true.
Input:
No argument.
Read a room. One room: def (the RoomDef as loaded: props, actors, hotspots, look lines, reactions on, talk, hints, onEnter), layout (geometry from layout/<id>.json), texts (every editable string literal with its JSON path, value, kind, line and speaker) and file. Use the path of a text with set_text. Read-only.
- Writes: no (read-only).
- MCP hints:
readOnlyHint: true.
Input:
| Field | Type | Required | Means |
|---|---|---|---|
id |
string |
yes | Room id, e.g. "house" (see list_rooms). |
Write a room layout. Replaces layout/<id>.json with layout (the whole Layout object, same shape as get_room returns: props, hotspots, actors, walk, scale, entries…). Read the room first and change only what you must; never invent coordinates the human has not given you.
- Writes: yes, it changes a file of the game (the Studio refreshes after it).
- MCP hints:
destructiveHint: true, idempotentHint: true.
Input:
| Field | Type | Required | Means |
|---|---|---|---|
id |
string |
yes | Room id, e.g. "house" (see list_rooms). |
layout |
object |
yes | The complete Layout object. |
Edit a text of a room. Edits one string literal of rooms/<id>.ts in place, addressed by its path from get_room texts (e.g. "look.pantry[1]", "on[3].do[0]", "talk.grandma[0].topic", "hints[2].lines[0]", "props.lamp.name"). value replaces the string. value: null deletes a list line, or a whole look.<id>. A path ending in "[+]" appends a line: "look.piano[+]", "hints[2].lines[+]", "on[3].do[+]" (a bare string in a command list is a hero line). Ids, image refs, flags and conditions are not texts and are refused. Paths after an append or a deletion shift: call get_room again. Result { ok, line, changed } (changed false: the value was already there).
- Writes: yes, it changes a file of the game (the Studio refreshes after it).
- MCP hints:
destructiveHint: true.
Input:
| Field | Type | Required | Means |
|---|---|---|---|
id |
string |
yes | Room id, e.g. "house" (see list_rooms). |
path |
string |
yes | JSON path of the text under defineRoom({...}); may end in "[+]" to append. |
value |
string | null |
yes | The new text, or null to delete. |
Write a structured value in a room. Writes a structured value (3.4) at a path of rooms/<id>.ts, as code in the file's style: a reaction ("on[3]", or "on[<length>]" to add one), a condition ("on[3].if"), a command list ("on[3].do", "onEnter"), the room's stage ("stage": layers, lights, emitters, transition, links; CONTENT_GUIDE "The stage"), its painter ("renderer": "dom" | "canvas"). With id: "@game" the game file instead, for its objectives only ("objectives.<id>": { title, done, optional?, parent? }, or one of its fields; list_rooms shows them). value is the JSON of it; omit it (null) to remove the path. dry: true returns the diff only. Otherwise the game is reloaded and validated after the write: an edit that adds a validation error is taken back and refused with the errors. Result { ok, line, changed, diff }.
- Writes: yes, it changes a file of the game (the Studio refreshes after it).
- MCP hints:
destructiveHint: true.
Input:
| Field | Type | Required | Means |
|---|---|---|---|
id |
string |
yes | Room id, e.g. "house" (see list_rooms). |
path |
string |
yes | Path under defineRoom({...}): "stage", "renderer", "on[3]", "on[3].if", "on[3].do", "onEnter"; with id "@game": "objectives.<id>". |
value |
any JSON | null |
yes | The value as JSON (a condition, a command list, a stage…); null removes the path. |
dry |
boolean |
no | Only return the diff, write nothing. |
Add a prop, hotspot or actor. Adds an entry to rooms/<id>.ts (section created if absent), its optional first look line, and a place in the layout: prop foot at at (height 60), hotspot 60 × 60 box centred on at, actor feet at at. name is required for props and hotspots; img is a prop image id (list_rooms images); char is the actor character id. at defaults to [320, 300]: then ask the human (add_note) to drag it in place in the Studio. 409 if the id exists.
- Writes: yes, it changes a file of the game (the Studio refreshes after it).
- MCP hints:
destructiveHint: false.
Input:
| Field | Type | Required | Means |
|---|---|---|---|
id |
string |
yes | Room id, e.g. "house" (see list_rooms). |
kind |
"prop" | "hotspot" | "actor" |
yes | |
entityId |
string |
yes | The new entity id (letters, digits, _ and -). |
name |
string |
no | Display name. |
img |
string |
no | Prop image id. |
char |
string |
no | Actor character id. |
at |
[number, number] |
no | [x, y] in the logical 640 × 400 room space. |
look |
string |
no | First look line. |
Read the storyboard. storyboard.json: { boards: [...] } with panels, lines, hints and talk topics. The storyboard is the source of truth for text: change it first, then the rooms. Read-only.
- Writes: no (read-only).
- MCP hints:
readOnlyHint: true.
Input:
No argument.
Write the storyboard. Replaces storyboard.json with storyboard (must be { boards: [...] }; send the whole object as read with get_storyboard, modified). Written compactly; an unchanged storyboard is not rewritten. Result { ok, changed }.
- Writes: yes, it changes a file of the game (the Studio refreshes after it).
- MCP hints:
destructiveHint: true, idempotentHint: true.
Input:
| Field | Type | Required | Means |
|---|---|---|---|
storyboard |
{ boards } |
yes | The whole storyboard. |
Read the notes. notes.json, the shared log between the human and the AI: { entries: [{ id, about, author, text, at, task? }] }. The human answers your questions here; entries with task: true are requests from the human for you to do. Read-only.
- Writes: no (read-only).
- MCP hints:
readOnlyHint: true.
Input:
No argument.
Write a note to the human. Appends a note to notes.json (shown in the Studio Notes tab). Use it when unsure what the human wants, or to ask them to place something. about is a room id, a panel id, room.entity or free text. author defaults to the name of your MCP client.
- Writes: yes, it changes a file of the game (the Studio refreshes after it).
Input:
| Field | Type | Required | Means |
|---|---|---|---|
about |
string |
no | What it is about. |
author |
string |
no | Who writes (default: the MCP client name, or "ai"). |
text |
string |
yes | The note. |
Validate the game. Static checks: broken ids, missing look lines, flags never set or read, minigame params. Result { ok, errors, warnings, ms }. Run after every content change.
- Writes: no (read-only).
- MCP hints:
readOnlyHint: true.
Input:
No argument.
Solve the game. Explores the game states to prove it can be finished, from New Game or from checkpoint from. Result { status, exit, headline, mode, finished, states, truncated, path, roomsReached, flagsReached, itemsNeverUsed, unusedItems, deadEnds, softlocks, errors, from, ms }. status/exit/headline are exactly what npm run solve prints (0 solved, 2 truncated: nothing proved, 1 a bug to fix). prove: true runs the exhaustive search (softlocks complete). profile: true adds why the search is slow or big.
- Writes: no (read-only).
- MCP hints:
readOnlyHint: true.
Input:
| Field | Type | Required | Means |
|---|---|---|---|
from |
string |
no | Checkpoint id (list_rooms checkpoints). |
profile |
boolean |
no | Add the solver profile as text: what the states are made of, what the search cost, independent dimensions, monotonic things. |
prove |
boolean |
no | Exhaustive search: every reachable state and the softlocks (slow on a big game; default: the fast witness). |
reality |
"closed" | "adversarial" | { scenario, signals } |
no | A game with reality.signals (4.1.1): the world to solve in. closed (default) no signal, a scenario { scenario, signals } in that order, adversarial any declared signal at any point. A simulation: no service is contacted. |
Content profiler. Game-design profiler, as Markdown: per room (zones, props, actors, exits, rules, topics, hints, scripts; things with no look line, verbs that only get fallbacks, props that never change), per item (obtained where, how many rules use it, consumed), per character (rooms, topics, lines, unreachable topics), unreachable rooms and exits with no way back. Read it to decide what to write next. Read-only.
- Writes: no (read-only).
- Needs: the backend ability
report: a backend without it (the demo, a hosted Studio without that route) leaves the tool out. - MCP hints:
readOnlyHint: true.
Input:
No argument.
The game as the tools see it. The game's intermediate representation (4.1.12): rooms, entities, rules, topics, listeners, scripts, objectives, Reality policies and the trusted extensions by name, each id with the file and line that writes it (provenance). The same JSON as npm run ir -- --json. Read-only.
- Writes: no (read-only).
- Needs: the backend ability
ir: a backend without it (the demo, a hosted Studio without that route) leaves the tool out. - MCP hints:
readOnlyHint: true.
Input:
No argument.
World map. The rooms and the ways between them (declared exits, goto commands, map places) as a DOT graph, with unreachable rooms and exits with no way back. Read-only.
- Writes: no (read-only).
- Needs: the backend ability
graph: a backend without it (the demo, a hosted Studio without that route) leaves the tool out. - MCP hints:
readOnlyHint: true.
Input:
No argument.
Dialogue tree. The conversation of a character in a room as an indented tree: topics (with their conditions), lines, choices and their options, branches. Derived from the talk topics, nothing else to maintain. Read-only.
- Writes: no (read-only).
- MCP hints:
readOnlyHint: true.
Input:
| Field | Type | Required | Means |
|---|---|---|---|
id |
string |
yes | Room id. |
actor |
string |
no | Actor id (default: every character with topics). |
Puzzle graph. What every rule, topic, script and listener needs (conditions, items) and changes (items, flags, props, places, events). Without id: the overview as Markdown (every item and flag with what produces and uses it, flags read but never set, things produced but never used). With id (an item, flag, prop, place or event): its card: acquired by, consumed by, used by, requires first, unlocks, downstream. Read it before changing a puzzle. Read-only.
- Writes: no (read-only).
- Needs: the backend ability
puzzle: a backend without it (the demo, a hosted Studio without that route) leaves the tool out. - MCP hints:
readOnlyHint: true.
Input:
| Field | Type | Required | Means |
|---|---|---|---|
id |
string |
no | An item, flag, prop (room.prop), place or event id; none for the overview. |
Storyboard coverage. The storyboard (get_storyboard) checked against the content, as Markdown: per board and panel, whether its room, speakers, lines, talk topics, sounds and actions ("Open the armchair", "Use pipe with tank") exist in the game: ok, partial (the pieces exist, no rule answers; a close line), missing, or unknown (prose). Read it to find what of the story is not implemented yet. Read-only.
- Writes: no (read-only).
- Needs: the backend ability
coverage: a backend without it (the demo, a hosted Studio without that route) leaves the tool out. - MCP hints:
readOnlyHint: true.
Input:
No argument.
Playtests. The sessions players shared from their phones (games/<id>/playtests/*.session.json, ids only) replayed on the current content and summed up, as Markdown: time per room, where players stall (the same action again and again without effect), hints shown, where they stopped, minigames played, sessions the content has outgrown. Read it to know where the game is harder than you think. Read-only.
- Writes: no (read-only).
- Needs: the backend ability
playtests: a backend without it (the demo, a hosted Studio without that route) leaves the tool out. - MCP hints:
readOnlyHint: true.
Input:
No argument.
Content lint. What the validator cannot say and the solver does not say loudly, as Markdown: conditions nothing can satisfy, rules another rule hides, items no rule needs or nothing gives, hints that cannot fire, choices with a dead option, and, from a solver run, live actions never run and rooms never reached. Each finding names its content path, its stable id and what to do. prove: true runs the exhaustive search first (slow on a big game). Read it before asking a human for a review. Read-only.
- Writes: no (read-only).
- Needs: the backend ability
lint: a backend without it (the demo, a hosted Studio without that route) leaves the tool out. - MCP hints:
readOnlyHint: true.
Input:
| Field | Type | Required | Means |
|---|---|---|---|
prove |
boolean |
no | Run the exhaustive proof first (default: the fast witness). |
Screenshot a room. Renders a room (optionally at a checkpoint) with the real engine through the running dev server (default http://localhost:5173/, env WEB_SCUMM_DEV_URL; start it with npm run studio or npm run dev) and Playwright. Returns the PNG path (relative to the repository) to open and look at, or an explanation when unavailable.
- Writes: no (read-only).
- Needs: the backend ability
screenshot: a backend without it (the demo, a hosted Studio without that route) leaves the tool out. - MCP hints:
readOnlyHint: true.
Input:
| Field | Type | Required | Means |
|---|---|---|---|
room |
string |
yes | Room id, e.g. "house" (see list_rooms). |
checkpoint |
string |
no | Checkpoint id. |
Search the documentation. Searches the documentation pages (the wiki written under wiki/, 4.5.0) by words, in French or English: page titles and questions first, then aliases, keywords and identifiers (a DSL command, an npm script, an HTTP code such as 423), then section headings, then section text. Accents and case do not matter; the glossary adds the other language's words (verrou, lease). Each result is id#section with its title, type, context, versions, status, score, the reason of the match and an excerpt with the words found in bold: read it with read_doc { id, section }. No confident match gives an empty list and the index pages to try. version leaves out what does not apply to that version. Read-only.
- Writes: no (read-only).
- Needs: the backend ability
docs: a backend without it (the demo, a hosted Studio without that route) leaves the tool out. - MCP hints:
readOnlyHint: true.
Input:
| Field | Type | Required | Means |
|---|---|---|---|
query |
string |
yes | Words or a question, in French or English. |
lang |
"en" | "fr" |
no | Only pages in this language (default: both). |
audience |
"player" | "author" | "admin" | "contributor" |
no | |
context |
"engine-repo" | "created-project" | "studio-local" | "studio-demo" | "studio-hosted" | "bridge" | "player" |
no | |
version |
string |
no | A product version (4.5.0): only what applies to it. |
type |
"tutorial" | "howto" | "reference" | "explanation" | "troubleshooting" | "index" |
no | |
includeArchived |
boolean |
no | Also deprecated and archived pages, and with version the pages that do not apply, marked so. |
limit |
integer 1..20 |
no | Results per answer (default 5, at most 20). |
cursor |
string |
no | The cursor of a previous answer to the same request, for more. |
List the documentation pages. The documentation pages there are to read (wiki/, 4.5.0), filtered by audience, context, type, language or state: id, title, type, audience, context, versions, state, languages and section ids. A page still to write is not listed. Read-only.
- Writes: no (read-only).
- Needs: the backend ability
docs: a backend without it (the demo, a hosted Studio without that route) leaves the tool out. - MCP hints:
readOnlyHint: true.
Input:
| Field | Type | Required | Means |
|---|---|---|---|
audience |
"player" | "author" | "admin" | "contributor" |
no | |
context |
"engine-repo" | "created-project" | "studio-local" | "studio-demo" | "studio-hosted" | "bridge" | "player" |
no | |
type |
"tutorial" | "howto" | "reference" | "explanation" | "troubleshooting" | "index" |
no | |
lang |
"en" | "fr" |
no | |
state |
"draft" | "ready" |
no | draft pages exist in the repository only. |
Read a documentation page. Reads the documentation. Recommended: search_docs, then read_doc { id, section } for the section it found (lang en or fr, default en; maxChars 20000 by default, at most 100000, and a cursor for the rest), with where the text comes from (version, commit, doc revision) at its top. name instead returns a whole, large historical page in one block, rebuilt from the sections of the documentation: CONTENT_GUIDE (the game format, the DSL of rooms, conditions and commands), ENGINE, TOOLS, STUDIO, WORKFLOW, AUDIO (music and effects), UPGRADING (v2 to v3), CLASSICS (the famous mechanics of the genre, each with its DSL: read it before asking for a new command); with name, the other arguments are ignored. Give either name or id, not both. Read-only.
- Writes: no (read-only).
- Needs: the backend ability
readDoc: a backend without it (the demo, a hosted Studio without that route) leaves the tool out. - MCP hints:
readOnlyHint: true.
Input:
| Field | Type | Required | Means |
|---|---|---|---|
name |
"CONTENT_GUIDE" | "ENGINE" | "TOOLS" | "STUDIO" | "WORKFLOW" | "AUDIO" | "UPGRADING" | "CLASSICS" |
no | One of the eight historical pages, whole (the other arguments are then ignored). |
id |
string |
no | A page id from search_docs or list_docs, e.g. "create.rooms". |
section |
string |
no | A section id of that page (its <a name>), e.g. "walkable-zones". |
lang |
"en" | "fr" |
no | The page's language (default en). |
cursor |
string |
no | The cursor of the previous answer, for the rest of the text. |
maxChars |
integer 1..100000 |
no | At most this many characters per answer (default 20000). |
Run the tests. Runs npx vitest run (engine tests and the game walkthrough) and returns the summary lines and the failures. Takes a few seconds to a minute. Read-only.
- Writes: no (read-only).
- Needs: the backend ability
runTests: a backend without it (the demo, a hosted Studio without that route) leaves the tool out. - MCP hints:
readOnlyHint: true.
Input:
No argument.
Art prompts. The image-model prompts for the game's art (same as npm run prompts): one STYLE block, then one ready-to-paste prompt per sheet (characters with the engine's pose rows and special poses, mouth kits, object sheets cell by cell, backgrounds with LOCATION and EMPTY SPOTS, furniture) and a checklist to cut and import them. Hand the sections to the human as-is; never write a sprite prompt by hand. missing: true keeps only the sheets with images not cut yet. Returns the markdown, and { missing, sheets } as structured content. Read-only.
- Writes: no (read-only).
- Needs: the backend ability
assetPrompts: a backend without it (the demo, a hosted Studio without that route) leaves the tool out. - MCP hints:
readOnlyHint: true.
Input:
| Field | Type | Required | Means |
|---|---|---|---|
missing |
boolean |
no | Only the sheets with at least one missing image, and only their missing cells. |
Verify a speedrun. Replays a speedrun envelope (.wsrun, 4.1.14) against the current game: reloads the exact rules of its category, replays its inputs with its seed, recomputes the in-game time, the splits, the final state and the hash chain, and checks the category’s rules. Returns { verdict, code, reason, trust }: valid is the only rankable verdict, inconclusive is never valid, and a verifier grants at most replay-valid. Pass the file path under the game project, or the envelope text. Read-only.
- Writes: no (read-only).
- Needs: the backend ability
speedrunVerify: a backend without it (the demo, a hosted Studio without that route) leaves the tool out. - MCP hints:
readOnlyHint: true.
Input:
| Field | Type | Required | Means |
|---|---|---|---|
path |
string |
no | Path of the .wsrun file, relative to the repository or project. |
envelope |
string |
no | The .wsrun text itself (instead of a path). |
The local server also gives two resources, as JSON: webscumm://game (the same as list_rooms) and
webscumm://room/<id> (the same as get_room). They keep the former name's scheme, webscumm://.
- A tool that fails returns a tool error,
isError: true, whose text isError: <message>, with(status <n>)when the operation carries an HTTP status (an id that exists already is 409, an edit that would add validation errors 422: see reference.error-codes). - Arguments that do not match a tool's input are refused before it runs:
bad arguments for <tool>: <field>: <why>. - An unknown tool, or one the backend leaves out:
no such tool: <name>. -
search_docs,list_docsandread_docname a stale cursorstale_cursorin their structured content.
- studio.api: the HTTP routes behind the same operations.
-
reference.cli: the
quest-n-click mcpcommand.
Generated publication · publication générée — current documentation · documentation courante: quest'n'click 4.4.0 r1, documentation revision · révision de la documentation 8dc717c69acb62c4742b69c54a7e7dfb620f75d8.
Earlier versions and permalinks · versions précédentes et liens permanents: https://wanoo.github.io/quest-n-click/docs/
An edit made in this wiki is overwritten at the next publication · une modification faite dans ce wiki est écrasée à la publication suivante.
Edit the source · Modifier la source · Report an error · Signaler une erreur
Index (6)
Start (6)
Play (9)
Install (17)
- Requirements
- Install from the release archive
- Install from npm, once published
- Install from the repository to work on the engine
- doctor: checking your machine
- Image toolchain
- Audio toolchain: ffmpeg, fluidsynth, Furnace, uv
- Upgrade
- Upgrade notes: 4.4
- Upgrade notes: 4.3
- Upgrade notes: 4.2
- Upgrade notes: 4.1
- Upgrade notes: v3
- Upgrade notes: v2 to v3
- Coming from web-scumm
- Package reference
- Install troubleshooting
Create a game (55)
- Your first game
- Layout of a created project and of the engine repository
- The working loop
- Content principles and the identity contract
- Rooms
- Geometry: placement, walk zones, masks, layers, camera
- Something is visible but unreachable
- Reactions
- Game commands
- Conditions
- Flags, variables and events: which to use
- Custom code
- Characters
- Items and inventory
- World map
- Dialogues
- Scripts and events
- Moving characters: patrols and walks
- Exits
- Chapters and objectives
- State and saves: persistent or temporary, renaming an id, migrations
- Staging: wide rooms and animations
- The stage: lights, particles, floors
- Skin and fonts
- Title and credits
- Heroes: several characters and hero choice
- Built-in minigames
- A custom minigame
- Translations
- Music in stems
- Sound effects
- Voices: per language and per hero
- Images: prompts, cutting sheets, transparency, scale
- Asset provenance
- The storyboard, source of truth
- Puzzle design
- Classic mechanics
- Review pages
- DSL reference
- Checking your game
- What the solver proves
- Solver options
- Playtests
- Remix
- Speedrun for authors
- The sealed ending
- Production template
- Example games
- Working with an AI
- Build and release a game
- Publish on GitHub Pages
- The static game on Clever Cloud
- Other static hosts
- Sub-path, cache and service worker, incomplete deploys, going back
- Testing on a phone over the LAN
Local Studio (24)
- The local Studio: overview and launch
- Edit a room
- Placement and stage
- Preview, apply, undo
- Storyboard
- Assets and cutting
- Check: validator, solver, critical path, heat, health, coverage
- Before and after captures
- Semantic diff
- Play and replay a session
- Rule explainer
- Language and objectives
- Voices and the heroes × languages matrix
- Map
- Notes
- Remix in the Studio
- Music
- The Assistant: bring your own key
- Demo mode and studio-apply
- Local and LAN security
- Studio API
- Local MCP: setting up each client
- MCP tools
- Studio troubleshooting
Team Studio (21)
- What runs where
- Concepts: revision, transaction, span, lease, preview, build
- Starting as an invited dev
- Working together day to day
- Roles and actions: the full matrix
- Invitations
- Managing members
- Write refused on the hosted Studio: stale base revision (409)
- Write refused on the hosted Studio: span locked (423)
- Recovering after a lost lease, a disconnection or a stale preview
- Comments
- Map and semantic diff
- Publishing builds
- Remote MCP
- The game in Git
- Upgrading the engine of a hosted game
- Hosted assets
- The server's command line
- Health and metrics routes
- Trying it locally with compose.yml
- Known limits
Clever Cloud (23)
- Clever Cloud: overview, cost and prerequisites
- Apps and add-ons
- Domains and TLS
- Keycloak
- Generic OIDC and GitLab
- Configuration
- First deployment
- Backups
- RPO and RTO
- Restore the Studio on a fresh installation
- Redeploys
- Upgrading the server and checking state after a migration
- Limits of going back
- Monitoring
- Security
- Rotating keys
- Recovering admin access
- Changing domain or OIDC provider
- Worker, PostgreSQL or Cellar down
- Exporting the game and leaving the installation
- Retention
- Clever Cloud troubleshooting
- Costs and teardown
Reality Bridge and connectors (16)
- The Reality Bridge: what it is
- Quick start
- Guarantees
- Install and run the Bridge
- Backup and restore
- Several tenants
- Signals and the manifest
- The Bridge's command line
- Connectors overview
- Email connector
- Telnet connector
- SSH connector
- Open Badges connector
- The connector SDK
- Security: Biscuit and signatures
- Bridge and connector troubleshooting
Contribute (25)
- Welcome
- Developer setup
- The dev loop
- Before a pull request
- Conventions
- Writing documentation
- Architecture
- Code tour
- Import boundaries
- Which tests run when
- Mutation testing
- The coverage ratchet
- The quality baseline
- CI explained
- Field passes
- Benchmarks
- Releasing
- npm packages
- Decisions and ADRs
- Governance
- Bot pull requests
- Contributing with AI agents
- Security policy
- Code of conduct
- Licences and credits