Talos docs

TimeInfo

Since 0.6Changed in 0.7

Simulation clock.

Plain text

Reached in a behaviour as ctx.time.

Signature

export interface TimeInfo {
  /** Simulated seconds since load (scaled). */
  readonly now: number
  readonly frame: number
  /** Fixed tick length, 1/60 s. */
  readonly dt: number
  /**
   * Always 1. A tool's or the editor's time scale paces ticks against the wall clock and changes
   * nothing measured in ticks, and a game must not be able to tell a fast-forwarded playtest from play.
   */
  readonly scale: number
  /**
   * Raise the bus event `event` from this behaviour `seconds` of sim time from now, as `ctx.events.emit`
   * would then: heard by `onEvent` and `ctx.events.on(event, …)` with `by` this entity's id, delivered at the
   * end of the tick it falls due on. The timing other engines write with `Invoke` or `WaitForSeconds`, without
   * hidden state: the timer is kept in this behaviour's `ctx.state` (under `$after`), so a snapshot, a
   * restore and a hot reload carry it and a restart drops it. It waits while the world is paused. `seconds`
   * must be finite and not negative, and it is called from a hook or a listener; otherwise
   * `time.after-invalid`.
   *
   * ```ts
   * onTriggerEnter(ctx) { ctx.time.after(3, "door-close") }
   * init(ctx) { ctx.events.on("door-close", (ev) => { if (ev.by === ctx.entity.id) ctx.state.open = false }) }
   * ```
   */
  after(seconds: number, event: string, data?: unknown, opts?: AfterOptions): void
}

Import: import type { TimeInfo } from "@argus/api"

Members

MemberSignatureDescription
nowreadonly now: numberSimulated seconds since load (scaled).
framereadonly frame: number
dtreadonly dt: numberFixed tick length, 1/60 s.
scalereadonly scale: numberAlways 1. A tool's or the editor's time scale paces ticks against the wall clock and changes nothing measured in ticks, and a game must not be able to tell a fast-forwarded playtest from play.
afterafter(seconds: number, event: string, data?: unknown, opts?: AfterOptions): voidRaise the bus event event from this behaviour seconds of sim time from now, as ctx.events.emit would then: heard by onEvent and ctx.events.on(event, …) with by this entity's id, delivered at the end of the tick it falls due on. The timing other engines write with Invoke or WaitForSeconds, without hidden state: the timer is kept in this behaviour's ctx.state (under $after), so a snapshot, a restore and a hot reload carry it and a restart drops it. It waits while the world is paused. seconds must be finite and not negative, and it is called from a hook or a listener; otherwise time.after-invalid. ts onTriggerEnter(ctx) { ctx.time.after(3, "door-close") } init(ctx) { ctx.events.on("door-close", (ev) => { if (ev.by === ctx.entity.id) ctx.state.open = false }) }

Example

The tested fixture fixtures/recipes/jump-pad-and-elevator/scenes/behaviors/camera-zone.ts.

import type { Behavior } from "@argus/api"

/**
 * A trigger volume that retunes the camera while the player is inside it.
 *
 * The engine has no camera-zone concept and needs none: a volume, a `trigger` component and this.
 * Here the player's behaviour owns the camera (it re-sends its params when the view is turned), so
 * the zone tells it what to change rather than calling `ctx.camera.set` itself. In a scene where
 * nothing else writes the camera, the zone can call `ctx.camera.set(kind, params)` directly.
 */
interface Props {
  /** `ctx.camera.set` params to merge in on the way in, and on the way out. */
  inside?: Record<string, unknown>
  outside?: Record<string, unknown>
}

export default {
  onTrigger(ctx, trigger) {
    const params = trigger.entering ? ctx.props.inside : ctx.props.outside
    if (params) ctx.events.emit("camera-zone", { target: trigger.other.id, params })
  },
} satisfies Behavior<Record<string, never>, Props>