Reference
drift/*
Every capability this host binds, with its effects and whether it is deterministic.
What this host contributes to the language: 327 capabilities across 23 modules, each carrying the effect it has. A different host would supply its own prefix for its own capabilities and inherit the standard library unchanged. This page is generated from the same registry the linker reads, so a newly bound module appears here without anybody editing it.
drift/2d 12
sprite
scene.write
fn(batch: SpriteBatch, texture: i32, x: f32, y: f32, w: f32, h: f32) -> void
Put one quad in the batch, covering the whole of a texture.
tinted
scene.write
fn(batch: SpriteBatch, texture: i32, x: f32, y: f32, w: f32, h: f32, r: f32, g: f32, b: f32, a: f32) -> void
The same, multiplied by a colour picked for the screen: sRGB, 0 to 1, decoded to linear as a tint on a node is, with alpha kept as given. White is the identity, so a white texture draws exactly this colour — which is how a solid rectangle is drawn.
frame
scene.write
fn(batch: SpriteBatch, sheet: SpriteSheet, frame: i32, x: f32, y: f32, w: f32, h: f32) -> void
Put one frame of a sheet in the batch. A frame the sheet does not have draws the whole sheet, which is unmistakable.
named
scene.readdeterministic
fn(sheet: SpriteSheet, name: String) -> i32
The index a name has in a sheet, or -1. Ask once and keep the number: a name lookup is a hash and a frame is an array read.
frames
scene.readdeterministic
fn(sheet: SpriteSheet) -> i32
How many frames the sheet was cut into.
tilemap
scene.write
fn(batch: SpriteBatch, map: Tilemap, sheet: SpriteSheet, x: f32, y: f32, w: f32, h: f32) -> i32
Draw the tiles a view rectangle can see, and answer how many that was. The cost is the view rather than the map.
tile
scene.readdeterministic
fn(map: Tilemap, column: i32, row: i32) -> i32
The frame in a cell, or -1 for an empty one — including for a cell outside the map, which answers empty rather than another row.
setTile
scene.write
fn(map: Tilemap, column: i32, row: i32, tile: i32) -> void
Put a frame in a cell. A cell outside the map is ignored rather than wrapping into another row.
columns
scene.readdeterministic
fn(map: Tilemap) -> i32
How wide the map is, in cells.
rows
scene.readdeterministic
fn(map: Tilemap) -> i32
How tall the map is, in cells.
count
scene.readdeterministic
fn(batch: SpriteBatch) -> i32
How many quads are in the batch this frame.
dropped
scene.readdeterministic
fn(batch: SpriteBatch) -> i32
How many quads did not fit this frame. Zero is the only good value; anything else is a batch that wants a bigger capacity.
drift/ai 9
agent
puredeterministic
fn(id: String) -> Agent?
Resolve an agent by the id the consumer registered it under. Absent when there is none.
wake
ai
fn(agent: Agent, reason: String, priority: i32) -> void
Tell an agent something happened. Returns immediately; the agent acts at its next tick.
consider
ai
fn(agent: Agent) -> void
Ask an agent to think, at ordinary priority. Returns immediately.
intentId
puredeterministic
fn(agent: Agent) -> String
What the agent is doing now. Empty before its first tick.
degraded
puredeterministic
fn(agent: Agent) -> bool
Whether the agent is over budget and running on its policy floor alone.
reachable
navigation.readdeterministic
fn(agent: Agent, x: float, y: float, z: float) -> bool
Whether a route exists from where this agent is to a point, without writing one.
path
navigation.readdeterministic
fn(agent: Agent) -> NavPath?
The route object this agent follows, for `drift/navigation` to read or steer along.
deciding
network.readdeterministic
fn(agent: Agent) -> bool
Whether this peer decides this agent’s model intents. Elsewhere they arrive already taken.
drift/animation 17
pose
puredeterministic
fn(jointCount: u32) -> Pose
A new pose at rest. This is where a bind pose comes from; take one and keep it.
toRest
animation.write
fn(pose: Pose, jointCount: u32) -> void
Return a pose to rest without allocating another, which is what a state machine does on re-entry.
sample
animation.write
fn(clip: Clip, at: f32, into: Pose) -> void
Sample a clip at a time. A channel no track mentions is left as it was, so a rotation-only clip preserves the rest of the pose.
blend
animation.write
fn(a: Pose, b: Pose, amount: f32, into: Pose) -> void
Blend two poses into a third, clamped at the ends. Safe when `into` is also `a` or `b`. It interpolates every channel, so `into` decides what an untouched joint blends from.
blendSet
animation.write
fn(tree: Blend, parameter: String, value: f32) -> void
Set one of a tree's parameters. A name no node in that tree declares is refused by name, because a typo that silently did nothing would present as an animation that will not respond. Both kinds of parameter are set this way: a blend weight, and a clock — the time a `clip` node named for its own sampling.
blendAt
animation.write
fn(tree: Blend, at: f32, into: Pose) -> void
Evaluate a whole tree into a pose. `at` is the clock for every node that did not name one of its own, so a tree of ordinary clips is sampled at one time and a node with a clock reads that parameter instead.
reach
animation.write
fn(skeleton: Skeleton, pose: Pose, root: u32, mid: u32, tip: u32, targetX: f32, targetY: f32, targetZ: f32, poleX: f32, poleY: f32, poleZ: f32) -> bool
Bend a two-bone chain so its tip reaches a target. Answers whether it was reachable; an unreachable target straightens the chain toward it rather than giving up.
motion
puredeterministic
fn() -> Motion
A new root displacement, at zero. Take one and keep it; nothing here allocates per frame.
rootMotion
animation.write
fn(clip: Clip, joint: u32, from: f32, to: f32, into: Motion) -> void
How far the root travelled between two times, in its own frame at `from`. Loops are accumulated, so a clip that wraps between the two times still answers a step forward. Pair every call with `stripRoot` or the character moves twice.
stripRoot
animation.write
fn(clip: Clip, joint: u32, pose: Pose) -> void
Pin a sampled pose's root to the clip's value at time zero, so the displacement `rootMotion` handed you is not also in the pose. Every other joint is left as it was.
motionX
puredeterministic
fn(motion: Motion) -> f32
The displacement along the root's own x axis at the earlier time.
motionY
puredeterministic
fn(motion: Motion) -> f32
The displacement along the root's own y axis at the earlier time.
motionZ
puredeterministic
fn(motion: Motion) -> f32
The displacement along the root's own z axis at the earlier time.
motionTurnX
puredeterministic
fn(motion: Motion) -> f32
The x part of the rotation the root turned through, as a quaternion.
motionTurnY
puredeterministic
fn(motion: Motion) -> f32
The y part of the rotation the root turned through, as a quaternion.
motionTurnZ
puredeterministic
fn(motion: Motion) -> f32
The z part of the rotation the root turned through, as a quaternion.
motionTurnW
puredeterministic
fn(motion: Motion) -> f32
The w part of the rotation the root turned through, as a quaternion. One means it did not turn.
drift/audio 9
sound
puredeterministic
fn(slot: String) -> Sound?
Resolve a sound slot. Absent when nothing was registered or nothing decoded.
play
audio.write
fn(sound: Sound, gain: f32) -> void
Play a resolved sound through the mix.
playPanned
audio.write
fn(sound: Sound, gain: f32, pan: f32) -> void
Play a resolved sound at a stereo position, -1 left to 1 right.
distanceGain
puredeterministic
fn(distance: f32, radius: f32) -> f32
How loud something is at a distance, falling off to nothing at the radius.
stereoPan
puredeterministic
fn(dx: f32, dz: f32, yaw: f32) -> f32
Where something sits in the stereo field, relative to a listener facing yaw.
duck
audio.write
fn(bus: String, factor: f32, seconds: f32) -> bool
Take a bus down to factor of its fader over seconds, 1 to bring it back, leaving the fader where the player set it. False when the mix has no bus of that name.
fade
audio.write
fn(bus: String, level: f32, seconds: f32) -> bool
Move a bus's fader to level over seconds. For a bus the game made: the music and effects faders are the player's, and duck is how a script goes over them. False when the mix has no bus of that name.
recall
audio.write
fn(snapshot: String, seconds: f32) -> bool
Crossfade every level, mute and send to a snapshot the host captured, over seconds. False when nothing was captured under that name.
pulse
nondeterministic
fn() -> f32
How hard the music is kicking, 0 to 1, spiking on each kick and falling back. 0 when the host runs no kick detector.
drift/behavior 8
tick
behavior.write
fn(behavior: Behavior) -> TreeStatus
Advance the routine one tick, and answer whether it failed, finished or is still going. Does nothing while paused.
step
behavior.write
fn(behavior: Behavior) -> TreeStatus
Advance one tick even while paused, which is what a step button is.
restart
behavior.write
fn(behavior: Behavior) -> void
Forget where the routine had got to, so the next tick starts it from the top.
setPaused
behavior.write
fn(behavior: Behavior, paused: bool) -> void
Hold this one agent while the world carries on.
paused
behavior.readdeterministic
fn(behavior: Behavior) -> bool
Whether it is being held.
status
behavior.readdeterministic
fn(behavior: Behavior) -> TreeStatus
What the last tick answered, without ticking again.
doing
behavior.readdeterministic
fn(behavior: Behavior, node: String) -> bool
Whether the agent is currently inside a node of this name — the routine's own answer, not a copy of it.
depth
behavior.readdeterministic
fn(behavior: Behavior) -> i32
How deep in the tree the last tick reached. For a debug readout.
drift/camera 2
snap
scene.write
fn(camera: Camera) -> void
Jump the camera to where it is heading, skipping the ease. What a scene cut needs.
shotAge
scene.readdeterministic
fn(camera: Camera) -> f32
Seconds since the current shot began. A read, so a deterministic function may ask.
drift/chemistry 53
substance
chemistry.readdeterministic
fn(chem: Chemistry, id: String) -> Substance
A registered material by id, such as `oak`. Refuses in words naming what the world has.
species
chemistry.readdeterministic
fn(chem: Chemistry, id: String) -> Species
A registered species by id, such as `O2`. Refuses in words if the world has no such species.
parcelCount
chemistry.readdeterministic
fn(chem: Chemistry) -> i32
How many parcel handles have ever been issued, live or not.
parcelAt
chemistry.readdeterministic
fn(chem: Chemistry, index: i32) -> i32
The handle at an index, for iteration. Check `alive` before reading it.
alive
chemistry.readdeterministic
fn(chem: Chemistry, parcel: i32) -> bool
Whether a parcel still exists.
substanceOf
chemistry.readdeterministic
fn(chem: Chemistry, parcel: i32) -> Substance
What material a parcel is made of.
temperature
chemistry.readdeterministic
fn(chem: Chemistry, parcel: i32) -> f32
K, averaged over the whole parcel.
surfaceTemperature
chemistry.readdeterministic
fn(chem: Chemistry, parcel: i32) -> f32
K at the outermost shell — the one that decides whether it catches.
coreTemperature
chemistry.readdeterministic
fn(chem: Chemistry, parcel: i32) -> f32
K at the innermost shell — the one that decides whether it is cooked.
mass
chemistry.readdeterministic
fn(chem: Chemistry, parcel: i32) -> f32
How much of it there is, in kilograms. Falls as it burns.
speciesMass
chemistry.readdeterministic
fn(chem: Chemistry, parcel: i32, species: Species) -> f32
kg of one species held anywhere in this parcel.
moisture
chemistry.readdeterministic
fn(chem: Chemistry, parcel: i32) -> f32
kg of water per kg of dry matter — the dry basis, which is how moisture content is quoted. Under 0.25 will burn; over 0.35 will not.
charFraction
chemistry.readdeterministic
fn(chem: Chemistry, parcel: i32) -> f32
Share of the parcel that is now carbon, 0 to 1.
charDepth
chemistry.readdeterministic
fn(chem: Chemistry, parcel: i32) -> f32
Metres of char measured inward from the surface.
wetness
chemistry.readdeterministic
fn(chem: Chemistry, parcel: i32) -> f32
kg of liquid water on the surface, per square metre of it.
wettable
chemistry.readdeterministic
fn(chem: Chemistry, parcel: i32) -> bool
Whether this material can hold liquid water, which is what `wet` asks. Rain over everything asks first, since `wet` refuses an iron nail.
phase
chemistry.readdeterministic
fn(chem: Chemistry, parcel: i32) -> MatterPhase
Whether the parcel is solid, liquid, gas or mixed. Mixed is a real answer: wet wood is a solid and a liquid at once.
burning
chemistry.readdeterministic
fn(chem: Chemistry, parcel: i32) -> bool
Whether a flame stands over it.
smouldering
chemistry.readdeterministic
fn(chem: Chemistry, parcel: i32) -> bool
Whether it is glowing with no flame. A smoulder survives air a flame cannot, which is why smothering leaves embers.
heatRelease
chemistry.readdeterministic
fn(chem: Chemistry, parcel: i32) -> f32
kW the reactions released last tick. A fire's size is its heat release rate, not its temperature. Negative while a surface is gasifying, which is correct.
ignitionProgress
chemistry.readdeterministic
fn(chem: Chemistry, parcel: i32) -> f32
How close to catching, 0 to 1: the least satisfied of the five criteria. A readout — nothing branches on it.
structuralIntegrity
chemistry.readdeterministic
fn(chem: Chemistry, parcel: i32) -> f32
How much is still load-bearing, 1 down to 0, as char eats the thickness. This package breaks nothing; it reports.
massFlux
chemistry.readdeterministic
fn(chem: Chemistry, parcel: i32) -> f32
kg/(m²·s) of gas leaving the surface — the smoke.
fuelFlux
chemistry.readdeterministic
fn(chem: Chemistry, parcel: i32) -> f32
The combustible share of that, which is what ignition is measured against.
positionX
chemistry.readdeterministic
fn(chem: Chemistry, parcel: i32) -> f32
Where the consumer said this parcel is.
positionY
chemistry.readdeterministic
fn(chem: Chemistry, parcel: i32) -> f32
Where the consumer said this parcel is.
positionZ
chemistry.readdeterministic
fn(chem: Chemistry, parcel: i32) -> f32
Where the consumer said this parcel is.
ambientTemperature
chemistry.readdeterministic
fn(chem: Chemistry, x: f32, y: f32, z: f32) -> f32
K of the air at a point.
oxygenFraction
chemistry.readdeterministic
fn(chem: Chemistry, x: f32, y: f32, z: f32) -> f32
Volume fraction of oxygen. Air is 0.209; a flame stops near 0.14 and a smoulder near 0.05.
humidity
chemistry.readdeterministic
fn(chem: Chemistry, x: f32, y: f32, z: f32) -> f32
Relative humidity, 0 to 1. Nothing dries in fog because the vapour pressure deficit is zero.
pressure
chemistry.readdeterministic
fn(chem: Chemistry, x: f32, y: f32, z: f32) -> f32
Pascals. Rises where the air is heated and confined, which is what an explosion event reports on.
concentration
chemistry.readdeterministic
fn(chem: Chemistry, species: Species, x: f32, y: f32, z: f32) -> f32
Parts per million by volume. The reading a game acts on — carbon monoxide is the one that kills.
smokeDensity
chemistry.readdeterministic
fn(chem: Chemistry, x: f32, y: f32, z: f32) -> f32
Extinction coefficient, 1/m: what to attenuate a light along a ray by.
visibility
chemistry.readdeterministic
fn(chem: Chemistry, x: f32, y: f32, z: f32) -> f32
How far you can see, metres. Clamped at ten kilometres.
place
chemistry.writedeterministic
fn(chem: Chemistry, substance: Substance, kilograms: f32, area: f32, x: f32, y: f32, z: f32) -> i32
Put a new parcel in the world. `area` is the exposed surface in m², and it is required rather than defaulted: a characteristic depth is volume over area, so a parcel with no area has no depth.
destroy
chemistry.writedeterministic
fn(chem: Chemistry, parcel: i32) -> void
Remove a parcel. Its handle is never reused.
move
chemistry.writedeterministic
fn(chem: Chemistry, parcel: i32, x: f32, y: f32, z: f32) -> void
Where it is. The consumer owns position; this package only reads it to work out what reaches it.
addHeat
chemistry.writedeterministic
fn(chem: Chemistry, parcel: i32, joules: f32) -> void
Joules into the surface shell, which is what a flux from outside does.
addHeatDeep
chemistry.writedeterministic
fn(chem: Chemistry, parcel: i32, shell: i32, joules: f32) -> void
Joules into a named shell. The difference from `addHeat` is a microwave and an oven.
setTemperature
chemistry.writedeterministic
fn(chem: Chemistry, parcel: i32, kelvin: f32) -> void
Set every shell to a temperature. **For authoring and tests, not for a tick** — it discards whatever enthalpy was there rather than accounting for it.
wet
chemistry.writedeterministic
fn(chem: Chemistry, parcel: i32, kilograms: f32) -> void
Pour water on it: real liquid water into the surface shell, where boiling will find it. Refuses, naming the material, where that material holds no water.
dry
chemistry.writedeterministic
fn(chem: Chemistry, parcel: i32, kilograms: f32) -> void
Take surface water away: a cloth, a hot dry pan, or wind.
ignite
chemistry.writedeterministic
fn(chem: Chemistry, parcel: i32) -> void
Supply a pilot for one tick. **This does not start a fire** — it satisfies one of five criteria, so holding a match to wet wood does nothing.
douse
chemistry.writedeterministic
fn(chem: Chemistry, parcel: i32) -> void
Remove the pilot and the flame. Embers survive, which is the point of it.
addSpecies
chemistry.writedeterministic
fn(chem: Chemistry, parcel: i32, species: Species, kilograms: f32) -> void
Salt the water, oil the pan, poison the well.
mix
chemistry.writedeterministic
fn(chem: Chemistry, from: i32, into: i32) -> void
Pour one parcel into another; the first is consumed. Both must be the same material — a mixture of two is a third material, authored as one.
release
chemistry.writedeterministic
fn(chem: Chemistry, species: Species, kilograms: f32, x: f32, y: f32, z: f32) -> void
A gas release into the air: a leak, a vent, an extinguisher.
addAirHeat
chemistry.writedeterministic
fn(chem: Chemistry, joules: f32, x: f32, y: f32, z: f32) -> void
Joules into a cell of air, which is what a heater does and what a fire does to the room.
eventCount
chemistry.readdeterministic
fn(chem: Chemistry) -> i32
Events this tick. Cleared at the top of every one.
eventKind
chemistry.readdeterministic
fn(chem: Chemistry, index: i32) -> ChemistryEvent
What happened in one of this tick’s events. An index outside `eventCount` is refused, naming both.
eventParcel
chemistry.readdeterministic
fn(chem: Chemistry, index: i32) -> i32
Which parcel it happened to.
eventSpecies
chemistry.readdeterministic
fn(chem: Chemistry, index: i32) -> i32
Which species, or -1 where the kind does not name one.
eventValue
chemistry.readdeterministic
fn(chem: Chemistry, index: i32) -> f32
The kind's own quantity.
drift/ecs 17
create
ecs.write
fn(world: World) -> Entity
A fresh entity with nothing on it. The handle is exact; do not put one in an `f32`.
destroy
ecs.write
fn(world: World, entity: Entity) -> bool
Remove an entity and every component it had. False when the handle was already stale.
alive
ecs.readdeterministic
fn(world: World, entity: Entity) -> bool
Whether this handle still names a live entity. A handle to something destroyed is false, even after its slot is reused.
has
ecs.readdeterministic
fn(world: World, entity: Entity, component: String) -> bool
Whether an entity carries a component.
attach
ecs.write
fn(world: World, entity: Entity, component: String) -> void
Give an entity a component, every field at the zero for its type. Set them with `write`.
detach
ecs.write
fn(world: World, entity: Entity, component: String) -> bool
Take a component away. False when it did not have one.
read
ecs.readdeterministic
fn(world: World, entity: Entity, component: String, field: String) -> f64
One numeric field. Reading a field of a component an entity does not have is 0.
write
ecs.write
fn(world: World, entity: Entity, component: String, field: String, value: f64) -> void
Set one numeric field.
count
ecs.readdeterministic
fn(world: World, component: String) -> u32
How many entities carry a component.
at
ecs.readdeterministic
fn(world: World, component: String, index: u32) -> Entity
The nth entity carrying a component. **The order is insertion modified by swap-removal**, so a walk that removes should count downwards — removing moves the last entity into a position already passed.
findNearest
ecs.readdeterministic
fn(world: World, component: String, fieldX: String, fieldY: String, fieldZ: String, x: float, y: float, z: float, radius: float) -> bool
Whether any entity carrying a component has position fields putting it within a radius, and the search `nearest` then reads. **A linear scan of that component's column, not an index** — the entity model keeps no spatial structure, so this costs one pass over everything carrying the component. Position is read from three fields you name, so nothing here knows what a transform is called.
nearest
ecs.readdeterministic
fn(world: World) -> Entity
The entity the last `findNearest` on this world found. **Valid only until the next one**, and meaningless when that answered false — the same lifetime a raycast hit has.
instantiate
ecs.write
fn(world: World, prefab: String) -> Entity
Make an entity from a prefab, with every component it names. Overrides are the host’s to apply; a script that wants a different value writes it after.
query
ecs.readdeterministic
fn(world: World, a: String, b: String, c: String, d: String) -> Cursor
Open a walk over everything carrying these components. The cursor is borrowed from the world’s pool; ending the walk gives it back.
without
ecs.readdeterministic
fn(cursor: Cursor, component: String) -> void
Narrow an open walk to entities that do **not** carry a component.
next
ecs.readdeterministic
fn(cursor: Cursor) -> Entity
The next entity, or a **negative** number when the walk is done — which also gives the cursor back. Negative rather than zero, because zero is a legal handle.
view
ecs.readdeterministic
fn(world: World, component: String, forWriting: bool) -> View
A component’s live columns. `forWriting` decides which of a system’s declarations is checked — a loop that only reads takes a readable view, and asking for more than the system declared is refused.
drift/editor 43
translateMode
editor
fn(gizmo: Gizmo) -> void
Make this an arrow gizmo, which moves what it is on.
rotateMode
editor
fn(gizmo: Gizmo) -> void
Make this a ring gizmo, which turns what it is on.
scaleMode
editor
fn(gizmo: Gizmo) -> void
Make this a scale gizmo. Scale is always in the object’s own axes, whatever the space says, because a non-uniform scale along a world axis would shear it.
gizmoMode
editor
fn(gizmo: Gizmo) -> GizmoMode
Which of the three the gizmo is: translate, rotate or scale.
worldSpace
editor
fn(gizmo: Gizmo) -> void
Point the handles along the world axes.
localSpace
editor
fn(gizmo: Gizmo) -> void
Point the handles along the object’s own axes.
space
editor
fn(gizmo: Gizmo) -> GizmoSpace
Which the handles are pointing along: the world or the object.
size
editor
fn(gizmo: Gizmo) -> f32
How big the gizmo is in metres. The host keeps this the same on screen as the camera moves.
setSize
editor
fn(gizmo: Gizmo, metres: f32) -> void
Set how big the gizmo is in metres. Non-positive draws nothing and picks nothing rather than failing.
hovered
editor
fn(gizmo: Gizmo) -> GizmoHandle
What the pointer is over: `None`, or a handle such as `TranslateX`, `TranslateYZ`, `RotateY` or `ScaleUniform`.
dragging
editor
fn(gizmo: Gizmo) -> bool
Whether a drag is running.
dragAngle
editor
fn(gizmo: Gizmo) -> f32
How far a rotation drag has turned, in radians, signed and past a full turn if it went that far. Zero when the drag is not a rotation. This is what to snap or clamp; the rotation itself cannot tell a three-quarter turn from a quarter turn back.
positionX
editor
fn(gizmo: Gizmo) -> f32
Where the thing being edited is, along x.
positionY
editor
fn(gizmo: Gizmo) -> f32
The same, along y.
positionZ
editor
fn(gizmo: Gizmo) -> f32
The same, along z.
setPosition
editor
fn(gizmo: Gizmo, x: f32, y: f32, z: f32) -> void
Put the gizmo, and the transform it is editing, somewhere. A drag that is running is not interrupted, so do this between drags.
scaleX
editor
fn(gizmo: Gizmo) -> f32
How much the thing being edited is scaled, along x.
scaleY
editor
fn(gizmo: Gizmo) -> f32
The same, along y.
scaleZ
editor
fn(gizmo: Gizmo) -> f32
The same, along z.
rotationX
editor
fn(gizmo: Gizmo) -> f32
The orientation being edited, as a quaternion: x.
rotationY
editor
fn(gizmo: Gizmo) -> f32
The same: y.
rotationZ
editor
fn(gizmo: Gizmo) -> f32
The same: z.
rotationW
editor
fn(gizmo: Gizmo) -> f32
The same: w. Identity is (0, 0, 0, 1).
mode
editor
fn(editor: Editor) -> EditorMode
What the editor is doing: editing, playing or paused.
playing
editor
fn(editor: Editor) -> bool
Whether the world is advancing. False while paused and while editing.
play
editor
fn(editor: Editor) -> bool
Start playing, taking a snapshot of the world first so `stop` can put it back. Resuming from paused does not re-snapshot. False when no world is bound to snapshot.
pause
editor
fn(editor: Editor) -> void
Hold the world where it is. The frame keeps drawing.
step
editor
fn(editor: Editor) -> void
Advance exactly one fixed tick, then hold. Does nothing while editing, where there is nothing to step.
stop
editor
fn(editor: Editor) -> bool
Leave play and put the world back as it was. Every entity handle changes, so a selection is re-found by its place in the snapshot and one that play created is dropped. False when there was nothing to put back.
rowCount
editor
fn(editor: Editor) -> i32
How many rows the tree showed at its last rebuild.
rebuildTree
editor
fn(editor: Editor, root: Node) -> void
Walk a node and everything under it into rows, honouring which branches are collapsed.
rowName
editor
fn(editor: Editor, row: i32) -> String
What the node on a row is called, or "" for a row that does not exist.
rowDepth
editor
fn(editor: Editor, row: i32) -> i32
How deep a row sits, with the root at zero. Minus one for a row that does not exist.
rowExpanded
editor
fn(editor: Editor, row: i32) -> bool
Whether a row is showing its children. Meaningless for a row with none.
toggleRow
editor
fn(editor: Editor, row: i32) -> void
Open a closed row or close an open one. Call `rebuildTree` afterwards to see it.
selectRow
editor
fn(editor: Editor, row: i32) -> void
Select the node on a row, which points the gizmo at it. A row that does not exist selects nothing.
selectedRow
editor
fn(editor: Editor) -> i32
Which row is selected, or minus one.
fieldCount
editor
fn(editor: Editor) -> i32
How many fields the inspector is showing.
fieldLabel
editor
fn(editor: Editor, field: i32) -> String
A field’s name as it was declared, or "" for a field that does not exist.
fieldGroup
editor
fn(editor: Editor, field: i32) -> String
What a field belongs to: a component’s name, or "transform" for a node.
fieldKind
editor
fn(editor: Editor, field: i32) -> FieldKind
How to show a field: a number, an integer, a boolean, text, an entity or an enum. Taken from the declared type, because a read cannot tell them apart. A field outside `fieldCount` is refused, naming both.
fieldNumber
editor
fn(editor: Editor, field: i32) -> f32
A field’s value as a number. Zero for a field that is not one, and for one that does not exist.
setFieldNumber
editor
fn(editor: Editor, field: i32, value: f32) -> bool
Write a number into a field. False where the field does not exist or will not take one.
drift/events 3
push
puredeterministic
fn(queue: Queue, id: String, priority: f32, holdFor: f32) -> void
Queue a message by identity. A repeat of the same id inside the dedupe window is dropped.
current
puredeterministic
fn(queue: Queue) -> String?
The id of the message showing now, if any. The queue carries identity and priority; the words are the consumer's.
clear
puredeterministic
fn(queue: Queue) -> void
Drop everything queued.
drift/input 14
down
input.read
fn(actions: Actions, action: String) -> bool
Whether an action is held.
pressed
input.read
fn(actions: Actions, action: String) -> bool
Whether an action went down this frame.
axisX
input.read
fn(actions: Actions, action: String) -> f32
A directional action's horizontal component, shortened to the rim with the vertical one so a keyboard diagonal is not faster than a straight line. For two independent controls such as throttle and steering, read rawAxisX instead.
axisY
input.read
fn(actions: Actions, action: String) -> f32
A directional action's vertical component, shortened to the rim with the horizontal one. For two independent controls, read rawAxisY instead.
rawAxisX
input.read
fn(actions: Actions, action: String) -> f32
An action's horizontal axis on its own, not shortened against the vertical one. This is what a throttle or a steering input wants: holding two keys gives a full 1 on each.
rawAxisY
input.read
fn(actions: Actions, action: String) -> f32
An action's vertical axis on its own, not shortened against the horizontal one.
canRumble
host
fn(actions: Actions) -> bool
Whether the pad these actions read has motors this browser can drive. Grey the control out when it is false; most pads on most browsers cannot.
rumble
host
fn(actions: Actions, durationMs: f32, strong: f32, weak: f32) -> bool
Rumble for a duration in milliseconds, at two magnitudes in [0, 1]: `strong` is the low-frequency motor and `weak` the high-frequency one. Answers whether the platform took it; false is a real answer, not an error.
stopRumble
host
fn(actions: Actions) -> bool
Stop whatever that pad is playing. Answers whether the platform took it.
touchX
input.read
fn(touch: Touch) -> f32
The touch stick's horizontal, -1 to 1, 0 while no thumb is on it.
touchY
input.read
fn(touch: Touch) -> f32
The touch stick's vertical, -1 to 1, up negative as a gamepad stick's is.
touchHeld
input.read
fn(touch: Touch) -> bool
Whether a thumb is held still on the action side of the screen: the held form of the primary.
touchTap
input.read
fn(touch: Touch) -> bool
Whether the action side was tapped since this was last asked. True once per tap, so ask it once a tick.
touchSlide
input.read
fn(touch: Touch) -> bool
Whether a downward flick on the action side is being held: the secondary, a slide or a crouch.
drift/network 9
self
network.readdeterministic
fn(session: Session) -> i32
Which participant this peer is. Fixed for the life of the session, which is why a deterministic system may read it.
authority
network.readdeterministic
fn(session: Session) -> bool
Whether this peer’s world is the authoritative one. Fixed when the session is created.
participants
nondeterministic
fn(session: Session) -> i32
How many participants the session holds. Nondeterministic because somebody may join or leave between two runs of the same recording.
confirmed
nondeterministic
fn(session: Session) -> i32
The highest tick every participant’s input has arrived for, or -1. Moves with packet timing, so a deterministic system may not branch on it.
halted
nondeterministic
fn(session: Session) -> bool
Whether the session has stopped, because an input arrived too late to apply or two peers computed different worlds.
haltReason
nondeterministic
fn(session: Session) -> String
Why it halted, as a sentence, or an empty string. Names the tick a divergence began at.
slots
nondeterministic
fn(session: Session) -> i32
How many replicated scalars each participant has. A consumer sizes this when the session is made.
replicated
nondeterministic
fn(session: Session, participant: i32, slot: i32) -> f32
Read a participant’s published scalar. An index out of range answers zero rather than failing, because a frame loop has nothing to do with a refusal.
replicate
network.write
fn(session: Session, slot: i32, value: f32) -> void
Publish a value in one of this peer’s slots. Not callable from a deterministic system: a replay re-runs one and a send is not idempotent.
drift/persistence 5
read
persistence.read
fn(store: Store, key: String) -> String?
What is stored under a key. Absent when nothing is, which is ordinary rather than exceptional.
write
persistence.write
fn(store: Store, key: String, value: String) -> void
Store a value under a key.
remove
persistence.write
fn(store: Store, key: String) -> void
Forget a key.
saveStatus
persistence.read
fn(store: Store) -> SaveStatus
Whether writes have landed: idle, pending, saving or failed. A store that writes synchronously is always idle, which is the true answer rather than a stub.
pendingSaves
persistence.read
fn(store: Store) -> u32
How many keys are waiting to reach the backend. Zero for a store that writes synchronously.
drift/physics 42
colliderCount
physics.readdeterministic
fn(colliders: Colliders) -> u32
How many colliders a set holds.
colliderCapacity
physics.readdeterministic
fn(colliders: Colliders) -> u32
How many slots the set has allocated, live or not. Equal to `colliderCount` until a group is removed; after that the live colliders are sparse within it.
colliderBytes
physics.readdeterministic
fn(colliders: Colliders) -> u32
What the set costs in memory, in bytes. The slots and shapes are exact; the spatial index includes an estimate of per-object overhead a JavaScript engine does not expose.
beginColliderGroup
physics.write
fn(colliders: Colliders) -> void
Open a group. Add boxes with `addColliderBox`, then `endColliderGroup` to put them in and get the handle back.
addColliderBox
physics.write
fn(colliders: Colliders, cx: f32, cy: f32, cz: f32, hx: f32, hy: f32, hz: f32) -> void
A box in the open group, by centre and half-extents — the same numbers a mesh builder takes, so nothing is authored twice. Nothing is queryable until `endColliderGroup`.
endColliderGroup
physics.write
fn(colliders: Colliders) -> u32
Put the open group into the set and return the handle that drops it again. Keep the handle: it is the only way to remove those colliders.
removeColliderGroup
physics.write
fn(colliders: Colliders, group: u32) -> void
Drop a group and everything in it. Refuses a handle the set does not hold, and refuses the colliders the set was constructed with — a set meant to stream is constructed empty.
anyWithin
physics.readdeterministic
fn(colliders: Colliders, x: f32, y: f32, z: f32, radius: f32) -> bool
Whether any collider overlaps the *box* around a sphere. The cheapest answer there is, and it over-reports a collider that only reaches the box corners. `nearestWithin` measures the sphere.
nearestWithin
physics.readdeterministic
fn(colliders: Colliders, x: f32, y: f32, z: f32, radius: f32) -> bool
Find the closest collider within a radius and record it. Read the result with the `near` functions. Valid until the next `nearestWithin` on this set.
nearCollider
physics.readdeterministic
fn(colliders: Colliders) -> i32
The collider the last `nearestWithin` on this set found, or −1.
nearX
physics.readdeterministic
fn(colliders: Colliders) -> f32
The closest point on that collider’s bounds, along x — the point on the wall rather than the wall’s centre.
nearY
physics.readdeterministic
fn(colliders: Colliders) -> f32
The closest point on that collider’s bounds, along y.
nearZ
physics.readdeterministic
fn(colliders: Colliders) -> f32
The closest point on that collider’s bounds, along z.
nearDistance
physics.readdeterministic
fn(colliders: Colliders) -> f32
How far that collider’s bounds are, in metres. Zero when the query point is inside them.
bodyCount
physics.readdeterministic
fn(world: PhysicsWorld) -> i32
How many bodies the world holds.
bodyX
physics.readdeterministic
fn(world: PhysicsWorld, body: i32) -> f32
A body's world position along x.
bodyY
physics.readdeterministic
fn(world: PhysicsWorld, body: i32) -> f32
A body's world position along y.
bodyZ
physics.readdeterministic
fn(world: PhysicsWorld, body: i32) -> f32
A body's world position along z.
bodyVelX
physics.readdeterministic
fn(world: PhysicsWorld, body: i32) -> f32
A body's velocity along x, in metres per second.
bodyVelY
physics.readdeterministic
fn(world: PhysicsWorld, body: i32) -> f32
A body's velocity along y, in metres per second.
bodyVelZ
physics.readdeterministic
fn(world: PhysicsWorld, body: i32) -> f32
A body's velocity along z, in metres per second.
bodyMass
physics.readdeterministic
fn(world: PhysicsWorld, body: i32) -> f32
A body's mass in kilograms, or zero where it has none because it is static or kinematic.
sleeping
physics.readdeterministic
fn(world: PhysicsWorld, body: i32) -> bool
Whether a body has been still long enough to stop being solved.
raycast
physics.readdeterministic
fn(world: PhysicsWorld, x: f32, y: f32, z: f32, dx: f32, dy: f32, dz: f32, maxDistance: f32, mask: i32) -> bool
Cast a ray and record what it hit. `mask` is required: without one the first thing a ray finds is often the body it started inside. Read the result with the `hit` functions.
hitBody
physics.readdeterministic
fn(world: PhysicsWorld) -> i32
The body the last `raycast` on this world found, or −1. Valid until the next raycast.
hitX
physics.readdeterministic
fn(world: PhysicsWorld) -> f32
Where the last raycast struck, along x. Valid until the next raycast.
hitY
physics.readdeterministic
fn(world: PhysicsWorld) -> f32
Where the last raycast struck, along y. Valid until the next raycast.
hitZ
physics.readdeterministic
fn(world: PhysicsWorld) -> f32
Where the last raycast struck, along z. Valid until the next raycast.
hitNormalX
physics.readdeterministic
fn(world: PhysicsWorld) -> f32
The surface normal the last raycast struck, along x.
hitNormalY
physics.readdeterministic
fn(world: PhysicsWorld) -> f32
The surface normal the last raycast struck, along y.
hitNormalZ
physics.readdeterministic
fn(world: PhysicsWorld) -> f32
The surface normal the last raycast struck, along z.
hitFraction
physics.readdeterministic
fn(world: PhysicsWorld) -> f32
How far along the ray the last hit was, from 0 to 1.
contactCount
physics.readdeterministic
fn(world: PhysicsWorld) -> i32
How many contact events the last step produced. Drain them after stepping, never during.
contactKind
physics.readdeterministic
fn(world: PhysicsWorld, index: i32) -> ContactKind
An event's kind: the two bodies began touching, are still touching, or have parted.
contactA
physics.readdeterministic
fn(world: PhysicsWorld, index: i32) -> i32
The lower-indexed body of a contact event.
contactB
physics.readdeterministic
fn(world: PhysicsWorld, index: i32) -> i32
The higher-indexed body of a contact event.
applyImpulse
physics.write
fn(world: PhysicsWorld, body: i32, px: f32, py: f32, pz: f32, atX: f32, atY: f32, atZ: f32) -> void
Apply an impulse at a world point. The point is required: through the centre of mass an impulse produces no rotation at all, which reads as a broken impulse rather than a missing argument.
applyForce
physics.write
fn(world: PhysicsWorld, body: i32, fx: f32, fy: f32, fz: f32, dt: f32, atX: f32, atY: f32, atZ: f32) -> void
A force applied for one step, which is an impulse of force times dt. The point is required for the same reason.
setVelocity
physics.write
fn(world: PhysicsWorld, body: i32, vx: f32, vy: f32, vz: f32) -> void
Set a body's velocity outright, waking its island.
setPosition
physics.write
fn(world: PhysicsWorld, body: i32, x: f32, y: f32, z: f32) -> void
Move a body outright. A teleport rather than a push: the broadphase moves with it.
wake
physics.write
fn(world: PhysicsWorld, body: i32) -> void
Wake a body and everything sharing its island, because a sleeping neighbour would settle it again.
setGravity
physics.write
fn(world: PhysicsWorld, x: f32, y: f32, z: f32) -> void
The world's gravity, in metres per second squared.
drift/random 3
unit
puredeterministic
fn(seed: u32) -> f32
A value from 0 to 1 for a seed. The same seed always gives the same value.
range
puredeterministic
fn(seed: u32, low: f32, high: f32) -> f32
A value between two bounds for a seed.
index
puredeterministic
fn(seed: u32, count: u32) -> u32
An index into a collection of `count` items. Zero for an empty one.
drift/render 10
bloom
scene.write
fn(renderer: Renderer, scale: f32) -> void
How much of the frame's bloom ceiling to take, 0 to 1. Held until changed. Does nothing when the quality profile's `bloom` is 0, because the chain is never built.
bloomAbove
scene.write
fn(renderer: Renderer, scale: f32, threshold: f32) -> void
How much of the bloom ceiling to take, 0 to 1, and how bright a pixel must be before it blooms, in scene units, above 0. Both held until changed. The threshold is compared before exposure, so a script that moves `exposure` through a day moves this with it: pass the brightness wanted on screen over the exposure, or sunlit stone blooms at noon and lamps never do at night.
exposure
scene.write
fn(renderer: Renderer, stops: f32) -> void
How far this frame is scaled into the tone curve, above 0. Replaces the profile's `outputExposure` for this frame onward. Adaptation is yours: a game knows it walked into a cave, and the renderer could only find out a frame late. Ignored where the output transform is `none` or `srgb`, since there is then no curve to be exposed into.
filmic
scene.write
fn(renderer: Renderer, slope: f32, toe: f32, shoulder: f32, blackClip: f32, whiteClip: f32) -> void
The `filmic` output transform's curve, held until changed: the straight segment's slope through mid grey, how much of the curve the toe and the shoulder take (0 to 1), and how far black and white clip past their ends (0 to 1). The engine defaults are 0.88, 0.55, 0.26, 0 and 0.04. Mid grey stays mid grey whatever they are. A number out of range is clamped into it. Ignored unless the quality profile's output transform is `filmic`.
motionBlur
scene.write
fn(renderer: Renderer, scale: f32) -> void
How much of the camera motion blur ceiling this frame takes, 0 to 1. Held until changed. Ramp it with whatever "fast" means here: blur that is always on stops being a speed cue within seconds and costs eight taps a moving pixel while doing so.
speedBlur
scene.write
fn(renderer: Renderer, strength: f32) -> void
How much speed blur the frame resolves with, 0 to 1. Held until changed, and ignored when screen effects are off.
focus
scene.write
fn(renderer: Renderer, distance: f32, range: f32, scale: f32) -> void
Where this frame's lens is focused and how deep the sharp zone is, in metres, and how much of the depth-of-field ceiling to take, 0 to 1. Held until changed. `scale` is required here though the engine defaults it to 1, because taking the whole ceiling is the expensive answer and a script author is further from that cost than a TypeScript caller.
occlusionFade
scene.write
fn(renderer: Renderer, distance: f32, radius: f32) -> void
Where ambient occlusion fades out with distance: whole up to `distance` metres from the eye and gone `radius` metres past it, so far scenery and a distant sky are not shaded in rings that follow the depth buffer. A negative distance is no fade, the default. Held until changed. Does nothing when the quality profile's `ambientOcclusion` is 0.
medium
scene.write
fn(renderer: Renderer, density: f32, albedo: f32, anisotropy: f32, maxDistance: f32) -> void
How thick the air is: a medium filling the whole frustum, rather than a beam inside a hull. `density` is extinction per metre and 0 is off — nothing is allocated and nothing is drawn, so a script that never raises it costs nothing. `albedo` is how much of what the air takes out comes back as light rather than heat, 0 to 1; `anisotropy` is -1 back to 1 forward, and is what makes haze glow toward a low sun; `maxDistance` is where the search for light to scatter stops, in metres, which is not where the fog stops. Held until changed. Does nothing when the quality profile's `globalMediumSteps` is 0, because no march is built.
veil
scene.write
fn(renderer: Renderer, red: f32, green: f32, blue: f32, alpha: f32) -> void
Composite a flat colour over the finished frame, for a cut dipping to white or to black. **Once per frame: a frame that does not call this draws with no veil at all**, unlike the dials above, because a transition that forgets to turn itself off is worse than one that forgets to turn on.
drift/rollback 6
tick
nondeterministic
fn(rewind: Rewind) -> i32
The last tick that was stepped, or -1 before the first.
isReplaying
nondeterministic
fn(rewind: Rewind) -> bool
Whether this tick is being re-run to correct a mispredicted one. Anything that should not happen twice — a sound, a particle, a message — asks this first.
depth
nondeterministic
fn(rewind: Rewind) -> i32
How many ticks back a rewind can reach. Eight at 60 Hz is 133 milliseconds of correction.
earliest
nondeterministic
fn(rewind: Rewind) -> i32
The oldest tick still retained, or -1. An input older than this cannot be applied and the session cannot be made correct.
replays
nondeterministic
fn(rewind: Rewind) -> i32
How many rewinds have happened. A session correcting constantly has a link problem.
replayedTicks
nondeterministic
fn(rewind: Rewind) -> i32
How many ticks those rewinds re-ran in total. Divided by `replays`, the average depth of a correction.
drift/scene 11
positionX
scene.readdeterministic
fn(node: Node) -> f32
A node's local x.
positionY
scene.readdeterministic
fn(node: Node) -> f32
A node's local y.
positionZ
scene.readdeterministic
fn(node: Node) -> f32
A node's local z.
setPosition
scene.write
fn(node: Node, x: f32, y: f32, z: f32) -> void
Move a node, marking it and its subtree for a world update.
setScale
scene.write
fn(node: Node, x: f32, y: f32, z: f32) -> void
Scale a node.
setRotation
scene.write
fn(node: Node, x: f32, y: f32, z: f32, radians: f32) -> void
Rotate a node about an axis.
windDirectionX
scene.readdeterministic
fn(wind: Wind) -> f32
The prevailing wind's x, normalised; zero when there is no wind to have a direction.
windDirectionZ
scene.readdeterministic
fn(wind: Wind) -> f32
The prevailing wind's z, normalised; zero when there is no wind to have a direction.
windSpeed
scene.readdeterministic
fn(wind: Wind) -> f32
How hard it is blowing, metres a second, never negative.
windGust
scene.readdeterministic
fn(wind: Wind) -> f32
The gust alone, -1 to 1, for a behaviour that wants the deviation and not the total.
distance
scene.readdeterministic
fn(a: Node, b: Node) -> f32
The distance between two nodes, in local space.
drift/terrain 8
heightAt
physics.readdeterministic
fn(terrain: Terrain, x: float, z: float) -> float
How high the ground is at a place, in metres. The surface that is drawn, not an approximation of it, so a thing put here stands on what you can see.
normalX
physics.readdeterministic
fn(terrain: Terrain, x: float, z: float) -> float
Which way the ground faces at a place, along x.
normalY
physics.readdeterministic
fn(terrain: Terrain, x: float, z: float) -> float
The same, along y. One on the flat and smaller on a slope.
normalZ
physics.readdeterministic
fn(terrain: Terrain, x: float, z: float) -> float
The same, along z.
slopeAt
physics.readdeterministic
fn(terrain: Terrain, x: float, z: float) -> float
How steep the ground is at a place, in radians from flat. Zero on the level; a quarter turn on a wall.
covers
physics.readdeterministic
fn(terrain: Terrain, x: float, z: float) -> bool
Whether a place is over the field at all. A query outside it answers the nearest edge rather than nothing, so ask this first where it matters.
extentX
physics.readdeterministic
fn(terrain: Terrain) -> f32
How far the field reaches along x, in metres.
extentZ
physics.readdeterministic
fn(terrain: Terrain) -> f32
How far the field reaches along z, in metres.
drift/time 4
fixedDelta
clock.read
fn() -> f32
The fixed simulation step, in seconds. Prefer the `dt` your function was given.
frameDelta
clock.read
fn() -> f32
Seconds since the previous rendered frame, after clamping.
wallDelta
clock.read
fn() -> f32
Seconds of real time since the previous frame, unclamped. Outside the boundary in every sense.
elapsed
clock.read
fn() -> f32
Seconds since the loop started.
drift/ui 18
layout
scene.write
fn(tree: UiTree, x: f32, y: f32, w: f32, h: f32) -> void
Lay the tree out into a box. The box is what is available: a tree sized by its contents comes to what its contents come to.
draw
scene.write
fn(tree: UiTree, batch: SpriteBatch, white: i32) -> i32
Put the tree in a batch and answer how many quads that was. `white` is the sprite pass's own white slot, which is what a background is drawn on.
has
scene.readdeterministic
fn(tree: UiTree, name: String) -> bool
Whether the tree holds a node of this name. Every reader below answers a defined value without it, so this is for a script that wants to know rather than one that would crash.
left
scene.readdeterministic
fn(tree: UiTree, name: String) -> f32
Where a node ended up, along x. Zero for a name the tree does not hold.
top
scene.readdeterministic
fn(tree: UiTree, name: String) -> f32
The same, along y.
width
scene.readdeterministic
fn(tree: UiTree, name: String) -> f32
How wide a node ended up.
height
scene.readdeterministic
fn(tree: UiTree, name: String) -> f32
How tall a node ended up.
visible
scene.readdeterministic
fn(tree: UiTree, name: String) -> bool
Whether a node is shown. A hidden node is out of the layout and out of the hit test, not merely invisible.
show
scene.write
fn(tree: UiTree, name: String, visible: bool) -> void
Show or hide a node and everything under it.
setText
scene.write
fn(tree: UiTree, name: String, text: String) -> void
Change what a node says. What draws it is the caller's: this package draws quads, and core already draws two kinds of text.
tint
scene.write
fn(tree: UiTree, name: String, r: f32, g: f32, b: f32, a: f32) -> void
Change a node's background colour, given as picked for the screen: sRGB, 0 to 1, decoded here to the linear light the renderer draws, as a theme's hex token is. Alpha is coverage and is kept as given. A node with no background gets one.
hovered
input.read
fn(tree: UiTree, name: String) -> bool
Whether the pointer is over a node.
pressed
input.read
fn(tree: UiTree, name: String) -> bool
Whether the pointer went down on a node and has not come up.
focused
input.read
fn(tree: UiTree, name: String) -> bool
Whether a node has the keyboard.
point
input.readscene.write
fn(tree: UiTree, x: f32, y: f32, down: bool) -> bool
Route the pointer, and answer whether this call activated anything. An activation is a press and a release on the same node, so somebody who pressed the wrong button can slide off it.
activated
input.read
fn(tree: UiTree, name: String) -> bool
Whether the last `point` activated this node. Read it in the same step that called `point`; the next one clears it.
key
input.readscene.write
fn(tree: UiTree, key: String, shift: bool) -> bool
Route a key, and answer whether it activated what has focus. Tab moves focus, Enter and space activate, and everything else is reported unhandled so the caller can have it.
focus
scene.write
fn(tree: UiTree, name: String) -> void
Give a node the keyboard. A name the tree does not hold focuses nothing.
drift/xr 12
presenting
scene.read
fn() -> bool
Whether a session is running. False before one starts and after the user takes the headset off.
supported
scene.read
fn() -> bool
Whether this device could present at all. False on a machine with no headset attached.
headX
input.read
fn() -> f32
Where the viewer’s head is, in metres. Zero outside a session.
headY
input.read
fn() -> f32
Where the viewer’s head is, in metres. Zero outside a session.
headZ
input.read
fn() -> f32
Where the viewer’s head is, in metres. Zero outside a session.
trigger
input.read
fn(hand: Hand) -> f32
How far a hand’s trigger is pulled, 0 to 1. Zero for a hand that is not there.
squeeze
input.read
fn(hand: Hand) -> f32
How far a hand’s grip is squeezed, 0 to 1. Zero for a hand that is not there.
holding
input.read
fn(hand: Hand) -> bool
Whether a hand is tracked this frame. False while a controller is set down or out of view.
jointX
input.read
fn(hand: Hand, joint: HandJoint) -> f32
Where a hand joint is, in metres. Zero for a joint that is not tracked.
jointY
input.read
fn(hand: Hand, joint: HandJoint) -> f32
Where a hand joint is, in metres. Zero for a joint that is not tracked.
jointZ
input.read
fn(hand: Hand, joint: HandJoint) -> f32
Where a hand joint is, in metres. Zero for a joint that is not tracked.
pinching
input.read
fn(hand: Hand) -> bool
Whether a hand’s thumb and index tips are close enough to count as a pinch.