GitHub - wanoo/web-scumm: Mobile-first SCUMM-style point-and-click engine with authoring tools and an AI-friendly workflow

GitHub

7 min read Original article ↗

The web-scumm logo: a pixel-art editor window with a harbour scene, a dialogue graph and a pointer, among picture cards, a treasure map, an AI panel, a notebook of puzzle diagrams and a coffee mug, under the words Web-SCUMM, Open source point & click engine

Make a point-and-click adventure for the browser: write it as data, shape it in a visual Studio, check that it can be finished, and ship it as a web game that installs on a phone and plays offline.

Version française

🎮 Play The Pantry Key, the sample game, on a phone in landscape or on a desktop
🛠 Studio Open the Studio in demo mode: edit the sample game, your edits stay in your browser
⏱ Start Your own game in its own folder, then a first room in fifteen minutes

The Pantry Key: Grandma's living room, nine verbs, the bag

Start

Node 22.12 or newer and Python 3 with Pillow (npm run assets prepares the art with them), on Windows, macOS or Linux. The engine installs from a release's archive (npm publishing comes in a later 4.2.x):

T=https://github.com/wanoo/web-scumm/releases/download/v4.2.0/web-scumm-4.2.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        # play it; then npm run verify, npm run build

npm run build writes dist/, a static site any host serves. ffmpeg serves the sound pipeline and is optional; npx web-scumm doctor says what is missing. PACKAGE is the whole guide; TUTORIAL walks the first room.

Build a game

The content is data. Rooms, props with states, characters, items, rules, conversations, hints, scripts and events are plain TypeScript objects, with no code in them, so every tool can read, check and play them:

export const garden: RoomDef = {
  id: 'garden', name: 'The garden', decor: 'garden',
  props: { tank: { name: 'water tank', states: { full: 'tank_full', empty: 'tank_empty' } } },
  exits: { back_door: { name: 'back door', to: 'house', entry: 'garden' } },
  on: [
    { verb: 'use', a: 'pipe', b: 'tank', if: '!tank_drained',
      do: [{ minigame: 'pipes' }, { lose: 'pipe' }, { set: 'tank_drained' }, { prop: ['tank', 'empty'] }] },
  ],
  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. What a game needs beyond them, a custom command, is TypeScript of its own: trusted code, named in the game and hashed with it (CONTENT_GUIDE, ENGINE). Famous mechanics of the genre are written this way in CLASSICS.

The Studio is the real engine with an editor on top: rooms with their placements, the storyboard panel by panel, every sprite sheet and where it is used, the checks after every save, a play tab that explains a rule and replays a session, and notes shared with an AI assistant (STUDIO).

Art, sound and languages. A prompt for every sprite sheet, object and backdrop in one style, sheets cut into sprites (PROMPTS); chip-tune music arranged from a MIDI and sound effects from one palette (AUDIO); every line translatable, a missing translation found before release.

Prove and ship it

  • Validated: broken references, unreachable rooms and untranslated lines are found before anyone plays.
  • Solved: the solver runs the real engine (no second model of the content). npm run verify asks for a witness, a path to an ending; npx web-scumm solve --prove explores every reachable state and fails on a softlock or a truncated search. These are two different promises, and the release asks for the second (BENCH says what the proof can and cannot do).
  • Replayed: a session is the unit of reproduction; saves load across versions, one frozen save per release from 3.0.0 on.
  • Shipped: a PWA that installs and plays offline after the first visit, with what a phone has to download held by a budget and every file accounted for with its licence.
  • Accessible as far as a machine can tell: axe-core on every screen, keyboard and touch play in CI. That is not a WCAG conformance claim: screen-reader and real-device passes are a person's to make (FIELD).

Further

  • Several playable characters, a world map, minigames playable by touch or keyboard, cutscenes and phone calls, autosave and save slots.
  • Remix: worlds generated from a seed, each one validated and solved before it ships (REMIX).
  • Speedrun: runs recorded, sealed and verified by a replay; leaderboards on the Bridge.
  • Reality: a game reacts to a fact from the world (an email answered, a terminal command, a badge) through a signed signal from a Bridge, without its content touching the network (REALITY, REALITY-OPS).

What is stable

Each surface is promised only as far as its proofs go (SUPPORT, GO / NO-GO 4.2):

Stable Limited Experimental
the content format and its tools; the desktop Chromium PWA; the Reality Bridge on SQLite the DOM player on phones and screen readers (untried by a person); the Safari PWA; Firefox (the PWA only); speedrun and Remix; voices; the four package archives (until a person installs them) the Canvas painter; the Bridge on Postgres (distributed); the four connectors

What only people and real devices can check is listed, not claimed: FIELD, and each release's notes say which passes were made.

How it is made

src/engine/      core (the DSL, the engine), tools (validate, solve, lint, i18n…), dom (the player), minigames, reality
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 and audio pipelines, the Vite plugins
bridge/          the Reality Bridge (the package web-scumm-bridge)
connectors/      the connectors of the world outside (the package web-scumm-connectors)
docs/en docs/fr  the documentation; docs/dev: the work log, the decisions, each release's passes

The engine, the solver and the replay share one code path; ARCHITECTURE and a half-hour CODE_TOUR explain how it fits together.

Made with an AI assistant, reviewed by people. The content is declarative, so an assistant reads and writes it like any other file (AGENTS.md holds the rules); every operation is a command and an MCP tool (MCP); after each change it can validate, solve, replay and take a screenshot, so it sees its own mistakes before a person does. Every result stays reviewable, in the Studio and in Git. CONTRIBUTING says how to change it.

In numbers

Measured on this commit of main by the automated gates (npm run quality:baseline writes these figures):

2332 unit test declarations, on Node 22 and 24, with coverage floors and gated

mutation testing; the reference game proved in 288 states; the player's first visit 133 KB of JavaScript, gzipped. Each release is built from the commit its candidate tested. The candidate makes the four package archives, the Bridge's image, the SBOMs, the runs and the baseline, and the release publishes those very files; the release makes only the built game, its assets manifest, the proved Remix catalogues, the reference speedrun and the sums, from the same commit. Every file is published with its SHA-256 sum and a provenance attestation (the list).

Documentation

Every page exists in English (docs/en/) and French (docs/fr/), and a test keeps the two in step: the TUTORIAL, the WORKFLOW from the first idea to the release, every command in TOOLS, what changed in the CHANGELOG, moving to a new version in UPGRADING, and where it comes from in the ROADMAP.

Current release: v4.2.0 "Stable World". It restores strict SemVer after the 4.1.x incubation line: a minor adds, a major removes. Its public API follows strict SemVer (SUPPORT). It ships before the people's passes: of the surfaces above, only the Stable column is promised; the passes are made on it, and a later 4.2.x promotes what they prove (GO / NO-GO 4.2, D38).

Licences

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. Fonts: SIL OFL. See CREDITS.md.

web-scumm is an independent project. "SCUMM-style" names a kind of game; the project is not affiliated with, endorsed by or derived from LucasArts, Lucasfilm, Disney or the ScummVM project, and ships none of their code, data or art.