Timer
The GameTimer provides pause-aware timing primitives for game logic. It offers one-shot delays, repeating intervals, and pollable cooldowns -- all operating in game-time milliseconds derived from the engine's delta time.
When the game is paused, all timers freeze automatically.
Accessing the Timer
const engine = await createGameEngine({ canvas });
const timer = engine.timer;API Reference
| Method | Signature | Returns | Description |
|---|---|---|---|
delay | (ms : number, callback : () => void) | () => void | One-shot timer; returns a cancel function |
interval | (ms : number, callback : () => void) | () => void | Repeating timer; returns a cancel function |
cooldown | (ms : number) | CooldownHandle | Pollable cooldown handle |
cancelAll | () | void | Cancel all active delays, intervals, and cooldowns |
delay
Fires a callback once after ms milliseconds of game time. Returns a cancel function.
showHitIndicator();
const cancel = engine.timer.delay(200, () =>
{
hideHitIndicator();
});
// Changed your mind? Cancel it.
cancel();The ms parameter must be >= 0. Passing a negative value throws a RangeError.
interval
Fires a callback repeatedly every ms milliseconds of game time. Returns a cancel function.
// Regenerate 1 HP every 2 seconds
const cancel = engine.timer.interval(2000, () =>
{
player.state.hp = Math.min(player.state.hp + 1, player.state.maxHp);
});
// Stop regeneration
cancel();The ms parameter must be > 0 (strictly positive). Passing zero or a negative value throws a RangeError.
WARNING
An interval of 0 is not allowed because it would fire infinitely within a single frame. Use delay(0, ...) for a next-frame callback instead.
cooldown
Creates a pollable cooldown handle. Starts in the ready state. After calling reset(), the cooldown becomes not-ready until ms milliseconds of game time have elapsed.
const fireCooldown = engine.timer.cooldown(500);
function tryShoot() : void
{
if(fireCooldown.ready)
{
shootProjectile();
fireCooldown.reset(); // Starts the 500ms cooldown
}
}CooldownHandle
interface CooldownHandle
{
readonly ready : boolean;
reset() : void;
}| Property / Method | Type | Description |
|---|---|---|
ready | boolean | true when the cooldown has elapsed (or has never been reset) |
reset() | () => void | Start (or restart) the cooldown timer |
Cooldowns are passive -- they do not fire callbacks. Check ready whenever you need to gate an action. This makes them ideal for ability cooldowns, rate-limiting player actions, or any "can I do this yet?" check.
cancelAll
Clears all active delays, intervals, and cooldowns:
engine.timer.cancelAll();This is called automatically during level transitions, so you do not need to manually clean up timers when switching levels.
Any CooldownHandle references you are still holding will report ready: true after cancelAll() is called.
Game Time vs. Wall Time
All durations are measured in game-time milliseconds. The timer advances by the engine's delta time each frame via an internal tick(dtMs) call. Key consequences:
| Behavior | Detail |
|---|---|
| Pausing freezes all timers | When the game is paused, tick() is not called -- delays, intervals, and cooldowns all freeze |
| Frame rate affects granularity | A 500ms delay fires on the first frame where accumulated time >= 500ms. At 60fps (~16.7ms/frame), that is within one frame of accuracy. |
| No built-in time scale | There is no time multiplier. Slow-motion or fast-forward would need to be implemented at the engine loop level. |
Usage Patterns
Timed Power-Up
function activateShield(entity : GameEntity) : void
{
entity.state.shielded = true;
engine.timer.delay(5000, () =>
{
entity.state.shielded = false;
});
}Spawn Wave Timer
let wave = 0;
const cancelWaves = engine.timer.interval(10000, () =>
{
wave++;
spawnEnemyWave(wave);
if(wave >= maxWaves)
{
cancelWaves();
}
});Rate-Limited Action
const dashCooldown = engine.timer.cooldown(3000);
engine.subscribeAction('dash', () =>
{
if(dashCooldown.ready)
{
performDash();
dashCooldown.reset();
}
});