Needle Engine Documentation
Getting Started
Tutorials
How-To Guides
Explanation
Reference
Help
Getting Started
Tutorials
How-To Guides
Explanation
Reference
Help

Time API

Access time data via this.context.time in components.


Properties

PropertyTypeDescription
timenumberScaled time since app started (affected by timeScale)
deltaTimenumberTime since last frame (use for smooth animations)
frameCountnumberTotal frames rendered since app started
realtimeSinceStartupnumberUnscaled time since app started (ignores timeScale)
timeScalenumberTime multiplier (default 1.0, set to 0.5 for slow-motion)

Frame-Rate Independent Movement

Always Use deltaTime

Multiply movement by deltaTime for smooth, frame-rate independent animation:

this.gameObject.position.x += speed * this.context.time.deltaTime;

Examples

Basic Movement

import { Behaviour } from "@needle-tools/engine";

export class MoveRight extends Behaviour {
    speed: number = 5;

    update() {
        // Move 5 units per second (frame-rate independent)
        this.gameObject.position.x += this.speed * this.context.time.deltaTime;
    }
}

Rotation

import { Behaviour } from "@needle-tools/engine";

export class Rotate extends Behaviour {
    rotationSpeed: number = 90; // degrees per second

    update() {
        // Convert degrees to radians and rotate
        const radiansPerSecond = this.rotationSpeed * (Math.PI / 180);
        this.gameObject.rotateY(radiansPerSecond * this.context.time.deltaTime);
    }
}

Time-Based Logic

import { Behaviour } from "@needle-tools/engine";

export class TimedSpawner extends Behaviour {
    spawnInterval: number = 2.0; // seconds
    private nextSpawnTime: number = 0;

    update() {
        // Check if enough time has passed
        if (this.context.time.time >= this.nextSpawnTime) {
            this.spawnObject();
            this.nextSpawnTime = this.context.time.time + this.spawnInterval;
        }
    }

    private spawnObject() {
        console.log("Spawning at time:", this.context.time.time);
    }
}

Slow Motion Effect

import { Behaviour } from "@needle-tools/engine";

export class SlowMotionController extends Behaviour {
    start() {
        // Normal speed
        this.context.time.timeScale = 1.0;
    }

    enableSlowMotion() {
        // Half speed
        this.context.time.timeScale = 0.5;
    }

    disableSlowMotion() {
        // Back to normal
        this.context.time.timeScale = 1.0;
    }

    pause() {
        // Freeze time
        this.context.time.timeScale = 0.0;
    }
}

Frame Counting

import { Behaviour } from "@needle-tools/engine";

export class FrameCounter extends Behaviour {
    update() {
        // Log every 60 frames
        if (this.context.time.frameCount % 60 === 0) {
            console.log("Frame:", this.context.time.frameCount);
            console.log("Time:", this.context.time.time);
        }
    }
}

Real Time (Unscaled)

import { Behaviour } from "@needle-tools/engine";

export class RealTimeCounter extends Behaviour {
    update() {
        // This continues even if timeScale is 0
        const realTime = this.context.time.realtimeSinceStartup;
        console.log("Real seconds elapsed:", realTime);
    }
}

Scaled vs Unscaled Time

PropertyAffected by timeScale?Use For
time✅ YesGame logic, animations
deltaTime✅ YesMovement, rotation
realtimeSinceStartup❌ NoProfiling, UI timers, cooldowns that shouldn't pause

Common Patterns

Smooth Lerp

const alpha = 5.0 * this.context.time.deltaTime; // Lerp factor
this.gameObject.position.lerp(targetPosition, alpha);

Clamp Movement Speed

const maxSpeed = 10;
const movement = speed * this.context.time.deltaTime;
const clampedMovement = Math.min(movement, maxSpeed * this.context.time.deltaTime);

Best Practices

✅ DO

  • Always use deltaTime for movement and animations
  • Use time for time-based triggers
  • Use realtimeSinceStartup for UI timers
  • Cache this.context.time if accessing multiple properties

❌ DON'T

  • Don't use fixed values for movement (not frame-rate independent)
  • Don't forget to multiply by deltaTime
  • Don't use Date.now() for game logic (use context.time)

Related

  • Lifecycle Methods - When to use time
  • Component Creation - Basic components
  • Coroutines - Time-based sequences
Suggest changes
Last Updated: 1/27/26, 6:44 PM

On this page

Extras

Copy for AI (LLMs)