Log inGet started

globals

The globals namespace — the engine's Luau API reference for globals.

The globals namespace — 774 functions.

globals/ColorSequence/deserialize

globals/ColorSequence/deserialize(data: any) -> ColorSequenceObj

Rebuild a ColorSequence from a {kind = "ColorSequence", keypoints = {...}} payload produced by :serialize(). Used by scene save/load.

globals/ColorSequence/new

globals/ColorSequence/new(...: any) -> ColorSequenceObj

Construct a ColorSequence from one of three signatures: a constant color (3-array {r,g,b} or {r=,g=,b=} record), a two-point lerp from c0 to c1, or a keypoints array. envelope is optional and may be a single number (broadcast across channels) or a 3-array. Up to 64 keypoints; the first must anchor at time = 0, the last at time = 1. NaN / Inf rejected.

globals/Entity

Entity: any

Entity wrapper namespace — auto-injected by the prelude from @builtin::modules.entity_reflect. Also reachable as the lowercase entity(...) proxy constructor.

globals/Entity/allTypes

globals/Entity/allTypes() -> { string }

List all registered reflectable component types in this engine instance.

globals/Entity/distance

globals/Entity/distance(entityIdA: string, entityIdB: string) -> number?

Compute the straight-line distance between two entities' Transform.position fields.

globals/Entity/getComponents

globals/Entity/getComponents(entityId: string) -> { string }?

List all reflected component types on an entity.

globals/Entity/getField

globals/Entity/getField(entityId: string, component: string, field: string) -> any

Get a specific component field value via the __reflect FFI.

globals/Entity/getName

globals/Entity/getName(entityId: string) -> string?

Get the name of an entity from its Name component.

globals/Entity/getPosition

globals/Entity/getPosition(entityId: string) -> Vec3?

Get the position of an entity — shortcut for getField(id, "Transform", "position").

globals/Entity/getRotation

globals/Entity/getRotation(entityId: string) -> Quat?

Get the rotation of an entity — shortcut for getField(id, "Transform", "rotation").

globals/Entity/getScale

globals/Entity/getScale(entityId: string) -> Vec3?

Get the scale of an entity — shortcut for getField(id, "Transform", "scale").

globals/Entity/getSchema

globals/Entity/getSchema(componentName: string) -> { ComponentFieldSchema }?

Get the full schema of a component type — field names + types.

globals/Entity/isVisible

globals/Entity/isVisible(entityId: string) -> boolean

Check if an entity is visible — reads the Visible component. Missing component is treated as visible.

globals/Entity/patch

globals/Entity/patch(entityId: string, component: string, fields: { [string]: any }) -> boolean

Patch multiple fields on a single component at once.

globals/Entity/setField

globals/Entity/setField(entityId: string, component: string, field: string, value: any) -> boolean

Set a specific component field value via the __reflect FFI.

globals/Entity/setPosition

globals/Entity/setPosition(entityId: string, pos: Vec3)

Set the position of an entity — shortcut for setField(id, "Transform", "position", pos).

globals/Entity/setScale

globals/Entity/setScale(entityId: string, scale: Vec3)

Set the scale of an entity — shortcut for setField(id, "Transform", "scale", scale).

globals/Entity/snapshot

globals/Entity/snapshot(entityId: string) -> any

Snapshot all reflected components on an entity into a { ComponentName = { field = value, ... }, ... } map.

globals/Field/alias

globals/Field/alias(target: string | { string }) -> FieldDesc<any>

globals/Field/assetRef

globals/Field/assetRef(category: C & string, default: AssetRef<C> | string | nil, mode: SyncMode, marker: SerializedMode?) -> FieldDesc<AssetRef<C>>

globals/Field/bool

globals/Field/bool(default: boolean, mode: SyncMode, marker: SerializedMode?) -> FieldDesc<boolean>

Boolean field. Default must be a boolean.

globals/Field/color

globals/Field/color(default: color, mode: SyncMode, marker: SerializedMode?) -> FieldDesc<color>

Color field. Default is a color — either {r = .., g = .., b = .., a = ..?} or {r, g, b, a?}.

globals/Field/componentRef

globals/Field/componentRef(componentType: T & string, default: ComponentRef<T> | nil, mode: SyncMode, marker: SerializedMode?) -> FieldDesc<ComponentRef<T>>

Typed component reference field. T is the component-type name — a singleton string type inferred from the componentType argument ("Camera", "Transform", "@user/Inventory"). The engine validates the referent exists and is of the declared type at every write.

globals/Field/dataRef

globals/Field/dataRef(contract: C & string, default: AssetRef<"data"> | string | nil, mode: SyncMode, marker: SerializedMode?) -> FieldDesc<AssetRef<"data">>

Contract-constrained typed-data reference field. Accepts only .data assets whose dataType contract chain includes contract. Rides the assetRef machinery (category "data") — dependency graph, sync, and rehydration behave exactly like Field.assetRef — with the contract gate enforced through the generic field-constraint hook on every write and on the registration-time default.

globals/Field/entityRef

globals/Field/entityRef(default: EntityRef | string | nil, mode: SyncMode, marker: SerializedMode?) -> FieldDesc<EntityRef>

Entity reference field. Accepts a live entity proxy (EntityRef), a raw entity-id string, or nil (no target). Writes are normalised to the plain id string for storage/replication; reads return a live EntityRef proxy (or nil), so public.<field>:method() and public.<field>.id work directly without re-resolving.

globals/Field/list

globals/Field/list(element: FieldDesc<any>, mode: SyncMode, marker: SerializedMode?) -> FieldDesc<ListValue>

List field — an array of one repeated element type. The element is the Field constructor descriptor every item conforms to, often a Field.struct for a list of records. The list value is an array of the element's value type. Like Field.struct, the engine descends the element schema to resolve nested asset refs into envelopes, so a stack of structs each holding an asset ref has every ref appear in the asset dependency graph, validates each item, and the LSP type-checks the array. The default value is an empty list. The element declares its own Sync or NoSync for typing; the list's own mode governs replication of the whole array as a unit.

globals/Field/number

globals/Field/number(default: number, mode: SyncMode, marker: SerializedMode?) -> FieldDesc<number>

Number field. Default must be a number.

globals/Field/quat

globals/Field/quat(default: quat, mode: SyncMode, marker: SerializedMode?) -> FieldDesc<quat>

Quaternion field. Default is a quat — either {x = .., y = .., z = .., w = ..} or {x, y, z, w}.

globals/Field/resource

globals/Field/resource(category: C & string, default: AssetRef<C> | Handle<C> | string | nil, mode: SyncMode, marker: SerializedMode?) -> FieldDesc<AssetRef<C> | Handle<C>>

Category-gated RESOURCE field — accepts EITHER a persistent AssetRef<C> OR a live GPU Handle<C>, gated by category. This is the renderer-facing field type (e.g. Model.model, Model.material, material texture slots): content can author a persistent asset OR pass a runtime handle (renderer.<resource>.create(...)); the component bridges either to the GPU resource. The category gate still holds — an AssetRef<audio> or a wrong-category handle (a TextureHandle on a "mesh" slot) is a type error AND a runtime rejection. Use Field.assetRef instead when the field MUST be a persistent asset (handles rejected). With Sync, persistent-asset values replicate to peers; a live GPU handle value is local by construction and stays local — peers keep the last replicated asset value.

globals/Field/string

globals/Field/string(default: string, mode: SyncMode, marker: SerializedMode?) -> FieldDesc<string>

String field. Default must be a string.

globals/Field/struct

globals/Field/struct(schema: FieldSchema, mode: SyncMode, marker: SerializedMode?) -> FieldDesc<StructValue>

Struct field — a table whose keys are themselves typed fields. The schema maps each subfield name to its Field constructor descriptor; the struct value is a table holding one value per subfield. Use this instead of Field.table when the table carries asset references or other typed data: the engine descends the schema to resolve nested asset refs into envelopes at registration and at write time, so they appear in the asset dependency graph, validates writes per subfield, and the LSP type-checks the shape. Each subfield declares its own Sync or NoSync for typing; the struct's own mode governs replication of the whole value as a unit.

globals/Field/table

globals/Field/table(default: T, mode: SyncMode, marker: SerializedMode?) -> FieldDesc<T>

Generic table field. T is the table's shape — usually inferred from the default value, or supplied explicitly via an explicit ascription Field.table({} :: MyShape, mode) when the default doesn't cover every key the runtime will write. The engine accepts any Luau table as a value at write time; per-shape enforcement is opt-in static typing only.

globals/Field/vec2

globals/Field/vec2(default: vec2, mode: SyncMode, marker: SerializedMode?) -> FieldDesc<vec2>

Vec2 field. Default is a vec2 — either {x = .., y = ..} or the 2-element array form {x, y}.

globals/Field/vec3

globals/Field/vec3(default: vec3, mode: SyncMode, marker: SerializedMode?) -> FieldDesc<vec3>

Vec3 field. Default is a vec3 — either {x = .., y = .., z = ..} or the 3-element array form {x, y, z}.

globals/Material

Material: any

Material helpers namespace — auto-injected by the prelude from @builtin::modules.material_utils.

globals/Material/Apply

globals/Material/Apply(entityId: string, materialRef: MaterialRefOrName) -> boolean

PascalCase back-compat alias for apply.

globals/Material/Create

globals/Material/Create(name: string, opts_or_shader: MaterialOpts | string | nil, props: MaterialOpts?) -> MaterialRef?

PascalCase back-compat alias for create. Accepts the legacy 3-arg form (name, shader_string, opts_table) by folding shader into opts, and the canonical 2-arg form (name, opts).

globals/Material/Exists

globals/Material/Exists(name: MaterialRefOrName) -> boolean

PascalCase back-compat alias for exists.

globals/Material/GetProperty

globals/Material/GetProperty(materialName: MaterialRefOrName, propertyName: string) -> any

PascalCase back-compat alias for getProperty.

globals/Material/GetPropertyNames

globals/Material/GetPropertyNames(materialName: MaterialRefOrName) -> { string }?

PascalCase back-compat alias for getPropertyNames.

globals/Material/SetProperty

globals/Material/SetProperty(materialName: MaterialRefOrName, property: string, value: any) -> any

PascalCase alias. Writes the property on the material ASSET by name/ref (persists into its mat.yaml, affecting every entity using it) — distinct from M.setProperty, which targets the material on one entity's model.

globals/Material/SetTexture

globals/Material/SetTexture(materialName: MaterialRefOrName, slot: string, textureRef: string) -> boolean

PascalCase back-compat alias for setTexture.

globals/Material/apply

globals/Material/apply(entity: any, materialRef: MaterialRefOrName) -> boolean

Apply a material to an entity's Model / SkinnedModel component by setting its material field. Accepts either an AssetRef envelope (from Material.create) or a bare material-name string. Errors when the entity has no Model or SkinnedModel — a material only renders where there is a mesh.

globals/Material/create

globals/Material/create(name: string, opts: MaterialOpts?) -> MaterialRef?

Create a named material in the MaterialRegistry. Returns the canonical AssetRef envelope ({ __ref, type="material", name, guid }) — pass directly to Material.apply, the Model / SkinnedModel material field, or any AssetRef<material> consumer.

globals/Material/exists

globals/Material/exists(name: MaterialRefOrName) -> boolean

Check whether a material exists in the registry. Accepts an AssetRef envelope or a bare material name.

globals/Material/getProperty

globals/Material/getProperty(materialName: MaterialRefOrName, propertyName: string) -> any

Read the current value of a material property.

globals/Material/getPropertyNames

globals/Material/getPropertyNames(materialName: MaterialRefOrName) -> { string }?

List the property names exposed by a registered material.

globals/Material/setProperty

globals/Material/setProperty(target: any, property: string, value: any)

Set a material property. Addresses the target the same way getProperty does: pass a material name / AssetRef to write the material ASSET (affecting every entity using it), or an entity proxy / id to write the material bound to that entity's Model / SkinnedModel. Errors when an entity target has no Model or SkinnedModel.

globals/Material/setTexture

globals/Material/setTexture(materialName: MaterialRefOrName, slot: string, textureRef: any) -> boolean

Set a texture slot on a named material.

globals/NumberRange/new

globals/NumberRange/new(min: number, max: number?) -> any

Construct a NumberRange. Pass one number for a constant range (min == max); pass two for a uniform random range. Reversed arguments are normalized to ascending order.

globals/NumberSequence/deserialize

globals/NumberSequence/deserialize(data: any) -> NumberSequenceObj

Rebuild a NumberSequence from a {kind = "NumberSequence", keypoints = {...}} payload produced by :serialize(). Used by scene save/load.

globals/NumberSequence/new

globals/NumberSequence/new(...: any) -> NumberSequenceObj

Construct a NumberSequence from one of three signatures: a constant value, a two-point lerp from v0 to v1, or a keypoints array of { time, value, envelope? } records. Envelope defaults to 0 when omitted. Up to 64 keypoints; the first must anchor at time = 0, the last at time = 1. NaN / Inf in time / value / envelope is rejected.

globals/Physics

Physics: any

Physics namespace — collisions, joints, raycasts, body manipulation. Auto-injected by the prelude from @builtin::modules.physics_utils. Same table as the lowercase physics alias.

globals/Physics/addCollider

globals/Physics/addCollider(entityId: string, config: table)

Add a Collider component to an entity.

globals/Physics/addConstraint

globals/Physics/addConstraint(entityId: string, opts: table?)

Add a transform constraint to an entity.

globals/Physics/addJoint

globals/Physics/addJoint(entityIdA: string, entityIdB: string, opts: table?)

Add a Joint component connecting two entities. Accepts either vec3-style anchor inputs (localAnchor = {x,y,z}) or pre-split scalar keys (localAnchorX/Y/Z).

globals/Physics/addVelocity

globals/Physics/addVelocity(a: string | number | vec3, b: (number | vec3)?, c: number?, d: number?)

Add to the linear velocity of an entity. Same call shapes as setVelocity.

globals/Physics/addWheelCollider

globals/Physics/addWheelCollider(entityId: string, config: table?)

Add a WheelCollider to an entity. The entity must be a child (or descendant) of a rigid body — the system walks up the hierarchy to find the Physics component.

globals/Physics/applyForce

globals/Physics/applyForce(entityIdOrForce: string | vec3, force: vec3?)

Apply a force to an entity's rigid body for the next physics step — call every frame for continuous thrust. With one argument the script-context entity is targeted; with two args the explicit entity id wins.

globals/Physics/applyForceAtPoint

globals/Physics/applyForceAtPoint(entityId: string, force: vec3, point: vec3)

Apply a force at a specific world-space point — generates the matching torque from the lever arm.

globals/Physics/applyImpulse

globals/Physics/applyImpulse(entityIdOrImpulse: string | vec3, impulse: vec3?)

Apply an instantaneous impulse (one-shot velocity change). With one argument the script-context entity is targeted; with two args the explicit entity id wins.

globals/Physics/applyTorque

globals/Physics/applyTorque(entityIdOrTorque: string | vec3, torque: vec3?)

Apply a torque to an entity's rigid body for the next physics step — call every frame for continuous spin-up. With one argument the script-context entity is targeted; with two args the explicit entity id wins.

globals/Physics/boxCast

globals/Physics/boxCast(origin: vec3, halfExtents: vec3, direction: vec3, maxDistance: number?) -> table?

Cast a box along a direction and return the first hit.

globals/Physics/colliderShapes

globals/Physics/colliderShapes(entityId: string) -> table

Read an entity's resolved physics collider shape(s) — box half-extents, sphere/capsule radius, or convex line points — as the physics engine sees them, including auto-sized colliders.

globals/Physics/getAngularVelocity

globals/Physics/getAngularVelocity(entityId: string?) -> vec3?

Read the angular velocity of an entity's rigid body.

globals/Physics/getGravity

globals/Physics/getGravity() -> vec3

Read the current world gravity vector.

globals/Physics/getVelocity

globals/Physics/getVelocity(entityId: string?) -> vec3?

Read the linear velocity of an entity's rigid body.

globals/Physics/getWheelState

globals/Physics/getWheelState(entityId: string) -> table?

Read a wheel collider's runtime state. Reads the native component the wheel system writes after each physics step.

globals/Physics/hasLineOfSight

globals/Physics/hasLineOfSight(fromId: string, toId: string) -> boolean

Check whether two entities have line-of-sight between their origins.

globals/Physics/ignoreCollision

globals/Physics/ignoreCollision(entityIdA: string, entityIdB: string, ignore: boolean?)

Toggle ignored-collision state between two specific entities.

globals/Physics/isSleeping

globals/Physics/isSleeping(entityId: string?) -> boolean?

Whether an entity's rigid body is currently asleep (at rest and not simulating). A body sleeps once it stops moving, to save simulation cost.

globals/Physics/overlapSphere

globals/Physics/overlapSphere(center: vec3, radius: number) -> table

Find every entity id whose colliders overlap a sphere.

globals/Physics/raycast

globals/Physics/raycast(origin: vec3, direction: vec3, maxDistance: number?, exclude: (string | {string})?) -> table?

Cast a ray and return the first hit.

globals/Physics/raycastAll

globals/Physics/raycastAll(origin: vec3, direction: vec3, maxDistance: number?, maxHits: number?, exclude: (string | {string})?) -> table

Cast a ray and return every hit up to maxHits.

globals/Physics/raycastBetween

globals/Physics/raycastBetween(fromId: string, toId: string, maxDistance: number?) -> table?

Cast a ray from one entity toward another and return the first hit.

globals/Physics/raycastScreen

globals/Physics/raycastScreen(sx: number, sy: number, maxDistance: number?, exclude: (string | {string})?) -> table?

Cast a ray from a screen pixel into the scene and return the first hit. Unprojects the pixel with screenToRay, then casts with raycast.

globals/Physics/removeCollider

globals/Physics/removeCollider(entityId: string)

Remove the Collider component from an entity (if present).

globals/Physics/removeConstraint

globals/Physics/removeConstraint(entityId: string, index: number?)

Remove transform constraints from an entity (if any are present).

globals/Physics/removeJoint

globals/Physics/removeJoint(entityId: string)

Remove the Joint component from an entity (if present).

globals/Physics/removeWheelCollider

globals/Physics/removeWheelCollider(entityId: string)

Remove the WheelCollider component from an entity (if present).

globals/Physics/setAngularDamping

globals/Physics/setAngularDamping(entityIdOrDamping: string | number, damping: number?)

Set angular damping on an entity's rigid body. One-arg form targets the script-context entity.

globals/Physics/setAngularVelocity

globals/Physics/setAngularVelocity(a: string | number | vec3, b: (number | vec3)?, c: number?, d: number?)

Set the angular velocity of an entity (radians/sec). Same call shapes as setVelocity.

globals/Physics/setBodyType

globals/Physics/setBodyType(entityId: string, bodyType: string)

Change a rigid body's type at runtime. Mass, colliders, and joints are preserved — only the body's response to forces and position writes changes.

globals/Physics/setCcdEnabled

globals/Physics/setCcdEnabled(entityIdOrEnabled: string | boolean, enabled: boolean?)

Enable or disable continuous collision detection on an entity's rigid body. One-arg form targets the script-context entity.

globals/Physics/setCollisionGroups

globals/Physics/setCollisionGroups(entityId: string, membership: number, filter: number)

Set the collision-group membership and filter bitmasks on an entity's colliders. Adds a CollisionGroup component if missing.

globals/Physics/setGravity

globals/Physics/setGravity(gravity: vec3)

Replace the world gravity vector.

globals/Physics/setGravityScale

globals/Physics/setGravityScale(entityIdOrScale: string | number, scale: number?)

Set the per-entity gravity scale (1.0 = normal, 0.0 = no gravity). One-arg form targets the script-context entity.

globals/Physics/setJointMotor

globals/Physics/setJointMotor(entityId: string, targetVelocity: number, maxForce: number)

Set a motor on an entity's joint.

globals/Physics/setLinearDamping

globals/Physics/setLinearDamping(entityIdOrDamping: string | number, damping: number?)

Set linear damping on an entity's rigid body (0 = no damping). One-arg form targets the script-context entity.

globals/Physics/setMass

globals/Physics/setMass(entityIdOrMass: string | number, mass: number?)

Set the mass of an entity's rigid body (kg). One-arg form targets the script-context entity.

globals/Physics/setRotationLocks

globals/Physics/setRotationLocks(entityId: string, x: boolean, y: boolean, z: boolean)

Lock or unlock rotation on specific axes.

globals/Physics/setTranslationLocks

globals/Physics/setTranslationLocks(entityId: string, x: boolean, y: boolean, z: boolean)

Lock or unlock translation on specific axes.

globals/Physics/setVelocity

globals/Physics/setVelocity(a: string | number | vec3, b: (number | vec3)?, c: number?, d: number?)

Set the linear velocity of an entity. Accepts (x, y, z) or a {x, y, z} vector for the script-context entity, or the same prefixed with an explicit entityId.

globals/Physics/sphereCast

globals/Physics/sphereCast(origin: vec3, radius: number, direction: vec3, maxDistance: number?) -> table?

Cast a sphere along a direction and return the first hit.

globals/Physics/wakeUp

globals/Physics/wakeUp(entityId: string?)

Wake an entity's sleeping rigid body so it resumes simulating. The motion setters (applyImpulse, setVelocity, setAngularVelocity) wake the body for you; call this to wake one explicitly.

globals/Transform

Transform: any

Transform helpers namespace — auto-injected by the prelude from @builtin::modules.transform.

globals/Transform/direction

globals/Transform/direction(fromX: number, fromY: number, fromZ: number, toX: number, toY: number, toZ: number) -> (number, number, number)

Normalized direction vector from point A to point B. Returns zeros when the two points coincide (within ~0.001 units).

globals/Transform/directionBetween

globals/Transform/directionBetween(entityA: EntityRef, entityB: EntityRef) -> (number, number, number)

Normalized direction from one entity to another. Returns zeros if either entity can't be resolved.

globals/Transform/distance

globals/Transform/distance(x1: number, y1: number, z1: number, x2: number, y2: number, z2: number) -> number

Euclidean distance between two world-space positions.

globals/Transform/distanceBetween

globals/Transform/distanceBetween(entityA: EntityRef, entityB: EntityRef) -> number?

Distance between two entities in world space.

globals/Transform/euler

globals/Transform/euler(qx: number, qy: number, qz: number, qw: number) -> (number, number, number)

Convert quaternion to euler angles (yaw, pitch, roll) in radians.

globals/Transform/eulerToQuat

globals/Transform/eulerToQuat(yaw: number, pitch: number?, roll: number?) -> (number, number, number, number)

Identity-aware overload of euler-to-quaternion. Uses the negative-yaw convention shared with quatFromYaw, quatFromYawPitch, lookAtQuat, and T.euler extraction — so T.euler(T.eulerToQuat(y, p, r)) returns (y, p, r). Order is yaw (Y) then pitch (X) then roll (Z).

globals/Transform/lerp

globals/Transform/lerp(ax: number, ay: number, az: number, bx: number, by: number, bz: number, t: number) -> (number, number, number)

Linearly interpolate between two positions.

globals/Transform/lerp1

globals/Transform/lerp1(a: number, b: number, t: number) -> number

Linearly interpolate two scalars.

globals/Transform/lerpAngle

globals/Transform/lerpAngle(a: number, b: number, t: number) -> number

Lerp between two angles via the shortest arc; returns a value in [-pi, pi].

globals/Transform/localToWorld

globals/Transform/localToWorld(px: number, py: number, pz: number, pqx: number, pqy: number, pqz: number, pqw: number, lx: number, ly: number, lz: number) -> (number, number, number)

Transform a local-space position into world space using a parent pose.

globals/Transform/lookAt

globals/Transform/lookAt(entityOrId: EntityRef, txOrTarget: number | string, ty: number?, tz: number?)

Make an entity face a world position. The target slot accepts either three explicit coordinates or an entity id whose position is resolved.

globals/Transform/lookAtQuat

globals/Transform/lookAtQuat(fx: number, fy: number, fz: number, tx: number, ty: number, tz: number) -> (number?, number?, number?, number?)

Compute quaternion to look from origin position toward a target. Returns four components (qx, qy, qz, qw), or nil when the from and to points are too close to derive a meaningful direction.

globals/Transform/normalizeAngle

globals/Transform/normalizeAngle(a: number) -> number

Normalize an angle into [-pi, pi].

globals/Transform/orbit

globals/Transform/orbit(centerX: number, centerY: number, centerZ: number, radius: number, height: number, angle: number) -> (number, number, number, number, number, number, number)

Position + rotation for orbiting around a center point. Returns the world position followed by the orientation that faces the center.

globals/Transform/quatFromAxisAngle

globals/Transform/quatFromAxisAngle(ax: number, ay: number, az: number, angle: number) -> (number, number, number, number)

Create quaternion from axis and angle (radians). Returns the identity quaternion when the axis is degenerate (length < 0.001).

globals/Transform/quatFromYaw

globals/Transform/quatFromYaw(yaw: number) -> (number, number, number, number)

Create quaternion from yaw (Y-axis rotation) in radians. Uses the negative-yaw convention shared with quatFromYawPitch, lookAtQuat, and T.euler extraction — so T.euler(T.quatFromYaw(y)) round-trips to y.

globals/Transform/quatFromYawPitch

globals/Transform/quatFromYawPitch(yaw: number, pitch: number) -> (number, number, number, number)

Create quaternion from yaw and pitch in radians.

globals/Transform/quatIdentity

globals/Transform/quatIdentity() -> (number, number, number, number)

Identity quaternion (0, 0, 0, 1).

globals/Transform/quatInverse

globals/Transform/quatInverse(qx: number, qy: number, qz: number, qw: number) -> (number, number, number, number)

Quaternion inverse. Equal to the conjugate for unit quaternions.

globals/Transform/quatMul

globals/Transform/quatMul(ax: number, ay: number, az: number, aw: number, bx: number, by: number, bz: number, bw: number) -> (number, number, number, number)

Quaternion multiplication: returns qa * qb (composition: rotate by qb then qa).

globals/Transform/quatRotateVec

globals/Transform/quatRotateVec(qx: number, qy: number, qz: number, qw: number, vx: number, vy: number, vz: number) -> (number, number, number)

Rotate a 3-vector by a quaternion.

globals/Transform/quatToEuler

globals/Transform/quatToEuler(qx: number, qy: number, qz: number, qw: number) -> (number, number, number)

Convert quaternion to (yaw, pitch, roll). Alias of euler with the explicit name so callers don't have to remember the order.

globals/Transform/slerp

globals/Transform/slerp(ax: number, ay: number, az: number, aw: number, bx: number, by: number, bz: number, bw: number, t: number) -> (number, number, number, number)

Spherical linear interpolation between two quaternions. Picks the shortest path (flips sign if dot < 0). Falls back to lerp+normalize when the two quats are very close (avoids div-by-zero on near-parallel inputs).

globals/Transform/vec/add

globals/Transform/vec.add(ax: number, ay: number, az: number, bx: number, by: number, bz: number) -> (number, number, number)

Component-wise vec3 addition.

globals/Transform/vec/cross

globals/Transform/vec.cross(ax: number, ay: number, az: number, bx: number, by: number, bz: number) -> (number, number, number)

Cross product a x b.

globals/Transform/vec/dot

globals/Transform/vec.dot(ax: number, ay: number, az: number, bx: number, by: number, bz: number) -> number

Dot product of two vec3s.

globals/Transform/vec/length

globals/Transform/vec.length(x: number, y: number, z: number) -> number

Euclidean length of a vec3.

globals/Transform/vec/normalize

globals/Transform/vec.normalize(x: number, y: number, z: number) -> (number, number, number)

Normalize a vec3. Returns zeros when the input is degenerate (length < 1e-8).

globals/Transform/vec/scale

globals/Transform/vec.scale(x: number, y: number, z: number, s: number) -> (number, number, number)

Component-wise scalar multiplication of a vec3.

globals/Transform/vec/sub

globals/Transform/vec.sub(ax: number, ay: number, az: number, bx: number, by: number, bz: number) -> (number, number, number)

Component-wise vec3 subtraction (a - b).

globals/Transform/worldToLocal

globals/Transform/worldToLocal(px: number, py: number, pz: number, pqx: number, pqy: number, pqz: number, pqw: number, wx: number, wy: number, wz: number) -> (number, number, number)

Transform a world-space position into a parent's local space.

globals/assert

assert(cond, msg?) -> value

Assert condition is truthy. Returns value if true.

globals/asset/add_tag

globals/asset/add_tag(ref: RefArg, tag: string)

Add a tag to the asset's .metadata.tags. Idempotent. Creates the sidecar and the tags array if missing.

globals/asset/categories

globals/asset/categories() -> { string }

List every asset category the engine currently recognises. Use to discover valid type argument values for the rest of asset.*.

globals/asset/containerize

globals/asset/containerize(ref: RefArg, outputName: string) -> string

Copy an asset and every dependency it transitively references into /source/<outputName>.bundle/ with fresh guids. Returns a promise — await(...) it before treating the bundle as ready.

globals/asset/containing

globals/asset/containing(path: string) -> AssetRef?

Walk path's ancestors and return an AssetRef handle for the OUTERMOST category-folder containing it (e.g. main.scene for "/source/scenes/main.scene/scene.json"). Returns nil for paths outside any registered asset type.

globals/asset/create

globals/asset/create(typeName: string, name: string, opts: { [string]: any }?) -> AssetRef

Instance a new asset of an existing type. Runs the type's behavior.luau onCreate(name, opts) hook to produce the asset's files, then writes them under /source/<name>.<type>/. This is the single generic asset-creation API. Refuses to clobber an existing edit-mode asset unless opts.overwrite = true, which re-authors it in place and keeps the existing guid (only the checksum changes). Pairs with asset.exists for content generators that re-run over the same names.

globals/asset/deps

globals/asset/deps(ref: RefArg, type: string?) -> DepsResult

Return the asset's outbound dependency graph — every other asset recorded as a content dependency of it.

globals/asset/describe

globals/asset/describe(typeName: string) -> DescribeResult

The creation contract for an asset type: the parameters its onCreate(name, opts) hook accepts, as data. kind is "schema" (typed contract), "legacy" (untyped opts — anything passes), "none" (template scaffold — takes no opts), or "error" (the type's schema failed to parse; error says why). contract is the human-readable rendering validation errors print.

globals/asset/exists

globals/asset/exists(name: string, typeName: string) -> boolean

Whether an asset named name of type typeName exists in the current mode's store (/source in edit, the runtime fork in play). A plain existence probe — it does NOT resolve a handle or pin a content dependency, so it is safe to call with a COMPUTED name (unlike asset.resolve, whose handle would become a static-pinned dependency).

globals/asset/get_field

globals/asset/get_field(ref: RefArg, key: string) -> any

Read one top-level field from the asset's .metadata.

globals/asset/guid

globals/asset/guid(ref: RefArg, type: string?) -> string

Return the guid for an asset.

globals/asset/has_field

globals/asset/has_field(ref: RefArg, key: string) -> boolean

True when the asset's .metadata carries the named field.

globals/asset/has_tag

globals/asset/has_tag(ref: RefArg, tag: string) -> boolean

True when the asset's .metadata.tags contains tag.

globals/asset/identity

globals/asset/identity(ref: RefArg, type: string?) -> string

Return the canonical identity for an asset.

globals/asset/import

globals/asset/import(path: string) -> string?

Import a raw source file NOW and return the produced asset path (a .bundle for a model, .texture for an image, .audio for a sound, …), or nil if no importer claims it. This is the deterministic, on-demand counterpart to the engine's automatic import-on-write: it runs in the calling task and returns only when the import is complete. Pair it with a quiet write — vfs.write(path, bytes, { quiet = true }) lands the raw bytes without firing the automatic importer, then asset.import(path) imports them under your control, so you can act on the result instead of polling for the import to appear.

globals/asset/inspect

globals/asset/inspect(ref: RefArg, type: string?) -> InspectRecord

Inspect an asset. Resolves ref, builds the common envelope every asset shares (identity, name, guid, source, typeName, typeDefinitionPath, scope, origin, description, tags), then dispatches to the resolved type's ref.inspect(self) (declared on its behavior.luau) for the type-specific detail. A type with no inspect hook leaves detail nil — the envelope alone. A hook that raises leaves detail nil and sets warning with the error text; asset.inspect itself never raises for a resolved ref.

globals/asset/list

globals/asset/list(type_or_opts: (AssetCategory | ListOpts)?, scope: string?, opts: ListOpts?) -> { AssetRef }

List registered assets as resolved AssetRef handles, optionally filtered by type, VFS path, scope, and .metadata fields. Each entry is the same envelope asset.resolve returns (__ref / type / name / guid / identity / path), so it can be passed anywhere an AssetRef is accepted. Accepts the table-only call form asset.list({ type = ..., path = ..., scope = ..., fields = ... }); type takes the same values asset.categories() lists, and path narrows to one VFS subtree (the folder and everything under it). The first positional argument is a path when it starts with /, a type otherwise. A key outside type / path / scope / fields raises. category is the older spelling of type; a table setting both raises. A static (literal) type or path makes the enumeration part of the calling file's content dependencies when it is saved — the set travels with published content, so consumers get at-least the authoring world's assets.

globals/asset/list_field_values

globals/asset/list_field_values(key: string) -> { any }

Distinct values seen for the named field across every asset's .metadata.

globals/asset/list_fields

globals/asset/list_fields() -> { string }

Distinct top-level field keys observed across every asset's .metadata. Useful for tooling discovering custom keys in use.

globals/asset/meta

globals/asset/meta(ref: RefArg, type: string?) -> AssetMeta

Read the asset's engine-owned identity record (guid / checksum). Distinct from .metadata (agent-editable); for that use asset.metadata.

globals/asset/metadata

globals/asset/metadata(ref: RefArg, type: string?) -> AssetMeta

Read the asset's agent-editable .metadata sidecar as a Lua table. Missing sidecar returns {}. Distinct from asset.meta (engine-owned).

globals/asset/preview

globals/asset/preview(ref: RefArg, opts: { [string]: any }?, type: string?) -> { [string]: any }

Render a preview of an asset. Resolves the ref and dispatches to its type's preview ref-method when present; otherwise returns the { available = false } sentinel ("no preview available for this type").

globals/asset/ref

globals/asset/ref(ref: RefArg, type: string?) -> AssetRef?

Build a reference handle for an asset — the canonical ref envelope constructor. Identical shape to asset.resolve; preferred name for the author-side use case (embedding refs in YAML / JSON / Luau output).

globals/asset/remove_field

globals/asset/remove_field(ref: RefArg, key: string)

Remove one top-level field from the asset's .metadata. No-op when the field isn't present.

globals/asset/remove_tag

globals/asset/remove_tag(ref: RefArg, tag: string)

Remove a tag from the asset's .metadata.tags. No-op when the tag isn't present.

globals/asset/resolve

globals/asset/resolve(ref: RefArg, type: string?) -> AssetRef?

Find an asset. The returned handle carries every name form the asset has (guid, identity, path, type) so downstream code can read any one of them without calling resolve again. Raises when ref resolves to no asset — or, with a type, to no asset of that type — and when a bare no-type name is ambiguous across categories (it never silently prefers one category). For a presence check that never raises, use asset.exists(name, type); to handle a possible miss inline, wrap the call in pcall.

globals/asset/set_field

globals/asset/set_field(ref: RefArg, key: string, value: any)

Set one field in the asset's .metadata, creating the sidecar if missing. Sibling fields are preserved. When the new value AND the existing value are both maps (objects), the new value DEEP-MERGES into the existing one, so writing one sub-key never drops the others — set_field(ref, "settings", { keepCpu = true }) keeps every other setting. Arrays and scalars replace. Clear a whole field with asset.remove_field; replace the entire sidecar with asset.set_metadata.

globals/asset/set_metadata

globals/asset/set_metadata(ref: RefArg, data: AssetMeta)

Replace the asset's .metadata sidecar with the given table. Pass an empty table to clear all fields.

globals/asset/source

globals/asset/source(ref: RefArg, type: string?) -> string

Return the VFS source path for an asset.

globals/asset/tags

globals/asset/tags(ref: RefArg) -> { string }

Convenience read of the .metadata.tags array.

globals/asset/typeRef

globals/asset/typeRef(target: RefArg) -> string?

Return the pinned asset_type reference (the type's guid) that the asset is an instance of. Resolve the full type with asset.resolve(asset.typeRef(target)). Returns nil for loose files / assets with no pinned type.

globals/asset/validate

globals/asset/validate(ref: RefArg, type: string?) -> ValidateResult

Validate an asset folder against its type's type.yaml, plus the type's own semantic validation. Structural problems come from type.yaml — missing required files, unsatisfied one_of_group alternatives, and (when allow_unlisted: false) unexpected children. validated = false when no type.yaml is registered — nothing structural to check. On top of that, when the asset's type ships a behavior.luau exporting a top-level validate(assetRef) -> { { code, message, severity? } }, its reported problems (severity defaults to "error") are appended to problems; error-severity problems flip ok to false, warnings leave it untouched. A hook that raises or returns a non-table is itself reported as a validate.hook_failed error problem — a broken hook blocks. A type with no validate export behaves exactly as the structural check alone. world.push calls this per user asset, so a type's semantic validation is enforced at publish time with no further wiring.

globals/asset/warmup

globals/asset/warmup(ref: RefArg, opts: WarmupOpts?) -> WarmupResult

Warm an asset's bytes into CPU memory and follow its declared content dependencies to each referenced asset, deduped by guid. Type-agnostic (reads the generic ref graph) and CPU-only — never touches the GPU. Side-effect-free name resolution (uses asset.guid/asset.deps, not asset.resolve).

globals/audio/decode

globals/audio/decode(zaud: string) -> (string?, number?, number?)

Decode a ZAUD payload into interleaved f32 PCM.

globals/audio/encode

globals/audio/encode(sourceBytes: string, opts: { [string]: any }?) -> (string?, string?)

Encode container audio bytes (ogg / mp3 / wav / flac) into a ZAUD payload.

globals/audio/encodePcm

globals/audio/encodePcm(pcm: any, sampleRate: number, channels: number, opts: { [string]: any }?) -> (string?, string?)

Encode raw interleaved f32 PCM into a ZAUD payload.

globals/audio/info

globals/audio/info(zaud: string) -> (AudioInfo?, string?)

Read a ZAUD payload's header without decoding the audio.

globals/av/is_live

globals/av/is_live() -> boolean

True if a live-stream session is currently active.

globals/av/is_recording

globals/av/is_recording() -> boolean

True if a recording session is currently active.

globals/av/live

globals/av/live(opts: LiveOpts?) -> string?

Start the live-stream encoder. The stream is served at /engine/live.stream and reverse-proxied at /stream/<instance>/live.stream as a binary length-prefixed protocol consumed by the multiviewer UI's WebCodecs decoder. When texture_handle is set, the encoder reads from that GPU texture's guid (a Camera pointed at it via setTargetTexture) instead of the scene's viewport — that's how spectator cameras work. Returns a stream URL, or nil when unsupported or a session is already active.

globals/av/record

globals/av/record(path: string, opts: RecordOpts?) -> string

Start recording the engine output to a VFS path. Default dir is /zero/runtime/recordings/ when path is not absolute. With no chroma/range opts the format defaults to full-range 4:4:4 HEVC where the GPU supports it, else 4:2:0 limited. Returns a promise handle — use task.await() for the final result.

globals/av/status

globals/av/status() -> AvStatus

Report the encoder subsystem's state. Always available regardless of GPU support. Returns { supported, reason, backend, live, recording }backend is the hardware encode backend in use ("vulkan" or "vaapi") when supported.

globals/av/stop_live

globals/av/stop_live() -> boolean

Stop any active live-stream session.

globals/av/stop_recording

globals/av/stop_recording(handle: string?) -> boolean

Stop the active recording (or the one for the given promise handle). The promise resolves with the final result once stop completes.

globals/await

await(promiseHandle: string): any

Yield the current coroutine until the given promise resolves and return its value. Pair with any FFI function that returns a promise handle (asset.load, http.get_json, scene.save, delay, ...).

globals/base64/decode

globals/base64/decode(text: string) -> (string?, string?)

Decode standard-alphabet base64 text back to the original binary string.

globals/base64/encode

globals/base64/encode(bytes: string) -> string

Encode a binary string to standard-alphabet (padded) base64 text.

globals/batch

batch(fn)

Execute a function with batched mutations. Operations inside the function are collected and executed in order at the end, instead of immediately. Use for bulk operations where you want to control when mutations flush. Within the batch, operations still execute in order — spawn before component.add before impulse.

globals/blend/destroyLayout

globals/blend/destroyLayout(handle: number) -> boolean

Drop the layout from the registry.

globals/blend/layout

globals/blend/layout(slots: { BlendSlot }, totalStride: number?) -> number?

Register a record-stride layout. Each slot is { offset, stride, op } where op is "lerp" / "slerp" / "sum" / "step". Slerp slots must have stride 4. totalStride defaults to max(offset + stride) across slots; pass an explicit value when records contain padding past the last slot.

globals/blend/lerpInto

globals/blend/lerpInto(outBuffer: number, layout: number, aBuffer: number, bBuffer: number, t: number) -> boolean

Two-input crossfade shortcut. Equivalent to blend.weightedInto(out, layout, { {a, 1-t}, {b, t} }). Faster for the common A/B fade case because it skips the inputs-table walk.

globals/blend/weightedInto

globals/blend/weightedInto(outBuffer: number, layout: number, inputs: { BlendInput }) -> boolean

Combine N weighted input Buffers into the output Buffer using the layout's slot ops. The output buffer's length must be a whole multiple of layout.totalStride; every input buffer must be at least as long as the output. Returns false on any handle / size mismatch.

globals/bundle/installInto

globals/bundle/installInto(bundleNamespace: BundleNamespace)

Install update onto the supplied bundle-shaped namespace. The prelude calls this once at boot with the engine's bundle global; users shouldn't call it directly.

globals/bundle/update

globals/bundle/update(entityId: string, bundleRef: BundleRef?) -> any

Re-compose a bundle from an entity's current hierarchy and write it back to the bundle's on-disk path. The VFS write triggers the engine's generic asset hot-reload pipeline, which fires onAssetReload(field) on every component subscribed to this bundle's guid via a declared asset field — those components reconcile per their own policy.

globals/camera/active

globals/camera/active() -> string?

Entity id of the on-screen render camera this frame — whichever camera wins the viewport by priority (the editor fly-camera in edit mode, the gameplay camera in play). Render features, billboards, and input bases that must follow the human's on-screen view read this.

globals/camera/editor

globals/camera/editor() -> string?

Entity id of the editor fly-camera (the EditorOnly authoring camera), or nil if the scene has none.

globals/camera/main

globals/camera/main() -> string?

Entity id of the main scene camera — the highest-priority active camera that is NOT the editor fly-camera. The gameplay/PlayerPrototype camera, an agent-placed scene camera, or a cutscene camera. Never the editor camera; nil if the scene has only the editor camera. For the camera currently drawn on screen, use camera.active().

globals/camera/viewData

globals/camera/viewData() -> CameraView?

The active viewport camera's render data this frame: world position, vertical FOV, viewport pixel size, the 6 world-space frustum planes (the same inward-pointing, normalized planes the renderer culls with), and the view-projection matrix. The camera state a render feature needs for camera-relative work — LOD selection, frustum culling, billboards. Render features also get it as ctx.camera.

globals/channel/create

globals/channel/create(opts: ChannelOpts) -> number?

Register a keyframe channel. times is the sorted keyframe time array; values is the packed value array (layout depends on interp); stride is the floats-per-sample width; interp is "step" | "linear" | "slerp" | "cubicHermite". Returns the channel handle, or nil on malformed input.

globals/channel/destroy

globals/channel/destroy(handle: number) -> boolean

Drop the channel from the registry.

globals/channel/sampleInto

globals/channel/sampleInto(ch: number, time: number, buf: number, offset: number) -> boolean

Sample the channel at time and write stride floats into the Buffer's data starting at f32 index offset. Returns false on unknown handle, layout mismatch, or out-of-bounds; the buffer is unchanged on failure.

globals/channel/sampleManyInto

globals/channel/sampleManyInto(ch: number, time: number, buf: number, offsets: { number }) -> boolean

Sample once, blit the result into every position in offsets. Saves the per-offset binary search when one channel feeds many bones / particles / parameters.

globals/channel/sampleQuat

globals/channel/sampleQuat(ch: number, time: number) -> (number?, number?, number?, number?)

Convenience accessor for stride-4 quaternion channels.

globals/channel/sampleVec3

globals/channel/sampleVec3(ch: number, time: number) -> (number?, number?, number?)

Convenience accessor for stride-3 channels. Returns the three components as multiret, or nil if the channel is unknown / has a different stride.

globals/color/complementary

globals/color/complementary(c: Color) -> Color

Complementary color — rotate hue 180° in Oklch space.

globals/color/darken

globals/color/darken(c: Color, amount: number) -> Color

Decrease the lightness of a color in Oklch perceptual space.

globals/color/desaturate

globals/color/desaturate(c: Color, amount: number) -> Color

Decrease the chroma (saturation) of a color in Oklch space.

globals/color/hex

globals/color/hex(hexString: string) -> Color?

Parse a hex color string into an sRGB color table. Accepts 3, 4, 6, or 8 hex digits with or without a leading # (e.g. "#f00", "f00f", "#ff0000", "ff000080"). Returns nil on parse failure.

globals/color/hsl

globals/color/hsl(h: number, s: number, l: number) -> Color

Build a color from HSL (h: 0-360, s: 0-1, l: 0-1). Returned as sRGB.

globals/color/hsla

globals/color/hsla(h: number, s: number, l: number, a: number) -> Color

Build a color from HSLA, returned as sRGB.

globals/color/hsv

globals/color/hsv(h: number, s: number, v: number) -> Color

Build a color from HSV (h: 0-360, s: 0-1, v: 0-1).

globals/color/lighten

globals/color/lighten(c: Color, amount: number) -> Color

Increase the lightness of a color in Oklch perceptual space.

globals/color/linear

globals/color/linear(r: number, g: number, b: number, a: number?) -> Color

Build a color from linear RGB values (not gamma-corrected), output converted to sRGB. Useful for GPU-correct blending. Alpha defaults to 1.

globals/color/mix

globals/color/mix(c1: Color, c2: Color, t: number) -> Color

Perceptually blend two colors in Oklch space — better than RGB mixing for gradients.

globals/color/mixRgb

globals/color/mixRgb(c1: Color, c2: Color, t: number) -> Color

Linearly blend two colors in sRGB space — simple, but not perceptually uniform. Prefer color.mix for natural gradients.

globals/color/oklch

globals/color/oklch(l: number, c: number, h: number) -> Color

Build a color from Oklch perceptual color space (l: 0-1, c: 0-0.4, h: 0-360). Ideal for perceptually uniform gradients and color manipulation.

globals/color/rgb

globals/color/rgb(r: number, g: number, b: number) -> Color

Build an sRGB color from CSS-style 0-255 RGB channels. Alpha defaults to 1. Channels are normalised to 0-1 on the way out so the result composes with every other color helper.

globals/color/rgba

globals/color/rgba(r: number, g: number, b: number, a: number) -> Color

Build an sRGB color from CSS-style 0-255 RGB channels with explicit alpha. RGB are normalised to 0-1; alpha is taken as-is in the 0-1 range.

globals/color/rotateHue

globals/color/rotateHue(c: Color, degrees: number) -> Color

Rotate the hue of a color by a given number of degrees in Oklch space.

globals/color/saturate

globals/color/saturate(c: Color, amount: number) -> Color

Increase the chroma (saturation) of a color in Oklch space.

globals/color/toHex

globals/color/toHex(c: Color) -> string

Convert a color to a hex string. Returns "#rrggbb" or "#rrggbbaa" if alpha is not 1.

globals/color/toHsl

globals/color/toHsl(c: Color) -> HslColor

Convert a color to HSL.

globals/color/toLinear

globals/color/toLinear(c: Color) -> Color

Convert a color from sRGB to linear RGB space — useful for GPU calculations that need linear-space values.

globals/color/toOklch

globals/color/toOklch(c: Color) -> OklchColor

Convert a color to Oklch perceptual color space.

globals/color/withAlpha

globals/color/withAlpha(c: Color, a: number) -> Color

Return a copy of a color with a different alpha value.

globals/compute/compile

globals/compute/compile(nameOrHandle: string | { [string]: any } | AssetRef, opts: { [string]: any }?) -> boolean

Compile a compute shader from inline WGSL + a declarative binding schema — the same codegen a .computeShader asset uses. The engine generates the @group/@binding declarations from bindings/params, so the source writes only @compute fn main. Symmetric with registerShader, but with zero-scaffolding bindings (incl. textures, samplers, storage textures and a params uniform). For asset-backed shaders prefer authoring a .computeShader (compiled automatically); use this for dynamic/generated compute shaders.

globals/compute/compileByName

globals/compute/compileByName(ref: string | { [string]: any } | AssetRef)

Optional explicit pre-warm for a .computeShader asset (idempotent — fingerprint-guarded). NORMALLY UNNECESSARY: compute.dispatch / dispatchEx auto-compile a .computeShader on first use. Reach for this only to avoid the one-frame first-dispatch warm-up in a latency-critical spot. Accepts an identity/guid string or a resolved asset handle (its .identity is used).

globals/compute/createBuffer

globals/compute/createBuffer(name: string, opts: BufferOpts) -> boolean

Create a named GPU storage buffer.

globals/compute/createSampler

globals/compute/createSampler(name: string, opts: { [string]: any }?) -> boolean

Create a named GPU sampler. opts: filter/wrap settings.

globals/compute/createStorageTexture2D

globals/compute/createStorageTexture2D(name: string, opts: { [string]: any }) -> boolean

Create a 2D storage texture (compute-writable render target). opts: { width, height, format? }.

globals/compute/createTexture3D

globals/compute/createTexture3D(name: string, opts: { [string]: any }) -> boolean

Create a 3D texture volume. opts: { width, height, depth, format?, storage? }.

globals/compute/createTextureHistory

globals/compute/createTextureHistory(name: string, opts: { [string]: any }) -> boolean

Create a temporal history buffer (ping-pong textures) for a target. opts: { width, height, format? }.

globals/compute/destroyBuffer

globals/compute/destroyBuffer(name: string) -> boolean

Destroy a named GPU compute buffer and free its memory.

globals/compute/destroyShader

globals/compute/destroyShader(name: string) -> boolean

Destroy a named compute shader pipeline.

globals/compute/destroyShaderEx

globals/compute/destroyShaderEx(name: string) -> boolean

Destroy a shader registered via registerShaderEx.

globals/compute/destroyStorageTexture2D

globals/compute/destroyStorageTexture2D(name: string) -> boolean

Destroy a named 2D storage texture.

globals/compute/destroyTexture3D

globals/compute/destroyTexture3D(name: string) -> boolean

Destroy a named 3D volume and free its GPU memory.

globals/compute/destroyTextureHistory

globals/compute/destroyTextureHistory(name: string) -> boolean

Destroy a named texture-history buffer.

globals/compute/dispatch

globals/compute/dispatch(shaderNameOrHandle: string | { [string]: any } | AssetRef, opts: DispatchOpts) -> boolean

Dispatch a compute shader with bound buffers. Accepts a shader name string or an asset handle from asset.load().

globals/compute/dispatchEx

globals/compute/dispatchEx(shaderNameOrHandle: string | { [string]: any } | AssetRef, opts: { [string]: any }) -> boolean

Dispatch a compute shader with extended texture/storage/sampler bindings. Asset-backed .computeShaders resolve to their stable guid (collision-safe, lazily compiled on first dispatch); raw registerShaderEx names pass through.

globals/compute/dispatchOnVertices

globals/compute/dispatchOnVertices(shaderNameOrHandle: string | { [string]: any } | AssetRef, opts: DispatchOnVerticesOpts) -> boolean

Dispatch a compute shader with a model's vertex buffer bound at binding 0 (read_write). Use to mutate vertex positions directly.

globals/compute/getReadbackResult

globals/compute/getReadbackResult(resultKey: string) -> { number }?

Poll for a completed read-back. Returns array of f32 values if ready, nil if pending. Result is consumed on retrieval.

globals/compute/getReadbackResultU32

globals/compute/getReadbackResultU32(resultKey: string) -> { number }?

Poll for a completed read-back interpreting bytes as u32. Returns array of integer values if ready, nil if pending.

globals/compute/isReadbackReady

globals/compute/isReadbackReady(resultKey: string) -> boolean

Check if a readback result is available without consuming it.

globals/compute/readBuffer

globals/compute/readBuffer(bufferName: string) -> string

Start an async GPU→CPU read-back of a named buffer. The buffer must have been created with readback = true. Returns a result key to poll with getReadbackResult().

globals/compute/readTexture3D

globals/compute/readTexture3D(name: string) -> string

Start a GPU→CPU readback of a named 3D volume. Returns a result key to poll.

globals/compute/registerShader

globals/compute/registerShader(nameOrHandle: string | { [string]: any } | AssetRef, opts: ShaderOpts?) -> boolean

Register a compute shader. Accepts an asset handle from asset.load(), or (name, opts) with inline WGSL source.

globals/compute/registerShaderEx

globals/compute/registerShaderEx(nameOrHandle: string | { [string]: any } | AssetRef, opts: { [string]: any }?) -> boolean

Register a compute shader with extended texture/sampler bindings. Accepts a name + opts or an asset handle.

globals/compute/setParam

globals/compute/setParam(name: string, prop: string, value: number) -> boolean

Set a named scalar parameter on a .computeShader (a params: entry in its bindings.yaml). Updates the shader's params uniform in place; the next dispatch sees the new value. No effect on raw registerShader shaders, which have no params block.

globals/compute/textureFormatBytes

globals/compute/textureFormatBytes(format: string) -> number

Bytes-per-voxel for a texture format string (rgba16f, r8, ...).

globals/compute/writeBuffer

globals/compute/writeBuffer(name: string, data: { number }, offset: number?) -> boolean

Write an array of floats to a named GPU buffer (little- endian f32 bytes).

globals/compute/writeBufferBytes

globals/compute/writeBufferBytes(name: string, bytes: string, offset: number?) -> boolean

Write the raw bytes of a binary string to a named GPU buffer, verbatim. For packed binary that already matches a GPU layout (decoded vertex / index / record pools, file bytes, a network message) — no number-array round trip, unlike writeBuffer / writeBufferU32 which reinterpret each element as one f32 / u32.

globals/compute/writeBufferU32

globals/compute/writeBufferU32(name: string, data: { number }, offset: number?) -> boolean

Write an array of unsigned integers to a named GPU buffer (little-endian u32 bytes).

globals/compute/writeFloatsTexture3D

globals/compute/writeFloatsTexture3D(name: string, floats: { number }, formatOrOpts: (string | { [string]: any })?) -> boolean

Upload float values into a named 3D volume, packed via the given format (default rgba16f).

globals/compute/writeTexture3D

globals/compute/writeTexture3D(name: string, data: { number }) -> boolean

Upload raw bytes (u8) into a named 3D volume.

globals/computed

computed(fn: () -> any): any

Mark a public.X = computed(fn) field as a derived read-only property — auto-injected by the prelude's component_proxy.

globals/debugger/__diagnostics

globals/debugger/__diagnostics() -> DebuggerDiagnostics

Internal diagnostic counters for debugging the debugger itself: { installs, debugbreakHits }.

globals/debugger/addWatch

globals/debugger/addWatch(expr: string) -> number

Register an expression to re-evaluate on every pause.

globals/debugger/continue_

globals/debugger/continue_() -> boolean

Resume the paused thread.

globals/debugger/disableAll

globals/debugger/disableAll()

Disable every registered breakpoint. Records persist; bytecode BREAK ops are cleared.

globals/debugger/disconnect

globals/debugger/disconnect(handle: number) -> boolean

Disconnect an onBreak or onResume callback.

globals/debugger/enableAll

globals/debugger/enableAll()

Enable every registered breakpoint and re-install them in the VM bytecode.

globals/debugger/evaluate

globals/debugger/evaluate(expr: string, frame: number?) -> (string?, string?)

Evaluate an expression against the paused frame's environment. Returns (value, error).

globals/debugger/getLocals

globals/debugger/getLocals(frame: number?) -> { [string]: string }

Locals captured at the active pause for the given frame index (1 = top). Values are stringified for safe display.

globals/debugger/getPauseInfo

globals/debugger/getPauseInfo() -> PauseInfo?

Info about the active pause, or nil if nothing is paused.

globals/debugger/getStack

globals/debugger/getStack() -> { Frame }

Captured stack from the active pause, top frame first. Empty when nothing is paused.

globals/debugger/getUpvalues

globals/debugger/getUpvalues(frame: number?) -> { [string]: string }

Upvalues captured at the active pause for the given frame.

globals/debugger/getWatchValue

globals/debugger/getWatchValue(id: number) -> (string?, string?)

Re-evaluate the watch expression against the paused frame's environment and return (value, error).

globals/debugger/getWatches

globals/debugger/getWatches() -> { Watch }

Snapshot of all watches with their last evaluated value and error, sorted by id.

globals/debugger/isPauseOnError

globals/debugger/isPauseOnError() -> boolean

Current pause-on-error toggle state for this VM.

globals/debugger/isPaused

globals/debugger/isPaused() -> boolean

Whether the debugger currently has a paused thread.

globals/debugger/listBreakpoints

globals/debugger/listBreakpoints() -> { Breakpoint }

Snapshot of every registered breakpoint, sorted by id ascending.

globals/debugger/onBreak

globals/debugger/onBreak(fn: (PauseInfo) -> ()) -> number

Register a callback invoked on every pause with { path, line, reason }. Returns a handle usable with debugger.disconnect.

globals/debugger/onResume

globals/debugger/onResume(fn: () -> ()) -> number

Register a callback invoked when the paused thread is resumed.

globals/debugger/removeBreakpoint

globals/debugger/removeBreakpoint(id: number) -> boolean

Remove the breakpoint with the given id.

globals/debugger/removeWatch

globals/debugger/removeWatch(id: number) -> boolean

Remove the watch with the given id.

globals/debugger/setBreakpoint

globals/debugger/setBreakpoint(path: string, line: number, opts: BreakpointOpts?) -> Breakpoint

Set a breakpoint at line in the script at VFS path.

globals/debugger/setPauseOnError

globals/debugger/setPauseOnError(enabled: boolean)

When true, uncaught Luau errors fire the onBreak callback (observation only — the error still propagates).

globals/debugger/stepInto

globals/debugger/stepInto() -> boolean

Run until the next line, descending into any function call.

globals/debugger/stepOut

globals/debugger/stepOut() -> boolean

Run until the current frame returns; pauses in the caller.

globals/debugger/stepOver

globals/debugger/stepOver() -> boolean

Run until the next line in the current frame. Calls inside the current line are skipped.

globals/debugger/toggleBreakpoint

globals/debugger/toggleBreakpoint(path: string, line: number) -> Breakpoint?

Toggle a breakpoint at the given line: removes if present, adds otherwise.

globals/declare

declare(spec)

Declare top-level component metadata: executionOrder (i32), bindings ({string}), syncedFunctions ({string}). Per-field schema (type, default, Sync/NoSync) lives in public = {...} via Field.<kind>(default, mode) constructors — see man field. Must be called at top level, not inside any function.

globals/delay

delay(seconds) -> promise

Returns a promise that resolves after N seconds. Use with await(delay(2)) to pause execution.

globals/editorTools

editorTools(scope: string) -> table

Bind a toolbox handle whose methods call each tool and return its value directly, raising on failure. Superseded by tools.use("", "", ...).

globals/egress/clearCredential

globals/egress/clearCredential(name: string) -> boolean

TRUSTED ONLY. Remove a named credential.

globals/egress/credentialNames

globals/egress/credentialNames() -> { string }

List the names of configured credentials. Names only — secret values are never exposed to Luau.

globals/egress/fetch

globals/egress/fetch(name: string, method: string, url: string, headers: Headers?, body: JsonBody?, response: EgressResponseType?) -> string?

Perform an HTTP request with a named credential injected server-side (in Rust). Returns a promise handle for task.await(), or nil when the credential is unknown or url is outside the credential's allowed base_url. The secret is never exposed to Luau. This is the seam that production points at the ZeroMind egress endpoint.

globals/egress/hasCredential

globals/egress/hasCredential(name: string) -> boolean

Whether a named credential is configured. Returns only a boolean — never the value. Service handlers use this to fail with a clear "not configured" message.

globals/egress/setCredential

globals/egress/setCredential(name: string, base_url: string, header_name: string, header_value: string) -> boolean

TRUSTED ONLY. Register a named credential whose header is injected into matching egress.fetch calls. The value is held in Rust and never returned to Luau.

globals/engine/discardPlayChanges

globals/engine/discardPlayChanges() -> any

globals/engine/gameplayReady

globals/engine/gameplayReady() -> any

globals/engine/gpuCompute

globals/engine/gpuCompute() -> any

globals/engine/mode

globals/engine/mode() -> any

globals/engine/offWorldLoaded

globals/engine/offWorldLoaded(id: number) -> boolean

Remove an onWorldLoaded subscriber by its watcher id.

globals/engine/onModeChange

globals/engine/onModeChange(callback: (string, string) -> ()) -> number

Register a callback that fires synchronously whenever engine.mode changes. Callback receives (newMode, oldMode) as strings. Returns a watcher id for future removal. Consumers (player_spawner, camera_spawner, editor-UI bootstrap, world entrypoint top-level onModeChange, etc.) all subscribe through this single API — there is no other fire path. Mode is engine state, so the watcher hangs off the engine module.

globals/engine/onPauseChange

globals/engine/onPauseChange(callback: (boolean, boolean) -> ()) -> number

Register a callback that fires synchronously whenever the gameplay pause flag flips via an explicit engine.paused write. Callback receives (newPaused, oldPaused) as booleans. Returns a watcher id. Pause is independent of engine.mode: pausing play mode returns the editor authoring surface (free camera + EditorOnly entities) over the frozen play world, and resuming hides it again. Mode-driven pause resets (the edit=paused / play=running defaults applied on a mode flip) are delivered through onModeChange, not this hook.

globals/engine/onWorldLoaded

globals/engine/onWorldLoaded(callback: () -> ()) -> number

Register a callback fired (no args) when the world is fully LOADED — its .world_entrypoint.luau ran AND its onWorldLoad returned (the startup scene loaded, defaults seeded, editor UI mounted). This is strictly AFTER onWorldReady (content synced): ready = "bytes are in the VFS"; loaded = "the entrypoint has run". LATCHED — a callback registered after the world is already loaded fires immediately, so a late consumer never misses it and never has to poll. Read the same state synchronously via engine.worldLoaded.

globals/engine/onWorldReady

globals/engine/onWorldReady(callback: () -> ()) -> number

Register a callback fired (no args) when the bound world's content has been synced into the VFS and the world is ready to load. This is the race-free, user-space hook that drives the whole world-VM lifecycle: the builtin world-entrypoint loader subscribes to it and, when it fires, loadstring(vfs.read(...))s /source/.world_entrypoint.luau and runs its onWorldLoad — exactly the way a scene entrypoint loads. The trusted VM fires this (via world.markReady()) ONLY once the bytes are in the VFS, so a subscriber never sees a half-synced world. Returns a watcher id.

globals/engine/onWorldUnloading

globals/engine/onWorldUnloading(callback: () -> ()) -> number

Symmetric teardown of engine.onWorldReady: register a callback fired (no args) when the bound world is unbinding/swapping out. The builtin loader runs the world entrypoint's onWorldUnload here, so the world entrypoint has the same load/unload parity a scene entrypoint has. Returns a watcher id.

globals/engine/paused

globals/engine/paused() -> any

globals/engine/profile

globals/engine/profile() -> any

globals/engine/timeScale

globals/engine/timeScale() -> any

globals/engine/worldLoaded

globals/engine/worldLoaded() -> any

globals/environment/capture

globals/environment/capture(x: number, y: number, z: number) -> boolean

Bake the scene into the environment from (x, y, z) as the single global reflection (slot 0 + one full-coverage probe). Every PBR surface reflects it. Queued — takes effect on the next frame. For multiple proximity-blended probes use the reflectionProbe system instead.

globals/environment/captureSlot

globals/environment/captureSlot(slot: number, x: number, y: number, z: number) -> boolean

Bake the scene into reflection-probe slot (cube-array index) from (x, y, z). Renders the FULL scene (geometry + sky) six times from that point into that slot. Register the probe's position+radius via setProbes so surfaces blend it by proximity. Queued — takes effect next frame.

globals/environment/captureSlotToAsset

globals/environment/captureSlotToAsset(name: string, slot: number, x: number, y: number, z: number, timeoutFrames: number?) -> (string?, string?)

Bake the scene into reflection-probe slot from (x, y, z) AND persist the 6 rendered faces into a faces6 .texture cubemap asset at /source/<name>.texture/ (px/nx/py/ny/pz/nz PNGs + a cube.yaml sidecar). Survives an engine restart and syncs like any other texture. Yields a few frames while the bake + GPU readback complete; must be called from a task/coroutine context (component hook, task.spawn, or execute). NATIVE only — the wasm async-readback path is a tracked follow-up.

globals/environment/captureToAsset

globals/environment/captureToAsset(name: string, x: number, y: number, z: number) -> (string?, string?)

Bake the single global reflection AND persist it to a faces6 .texture asset (slot 0). Yields a few frames; call from a task/coroutine context.

globals/environment/loadFromAsset

globals/environment/loadFromAsset(name: string) -> (boolean, string?)

Load a persisted global reflection asset into slot 0 and make it the active single reflection (one full-coverage probe).

globals/environment/loadSlotFromAsset

globals/environment/loadSlotFromAsset(name: string, slot: number) -> (boolean, string?)

Load a persisted faces6 .texture cubemap (written by captureSlotToAsset) into reflection-probe slot WITHOUT re-rendering the scene. Reads the 6 face PNGs from /source/<name>.texture/ and uploads them into the slot's cube layers. How a persisted probe restores its baked environment on reload.

globals/environment/setProbes

globals/environment/setProbes(probes: { any }) -> boolean

Set the active reflection probes' blend data. probes is an array of { x, y, z, radius } (or { position = {x,y,z}, radius = r }); index i maps to cube slot i. Surfaces blend the probe slots by proximity to these positions, so objects reflect the nearest probe(s). Queued for next frame.

globals/error

error(message, level?)

Raise an error. Halts execution.

globals/font/glyph

globals/font/glyph(name: string, codepoint: number) -> any

Read one glyph's vectorized outline from a registered font, in font units (resolution-independent — scale by fontSize / unitsPerEm).

globals/font/list

globals/font/list() -> { string }

List every registered font family name.

globals/font/parse

globals/font/parse(bytes: string) -> string?

Parse a font file (TTF / OTF raw bytes) ONCE into the baked, vectorized glyph format (ZFNT): per-glyph vector outlines + metrics + character map, plus the original bytes. Heavy — run at import time (the .font assetType's onCreate / the font importer), then store the result as the asset payload. font.register loads it cheaply.

globals/font/register

globals/font/register(name: string, zfnt: string) -> any

Register a baked font (ZFNT from font.parse) under name, making it usable on every text surface via fontFamily = "<name>". Loads the vectorized glyph data into the runtime store (for font.glyph / font.textMesh) and feeds the embedded face to the 2D text and egui UI systems. Passing raw font bytes still works but logs a slow-path warning — bake with font.parse at import. Re-registering the same name replaces it.

globals/font/textMesh

globals/font/textMesh(name: string, text: string, opts: table?) -> any

Tessellate a string into renderable mesh geometry from a registered font's glyph outlines — true 3D text, laid out left-to-right by advance (newlines drop a line). Hand the result to renderer.mesh.create() (GPU) or asset.create("mesh") (persistable).

globals/getLookHitTable

getLookHitTable() -> table | nil

Get the physics raycast hit at screen center (crosshair).

globals/getPointerHitTable

getPointerHitTable() -> table | nil

Get the physics raycast hit under the mouse pointer.

globals/getTime

getTime() -> number

Get time in seconds since the engine started. Useful for animations and time-based logic.

globals/getViewportSize

getViewportSize() -> { width: number, height: number }

Get the viewport dimensions in pixels as a single table { width, height }. Returns one table, not two numbers.

globals/getmetatable

getmetatable(table) -> mt | nil

Get a table's metatable.

globals/http/get_bytes

globals/http/get_bytes(url: string, headers: Headers?) -> PromiseId

Async HTTP GET returning raw bytes (binary-safe string). Suitable for piping into vfs.write to download a file.

globals/http/get_json

globals/http/get_json(url: string, headers: Headers?) -> PromiseId

Async HTTP GET returning JSON. Returns a promise handle — wrap with task.await() to block until the response arrives.

globals/http/post_bytes

globals/http/post_bytes(url: string, headers: Headers?, body: JsonBody?) -> PromiseId

Async HTTP POST returning raw bytes — use for APIs that accept JSON input but return binary output (audio, images).

globals/http/post_json

globals/http/post_json(url: string, headers: Headers?, body: JsonBody?) -> PromiseId

Async HTTP POST returning JSON. Body is a Luau table; the FFI layer JSON-encodes it before the request goes out.

globals/http/request

globals/http/request(method: string, url: string, headers: Headers?, body: JsonBody?) -> PromiseId

Async HTTP request with an arbitrary verb (GET/POST/PUT/PATCH/ DELETE/…) returning JSON. Body is a Luau table; an empty 2xx response resolves to an empty table.

globals/http/request_raw

globals/http/request_raw(method: string, url: string, headers: Headers?, body: string?) -> PromiseId

Async HTTP request with an arbitrary verb and a RAW binary request body (a binary-safe string), for content-addressed blob uploads. The resolved value is the response body text.

globals/ipairs

ipairs(table) -> iterator

Iterate array portion of table (1, 2, 3...).

globals/jobs/find

globals/jobs/find(name: string) -> JobHandle?

Look up a registered job by name. Returns a JobHandle or nil for anonymous / unknown names. Single FFI crossing — returns the id directly, no registry snapshot.

globals/jobs/inspect

globals/jobs/inspect(target: JobHandle | string) -> JobInfo?

Return a snapshot row by job handle or by name without retrieving a full handle. Single FFI crossing — pulls only the matching row.

globals/jobs/list

globals/jobs/list(phase: string?) -> { JobInfo }

List registered job summaries. Pass a phase name to filter to a single phase. Single FFI crossing — only the requested rows cross the bridge.

globals/jobs/register

globals/jobs/register(descriptor: table) -> JobHandle?

Register a substrate job. Returns a JobHandle on success, nil on validation failure. Dispatches by executor.kind:\n - "kernel" / "stub" → standard __jobs.register (JSON-only descriptor).\n - "luau"__jobs.register_luau(descriptor, executor.run) so the Luau function survives the JSON crossing as a stable registry ref. The dispatcher invokes the run closure once per frame; the closure captures any bindings/buffers it needs.\n\norigin is auto-filled with the VFS path of the calling script unless the descriptor already supplies one — surfaced under /zero/runtime/jobs/<phase>/<key>/origin.txt for agent traceability. Single FFI crossing — auto-origin runs Rust-side via lua_getinfo, no separate stack-inspection trip.

globals/layers/active

globals/layers/active() -> any

globals/layers/find

globals/layers/find(ref: AssetRef<scene> | string) -> any?

globals/layers/fireBeforeLoad

globals/layers/fireBeforeLoad(proxy: any) -> nil

globals/layers/fireLoad

globals/layers/fireLoad(proxy: any) -> nil

globals/layers/fireUnload

globals/layers/fireUnload(proxy: any) -> nil

globals/layers/install

globals/layers/install() -> nil

globals/layers/is_loaded

globals/layers/is_loaded(ref: AssetRef<scene> | string) -> boolean

globals/layers/list

globals/layers/list() -> { any }

globals/layers/load

globals/layers/load(ref: AssetRef<scene> | string, opts: LoadOpts?) -> any

Load a scene into the root non-additive slot ("main") OR as an additive overlay alongside it. Identity is ref-based: pass an AssetRef<scene> envelope (preferred — caught at the callsite by the LSP) or an identity string (resolved via asset.ref at entry, hard-error if no stable guid comes back). For non-additive, idempotency is by guid: re-loading the same scene logs and returns the existing proxy without tearing anything down. Different guid → unloads the current root + cascades every additive overlay it spawned + transitions the multiplayer room + loads the new scene. Logs every step at info level so a silent no-op is impossible.

globals/layers/loadInFlight

globals/layers/loadInFlight() -> number

Returns the number of scene loads currently in flight (queued but not yet visible via onLoad dispatch). Returns 0 when the engine is in a stable load state. Used by engine.mode = ... to block flips while a load is mid-air; agents can read this to wait for a load to finish before driving the next operation.

globals/layers/offBeforeLoad

globals/layers/offBeforeLoad(h: number) -> boolean

globals/layers/offLoad

globals/layers/offLoad(h: number) -> boolean

globals/layers/offUnload

globals/layers/offUnload(h: number) -> boolean

globals/layers/onBeforeLoad

globals/layers/onBeforeLoad(cb: (any) -> ()) -> number

globals/layers/onLoad

globals/layers/onLoad(cb: (any) -> ()) -> number

globals/layers/onUnload

globals/layers/onUnload(cb: (any) -> ()) -> number

globals/layers/reload

globals/layers/reload(ref: (AssetRef<scene> | string)?) -> any?

globals/layers/unload

globals/layers/unload(refOrProxy: (AssetRef<scene> | string | any)?) -> nil

globals/library/has

globals/library/has(path: string) -> boolean

Check if a library asset exists at the given path.

globals/library/import

globals/library/import(namespace: string, worldName: string)

Import a saved world as a library. The world directory at data/worlds/<worldName>/ is loaded and registered under the given namespace. After import, all files in the world are accessible via require('@namespace/path') and visible at /zero/source/libs/@namespace/.

globals/library/list

globals/library/list(assetType: string?) -> { LibraryAsset }

List all available library assets. Optionally filter by asset type — call asset.categories() for the live set.

globals/loadstring

loadstring(code, chunkname?) -> function | (nil, error)

Compile a Luau source string into a callable function. Returns the compiled function on success, or nil + error message on failure. The returned function can be called to execute the code.

globals/logs/clear

globals/logs/clear() -> boolean

Drop all buffered log entries. Lifetime per-level counts (logs.count) are preserved.

globals/logs/count

globals/logs/count() -> LogCounts

Aggregate counters for the log ring. Lifetime counts survive eviction, so errors reflects the total seen even if the lines have scrolled out of the buffer.

globals/logs/errors

globals/logs/errors(limit: number?) -> { LogEntry }

Most-recent ERROR-level entries (newest first). limit defaults to 100.

globals/logs/find

globals/logs/find(text: string, limit: number?) -> { LogEntry }

Case-insensitive substring search over log messages. limit defaults to 200 (keeps the most recent matches).

globals/logs/query

globals/logs/query(opts: LogQueryOpts?) -> { LogEntry }

Query the engine's in-memory log ring. The live alternative to grepping data/logs/engine-<port>.log.

globals/logs/tail

globals/logs/tail(limit: number?) -> { LogEntry }

Most-recent entries of any level in chronological order. limit defaults to 100.

globals/logs/warnings

globals/logs/warnings(limit: number?) -> { LogEntry }

Most-recent WARN+ entries (newest first). limit defaults to 100.

globals/lsp/check

globals/lsp/check(path: string, opts: CheckOpts?) -> { Diagnostic }

Validate a single .luau file in the VFS and return its diagnostics.

globals/lsp/checkAll

globals/lsp/checkAll(opts: CheckAllOpts?) -> CheckAllResult

Validate the user's Luau scripts and return an aggregate summary plus diagnostic list. opts.scope = "user" (default) skips library mounts; "all" includes them.

globals/lsp/checkCode

globals/lsp/checkCode(source: string, opts: CheckOpts?) -> { Diagnostic }

Validate inline Luau source without a backing file. Useful for checking code before writing it to disk.

globals/lsp/checkDirty

globals/lsp/checkDirty() -> { Diagnostic }

Drain the dirty-file set populated by the hot-reload hook, validate each, and return the combined diagnostic list.

globals/lsp/describe

globals/lsp/describe(path: string) -> DocEntry?

Inspect a single documented entry. Returns the full doc table (signature, args, returns, examples, level), or nil.

globals/lsp/describeTool

globals/lsp/describeTool(path: string) -> string?

Return the full documentation text for a code-mode tool.

globals/lsp/docsByKind

globals/lsp/docsByKind(kind: string) -> { MethodSummary }

List every doc whose registration kind matches kind. Valid: "binding", "runtime_tool", "module", "component", "library", "lua_export".

globals/lsp/getStrictMode

globals/lsp/getStrictMode() -> StrictMode

Return the current strict mode.

globals/lsp/isStrict

globals/lsp/isStrict() -> boolean

Is the pre-execute LSP gate fully strict? False when off or in soft mode.

globals/lsp/lastCheckGen

globals/lsp/lastCheckGen() -> number

Generation counter — bumped each time the cache is rebuilt. UI polls this to know when to redraw.

globals/lsp/methods

globals/lsp/methods(namespace: string) -> { MethodSummary }

List every documented method / entry under a namespace.

globals/lsp/modules

globals/lsp/modules() -> { ModuleEntry }

List every Luau library module the engine currently knows about — discovered via --!module headers, library scans, and manually-recorded docs.

globals/lsp/namespaces

globals/lsp/namespaces() -> { NamespaceEntry }

List every top-level documentation namespace the engine knows about — FFI bindings, library / prelude modules, component contexts, Luau builtins, globals.

globals/lsp/readDirectives

globals/lsp/readDirectives(source: string) -> DirectiveBlock

Parse the leading --! directive block of a Luau source string. Used by UIs that audit which files have skip directives and what they suppress.

globals/lsp/search(query: string, opts: SearchOpts?) -> { MethodSummary }

Case-insensitive substring search across every registered doc's path, signature, and description.

globals/lsp/setStrict

globals/lsp/setStrict(enabled: boolean) -> boolean

Toggle the pre-execute LSP gate. Returns true when the change was persisted to .world_settings, false when the play-mode write lock blocked the write.

globals/lsp/setStrictMode

globals/lsp/setStrictMode(mode: StrictMode) -> boolean

Set the pre-execute strict gate's mode. Returns true when the change was persisted to .world_settings, false when the play-mode write lock blocked the write.

globals/lsp/summary

globals/lsp/summary() -> Summary

Counts only — does not re-run validation.

globals/lsp/tools

globals/lsp/tools() -> { ToolEntry }

List every code-mode tool registered in the VFS under /zero/docs/tools/<category>/<tool>.

globals/lsp/typeOf

globals/lsp/typeOf(expr_source: string, context_path: string?) -> TypeDescriptor

Infer the static type of a Luau expression. When context_path is given, the file is loaded and walked so the inference env contains every local + alias in scope at its end.

globals/luau_profile/begin

globals/luau_profile/begin(name: string) -> number

Open a named manual region. Returns an opaque integer id; pass it back to end_region(id) to close and record elapsed wall-clock under name.

globals/luau_profile/dump

globals/luau_profile/dump(path: string) -> DumpResult

Write the folded-stack dump to path, one line per stack as <ticks> <stack_csv> — the format upstream Luau emits and tools/perfgraph.py consumes unchanged.

globals/luau_profile/dump_regions

globals/luau_profile/dump_regions(path: string) -> DumpRegionsResult

Write per-region stats to path as JSON.

globals/luau_profile/end_region

globals/luau_profile/end_region(id: number)

Close a region previously opened by begin(name). Records elapsed wall-clock under the region's name. Silently no-ops on unknown id (typically a double-close or swapped-out VM).

globals/luau_profile/is_running

globals/luau_profile/is_running() -> boolean

True iff the background sampler is currently running.

globals/luau_profile/reset

globals/luau_profile/reset()

Clear every accumulated sample and region stat. The sampler keeps running if it was already on; only the data is wiped.

globals/luau_profile/sampling_available

globals/luau_profile/sampling_available() -> boolean

True on platforms where the background sampler can run (native targets), false on WASM. Manual regions work everywhere — only the sampler is platform-gated.

globals/luau_profile/snapshot

globals/luau_profile/snapshot(top_n: number?) -> Snapshot

Snapshot the current accumulator without touching the filesystem — cheap enough for per-frame UI polling. top_n truncates stacks to the N hottest entries; omitting it returns all stacks sorted descending by self_us. regions is always returned in full (sorted by total_us).

globals/luau_profile/start

globals/luau_profile/start(hz: number?) -> StartResult

Start the background Luau sampling profiler at hz samples per second (default 1000, clamped to [1, 100000]). Idempotent — calling while already running is a no-op. Returns { available, hz }available = false on WASM (no std::thread). Manual regions work regardless.

globals/luau_profile/stop

globals/luau_profile/stop()

Stop the background sampler. Blocks until the sampler thread joins (typically <1ms). Safe when not running. Does not clear the accumulator — call reset() to drop samples.

globals/mathx/addScaledVec3

globals/mathx/addScaledVec3(dstBuffer: number, srcBuffer: number, count: number, scale: number) -> boolean

dst[i] += src[i] * scale for count vec3 elements. Both buffers must hold at least count * 3 floats. Useful for particle integration (position += velocity * dt) and accumulator passes.

globals/mathx/dampScalar

globals/mathx/dampScalar(buffer: number, offset: number, count: number, target: number, smoothTime: number, dt: number) -> boolean

Critically-damped exponential approach toward target for count scalars at buffer[offset .. offset+count]. smoothTime is the time constant (~ 0.16 ⇒ ~63% per frame at 60 Hz). Pass smoothTime <= 0 to snap to the target.

globals/mathx/lerpVec3

globals/mathx/lerpVec3(buffer: number, offset: number, count: number, tx: number, ty: number, tz: number, t: number) -> boolean

Element-wise linear blend of count vec3s in buffer[offset .. offset+count*3] toward (tx, ty, tz) by t.

globals/mathx/normalizeQuat

globals/mathx/normalizeQuat(buffer: number, offset: number, count: number) -> boolean

Re-normalise count quaternions in place. Zero-length quats become identity (0, 0, 0, 1) so downstream code never sees NaN.

globals/mathx/slerpQuat

globals/mathx/slerpQuat(buffer: number, offset: number, count: number, tx: number, ty: number, tz: number, tw: number, t: number) -> boolean

Slerp count quaternions (xyzw) at buffer[offset..] toward (tx, ty, tz, tw) by t. Falls back to nlerp+normalize for very-close quats. Always picks the shortest-arc path.

globals/mathx/transformVec3

globals/mathx/transformVec3(buffer: number, offset: number, count: number, mat16: { number }) -> boolean

Treat each vec3 in buffer[offset..] as a position (w = 1), multiply by the 4x4 column-major matrix mat16 (16-element array), write .xyz of the result back. Layout matches glam, wgpu, and GLSL conventions.

globals/mcpLog/clear

globals/mcpLog/clear() -> boolean

Clear all entries from the engine's MCP log ring buffer.

globals/mcpLog/query

globals/mcpLog/query(limit: number?) -> { McpLogEntry }

Return the most-recent MCP tool-call entries from the engine's MCP log ring buffer (newest last). Pass limit to cap how many entries are returned — omit for the full ring (up to 500 entries).

globals/modelImport/decompose

globals/modelImport/decompose(bytes: string, format: string) -> string

Parse raw model bytes on a background thread. format is the real source extension ("fbx", "obj", "dae", "gltf", "glb", "stl", "ply", "3ds", …), forwarded to assimp as the format hint. Returns a promise handle: task.await it, then read the data with result(handle).

globals/modelImport/decomposeFiles

globals/modelImport/decomposeFiles(files: { ModelFile }, mainName: string) -> string

Parse a model plus its companion files on a background thread, so assimp resolves the model's external references (a .gltf's external .bin and image files, an .obj's .mtl colors/textures, MD5's .md5anim, …). files is an array of { name = basename, bytes = <bytes> } that MUST include the model file itself; mainName is that file's basename. Returns a promise handle: task.await it, then read the data with result(handle) — the same shape decompose produces.

globals/modelImport/extractAnimation

globals/modelImport/extractAnimation(sourcePath: string, clipName: string) -> string

Read a model source file and extract one animation clip to its .zanim payload, stashed for retrieval. The source extension decides the parser, so this is format-agnostic. Returns a promise handle: task.await it, then extractAnimationResult(handle) returns the bytes.

globals/modelImport/extractAnimationResult

globals/modelImport/extractAnimationResult(handle: string) -> string?

After awaiting an extractAnimation handle, return the extracted .zanim bytes (binary-safe), consuming them. The bytes to hand to asset.create("animation", name, { bytes }). Returns nil on failure or if already taken.

globals/modelImport/result

globals/modelImport/result(handle: string) -> any?

Read the decomposed model after decompose's handle has been awaited. Every format decomposes into the same shape, so this is format-agnostic. Runs on the main thread; consumes the stored result.

globals/modelImport/retryHandle

globals/modelImport/retryHandle(makeHandle: () -> any, retries: number?, yield: (() -> ())?) -> string?

Call makeHandle — which returns a promise-handle string, or a falsy value on a transient failure (e.g. a source read that raced a pending write during a parallel import) — up to retries + 1 times, yielding via yield between attempts so a pending write can land before the next try. Returns the handle string once one is produced, or nil when every attempt failed. Callers task.await the result only when it is non-nil, so a transient miss never reaches task.await as a non-string.

globals/modelImport/rigFromMeshSkin

globals/modelImport/rigFromMeshSkin(meshBytes: string) -> string?

Lift the skeleton out of a skinned .mesh (ZMSH) payload and return it as a .rig JSON document: bones (hierarchy, rest pose, inverse-bind), the auto-derived humanoid profile, and the humanoid classification. The source rig a skinned mesh's clips retarget through. Returns nil when the bytes are not a mesh or carry no skin.

globals/modelImport/rigFromSkeleton

globals/modelImport/rigFromSkeleton(skeleton: AnimationSkeleton) -> string?

Build a .rig JSON document from the skeleton an animation-only file was authored on — result(handle).skeleton, the bones its clips drive with their local rest transforms. Forward kinematics over the locals resolves globals + inverse-bind; the humanoid profile + classification are derived as for rigFromMeshSkin. The source rig a standalone clip retargets through. Returns nil on malformed input.

globals/multiplayer/beginOperation

globals/multiplayer/beginOperation(description: string)

Begin recording an undoable operation. All mutations until commitOperation() are grouped into one undo entry.

globals/multiplayer/canRedo

globals/multiplayer/canRedo() -> boolean

Check if this client has any redoable operations.

globals/multiplayer/canUndo

globals/multiplayer/canUndo() -> boolean

Check if this client has any undoable operations.

globals/multiplayer/cancelOperation

globals/multiplayer/cancelOperation()

Cancel the current operation and restore all properties to their values at begin time.

globals/multiplayer/claimOwnership

globals/multiplayer/claimOwnership(entityId: string?) -> boolean

Request ownership of an entity. Returns true if the claim was tentatively granted (relay confirmation pending).

globals/multiplayer/commitOperation

globals/multiplayer/commitOperation()

Finalize the current operation and push it onto the undo stack. Only changes that actually differ from the start state are recorded.

globals/multiplayer/connect

globals/multiplayer/connect(relayUrl: string)

Connect to a multiplayer relay server for the current world. Uses the loaded world's world_id as the room prefix for scene isolation. A world must be loaded before connecting.

globals/multiplayer/disconnect

globals/multiplayer/disconnect()

Disconnect from the multiplayer relay server.

globals/multiplayer/getDiagnostics

globals/multiplayer/getDiagnostics() -> SyncDiagnostics

Get sync diagnostics — bandwidth, latency, peer count, top consumers.

globals/multiplayer/getPeerId

globals/multiplayer/getPeerId() -> number?

Get this client's peer ID in the current session.

globals/multiplayer/getPeers

globals/multiplayer/getPeers() -> { PeerInfo }

Get a list of all connected peers in the current session.

globals/multiplayer/getTickRate

globals/multiplayer/getTickRate() -> number

Get the current sync tick rate (network updates per second).

globals/multiplayer/isConnected

globals/multiplayer/isConnected() -> boolean

Check if a multiplayer session is active and connected to a relay.

globals/multiplayer/isHost

globals/multiplayer/isHost() -> boolean

Whether THIS client is the host (authoritative owner) of the current scene's play room — the relay room CREATOR, or offline / single-player. Host code spawns the shared synced world (via entity.spawnSynced or a scene's onHostLoad) and runs authoritative simulation; a non-host (JOINER) receives that content from the relay snapshot and must NOT re-create it. Gate ANY code that spawns synced entities or owns shared state with this so it runs on exactly one client — running it on every peer is the double-spawn 'explosion'.

globals/multiplayer/isOwner

globals/multiplayer/isOwner(entityId: string?) -> boolean

Check if the local client owns the given entity (or the current entity if called from a component). Only the owner can modify synced properties directly.

globals/multiplayer/isRoomCreator

globals/multiplayer/isRoomCreator(roomKey: string) -> boolean?

Whether this client created the given room — it was the FIRST peer to join it (race-free; the relay assigns it on join). In play mode the creator instantiates the scene's entities (synced) and every other joiner receives them from the relay snapshot, so the scene is never double-instantiated.

globals/multiplayer/joinRoom

globals/multiplayer/joinRoom(roomKey: string)

Join a relay room. Room keys are built as {worldGuid}/{mode}/{sceneGuid} and partition the relay's fan-out — only peers in the same room receive each other's broadcasts. No-op when not connected or already joined.

globals/multiplayer/leaveRoom

globals/multiplayer/leaveRoom(roomKey: string)

Leave a relay room. No-op when not connected or not joined.

globals/multiplayer/loopback

globals/multiplayer/loopback() -> { [string]: any }

Loopback testing harness. Returns a table with enable(), disable(), flush(), receive() methods for testing sync without a relay server.

globals/multiplayer/on

globals/multiplayer/on(channel: string, callback: (number, ...any) -> ())

Subscribe to a custom message channel. The callback runs as callback(fromPeerId, ...args) whenever another peer calls multiplayer.send(channel, ...). Multiple callbacks per channel fire in registration order.

globals/multiplayer/redo

globals/multiplayer/redo() -> boolean

Redo this client's last undone operation.

globals/multiplayer/releaseOwnership

globals/multiplayer/releaseOwnership(entityId: string?) -> boolean

Release ownership of an entity.

globals/multiplayer/send

globals/multiplayer/send(channel: string, ...: any)

Broadcast a message on a named channel to every OTHER peer in the room. The relay forwards it transparently; peers receive it via multiplayer.on. Arguments may be any synced value (nil, boolean, number, string, Vec3, entity/component proxy, or table) and are delivered to listeners in order. No-op when not connected.

globals/multiplayer/undo

globals/multiplayer/undo() -> boolean

Undo this client's last edit-mode operation.

globals/next

next(table, key?) -> key, value

Raw table iteration.

globals/notices/post

globals/notices/post(template: string, params: { [string]: any }?, opts: NoticeOpts?)

Post a notice. template is a fixed sentence used to collapse repeats; put varying values in params. opts.severity defaults to "info"; opts.includeLocation attaches the emitting call site.

globals/nx/add

globals/nx/add(dst: NxBuffer, x: NxScalarOrBuffer) -> boolean

b[i] += x (x scalar) or b[i] += x[i] (x buffer). Dispatches on type(x). For interleaved-stride writes use nx.addStrided.

globals/nx/addStrided

globals/nx/addStrided(b: NxBuffer, scalar: number, stride: number, offset: number?) -> boolean

Strided add: buf[k * stride + offset] += scalar for every valid k.

globals/nx/addStridedFrom

globals/nx/addStridedFrom(dst: NxBuffer, src: NxBuffer, scale: number?, dst_stride: number, dst_off: number?, src_stride: number, src_off: number?) -> boolean

Strided BLAS-axpy from src into dst: dst[k * dst_stride + dst_off] += scale * src[k * src_stride + src_off].

globals/nx/applyAbs

globals/nx/applyAbs(b: NxBuffer) -> boolean

In-place b[i] = abs(b[i]).

globals/nx/applyCeil

globals/nx/applyCeil(b: NxBuffer) -> boolean

In-place b[i] = ceil(b[i]).

globals/nx/applyCos

globals/nx/applyCos(b: NxBuffer) -> boolean

In-place b[i] = cos(b[i]).

globals/nx/applyExp

globals/nx/applyExp(b: NxBuffer) -> boolean

In-place b[i] = exp(b[i]).

globals/nx/applyFloor

globals/nx/applyFloor(b: NxBuffer) -> boolean

In-place b[i] = floor(b[i]).

globals/nx/applyFract

globals/nx/applyFract(b: NxBuffer) -> boolean

In-place b[i] = fract(b[i]) (fractional part).

globals/nx/applyLog

globals/nx/applyLog(b: NxBuffer) -> boolean

In-place b[i] = ln(b[i]).

globals/nx/applyLog2

globals/nx/applyLog2(b: NxBuffer) -> boolean

In-place b[i] = log2(b[i]).

globals/nx/applyNeg

globals/nx/applyNeg(b: NxBuffer) -> boolean

In-place b[i] = -b[i].

globals/nx/applyRecip

globals/nx/applyRecip(b: NxBuffer) -> boolean

In-place b[i] = 1 / b[i].

globals/nx/applyRecipSqrt

globals/nx/applyRecipSqrt(b: NxBuffer) -> boolean

In-place b[i] = 1 / sqrt(b[i]).

globals/nx/applyRound

globals/nx/applyRound(b: NxBuffer) -> boolean

In-place b[i] = round(b[i]).

globals/nx/applySign

globals/nx/applySign(b: NxBuffer) -> boolean

In-place b[i] = sign(b[i]) (returns -1, 0, or +1).

globals/nx/applySin

globals/nx/applySin(b: NxBuffer) -> boolean

In-place b[i] = sin(b[i]).

globals/nx/applySqrt

globals/nx/applySqrt(b: NxBuffer) -> boolean

In-place b[i] = sqrt(b[i]).

globals/nx/applySquare

globals/nx/applySquare(b: NxBuffer) -> boolean

In-place b[i] = b[i] * b[i].

globals/nx/applyTan

globals/nx/applyTan(b: NxBuffer) -> boolean

In-place b[i] = tan(b[i]).

globals/nx/applyTrunc

globals/nx/applyTrunc(b: NxBuffer) -> boolean

In-place b[i] = trunc(b[i]).

globals/nx/applyWindow

globals/nx/applyWindow(signal: NxBuffer, window: NxBuffer) -> boolean

Element-wise signal[i] *= window[i] in place. Operates over the shorter of the two — passing a longer window to window a shorter clip is intentional, not an error.

globals/nx/axpby

globals/nx/axpby(dst: NxBuffer, a: number, src: NxBuffer, b: number) -> boolean

BLAS axpby: dst[i] = a*dst[i] + b*src[i].

globals/nx/clamp

globals/nx/clamp(b: NxBuffer, min_v: number, max_v: number) -> boolean

In-place clamp: b[i] = clamp(b[i], min_v, max_v).

globals/nx/copy

globals/nx/copy(dst: NxBuffer, src: NxBuffer) -> boolean

Copy every record from src into dst (memcpy fast path).

globals/nx/copyStridedFrom

globals/nx/copyStridedFrom(dst: NxBuffer, src: NxBuffer, scale: number?, dst_stride: number, dst_off: number?, src_stride: number, src_off: number?) -> boolean

Strided copy from src into dst with optional scaling: dst[k * dst_stride + dst_off] = scale * src[k * src_stride + src_off].

globals/nx/create

globals/nx/create(type_: NxType, n: number) -> NxBuffer?

Allocate a CPU buffer of type × len records. Thin alias for substrate.createBuffer({type=type_, len=n, kind="cpu"}) — kept here so the public nx library is the canonical entry point and users never need to import buffer separately.

globals/nx/div

globals/nx/div(dst: NxBuffer, x: NxScalarOrBuffer) -> boolean

b[i] /= x (x scalar) or b[i] /= x[i] (x buffer).

globals/nx/dot

globals/nx/dot(a: NxBuffer, b: NxBuffer) -> number?

Reduction: dot product of two same-shaped buffers.

globals/nx/fft1d

globals/nx/fft1d(re: NxBuffer, im: NxBuffer, inverse: boolean?) -> boolean

In-place 1D FFT over parallel re / im CPU buffers. inverse=true runs the inverse transform scaled by 1/N (so ifft(fft(x)) ≈ x).

globals/nx/fft2d

globals/nx/fft2d(re: NxBuffer, im: NxBuffer, width: number, height: number, inverse: boolean?) -> boolean

In-place 2D FFT over row-major parallel re / im buffers of length width*height. inverse=true is scaled by 1 / (width * height).

globals/nx/fill

globals/nx/fill(b: NxBuffer, value: number?) -> boolean

Fill the buffer with value (default 0.0). Equivalent to the scalar form of nx.add against a zeroed buffer, but skips the type-dispatch.

globals/nx/fillRandomNormal

globals/nx/fillRandomNormal(b: NxBuffer, mean: number?, stddev: number?, seed: NxSeed) -> boolean

Fill the buffer with Gaussian samples (Box-Muller), with the given mean and standard deviation, using a splitmix-keyed PRNG.

globals/nx/fillRandomUniform

globals/nx/fillRandomUniform(b: NxBuffer, min_v: number?, max_v: number?, seed: NxSeed) -> boolean

Fill the buffer with uniform-random samples in [min, max), using a splitmix-keyed deterministic PRNG.

globals/nx/fillStrided

globals/nx/fillStrided(b: NxBuffer, value: number, stride: number, offset: number?) -> boolean

Strided fill: buf[k * stride + offset] = value for every valid k.

globals/nx/fromTable

globals/nx/fromTable(arr: { number }, type_: NxType?) -> NxBuffer?

Build a CPU buffer from a Lua table of numbers. The table is written through buf:write in a single FFI crossing — no per-element Lua loop. For large arrays, prefer one of the nx.* constructors + a kernel pass over building a Lua array first.

globals/nx/full

globals/nx/full(n: number, type_: NxType?, value: number?) -> NxBuffer?

Allocate a buffer of type × len records and fill with value.

globals/nx/ifft1d

globals/nx/ifft1d(re: NxBuffer, im: NxBuffer) -> boolean

Convenience: nx.fft1d(re, im, true).

globals/nx/ifft2d

globals/nx/ifft2d(re: NxBuffer, im: NxBuffer, width: number, height: number) -> boolean

Convenience: nx.fft2d(re, im, w, h, true).

globals/nx/integratePosition

globals/nx/integratePosition(pos: NxBuffer, vel: NxBuffer, dt: number) -> boolean

Per-vec3: pos[i] += vel[i] * dt — semi-implicit Euler position integration. Both buffers must be vec3 (stride 3).

globals/nx/irfft1d

globals/nx/irfft1d(re: NxBuffer, im: NxBuffer) -> NxBuffer?

Real-output inverse 1D FFT. Input re / im are length N/2 + 1. Returns a fresh CPU f32 buffer of length 2 * (N/2 + 1 - 1) = N real samples.

globals/nx/irfft2d

globals/nx/irfft2d(re: NxBuffer, im: NxBuffer, width: number, height: number) -> NxBuffer?

Real-output inverse 2D FFT. Input re / im are (width/2 + 1) * height row-major. Returns a fresh f32 buffer of length width * height.

globals/nx/lerpTo

globals/nx/lerpTo(dst: NxBuffer, src: NxBuffer, t: number) -> boolean

dst[i] += t * (src[i] - dst[i]) — element-wise lerp toward src by t.

globals/nx/max

globals/nx/max(b: NxBuffer) -> number?

Reduction: maximum of all elements.

globals/nx/maxOp

globals/nx/maxOp(dst: NxBuffer, x: NxScalarOrBuffer) -> boolean

Element-wise b[i] = max(b[i], x) (scalar) or b[i] = max(b[i], x[i]) (buffer).

globals/nx/mean

globals/nx/mean(b: NxBuffer) -> number?

Reduction: arithmetic mean of all elements.

globals/nx/min

globals/nx/min(b: NxBuffer) -> number?

Reduction: minimum of all elements.

globals/nx/minOp

globals/nx/minOp(dst: NxBuffer, x: NxScalarOrBuffer) -> boolean

Element-wise b[i] = min(b[i], x) (scalar) or b[i] = min(b[i], x[i]) (buffer).

globals/nx/mul

globals/nx/mul(dst: NxBuffer, x: NxScalarOrBuffer) -> boolean

b[i] *= x (x scalar) or b[i] *= x[i] (x buffer).

globals/nx/mulStrided

globals/nx/mulStrided(b: NxBuffer, scalar: number, stride: number, offset: number?) -> boolean

Strided multiply: buf[k * stride + offset] *= scalar for every valid k.

globals/nx/normL1

globals/nx/normL1(b: NxBuffer) -> number?

Reduction: L1 norm — sum(|b[i]|).

globals/nx/normL2

globals/nx/normL2(b: NxBuffer) -> number?

Reduction: L2 norm — sqrt(sum(b[i]^2)).

globals/nx/normalizeVec3

globals/nx/normalizeVec3(b: NxBuffer) -> boolean

Normalise each vec3 in-place. Vectors below 1e-8 are left untouched.

globals/nx/ones

globals/nx/ones(n: number, type_: NxType?) -> NxBuffer?

Allocate a buffer of type × len records and fill with 1.0.

globals/nx/pow

globals/nx/pow(b: NxBuffer, p: number) -> boolean

In-place b[i] = b[i] ^ p (scalar exponent).

globals/nx/quatFromYaw

globals/nx/quatFromYaw(dst: NxBuffer, yaw: NxBuffer) -> boolean

Per-quat: dst[i] = (0, sin(yaw[i]/2), 0, cos(yaw[i]/2)) — the pure-Y axis-angle quaternion for each yaw value. dst must be stride-4 (quat); yaw must be stride-1 (f32).

globals/nx/rfft1d

globals/nx/rfft1d(signal: NxBuffer?) -> (NxBuffer?, NxBuffer?)

Real-input forward 1D FFT. Allocates two new CPU f32 buffers of length N/2 + 1 holding the (re, im) parts of the Hermitian-symmetric spectrum (same convention as NumPy np.fft.rfft).

globals/nx/rfft2d

globals/nx/rfft2d(signal: NxBuffer, width: number, height: number) -> (NxBuffer?, NxBuffer?)

Real-input forward 2D FFT. Input signal is row-major width*height. Returns (re_buf, im_buf) of length (width/2 + 1) * height each (matches np.fft.rfft2 layout).

globals/nx/scale

globals/nx/scale(b: NxBuffer, s: number) -> boolean

In-place b[i] *= s.

globals/nx/sinCosTo

globals/nx/sinCosTo(src: NxBuffer, sin_dst: NxBuffer, cos_dst: NxBuffer) -> boolean

Compute sin_dst[i] = sin(src[i]) and cos_dst[i] = cos(src[i]) in one pass using cheaper paired-trig argument reduction.

globals/nx/sub

globals/nx/sub(dst: NxBuffer, x: NxScalarOrBuffer) -> boolean

b[i] -= x (x scalar) or b[i] -= x[i] (x buffer).

globals/nx/sum

globals/nx/sum(b: NxBuffer) -> number?

Reduction: sum of all elements.

globals/nx/wanderYaw

globals/nx/wanderYaw(args: NxWanderArgs) -> boolean

Fused per-entity wander step. Each entity's yaw[i] walks by a uniform random delta in [-yawDelta, +yawDelta], then pos[i] advances forward in the (sin yaw, cos yaw) direction by step. Optional rot quat output writes a pure-Y axis-angle rotation. Replaces the per-entity Luau loop pattern (~12 ms / 5000 in interpreter) with a single Rust pass (~0.2 ms / 5000). Buffer requirements: pos vec3 (stride 3), yaw f32 (stride 1), rot optional quat (stride 4). All counts should match (kernel walks min(count_i)).

globals/nx/window/blackman

globals/nx/window.blackman(n: number) -> NxBuffer?

Allocate a fresh CPU f32 buffer of length n filled with a symmetric Blackman window (NumPy np.blackman convention).

globals/nx/window/hamming

globals/nx/window.hamming(n: number) -> NxBuffer?

Allocate a fresh CPU f32 buffer of length n filled with a symmetric Hamming window (NumPy np.hamming convention).

globals/nx/window/hann

globals/nx/window.hann(n: number) -> NxBuffer?

Allocate a fresh CPU f32 buffer of length n filled with a symmetric Hann window (NumPy np.hanning convention).

globals/nx/zeros

globals/nx/zeros(n: number, type_: NxType?) -> NxBuffer?

Allocate a buffer of type × len records and fill with 0.0.

globals/packages/list

globals/packages/list() -> { PackageEntry }

List every registered package across scopes.

globals/packages/lookup

globals/packages/lookup(name_or_scope: string, name: string?) -> PackageEntry?

Look up a single package by name (any scope) or by exact (scope, name).

globals/pairs

pairs(table) -> iterator

Iterate all key-value pairs.

globals/pcall

pcall(fn, ...) -> ok, result

Protected call. Returns false + error on failure.

globals/physics

physics: any

Lowercase alias of Physics. Same identity (#565). Prefer this in new code so the convention matches entity, scene, cam, ...

globals/postprocess/add

globals/postprocess/add(name: string, source: string, opts: PostprocessOpts?) -> boolean

Queue registration of a fullscreen post-process effect. The effect is applied on the next frame. source is WGSL providing ONLY fn fragment(in: PostInput) -> vec4<f32>; the engine generates the group(0) framework + schema-driven group(1) from opts.properties. Effects run in priority order (lower first, default 100).

globals/postprocess/list

globals/postprocess/list() -> { string }

List all registered post-process effect names in renderer priority order (lower priority runs first).

globals/postprocess/remove

globals/postprocess/remove(name: string) -> boolean

Queue removal of a post-process effect. Takes effect on the next frame. Removing a name that isn't registered is a silent no-op.

globals/postprocess/setEnabled

globals/postprocess/setEnabled(name: string, enabled: boolean) -> boolean

Queue an enable/disable toggle on a registered post-process effect. Targeting an unknown name is a silent no-op.

globals/postprocess/setProperty

globals/postprocess/setProperty(name: string, prop: string, value: (number | { number })) -> boolean

Queue a named material-property update on a registered post-process effect. The property must be declared in the effect's properties schema; read in WGSL as material.<prop>. value is a number or a number array (vec/color). Targeting an unknown effect or an undeclared property is a silent no-op.

globals/postprocess/setSampler

globals/postprocess/setSampler(name: string, opts: { [string]: any }) -> boolean

Configure the per-effect user sampler shared by the effect's declared texture properties. opts.filter = "linear" (default) or "nearest". opts.wrap (alias .address) = "clamp" (default), "repeat", or "mirror" — applied to all axes.

globals/postprocess/setTexture

globals/postprocess/setTexture(name: string, prop: string, path: string) -> boolean

Bind a texture to one of an effect's declared texture properties. Declare it in properties ({ name = "noise", type = "texture" }) and sample in WGSL as textureSample(noise, noise_sampler, in.uv). path is any TextureCache-resolvable spec (@builtin::textures.foo, color:1,0,0, default:white, a render-target name, ...). Targeting an unknown effect / property or unresolvable path silently no-ops.

globals/preset

preset: any

Preset namespace — apply named tuning bundles to components. Auto-injected by the prelude from @builtin::modules.preset.

globals/preset/create

globals/preset/create(name: string, entityId: string, componentType: string, opts: PresetCreateOpts?) -> PresetCreateResult

Snapshot an existing component's public property table into a preset asset on disk. Bare names land under /source/presets/<name>.preset/preset.yaml; absolute paths must point to a .preset directory or its inner preset.yaml.

globals/preset/load

globals/preset/load(source: AssetRef<preset>, overrides: table?) -> { [string]: any }

Load a preset asset and return the plain component property table.

globals/print

print(...)

Print values to the engine console. Concatenates all arguments with tabs.

globals/profiler/begin

globals/profiler/begin(name: string)

Start a named profiling block. Call profiler.finish(name) to record the duration. Blocks appear in profiler.stats() under "script.<name>" and inside captures.

globals/profiler/disableRing

globals/profiler/disableRing()

Disable the ring buffer and clear its history.

globals/profiler/enableRing

globals/profiler/enableRing(seconds: number?) -> boolean

Enable the always-recording ring buffer, retaining the last seconds of per-frame data (default 20). Query it AFTER the fact with profiler.retro() — latency-immune, since the data is historical. Editor profile only: returns false in the runtime profile. The enable is the gate; the ring costs nothing until on.

globals/profiler/finish

globals/profiler/finish(name: string?) -> number?

Finish a profiling block and record the elapsed duration as "script.<name>". Without an argument, closes the most-recently- begun block (LIFO stack). With a name, closes the most recent block whose name matches — useful when blocks of different names are nested.

globals/profiler/gpuFrame

globals/profiler/gpuFrame() -> GpuFrameReport

Label-aggregated GPU pass timings of the most recent resolved frame, measured with GPU timestamp queries. supported is false when the device lacks timestamp queries — spans stays empty. Each span sums every render/compute pass recorded under one label that frame (count passes): compute.<shader> per compute dispatch, scene.* for the scene passes, post.<effect> per post-process effect, feature.* for render-feature passes. The GPU may overlap passes, so total_ms can exceed frame_span_ms (first pass begin to last pass end). The readback is asynchronous: the report lags the live frame by a few frames. Steady per-frame workloads read reliably; a lone one-shot dispatch submitted in isolation can under-report on some drivers.

globals/profiler/hits

globals/profiler/hits(label: string?) -> string?

Drain the watchdog's recorded hit frames into a capture stored under label (default "watch_hits") and clear the buffer. Returns the capture JSON (same shape as stopCapture), or nil if there were no hits.

globals/profiler/isCapturing

globals/profiler/isCapturing() -> boolean

Check if a profiler capture is currently active.

globals/profiler/lastCapture

globals/profiler/lastCapture() -> string?

Get the most recent completed capture result as a JSON string. Same shape as profiler.stopCapture(). Returns nil if no capture has been completed yet.

globals/profiler/retro

globals/profiler/retro(seconds: number?, label: string?) -> { [string]: any }?

Retroactively aggregate the last seconds of the ring (default: the whole ring). The full per-frame capture is retained under label (default "retro") for in-engine drill-down (profiler.frame/hotspots); this RETURNS a compact structured aggregate table (frame-time distribution

  • per-system summary), never the raw per-frame array — bounded, so it is safe over the ZeroMind bridge. Code-facing primitive; the retro tool renders the agent-facing report. Latency-immune: the data is historical.

globals/profiler/ringStatus

globals/profiler/ringStatus() -> string

Ring buffer status as a JSON string: { enabled, frames, capacity, span_seconds }.

globals/profiler/startCapture

globals/profiler/startCapture(label: string?) -> boolean

Start recording per-frame profiler data. Each frame's system timings are captured until stopCapture() is called. Results are accessible via profiler.lastCapture() and VFS at /zero/runtime/profiler/<label>.json.

globals/profiler/stats

globals/profiler/stats(pattern: string?) -> { ProfilerStat }

Get current EMA profiling statistics from the SystemProfiler. Optional glob pattern filters by metric name (supports * and ? wildcards).

globals/profiler/stopCapture

globals/profiler/stopCapture() -> string?

Stop the active profiler capture and return its result as a JSON string. The capture is also saved to VFS at /zero/runtime/profiler/<label>.json. Top-level fields: label, frame_count, started_at, ended_at, frames, summary. Compute duration as ended_at - started_at.

globals/profiler/unwatch

globals/profiler/unwatch()

Disarm the watchdog. Recorded hits are kept for a final profiler.hits().

globals/profiler/watch

globals/profiler/watch(ceilingMs: number, mode: string?, excludeAgent: boolean?, maxHits: number?) -> boolean

Arm the frame-time watchdog. When a frame's EFFECTIVE time (total minus agent-injected execute cost) crosses ceilingMs, mode "record" logs every offending frame (read with profiler.hits()), and mode "pause" pauses gameplay ONCE to freeze the bad state, then disarms. Editor profile only: returns false in the runtime profile. excludeAgent (default true) keeps the agent's own calls from tripping it.

globals/profiler/watchStatus

globals/profiler/watchStatus() -> string

Watchdog status as a JSON string: { armed, ceiling_ms, mode, exclude_agent, hits, dropped_hits, tripped }.

globals/queue

queue(fn, opts?): (boolean, string?)

Defer FFI write paths inside fn to be applied across frames by the engine drainer. Returns (true, nil) on success or (false, err) if the body throws — partial batch is cleared so it never lands. Nested queue() is re-entrant (depth counter). Reads inside the body are not yet fenced (Stage 2). See modules.queue and docs/plans/2026-05-06-luau-queue-deferred-mutations.md.

globals/rawequal

rawequal(a, b) -> boolean

Compare without metamethods.

globals/rawget

rawget(table, key) -> value

Get without metamethods.

globals/rawlen

rawlen(table) -> number

Length without metamethods.

globals/rawset

rawset(table, key, value)

Set without metamethods.

globals/reflectionProbe/add

globals/reflectionProbe/add(x: number, y: number, z: number, opts: { [string]: any }?) -> string

Add a reflection probe at (x, y, z) in one call: spawns a probe entity carrying a ReflectionProbe component (which registers it and, unless opts.bake == false, bakes it). The probe is an editor gizmo — invisible in play mode. Returns the probe entity id.

globals/reflectionProbe/apply

globals/reflectionProbe/apply() -> number

Push the current active-probe blend data (live positions + radii) to the renderer. Builds a dense slot array so each probe's data lands at its cube slot; freed/missing slots become inert placeholders. Called automatically by add / bake / remove; call it directly after moving a probe entity.

globals/reflectionProbe/bake

globals/reflectionProbe/bake(id: string) -> (string?, string?)

Bake the scene into probe id's cube slot from its current position AND persist it to a faces6 .texture asset (so it survives reload + syncs), then re-apply the probe set. Yields a few frames; call from a task/coroutine context (component hook via task.spawn, bakeAll, or execute).

globals/reflectionProbe/bakeAll

globals/reflectionProbe/bakeAll() -> { baked: number, failed: number, errors: { string } }

Bake EVERY registered probe in the active layers, in one call. Captures each probe's scene from its position into its slot, persists it, and applies the full probe set. The agent/editor one-liner. Yields; call from a task/coroutine context (execute, a tool, or task.spawn).

globals/reflectionProbe/count

globals/reflectionProbe/count() -> number

Number of registered probes.

globals/reflectionProbe/list

globals/reflectionProbe/list() -> { any }

List every registered probe: { { id, slot, radius, asset, position }, ... }.

globals/reflectionProbe/loadBaked

globals/reflectionProbe/loadBaked(id: string) -> boolean

Load probe id's PERSISTED baked cube (probe_<key>.texture) into its slot WITHOUT re-rendering the scene — the runtime path. A probe bakes once at authoring time and loads the asset on every subsequent scene load. Returns false (not an error) when no baked asset exists yet.

globals/reflectionProbe/register

globals/reflectionProbe/register(id: string, radius: number, key: string?) -> number?

Register a reflection probe for entity id with influence radius. Assigns a free cube slot and applies the updated probe set. Idempotent — a re-register keeps the same slot and just updates the radius. Called by the ReflectionProbe component's awake; rarely called directly.

globals/reflectionProbe/setRadius

globals/reflectionProbe/setRadius(id: string, radius: number)

Update a probe's influence radius and re-apply.

globals/reflectionProbe/unregister

globals/reflectionProbe/unregister(id: string)

Unregister entity id's probe, freeing its cube slot, and re-apply.

globals/renderer/destroy

globals/renderer/destroy(handle: any) -> boolean

Free the GPU resource behind a MeshHandle / TextureHandle (the GPU-destroy verb). Routes by the handle's category. The on-disk asset, if any, is untouched. A CPU handle's :unload() frees the CPU copy separately.

globals/renderer/feature/create

globals/renderer/feature.create(ref: any, guid: string?) -> any

Instantiate a render feature so the engine calls its render(ctx) hook every frame. ref is an AssetRef<renderFeature> whose init.luau returns { setup?, render, teardown? }. Returns a live RenderFeatureHandle (its guid is the stable id, same as mesh/texture handles); tear it down with renderer:destroy(handle). Pass guid to assign a specific id.

globals/renderer/feature/destroy

globals/renderer/feature.destroy(handleOrGuid: any) -> boolean

Tear down a live render feature by its RenderFeatureHandle OR its guid string — the by-id path for when the handle was lost (e.g. across execute calls). Same effect as renderer.destroy(handle). Returns true if a feature was live under that id.

globals/renderer/feature/list

globals/renderer/feature.list() -> { { guid: string, identity: string } }

List every render feature currently live (running its render(ctx) each frame). Each entry is { guid, identity } — the guid is the same id a RenderFeatureHandle carries, so you can tear a feature down by guid even after losing its handle (e.g. across separate execute calls).

globals/renderer/getRaytrace

globals/renderer/getRaytrace() -> boolean

Whether ray tracing is currently enabled.

globals/renderer/mainCameraView

globals/renderer/mainCameraView() -> { number }?

The main camera's inverse view-projection (column-major, 16 numbers) followed by its world position (3 numbers) — {m0..m15, px,py,pz} — for reconstructing world positions from the depth buffer in a ray-tracing pass. Nil before the first render.

globals/renderer/material/create

globals/renderer/material.create(content: MaterialContent, key: string) -> MaterialHandle

Register (or update) a material's GPU resource under key and return its MaterialHandle. content = { shader, properties, textures, aliases?, render? }. The referenced textures must already be GPU-resident (the material assetType materialises each slot via texRef:handle() before calling this) — this only files the shader+property+texture-slot record the renderer binds. Mirrors renderer.mesh.create / renderer.texture.create; idempotent upsert by key. render sets pipeline render-state (cull / depthWrite / blend) — e.g. { cull = "front", depthWrite = false } for an inverted-hull outline program.

globals/renderer/material/describe

globals/renderer/material.describe(key: string) -> any

The recoverable definition ({ shader, properties, textures, name }) this module registered under key via renderer.material.create, or nil for keys registered elsewhere (e.g. material assets resolved by the assetType).

globals/renderer/material/destroy

globals/renderer/material.destroy(key: string) -> boolean

Drop a runtime material registered via renderer.material.create: clears its recoverable definition, unregisters its runtime-resource stamp so it is no longer swept into the material freeze/save flow, and frees the GPU record. Use for transient materials (e.g. a preview swatch) that must not outlive their use. The on-disk asset, if any, is untouched.

globals/renderer/material/setProperty

globals/renderer/material.setProperty(key: string, name: string, value: any) -> ()

Push one changed uniform property to a registered material's GPU record (frame-fast incremental update; no re-register). Keyed by the material's registry key.

globals/renderer/material/setTexture

globals/renderer/material.setTexture(key: string, slot: string, ref: string) -> ()

Push one changed texture slot to a registered material's GPU record. The texture must already be GPU-resident (materialise it with texRef:handle() first). Keyed by the material's registry key.

globals/renderer/mesh/buildClusters

globals/renderer/mesh.buildClusters(guid: string) -> string?

Build a cluster-LOD DAG (Nanite-style virtualized geometry) for the static CPU mesh held under guid and return its serialized data.clusters bytes. The native offline bake; returns nil when the mesh is degenerate or the platform has no builder (the cross-platform runtime consumes pre-baked clusters). Pair with renderer.mesh.uploadClusters.

globals/renderer/mesh/clusterComponents

globals/renderer/mesh.clusterComponents(clusterBytes: string) -> (ClusterComponents?, string?)

Split a cluster blob (from renderer.mesh.buildClusters) into its GPU-ready component byte pools — the cluster vertex pool, the u32 index pool, and the per-cluster record array — plus their counts. A pure decode (no GPU work): upload the pools to compute buffers (compute.createBuffer + compute.writeBufferBytes) to drive a cluster draw from Luau.

globals/renderer/mesh/create

globals/renderer/mesh.create(src: any, guid: string?) -> MeshHandle

Create (or fetch) a GPU mesh resource and return its MeshHandle. src: a MeshCpuHandle from meshRef:load() (CPU→GPU upload under the asset's guid, idempotent — returns the resident handle if already uploaded); raw geometry {positions, indices, normals?, uvs?, colors?} (a new runtime mesh); GPU compute buffers {vertexBuffer, indexBuffer, vertexCount, indexCount, aabbMin?, aabbMax?}; or a MeshHandle (returned as-is). NEVER takes an AssetRef — load the CPU first.

globals/renderer/mesh/decode

globals/renderer/mesh.decode(zmsh: string) -> (MeshGeometry?, string?)

Decode engine-native ZMSH bytes back into geometry { positions, indices, normals?, uvs?, colors? }. Inverse of renderer.mesh.encode.

globals/renderer/mesh/encode

globals/renderer/mesh.encode(geom: MeshGeometry) -> string?

Encode raw geometry into engine-native ZMSH bytes (the on-disk mesh payload). The CPU codec behind the mesh assetType's onCreate.

globals/renderer/mesh/encodeCpu

globals/renderer/mesh.encodeCpu(guid: string) -> string

Encode the CPU mesh resident under guid into ZMSH bytes. Reads the ONE guid-keyed CPU store — meshRef:load() populates it for assets, and renderer.mesh.readback(guid) populates it for a runtime mesh. Errors loudly when no CPU mesh is resident under the guid.

globals/renderer/mesh/getVertices

globals/renderer/mesh.getVertices(guid: string) -> { any }

Read the vertices of the CPU mesh resident under guid — one entry per vertex, { pos = {x,y,z}, normal = {x,y,z}, uv = {u,v} }. Reads the resident CPU store directly (no re-decode). Errors when no CPU mesh is resident under the guid — load it (meshRef:load()) or retain it (keepCpu) first.

globals/renderer/mesh/isCpuResident

globals/renderer/mesh.isCpuResident(guid: string) -> boolean

True if a CPU mesh is resident under guid in the guid-keyed CPU store.

globals/renderer/mesh/isResident

globals/renderer/mesh.isResident(guid: string) -> boolean

True if a GPU mesh is resident under guid.

globals/renderer/mesh/loadCpu

globals/renderer/mesh.loadCpu(ref: any) -> MeshCpuHandle

Load a .mesh asset's geometry into the ONE guid-keyed CPU store (the Disk→CPU step) and return a CPU handle. The handle holds NO geometry — only the guid plus counts and the per-handle read/encode/unload ops (which read the Rust-side store). Called by meshRef:load(). DEFAULT lifecycle: upload to the GPU then handle:unload(); the store is populated only by this call.

globals/renderer/mesh/readback

globals/renderer/mesh.readback(guid: string) -> MeshCpuHandle

Read a runtime GPU mesh's geometry back to CPU and return a MeshCpuHandle for it — the GPU→CPU half of the runtime-mesh freeze path. A mesh made with renderer.mesh.create keeps no CPU copy, so persisting it (:encode()asset.create("mesh", …)) reads it back here first. Yields until the readback completes (a frame or two). After it returns the geometry is resident in the guid-keyed CPU store: :getTriangles, :getVertices, :getBounds, :encode, :unload all work. Errors if no GPU mesh is resident in the vertex pool under guid.

globals/renderer/mesh/setVertices

globals/renderer/mesh.setVertices(guid: string, positions: { number })

Replace the resident CPU mesh's vertex positions (flat { x,y,z, ... }) under guid, IN PLACE — indices, normals/uvs, and skinning are preserved, the AABB recomputes, and the GPU re-fetches the new geometry so it shows on screen. The mesh must be CPU-resident (load it, or retain it with keepCpu). Errors with the reason otherwise, or when the vertex count doesn't match.

globals/renderer/mesh/unloadCpu

globals/renderer/mesh.unloadCpu(guid: string)

Drop the CPU mesh resident under guid from the guid-keyed CPU store. The explicit release for a runtime geometry mesh's recoverable definition.

globals/renderer/mesh/update

globals/renderer/mesh.update(handle: MeshHandle, src: any) -> MeshHandle

Overwrite the GPU resource behind handle IN PLACE, under the same guid, from new geometry or compute buffers. Never writes a .mesh file — the play-mode mutate path. A Model bound to handle.guid reflects the change with no re-bind. Returns the same handle with refreshed bounds.

globals/renderer/mesh/uploadClusters

globals/renderer/mesh.uploadClusters(guid: string, clusters: string) -> boolean

Attach a cluster-LOD DAG (bytes from renderer.mesh.buildClusters) to the GPU mesh keyed by guid, enabling the continuous-cut cluster draw path for that mesh.

globals/renderer/raytraceCapability

globals/renderer/raytraceCapability() -> string

The active ray-tracing backend: "hardware" (GPU ray query) or "compute" (software traversal — the path on devices without hardware ray query, e.g. the web). The same ray-tracing features work on both.

globals/renderer/setRaytrace

globals/renderer/setRaytrace(enabled: boolean) -> ()

Enable or disable GPU ray tracing. While enabled the engine builds the scene acceleration structure each frame so ray-tracing render features can trace against it; disabling stops the build (so it costs nothing until a ray-traced effect is active). Required before any ray-traced shadows / AO / reflections render.

globals/renderer/texture/capture

globals/renderer/texture.capture(handle: TextureHandle) -> string

Request a CPU readback of the GPU texture behind handle (e.g. a camera's rendered output). Returns a result key to pass to a TextureCpuHandle's :encode() once the readback completes.

globals/renderer/texture/cpuCreate

globals/renderer/texture.cpuCreate(width: number, height: number, fill: any?) -> TextureCpuHandle

Allocate a blank CPU image (RGBA8) filled with a solid colour and return a TextureCpuHandle. Compose into it with canvas:blit(src, x, y, w, h), then canvas:encodeJpeg() / :encodePng() for the bytes; :unload() drops it.

globals/renderer/texture/create

globals/renderer/texture.create(src: any, guid: string?) -> TextureHandle

Create (or fetch) a GPU texture resource and return its TextureHandle. src: a TextureCpuHandle from texRef:load() (CPU→GPU under the asset's guid, idempotent); raw pixels {rgba, width, height, srgb?} (a flat widthheight4 byte buffer, 0-255, row-major, top-to-bottom, RGBA); a TextureHandle (returned as-is); or render-target dimensions {width, height, name?} with no pixel source — an empty GPU texture a render pass writes into (camera output, UI surface) and that samples like any other texture. NEVER takes an AssetRef — load the CPU first.

globals/renderer/texture/decode

globals/renderer/texture.decode(ztex: string) -> (any, any, any)

Decode an engine-native ZTEX payload to RGBA8 pixels.

globals/renderer/texture/destroy

globals/renderer/texture.destroy(handle: TextureHandle)

Release the GPU texture behind handle. For an empty render-into texture (camera output, UI surface) this also frees its render scratch; for an uploaded runtime texture it drops the GPU resource (and any CPU shadow).

globals/renderer/texture/encode

globals/renderer/texture.encode(rgba: any, width: number, height: number, opts: any) -> (string?, string?)

Encode raw RGBA8 pixels into an engine-native ZTEX payload (the on-disk texture content). The CPU codec behind the texture assetType's onCreate.

globals/renderer/texture/encodeFromImage

globals/renderer/texture.encodeFromImage(bytes: string, opts: any) -> (string?, string?)

Encode source image bytes (png/jpg/webp/…) into an engine-native ZTEX payload. Used by the texture importer / assetType onChange.

globals/renderer/texture/info

globals/renderer/texture.info(ztex: string) -> (any, any)

Read the header of an engine-native ZTEX payload without copying the pixels. Returns its format, dimensions, mip count, and filter ("nearest" or "linear" — the sampler baked into the blob from the asset's settings.filter).

globals/renderer/texture/isResident

globals/renderer/texture.isResident(guid: string) -> boolean

True if a GPU texture is resident under guid.

globals/renderer/texture/loadCpu

globals/renderer/texture.loadCpu(ref: any, encodeOpts: any?) -> TextureCpuHandle

Load a .texture asset's pixels into the ONE guid-keyed CPU store (the Disk→CPU step) and return a CPU handle for per-pixel access (no GPU readback). The handle holds NO pixels — only the guid plus dims and the read/write/encode/unload ops (which read the Rust store). Called by texRef:load(). DEFAULT: upload to the GPU then handle:unload().

globals/renderer/texture/readback

globals/renderer/texture.readback(guid: string) -> TextureCpuHandle

Read a runtime GPU texture's pixels back to CPU and return a TextureCpuHandle for them — the GPU→CPU half of the runtime-texture freeze path. A texture made with renderer.texture.create keeps no CPU copy, so persisting it (:encode()asset.create("texture", …)) reads it back here first. Yields until the readback completes (a frame or two). After it returns the pixels are resident in the guid-keyed CPU store: :readPixel, :writePixel, :getInfo, :encode, :unload all work. Errors if no GPU texture is resident under guid.

globals/renderer/texture/update

globals/renderer/texture.update(handle: TextureHandle, src: any) -> TextureHandle

Overwrite the GPU texture behind handle IN PLACE, under the same guid, from new raw pixels. Never writes a .texture file — the play-mode mutate path. Returns the same handle (refreshed dims).

globals/require

require(path) -> module

Load a Lua module by VFS path. Cached after first load. Use for shared libraries.

globals/retarget/animation

globals/retarget/animation(clipRef: any, targetMeshRef: any, sourceMeshRef: any?) -> (boolean, string)

Retarget an animation clip onto a target rig, returning the VFS path of a new .anim whose channels name the target skeleton's bones with bind-pose corrected rotations. The source rig is the clip's embedded rig.zmsh (else sourceMeshRef's skin, else the skinned mesh beside the clip in its bundle); the target rig is targetMeshRef's skin. Play the result with animGraph.addClip(entity, path). Pure asset transform — no entity/ECS state.

globals/retarget/extractRig

globals/retarget/extractRig(meshBytes: string) -> string?

Strip a .mesh (ZMSH) payload to a lean skin-only rig: the skeleton with geometry removed, re-encoded as a ZMSH whose only content is the skin. Returns the rig bytes, or nil when the mesh carries no skin. A .animation composite embeds this as rig.zmsh so a clip travels with its own source rig.

globals/retarget/humanoidProfile

globals/retarget/humanoidProfile(meshBytes: string) -> HumanoidHolder?

Derive the humanoid retarget holder for a rig from a .mesh (ZMSH) payload, when that skeleton has the essential humanoid structure (a hips root, a head or neck, at least one full arm chain and one full leg chain). Returns nil for a rig that is not a humanoid — a prop, a plant whose leaves animate, a quadruped — so a clip from it stays a plain clip rather than joining the shared humanoid-animation pool.

globals/retarget/isHumanoid

globals/retarget/isHumanoid(meshBytes: string) -> boolean

Whether a rig is a humanoid avatar — true when humanoidProfile resolves a holder for it. Use this to tell a humanoid character apart from a generic animated mesh (a prop, a plant, a quadruped) before treating its clips as shareable humanoid animations.

globals/retarget/serializeProfile

globals/retarget/serializeProfile(holder: HumanoidHolder) -> string

Serialize a humanoid holder to the humanoid.profile file body: an editable YAML role -> bone-name map. Roles list hips-first head-to-toe through the limbs, then any extras name-sorted, so the file reads top-down and diffs stably. Edit a value to correct an auto-derived mapping.

globals/screenToPlanePoint

screenToPlanePoint(sx, sy, plane_y) -> x, y, z

Unproject screen coords to the intersection point on a horizontal Y-plane (the common cursor-on-ground case). Returns three numbers (x, plane_y, z) on hit, or no values when the ray is parallel to the plane, the plane is behind the camera, or no main camera has rendered yet — so local x, y, z = screenToPlanePoint(...) cleanly yields nil, nil, nil on miss.

globals/screenToRay

screenToRay(sx, sy) -> { origin: vec3, direction: vec3 } | nil

Unproject screen coordinates to a world-space ray. Returns a single table { origin = {x,y,z}, direction = {x,y,z} } where direction is a unit vector, or nil if no main camera has rendered yet. The ray is computed against the main viewport, so offscreen passes (capture, shadow, post-process) do not disturb it.

globals/select

select(index, ...) -> values

Select from varargs. select('#', ...) returns count.

globals/service/authenticated

globals/service/authenticated() -> boolean

Whether a platform identity (JWT) is available to attach to service calls. Returns only a boolean — never the token.

globals/service/balance

globals/service/balance() -> string?

Read the caller's credit balance from ZeroMind. Returns a promise handle for task.await() resolving the balance JSON, or nil when the gateway is unconfigured or no caller identity is available.

globals/service/configureGateway

globals/service/configureGateway(baseUrl: string) -> boolean

TRUSTED ONLY. Set the ZeroMind base URL that service.invoke and service.balance target. The trusted-VM auth bootstrap calls this with the resolved issuer.

globals/service/gatewayConfigured

globals/service/gatewayConfigured() -> boolean

Whether the ZeroMind service gateway has been configured. Service handlers use this to distinguish "gateway not configured" from "not signed in" when invoke returns nil.

globals/service/invoke

globals/service/invoke(offering: string, endpoint: string, opts: InvokeOpts?) -> string?

Invoke a provider offering's logical endpoint through ZeroMind. Returns a promise handle for task.await() resolving the InvokeResponse JSON, or nil when the gateway is unconfigured or no caller identity is available. The JWT and real upstream URL are never exposed to Luau.

globals/setmetatable

setmetatable(table, mt) -> table

Set a table's metatable.

globals/settings/all

globals/settings/all() -> { [string]: any }

Snapshot of the entire settings document (parsed). Modifying the returned table does NOT propagate — call set or setMany to persist. Useful for editors/inspectors that render every section.

globals/settings/get

globals/settings/get(key: string) -> any

Look up a value by dotted key. Returns whatever the file holds at that path — string / number / boolean / array / table — or nil if missing.

globals/settings/getBool

globals/settings/getBool(key: string, default: boolean?) -> boolean

Boolean-typed accessor. Returns the value when present and boolean-typed; falls back to default (or false) on missing key or type mismatch.

globals/settings/getNumber

globals/settings/getNumber(key: string, default: number?) -> number

Number-typed accessor. Returns the value when present and number-typed; falls back to default (or 0) on missing key or type mismatch.

globals/settings/getString

globals/settings/getString(key: string, default: string?) -> string

String-typed accessor. Returns the value when present and string-typed; falls back to default (or "" if omitted) on missing key or type mismatch.

globals/settings/set

globals/settings/set(key: string, value: any)

Set a value by dotted key, then serialize and write the file. In play mode the write fails like any other source-file write — call wld.edit() first to unlock.

globals/settings/setMany

globals/settings/setMany(updates: { [string]: any })

Apply many key/value updates in one batched write — fewer serialize+write round-trips than calling set per-key. Same lock semantics as set.

globals/shell/run

globals/shell/run(command: string) -> ShellResult

Execute a command in the engine's emulated Unix shell. Blocks until the command completes. This is the same shell as the MCP bash tool — 60+ builtins (ls, cat, grep, find, echo, ...) operating on the virtual scene filesystem.

globals/shell/runAsync

globals/shell/runAsync(command: string) -> string

Asynchronous version of shell.run. Returns a promise ID that resolves to a JSON-encoded result string. Use with task.await().

globals/skeleton/applyPose

globals/skeleton/applyPose(sinkHandle: number, bufferHandle: number) -> boolean

Snapshot the buffer's first layout.total_floats values and queue a pending apply for the next ECS drain. Returns false on unknown sink/buffer or buffer too small for the layout. The Buffer is unchanged.

globals/skeleton/bindClip

globals/skeleton/bindClip(zanimBytes: string, boneOrder: { string }) -> ClipBindInfo?

Decode a zanim payload and bind it to boneOrder, precomputing which of the clip's channels feed each bone so per-frame sampleClip is allocation-free. Returns { handle, matched, total, duration }, or nil on a malformed payload / empty bone order. Check matched: 0 means the clip drives none of these bones.

globals/skeleton/bindPose

globals/skeleton/bindPose(entityId: string?, opts: SkeletonLayout) -> number?

Register a pose sink targeting entityId. The opts table carries the layout: boneOrder is the bone-name array ({"hip", "spine", ...}), stride defaults to 10 (translation.xyz + rotation.xyzw + scale.xyz). Pass entityId as nil to use the current component's owning entity.

globals/skeleton/clipBones

globals/skeleton/clipBones(zanimBytes: string) -> { string }?

Decode a zanim payload and return its bone-name array. Pure: build a bind order or a retarget map from a clip without binding a sampler. Returns nil on bytes that aren't a valid zanim payload.

globals/skeleton/clipDecode

globals/skeleton/clipDecode(zanimBytes: string) -> string?

Decode a zanim payload to its readable JSON form ({ name, duration, channels, bone_names }). The binary parse is the engine's; json.decode the result to inspect or transform a clip's channels (e.g. the retarget bake) in Luau. Returns nil on bytes that aren't a valid zanim payload. Inverse of clipEncode.

globals/skeleton/clipEncode

globals/skeleton/clipEncode(jsonString: string) -> string?

Encode a clip's JSON form (the shape clipDecode returns) back to a zanim payload — the bytes a .animation stores and bindClip/sampleClip consume. Inverse of clipDecode. Returns nil on invalid JSON.

globals/skeleton/jointTransforms

globals/skeleton/jointTransforms(entityId: string) -> table

Read a skinned entity's per-joint world transforms for the current animated pose.

globals/skeleton/sampleClip

globals/skeleton/sampleClip(handle: number, time: number, buffer: number) -> boolean

Sample the bound clip at time (clamped to [0, duration]) and write one stride-10 pose record per bound bone into the Buffer, starting at index 0. Bones the clip does not drive are written as identity. Returns false on unknown handle/buffer or a buffer too small for the bone count.

globals/skeleton/unbindClip

globals/skeleton/unbindClip(handle: number) -> boolean

Drop the bound clip sampler from the registry.

globals/skeleton/unbindPose

globals/skeleton/unbindPose(sinkHandle: number) -> boolean

Remove the sink from the registry.

globals/sky/get

globals/sky/get() -> { [string]: any }

Get all current sky configuration as a table. Returns the same fields as sky.set accepts, plus read-only fields like material_name and type. Color values are returned as positional arrays [r, g, b].

globals/sky/getTimeOfDay

globals/sky/getTimeOfDay() -> number

Get the current time of day in hours (0-24).

globals/sky/preset

globals/sky/preset(name: string)

Apply a named sky preset. Available: clear_day, sunset, sunrise, overcast, night, studio, none. Raises a Luau error for unrecognized names — wrap in pcall if uncertain.

globals/sky/set

globals/sky/set(opts: SkyOpts)

Configure the sky system. All fields are optional — only provided fields are updated. Color fields accept both named {x=r, y=g, z=b} and positional {r, g, b} forms. color is an alias for solid_color.

globals/sky/setSunDirection

globals/sky/setSunDirection(dir: SkyColor)

Set an explicit sun direction and disable time-based sun positioning. The directional light is updated to match.

globals/sky/setTimeOfDay

globals/sky/setTimeOfDay(time: number)

Set the time of day (0-24 hours). 0 = midnight, 6 = sunrise, 12 = noon, 18 = sunset.

globals/spawn

spawn(...): any

High-level spawn helpers — auto-injected by the prelude from @builtin::modules.spawn. Provides spawn.cube, spawn.sphere, etc.

globals/subscriptions/cancel

globals/subscriptions/cancel(id: string) -> boolean

Cancel a subscription by id: disconnects the live connection immediately and marks the row cancelled. Returns true when a live subscription was cancelled, false for an unknown or already-disconnected id.

globals/subscriptions/get

globals/subscriptions/get(id: string) -> SubscriptionRow?

One subscription row by id, or nil when the id is unknown (never tracked, or evicted after its publisher was destroyed).

globals/subscriptions/list

globals/subscriptions/list(filter: SubscriptionFilter?) -> { SubscriptionRow }

Every tracked subscription row, optionally filtered by publisher instance id, publisher entity id, event name, and/or connected state.

globals/subscriptions/publishers

globals/subscriptions/publishers() -> { PublisherRow }

Every live event publisher: component instance, entity, and per-event fire stats (fires happen whether or not anyone subscribes) plus current subscriber ids.

globals/text/create

globals/text/create(options: table) -> any

Create a text handle from an initial content + style table. The handle owns a runtime GPU texture (see text.textureGuid); pass it to every other call.

globals/text/destroy

globals/text/destroy(handle: any)

Destroy a text handle and release its raster + glyph layout.

globals/text/listFonts

globals/text/listFonts() -> { string }

List the font families currently available to the text system.

globals/text/loadFont

globals/text/loadFont(ref: any) -> any

Load a font from an asset reference so it becomes available to setStyle's fontFamily.

globals/text/measure

globals/text/measure(handle: any) -> any

Measure the rasterised text in pixels without producing a texture.

globals/text/rasterize

globals/text/rasterize(handle: any, texture: any, scale: number?) -> any

Rasterise the handle's current text + style into the given runtime GPU texture. Bind that texture's guid as a material's base_color_texture to display the text; re-rasterising the same texture overwrites it in place.

globals/text/setStyle

globals/text/setStyle(handle: any, style: table)

Replace the handle's style. Fields not present keep their current value.

globals/text/setText

globals/text/setText(handle: any, content: string)

Replace the handle's text content.

globals/text/textureGuid

globals/text/textureGuid(handle: any) -> string?

The runtime GPU texture guid this handle rasterises into — bind it as a material texture (base_color_texture) to display the text.

globals/toml/encode

globals/toml/encode(root: { [string]: any }) -> string

Encode a Luau table as canonical TOML bytes. Top-level string-keyed sub-tables become section headers ([name]); deeper string-keyed tables become dotted sections ([a.b]). Sequence tables are emitted as inline arrays, and string-keyed tables in value position (e.g. array elements) as inline tables ({ k = v }). Section + key order is alphabetical so the same input always produces the same bytes.

globals/toml/parse

globals/toml/parse(src: string) -> { [string]: any }

Parse a TOML document into a nested Luau table. Sections ([a.b]) become nested tables; key/value pairs become entries on the current section (or root if before any section header). Throws with the line number on syntax errors.

globals/tonumber

tonumber(value, base?) -> number | nil

Convert value to number.

globals/tools/create

globals/tools/create(args: { [string]: any }) -> { ok: boolean, path: string?, identity: string?, signature: string?, error: string? }

Create a new tool on disk inside an EXISTING toolbox. Scaffolds the .tool/ folder via asset.create("tool", …), then writes the supplied code wrapped in a documented typed function into init.luau (the --!desc/--!arg/--!return/ --!example doc block + signature built from the structured metadata), the tags into .metadata, and a brief README.md — so the authored tool is indistinguishable from a builtin. Errors cleanly if the parent toolbox doesn't exist — call tools.createToolbox first so the toolbox starts out with a real description instead of the placeholder template body. The engine's normal hot-reload pipeline picks up the new files and binds the tool's global on the next pass. Every toolbox created via tools.createToolbox ships a shared.module/ (the template default has ok/fail result-envelope constructors; users can extend or replace it via sharedCode at create time or by editing the module later). The generated init.luau automatically declares local shared = require(".shared") before your function body, so the code you pass can reference shared.ok(...) / shared.fail(...) (or whatever the toolbox's custom helpers expose) directly. If a toolbox doesn't have a shared.module/ for some reason, the require is skipped so there's no dangling import to fail.

globals/tools/createToolbox

globals/tools/createToolbox(args: { [string]: any }) -> { ok: boolean, path: string?, identity: string?, error: string? }

Create a new toolbox folder. A toolbox is the namespace container for tools — .toolbox/ on disk; once tools are authored inside it they are invoked as tools.use("<name>", "<toolName>", …). This call scaffolds the .toolbox/ folder via asset.create("toolbox", …) and overwrites the placeholder README.md with a real description so the toolbox doesn't ship the template stub. Optionally seeds shared.module/ if the caller supplies cross-tool helper code. Authoring a tool inside this toolbox is the separate tools.create call.

globals/tools/delete

globals/tools/delete(identity: string) -> { ok: boolean, path: string?, error: string? }

Remove a previously-authored tool by identity. Deletes the .tool/ folder and its contents from the VFS via vfs.remove(..., { recursive = true }). The engine drops the tool's global on the next hot-reload pass. Refuses to operate on a path that doesn't exist (returns { ok = false } with an explanatory error).

globals/tools/get

globals/tools/get(identity: string) -> ToolMeta?

Read back a tool's assembled metadata — description, typed signature, per-argument docs, return, examples, and tags — gathered from the four canonical sources in its .tool/ folder. Individual tools aren't entries in the asset index (only their parent toolboxes are), so this resolves the toolbox via asset.resolve(toolbox, "toolbox") and reads the tool relative to it. Returns nil when the toolbox or tool is missing.

globals/tools/list

globals/tools/list(tier: (number | string)?, toolbox: string?) -> { stdout: string, value: any }

Discover registered code-mode tools, grouped by toolbox. Default tier returns just { <toolbox> = { name, name, … } } plus a formatted stdout listing every toolbox on one line with its tools — compact enough that listing the whole catalogue doesn't flood agent context. Higher tiers enrich each entry with its one-line description (tier 2) or its full assembled metadata — signature, args, returns, examples (tier 3). Pass a toolbox name to restrict the output to one toolbox.

globals/tools/search(query: string?, opts: { toolbox: string?, limit: number? }?) -> { stdout: string, value: any }

Search registered code-mode tools by relevance, the canonical in-engine tool-discovery entry point — callable from execute Luau so an agent can find the tool it needs without leaving the engine. Enumerates every tool across every toolbox (reusing the same filesystem discovery tools.list uses), then scores each against the query: a token hit in the tool NAME weighs most, then its DESCRIPTION, then its TAGS. Tools scoring above zero are returned best-first. With an empty/omitted query and no toolbox filter, returns the whole catalogue (name + signature

  • toolbox) so the agent can browse. Each returned name is the tool's <toolbox>.<tool> identity; invoke it with the use_tool MCP tool (toolbox + tool + positional args), the form each entry's examples are rendered in.

globals/tools/toolboxes

globals/tools/toolboxes() -> { stdout: string, value: { { toolbox: string, purpose: string, toolCount: number } } }

Discover the registered toolboxes as a grouped overview — one row per toolbox with its one-line purpose and tool count. The toolbox-first entry point to tool discovery: an agent navigates by DOMAIN (which toolbox), then drills into a toolbox's tools with tools.search("", { toolbox = "<name>" }). purpose is sourced from the toolbox's README.md (its first descriptive line), falling back to the .metadata description.

globals/tools/use

globals/tools/use(toolbox: string, tool: string, ...: any) -> any

Invoke one code-mode tool by naming its toolbox and tool explicitly — the Luau-code counterpart to the use_tool MCP tool. The normal path is the use_tool MCP tool; this is the escape hatch for editor panels and shipped modules that script a tool from engine Luau. Resolves the toolbox from the runtime store (builtin, library, and user-authored runtime toolboxes all work), calls the named tool with the remaining args, and returns the tool's value directly — unwrapping the ZmToolResult envelope and RAISING a Luau error when the tool fails. Because every call names both toolbox and tool, it can never read as a tools.<box> namespace.

globals/tostring

tostring(value) -> string

Convert value to string.

globals/type

type(value) -> string

Returns type name of a value.

globals/typeof

typeof(value) -> string

Returns detailed type name.

globals/ui/blur

globals/ui/blur()

Surrender keyboard focus from whichever widget currently holds it.

globals/ui/bringAreaToFront

globals/ui/bringAreaToFront(id: string)

Raise a movable area to the top of the window stacking order — the programmatic equivalent of clicking it. egui orders overlapping areas by interaction, so bumping a screen layer alone will NOT bring an unclicked window forward; call this when a taskbar button, focus change, or app launch should bring its window to the front.

globals/ui/captureWindow

globals/ui/captureWindow(screen: string, window: string, opts: CaptureOpts?) -> CaptureResult?

Render a single Window widget to its own offscreen texture and write the result as PNG at /runtime/render_surfaces/<rtHandle>.png. The screen does NOT need to be visible. Returns { rtHandle, texturePath } or nil on invalid inputs (width/height clamped to [1, 8192], defaults 600x400).

globals/ui/click

globals/ui/click(callbackId: string, value: any?)

Simulate a widget click / interaction by its callback id.

globals/ui/defineStyle

globals/ui/defineStyle(name: string, style: StyleProps)

Define a named style. Style keys follow <widgetType>.<className> (e.g. "label.h1", "button.primary") or bare <className> to apply across widget types. Widgets reference styles via the classes (or class) prop.

globals/ui/defineStyles

globals/ui/defineStyles(styles: { [string]: StyleProps })

Define multiple named styles at once.

globals/ui/defineWidget

globals/ui/defineWidget(name: string, builderFn: (WidgetTree, { WidgetTree }) -> WidgetTree)

Register a custom widget kind. When a tree contains { type = name, props = ..., children = ... }, the decoder calls builderFn(props, children) at register / update time and substitutes the returned widget table in place. Errors surface through ui.lastValidation() with codes widget-builder-error / widget-builder-bad-return / decode-recursion-depth-exceeded.

globals/ui/focus

globals/ui/focus(widgetId: string)

Programmatically request keyboard focus on a widget. Queued as a one-shot; the next render of the matching widget calls response.request_focus().

globals/ui/focusedWidget

globals/ui/focusedWidget() -> string?

Return the widget id of whichever widget currently holds keyboard focus, or nil. Snapshotted post-render each frame.

globals/ui/getAreaPos

globals/ui/getAreaPos(id: string) -> AreaPos?

Read the current pivot position of an area widget, including any user drag deltas. Returns { x, y } or nil if the area didn't render this frame.

globals/ui/getAreaSize

globals/ui/getAreaSize(id: string) -> AreaSize?

Read the measured size of an area widget, including any user resize-grip drags if the area is resizable. Returns { w, h } or nil if the area didn't render this frame.

globals/ui/getDockLayout

globals/ui/getDockLayout(id: string) -> string?

Read the current serialized layout (split/tab arrangement) of a dockArea widget as a JSON string. Returns nil if the dockArea didn't render this frame. Persist the string and pass it back via the dockArea's layout prop to restore the arrangement.

globals/ui/getLayoutInfo

globals/ui/getLayoutInfo(widgetId: string?) -> LayoutInfo?

Get layout info (position, size, content bounds) for UI containers. If widgetId is given, returns info for that widget only; otherwise returns all.

globals/ui/getScreenTree

globals/ui/getScreenTree(screenName: string) -> WidgetTree?

Return the last widget tree table passed to registerScreen / updateScreen for screenName.

globals/ui/getTheme

globals/ui/getTheme() -> string

Get the name of the currently active theme.

globals/ui/getToken

globals/ui/getToken(name: string) -> string?

Look up a single design token value from the active theme.

globals/ui/getTokens

globals/ui/getTokens() -> { [string]: string }

Get all design tokens from the active theme as a key-value map.

globals/ui/getWidgetProps

globals/ui/getWidgetProps(typeName: string) -> { WidgetPropDescriptor }?

Get the property definitions for a widget type.

globals/ui/getWidgetTypes

globals/ui/getWidgetTypes() -> { string }

Get all available widget type names that can be used in widget trees.

globals/ui/hideScreen

globals/ui/hideScreen(name: string)

Hide a registered screen.

globals/ui/lastRegistration

globals/ui/lastRegistration() -> { name: string, layer: number? }?

The name and layer passed to the most recent ui.registerScreen call, recorded synchronously at call time. A host that mounts a nested app reads this immediately after the mount to learn which screen the nested code registered, without intercepting the ui table.

globals/ui/lastValidation

globals/ui/lastValidation(screenName: string?) -> any

Validation diagnostics produced at the most recent registerScreen / updateScreen. With no args returns a { [screen] = entry } map; with a name returns that screen's entry or nil. Validation gated by world setting ui.validation = "off" | "warn" | "strict" (default "warn").

globals/ui/listScreens

globals/ui/listScreens() -> { ScreenSummary }

List every registered screen with its current visibility, layer, and whether the screen has a populated root widget tree. Sorted by layer ascending, then name.

globals/ui/listThemes

globals/ui/listThemes() -> { string }

List all registered theme names.

globals/ui/registerBackgroundShader

globals/ui/registerBackgroundShader(shaderHandle: any, width: number?, height: number?)

Register a shader for UI backgrounds. Accepts an asset handle from asset.load(), or legacy (name, wgslSource, width?, height?) for inline source.

globals/ui/registerScreen

globals/ui/registerScreen(name: string, widgetTree: WidgetTree, layer: number?)

Register a named UI screen with a widget tree. Optional layer controls z-ordering (higher = on top). Tag-based grouping lives in Z.tags (Z.tags.set(name, { "editor" }) after register).

globals/ui/registerTheme

globals/ui/registerTheme(name: string, theme: ThemeDefinition)

Register a theme from a flat Luau table. Most callers should use Z.theme.register(name, table) which runs the cascade for them.

globals/ui/removeScreen

globals/ui/removeScreen(name: string)

Alias for ui.unregisterScreen.

globals/ui/resetAreaSize

globals/ui/resetAreaSize(id: string)

Clear a resizable area's remembered size (from a grip drag or ui.setAreaSize) so its declared — or content — size takes over again.

globals/ui/response

globals/ui/response(widgetId: string) -> WidgetResponse?

Per-widget interaction snapshot for the most recent frame. Returns { clicked, hovered, focused, changed, value } where clicked / changed mark transitions and hovered / focused mark current state.

globals/ui/screen

globals/ui/screen(name: string) -> { [string]: any }?

Get a screen proxy with methods like setResolution and rasterize.

globals/ui/screenSize

globals/ui/screenSize() -> { width: number, height: number }

The UI coordinate space as { width, height } (logical points). This is the space area pos, anchors, and getLayoutInfo rects use — and it is NOT the pixel size of a capture screenshot, which may be downscaled. Use this for absolute area positioning (e.g. pinning a menu above a bottom taskbar) instead of guessing the size from a capture image.

globals/ui/scroll

globals/ui/scroll(deltaX: number, deltaY: number)

Simulate a mouse-wheel scroll event on the UI.

globals/ui/setAreaPos

globals/ui/setAreaPos(id: string, x: number, y: number)

Programmatically move a movable area widget to (x, y). Applied for one frame; subsequent frames let drag tracking take over.

globals/ui/setAreaSize

globals/ui/setAreaSize(id: string, w: number, h: number)

Programmatically set a resizable area's size (the user-size override) — for maximize / restore / tile. Persists until the area's declared width/height changes or ui.resetAreaSize(id) clears it.

globals/ui/setScreenRenderLayer

globals/ui/setScreenRenderLayer(name: string, mask: number)

Set a screen's render-layer membership bitmask. A screen draws into a camera or capture only when this mask intersects the camera's include mask — the same rule geometry follows. Content UI defaults to the ui bit; the editor places its chrome on EditorUI so agent captures can drop it. Masks come from __renderLayers.bit(name).

globals/ui/setScrollPosition

globals/ui/setScrollPosition(widgetId: string, offsetY: number)

Set the scroll offset of a scrollArea widget.

globals/ui/setShaderUniforms

globals/ui/setShaderUniforms(name: string, uniforms: { [string]: number })

Set uniform values on a registered background shader.

globals/ui/setTheme

globals/ui/setTheme(name: string)

Switch the active global theme by name.

globals/ui/showScreen

globals/ui/showScreen(name: string)

Make a registered screen visible.

globals/ui/unregisterScreen

globals/ui/unregisterScreen(name: string)

Remove a screen from the registry entirely. Unlike hideScreen, this deletes the entry so it no longer appears in listScreens or render iteration.

globals/ui/unregisterWidget

globals/ui/unregisterWidget(name: string)

Drop a registered custom widget kind. Subsequent references produce an unknown-widget-type diagnostic.

globals/ui/updateScreen

globals/ui/updateScreen(name: string, widgetTree: WidgetTree)

Replace the widget tree of an already-registered screen.

globals/ui/useStyles

globals/ui/useStyles(themeName: string)

Apply a registered style file's classes additively without changing the active theme.

globals/ui/widgetState

globals/ui/widgetState(widgetId: string, key: string, default: any?) -> any

Read per-widget cross-frame state. Returns the value previously written via widgetStateSet, or default (or nil). State is keyed by widget id and persists across re-renders within a screen's lifetime; cleared automatically when the owning screen is unregistered.

globals/ui/widgetStateClear

globals/ui/widgetStateClear(widgetId: string, key: string)

Remove a per-widget state entry.

globals/ui/widgetStateSet

globals/ui/widgetStateSet(widgetId: string, key: string, value: any)

Write per-widget cross-frame state. Replaces any existing value under (widgetId, key). Tables are stored by reference.

globals/unpack

unpack(table, i?, j?) -> values

Unpack table elements as return values.

globals/userfile/pick

globals/userfile/pick(opts: PickOpts?) -> PickResult

Open the user's system file picker and bring the chosen file(s) into the engine. Yields until the user finishes (call from a coroutine / task, like any task.await) and returns { cancelled, files = {{ name, mime, size, bytes?, vfsPath? }} }. Without writeTo each file carries bytes (a binary-safe string); with writeTo each carries vfsPath (read it with vfs.read). Cancelling returns { cancelled = true, files = {} }; a genuine failure (e.g. a lost browser user-activation gesture) raises an error.

globals/userfile/pickFolder

globals/userfile/pickFolder(opts: PickOpts?) -> PickResult

Convenience for userfile.pick({ folder = true }) — pick a whole directory tree. Yields until the user finishes and returns the same result table as pick. On the web this degrades to a multi-file selection.

globals/vfs/clearPlayShadow

globals/vfs/clearPlayShadow() -> boolean

Forget the entire play-shadow set after a bulk promote or discard. Tracking only — never touches the bytes.

globals/vfs/evict

globals/vfs/evict(path: string, opts: VfsOpts?) -> boolean

Drop the in-memory bytes for path from the writable MemFs layer without removing the asset. Use after processing large binaries to reclaim RAM.

globals/vfs/exists

globals/vfs/exists(path: string, opts: VfsOpts?) -> boolean

Is the path known to the VFS? Checks the Stage-1 metadata (.meta sidecar / ManifestView) — NOT "are the bytes locally cached?". Use vfs.read(path) ~= nil to confirm bytes are reachable.

globals/vfs/list

globals/vfs/list(path: string?) -> { VfsListEntry }

List entries in a VFS directory.

globals/vfs/mkdir

globals/vfs/mkdir(path: string, opts: VfsOpts?) -> boolean

Create a directory. mkdir -p semantics — idempotent. Errors if a file already exists at the same path.

globals/vfs/move

globals/vfs/move(src: string, dst: string, opts: { quiet: boolean? }?) -> (boolean, string?)

Move a file from src to dst. By default fires the destination's write side effects; pass opts.quiet = true to suppress them.

globals/vfs/pendingWrites

globals/vfs/pendingWrites() -> { string }

List the /source paths with an in-flight local write the synced manifest has not reflected yet — the read-your-writes frontier. A just-written file appears here until its upload round-trips and the synced dirty state catches up; world.vcsStatus unions these so a fresh edit reads back as dirty immediately. Empty when fully synced.

globals/vfs/playShadowPaths

globals/vfs/playShadowPaths() -> { string }

List the /source paths edited during running play that are currently held as copy-on-write SHADOWS (MemFs-only, on-disk original untouched) — the universal play shadow-copy set. These are the in-play edits persist promotes over the originals on confirm, or drops on a guarded discard. Empty outside play or when nothing was edited.

globals/vfs/promotePlayShadow

globals/vfs/promotePlayShadow(path: string) -> (boolean, string?)

Promote a single play-shadow edit into a canonical write. Re-asserts the live overlay bytes through the full write pipeline with the play write lock released, then unmarks the path. The bytes stay in the engine end to end, so binary content promotes exactly. Requires play to be paused.

globals/vfs/read

globals/vfs/read(path: string, opts: VfsOpts?) -> string?

Read a file from the virtual filesystem. Binary-safe. Returns file contents as a string, or nil if the file is not known. Relative paths resolve under opts.root (default /source/). When called from a coroutine and the bytes aren't locally cached, transparently yields the coroutine while the lazy fetch runs.

globals/vfs/readAsync

globals/vfs/readAsync(path: string, opts: VfsOpts?) -> string

Asynchronous binary-safe read. Returns a promise ID that resolves to the file contents. Useful for reading render textures from the main thread without blocking.

globals/vfs/reload

globals/vfs/reload(modulePath: string?) -> boolean

Clear entries from the require() cache so the next require(name) re-runs the module's source. Pass a single module identity to drop only that entry; call with no arguments to drop every cached module.

globals/vfs/remove

globals/vfs/remove(path: string, opts: VfsOpts?) -> (boolean, string?)

Remove a file. Refuses to remove directories unless opts.recursive = true. Refuses protected system roots.

globals/vfs/revertPlayShadow

globals/vfs/revertPlayShadow(path: string) -> (boolean, string?)

Revert a single play-shadow edit: restore the pre-play copy captured at the first play-mode write (the last edit-mode state, unstaged edits included) into the live slot — or remove the file when it did not exist at that moment — then unmark the path. Hot-reload picks the original back up, so the running session actually reverts. Requires play to be paused.

globals/vfs/unmarkPlayShadow

globals/vfs/unmarkPlayShadow(path: string) -> boolean

Forget a single play-shadow path after it has been promoted (saved over source) or discarded. Tracking only — never touches the bytes.

globals/vfs/unwatch

globals/vfs/unwatch(watcherId: number) -> boolean

TRUSTED ONLY. Remove a previously registered VFS watcher.

globals/vfs/watch

globals/vfs/watch(path: string, callback: (string, string) -> ()) -> number

TRUSTED ONLY. Register a callback that fires when a VFS path is written or removed. Two match modes: exact, or folder/prefix (key ends with /). Callback signature: function(path: string, kind: "write" | "remove"). Returns a watcher id for vfs.unwatch.

globals/vfs/write

globals/vfs/write(path: string, content: string, opts: VfsOpts?) -> (boolean, string?)

Write content to a file. Binary-safe. Overwrites existing files by default — pass opts.overwrite = false to refuse to clobber. Locked in play mode (returns (false, errmsg)).

globals/video/create

globals/video/create(url: string, options: VideoOptions?) -> string

Create a video player. Returns a texture handle (e.g. "video_0") usable directly in material.setTexture() — its frames sample like any other texture.

globals/video/destroy

globals/video/destroy(handle: string) -> boolean

Destroy a video player and free the render target and all resources.

globals/video/getInfo

globals/video/getInfo(handle: string) -> VideoInfo?

Get video information and current playback state.

globals/video/pause

globals/video/pause(handle: string) -> boolean

Pause video playback. Can be resumed with video.play.

globals/video/play

globals/video/play(handle: string) -> boolean

Start or resume video playback.

globals/video/seek

globals/video/seek(handle: string, time: number) -> boolean

Seek to a specific time (seconds) in the video.

globals/video/setLoop

globals/video/setLoop(handle: string, loop: boolean) -> boolean

Enable or disable looping.

globals/video/setRate

globals/video/setRate(handle: string, rate: number) -> boolean

Set the playback speed multiplier. 1.0 = normal, 2.0 = double speed, 0.5 = half speed.

globals/video/stop

globals/video/stop(handle: string) -> boolean

Stop video playback and reset to the beginning.

globals/warn

warn(...)

Emit a warning message at the warn log level. Roblox/Luau-style counterpart to print.

globals/world/add

globals/world/add(path: string, opts: AddOpts?)

Stage one path's manifest row, expanding to the full asset family if the path lives inside a composite asset. Idempotent at (stage, manifest_row). Pass { force = true } to bypass the .zmignore / .gitignore gate — same intent as git add -f. Without force, attempts to stage an ignored path (or a path whose .refs points at an ignored dep) error.

globals/world/add_all

globals/world/add_all() -> { string }

Stage every dirty manifest row, skipping any path that matches .zmignore / .gitignore. Paths that match an ignore pattern are silently skipped — world.add(path, { force = true }) is the explicit way to override the gate for an individual path. Rows still flagged conflicted by world.pullAsset are held back too — resolve them (edit + world.add(path), or world.resolvePullConflict) and re-run.

globals/world/affirm

globals/world/affirm(token: string)

Consume an XXX-XXX-XXX-style affirmation token returned by a destructive op surface (e.g. vfs.remove). The destruction commits atomically with the pending-row delete; the token is one-shot. Errors verbatim on expiry / wrong-user.

globals/world/args

globals/world/args() -> any

globals/world/avatar_default_edit

globals/world/avatar_default_edit() -> any

globals/world/avatar_default_play

globals/world/avatar_default_play() -> any

globals/world/camera_default_edit

globals/world/camera_default_edit() -> any

globals/world/camera_default_play

globals/world/camera_default_play() -> any

globals/world/checkUpdates

globals/world/checkUpdates() -> { UpdateReport }

Discover upstream changes for every asset this world has pulled. Read-only — makes no local mutation and no VCS write. Each locally-pulled row identifies its own origin asset via origin_asset_guid (recorded as that entry's own asset guid at pull time — see world.installAsset). For every distinct origin asset among the pulled rows, this re-resolves that asset's latest transitive closure and compares each returned entry's checksum against the matching local row's recorded origin_checksum.

globals/world/commit

globals/world/commit(message: string) -> string

globals/world/conflicts

globals/world/conflicts() -> { ConflictEntry }

List every locally-pulled row currently flagged conflicted — the findable surface world.pullAsset leaves behind on an unresolved merge. Read-only.

globals/world/connectedUsers

globals/world/connectedUsers() -> any

globals/world/contentRequirements

globals/world/contentRequirements(scope: { string }?) -> { { asset: string, typeName: string, detail: string } }

List the world's unmet content requirements: user-authored assets whose type-declared content constraints are not yet satisfied (an empty README, a .metadata with no description or tags — the empty-skeleton state a fresh create emits for the author to fill). The same walk world.push gates on: push refuses while this list is non-empty, and zm status surfaces it as "requires content before publish". Empty list = every checked asset meets its type's contract.

globals/world/contribute

globals/world/contribute(opts: ContributeOpts?) -> { ContributeOutcome }

Send improvements to installed content back upstream — git subtree push ending in a pull request. For each targeted origin world: the diverging subtree is remapped to the origin's canonical paths, three-way merged against the origin's CURRENT content (regions the origin also changed become local conflicts to resolve first), pushed as a contrib/<id> branch in the origin world, and opened as a pull request there. With merge (the default) the pull request is merged immediately when authorized — a refusal leaves it open and reported, never a failure. After a merge, the local fork re-pulls so its origin pins advance and the asset no longer reads as ahead.

globals/world/createBranch

globals/world/createBranch(name: string, fromCommit: string?)

Create a branch — git branch <name> [<start>]. The branch starts at fromCommit (defaults to the session branch's HEAD) and gets its own working tree, materialized from that commit. The session stays on its current branch; move with world.swap(world.guid(), "", "", "<branch>") (git checkout).

globals/world/diff

globals/world/diff(...: string) -> any

Mirror git diff's CLI arg shape. Returns per-file diffs by default; pass --stat for summary stats, --name-only for just paths. Positional commit ids drive the two sources; --staged pivots to staged-vs-HEAD. ---separated args scope the diff to specific paths.

globals/world/discard

globals/world/discard()

Drop the implicit stage without committing. Live manifest dirty flags are preserved so the user can re-stage later. No-op if the stage doesn't exist.

globals/world/discardFile

globals/world/discardFile(path: string)

Discard one file's unstaged working edits, reverting its content to the last commit — the git restore <path> shape. One shot: the discarded bytes are snapshotted to trash first, so the discard is recoverable via world.restore(<handle>). Errors when the path is not dirty (nothing to discard) or was never committed (nothing to revert to — remove it instead).

globals/world/fetch

globals/world/fetch(branch: string?) -> FetchResult

Update the origin/<branch> remote-tracking ref — git fetch. Mirrors the world's ZeroMind branch head into the local commit history (no working-tree change) and reports how the session branch relates to it: behind origin commits to pull, ahead local commits to push, diverged when both. A stale installed pin or out-of-band ZeroMind change shows up here as behind — reconcile with world.pull().

globals/world/forkLive

globals/world/forkLive(opts: { source: string, sourceBranch: string?, maxBatches: number? }) -> number

Seed THIS (empty) world's live content from another world by copying its whole manifest as clean Pulled rows — the in-engine half of "fork a world". Provenance is preserved: each row points at the content's ORIGINAL owner (a fork of a fork-of-A still points at A), so the fork never claims to have authored what it pulled. The copy runs server-side in bounded batches (idempotent + resumable), looping until the source is fully mirrored. Pair with world.add_all() + world.commit() + world.push() to publish the fork.

globals/world/forkStatus

globals/world/forkStatus() -> { ForkStatus }

Per-asset "ahead of origin" report — the fork analogue of git status against an upstream. Every installed (pulled) row whose content diverges from its pinned origin is listed, partitioned by the TRUE origin world it was pulled from (nested dependencies carry the world that authored them, not the intermediary they arrived through). This is information for judgment: decide whether a change belongs upstream, then world.contribute.

globals/world/head

globals/world/head() -> string?

Return the current branch HEAD commit id, or nil if the branch has no commits yet.

globals/world/installAsset

globals/world/installAsset(opts: InstallAssetOpts) -> InstallAssetResult

globals/world/installLibrary

globals/world/installLibrary(opts: InstallLibraryOpts) -> InstallLibraryResult

Declarative cross-world dependency. Writes a single marker file at /source/libs/@<name> whose body is the zero/world-import/v1 JSON. The next commit ships it as one regular manifest entry; ZM's import-derivation pass at finalize-time decodes the marker and stamps the new commit's imports[]. Unmodified library content never ships in the importing world's tree — it's fetched from the source world on demand by the engine's library resolver.

globals/world/list

globals/world/list() -> { WorldEntry }

List every world the authenticated user has access to. Calls the spacetime list_my_worlds procedure which wraps ZeroMind's GET /v1/me/worlds. Flattens each entry to one record per world with the role promoted to a top-level field.

globals/world/log

globals/world/log(opts: LogOpts?) -> { CommitRow }

Return the commit log for the current branch, newest first. Pass opts.path to get the per-path history (git log -- <path>): only the commits that touched that file, newest-first.

globals/world/merge

globals/world/merge(sourceBranch: string) -> MergeResult

Merge another branch into the session branch — git merge <source>. The merge runs locally in the world's SpacetimeDB clone and is abortable with world.mergeAbort; nothing reaches ZeroMind until the result is pushed. Requires a clean working tree (commit or stash first — that is also what makes abort exact). Clean → a two-parent merge commit lands on the session branch and the merged content appears in the working tree. Conflicts → git-style markers are projected into each conflicting text file, the cleanly-merged remainder is applied as working-tree changes, and world.vcsStatus().unmerged lists what needs attention: resolve each path (edit out the markers / rewrite / remove the file), then world.add + world.commit — that commit records the merge (second parent = the source head) and clears the unmerged set.

globals/world/mergeAbort

globals/world/mergeAbort()

Abort the in-progress merge — git merge --abort. Clears the unmerged set and restores the working tree to the pre-merge state (the target head's committed content; the branch head never moved during a conflicted merge). Errors when no merge is in progress.

globals/world/prList

globals/world/prList(worldGuid: string?, number: number?) -> any

List a world's pull requests, or fetch one.

globals/world/prMerge

globals/world/prMerge(worldGuid: string, number: number, strategy: string?) -> any

Merge a pull request — the agent-side merge button.

globals/world/previewInstall

globals/world/previewInstall(opts: InstallAssetOpts) -> PreviewResult

Preview what installing an asset WOULD write, without writing anything. Fetches + decodes the closure and plans placement (the same helpers world.installAsset uses), returning a flat node list plus rollup totals. A truncated closure is reported (not raised) so a caller can surface it and block import.

globals/world/pull

globals/world/pull(branch: string?) -> PullResult

Fetch and reconcile with origin — git pull. Strictly behind → fast-forward (the branch head moves to the origin mirror, no merge commit). Diverged → three-way merge of the origin mirror, with the same conflict/marker/resolve flow as world.merge (resolve the unmerged paths, then world.add + world.commit; abortable with world.mergeAbort). Requires a clean working tree.

globals/world/pullAsset

globals/world/pullAsset(opts: PullAssetOpts?) -> PullAssetResult

globals/world/push

globals/world/push(commitId: string?) -> string?

Publish the current branch to ZeroMind. The no-argument form is a git merge --squash push: EVERY unpushed commit on the branch collapses into a SINGLE ZeroMind commit (latest content per path, parented on the branch's current remote HEAD). Because only the merged final state's bytes are uploaded, a superseded or lost intermediate-commit blob can never break the push — this is what makes a churn-heavy world publishable. The local commit history is preserved as the editing journal; on success every squashed commit shares the one remote commit id. The explicit commitId form still pushes that single commit verbatim via publish_commit (advanced / chain-replay use; its parent must already be on the remote).

globals/world/reset

globals/world/reset(targetCommitId: string) -> string?

Rewind HEAD to targetCommitId in one shot. Non-destructive — orphaned commits stay in storage and each becomes a trash entry the user can world.restore (in chain order) to re-attach the branch. Errors when targetCommitId is not an ancestor of HEAD. Returns a summary of what was rewound.

globals/world/resolveConflict

globals/world/resolveConflict(path: string, mode: string, content: string?) -> ResolveResult

Resolve one conflicted /source record, one path at a time. mode is merge | apply | take-local | take-backend | discard. merge returns { merged, clean } and mutates nothing — a clean merge can be finalized with apply, and a conflicted one carries <<<<<<< / ======= / >>>>>>> markers to edit first. apply writes the finalized content to /source; take-local writes the retained local bytes; take-backend / discard keep the backend head. Errors when the record is absent, a merge has no common ancestor or hits binary content, or a write fails.

globals/world/resolvePullConflict

globals/world/resolvePullConflict(path: string, choice: string)

globals/world/restore

globals/world/restore(handle: any)

Restore one trash entry by row_id. Errors verbatim on handler-not-yet-implemented / world-mismatch.

globals/world/show

globals/world/show(...: string) -> any

Mirror git show's CLI arg shape. Default returns commit metadata + full diff vs parent. world.show("commit:/path") returns just the bytes. Flags: --stat, --name-only.

globals/world/startup_scene

globals/world/startup_scene() -> any

globals/world/stash

globals/world/stash(label: string?)

Save the caller's current pending dirty + staged state on the active (world, branch) into a stash row. label is optional free-form text. Non-destructive — dirty + staged state is preserved on disk.

globals/world/stashDrop

globals/world/stashDrop(handle: any)

Request an affirmation token to drop a stash. Always errors — successful mint surfaces the token as affirmation required: zm affirm <token>. The agent runs zm affirm <token> to actually drop; restoration via world.restore() reappears the stash under a new row_id.

globals/world/stashPop

globals/world/stashPop(handle: any) -> StashSnapshot

Author-only. Pop the stash row (deletes it server-side) and return the decoded snapshot. The caller is responsible for re-applying the snapshot to disk via the normal write paths (so ACL gates fire on every restored path).

globals/world/stashes

globals/world/stashes() -> { StashRow }

List every stash row in the world. Anyone with read access sees every stash; the per-row author_hex makes it clear which entries the caller can pop / drop themselves.

globals/world/status

globals/world/status() -> any

globals/world/status_text

globals/world/status_text() -> any

globals/world/syncStatus

globals/world/syncStatus() -> SyncStatus

Read the durable-sync status: { subscribed, content_synced, progress, pending_writes, conflicts }. conflicts maps each conflicted /source path to { base_sha, local_sha, backend_sha, isBinary }. Synchronous.

globals/world/trash

globals/world/trash() -> { TrashRow }

List trash entries for the world. Anyone with read access to the world can list trash — recovery is a shared safety net, not a privacy boundary. The handle (row_id) feeds back into world.restore.

globals/world/uninstallLibrary

globals/world/uninstallLibrary(name: string) -> string

Delete the library marker file. name accepts "@combat" or "combat" (the leading @ is the convention carried by the on-disk path).

globals/world/unstage

globals/world/unstage(path: string)

Remove a path from the staging area. Live manifest dirty state is untouched.

globals/world/vcsStatus

globals/world/vcsStatus() -> StatusResult

Return the working-tree VCS status: dirty paths, staged entries, and (always empty in the spacetime model) untracked. Named vcsStatus (not status) because world.status() is the runtime-snapshot accessor owned by world_status.module; the source-control surface keeps its own VCS-specific name so the two never shadow each other. Each dirty[i].dirtied_by is the SpacetimeDB Identity hex of the most recent writer; dirty_since_micros is the microsecond timestamp of the first write of the current dirty run.

globals/worldToScreen

worldToScreen(x, y, z) -> sx, sy

Project a world-space point to screen-space coordinates.

globals/xpcall

xpcall(fn, handler, ...) -> ok, result

Protected call with custom error handler.

  • api
  • reference