Skip to content
quest'n'click

PlayHow-toFor playersApplies from 4.1.14

Speedrun for players: LiveSplit and OBS

Cette page en françaisThis page on the GitHub wiki

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.

What you get

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).

Context and versions

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.

Prerequisites

  • 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.

Where to run the commands

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/).

Steps

  1. 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.
  1. 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).
  1. At the finish: the run is sealed, and the pause menu shows Export run: a .wsrun file, the proof to send to a leaderboard or a friend. The dev panel (?dev) has the same export.
  1. 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.

Streaming: OBS and LiveSplit

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.

  1. OBS: start the overlay, then add an OBS Browser Source at http://127.0.0.1:7777/?mode=full (or compact: 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.io

    Then open the game at https://…/?speedrunTool=7777. Use your game's own address in --origin.

  1. 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.

  1. LiveSplit splits from a run: write a LiveSplit .lss file 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.

Expected result, and how to check it

  • 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.

Common errors

SymptomCauseFix
No Speedrun row in the pause menuThe game declares no categoryNothing 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 portReload the game with the overlay's port in the address
The overlay gets nothing from a deployed gameThe tool accepts the dev server's origins only by defaultRestart it with --origin=<the game's address>
LiveSplit does not moveIts WebSocket server is not startedLiveSplit › Control › Start WebSocket Server
The run does not startThe category could not start (the message says why)Read the message; report it to the game's author

Files or data changed

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.

Recovery or going back

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).

Limits

References