LiveSplit One’s auto splitting runtime loads a compiledDocumentation Index
Fetch the complete documentation index at: https://mintlify.com/CryZe/asr-assemblyscript/llms.txt
Use this file to discover all available pages before exploring further.
.wasm module and drives it by calling a single exported function — update() — at a configurable rate. Every piece of logic your auto splitter performs happens inside that function or in code called from it. Understanding this loop-based model is the first step to writing a reliable auto splitter: you are not writing a traditional program with a main that runs to completion, but rather a callback that fires dozens of times per second and must quickly read memory, check conditions, and return.
How the Runtime Loads Your Module
Compile and load the WASM module
The runner points LiveSplit One at your compiled
.wasm file. The runtime
instantiates the WebAssembly module and wires up all host imports — the
functions you call to read memory, control the timer, and interact with the
runtime itself.Call update() on each tick
Once the module is instantiated, the runtime begins calling your exported
update() function repeatedly at the configured tick rate. Each call is one
“tick” of your auto splitter.Receive host function calls back
Inside
update(), your code calls back into the host via the imported
functions from asr-assemblyscript — for example, reading process memory or
splitting the timer. The host executes those calls synchronously and returns
control to your function before the next tick.Required Export: update()
The runtime expects exactly one exported function from your module:
start, init, or constructor called by the runtime — any one-time setup must be handled through module-level initializers or a flag you check on the first tick.
Required Import: asr-assemblyscript/runtime
Importing
asr-assemblyscript/runtime at the top of your entry file is
required. It installs a custom abort handler that routes AssemblyScript
runtime errors to a unreachable WebAssembly trap instead of trying to call
browser APIs that don’t exist in the auto splitting runtime. Without it, your
module will fail to compile or behave incorrectly at runtime.--use flag. In your package.json build scripts this looks like:
Minimal Auto Splitter Structure
The smallest possible auto splitter imports the runtime module, imports any other modules you need, and exportsupdate():
Configuring the Tick Rate
By default the runtime chooses a tick rate for you. If your auto splitter needs a specific polling frequency — for example, a game that updates at exactly 60 Hz — you can callsetTickRate from asr-assemblyscript/runtime:
setTickRate(ticks_per_second: f64): void accepts a f64 specifying how many times per second update() should be called. You typically call this once at the top of update() (calling it repeatedly is safe — the value is applied immediately).
Managing Process State Across Ticks
Becauseupdate() is called repeatedly, any state that must persist between ticks — such as the ProcessId returned when you attach to a game — must be stored in module-level variables. The pattern below is the recommended skeleton for any auto splitter that reads game memory:
processId === 0—Process.attachreturns0when the game is not running. Storing0as the sentinel value means you can always check whether you currently hold a valid handle.!Process.isOpen(processId)— even after a successful attach, the game can close at any time. CallingisOpenevery tick detects this and lets you re-attach on the next tick where the game is found again.returnafter a failed attach — if the game isn’t running yet, bail out early and try again next tick rather than executing the rest of your logic with a bad handle.
Timer State
Before callingTimer.start() or Timer.split(), check that the timer is in the expected state using Timer.getState(). The return type is TimerState (a u32 alias) with the following values:
| Value | Constant meaning | Description |
|---|---|---|
0 | Not Running | Timer has not been started |
1 | Running | Timer is actively counting |
2 | Paused | Timer is paused |
3 | Ended | Run has been completed |
Additional Timer Functions
Beyondstart(), split(), and reset(), the Timer module exposes game-time controls for auto splitters that manage their own timing:
| Function | Signature | Description |
|---|---|---|
setGameTime | (secs: i64, nanos: i32): void | Set the current game time |
pauseGameTime | (): void | Pause the automatic flow of game time |
resumeGameTime | (): void | Resume the automatic flow of game time |
setVariable | (key: string, value: string): void | Publish a custom key/value pair for visualization |