Repository navigation
EN Create Game Commands
Français · Type: reference · Audience: author · Context: engine repository, created project · Status: ready · Applies from: 4.3.0
The commands a rule, a topic, a script or a listener runs, grouped by what they do. Every command is data: a plain string, or an object whose key names the command. The generated DSL reference gives each command's exact shape, field by field; this page says what each does and when to use it.
A command list (do, then, onEnter…) runs in order, each command waiting for the previous one to finish. A single
command written as plain text makes the hero speak: 'There. A step up.'. The catalogue of commands is
src/engine/core/cmds.ts (CMD_KEYS): it says which commands change the game's
state (what the solver and the saves care about) and which only show something. A key it does not know is refused by
the validator.
| Command | Effect |
|---|---|
'text' |
The hero says the line. |
{ say: ['grandma', 'text'] } |
A character speaks. 'hero' always designates the hero, whatever its id. An offscreen character (narrator, radio) speaks in a frame at the top of the screen. |
{ say: ['grandma', 'LOOK OUT!'], shout: true } |
A shout: bigger text, and it shakes. |
{ say: [...], id: 'house.l-careful' } |
A line with a stable id: its translation and its voice clip follow the id (translations). |
{ say: [...], voice: 'grandma_01' } |
Plays that clip of audio.voices; the line stays while it plays (voices). |
A line stays on screen for as long as it takes to read, or until a tap. validate warns about a line above 140
characters; under 90 reads comfortably on a phone (dialogues).
| Command | Effect |
|---|---|
{ walk: 'shelf' } |
The hero walks to the shelf's approach point (set in the layout). |
{ walk: [300, 350], who: 'grandpa' } |
Grandpa walks to that point (any actor in the room; with no walk pose, they slide in their current pose). Where he stops is kept in the save. |
{ face: 'left' }, { face: 'grandma' }, { face: 'hero', who: 'grandma' }
|
Turn left, or turn to face someone or something (the hero included). In a cutscene nobody is acted on, so nobody turns by themselves: this is how two characters look at each other. |
{ pose: ['cat', 'sleep'] } |
A lasting pose (until the next one). Character poses: see their sprites sheet. |
{ anim: ['hero', 'use'], ms: 600 } |
Hold the pose for the given time, then return to normal. Works for any actor in the room, even one in pose: 'front': { anim: ['grandpa', 'surprise'], ms: 900 } plays the surprise pose from their sheet, then they go back to front. at: { 2: [{ sfx: 'thud' }] } runs commands when the pose reaches that frame. |
{ place: ['grandpa', [420, 360]], face: 'left' } |
Teleport a character. |
{ launch: { target: 'vase', to: [420, 310], height: 60, rotate: 360, ms: 900 } } |
Stage physics (3.4): a ballistic flight of a prop or a character from where it stands (or from) to to, a point or a thing. Computed, never simulated: the same flight on every device. A character stays where it lands; a prop until the room is entered again: follow it with what it means ({ hide: 'vase' }, { prop: ['vase', 'broken'] }). |
{ spring: { target: 'lamp', axis: 'rot', amplitude: 12, frequency: 3, damping: 0.25 } } |
A damped swing or shake around its place (axis x, y or rot). |
{ path: { target: 'bat', points: [[80, 120], [300, 60], [560, 140]], orient: true } } |
Along a smooth curve through the points, turned along it. |
{ follow: { target: 'parrot', leader: 'hero', offset: [10, -70], ms: 3000 } } |
Keeps one at an offset from another for a while. |
{ wait: 500 } |
Pause, in milliseconds. In a script, the player keeps playing meanwhile. |
{ parallel: [[…], […]] } |
Play several lists at the same time (e.g. two characters walking). |
{ camera: … }, { play: [prop, anim] }, { stopAnim: prop }
|
The camera of a wide room and prop animations: geometry, staging. |
With reduced motion, every motion jumps to its end. The motions (launch, spring, path, follow) are presentation
only: the solver does not see them. Making a character walk on its own, a patrol: moving characters.
| Command | Effect |
|---|---|
{ prop: ['lamp', 'on'] } |
Change a prop's state. 'room.prop' targets another room. |
{ show: 'ghost', fade: 1200 }, { hide: 'ghost', fade: 1500 }
|
Make an actor or prop appear or disappear, with an optional fade. Kept in the save. |
{ gain: 'rope' }, { lose: 'rope' }
|
Add or remove an inventory item. gain on an item marked used reactivates it. |
{ used: 'rope' }, { used: ['rope', 'badge'] }
|
The item has served its purpose: it stays in the bag, greyed out (items). |
{ set: 'tied' }, { set: ['tries', 3] }, { unset: 'x' }, { inc: 'tries' }, { inc: 'tries', by: -1 }
|
Flags: checkboxes, counters and values, named however you like (flags, variables and events). |
{ unlock: 'market' } |
Unlock a place on the map. A locked place does not appear (world map). |
{ goto: 'market', at: 'gate' } |
Change rooms; at is an entry point of the layout, or a point. |
{ map: true } |
Open the map. |
{ moveActor: ['grandpa', 'house'], at: 'door' } |
Send a character to another room (moving characters). |
{ emit: 'bell_rang' } |
Fire an event: its listeners run right here (scripts and events). |
{ startScript: 'id' }, { stopScript: 'id' }
|
Start a script from the top, or stop it (scripts). |
{ waitUntil: COND }, { waitEvent: 'gong' }
|
In a script: pause until a condition holds, or until an event. |
{ switchPlayer: 'laverne' }, { transfer: ['tentacle', 'hoagie'] }
|
Several playable characters: take control of another one, hand an item to another one (heroes). |
{ custom: 'sparkle', args: { ms: 1200 } } |
A command the game defines in code (custom code). |
| Command | Effect |
|---|---|
{ sfx: 'coin' } |
Sound effect. caption: '[A door slams upstairs]' writes what it means for whoever cannot hear it (sound effects). |
{ music: 'market' } |
Change the music (crossfade). |
{ music: { push: 'minigame' } } then { music: { pop: true } }
|
Temporary music, then back to the previous track. |
{ music: { once: 'jingle' } } |
Play a track once on top, then the music resumes. |
{ music: { stinger: 'success' } } |
A short cue (a track of audio.music or a sound of audio.sfx) on the next beat of the score that plays (3.5); at once with a single mix (music). |
{ music: { stop: true } } |
Stop the music. |
{ toast: 'New place: Market' } |
A small message at the top of the screen (id gives it a stable id for its translation). |
{ shake: 400 } |
The screen shakes, for that many milliseconds. |
| Command | Effect |
|---|---|
{ if: COND, then: […], else: […] } |
Branch on a condition. |
{ once: […], id } |
Only once in the whole game. |
{ nth: [[…1st time], […2nd time], […after]], id } |
By number of times; the last branch repeats. |
{ cycle: [[…], […]], id } |
In a loop: 1, 2, 1, 2… (e.g. a record player alternating two tracks). |
{ random: [[…], […]], id } |
At random, never the same one twice in a row. |
In schema 3 each of once, nth, cycle and random needs a stable id: its count is kept in the save under it
(key is the old, v2 name). Remembering something for later is a flag (set); signalling a moment is an event
(emit): which to use.
| Command | Effect |
|---|---|
{ cutscene: […] } |
Cutscene: black bars, a "Skip" button. Skipping plays the rest instantly: effects (items, flags, states) still apply. |
{ choice: [{ id, text, do, if?, once?, img? }, …] } |
The player picks a line; the hero says it, then do plays. img shows the option as a card with that image (dialogues). |
{ talk: 'grandma' } |
Open an actor's conversation menu from a script. |
{ minigame: 'pipes', params: { tiles: …, cols: 4 }, then: […] } |
Launch a minigame. A minigame is never failed: then always plays, even if you skip. All its images come from params (minigames). |
{ phone: 'grandma', do: […] } |
Incoming call: ringtone (skin.sounds.phone), a Pick-up button, then the lines in do. During the call, the caller shows in a phone frame (bottom left), mouth animated while they talk; their lines appear at the top. |
{ phone: ['lou', 'seller'], do: […] } |
A call with several people: all shown side by side in the same frame (the first one in front), each at its own size (height). Each { say: ['lou', …] } animates the right person's mouth. Pose shown: the first of skin.callPoses that exists (default phone, front, face, idle); mouths from mouths.phone (otherwise the phone_talk pose alternates, otherwise a small bounce). Ids are characters from characters (no actor needed in the room). |
{ guide: { verb: 'look', target: 'shelf', say: 'Pick Look, then tap the shelf.' } } |
Tutorial: the hero gives the instruction, the verb blinks, the target glows. It waits until the player does exactly that action; any other action repeats the instruction. |
{ hint: true } |
Give the current hint (same as talking to the hint item). |
{ ending: true, after?: […] } |
The sealed ending (GameDef.ending): scratch ticket, confetti, then after, then the final card. { reveal: true } is the old name, still accepted (the sealed ending). |
{ end: true } |
End of game. |
Limit ·
custom-for-the-restWhat none of these commands does needs a custom command, written in TypeScript with its declared effects (custom code). There is no command that runs arbitrary code from the content.
- Every command's exact shape: the DSL reference. The types:
Cmdinsrc/engine/core/types/content.ts. - Reactions, conditions, scripts and events.
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