quest'n'click 4.5.0 · r1

Built for quest'n'click 4.5.0, revision r1. Whether it is published, and which one is current, is recorded at publication.json.

Layout of a created project and of the engine repository

Français · Type: reference · Audience: author, contributor · Context: engine repository, created project · Status: ready · Applies from: 4.3.0

A game lives in one of two places, and the commands differ between them. This page says what each holds, where the game's files are, and which npm run scripts exist where. When a page says "in the created project" or "in the engine repository", this is the difference it means.

A created projectThe engine repository
Made bynpx create-quest-n-click my-game "My Game" or npx quest-n-click create …git clone of wanoo/quest-n-click
The game's foldergame/games/<id>/ (several games side by side)
The enginenode_modules/quest-n-click/ (installed, never written)src/engine/ (you may change it)
Which gamealways game/GAME, else .cache/game, else config.game in package.json, else demo (choosing the game)
npm run scriptseight (below)about 150, the whole toolbox

A created project

quest-n-click create <folder> ["Title"] [--engine=<npm spec>] (cli/create.mjs) refuses a folder that exists and is not empty, then writes:

PathWhat
game/the template game (games/_template), with __ID__ and __TITLE__ replaced; the template's own tests/ is left out
game/provenance.jsonone entry saying every image is a placeholder drawn from shapes: a release refuses it until each file is replaced and reviewed (npx quest-n-click provenance --lock)
public/the page's icons, its preview image (og.png) and the full font the engine falls back to; public/assets/ is written by npm run assets, not committed
package.json"config": { "game": "<id>" }, the dependency on the engine (^<version>, or --engine), and the scripts below
tsconfig.json@engine/* points into node_modules/quest-n-click/src/engine, quest-n-click/* into its public API, @game into game/index.ts
.gitignorenode_modules, dist, .cache, public/assets
README.mdthe five commands below, as a reminder

Later, npm run build writes dist/ (with licenses/), and the tools write .cache/.

In the created project, npm run dev and npm run studio call quest-n-click dev or quest-n-click studio, which run the package's own Vite configuration with the project as working folder and game/ as the game: the game on http://127.0.0.1:5173/, the Studio at /__studio/, opened in the browser. Neither is the hosted Studio Server (team Studio).

The project's id is the folder's name in lowercase, letters, digits and dashes; the title defaults to that id in title case.

The game's files

The same files in both places: game/ in a created project, games/<id>/ in the engine repository.

index.ts          entry point: export { game, layouts, manifest, minigames?, extraImages?, commands?, locales? }
game.ts           the game: verbs, characters, items, map, global rules, game start, skin (the look), ending, interface texts
cast.ts           the characters, with helpers for the standard sprite sheets (human, cat, mouths)
items.ts          the inventory items
rules.ts          fallback answers, reactions by kind ("never pull a cat"), rules valid everywhere
rooms/<room>.ts   one file per room (logic)
layout/<room>.json one file per room (geometry, written by the editor; never by hand)
storyboard.json   the story, board by board and panel by panel: the source of truth for the text
assets.gen.json   manifest of images and sounds (written by npm run assets)
sources.json      where the asset sources come from (optional)
provenance.json   where each asset comes from and under which licence
site.json         page title, description, theme colour, art style
locales/<lang>.json translations (written by npm run i18n -- extract)
art/, audio/      the sources of the images and sounds
tests/            the game's own tests (engine repository only)

index.ts is the template's and is kept as is: it gathers the layouts and the translations with Vite and exports the game's minigames, extraImages (images to prepare even when no content references them) and commands (custom code).

site.json

{ "lang": "en", "title": "…", "shortName": "…", "description": "…", "themeColor": "#0a0a12", "artStyle": "cel" }

Which scripts exist where

A created project's package.json has eight scripts. Each calls the engine's command, quest-n-click, with the project's folder as the working folder (cli/quest-n-click.mjs):

In the created projectRunsIn the engine repository
npm run devthe game in the browser, reloading as you editnpm run dev (the current game)
npm run studiothe Studionpm run studio
npm run assetsart/ and audio/ into public/assets (Python 3 with Pillow)npm run assets
npm run verifyvalidate, solve, i18n status, lint, playtestsnpm run verify:game (adds the chapters proof and the Remix worlds)
npm run buildassets, verify, the production build in dist/, every file accounted fornpm run build (also type-checks and runs the engine's tests first)
npm run releasebuild, then the release gates; --commercial: no exception, no placeholdernpm run verify:release, npm run verify:commercial
npm run previewserves dist/ on 127.0.0.1npm run preview
npm run quest-n-click -- <command>any other command of the engine(the scripts below)

Every other tool is a subcommand of quest-n-click, run with npx in the created project:

# in the created project
npx quest-n-click validate
npx quest-n-click solve --prove
npx quest-n-click help        # the full list

In the engine repository the same tools are scripts of their own: npm run validate, npm run solve, npm run lint, npm run i18n, npm run ids, npm run prompts, npm run voices, npm run weight, npm run provenance, npm run playtests, npm run migrate, npm run mcp, npm run doctor. The full table is on npm scripts.

Only in the engine repository: npm run new-game, npm run game, npm run dev:lan, npm run studio:lan, npm test and npm run check (the engine's tests), npm run e2e*, npm run replay, npm run remix, npm run page:*, npm run seal, and the release and qualification scripts.

Limit · no-lan-in-project A created project has no dev:lan nor studio:lan, no start and no GitHub Pages workflow. Testing on a phone over the network from a created project is described on testing on a phone over the LAN.

Limit · doctor-in-project npx quest-n-click doctor in a created project imports Playwright, which the package does not depend on: it may fail there until Playwright is installed (install troubleshooting).

The engine repository

Clone it to work on the engine, or to keep several games beside it (games/demo, games/heroes, games/reference, games/signals, games/_template, example games). Node 22.12 or later is required (engines in package.json); npm run doctor says what is missing (requirements).

npm run dev and npm run studio work in both places. In the engine repository they first point .cache/game at the current game (choosing the game), then start Vite on http://127.0.0.1:5173/ (loopback only; the Studio at /__studio/). In a created project they open the project's one game (above). Neither is the hosted Studio Server (team Studio).

Layout of the engine's code

src/engine/
  core/        pure logic (no DOM): state, conditions, reactions, scripts, events, conversations, hints, saves
    types.ts     the content format (re-exports types/: content, game, stage, audio, state, session, reality, speedrun)
    engine.ts    the Engine class: player actions, resolution, the command interpreter
    cmds.ts      the catalogue of commands (CMD_KEYS): which change the state, which hold nested lists
    cond.ts      condition evaluation
    define.ts    defineGame / defineRoom, normalizeExits, compileGame, FLOOR and NEAR
    ports.ts     the Presenter interface (what the core asks of the display) + FakePresenter for node
  scene/       the scene frame (pure): SceneFrame, the hit test, the Renderer and Intent contracts (4.1.11)
  dom/         the browser display: app.ts (layout, verbs, inventory, menus), presenter.ts, room.ts (the scene),
               walk.ts (walk areas: earcut triangulation + navmesh paths), audio.ts (Howler), render-dom.ts and
               render-canvas.ts (the two painters), fonts.ts, assets.ts
  minigames/   pipes, stroke, pick, hide, runner, scratch, cables, code-wheel; all their images come from params
  ending/      the sealed ending: seal.ts (AES-GCM), card.ts, index.ts
  reality/     the client of a Reality Bridge
  tools/       validator, solver, lint and the other node tools
  dev/         debug overlay and placement editor (dev server only)
  api/         the public entry points (content, player, minigames, reality, testing)

The rule: src/engine/ never imports from games/ and never names a single image, sound or interface text. Texts come from GameDef.ui; icons, sounds, fonts and default heights from GameDef.skin (skin and fonts); minigame images from their params; the sealed ending from GameDef.ending. src/main.ts imports @game (an alias for the game's index.ts) and knows nothing else about the game. Verb ids are free (the game's verbs); four have a meaning for the engine: look, talk, give and use (reactions). The tour of the code for contributors is on architecture.


Edit the source of this page · Report an error