Repository navigation
EN Team Try Locally
Français · Type: tutorial · Audience: admin · Context: hosted Studio · Status: ready · Applies from: 4.2.3
The Studio Server (hosted team Studio) · contract: experimental · verified by CI (support matrix of 4.4.0, 2026-10-23): Postgres, S3 and Keycloak in CI; Chromium and Firefox (job studio-hosted); WebKit on macOS, by hand only · automated checks: jobs
studio-hosted,studio-install-smoke; CI planstudioHosted; 3 test files · people's passes:studio-hostednot run (#149),studio-collabnot run (#150),studio-previewnot run (#166),studio-assets-hostednot run (#167),studio-mcp-remotenot run (#196),studio-oidc-genericnot run (#197) · known limits:no-oidc-mode,compose-not-verified
You want to see the Studio Server work before hosting it. In ten minutes, on your machine, you will run it in its
simplest mode (no login, SQLite and a folder), import a game, write through its API, watch the journal, and export the
game back. Then you will see what ops/studio/compose.yml adds to try the full team mode.
A Studio Server on 127.0.0.1:8787 holding one game at revision 1, then 2 after your first write, and a folder with
that game exported at its head. Every step prints something you can check.
- The engine repository with its dependencies installed (
npm ci), and Node 22.12 or newer (see Requirements). -
curl. Docker is never required; it only serves the optional part at the end.
-
Write a configuration without
oidc: the server is then the local one, on the loopback only, with SQLite and a folder for the contents. Save it as/tmp/studio-try/studio.config.json:{ "publicUrl": "http://127.0.0.1:8787", "playUrl": "http://127.0.0.1:8788", "game": "template", "workDir": "/tmp/studio-try/work", "host": "127.0.0.1", "port": 8787, "store": { "kind": "sqlite", "file": "/tmp/studio-try/work/journal.sqlite" }, "blobs": { "kind": "fs", "dir": "/tmp/studio-try/work/blobs" } }playUrlmust be another origin thanpublicUrl, even here. Then create the folder:# anywhere mkdir -p /tmp/studio-try/work
-
Import a game.
# in the engine repository npm run studio-server -- import games/_template --config /tmp/studio-try/studio.config.jsonYou see
{"event":"imported","game":"template","revision":1}.
-
Start the server (it stays in the foreground; use a second terminal for the next steps):
# in the engine repository npm run studio-server -- serve --config /tmp/studio-try/studio.config.jsonYou see
{"event":"lease-taken",…}then{"event":"listening","host":"127.0.0.1","port":8787,…}.
-
Ask it how it is.
# anywhere on the machine curl http://127.0.0.1:8787/readyz curl http://127.0.0.1:8787/api/revisionYou see
{"ok":true,"writes":"served"}(this instance serves writes) and{"epoch":"…","revision":1}.
-
Write through the API, with an operation id, twice:
# anywhere on the machine curl -i -X POST -H 'content-type: application/json' -H 'x-studio-op: try-local-0001' \ -d '{"text":"hello from curl"}' http://127.0.0.1:8787/api/notes curl -i -X POST -H 'content-type: application/json' -H 'x-studio-op: try-local-0001' \ -d '{"text":"hello from curl"}' http://127.0.0.1:8787/api/notes
You see the first answer with
x-studio-revision: 2; the second, the same answer withx-studio-replayed: 1: the write was applied once.
-
Read the journal and the diff.
# anywhere on the machine curl "http://127.0.0.1:8787/api/ops?after=1" curl http://127.0.0.1:8787/api/diff/1..2
You see operation 2 writing
notes.json, and the diff naming the note's fields added.
-
Stop the server with Ctrl+C in its terminal. You see
{"event":"stopping","signal":"SIGINT"}.
-
Export the game at its head:
# in the engine repository npm run studio-server -- export /tmp/studio-try/exported --config /tmp/studio-try/studio.config.json
You see
{"event":"exported","revision":2,"files":…}, and/tmp/studio-try/exported/export-manifest.jsonwith each file's hash. Delete/tmp/studio-trywhen you are done.
Limit ·
no-oidc-modeWithout OIDC there is no login, no member and no role: anything that can reach the loopback writes. So the server refuses any address but the loopback. There are no spans, leases, comments, previews nor published builds (they need a team Studio), and the Studio's browser page needs a login this mode does not have: use the API here, andnpm run studiofor a local Studio in the browser.
ops/studio/compose.yml starts, on the loopback only, Postgres (127.0.0.1:55432,
user studio), MinIO, an S3 store (127.0.0.1:59000), and Keycloak (127.0.0.1:58080) with the test realm
web-scumm and one test user, lea@example.org, password lea-local-only, email verified:
# in the engine repository
docker compose -f ops/studio/compose.yml up -dIt is a starting point, not a turnkey setup. On top of it you still need:
- a configuration with
oidc(issuerhttp://127.0.0.1:58080/realms/web-scumm, clientsstudioandweb-scumm-cli) andoidc.allowInsecure: true, since the provider answers over http; the realm'sstudioclient expects its callback athttp://localhost:8080/auth/callback, sopublicUrlishttp://localhost:8080unless you edit the realm; -
store.kindpostgreswithSTUDIO_DATABASE_URL, andblobs.kinds3on MinIO with a bucket you create andSTUDIO_S3_KEY_ID/STUDIO_S3_KEY_SECRET; - the secrets
STUDIO_OIDC_CLIENT_SECRET(the realm's) andSTUDIO_SESSION_KEY; - a worker (
npm run studio-worker, withWORKER_PUBLIC_KEYandWORKER_INSTANCE), its keys made byworker-keys, andworkerin the configuration withSTUDIO_WORKER_KEY; - the Studio's page built:
npm run studio-client; -
trustProxyif the server listens beyond the loopback.
Limit ·
compose-not-verifiedThis full local mode is not exercised end to end by the project's tests: CI's hosted e2e runs the server with a test provider in its own process. Browsers keepSecurecookies over http on the loopback unevenly (WebKit keeps none); the e2e serves Firefox and WebKit over https with a certificate made for the run. The reference deployment is Clever Cloud: see First deployment.
- A write is an operation with an id, applied once (Concepts).
- Every change moves the revision, and the journal lists it (Concepts).
-
exportgives the game back at its head (The server's command line).
- What runs where: the parts of a hosted Studio.
- Clever Cloud: overview, then First deployment.
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