Skip to content

TickLoop

runtoolkit edited this page Apr 13, 2026 · 1 revision

TickLoop

Drives the engine's tick pipeline. Each registered channel fires at its own rate, offset, and optional condition.

Constructor

import { TickLoop } from './src/tick.js';

const loop = new TickLoop(50); // 50ms per tick = 20 TPS

Throws RangeError if msPerTick is not a positive finite number.


Lifecycle

loop.start();   // → true if started, false if already running
loop.stop();    // → true if stopped, false if not running
loop.pause();   // suspends tick dispatch (loop keeps running)
loop.resume();  // resumes dispatch
loop.step();    // manually fire one tick (useful for testing)

loop.paused;    // boolean
loop.tickCount; // number of ticks fired so far

Channels

loop.register(name, fn, { rate, offset, condition });
Option Type Default Description
rate number 1 Fire every N ticks
offset number 0 Tick phase offset
condition function | null null Skip tick if returns false

A channel fires when (tickCount + offset) % rate === 0 and condition() is truthy (if set).

// Every tick
loop.register('always', (tick) => { ... });

// Every 5 ticks
loop.register('slow', (tick) => { ... }, { rate: 5 });

// Every 5 ticks, offset by 2 (fires on ticks 3, 8, 13, ...)
loop.register('offset', (tick) => { ... }, { rate: 5, offset: 2 });

// Conditional
loop.register('guarded', (tick) => { ... }, { condition: () => someFlag });

Managing channels

loop.unregister(name);
loop.enable(name);
loop.disable(name);
loop.setRate(name, newRate);
loop.setOffset(name, newOffset);
loop.setCondition(name, fn);   // null to remove condition

loop.list();
// → [{ name, rate, offset, enabled }, ...]

Accessing a non-existent channel name throws Error.


Error handling

Errors thrown inside a channel's fn are caught and logged to console.error. They do not stop the tick loop or affect other channels.

Clone this wiki locally