Mobile-first SCUMM-style point-and-click engine with authoring tools and an AI-friendly workflow
See the codeBuild a complete point-and-click adventure with an AI, and prove it can be finished.
A SCUMM-style engine made for phones, a visual Studio to produce the game, and a pipeline that checks it, proves it and ships it as a web game that works offline. It started as the engine of a 9-room family game, written and shipped in a single day with an AI assistant.
| 🎮 Play | The Pantry Key, the sample game: phone in landscape, or desktop |
| 🛠 Studio | Open the Studio in demo mode: your edits stay in your browser |
| 🚀 Start | Make your own game in a few commands |
| 📚 Docs | The method · the content format · all the docs |

New in v3.7 "Field Proof": the sample game may be sold: its theme, Tchaikovsky's Swan Lake written out and
arranged for the project, replaces an arrangement under a non-commercial licence, so npm run verify:commercial
passes. The reference chapter plays two scores joined by bridges, and the browser checks that a transition can be
cancelled, restored from a save, or stopped without leaving a sound behind (3.6.1 "Audio truth" gave the music its
three intents: play, restore, stop). The nightly corpus runs in four shards and keeps its counts.
v3.6 "Production": the music director is held to budgets of its own (stems, offline, decoded audio, a cap on what it keeps), its stem files are measured before a release, and one score hands over to another on a beat, a bar, a phrase or a marker, through a bridge; a save keeps where the music was. The proof pools items per group of characters who can meet, so open chains with three characters are proved where 3.5 gave up (the measures), and random games of three kinds are checked against the explicit search every night (counted as tried, compared and partial).
v3.5 "Score": music that follows the game. A track is cut into stems that play in sync; the mix changes with the room, the active character or a flag, on the next bar, without a click. The proof runs on several cores with the same result, and pools the items the characters can hand each other, so two-character games with items moving freely are proved (how it is measured). It is an adaptive stem mixer with transitions, not iMUSE: no tempo changes, no branches inside a score. 3.4 "Stagecraft" brought scenes with depth: a Canvas painter, layers, masks, lights, walk zones and stairs, the structured Studio, and a second game, "The Night Market".
| Step | What web-scumm gives you |
|---|---|
| Write | A storyboard first, then rooms, dialogue with choices, hints and rules, all as plain data. |
| Build | Rooms placed by dragging, characters cut from generated sprite sheets, prompts for every image, chip-tune music and sound effects. |
| Check | Broken references, untranslated lines, the licence of every shipped file, what a phone has to download. |
| Prove | A path to the ending, every state where the ending is lost and why, saves that load across versions, real browsers. |
| Ship | A static web game that installs on a phone, plays offline, on touch, mouse or keyboard. |
Measured on the release, proof cache off (BENCH.md):
| What | Result |
|---|---|
| "The Night Market", 8 rooms, 2 playable characters | proved in 288 states, 1.2 s; the abstractions audited against 83 672 explicit states |
| An open chain of 20 rooms, 2 characters, 12 items moving freely | proved in 14 002 states, 19 s (out of reach before 3.5) |
| An open chain of 14 rooms, 3 characters, items moving freely | proved in 93 480 states, 166 s (out of reach before 3.6) |
| 900 random games, abstractions against the explicit search | 549 verdicts compared, no divergence (351 stopped partial) |
| A 40 000-state proof on 4 worker threads | ×2.54 faster, the same result as on 1 |
| The music director, rendered offline for 30 minutes | 0 samples of drift; 100 changes of mix without a click; 0.02 ms jitter live |
| Its staged market: 6 layers, parallax, 3 masks, two floors | 50 frames per second with the CPU slowed 4× (Canvas) |
| A first visit | every byte the browser fetched was predicted by the asset graph |
| Reference game, 40 rooms × 3 characters, structured by eras | proved in 578 states, 4.1 s |
| The sample game, every reachable state | proved in 2.5 s, then 0.17 s from the proof cache |
| The sample game, chapter by chapter | proved in 3.7 s |
| The 7 bundled minigames | each one won with the keyboard alone, in Chromium and WebKit |
| Accessibility | tested at the keyboard, no serious or critical axe-core violation on any screen checked (not a WCAG claim) |
| Shipped assets | every file's hash and licence locked after review; weight budgets per room and chapter |
The proof explores the game as the engine plays it and assumes the minigames are won. The reference game keeps each character in their own era. When items can move freely between three characters, the search still stops before the end, and BENCH.md says so.
![]() Conversations with topics, choices and a transcript | ![]() Minigames, playable by touch or keyboard |
![]() A world map, characters who move between places | ![]() An ending that remembers what the player guessed |
Nine classic verbs and a bag, dialogue, hints from a character, cutscenes and phone calls, rooms wider than the screen, several playable characters with their own bags, scripts and events, seven minigames, an optional sealed ending, autosave and save slots, translations, settings, touch, mouse and keyboard, and the whole game offline after the first visit.
![]() Rooms: the real engine, a placement editor on top, every line editable in place | ![]() Storyboard: the story panel by panel, checked against the game |
![]() Assets: every sheet and cell, where it is used, the prompt to make it | ![]() Check: the validator and the solver, run again after every save |
The puzzle graph shows what each item, flag and room leads to. With Critical path on, what does not lead to the end fades. With Heat, the rules the solver went through most turn red. The Studio also has a Play tab with a rule explainer and session replay, shared notes with the AI, and an Assistant that works with any model.
Needs Node 22+, Python 3 for the art tools (pip install -r requirements.txt) and ffmpeg for sound.
In its own project (3.9, PACKAGE): the engine installs from a release's tarball (npm
publishing to come, then npx create-web-scumm my-game):
T=https://github.com/wanoo/web-scumm/releases/download/v3.9.0/web-scumm-3.9.0.tgz
npx --package=$T web-scumm create my-game "My Game" --engine=$T
cd my-game && npm install
npm run assets && npm run dev # then npm run verify, npm run build, npm run release
In this repository, beside the sample games:
npm install
npm run doctor # checks Node, Python modules, ffmpeg and the test browsers
npm run new-game my-game "My Game" # games/my-game from the template, set as the current game
npm run assets # prepares the placeholder art
npm run studio # the Studio: rooms, story, assets, checks, play
Then, before anyone plays it:
npm run verify:game # validation, a path to the ending, chapters, translations, lint, playtests
npm run prove:game # every reachable state: softlocks and truncation fail
npm run build # tests, bundle and audits, into dist/ for any static host
npm run dev plays your game on this computer, npm run dev:lan on your phone. Write the story in
storyboard.json first, then the rooms with CONTENT_GUIDE open.
WORKFLOW is the whole method, step by step.
Everything is data: rooms, props with states, characters, items, rules, topics, hints, scripts, events. There is no code in the content, so every tool can read it, check it and play it.
export const garden: RoomDef = {
id: 'garden', name: 'The garden', decor: 'garden',
props: { tank: { name: 'water tank', states: { full: 'tank_full', empty: 'tank_empty' } } },
actors: { grandpa: { char: 'grandpa' } },
exits: { back_door: { name: 'back door', to: 'house', entry: 'garden' } },
on: [
{ verb: 'use', a: 'pipe', b: 'tank', if: '!tank_drained',
do: [{ minigame: 'pipes', params: { /* see games/demo */ } }, { lose: 'pipe' }, { set: 'tank_drained' }, { prop: ['tank', 'empty'] }] },
],
talk: { grandpa: [{ topic: 'Where is the key?', if: '!tank_drained', do: [{ say: ['grandpa', 'It fell in the tank. Plop.'] }] }] },
hints: [{ until: 'tank_drained', lines: ['Use the pipe on the water tank.'] }],
};
A rule is a verb, a target, a condition and a list of commands. CLASSICS writes twenty famous mechanics of the genre with it: insult sword fighting, a nurse on patrol, a tree planted in the past.
CLAUDE.md and AGENTS.md hold the rules.npm run prompts writes ready-to-paste image prompts for every character sheet, object, background and piece of
furniture, all in one style. npm run assets cuts the generated sheets into sprites (PROMPTS).
npm run audio arranges a MIDI for Mega Drive chips and renders the sound effects from the same palette
(AUDIO).
| Read | For |
|---|---|
| WORKFLOW | the method, from the first idea to the release |
| CONTENT_GUIDE · CLASSICS · DESIGN | writing content, famous mechanics, making it a good game |
| STUDIO · TOOLS · MCP | the Studio, every command, the AI tools |
| ENGINE · BENCH · FIELD | how the engine works, what the proof can and cannot do, what only people and real devices check |
| PROMPTS · AUDIO · PAGES | images, sound, the review pages |
| PACKAGE · API · SUPPORT | a game in its own project (npx create-web-scumm), the public API, what stays stable |
| ROADMAP · CHANGELOG · UPGRADING | where it comes from, every release, moving to a new version |
Every page also exists in French under docs/fr/. docs/dev/ holds the log of the work with the other assistant.
Current release: v3.9.0 "Independence": the engine as a
package (web-scumm, create-web-scumm), a game made outside the repository verified, built and played in CI, and
the public API that 4.0 will hold stable. The story from v1.3 to v3.9 is in the
ROADMAP, every change in the CHANGELOG.
src/engine/ core (the DSL, the engine), tools (validate, solve, lint, i18n…), dom (the renderer), minigames
games/demo/ the sample game: rooms, layouts, art, audio, locales, storyboard
games/_template/ copied by npm run new-game
tools/ the commands, the Studio, the MCP server, the art pipeline
scripts/ the browser tests, the sealed ending, new-game, the README screenshots
docs/en docs/fr the documentation; docs/dev: the work log
The images of this page come from the production bundle and the Studio, taken by npm run docs:screenshots.
Code: MIT. Sample artwork, sound effects and theme: CC BY 4.0 (attribution "Wano"); the theme is Tchaikovsky's Swan
Lake (public domain), written out and arranged for the project, so the sample game passes npm run verify:commercial
(3.7). Fonts: SIL OFL. See CREDITS.md.
Mobile-first SCUMM-style point-and-click engine with authoring tools and an AI-friendly workflow
See the codeBuild a complete point-and-click adventure with an AI, and prove it can be finished.
A SCUMM-style engine made for phones, a visual Studio to produce the game, and a pipeline that checks it, proves it and ships it as a web game that works offline. It started as the engine of a 9-room family game, written and shipped in a single day with an AI assistant.
| 🎮 Play | The Pantry Key, the sample game: phone in landscape, or desktop |
| 🛠 Studio | Open the Studio in demo mode: your edits stay in your browser |
| 🚀 Start | Make your own game in a few commands |
| 📚 Docs | The method · the content format · all the docs |

New in v3.7 "Field Proof": the sample game may be sold: its theme, Tchaikovsky's Swan Lake written out and
arranged for the project, replaces an arrangement under a non-commercial licence, so npm run verify:commercial
passes. The reference chapter plays two scores joined by bridges, and the browser checks that a transition can be
cancelled, restored from a save, or stopped without leaving a sound behind (3.6.1 "Audio truth" gave the music its
three intents: play, restore, stop). The nightly corpus runs in four shards and keeps its counts.
v3.6 "Production": the music director is held to budgets of its own (stems, offline, decoded audio, a cap on what it keeps), its stem files are measured before a release, and one score hands over to another on a beat, a bar, a phrase or a marker, through a bridge; a save keeps where the music was. The proof pools items per group of characters who can meet, so open chains with three characters are proved where 3.5 gave up (the measures), and random games of three kinds are checked against the explicit search every night (counted as tried, compared and partial).
v3.5 "Score": music that follows the game. A track is cut into stems that play in sync; the mix changes with the room, the active character or a flag, on the next bar, without a click. The proof runs on several cores with the same result, and pools the items the characters can hand each other, so two-character games with items moving freely are proved (how it is measured). It is an adaptive stem mixer with transitions, not iMUSE: no tempo changes, no branches inside a score. 3.4 "Stagecraft" brought scenes with depth: a Canvas painter, layers, masks, lights, walk zones and stairs, the structured Studio, and a second game, "The Night Market".
| Step | What web-scumm gives you |
|---|---|
| Write | A storyboard first, then rooms, dialogue with choices, hints and rules, all as plain data. |
| Build | Rooms placed by dragging, characters cut from generated sprite sheets, prompts for every image, chip-tune music and sound effects. |
| Check | Broken references, untranslated lines, the licence of every shipped file, what a phone has to download. |
| Prove | A path to the ending, every state where the ending is lost and why, saves that load across versions, real browsers. |
| Ship | A static web game that installs on a phone, plays offline, on touch, mouse or keyboard. |
Measured on the release, proof cache off (BENCH.md):
| What | Result |
|---|---|
| "The Night Market", 8 rooms, 2 playable characters | proved in 288 states, 1.2 s; the abstractions audited against 83 672 explicit states |
| An open chain of 20 rooms, 2 characters, 12 items moving freely | proved in 14 002 states, 19 s (out of reach before 3.5) |
| An open chain of 14 rooms, 3 characters, items moving freely | proved in 93 480 states, 166 s (out of reach before 3.6) |
| 900 random games, abstractions against the explicit search | 549 verdicts compared, no divergence (351 stopped partial) |
| A 40 000-state proof on 4 worker threads | ×2.54 faster, the same result as on 1 |
| The music director, rendered offline for 30 minutes | 0 samples of drift; 100 changes of mix without a click; 0.02 ms jitter live |
| Its staged market: 6 layers, parallax, 3 masks, two floors | 50 frames per second with the CPU slowed 4× (Canvas) |
| A first visit | every byte the browser fetched was predicted by the asset graph |
| Reference game, 40 rooms × 3 characters, structured by eras | proved in 578 states, 4.1 s |
| The sample game, every reachable state | proved in 2.5 s, then 0.17 s from the proof cache |
| The sample game, chapter by chapter | proved in 3.7 s |
| The 7 bundled minigames | each one won with the keyboard alone, in Chromium and WebKit |
| Accessibility | tested at the keyboard, no serious or critical axe-core violation on any screen checked (not a WCAG claim) |
| Shipped assets | every file's hash and licence locked after review; weight budgets per room and chapter |
The proof explores the game as the engine plays it and assumes the minigames are won. The reference game keeps each character in their own era. When items can move freely between three characters, the search still stops before the end, and BENCH.md says so.
![]() Conversations with topics, choices and a transcript | ![]() Minigames, playable by touch or keyboard |
![]() A world map, characters who move between places | ![]() An ending that remembers what the player guessed |
Nine classic verbs and a bag, dialogue, hints from a character, cutscenes and phone calls, rooms wider than the screen, several playable characters with their own bags, scripts and events, seven minigames, an optional sealed ending, autosave and save slots, translations, settings, touch, mouse and keyboard, and the whole game offline after the first visit.
![]() Rooms: the real engine, a placement editor on top, every line editable in place | ![]() Storyboard: the story panel by panel, checked against the game |
![]() Assets: every sheet and cell, where it is used, the prompt to make it | ![]() Check: the validator and the solver, run again after every save |
The puzzle graph shows what each item, flag and room leads to. With Critical path on, what does not lead to the end fades. With Heat, the rules the solver went through most turn red. The Studio also has a Play tab with a rule explainer and session replay, shared notes with the AI, and an Assistant that works with any model.
Needs Node 22+, Python 3 for the art tools (pip install -r requirements.txt) and ffmpeg for sound.
In its own project (3.9, PACKAGE): the engine installs from a release's tarball (npm
publishing to come, then npx create-web-scumm my-game):
T=https://github.com/wanoo/web-scumm/releases/download/v3.9.0/web-scumm-3.9.0.tgz
npx --package=$T web-scumm create my-game "My Game" --engine=$T
cd my-game && npm install
npm run assets && npm run dev # then npm run verify, npm run build, npm run release
In this repository, beside the sample games:
npm install
npm run doctor # checks Node, Python modules, ffmpeg and the test browsers
npm run new-game my-game "My Game" # games/my-game from the template, set as the current game
npm run assets # prepares the placeholder art
npm run studio # the Studio: rooms, story, assets, checks, play
Then, before anyone plays it:
npm run verify:game # validation, a path to the ending, chapters, translations, lint, playtests
npm run prove:game # every reachable state: softlocks and truncation fail
npm run build # tests, bundle and audits, into dist/ for any static host
npm run dev plays your game on this computer, npm run dev:lan on your phone. Write the story in
storyboard.json first, then the rooms with CONTENT_GUIDE open.
WORKFLOW is the whole method, step by step.
Everything is data: rooms, props with states, characters, items, rules, topics, hints, scripts, events. There is no code in the content, so every tool can read it, check it and play it.
export const garden: RoomDef = {
id: 'garden', name: 'The garden', decor: 'garden',
props: { tank: { name: 'water tank', states: { full: 'tank_full', empty: 'tank_empty' } } },
actors: { grandpa: { char: 'grandpa' } },
exits: { back_door: { name: 'back door', to: 'house', entry: 'garden' } },
on: [
{ verb: 'use', a: 'pipe', b: 'tank', if: '!tank_drained',
do: [{ minigame: 'pipes', params: { /* see games/demo */ } }, { lose: 'pipe' }, { set: 'tank_drained' }, { prop: ['tank', 'empty'] }] },
],
talk: { grandpa: [{ topic: 'Where is the key?', if: '!tank_drained', do: [{ say: ['grandpa', 'It fell in the tank. Plop.'] }] }] },
hints: [{ until: 'tank_drained', lines: ['Use the pipe on the water tank.'] }],
};
A rule is a verb, a target, a condition and a list of commands. CLASSICS writes twenty famous mechanics of the genre with it: insult sword fighting, a nurse on patrol, a tree planted in the past.
CLAUDE.md and AGENTS.md hold the rules.npm run prompts writes ready-to-paste image prompts for every character sheet, object, background and piece of
furniture, all in one style. npm run assets cuts the generated sheets into sprites (PROMPTS).
npm run audio arranges a MIDI for Mega Drive chips and renders the sound effects from the same palette
(AUDIO).
| Read | For |
|---|---|
| WORKFLOW | the method, from the first idea to the release |
| CONTENT_GUIDE · CLASSICS · DESIGN | writing content, famous mechanics, making it a good game |
| STUDIO · TOOLS · MCP | the Studio, every command, the AI tools |
| ENGINE · BENCH · FIELD | how the engine works, what the proof can and cannot do, what only people and real devices check |
| PROMPTS · AUDIO · PAGES | images, sound, the review pages |
| PACKAGE · API · SUPPORT | a game in its own project (npx create-web-scumm), the public API, what stays stable |
| ROADMAP · CHANGELOG · UPGRADING | where it comes from, every release, moving to a new version |
Every page also exists in French under docs/fr/. docs/dev/ holds the log of the work with the other assistant.
Current release: v3.9.0 "Independence": the engine as a
package (web-scumm, create-web-scumm), a game made outside the repository verified, built and played in CI, and
the public API that 4.0 will hold stable. The story from v1.3 to v3.9 is in the
ROADMAP, every change in the CHANGELOG.
src/engine/ core (the DSL, the engine), tools (validate, solve, lint, i18n…), dom (the renderer), minigames
games/demo/ the sample game: rooms, layouts, art, audio, locales, storyboard
games/_template/ copied by npm run new-game
tools/ the commands, the Studio, the MCP server, the art pipeline
scripts/ the browser tests, the sealed ending, new-game, the README screenshots
docs/en docs/fr the documentation; docs/dev: the work log
The images of this page come from the production bundle and the Studio, taken by npm run docs:screenshots.
Code: MIT. Sample artwork, sound effects and theme: CC BY 4.0 (attribution "Wano"); the theme is Tchaikovsky's Swan
Lake (public domain), written out and arranged for the project, so the sample game passes npm run verify:commercial
(3.7). Fonts: SIL OFL. See CREDITS.md.