Ctx
Since 0.6Changed in 0.7
Everything a behavior can reach.
One Ctx per behavior instance; state and props are per instance, nav/input/controller/animator are null when the entity lacks that component. @typeParam S shape of state (persisted across hot reloads) @typeParam P shape of props (the script component's props in the scene)
Reached in a behaviour as ctx.
Signature
export interface Ctx<S = Record<string, any>, P = Record<string, any>> {
entity: EntityHandle
world: WorldQuery
nav: NavAgent | null
input: InputState | null
controller: Controller | null
animator: Animator | null
/** The entity's physics body; null while it has none. Read live, like `controller`. */
body: RigidBody | null
/** The entity's joint while it is in force; null otherwise. Read live, like `body`. */
joint: Joint | null
/** The entity's vehicle while it is running; null otherwise. Read live, like `body`. */
vehicle: Vehicle | null
/** The entity's wheel while it is running; null otherwise. Read live, like `body`. */
wheel: Wheel | null
/** The entity's sprite; null when it has no `sprite` component. Read live, like `body`. */
sprite: Sprite | null
/** The entity's tilemap; null when it has no `tilemap` component. Read live, like `body`. */
tilemap: Tilemap | null
/** Values this behaviour publishes for a data recording. Always present. */
data: DataHandle
events: EventBus
hud: HudHandle
ui: UiHandle
time: TimeInfo
/** The sky, read-only. */
environment: EnvironmentInfo
/** The scene's water, read-only. */
water: WaterHandle
/** The scene's wind, read-only. */
wind: WindHandle
camera: CameraHandle
/** The local players and the entity each drives. Always present. */
players: PlayersHandle
/** Split screen for local multiplayer; view 1 is `camera`. */
views: ViewsHandle
audio: AudioHandle
particles: ParticlesHandle
labels: LabelsHandle
/** Shader parameters. */
render: RenderHandle
strings: StringsHandle
save: SaveHandle
/** The project's `data/**` files, read-only. */
files: FilesHandle
session: SessionHandle
/** Diagnostics for the behavior itself: `wallMs()`, the one wall clock, not for gameplay state. */
debug: DebugHandle
/**
* Plain object owned by this instance; survives `reload`. Must stay JSON-serialisable. A snapshot
* restore (the critic's playtester restores between its probes) puts the snapshot's values back
* into this same object, and into the objects under it, so `const st = ctx.state` kept from
* `init` is still the live state afterwards.
*/
state: S
/** Read-only copy of the script component's props. Always an object: `{}` when the component has none, never null. */
props: P
/** Structured log line for the observability layer; `data` is JSON round-tripped. */
log(msg: string, data?: unknown): void
}
Import: import type { Ctx } from "@argus/api"
Members
| Member | Signature | Description |
|---|---|---|
entity | entity: EntityHandle | |
world | world: WorldQuery | |
nav | nav: NavAgent | null | |
input | input: InputState | null | |
controller | controller: Controller | null | |
animator | animator: Animator | null | |
body | body: RigidBody | null | The entity's physics body; null while it has none. Read live, like controller. |
joint | joint: Joint | null | The entity's joint while it is in force; null otherwise. Read live, like body. |
vehicle | vehicle: Vehicle | null | The entity's vehicle while it is running; null otherwise. Read live, like body. |
wheel | wheel: Wheel | null | The entity's wheel while it is running; null otherwise. Read live, like body. |
sprite | sprite: Sprite | null | The entity's sprite; null when it has no sprite component. Read live, like body. |
tilemap | tilemap: Tilemap | null | The entity's tilemap; null when it has no tilemap component. Read live, like body. |
data | data: DataHandle | Values this behaviour publishes for a data recording. Always present. |
events | events: EventBus | |
hud | hud: HudHandle | |
ui | ui: UiHandle | |
time | time: TimeInfo | |
environment | environment: EnvironmentInfo | The sky, read-only. |
water | water: WaterHandle | The scene's water, read-only. |
wind | wind: WindHandle | The scene's wind, read-only. |
camera | camera: CameraHandle | |
players | players: PlayersHandle | The local players and the entity each drives. Always present. |
views | views: ViewsHandle | Split screen for local multiplayer; view 1 is camera. |
audio | audio: AudioHandle | |
particles | particles: ParticlesHandle | |
labels | labels: LabelsHandle | |
render | render: RenderHandle | Shader parameters. |
strings | strings: StringsHandle | |
save | save: SaveHandle | |
files | files: FilesHandle | The project's data/** files, read-only. |
session | session: SessionHandle | |
debug | debug: DebugHandle | Diagnostics for the behavior itself: wallMs(), the one wall clock, not for gameplay state. |
state | state: S | Plain object owned by this instance; survives reload. Must stay JSON-serialisable. A snapshot restore (the critic's playtester restores between its probes) puts the snapshot's values back into this same object, and into the objects under it, so const st = ctx.state kept from init is still the live state afterwards. |
props | props: P | Read-only copy of the script component's props. Always an object: {} when the component has none, never null. |
log | log(msg: string, data?: unknown): void | Structured log line for the observability layer; data is JSON round-tripped. |
Example
The tested fixture fixtures/app/agent.ts.
import type { Behavior } from "@argus/api"
// Sends a nav agent to `props.target` once, then reports arrival through ctx.state so the
// test can read it without polling the crowd directly.
export default {
init(ctx) {
ctx.state.arrived = false
ctx.nav?.goTo(ctx.props.target as [number, number, number])
},
update(ctx) {
if (ctx.nav?.arrived) ctx.state.arrived = true
},
} satisfies Behavior