Timer
GameTimer is the engine's source of game time: delay, interval, and cooldown, all in milliseconds of game time. It is not part of the entity system: a behavior does not reach it, and its callbacks land between fixed steps rather than inside one.
const timer = engine.timer;The timer advances from a frame callback registered with the default suspendedByPause : true, so it stops while the game is paused and its milliseconds scale with GameManager.timeScale the same way any other pause-suspended frame callback's elapsed time does: slow(0.5) on the debug console runs every delay, interval, and cooldown at half speed along with everything else that follows the time scale. See Engine.
Members
| Member | Meaning |
|---|---|
delay(ms, callback) | Fires callback once, ms of game time from now. Answers with a function that cancels it. |
interval(ms, callback) | Fires callback every ms of game time. Answers with a function that stops it. |
cooldown(ms) | A CooldownHandle for that duration |
cancelAll() | Drops every delay and interval, and readies every cooldown |
delay
showHitIndicator();
const cancel = engine.timer.delay(200, () =>
{
hideHitIndicator();
});
cancel(); // changed its mind before the 200ms passedms must be zero or more; a negative value throws a RangeError.
interval
// Regenerate 1 HP every 2 seconds.
const cancel = engine.timer.interval(2000, () =>
{
player.state.hp = Math.min(player.state.hp + 1, player.state.maxHp);
});
cancel();ms must be greater than zero; passing zero or a negative value throws a RangeError, since a zero-length interval would fire without end inside a single frame. delay(0, callback) is the next-frame callback that call would have meant.
A frame whose elapsed time covers more than one period fires the callback that many times, so an interval keeps its count against game time rather than against frames.
cooldown
A pollable handle, starting ready. reset() makes it not ready until ms of game time have passed.
const fireCooldown = engine.timer.cooldown(500);
function tryShoot() : void
{
if(fireCooldown.ready)
{
shootProjectile();
fireCooldown.reset();
}
}CooldownHandle
interface CooldownHandle
{
readonly ready : boolean;
reset() : void;
}| Member | Meaning |
|---|---|
ready | true once ms has elapsed since the last reset(), or if reset() has never been called |
reset() | Starts, or restarts, the cooldown |
A cooldown fires no callback of its own; a caller polls ready wherever it needs to decide whether an action is allowed yet.
cancelAll
engine.timer.cancelAll();Drops every active delay and interval, and readies every cooldown without retiring it: a cooldown taken before the call still counts down normally after a later reset(). Nothing calls this on its own; a game that wants its timers cleared on a level transition calls it from the transition.
A timer callback and the drain
A timer callback runs outside the fixed step, so it never writes entity state directly. It emits an event instead, for the entity's own behavior to apply at the next drain:
function activateShield(playerID : string) : void
{
player.emit('action:shield', { active: true }, playerID);
engine.timer.delay(5000, () =>
{
player.emit('action:shield', { active: false }, playerID);
});
}See Events for the drain this lands at.
A cooldown polled from a frame callback
const dashCooldown = engine.timer.cooldown(3000);
let dashesHandled = 0;
engine.managers.gameManager.registerFrameCallback(() =>
{
if(player.state.dashRequested > dashesHandled && dashCooldown.ready)
{
performDash();
dashCooldown.reset();
}
dashesHandled = player.state.dashRequested;
});dashRequested is a counter a behavior increments on each action:dash event; the frame callback polls it after the fixed step has run.
