Repository navigation
EN Play Speedrun
Français · Type: how-to · Audience: player · Context: player's browser · Status: ready · Applies from: 4.1.14
Speedrun and Remix · contract: stable · verified by CI (support matrix of 4.4.0, 2026-10-23): Replays in four runtimes (cross-runtime) · automated checks: jobs
cross-runtime,e2e; CI plane2e; 2 test files · people's passes:runs-real-playersnot run (#85),run-resume-power-cyclenot run (#84),mystery-deployednot run (#82),livesplit-obsnot run (#81),code-wheel-humannot run (#78) · known limits:integrity-not-authenticity,livesplit-obs-not-tried
How to run a quest'n'click game against the clock, export the proof of your run, and show your timer in OBS or drive LiveSplit. For authors who want to declare categories: Speedrun for authors.
A timed attempt in a category the game declares (Any%, for instance), split on what happens in the game, never on
pixels; at the finish, a sealed .wsrun file that anyone can replay and verify; your records on your device; and, if
you stream, a timer in OBS or LiveSplit driven by the game.
A replay proves that a run is possible and that its in-game time is exact. It does not promise to detect every cheat: only a server's or a person's observation raises the trust further (see the limits).
The player of a game that declares speedrun categories (speedrun in its content). The engine has had speedruns since
4.1.14 "Time Attack"; this page holds from that version. The sample game at
wanoo.github.io/quest-n-click declares no category, so its pause menu has no
Speedrun row; the reference game in the engine repository (games/reference) declares several.
- A game whose pause menu shows Speedrun.
- For OBS or LiveSplit only: Node 22.12 or newer on the machine you stream from, and a copy of the engine (a created project, or the engine repository); OBS or LiveSplit.
The run itself needs no command: it happens in the game. The streaming tools are small Node processes on your own
machine, never on a server and never in the game: in the engine repository through npm run, or in a created
project from the engine package it installed (node_modules/quest-n-click/tools/speedrun/).
- Start: pause menu › Speedrun › a category. The game restarts with the category's seed; a small timer shows the category, the time it is ranked on (real time, in-game time, or in-game time without pauses) and the last split.
- During the run: the pause menu shows Abandon run. Opening the menu is recorded as a pause, and the tab going to the background is recorded too; neither stops the in-game time (the game does not run while it waits).
-
At the finish: the run is sealed, and the pause menu shows Export run: a
.wsrunfile, the proof to send to a leaderboard or a friend. The dev panel (?dev) has the same export.
-
Your records stay on the device, offline (IndexedDB
web-scumm-runs): the personal best and its splits, the best segment of every split, the sum of best, attempts, finishes, abandons, notes. A run resumes after a crash or a closed tab from its last stored chunk (every 500 inputs); what was played after it is played again.
The ghost is your personal best played beside you, on semantic targets: the room it is in, the action it does and what it holds, ahead or behind at each split, never a pixel trail. It is off the first time you play a category on this device, because it would show the answers of the puzzles.
The tools run on the player's machine (decision D23), never on the Bridge, never in the game. Open the game with
?speedrunTool=<port> in its address: the page then posts its run's events (the category, the split ids and names,
the times; nothing else: no save, no player id, no token) to 127.0.0.1:<port>. A page carries one port, so it feeds
one tool at a time. The tools accept events from the game's origin only: the dev server and the preview by default
(localhost and 127.0.0.1, ports 5173 and 4173), --origin=<url> for a deployed game. Another page open in the
browser cannot post fake splits.
-
OBS: start the overlay, then add an OBS Browser Source at
http://127.0.0.1:7777/?mode=full(orcompact: the timer and the last split;transparent: the same on no background). It updates by Server-Sent Events.# in the engine repository, on your machine npm run speedrun:overlay -- --port=7777 --origin=https://wanoo.github.io# in a created project, on your machine node node_modules/quest-n-click/tools/speedrun/overlay.mjs --port=7777 --origin=https://wanoo.github.ioThen open the game at
https://…/?speedrunTool=7777. Use your game's own address in--origin.
-
LiveSplit: in LiveSplit, Control › Start WebSocket Server (it listens on
ws://127.0.0.1:16834/livesplit), then start the bridge and open the game with?speedrunTool=7778. The game drives LiveSplit: start, in-game time, split, skip, pause, reset.# in the engine repository, on your machine npm run speedrun:livesplit -- serve --port=7778 --origin=https://wanoo.github.io--livesplit=ws://…points to another LiveSplit address.
-
LiveSplit splits from a run: write a LiveSplit
.lssfile with a run's splits as the personal best.# in the engine repository, on your machine npm run speedrun:livesplit -- export run.wsrun --names=Pantry,Garden,Market --out=run.lss
Without
--names, the segments are named by the split ids; without--out, the file is written beside the run.
- In the game: the timer, then Export run at the finish.
- In OBS: the Browser Source shows the category's name instead of "waiting for a run…", and the splits as you reach them.
- In LiveSplit: the timer starts when the run starts and splits with the game.
| Symptom | Cause | Fix |
|---|---|---|
| No Speedrun row in the pause menu | The game declares no category | Nothing to do: that game has no speedrun |
| The overlay stays on "waiting for a run…" | The page was opened without ?speedrunTool=<port>, or with another port |
Reload the game with the overlay's port in the address |
| The overlay gets nothing from a deployed game | The tool accepts the dev server's origins only by default | Restart it with --origin=<the game's address>
|
| LiveSplit does not move | Its WebSocket server is not started | LiveSplit › Control › Start WebSocket Server |
| The run does not start | The category could not start (the message says why) | Read the message; report it to the game's author |
In the browser: the run's chunks and your records in IndexedDB (web-scumm-runs). On disk: the .wsrun you export,
the .lss that export writes. The tools keep nothing.
Abandon run ends an attempt (counted as an abandon). A run resumed after a crash continues from its last chunk; a run cannot be resumed in another world or with another proof. A run submitted to a leaderboard on a Bridge can be deleted with the token the Bridge gave at submission (Privacy).
Limit ·
integrity-not-authenticityThe chain proves a file was not altered after it was sealed, not that the player was honest: pauses, menus, saves, the real time and the inputs used are the player's word. A run whose inputs a script chose replays as valid; only a witness or a moderator rules it out.
Limit ·
livesplit-obs-not-triedOBS and LiveSplit are tested by machines only. A real session by a person is the passlivesplit-obs, open (#81) as of 4.4.0.
- Speedrun for authors: categories, timing, verification, leaderboards, trust levels.
- Accessibility: options that never count as cheats.
- Design: ADR 0016 (the clock, the seeded generator, the chained proof), ADR 0017 (verdicts and trust).
- The code:
tools/speedrun/overlay.mjs,tools/speedrun/livesplit.mjs,tools/speedrun/local.mjs.
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