TimeInfo
Since 0.6Changed in 0.7
Simulation clock.
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
| Member | Signature | Description |
|---|---|---|
now | readonly now: number | Simulated seconds since load (scaled). |
frame | readonly frame: number | |
dt | readonly dt: number | Fixed tick length, 1/60 s. |
scale | readonly scale: 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. |
after | after(seconds: number, event: string, data?: unknown, opts?: AfterOptions): void | 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 }) } |
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>