Open source point & click engine
Make a point-and-click adventure for the browser.
Write it as data, shape it in a visual Studio, prove it can be finished, and ship it as a web game that installs on a phone and plays offline.
v4.5.0released on 23 October 2026★ 15 stars on GitHub

A game is data, never code
Rooms, props, rules and lines are plain TypeScript objects. A person writes them, an AI assistant writes them, a solver reads them.
import { defineRoom } from 'quest-n-click/content';
export default defineRoom({
id: 'house',
name: "Grandma's house",
decor: 'decor/house',
music: 'house',
// Props: images on the background, each with states.
props: {
lamp: { name: 'lamp', states: { off: 'house/r1c1', on: 'house/r1c2' } },
stool: { name: 'stool', states: { shelf: 'house/r1c5', pulled: 'house/r1c6' } },
},
// Characters present.
actors: {
grandma: { char: 'grandma', facing: 'left' },
cat: { char: 'cat', pose: 'sleep', visible: '!cat_awake' },
},
// Zones of the background that can be acted on.
hotspots: {
shelf: { name: 'shelf' },
door: { name: 'garden door' },
},
// Look. A list = a different line each time.
look: {
shelf: 'The shelf. Too high without a step up.',
cupboard: ['An old cupboard.', 'Still an old cupboard.',
'Someday I will check what is behind it.'],
},
});// A reaction: a verb, a target, a condition, and what happens.
on: [
{ id: 'pull.stool', verb: 'pull', a: 'stool',
if: { prop: ['stool', 'shelf'] },
do: [
{ prop: ['stool', 'pulled'] },
'There. A step up.',
] },
{ id: 'tie.rope', verb: 'use', a: 'rope', b: ['hook', 'bucket'],
do: [
{ lose: 'rope' }, { set: 'tied' },
'Tied. One end on the hook, the other on the bucket.',
{ say: ['grandma', 'Careful with that bucket, dear.'] },
] },
],
// Hints, from the walkie-talkie: the first whose condition is still false.
hints: [
{ until: { has: 'rope' }, lines: ['Khhh… check the side of the armchair.'] },
{ until: 'tied', lines: ['Khhh… a rope… it ties to things.'] },
],// Talk topics. "Bye" is added to every menu.
talk: {
grandma: [
{ id: 'ask.basket', topic: "Grandma, what's in the basket?",
do: [{ say: ['grandma', 'A surprise for everyone.'] }] },
{ id: 'ask.market', topic: 'Can I go to the market alone?',
do: [
{ say: ['grandma', 'Alone?! With your scarf, your hat, your water bottle…'] },
{ say: ['grandma', '… Fine. Back by ten.'] },
] },
],
},
// On every entry into the room.
onEnter: [
{ once: ['The living room. Home base.'], id: 'arrival.first' },
],What you get
Grouped by who you are. Every item links to the page that says more.
For players
- A classic point-and-click interface: verbs, a bag, a sentence line; a double tap acts with the verb you mean; a key per verb when the game gives one (Controls).
- Phone and desktop: landscape on a phone, the classic layout with a mouse; the whole game at the keyboard (Accessibility).
- Installs and plays offline: a PWA that caches the whole game after the first visit and says when it is complete (Install the game as an app).
- Autosave and save slots, with export and import as a file (Saves).
- Settings: text speed and size, reduced motion, a readable font, sound captions, volumes, the language (Settings, Languages).
- Speedruns: categories, an in-game clock, splits, a ghost, a sealed proof, OBS and LiveSplit (Speedrun for players).
In a game
- Several playable characters, and since 4.3.0 the hero chosen at New Game among any number, with portraits, a name per hero and lines that follow the hero (Heroes).
- A world map, its places unlocked by the story; since 4.4.0 one pin can hold several places (World map).
- Minigames playable by touch or keyboard (pick, hide, pipes, runner, stroke, scratch, cables, the code wheel), and your own (Built-in minigames).
- Cutscenes and phone calls, scripts and events that make the world act without a tap, characters that walk and patrol (Scripts and events, Moving characters).
- Staging: wide rooms and a camera, animations with frame events, layers, masks, lights, particles, walk zones and links (Staging, The stage).
- Music in stems that follows the game's state, sound effects from one palette, recorded voices per language and per hero (Music in stems, Voices).
- Remix: worlds generated from a seed, each one validated and solved before it ships; a daily challenge and mystery worlds with a Bridge (Remix).
- Speedrun: runs recorded, sealed and verified by a replay; leaderboards on the Bridge (Speedrun for authors).
- 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 (The Reality Bridge).
For authors
- Content as data, in TypeScript objects with no code; custom commands as trusted code named in the game (Content principles, Custom code).
- Checked before anyone plays: the validator finds broken references, unreachable rooms and untranslated lines; the
solver runs the real engine to find a winning path (
npm run verify) or to prove every reachable state can finish (solve --prove) (Checking your game, What the solver proves). - Replayed: a session reproduces a tester's game exactly (Playtests).
- Art, sound and languages: a prompt for every sprite sheet, sheets cut into sprites, chip-tune music arranged from a MIDI, every line translatable (Images, Translations).
- Shipped: a static site with a download budget and every file accounted for with its licence (Build and release, Asset provenance).
- The local Studio: the real engine with an editor on top, the storyboard, the assets, the checks after every save, a play tab that explains a rule and replays a session, the hero × language matrix, an assistant with your own key (The local Studio).
- Working with an AI: every operation is a command and an MCP tool (Working with an AI).
For teams and operators
- The hosted team Studio (experimental): one game, several people behind OpenID Connect, spans and leases, previews per revision, comments, a semantic diff, Git, a remote MCP for agents, backups and restores; documented for Clever Cloud (What runs where, Clever Cloud overview).
- The Reality Bridge: on SQLite (stable) or Postgres (experimental), several tenants, backups, leaderboards; four connectors (experimental) (Install and run the Bridge).
What the player sees, what the author sees
Screenshots of the real production build and the real Studio, from the engine's gallery page.
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
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
Prove it can be finished
Before anyone plays, the validator finds what is broken and the solver runs the real engine through every reachable state.
1
Validate
Broken references, unreachable rooms, untranslated lines, minigame parameters.
2
Solve
A winning path from New Game, then an exhaustive proof: no state where the game is lost.
3
Ship
A PWA with a download budget, every file accounted for with its licence, checked in real browsers.
In numbers
- 3315
- unit test declarations
- 288
- states proved in the reference game
- 136
- KB of JavaScript on first visit, gzipped
Measured on the release commit by the automated gates, read from the README of the tag.

Start in three commands
Node 22.12 or newer. Python 3 and ffmpeg serve the art and sound tools; `npm run doctor` says which is missing.
Then the tutorial takes you through a first room in fifteen minutes.
T=https://github.com/wanoo/quest-n-click/releases/download/v4.5.0/quest-n-click-4.5.0.tgz
npx --package=$T quest-n-click create my-game "My Game" --engine=$T
cd my-game && npm install
npm run assets && npm run dev