Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/sanchedev/tiny-engine/llms.txt

Use this file to discover all available pages before exploring further.

Timer is a lightweight, non-visual node that tracks elapsed time in seconds. Each frame the engine adds delta to an internal counter; when the counter reaches duration, the node fires timeout and stops. You can start it automatically with autoPlay, or control it imperatively via play(), pause(), and stop(). Use Timer for cooldowns, respawn delays, timed events, countdowns, and any other game logic that needs to respond after a fixed number of seconds.

Usage

import { useRefNode, useEvent } from 'tiny-engine/hooks'
import { PrimaryNode } from 'tiny-engine/nodes/enum'

function SpawnWave() {
  const timer = useRefNode(PrimaryNode.Timer)

  useEvent(timer, 'timeout', () => {
    spawnEnemyWave()
    timer.node.play(0) // restart for the next wave
  })

  return <timer ref={timer} duration={10} autoPlay />
}

Props

duration
number | SignalGetter<number>
required
Total duration in seconds. When the elapsed time reaches this value, the timer stops and fires timeout. Reactive when a SignalGetter is passed — changing the signal updates duration without restarting the timer.
autoPlay
boolean
When true, play() is called automatically at the end of the constructor so the timer is running as soon as the scene loop’s first update() tick fires. Defaults to false.
ref
NodeRef<PrimaryNode.Timer>
A ref created by useRefNode(PrimaryNode.Timer). Exposes the Timer instance so you can call play(), pause(), and stop() imperatively.
id
string | symbol
Optional node identifier. Must match [a-zA-Z][a-zA-Z0-9-_]* when a string.
zIndex
number
Draw order among siblings. Defaults to 0.
deltaIncrease
number
Speed multiplier applied to delta for this node. Use values below 1 to slow the timer down or above 1 to speed it up. Defaults to 1.
children
Node[]
Optional child nodes. The timer itself has no visual output but can serve as a logical parent.

Events

Subscribe with useEvent.
Event nameCallback signatureDescription
timeout() => voidFires once when elapsed time reaches duration.
timeChanged(elapsed: number) => voidFires every frame while the timer is running, before the increment.
started() => voidFires once after the node finishes start().
updated(delta: number) => voidFires every frame during the update cycle.
drawed(delta: number) => voidFires every frame during the draw cycle.
destroyed() => voidFires once when the node is removed.
timeChanged fires before the counter is incremented for that frame. On the final frame, timeout fires instead of timeChanged.

Runtime methods

MethodSignatureDescription
play(from?)(from?: number) => voidStart or resume the timer. Pass a number to seek to that position (clamped to [0, duration]).
pause()() => voidPause the timer without resetting elapsed time.
stop()() => voidStop the timer and reset elapsed time to 0.

Complete example — cooldown with progress display

import { Vector2 } from 'tiny-engine'
import { useSignal, useRefNode, useEvent } from 'tiny-engine/hooks'
import { PrimaryNode } from 'tiny-engine/nodes/enum'

const COOLDOWN_DURATION = 3 // seconds

function AbilityCooldown() {
  const timer    = useRefNode(PrimaryNode.Timer)
  const [elapsed, setElapsed] = useSignal(0)
  const [ready, setReady]     = useSignal(true)

  const activateAbility = () => {
    if (!ready()) return
    setReady(false)
    setElapsed(0)
    timer.node.play(0)
    console.log('Ability activated!')
  }

  useEvent(timer, 'timeChanged', (t) => {
    setElapsed(t)
  })

  useEvent(timer, 'timeout', () => {
    setReady(true)
    console.log('Ability ready again')
  })

  return (
    <transform>
      {/* Cooldown bar width shrinks as timer progresses */}
      <rectangle
        size={useComputed(() => [
          100 * (1 - elapsed() / COOLDOWN_DURATION),
          8,
        ])}
        fillColor={[0.2, 0.8, 0.2, 1]}
      />
      <clickable
        size={[100, 20]}
        onClick={activateAbility}
      />
      <timer ref={timer} duration={COOLDOWN_DURATION} />
    </transform>
  )
}

Example — single-use delay

Use autoPlay when you just need a one-shot delay from the moment the node enters the scene:
function DelayedSpawn() {
  const timer = useRefNode(PrimaryNode.Timer)

  useEvent(timer, 'timeout', () => {
    spawnBoss()
    timer.node.destroy()
  })

  return <timer ref={timer} duration={5} autoPlay />
}
Call timer.node.play(0) inside timeout to restart the timer for repeating intervals. There is no built-in “repeat” mode — restart manually when needed.
  • useRefNode — obtain a typed ref to access play(), pause(), stop()
  • useEvent — subscribe to timeout and timeChanged
  • useSignal — store elapsed time or cooldown state reactively
  • Transform — parent node for grouping the timer with other nodes

Build docs developers (and LLMs) love