---
title: "typed"
description: "The typed namespace — the engine's Luau API reference for typed."
section: "API Reference"
slug: "api-typed"
canonical: "https://origozero.ai/docs/api-typed"
updated: "2026-09-07T03:15:14.060489772+00:00"
tags: ["api", "reference"]
---

# typed

The `typed` namespace — 2090 functions.

## typed/builtin//assetTypes/agentSkill/behavior/M/onChange {#typed-builtin-assettypes-agentskill-behavior-m-onchange}

```lua
M.onChange(self: any?, change: any?)
```

Lifecycle hook: re-publish this skill when anything inside its folder
is written, so a skill just authored is listed and an edited description
is the one agents see. Reads the manifest and writes nothing back.

**Parameters**

- `self` `any` _(optional)_ — The changed skill's AssetRef.
- `change` `any` _(optional)_ — The write record the dispatcher passes through.

## typed/builtin//assetTypes/agentSkill/behavior/M/onRegister {#typed-builtin-assettypes-agentskill-behavior-m-onregister}

```lua
M.onRegister(self: any?)
```

Lifecycle hook: publish this skill to the roster agents read when the
skill first registers. The scope it is listed under is derived from the
asset's own identity.

**Parameters**

- `self` `any` _(optional)_ — The registering skill's AssetRef.

## typed/builtin//assetTypes/avatar/behavior/M/onCreate {#typed-builtin-assettypes-avatar-behavior-m-oncreate}

```lua
M.onCreate(name: string, opts: CreateOpts?) -> { [string]: string }
```

Generic-creation hook for `asset.create("avatar", name, opts)`. Composes
the avatar from a `body` plus an independent movement controller and
animation system, written as `avatar.json`. The `body` is a `.bundle`
(skinned mesh + bones), a plain `.mesh` (a simple visual), or omitted (a
body-less avatar — a controller / first-person camera with no mesh).
Defaults: the standard humanoid controller and, for a humanoid body, the
shared `Locomotion` (clips from the `locomotion` preset, default "synty").
Override `animation` to author your own locomotion without touching movement;
pass `controller = false` for a body the engine doesn't move; pass `clip` for
a single-clip `ClipPlayer`. Humanoid-ness drives the default animation only
and is auto-derived from a rigged body; pass `humanoid` to set it explicitly
(e.g. a body-less first-person avatar that still carries `Humanoid`).

**Parameters**

- `name` `string`
- `opts` `CreateOpts` _(optional)_

**Returns** `{ [string]: string }` — `{ ["avatar.json"] = <json> }`.

```lua
asset.create("avatar", "my_hero", { body = heroBundle })  -- standard controller + locomotion
asset.create("avatar", "fp_player", { humanoid = true })  -- body-less first-person player
```

## typed/builtin//assetTypes/bundle/behavior/M/onCreate {#typed-builtin-assettypes-bundle-behavior-m-oncreate}

```lua
M.onCreate(name: string, opts: CreateOpts?) -> { [string]: string }
```

Generic-creation hook for `asset.create("bundle", name, opts)`.
With `opts.entity`, composes that LIVE entity's hierarchy into the new
bundle's `entity_template` in the same call — one step, capturing live
component state (serialized component snapshots) + transforms of the root and
every non-temporary descendant. With no opts, the bundle starts from
the template skeleton's `entity_template`.

**Parameters**

- `name` `string`
- `opts` `CreateOpts` _(optional)_

**Returns** `{ [string]: string }` — `{ entity_template = <JSON> }` when `opts.entity` is given, else `{}`.

```lua
asset.create("bundle", "tree_prefab", { entity = rootRef })
```

## typed/builtin//assetTypes/computeShader/behavior/TextureHandleMethods/destroy {#typed-builtin-assettypes-computeshader-behavior-texturehandlemethods-destroy}

```lua
TextureHandleMethods.destroy(self: any?) -> boolean
```

Destroy this texture or sampler and free its GPU memory.

**Parameters**

- `self` `any` _(optional)_

**Returns** `boolean` — True on success.

## typed/builtin//assetTypes/computeShader/behavior/TextureHandleMethods/read {#typed-builtin-assettypes-computeshader-behavior-texturehandlemethods-read}

```lua
TextureHandleMethods.read(self: any?) -> Readback
```

Start a GPU→CPU read-back of this 3D texture's voxels. The read takes
frames to arrive — ask the returned `Readback` whether it is `:ready()`,
then drain it.

## typed/builtin//assetTypes/computeShader/behavior/TextureHandleMethods/write {#typed-builtin-assettypes-computeshader-behavior-texturehandlemethods-write}

```lua
TextureHandleMethods.write(self: any?, data: buffer | string | { number }) -> boolean
```

Upload voxels into this 3D texture: a `buffer` or a binary string
carrying the texture's byte layout verbatim, or one number per channel in
the texture's format.

**Parameters**

- `self` `any` _(optional)_
- `data` `buffer | string | { number }` — Voxel bytes, or voxel values in texel order.

**Returns** `boolean` — True on success.

## typed/builtin//assetTypes/computeShader/behavior/TextureHandleMethods/writeFloats {#typed-builtin-assettypes-computeshader-behavior-texturehandlemethods-writefloats}

```lua
TextureHandleMethods.writeFloats(self: any?, floats: { number }, formatOrOpts: (string | { [string]: any })?) -> boolean
```

Upload float voxels into this 3D texture, converting to the texture's
format.

**Parameters**

- `self` `any` _(optional)_
- `floats` `{ number }` — Voxel values in texel order.
- `formatOrOpts` `(string | { [string]: any })` _(optional)_ — Source format name, or an options table.

**Returns** `boolean` — True on success.

## typed/builtin//assetTypes/dynamicAsset/behavior/M/onChange {#typed-builtin-assettypes-dynamicasset-behavior-m-onchange}

```lua
M.onChange(ref: any?, change: any?)
```

Regenerate this dynamic asset when its own `prompt.json` is written with
a prompt other than the one already generated. A write anywhere else in the
instance is ignored, and a prompt arriving while a generation is in flight is
held for the poll loop to pick up when that one settles.

**Parameters**

- `ref` `any` _(optional)_ — The changed `.dynamicAsset`'s reference.
- `change` `any` _(optional)_ — The change record the asset dispatcher raised for the write.

## typed/builtin//assetTypes/effect/behavior/M/onChange {#typed-builtin-assettypes-effect-behavior-m-onchange}

```lua
M.onChange(ref: any?, change: any?)
```

Drop the effect declaration cached on this ref after a write inside the
instance, so the next read re-parses `effect.yaml` from the file on disk.

**Parameters**

- `ref` `any` _(optional)_ — The changed `.effect` asset's reference.
- `change` `any` _(optional)_ — The change record the asset dispatcher raised for the write.

## typed/builtin//assetTypes/font/behavior/M/onRegister {#typed-builtin-assettypes-font-behavior-m-onregister}

```lua
M.onRegister(self: any?)
```

Install this `.font` instance into the engine's text systems. Reads the
instance's baked `data.zfnt` and calls `font.register(name, zfnt)`, which
loads the vectorized glyph data into the runtime store (for `font.glyph` /
`font.textMesh`) and feeds the embedded font bytes to the 2D/3D text and
egui UI systems. Falls back to a raw font file for instances authored
before the baked layout (`font.register` reparses, with a slow-path warn).
Fired once per instance by the asset system (live on `asset.create`, and in
the world-load sweep). Guarded so a single bad font never errors the sweep.

**Parameters**

- `self` `any` _(optional)_

## typed/builtin//assetTypes/inputMap/behavior/M/onChange {#typed-builtin-assettypes-inputmap-behavior-m-onchange}

```lua
M.onChange(self: any?, change: any?)
```

Re-activate this map after a write inside the instance, so an edit
to its bindings takes hold in the running session. Only the map that is
currently active is re-activated; a removal is ignored.

**Parameters**

- `self` `any` _(optional)_ — The changed `.inputMap` asset's reference.
- `change` `any` _(optional)_ — The change record the asset dispatcher raised for the write.

## typed/builtin//assetTypes/mesh/behavior/M/onCreate {#typed-builtin-assettypes-mesh-behavior-m-oncreate}

```lua
M.onCreate(name: string, opts: CreateOpts) -> { [string]: string }
```

Generic-creation hook for `asset.create("mesh", name, opts)`. Pure:
returns the content-file map; `asset.create` writes it to the authored
destination, registering the `.mesh` asset under its minted guid. Disk-only —
nothing is uploaded to the GPU here (the GPU mesh is a separate, explicit
`renderer.mesh.create` step keyed by this asset's guid).

`opts` is raw geometry `{ positions, indices, normals?, uvs?, colors? }`
(flat float / u32 arrays, encoded to `data.zmsh` via `renderer.mesh.encode`),
or a pre-encoded `{ bytes }` payload (stored verbatim).

**Parameters**

- `name` `string` — Mesh identity (the instance name).
- `opts` `CreateOpts`

**Returns** `{ [string]: string }` — `{ ["data.zmsh"] = <ZMSH> }` — the container's primary content file.

```lua
asset.create("mesh", "tree", { positions = {...}, indices = {...} })
```

## typed/builtin//assetTypes/population/behavior/Live/bounds {#typed-builtin-assettypes-population-behavior-live-bounds}

```lua
Live.bounds(self: any?) -> any
```

The world-space box the drawn instances occupy — each variant's mesh
AABB carried through every one of its matrices. The matrices are
world-space, so this is where the population stands, whatever entity owns
it.

**Parameters**

- `self` `any` _(optional)_

**Returns** `any` — `{ min, max }` as Vec3 tables, or nil once nothing is registered.

```lua
local box = live:bounds()
```

## typed/builtin//assetTypes/population/behavior/Live/count {#typed-builtin-assettypes-population-behavior-live-count}

```lua
Live.count(self: any?) -> number
```

Instances the engine reports drawing across every registration this
holds. Read back from the renderer rather than from the recipe, so a
registration that went away, or that the renderer turned away, counts as
gone.

**Parameters**

- `self` `any` _(optional)_

**Returns** `number` — Instance count.

```lua
print(live:count())
```

## typed/builtin//assetTypes/population/behavior/Live/destroy {#typed-builtin-assettypes-population-behavior-live-destroy}

```lua
Live.destroy(self: any?)
```

Release every registration and its transform buffer. The draw is
dropped BEFORE its buffer is destroyed: a registration reserves slots
against the buffer it was given, so a buffer that goes away takes its
registration with it. The meshes belong to their `.mesh` assets and stay.
A second call finds an empty list and returns.

**Parameters**

- `self` `any` _(optional)_

```lua
live:destroy()
```

## typed/builtin//assetTypes/population/behavior/Live/drawCalls {#typed-builtin-assettypes-population-behavior-live-drawcalls}

```lua
Live.drawCalls(self: any?) -> number
```

Draw calls this population costs — one per variant the renderer is
drawing, at any instance count. A variant the renderer turned away costs
nothing and is counted nowhere; `:errors()` says why.

**Parameters**

- `self` `any` _(optional)_

**Returns** `number` — Registration count.

```lua
print(live:drawCalls())
```

## typed/builtin//assetTypes/population/behavior/Live/errors {#typed-builtin-assettypes-population-behavior-live-errors}

```lua
Live.errors(self: any?) -> { any }
```

Why this population is drawing less than its recipe asks for: one entry
per registration the renderer turned away, carrying the variant it belongs
to, the mesh it names and the renderer's own reason. A population drawing
everything it holds answers with an empty list, so this and `:drawCalls()`
agree with the frame.

**Parameters**

- `self` `any` _(optional)_

**Returns** `{ any }` — Array of `{ variant, meshGuid, error }`.

```lua
for _, e in ipairs(live:errors()) do warn(e.variant, e.error) end
```

## typed/builtin//assetTypes/population/behavior/Live/settled {#typed-builtin-assettypes-population-behavior-live-settled}

```lua
Live.settled(self: any?) -> boolean
```

Whether the renderer has answered for every registration this holds.
A registration is made a stage before the renderer sees it, so the frame it
is made in is one where nothing yet says whether the copies are drawn;
`:errors()` is complete from the frame this turns true.

**Parameters**

- `self` `any` _(optional)_

**Returns** `boolean` — `true` once every registration has an answer.

```lua
if live:settled() then check(live:errors()) end
```

## typed/builtin//assetTypes/population/behavior/M/onCreate {#typed-builtin-assettypes-population-behavior-m-oncreate}

```lua
M.onCreate(name: string, opts: CreateOpts?) -> { [string]: string }
```

Generic-creation hook for `asset.create("population", name, opts)`.
Pure: returns the content-file map; `asset.create` writes it to the
mode-aware destination. Each variant contributes its mesh + material to
`population.json` and its matrices to `transforms.bin`, in variant order.

**Parameters**

- `name` `string` — Population identity (the instance name).
- `opts` `CreateOpts` _(optional)_

**Returns** `{ [string]: string }` — `{ ["population.json"] = <JSON>, ["transforms.bin"] = <blob> }`.

```lua
asset.create("population", "forest", { variants = { { mesh = meshGuid, material = matGuid, transforms = flat } } })
```

## typed/builtin//assetTypes/rig/behavior/M/onChange {#typed-builtin-assettypes-rig-behavior-m-onchange}

```lua
M.onChange(self: any?, _change: any?)
```

Drop the cached decode when the rig's content changes — a hot-reload
or a re-import — so the next `:doc()` re-parses the new `rig.json`.

**Parameters**

- `self` `any` _(optional)_ — The rig AssetRef that changed.
- `_change` `any` _(optional)_ — What happened to it; the cache is dropped whatever it was.

## typed/builtin//assetTypes/rig/behavior/M/onCreate {#typed-builtin-assettypes-rig-behavior-m-oncreate}

```lua
M.onCreate(name: string, opts: CreateOpts) -> { [string]: string }
```

Generic-creation hook for `asset.create("rig", name, opts)`. Pure:
returns the content-file map; `asset.create` writes it to the authored
destination, registering the `.rig` asset under its minted guid. The JSON
document carries the skeleton, its retarget profile (the role -> bone driver,
present for a humanoid), and its humanoid classification — a non-humanoid rig
(a prop, a plant, a quadruped) simply has no profile in the same document.

**Parameters**

- `name` `string` — Rig identity (the instance name).
- `opts` `CreateOpts`

**Returns** `{ [string]: string }` — `{ ["rig.json"] = <json> }`.

```lua
asset.create("rig", "PolygonSyntyCharacter", { json = rigJson })
```

## typed/builtin//assetTypes/testSuite/shared/Test/afterEach {#typed-builtin-assettypes-testsuite-shared-test-aftereach}

```lua
Test.afterEach(fn: () -> ())
```

Register an after-each hook on the current suite. Runs after
every test body in the suite. Hook errors print a warning rather
than aborting `Test.run`.

**Parameters**

- `fn` `() -> ()` — The hook function.

```lua
Test.afterEach(function() layers.active:reload() end)
```

## typed/builtin//assetTypes/testSuite/shared/Test/beforeEach {#typed-builtin-assettypes-testsuite-shared-test-beforeeach}

```lua
Test.beforeEach(fn: () -> ())
```

Register a before-each hook on the current suite. Runs before
every test body in the suite. Hook errors mark the test failed
rather than aborting `Test.run`.

**Parameters**

- `fn` `() -> ()` — The hook function.

```lua
Test.beforeEach(function() engine.mode = "edit" end)
```

## typed/builtin//assetTypes/testSuite/shared/Test/beginWorldBaseline {#typed-builtin-assettypes-testsuite-shared-test-beginworldbaseline}

```lua
Test.beginWorldBaseline() -> WorldBaseline
```

Capture a clean-slate world baseline: snapshot every non-persistent
layer (by guid + additive flag) then unload them, so suites can't depend
on whatever scene the engine booted with. Persistent layers (e.g. the
editor overlay) are left untouched. Holds until the unload cascade has
landed, so the first suite starts on a world that has stopped moving. Pair
with `Test.restoreWorldBaseline` to put the captured layers back
afterwards.

**Returns** `WorldBaseline` — A `WorldBaseline` token to hand to `Test.restoreWorldBaseline`.

```lua
local base = Test.beginWorldBaseline(); ...; Test.restoreWorldBaseline(base)
```

## typed/builtin//assetTypes/testSuite/shared/Test/captureFailure {#typed-builtin-assettypes-testsuite-shared-test-capturefailure}

```lua
Test.captureFailure(fn: () -> ()) -> string?
```

Run a body and return the failure it records instead of recording it.
Matchers report by flagging the running test, so a test that asserts a
matcher rejects something would flag itself; this hands back the rendered
message and leaves the surrounding test's own state untouched. A body that
records more than one failure returns the headline for them — use
`Test.captureOutcome` for the whole ordered list.

**Parameters**

- `fn` `() -> ()` — The body to run. Errors it raises propagate to the caller.

**Returns** `string?` — The rendered failure message, or nil when the body recorded none.

```lua
local msg = Test.captureFailure(function() Test.expect(1).toBe(2) end)
Test.expect(msg).toContain("to be 2")
```

## typed/builtin//assetTypes/testSuite/shared/Test/captureOutcome {#typed-builtin-assettypes-testsuite-shared-test-captureoutcome}

```lua
Test.captureOutcome(fn: () -> ()) -> Outcome
```

Run a body the way the runner runs a test body and hand back everything
that would be reported for it: the failures it recorded in the order they
happened, the headline composed from them, and whether a raise ended it. A
raise is recorded as the final failure, which is how the runner treats one.
The surrounding test's own record stays untouched.

**Parameters**

- `fn` `() -> ()` — The body to run.

**Returns** `Outcome` — `{ failed, error, failures, raised }`.

```lua
local o = Test.captureOutcome(function() Test.expect(1).toBe(2); error("boom") end)
Test.expect(o.failures[1]).toBe("Expected 1 to be 2")
```

## typed/builtin//assetTypes/testSuite/shared/Test/captureTestOutcome {#typed-builtin-assettypes-testsuite-shared-test-capturetestoutcome}

```lua
Test.captureTestOutcome(spec: TestSpec) -> TestOutcome
```

Run a test's whole lifecycle the way the runner runs one — `beforeEach`,
the body, `afterEach`, then the cleanups registered while it ran — and hand
back the verdict composed from everything all of them recorded. The runner
reads its verdict from the same place, so what this reports for a test is
what a sweep reports for it. A failure a hook records names the hook it came
from. The surrounding test's own record stays untouched.

**Parameters**

- `spec` `TestSpec` — `{ body, beforeEach, afterEach, name }`. Only `body` is required.

**Returns** `TestOutcome` — `{ skipped, reason, failed, error, failures, raised }`.

```lua
local o = Test.captureTestOutcome({ body = function() end, afterEach = function() Test.expect(1).toBe(2) end })
Test.expect(o.failures[1]).toBe("afterEach: Expected 1 to be 2")
```

## typed/builtin//assetTypes/testSuite/shared/Test/cleanupTmp {#typed-builtin-assettypes-testsuite-shared-test-cleanuptmp}

```lua
Test.cleanupTmp()
```

Remove the sandbox tmp root and everything in it. Logs a warning
if the remove fails but doesn't error.

```lua
Test.cleanupTmp()
```

## typed/builtin//assetTypes/testSuite/shared/Test/clear {#typed-builtin-assettypes-testsuite-shared-test-clear}

```lua
Test.clear()
```

Clear all suites and reset stats / leaked-id tracking. Use this
to re-run the suite from a clean state (in particular: re-runs in
the same execute() batch).

```lua
Test.clear()
```

## typed/builtin//assetTypes/testSuite/shared/Test/clearLoadedLayers {#typed-builtin-assettypes-testsuite-shared-test-clearloadedlayers}

```lua
Test.clearLoadedLayers()
```

Put the world back to the clean slate a sweep begins from: the run's
stand-in root released, and every non-persistent layer unloaded.

A sweep takes its baseline once and restores it once, so a suite that loads
a scene and does not put it back hands that scene to every suite after it.
What the next suite then meets is not the slate it was written against —
and a scene expecting player spawns without a PlayerSpawn refuses the
`engine.mode = "play"` its `beforeEach` asks for, so the suite fails whole
for something the suite before it did. Which suites those are depends on
the order the sweep sharded them into, so the failure moves between runs.

**Returns** Nothing.

```lua
Test.clearLoadedLayers()
```

## typed/builtin//assetTypes/testSuite/shared/Test/closeSuiteBoundary {#typed-builtin-assettypes-testsuite-shared-test-closesuiteboundary}

```lua
Test.closeSuiteBoundary(suite: string, pre: SuiteBoundary) -> SuiteHandover
```

Close a boundary opened by `Test.openSuiteBoundary`: unload the layers
the suite loaded and left, name the render-feature identities it left
registered, and write a line to the engine log for each of the two that has
something to say. This is the per-suite handover, so a caller running one
suite after another has one call to make between them. The boundary it
names leaves the open set, so `Test.suiteBoundary` goes back to the one
around it.

It answers for what is standing, and it spends no frames finding out: a
caller that needs the queued teardown to have landed before it reads a
count calls `Test.settleWorldTeardown` around its own reading, and pays the
frames where it wants them.

What it answers for is what the suite ADDED to the world it was handed: a
layer that appeared between the two reads is unloaded, and a render-feature
identity that appeared is named. A layer or a feature the suite took away
is the suite's own doing and stands as the suite left it.

**Parameters**

- `suite` `string` — The name to attribute what crossed to, as it reads in the log.
- `pre` `SuiteBoundary` — The token `Test.openSuiteBoundary` returned.

**Returns** `SuiteHandover` — `{ suite, layers, features }` — the name it was given, the layer guids it asked the engine to unload, and the feature identities left standing. The same record is published as `Test.lastSuiteHandover`.

```lua
local left = Test.closeSuiteBoundary("vfs", pre)
```

## typed/builtin//assetTypes/testSuite/shared/Test/componentRegistered {#typed-builtin-assettypes-testsuite-shared-test-componentregistered}

```lua
Test.componentRegistered(name: string) -> boolean
```

Whether a component type is registered under `name`, so that
`component.add(name)` takes it. An authored component's asset resolves
the moment its source is written; the type it declares registers when
that registration drains, on a later frame, and this reads the
registration through the handle's own `isRegistered()`, the ECS
registry a queued `component.add` is routed by.

**Parameters**

- `name` `string` — The component type name.

**Returns** `boolean` — true once the type is registered, false until then.

```lua
Test.waitUntil(function() return Test.componentRegistered("Probe") end, 120)
```

## typed/builtin//assetTypes/testSuite/shared/Test/describe {#typed-builtin-assettypes-testsuite-shared-test-describe}

```lua
Test.describe(name: string, fn: () -> ()) -> Suite
```

Define a test suite. Collects tests via `Test.it` / `Test.skip`
calls inside the supplied function and registers them under `name`.
Per-suite and per-test documentation (overall description + per-test
pass condition) is authored as `--!desc` / `--!pass` doc-comments
above the `Test.describe` / `Test.it` calls and extracted statically
by the engine's doc parser (`zero_scripting::module_docs`); it is not
passed at runtime.

**Parameters**

- `name` `string` — Suite name (used in output).
- `fn` `() -> ()` — The suite-definition function. Runs once during `describe` to
collect tests into the suite. Nested describes work — the current
suite is restored when this call returns. A body that ends on a raise
leaves a failing case behind naming the raise, so the declarations it
never reached are answered for and the run ends on them; a body that
stands down leaves a skipped case carrying the reason.

**Returns** `Suite` — The newly-registered suite table.

```lua
Test.describe("math", function() Test.it("adds", function() Test.expect(1+1).toBe(2) end) end)
```

## typed/builtin//assetTypes/testSuite/shared/Test/describeValue {#typed-builtin-assettypes-testsuite-shared-test-describevalue}

```lua
Test.describeValue(value: any?) -> string
```

Render any value as human-readable text for test output. Strings pass
through unchanged; tables render structurally (`{code = "x", n = 2}`) with
bounded breadth, depth, and string length; a value with its own
`__tostring` uses it. Every failure message and raised error the harness
reports goes through this, so a table-valued failure names its contents
instead of an address.

**Parameters**

- `value` `any` _(optional)_ — Any Luau value.

**Returns** `string` — Bounded, deterministic text for `value`.

```lua
Test.describeValue({ code = "E1", line = 4 }) --> '{code = "E1", line = 4}'
```

## typed/builtin//assetTypes/testSuite/shared/Test/detectLeakedGpuLabels {#typed-builtin-assettypes-testsuite-shared-test-detectleakedgpulabels}

```lua
Test.detectLeakedGpuLabels(preSnapshot: { [string]: number }) -> { string }
```

Name the GPU labels the allocator holds now that `preSnapshot` did not,
and the ones it now holds more allocations under. This is the reading for a
suite whose fixtures carry engine-given labels it cannot pick out by name;
a suite that names its own reads them with `Test.gpuLabelsMatching`, which
answers the same on a second run in the same engine.

The name is the only handle a named GPU resource has, so the case that
named one is the one that can release it, and this answer is the list of
what the suite left standing.

**Parameters**

- `preSnapshot` `{ [string]: number }` — The map returned by `Test.snapshotGpuLabels`.

**Returns** `{ string }` — The labels added since the snapshot, sorted.

```lua
local left = Test.detectLeakedGpuLabels(pre)
```

## typed/builtin//assetTypes/testSuite/shared/Test/detectLeakedRenderFeatures {#typed-builtin-assettypes-testsuite-shared-test-detectleakedrenderfeatures}

```lua
Test.detectLeakedRenderFeatures(preSnapshot: { [string]: string }) -> { string }
```

Name the render features registered since `preSnapshot`, counted by
identity. A suite that re-registers an identity replaces the live instance
under a new guid, so what a suite hands over is which identities are
running and how many of each, not which guid is carrying them.

The answer is a report rather than a teardown. A render feature is brought
up by the system that needs it, and that system keeps its own record of
whether it is live: a feature destroyed from outside leaves the system
believing it is still running, so it never brings it back and everything
that feature drew is missing from then on. Naming the suite that left one
is what a reader can act on.

The answer covers the identities the suite ADDED to the set it was handed.
The set as the suite leaves it is what the next boundary opens against, so
an identity the suite took down is the baseline every suite behind it is
measured from.

**Parameters**

- `preSnapshot` `{ [string]: string }` — The map returned by `Test.snapshotRenderFeatures`.

**Returns** `{ string }` — The identities registered since the snapshot, one entry per instance, sorted.

```lua
local left = Test.detectLeakedRenderFeatures(pre)
```

## typed/builtin//assetTypes/testSuite/shared/Test/detectSourcePollution {#typed-builtin-assettypes-testsuite-shared-test-detectsourcepollution}

```lua
Test.detectSourcePollution(pre: { [string]: boolean }) -> { string }
```

Compare the current top-level `/zero/source` entries against a
pre-suite snapshot and return every NEW entry that isn't engine- or
runner-managed. A non-empty result means the suite left content at the
world root — pollution it must instead sandbox under `Test.TMP_ROOT` or
remove via `Test.registerCleanup`.

**Parameters**

- `pre` `{ [string]: boolean }` — The set returned by `Test.snapshotSourceContent`.

**Returns** `{ string }` — Array of leaked top-level entry names (empty when the suite is clean).

```lua
local leaked = Test.detectSourcePollution(pre)
```

## typed/builtin//assetTypes/testSuite/shared/Test/detectSpawnedEntities {#typed-builtin-assettypes-testsuite-shared-test-detectspawnedentities}

```lua
Test.detectSpawnedEntities(preSnapshot: { [any]: boolean }) -> { { id: any, name: string } }
```

Compare the entities alive now against a snapshot and report every one
that appeared since. Use it to assert an operation spawns nothing: the
answer is the entity set itself, so it holds whatever else the world
already carries — unlike a name lookup, which reports ambient content
whenever the name is one the world uses too. The entity analogue of
`Test.detectSourcePollution`.

**Parameters**

- `preSnapshot` `{ [any]: boolean }` — The set returned by `Test.snapshotEntities`.

**Returns** `{ { id: any, name: string } }` — Array of `{ id, name }` for each entity spawned after the snapshot.

```lua
local pre = Test.snapshotEntities(); op(); Test.expect(#Test.detectSpawnedEntities(pre)).toBe(0)
```

## typed/builtin//assetTypes/testSuite/shared/Test/ensureRootLayer {#typed-builtin-assettypes-testsuite-shared-test-ensurerootlayer}

```lua
Test.ensureRootLayer() -> any
```

Take a root scene layer for the run, so `layers.active` and every
scene-scoped surface reached through it (`layers.active.camera`, `:save()`,
the `sceneAuthoring` review tools, `@scene` paths) answer inside a test the
way they answer from `execute`. A sweep starts each run from a clean slate
with the booted scene unloaded, so `layers.active` reads nil until a test
asks for a scene: this returns the active root when one is loaded, and
otherwise duplicates `Test.DEFAULT_SCENE_FIXTURE` to `Test.BASELINE_SCENE`
and loads it. The stand-in layer goes out with the test that took it, so a
suite that never asks for a root still meets a clean slate; its source is
minted once and reloaded by the next test to ask, and the runner drops that
on the way out. Reach for `Test.useScene` / `Test.useSceneEach` instead when
the test spawns into the scene, saves it, or asserts on its entity set —
those mint a fresh scene per test and tear it down after. An edit↔play flip
that is rebuilding the scene is waited out first, so the root this returns
is the one the body keeps rather than a proxy the rebuild is about to
replace.

**Returns** `any` — The active root `SceneProxy`, carrying the path of the scene it holds.

```lua
local root = Test.ensureRootLayer(); Test.expect(root.guid).toBeTruthy()
```

## typed/builtin//assetTypes/testSuite/shared/Test/expect {#typed-builtin-assettypes-testsuite-shared-test-expect}

```lua
Test.expect(value: any?) -> any
```

Create an expectation builder over a value. Returns a chainable
table with matchers like `toBe`, `toBeTruthy`, `toContain`,
`toMatch`, `toHaveLength`, `toBeCloseTo`, and a `never` flip.

**Parameters**

- `value` `any` _(optional)_ — The value under inspection.

**Returns** `any` — The expectation table. Each matcher records failure (without throwing) so multiple expectations per test still execute.

```lua
Test.expect(1 + 1).toBe(2)
Test.expect("hello").toContain("ell")
```

## typed/builtin//assetTypes/testSuite/shared/Test/generateJsonReport {#typed-builtin-assettypes-testsuite-shared-test-generatejsonreport}

```lua
Test.generateJsonReport(stats: Stats, results: { Result }, suites: { SuiteTiming }?) -> string
```

Render the engine test results as a machine-readable JSON document.
This is the format the `tests` toolbox saves for diffing runs
(`tests.compare`). Consumers should index `results` by `(suite, test)`.

**Parameters**

- `stats` `Stats` — Aggregate stats from `Test.getStats()`.
- `results` `{ Result }` — Per-test records from `Test.getResults()`.
- `suites` `{ SuiteTiming }` _(optional)_ — Per-suite timings, carried through to the report's `suites` key. Omitted, the key is an empty array.

**Returns** `string` — A JSON string `{ date, stats, results, suites }`.

```lua
local j = Test.generateJsonReport(Test.getStats(), Test.getResults())
```

## typed/builtin//assetTypes/testSuite/shared/Test/generateMarkdownReport {#typed-builtin-assettypes-testsuite-shared-test-generatemarkdownreport}

```lua
Test.generateMarkdownReport(stats: Stats, results: { Result }) -> string
```

Render the engine test results as a Markdown report (the format
written to `/source/tmp/test_results.md`).

**Parameters**

- `stats` `Stats` — Aggregate stats from `Test.getStats()`.
- `results` `{ Result }` — Per-test records from `Test.getResults()`.

**Returns** `string` — The Markdown document as a string.

```lua
local md = Test.generateMarkdownReport(Test.getStats(), Test.getResults())
```

## typed/builtin//assetTypes/testSuite/shared/Test/getResults {#typed-builtin-assettypes-testsuite-shared-test-getresults}

```lua
Test.getResults() -> { Result }
```

Get the detailed result records from the last `Test.run`.

**Returns** `{ Result }` — Array of `Result` entries — one per test executed.

```lua
local rs = Test.getResults()
```

## typed/builtin//assetTypes/testSuite/shared/Test/getStats {#typed-builtin-assettypes-testsuite-shared-test-getstats}

```lua
Test.getStats() -> Stats
```

Get the aggregate stats from the last `Test.run`.

**Returns** `Stats` — The `Stats` table: total, passed, failed, skipped.

```lua
local s = Test.getStats(); print(s.failed)
```

## typed/builtin//assetTypes/testSuite/shared/Test/gpuLabelsMatching {#typed-builtin-assettypes-testsuite-shared-test-gpulabelsmatching}

```lua
Test.gpuLabelsMatching(needle: string) -> { string }
```

Name every GPU label the allocator holds right now that contains
`needle`. A suite that gives its fixtures a prefix of its own reads its
whole footprint this way, whatever the sweep around it has allocated, and
whatever earlier run of the same suite left standing — the reading is an
absolute one, so a leak already in the ledger is still reported.

**Parameters**

- `needle` `string` — Substring a label must contain to be named.

**Returns** `{ string }` — The matching labels, sorted.

```lua
local mine = Test.gpuLabelsMatching("_test_myfixture")
```

## typed/builtin//assetTypes/testSuite/shared/Test/gpuLedgerReady {#typed-builtin-assettypes-testsuite-shared-test-gpuledgerready}

```lua
Test.gpuLedgerReady(frames: number?) -> boolean
```

Wait for the device allocator's ledger to be sampled, and say whether
this engine has one at all. `renderer.gpuMemory().allocator` is the
device allocator's own record, so it is there on a backend that allocates
its own memory and absent on one whose host allocates for it — a browser's
WebGPU device among them — and it arrives on a sampled frame rather than
on the call that asks. Every reading built on `Test.snapshotGpuLabels`
asks this first: on a device with no ledger each of them answers with
silence, which reads exactly like a suite that left nothing behind, so a
case stands itself down here instead of passing on a reading it never
took.

**Parameters**

- `frames` `number` _(optional)_ — Frames to wait for the first sample. Default 300.

**Returns** `boolean` — True when the ledger is here to be read.

```lua
if not Test.gpuLedgerReady() then Test.skip("this device keeps no allocator ledger") end
```

## typed/builtin//assetTypes/testSuite/shared/Test/it {#typed-builtin-assettypes-testsuite-shared-test-it}

```lua
Test.it(name: string, fn: (TestContext) -> ()) -> any?
```

Define a single test within the enclosing `describe`. The test
body receives an optional context `t` exposing `waitFrames`, `expect`,
`fail`, and identifying metadata.

## typed/builtin//assetTypes/testSuite/shared/Test/measurement {#typed-builtin-assettypes-testsuite-shared-test-measurement}

```lua
Test.measurement(what: string) -> nil
```

Declare that the running test's verdict is decided by how fast the
host ran — a rate, a ratio between two rates, or a wall-clock bound. Such
a test asks a real question about the engine and answers it differently on
a loaded machine than on a quiet one, so its verdict belongs to a run whose
purpose is to measure. A run that admits measurements (`Test.measurements`,
which `tests.run { measurements = true }` sets) runs the body; anywhere
else the call stands the test down carrying what it measures, the way any
unmet precondition does.

**Parameters**

- `what` `string` — What the test measures, named so the stood-down row says which
measurement the run declined.

**Returns** `nil` — Nothing. The call either returns and the body continues, or stands the test down and does not return.

```lua
Test.it("a take costs the run nothing", function() Test.measurement("the rate the engine publishes frames at") end)
```

## typed/builtin//assetTypes/testSuite/shared/Test/openSuiteBoundary {#typed-builtin-assettypes-testsuite-shared-test-opensuiteboundary}

```lua
Test.openSuiteBoundary() -> SuiteBoundary
```

Read the live state a suite is about to be handed, so the state it
hands on can be compared against it. Pair with `Test.closeSuiteBoundary`,
which drains the suite's teardown and reports what crossed. The suite
envelope opens a boundary before it loads a suite and closes it after, and
the one currently open is published as `Test.suiteBoundary` — so a body
reads the world its own suite was handed, and a boundary the body opens
nests inside it.

**Returns** `SuiteBoundary` — A `SuiteBoundary` token to hand to `Test.closeSuiteBoundary`.

```lua
local pre = Test.openSuiteBoundary()
```

## typed/builtin//assetTypes/testSuite/shared/Test/prepareTmp {#typed-builtin-assettypes-testsuite-shared-test-preparetmp}

```lua
Test.prepareTmp()
```

Recreate the sandbox tmp root. Removes any leftover files
and creates a fresh empty directory at `Test.TMP_ROOT`. Safe to
call from `Test.beforeEach`.

```lua
Test.prepareTmp()
```

## typed/builtin//assetTypes/testSuite/shared/Test/registerCleanup {#typed-builtin-assettypes-testsuite-shared-test-registercleanup}

```lua
Test.registerCleanup(fn: () -> ()) -> nil
```

Push a cleanup function onto the current test's auto-teardown
list. Drained LIFO after `Test.afterEach`, on both success and
failure paths, so the cleanup fires even when the test body
errors out. Use this when a test allocates additional resources
(extra `layers.load` after the initial useScene, temp VFS paths
outside the sandbox, registered MCP tools, …) that the standard
useScene auto-teardown doesn't cover.

**Parameters**

- `fn` `() -> ()` — No-arg function to run as cleanup. Errors are caught + logged.

**Returns** `nil`

```lua
Test.registerCleanup(function() pcall(layers.unload, myRef) end)
```

## typed/builtin//assetTypes/testSuite/shared/Test/releaseRootLayer {#typed-builtin-assettypes-testsuite-shared-test-releaserootlayer}

```lua
Test.releaseRootLayer()
```

Unload the stand-in root scene layer `Test.ensureRootLayer` loaded and
drop its source folder. The next `Test.ensureRootLayer` mints a fresh one.
A no-op when the run never took a stand-in.

```lua
Test.releaseRootLayer()
```

## typed/builtin//assetTypes/testSuite/shared/Test/restoreWorldBaseline {#typed-builtin-assettypes-testsuite-shared-test-restoreworldbaseline}

```lua
Test.restoreWorldBaseline(baseline: WorldBaseline?)
```

Restore the layers captured by `Test.beginWorldBaseline`, leaving the
engine in the shape it was found. The run's stand-in root goes first, then
each captured layer is reloaded by guid via `asset.resolve`; the additive
flag decides root vs overlay. Per-layer pcall'd so one failed restore
doesn't block the rest.

**Parameters**

- `baseline` `WorldBaseline` _(optional)_ — The token returned by `Test.beginWorldBaseline`.

```lua
Test.restoreWorldBaseline(base)
```

## typed/builtin//assetTypes/testSuite/shared/Test/run {#typed-builtin-assettypes-testsuite-shared-test-run}

```lua
Test.run() -> boolean
```

Run every registered suite. Resets stats, executes each test
body inside a `pcall` so a runtime error marks the test failed
rather than aborting the run, snapshots/cleans up leaked entities
between tests, and defensively returns the scene to `edit` mode
if a test leaks `play` mode. On the way out — pass, fail, OR an
uncaught framework error — it always tears down the entire sandbox
tmp root, so no test artifacts ever outlive the run.

**Returns** `boolean` — `true` if every test passed (zero failures), `false` otherwise.

```lua
local ok = Test.run()
```

## typed/builtin//assetTypes/testSuite/shared/Test/sandbox {#typed-builtin-assettypes-testsuite-shared-test-sandbox}

```lua
Test.sandbox(tag: string?) -> string
```

Create a fresh, empty sandbox container folder under the current test's
tmp dir and return its absolute path. Pass it as an `into` container path to
`asset.create` / `Material.Create` (`into = { path = Test.sandbox("mats") }`)
so the new asset is authored under the sync-excluded `/source/tmp/tests/...`
sandbox instead of the world root. The runner sweeps the folder at
end-of-test, and the egress filter keeps everything under it out of the
bound world's content store — so even hundreds of fixtures never pollute the
user's `/source` tree or block play / push.

**Parameters**

- `tag` `string` _(optional)_ — Folder name relative to the current test's sandbox.

**Returns** `string` — The absolute container path, guaranteed to exist.

```lua
local r = asset.create("material", "gold", { shader = "pbr", into = { path = Test.sandbox("mats") } })
```

## typed/builtin//assetTypes/testSuite/shared/Test/sceneRenderState {#typed-builtin-assettypes-testsuite-shared-test-scenerenderstate}

```lua
Test.sceneRenderState() -> string
```

The scene's shading state as one string two readings can be compared
by: the ambient term, the directional sun, and every punctual light the
renderer resolved, with the fields ordered so the same state always
encodes the same way.

A test that compares rendered frames with each other rests on all of them
having been drawn under one shading state. This is the reading that says
so: take it before the frames and again after, and two equal readings mean
a difference between the frames belongs to what the test varied.

**Returns** `string` — The encoded shading state.

```lua
local before = Test.sceneRenderState()
```

## typed/builtin//assetTypes/testSuite/shared/Test/settleReading {#typed-builtin-assettypes-testsuite-shared-test-settlereading}

```lua
Test.settleReading(take: () -> any, agrees: (any, any) -> any, opts: { attempts: number?, framesBetween: number? }?) -> (boolean, number, any)
```

Take readings of a subject until two consecutive ones agree, and
report how many that took.

A rig that has just been assembled reaches the picture over several
frames: a material compiles, a probe fills, an atmosphere resolves. A test
that measures such a rig has to hold until it stops moving, and the
reading that says so is the rig's own — one taken twice.

The call takes ONE reading per attempt and compares it with the attempt
before, so a subject that settles at once costs two readings and one that
never settles costs `attempts`. `agrees` decides how close two readings
have to be: give it the tolerance the test's own assertions leave room
for. Whether two readings off a still rig come back equal is a property
of the host that drew them, so a poll that asks for equality is a poll
whose length the host decides — and every attempt it spends costs
whatever a reading costs.

**Parameters**

- `take` `() -> any` — Zero-arg function returning one reading. Called once per attempt.
- `agrees` `(any, any) -> any` — Called with the previous reading and the current one; truthy
means the subject has settled.
- `opts` `{ attempts: number?, framesBetween: number? }` _(optional)_ — `attempts` — how many readings to take before giving up (default
12, clamped to a minimum of 2). `framesBetween` — engine frames to wait
between readings (default 4, clamped to a minimum of 0).

**Returns** `(boolean, number, any)` — Whether two consecutive readings agreed, how many readings that cost, and the last reading taken.

```lua
local ok, tries = Test.settleReading(shoot, function(a, b) return apart(a, b) < 1 end)
```

## typed/builtin//assetTypes/testSuite/shared/Test/settleWorldTeardown {#typed-builtin-assettypes-testsuite-shared-test-settleworldteardown}

```lua
Test.settleWorldTeardown(maxFrames: number?) -> WorldQuiescence
```

Hold until the work a teardown queued has landed: yields frames until
every reading — live entities, loaded layers, registered render features,
resident offscreen render targets, layer loads in flight — is unchanged for
five consecutive frames. A despawn applies a frame after it is asked for,
the render target that entity owned is reclaimed the frame after that, and
a layer unload drains over several more, so a caller that yields a single
frame hands the rest of that chain to whatever runs next. A test that
tears down world state and then reads a count off the engine wants this
between the two.

**Parameters**

- `maxFrames` `number` _(optional)_ — How long to wait before reporting instead. Defaults to sixty.
A budget below the stability window cannot reach it, so it is answered
`settled = false`; nought or less is answered that way without waiting a
frame.

**Returns** `WorldQuiescence` — `{ settled, frames, moving }` — `moving` names the facets seen to change on the last frame any of them did, and is empty whenever the wait saw nothing move, so `settled` is what says whether the world had stopped or the budget ran out first. A caller that cannot reach a frame boundary is answered `settled = false` after nought frames, with `moving` naming `yield`.

```lua
local q = Test.settleWorldTeardown(); print(q.settled, q.frames)
```

## typed/builtin//assetTypes/testSuite/shared/Test/skip {#typed-builtin-assettypes-testsuite-shared-test-skip}

```lua
Test.skip(name: string, fn: ((TestContext) -> ())?) -> any?
```

Skip a test, in either of the two moments a test can be skipped.

With a body, it DECLARES a skipped test: the `Test.it` shape, marked
`skip = true`, so the runner counts it under `skipped` and leaves the body
unrun. That is the form a `describe` takes, and a reason arriving there on
its own raises naming it.

Inside a running test — its body, or one of the hooks around it — a call
carrying a reason alone STANDS THAT TEST DOWN: the test ends at the call
and is reported skipped, and the reason travels with it to the console, the
per-test record and the report. That is the shape for a test whose
precondition this engine does not meet, which has nothing to verify and has
earned no pass. Anything the test's hooks record around the stand-down is a
failure of the test they ran for and outranks it.

**Parameters**

- `name` `string` — The test's name when declaring one; the reason it stood down when
standing the running test down.
- `fn` `((TestContext) -> ())` _(optional)_ — Test body. Supplying one declares a test wherever the call is made.
Left out, the call stands down the test that is running, and raises where
no test is running.

**Returns** `any?` — The registered test entry when declaring one, or `nil` outside a `describe`. A stand-down ends the test rather than returning.

```lua
Test.skip("not yet", function() error("...") end)
Test.it("draws", function() if not engine.gpuCompute then Test.skip("no GPU compute") end end)
```

## typed/builtin//assetTypes/testSuite/shared/Test/snapshotEntities {#typed-builtin-assettypes-testsuite-shared-test-snapshotentities}

```lua
Test.snapshotEntities() -> { [any]: boolean }
```

Snapshot the set of entity ids currently alive. Pair with
`Test.sweepLeakedEntities` to despawn everything spawned after the snapshot
— the safety net for entities leaked outside a test body (suite-registration
side effects, crashed tests) that the per-test cleanup can't see.

**Returns** `{ [any]: boolean }` — A `{ [entityId] = true }` set.

```lua
local pre = Test.snapshotEntities(); ...; Test.sweepLeakedEntities(pre)
```

## typed/builtin//assetTypes/testSuite/shared/Test/snapshotGpuLabels {#typed-builtin-assettypes-testsuite-shared-test-snapshotgpulabels}

```lua
Test.snapshotGpuLabels() -> { [string]: number }
```

Snapshot the GPU resources the allocator holds right now, mapping each
label to how many allocations carry it. Pair with
`Test.detectLeakedGpuLabels`, which names the labels a suite added and left
standing. A GPU resource created under a name — a `compute` storage target,
a 3D texture, a history pair — answers to that name for as long as the
engine runs, so whoever names one owns releasing it: a root scene load and
`renderer.collect` both leave it where it is.

**Returns** `{ [string]: number }` — A `{ [label] = allocations }` map.

```lua
local pre = Test.snapshotGpuLabels()
```

## typed/builtin//assetTypes/testSuite/shared/Test/snapshotLayers {#typed-builtin-assettypes-testsuite-shared-test-snapshotlayers}

```lua
Test.snapshotLayers() -> { [string]: boolean }
```

Snapshot the layers loaded right now, by guid. Pair with
`Test.sweepLeakedLayers`, which unloads every layer loaded after the
snapshot — the layer analogue of `Test.snapshotEntities`, for a suite that
loads a scene and leaves it standing for every suite behind it.

**Returns** `{ [string]: boolean }` — A `{ [layerGuid] = true }` set.

```lua
local pre = Test.snapshotLayers(); ...; Test.sweepLeakedLayers(pre)
```

## typed/builtin//assetTypes/testSuite/shared/Test/snapshotRenderFeatures {#typed-builtin-assettypes-testsuite-shared-test-snapshotrenderfeatures}

```lua
Test.snapshotRenderFeatures() -> { [string]: string }
```

Snapshot the render features registered right now, mapping each guid to
the asset identity it was created from. Pair with
`Test.detectLeakedRenderFeatures`, which names the ones registered after
the snapshot. A feature draws on every frame of every suite behind the one
that registered it, so one left standing changes what a later suite's pixel
and draw-call readings measure.

**Returns** `{ [string]: string }` — A `{ [featureGuid] = identity }` map.

```lua
local pre = Test.snapshotRenderFeatures()
```

## typed/builtin//assetTypes/testSuite/shared/Test/snapshotScreens {#typed-builtin-assettypes-testsuite-shared-test-snapshotscreens}

```lua
Test.snapshotScreens() -> { [string]: boolean }
```

Snapshot the UI screens currently registered, mapping each name to its
current visibility. Pair with `Test.sweepLeakedScreens`, which unregisters
every screen registered after the snapshot AND restores the visibility of
the snapshotted screens — the safety net for UI screens a suite mounts and
never tears down (which pile up as ghost screens) and for a suite that
toggles a pre-existing screen's visibility (e.g. `Z.screens.hideAll`) and
leaves the user's own UI hidden after the run.

**Returns** `{ [string]: boolean }` — A `{ [screenName] = visible }` map.

```lua
local pre = Test.snapshotScreens(); ...; Test.sweepLeakedScreens(pre)
```

## typed/builtin//assetTypes/testSuite/shared/Test/snapshotSourceContent {#typed-builtin-assettypes-testsuite-shared-test-snapshotsourcecontent}

```lua
Test.snapshotSourceContent() -> { [string]: boolean }
```

Snapshot the set of top-level `/zero/source` entry names that exist
before a suite runs. Paired with `Test.detectSourcePollution` to flag
content a suite leaks OUTSIDE its sandbox — world state that would bleed
into later suites (and the publish gate). The world-content analogue of
`Test.snapshotEntities`.

**Returns** `{ [string]: boolean }` — A name->true set of the current top-level entries.

```lua
local pre = Test.snapshotSourceContent()
```

## typed/builtin//assetTypes/testSuite/shared/Test/snapshotSourceSync {#typed-builtin-assettypes-testsuite-shared-test-snapshotsourcesync}

```lua
Test.snapshotSourceSync() -> SourceSyncMark
```

Snapshot what holds `/zero/source` and how far the engine has got
materialising the bound world's own content into it. Two marks bracket a
suite and feed `Test.sourceDiffAttributable`, which reads them to say
whether the entries that appeared at the world root across that window
are the suite's doing.

**Returns** `SourceSyncMark` — `{ worldBound, subscribed, contentSynced, applied }` for this instant.

```lua
local mark = Test.snapshotSourceSync()
```

## typed/builtin//assetTypes/testSuite/shared/Test/sourceDiffAttributable {#typed-builtin-assettypes-testsuite-shared-test-sourcediffattributable}

```lua
Test.sourceDiffAttributable(pre: SourceSyncMark, post: SourceSyncMark) -> (boolean, string?)
```

Whether a `/zero/source` name diff taken across two marks names only
what the suite between them wrote. A world materialises its own content
into the world root on its own schedule — a session that is still
applying content, that applied some while the suite ran, or that never
reported at all while a world held the root, puts entries there that the
diff would otherwise read as the suite's.

**Parameters**

- `pre` `SourceSyncMark` — The mark taken before the suite ran.
- `post` `SourceSyncMark` — The mark taken after it finished.

**Returns** `(boolean, string?)` — `true` when the diff is the suite's alone; otherwise `false` plus a phrase naming what held the source root instead.

```lua
local mine, why = Test.sourceDiffAttributable(pre, Test.snapshotSourceSync())
```

## typed/builtin//assetTypes/testSuite/shared/Test/sweepLeakedEntities {#typed-builtin-assettypes-testsuite-shared-test-sweepleakedentities}

```lua
Test.sweepLeakedEntities(preSnapshot: { [any]: boolean }) -> number
```

Despawn every entity not present in `preSnapshot` (from
`Test.snapshotEntities`). Unlocks destroy-locked entities first so even
PlayerOwned leaks can be cleaned. Yields one frame so the deferred despawns
drain before the next suite snapshots its own baseline.

**Parameters**

- `preSnapshot` `{ [any]: boolean }` — The set returned by `Test.snapshotEntities`.

**Returns** `number` — Number of entities despawned.

```lua
Test.sweepLeakedEntities(pre)
```

## typed/builtin//assetTypes/testSuite/shared/Test/sweepLeakedLayers {#typed-builtin-assettypes-testsuite-shared-test-sweepleakedlayers}

```lua
Test.sweepLeakedLayers(preSnapshot: { [string]: boolean }) -> { string }
```

Unload every non-persistent layer loaded since `preSnapshot`. Persistent
layers (the editor overlay) are left alone. The answer names the layers it
asked the engine to unload, which covers what appeared between the snapshot
and now; a layer that went stays gone. Each unload lands over the frames
after the call, so a caller reading the loaded set straight back waits for
what it asked for — `Test.waitUntil` on `Test.snapshotLayers`, or
`Test.settleWorldTeardown` when it wants the whole cascade behind it.

**Parameters**

- `preSnapshot` `{ [string]: boolean }` — The set returned by `Test.snapshotLayers`.

**Returns** `{ string }` — The guids unloaded.

```lua
Test.sweepLeakedLayers(pre)
```

## typed/builtin//assetTypes/testSuite/shared/Test/sweepLeakedScreens {#typed-builtin-assettypes-testsuite-shared-test-sweepleakedscreens}

```lua
Test.sweepLeakedScreens(preSnapshot: { [string]: boolean }) -> number
```

Restore the screen set captured by `Test.snapshotScreens`: unregister
every screen registered after the snapshot, and put each snapshotted
screen's visibility back to how the run found it. Screens reloaded with a
world layer come back in the restore pass, so only screens a suite mounted
outside a layer get swept; a suite that hid a pre-existing screen (e.g. via
`Z.screens.hideAll`) gets that screen re-shown so the user's UI doesn't
stay blank after a test run. Yields one frame so the changes drain before
the caller reads the screen set again.

**Parameters**

- `preSnapshot` `{ [string]: boolean }` — The map returned by `Test.snapshotScreens`.

**Returns** `number` — Number of screens unregistered (leaked).

```lua
Test.sweepLeakedScreens(pre)
```

## typed/builtin//assetTypes/testSuite/shared/Test/tmpPath {#typed-builtin-assettypes-testsuite-shared-test-tmppath}

```lua
Test.tmpPath(relativePath: string?) -> string
```

Build a sandboxed path for a test fixture under the CURRENT test's own
folder (`TMP_ROOT/<suite>/<test>/...`). Every write a test makes should go
through this so it lands inside the per-test sandbox the runner cleans up
automatically — never at a hand-rolled `/source/...` path that survives the
run and syncs to spacetime. Empty / non-string `relativePath` returns the
test's folder itself. Called outside a running test it falls back to the
suite folder, then to `TMP_ROOT` (see `currentTestDir`).

**Parameters**

- `relativePath` `string` _(optional)_ — Path fragment relative to the current test's folder.

**Returns** `string` — The fully-qualified path under the per-test sandbox.

```lua
local p = Test.tmpPath("Foo.component/init.luau")
```

## typed/builtin//assetTypes/testSuite/shared/Test/uniqueName {#typed-builtin-assettypes-testsuite-shared-test-uniquename}

```lua
Test.uniqueName(stem: string) -> string
```

A name no earlier run and no earlier case in this engine has used, so a
registry, a cache, a log scope or a VFS path keyed by name answers for the
thing this case just made under it. The counter separates the cases within
one engine and the random draw separates one engine's names from another's,
which is what a suite sharded across parallel engines over one world needs.

**Parameters**

- `stem` `string` — What the name is for. It stays at the front, so an artifact that
outlives its case still says which case minted it.

**Returns** `string` — `<stem>_<n>_<r>` — the stem, this VM's next counter value, and a random draw.

```lua
local name = Test.uniqueName("probe_material") --> "probe_material_7_412903"
```

## typed/builtin//assetTypes/testSuite/shared/Test/useScene {#typed-builtin-assettypes-testsuite-shared-test-usescene}

```lua
Test.useScene(opts: { fixture: string?, additive: boolean? }?) -> any
```

Mint an isolated scene for the current test. Duplicates the
body of `opts.fixture` (a `.scene` folder) into a unique path
under `Test.TMP_ROOT/scenes/` and loads it through `layers.load`.
The freshly-loaded layer becomes the active root (or an additive
overlay when `opts.additive == true`).

The duplicate is registered for auto-teardown on the current test —
when the test body finishes (success OR failure), the runner
unloads the layer and removes the sandbox copy. Whatever was
authored on top of the duplicate (entities, components, dirty
edits) is therefore discarded automatically. Nothing the test
writes lands in user content.

Tests that need a richer baseline (a Player template, a Camera
rig, custom lighting) pass an explicit `opts.fixture` pointing at
a fixture folder of their own — useScene treats it like any other
`.scene` source.

**Parameters**

- `opts` `{ fixture: string?, additive: boolean? }` _(optional)_ — Optional `{ fixture, additive }`. `fixture` is the VFS
path of a `.scene` folder (defaults to
`Test.DEFAULT_SCENE_FIXTURE`). `additive` controls whether the
duplicate loads as an additive overlay alongside whatever else is
loaded, or replaces the current root (the default).

**Returns** `any` — The loaded `SceneProxy` (same instance `layers.active` / `layers.find` would hand back) so callers can read `.guid` / `.name` / spawn entities into it / register additive overlays.

```lua
local scene = Test.useScene()                            -- empty root
local hud = Test.useScene({ additive = true })           -- empty overlay
local rig = Test.useScene({ fixture = "/zero/source/libs/@builtin/_canonical/static_player.scene" })
```

## typed/builtin//assetTypes/testSuite/shared/Test/useSceneEach {#typed-builtin-assettypes-testsuite-shared-test-usesceneeach}

```lua
Test.useSceneEach(opts: { fixture: string?, additive: boolean? }?) -> nil
```

Suite-level sugar for "mint a fresh scene before every test in
this suite". Equivalent to writing
`Test.beforeEach(function() Test.useScene(opts) end)` but
composable — preserves any beforeEach the suite already
registered and adds the useScene call after it.

**Parameters**

- `opts` `{ fixture: string?, additive: boolean? }` _(optional)_ — Same shape as `Test.useScene`'s `opts`. Forwarded as-is.

**Returns** `nil`

```lua
Test.describe("VFS Entity", function()
Test.useSceneEach()              -- empty root scene per test
Test.it("...", function() ... end)
end)
```

## typed/builtin//assetTypes/testSuite/shared/Test/waitForSteadyScene {#typed-builtin-assettypes-testsuite-shared-test-waitforsteadyscene}

```lua
Test.waitForSteadyScene(stableFrames: number?, maxFrames: number?) -> boolean
```

Hold until the scene's shading state has read the same for
`stableFrames` frames in a row and no scene load is in flight.

A scene the engine is still settling into changes what it draws over the
frames after the call that changed it: a layer's entities drain, their
lights leave the resolved set, and the picture moves with them. Waiting on
the reading rather than on a frame count holds for as long as the machine
the test runs on needs.

**Parameters**

- `stableFrames` `number` _(optional)_ — How many consecutive frames must read the same. Defaults to
4; clamped to a minimum of 1.
- `maxFrames` `number` _(optional)_ — Frame budget before giving up. Defaults to 240.

**Returns** `boolean` — Whether the scene reached that many identical readings in budget.

```lua
Test.waitForSteadyScene()
```

## typed/builtin//assetTypes/testSuite/shared/Test/waitFrames {#typed-builtin-assettypes-testsuite-shared-test-waitframes}

```lua
Test.waitFrames(n: number?)
```

Wait at least `n` engine frames before continuing. Yields the
running coroutine and returns control after at least `n` frame
boundaries have elapsed. When invoked through a non-yieldable
C-call chain the underlying `task.wait` raises; the runner catches
that sentinel and treats the test as SKIPPED for that invocation.
Run suites via the `tests` toolbox (`tests.run`) — or call
`Test.run` from a yieldable context — to actually exercise the wait
paths.

**Parameters**

- `n` `number` _(optional)_ — Frame count. Defaults to 1; clamped to a minimum of 1.

```lua
function(t) t.waitFrames(2); Test.expect(entity.exists(id)).toBe(false) end
```

## typed/builtin//assetTypes/testSuite/shared/Test/waitUntil {#typed-builtin-assettypes-testsuite-shared-test-waituntil}

```lua
Test.waitUntil(predicate: () -> any, maxFrames: number?) -> boolean
```

**Parameters**

- `predicate` `() -> any`
- `maxFrames` `number` _(optional)_

**Returns** `boolean`

## typed/builtin//assetTypes/testSuite/shared/Test/withSteadyScene {#typed-builtin-assettypes-testsuite-shared-test-withsteadyscene}

```lua
Test.withSteadyScene(body: () -> any, attempts: number?) -> (any?, string?)
```

Run `body` inside a window in which the scene's shading state holds
still, so the frames it takes can be compared with each other.

The call waits for the scene to steady, reads `Test.sceneRenderState()`,
and runs the body while a watcher reads the state again on every frame the
body spans. A body whose frames were taken across a change in that state
measured something the test did not vary, so it is run again on a scene
that has settled — up to `attempts` times, after which the call reports
what moved instead of handing back frames. Reading every frame catches a
change that lands and is undone inside one window.

The body measures and returns; put the assertions on what it returns.
A body that runs twice records anything it asserts twice.

**Parameters**

- `body` `() -> any` — Zero-arg function that takes the frames and returns them.
- `attempts` `number` _(optional)_ — How many windows to try. Defaults to 4; clamped to 1.

**Returns** `(any?, string?)` — What the body returned, or `(nil, reason)` when the scene kept moving.

```lua
local frames, reason = Test.withSteadyScene(function() ... end)
```

## typed/builtin//components/Asset/public/bakeIntoScene {#typed-builtin-components-asset-public-bakeintoscene}

```lua
public.bakeIntoScene()
```

Promote the bundle's spawned children from temporary to permanent
scene state and remove the Asset component, "baking" the bundle's
contents directly into the owning scene. Subsequent saves persist the
baked entities verbatim and stop replaying the bundle template.

**Returns** true once the bake completes.

```lua
asset:bakeIntoScene()
```

## typed/builtin//components/BoxCollider/public/setHalf {#typed-builtin-components-boxcollider-public-sethalf}

```lua
public.setHalf(size: vec3)
```

Set the box's half-extents. Recreates the collision shape.

**Parameters**

- `size` `vec3` — Half-extents as { x, y, z } or { x = , y = , z = }.

```lua
collider:setHalf({ 1, 2, 0.5 })
```

## typed/builtin//components/BoxCollider/public/setTrigger {#typed-builtin-components-boxcollider-public-settrigger}

```lua
public.setTrigger(trigger: boolean)
```

Toggle trigger mode. A trigger reports overlaps without blocking.

**Parameters**

- `trigger` `boolean` — true to detect overlaps only, false to collide solidly.

```lua
collider:setTrigger(true)
```

## typed/builtin//components/Camera/public/capture {#typed-builtin-components-camera-public-capture}

```lua
public.capture()
```

Capture a frame from this camera to its current render target. Alias
of render() — kept so the verb matches the agent-facing capture
toolbox.

```lua
cam:capture()
```

## typed/builtin//components/Camera/public/lookAt {#typed-builtin-components-camera-public-lookat}

```lua
public.lookAt(target: string | table) -> (boolean, string?)
```

Aim this camera at a world position or another entity. Returns whether
the camera was rotated, so a target naming an entity the scene does not
carry is reported rather than leaving the camera on its previous aim.

**Parameters**

- `target` `string | table` — An entity id string, an entity name, an entity proxy, or a
position table ({x, y, z} array form or {x=, y=, z=} map form).

**Returns** `(boolean, string?)` — True when the camera was rotated, and nil for the second value. False plus the reason otherwise — `"unresolved"` when the target names no entity, `"no-transform"` when one of the two carries no transform, `"degenerate"` when the camera already sits on the point it was asked to face.

```lua
cam:lookAt(playerId)
cam:lookAt("player")
cam:lookAt({0, 1, 0})
cam:lookAt({x = 0, y = 1, z = 0})
```

## typed/builtin//components/Camera/public/render {#typed-builtin-components-camera-public-render}

```lua
public.render(rtGuid: string?)
```

Schedule a single-frame render for this camera. Works whether the
component is enabled or disabled. Uses the camera's current transform, fov,
near/far, and render layers. Pass a render-target guid to render this frame
into THAT texture instead of the camera's configured output — the
one-shot-target form the capture path uses to read a camera's exact view
back without disturbing where it normally renders.

## typed/builtin//components/Camera/public/setTargetTexture {#typed-builtin-components-camera-public-settargettexture}

```lua
public.setTargetTexture(tex: renderer.TextureHandle?)
```

Point the camera at a GPU texture to render into, or back to the main
viewport. Create the texture first with
`renderer.texture.create({ width, height })` (it owns its own size); the
camera only references it — free it with `renderer.destroy(handle)` when done.

**Parameters**

- `tex` `renderer.TextureHandle` _(optional)_ — A `TextureHandle` to render into, or nil for the main viewport.

```lua
local tex = renderer.texture.create({ width = 512, height = 512 })
cam:setTargetTexture(tex)   -- render into the texture
cam:setTargetTexture(nil)   -- back to the main viewport
```

## typed/builtin//components/Humanoid/public/attach {#typed-builtin-components-humanoid-public-attach}

```lua
public.attach(point: string, childId: string)
```

Parent an existing entity under the bone at `point` (see `socket`), so it
rides that bone's animation. Convenience over `socket(point)` + setParent.

**Parameters**

- `point` `string` — string — a canonical role, or an exact bone name.
- `childId` `string` — string — the entity to attach.

**Returns** entity (the socket bone) | nil when the point doesn't resolve.

## typed/builtin//components/Humanoid/public/bone {#typed-builtin-components-humanoid-public-bone}

```lua
public.bone(name: string)
```

Lookup a single bone entity by canonical name (`"Head"`, `"Hand_R"`, etc).
Returns nil when the bone isn't present (e.g. a skeleton missing the finger sub-tree).

**Parameters**

- `name` `string` — string — canonical bone name from the humanoid table

**Returns** entity | nil

## typed/builtin//components/Humanoid/public/socket {#typed-builtin-components-humanoid-public-socket}

```lua
public.socket(point: string)
```

Resolve an attachment point to the live bone entity for THIS body, so
content attaches a prop to a known point WITHOUT knowing the per-mesh bone
name. `point` is a canonical ROLE (`"righthand"`, `"lefthand"`, `"head"`,
`"hips"`, …) resolved mesh-independently via the body's RetargetProfile;
if it matches no role it falls back to an exact bone NAME (per-rig custom
attachment). Returns the bone entity, or nil when absent.

**Parameters**

- `point` `string` — string — a canonical role, or an exact bone name.

**Returns** entity | nil

## typed/builtin//components/Light/public/lightMobility {#typed-builtin-components-light-public-lightmobility}

```lua
public.lightMobility() -> string
```

How GI baking should treat this light, resolved to `"static"`,
`"mixed"` or `"dynamic"`. Every component that puts a light in the
scene answers this, which is how a bake finds the lights it has to
account for without knowing what component authored them.

**Returns** `string` — The resolved mobility.

```lua
if light:lightMobility() == "dynamic" then ... end
```

## typed/builtin//components/Light/public/resolveMobility {#typed-builtin-components-light-public-resolvemobility}

```lua
public.resolveMobility() -> string
```

Resolve this light's mobility to `"static"`, `"mixed"` or
`"dynamic"` — how GI baking treats it. An explicit `mobility` field
wins; `"auto"` resolves to `"dynamic"` for a light something carries
(non-world participation, an animated or physics-driven entity) and
`"mixed"` for the rest.

`"static"` bakes the light whole — direct light and bounce — and
withholds its live contribution, so it costs nothing per frame and
lights nothing that was not there at bake time.

`"mixed"` bakes only its bounce and keeps its direct light and shadows
live, so it still lights and shadows anything that moves. This is what
`"auto"` picks, because a light that stands still still shines on
characters walking under it.

`"dynamic"` keeps the light out of the bake entirely.

**Returns** `string`

```lua
local mob = light:resolveMobility()
```

## typed/builtin//components/Light/public/setCastsShadows {#typed-builtin-components-light-public-setcastsshadows}

```lua
public.setCastsShadows(b: boolean)
```

Enable or disable shadow casting. Point lights cast omnidirectional
(cube) shadows; spot lights cast a single projected shadow. Capacity is
capped per kind — past the cap the light stays lit but unshadowed.

**Parameters**

- `b` `boolean` — `true` to cast shadows, `false` to disable.

```lua
light:setCastsShadows(true)
```

## typed/builtin//components/Light/public/setColor {#typed-builtin-components-light-public-setcolor}

```lua
public.setColor(color: table)
```

Set the light color. Values >1 are auto-scaled from 0..255.

**Parameters**

- `color` `table` — `{r, g, b}` array or `{r=, g=, b=}` map.

```lua
light:setColor({1, 0.8, 0.5})
light:setColor({r = 255, g = 200, b = 128})
```

## typed/builtin//components/Light/public/setDirection {#typed-builtin-components-light-public-setdirection}

```lua
public.setDirection(dirOrX: table | number, y: number?, z: number?)
```

Set the direction vector (directional lights only). Accepts three
numbers or a single `{x, y, z}` / `{x=, y=, z=}` vector.

**Parameters**

- `dirOrX` `table | number` — Either the x component, or a `{x, y, z}` array / `{x=, y=, z=}` map.
- `y` `number` _(optional)_ — The y component when the first argument is a number.
- `z` `number` _(optional)_ — The z component when the first argument is a number.

```lua
light:setDirection(-0.5, -1, -0.3)
light:setDirection({-0.5, -1, -0.3})
```

## typed/builtin//components/Light/public/setIntensity {#typed-builtin-components-light-public-setintensity}

```lua
public.setIntensity(i: number)
```

Set the light intensity (0..N).

**Parameters**

- `i` `number` — Intensity scalar.

```lua
light:setIntensity(2.5)
```

## typed/builtin//components/Light/public/setKind {#typed-builtin-components-light-public-setkind}

```lua
public.setKind(lightKind: string)
```

Switch the light kind ("point" / "directional" / "ambient" /
"distant"). `"directional"` aims the scene's sun, which is a single
field: setting it replaces whatever the sun was. `"distant"` is parallel
light held as a row of the scene's light buffer, so several coexist —
`DirectionalLight` is the component that authors one.

**Parameters**

- `lightKind` `string` — One of `"point"`, `"directional"`, `"ambient"`, `"distant"`.

```lua
light:setKind("directional")
```

## typed/builtin//components/Light/public/setRadius {#typed-builtin-components-light-public-setradius}

```lua
public.setRadius(r: number)
```

Set the radius (point lights only).

**Parameters**

- `r` `number` — Radius in world units.

```lua
light:setRadius(15)
```

## typed/builtin//components/Model/public/applySessionMaterial {#typed-builtin-components-model-public-applysessionmaterial}

```lua
public.applySessionMaterial(handle: any?)
```

Show a session-created runtime material on this Model in place of
its authored material. The authored `material` field is never touched —
persisted state always carries the authored ref, so nothing broken can
be saved. The handle is kept in the session store under
`renderer.material.sessionKeyFor(entityId)`, so awake re-adopts it
across VM reloads; on a fresh boot (runtime materials gone) the Model
renders its authored material again automatically.
Called with no handle, it copies this Model's current material into a fresh
session material keyed to this entity, so later `setMaterialProperty` edits
land on the copy instead of the shared authored material.

A copy per entity is what a DIFFERENT LOOK per entity costs — its own
pipeline binding and its own row in the material table. When entities want
the same look and differ only in a VALUE, `renderer.instanceData.set` writes
one of the four `vec4` lanes every drawn object already carries, which the
shader reads as `input.shader_data[lane]`, and one material serves them all.

**Parameters**

- `handle` `any` _(optional)_ — The runtime material handle OBJECT, as `renderer.material.create`
and `renderer.material.animatedTexture` return it. Its `guid` field is the
material's registry key, which is what `renderer.material.setProperty` /
`describe` / `destroy` take; this call takes the handle itself.
Omit to copy this Model's current material into a new session material.

```lua
model:applySessionMaterial(handle)
model:applySessionMaterial()  -- copy the current material for per-entity edits
```

## typed/builtin//components/Model/public/clearOutline {#typed-builtin-components-model-public-clearoutline}

```lua
public.clearOutline()
```

Remove the outline from this mesh.

```lua
model:clearOutline()
```

## typed/builtin//components/Model/public/clearTint {#typed-builtin-components-model-public-cleartint}

```lua
public.clearTint()
```

Reset the tint so the mesh renders with its original material colour.

```lua
model:clearTint()
```

## typed/builtin//components/Model/public/getMaterialProperty {#typed-builtin-components-model-public-getmaterialproperty}

```lua
public.getMaterialProperty(property: string)
```

Read a property from this Model's material — the session material when
one is active, else the authored material.

**Parameters**

- `property` `string` — Property name (string).

**Returns** The current value of the property, or nil when no material is assigned.

```lua
local color = model:getMaterialProperty("baseColor")
```

## typed/builtin//components/Model/public/getMaterialPropertyNames {#typed-builtin-components-model-public-getmaterialpropertynames}

```lua
public.getMaterialPropertyNames()
```

List all property names available on this Model's material — the session
material when one is active, else the authored material.

**Returns** Array of property name strings (empty when no material is assigned).

```lua
for _, name in ipairs(model:getMaterialPropertyNames()) do print(name) end
```

## typed/builtin//components/Model/public/resolveMobility {#typed-builtin-components-model-public-resolvemobility}

```lua
public.resolveMobility() -> string
```

Resolve this entity's effective mobility: `"static"` (stands still —
receives lightmaps, occludes baked light) or `"movable"` (moves — samples
probe volumes for indirect light). An explicit `mobility` field value wins;
`"auto"` derives it from the entity AND everything carrying it: anything
that animates, simulates, or is driven (a non-static `Physics` body, a
`SkinnedModel`, a `ClipPlayer`, a `Mover`/`FreeMover` — on this entity or
any ancestor — or a non-world runtime participation) is movable,
everything else is static.

**Returns** `string` — `"static"` or `"movable"`.

```lua
if model:resolveMobility() == "static" then Lightmap.bake(id) end
```

## typed/builtin//components/Model/public/restoreSessionMaterial {#typed-builtin-components-model-public-restoresessionmaterial}

```lua
public.restoreSessionMaterial() -> boolean
```

End the session-material swap: the Model renders its authored
material again.

**Returns** `boolean` — `true` when a session material was active, else `false`.

```lua
model:restoreSessionMaterial()
```

## typed/builtin//components/Model/public/setMaterialProperties {#typed-builtin-components-model-public-setmaterialproperties}

```lua
public.setMaterialProperties(props: { [string]: any }) -> number
```

Set many properties on this Model's material in one call, the plural of
`setMaterialProperty` and with the same target: this entity's session copy
when one is active, else the authored material every entity sharing it
takes. Each key resolves against the material's declared vocabulary the way
the singular resolves it; a property the material's shader does not expose
is skipped, so one patch table serves models on different shaders.

**Parameters**

- `props` `{ [string]: any }` — Table of `{ [propertyName] = value }` pairs.

**Returns** `number` — Number of properties applied.

```lua
model:setMaterialProperties({ roughness = 0.2, metallic = 0.9 })
```

## typed/builtin//components/Model/public/setMaterialProperty {#typed-builtin-components-model-public-setmaterialproperty}

```lua
public.setMaterialProperty(property: string, value: any?)
```

Set a property on this Model's material. With a session material active
(see `applySessionMaterial`), the write lands on this entity's session copy
alone; otherwise it changes the shared material at runtime, which every
entity sharing it takes since material properties are registry-wide. Either
way the change reaches the GPU and not the material's `mat.yaml` — call
`material:saveDefinition()` to write the current values into the asset. The
key resolves against the material's declared vocabulary on both targets, so
the same name reaches the same uniform.

**Parameters**

- `property` `string` — Property name (string).
- `value` `any` _(optional)_ — New value for the property. Type depends on the property.

```lua
model:setMaterialProperty("baseColor", {1, 0, 0, 1})
model:setMaterialProperty("roughness", 0.5)
```

## typed/builtin//components/Model/public/setOutline {#typed-builtin-components-model-public-setoutline}

```lua
public.setOutline(color: table, intensity: number?)
```

Set the outline colour and intensity for this mesh.

**Parameters**

- `color` `table` — Outline color as {r, g, b} array or {r=, g=, b=} map. Channel
values are 0-1.
- `intensity` `number` _(optional)_ — Outline intensity (0 = none, 1 = full). Defaults to 1.

```lua
model:setOutline({0, 1, 0})
model:setOutline({r = 1, g = 1, b = 0}, 0.8)
```

## typed/builtin//components/Model/public/setTint {#typed-builtin-components-model-public-settint}

```lua
public.setTint(color: table, blend: number?)
```

Set the mesh tint colour and blend amount.

**Parameters**

- `color` `table` — Tint color as {r, g, b} array or {r=, g=, b=} map. Channel values
are 0-1.
- `blend` `number` _(optional)_ — Blend amount (0 = no tint, 1 = full tint). Defaults to 1.

```lua
model:setTint({1, 0, 0})
model:setTint({r = 1, g = 0, b = 0}, 0.5)
```

## typed/builtin//components/Physics/public/addVelocity {#typed-builtin-components-physics-public-addvelocity}

```lua
public.addVelocity(dx: number, dy: number, dz: number)
```

Add to the body's current linear velocity.

**Parameters**

- `dx` `number` — Velocity delta along world X.
- `dy` `number` — Velocity delta along world Y.
- `dz` `number` — Velocity delta along world Z.

```lua
body:addVelocity(0, 2, 0)
```

## typed/builtin//components/Physics/public/applyForce {#typed-builtin-components-physics-public-applyforce}

```lua
public.applyForce(x: number, y: number, z: number)
```

Apply a continuous force to this body (Newtons).

**Parameters**

- `x` `number` — Force component along world X.
- `y` `number` — Force component along world Y.
- `z` `number` — Force component along world Z.

```lua
body:applyForce(0, 100, 0)
```

## typed/builtin//components/Physics/public/applyImpulse {#typed-builtin-components-physics-public-applyimpulse}

```lua
public.applyImpulse(x: number, y: number, z: number)
```

Apply an instantaneous impulse to this body (kg·m/s).

**Parameters**

- `x` `number` — Impulse component along world X.
- `y` `number` — Impulse component along world Y.
- `z` `number` — Impulse component along world Z.

```lua
body:applyImpulse(5, 0, 0)
```

## typed/builtin//components/Physics/public/applyTorque {#typed-builtin-components-physics-public-applytorque}

```lua
public.applyTorque(x: number, y: number, z: number)
```

Apply a torque to this body (rotational force).

**Parameters**

- `x` `number` — Torque around world X.
- `y` `number` — Torque around world Y.
- `z` `number` — Torque around world Z.

```lua
body:applyTorque(0, 5, 0)
```

## typed/builtin//components/Physics/public/setVelocity {#typed-builtin-components-physics-public-setvelocity}

```lua
public.setVelocity(x: number, y: number, z: number)
```

Set the body's linear velocity directly.

**Parameters**

- `x` `number` — Velocity component along world X.
- `y` `number` — Velocity component along world Y.
- `z` `number` — Velocity component along world Z.

```lua
body:setVelocity(0, 10, 0)
```

## typed/builtin//components/PlayerNameLabel/public/refresh {#typed-builtin-components-playernamelabel-public-refresh}

```lua
public.refresh()
```

Re-read the owner and rasterise the label. Called by `PlayerAvatar` when
the owning identity or its display name changes.

## typed/builtin//components/ProceduralSky/public/applyPreset {#typed-builtin-components-proceduralsky-public-applypreset}

```lua
public.applyPreset(preset: string)
```

Apply a named look (clear_day, sunset, sunrise, overcast, night).

**Parameters**

- `preset` `string` — One of the named presets.

```lua
sky:applyPreset("sunset")
```

## typed/builtin//components/ProceduralSky/public/setGroundColor {#typed-builtin-components-proceduralsky-public-setgroundcolor}

```lua
public.setGroundColor(color: { [any]: number })
```

Set the ground (below-horizon) colour. Values >1 auto-scale from 0..255.

**Parameters**

- `color` `{ [any]: number }` — `{r, g, b}` array or `{r=, g=, b=}` map.

```lua
sky:setGroundColor({0.3, 0.25, 0.2})
```

## typed/builtin//components/ProceduralSky/public/setHorizonColor {#typed-builtin-components-proceduralsky-public-sethorizoncolor}

```lua
public.setHorizonColor(color: { [any]: number })
```

Set the horizon sky colour. Values >1 auto-scale from 0..255.

**Parameters**

- `color` `{ [any]: number }` — `{r, g, b}` array or `{r=, g=, b=}` map.

```lua
sky:setHorizonColor({0.9, 0.4, 0.2})
```

## typed/builtin//components/ProceduralSky/public/setTimeOfDay {#typed-builtin-components-proceduralsky-public-settimeofday}

```lua
public.setTimeOfDay(hours: number)
```

Set the time of day in hours (0..24). Orients the sun and the day/night gradient.

**Parameters**

- `hours` `number` — 0..24.

```lua
sky:setTimeOfDay(18.5)
```

## typed/builtin//components/ProceduralSky/public/setZenithColor {#typed-builtin-components-proceduralsky-public-setzenithcolor}

```lua
public.setZenithColor(color: { [any]: number })
```

Set the zenith (straight-up) sky colour. Values >1 auto-scale from 0..255.

**Parameters**

- `color` `{ [any]: number }` — `{r, g, b}` array or `{r=, g=, b=}` map.

```lua
sky:setZenithColor({0.05, 0.1, 0.3})
```

## typed/builtin//components/SkinnedModel/public/applySessionMaterial {#typed-builtin-components-skinnedmodel-public-applysessionmaterial}

```lua
public.applySessionMaterial(handle: any?)
```

Show a session-created runtime material on this SkinnedModel in
place of its authored material. The authored `material` field is never
touched — persisted state always carries the authored ref. The handle
is kept in the session store under
`renderer.material.sessionKeyFor(entityId)`, so awake re-adopts it
across VM reloads; on a fresh boot (runtime materials gone) the
SkinnedModel renders its authored material again automatically.

**Parameters**

- `handle` `any` _(optional)_ — The runtime material handle (from `renderer.material.create`).

```lua
skinned:applySessionMaterial(handle)
```

## typed/builtin//components/SkinnedModel/public/clearOutline {#typed-builtin-components-skinnedmodel-public-clearoutline}

```lua
public.clearOutline()
```

Remove the outline from this mesh.

```lua
sm:clearOutline()
```

## typed/builtin//components/SkinnedModel/public/clearTint {#typed-builtin-components-skinnedmodel-public-cleartint}

```lua
public.clearTint()
```

Reset the tint so the mesh renders with its original material colour.

```lua
sm:clearTint()
```

## typed/builtin//components/SkinnedModel/public/getMaterialProperty {#typed-builtin-components-skinnedmodel-public-getmaterialproperty}

```lua
public.getMaterialProperty(property: string)
```

Read a property from this model's material.

**Parameters**

- `property` `string` — Property name (string).

**Returns** The current value of the property, or nil when no material is assigned.

```lua
local color = sm:getMaterialProperty("baseColor")
```

## typed/builtin//components/SkinnedModel/public/getMaterialPropertyNames {#typed-builtin-components-skinnedmodel-public-getmaterialpropertynames}

```lua
public.getMaterialPropertyNames()
```

List all property names available on this model's material.

**Returns** Array of property name strings (empty when no material is assigned).

```lua
for _, name in ipairs(sm:getMaterialPropertyNames()) do print(name) end
```

## typed/builtin//components/SkinnedModel/public/restoreSessionMaterial {#typed-builtin-components-skinnedmodel-public-restoresessionmaterial}

```lua
public.restoreSessionMaterial() -> boolean
```

End the session-material swap: the SkinnedModel renders its
authored material again.

**Returns** `boolean` — `true` when a session material was active, else `false`.

```lua
skinned:restoreSessionMaterial()
```

## typed/builtin//components/SkinnedModel/public/setMaterialProperties {#typed-builtin-components-skinnedmodel-public-setmaterialproperties}

```lua
public.setMaterialProperties(props: { [string]: any }) -> number
```

Set many properties on this model's material in one call, the plural of
`setMaterialProperty`. Affects every entity sharing the material since
material properties are registry-wide. A property the material's shader
does not expose is skipped, so one patch table serves models on different
shaders.

**Parameters**

- `props` `{ [string]: any }` — Table of `{ [propertyName] = value }` pairs.

**Returns** `number` — Number of properties applied.

```lua
sm:setMaterialProperties({ roughness = 0.5, metallic = 0.2 })
```

## typed/builtin//components/SkinnedModel/public/setMaterialProperty {#typed-builtin-components-skinnedmodel-public-setmaterialproperty}

```lua
public.setMaterialProperty(property: string, value: any?)
```

Set a property on this model's material at runtime. Affects every
entity sharing the material since material properties are registry-wide,
and reaches the GPU rather than the material's `mat.yaml` — call
`material:saveDefinition()` to write the current values into the asset.

**Parameters**

- `property` `string` — Property name (string).
- `value` `any` _(optional)_ — New value for the property. Type depends on the property.

```lua
sm:setMaterialProperty("roughness", 0.5)
```

## typed/builtin//components/SkinnedModel/public/setOutline {#typed-builtin-components-skinnedmodel-public-setoutline}

```lua
public.setOutline(color: table, intensity: number?)
```

Set the outline colour and intensity for this mesh.

**Parameters**

- `color` `table` — Outline color as {r, g, b} array or {r=, g=, b=} map. Channel
values are 0-1.
- `intensity` `number` _(optional)_ — Outline intensity (0 = none, 1 = full). Defaults to 1.

```lua
sm:setOutline({0, 1, 0})
sm:setOutline({r = 1, g = 1, b = 0}, 0.8)
```

## typed/builtin//components/SkinnedModel/public/setTint {#typed-builtin-components-skinnedmodel-public-settint}

```lua
public.setTint(color: table, blend: number?)
```

Set the mesh tint colour and blend amount.

**Parameters**

- `color` `table` — Tint color as {r, g, b} array or {r=, g=, b=} map. Channel values
are 0-1.
- `blend` `number` _(optional)_ — Blend amount (0 = no tint, 1 = full tint). Defaults to 1.

```lua
sm:setTint({1, 0, 0})
sm:setTint({r = 1, g = 0, b = 0}, 0.5)
```

## typed/builtin//components/Text3D/public/getSize {#typed-builtin-components-text3d-public-getsize}

```lua
public.getSize()
```

Measure the rasterised text in pixels.

**Returns** Table with `width` and `height` in pixels (zero when not yet rasterised).

## typed/builtin//components/Text3D/public/getText {#typed-builtin-components-text3d-public-gettext}

```lua
public.getText()
```

Read the current text content.

**Returns** Current text string.

## typed/builtin//components/Text3D/public/getWorldSize {#typed-builtin-components-text3d-public-getworldsize}

```lua
public.getWorldSize()
```

Read the world-space size of the text quad after rasterisation.

**Returns** Table with `width` and `height` in world units.

## typed/builtin//components/Text3D/public/refresh {#typed-builtin-components-text3d-public-refresh}

```lua
public.refresh()
```

Force the text to re-rasterise now.

```lua
t:refresh()
```

## typed/builtin//components/Text3D/public/setStyle {#typed-builtin-components-text3d-public-setstyle}

```lua
public.setStyle(options: table)
```

Update one or more style fields in a single call. Unknown keys are
ignored. Each changed field fires the reactive rebuild (position-only for
offset/pivot keys, a re-rasterise for styling keys).

**Parameters**

- `options` `table` — Table of style overrides keyed by public-field name.

```lua
t:setStyle({fontSize = 64, color = "yellow"})
```

## typed/builtin//components/Text3D/public/setText {#typed-builtin-components-text3d-public-settext}

```lua
public.setText(content: string)
```

Replace the displayed text content.

**Parameters**

- `content` `string` — New text string.

```lua
t:setText("Hello World")
```

## typed/builtin//controller/camera_rig/R/applyPose {#typed-builtin-controller-camera-rig-r-applypose}

```lua
R.applyPose(selfId: string, camX: number, camY: number, camZ: number, lookX: number, lookY: number, lookZ: number)
```

Write a camera pose onto an entity, aiming at a point. Both the pose
and the aim point are expressed in the camera entity's own transform
frame — parent-relative when the camera is parented, world space when it
is not.

**Parameters**

- `selfId` `string` — The camera entity id.
- `camX` `number` — Camera X.
- `camY` `number` — Camera Y.
- `camZ` `number` — Camera Z.
- `lookX` `number` — Aim point X.
- `lookY` `number` — Aim point Y.
- `lookZ` `number` — Aim point Z.

```lua
CameraRig.applyPose(id, cx, cy, cz, tx, ty, tz)
```

## typed/builtin//controller/camera_rig/R/damp {#typed-builtin-controller-camera-rig-r-damp}

```lua
R.damp(current: number, goal: number, tau: number, dt: number) -> number
```

Frame-rate independent damping toward a goal.

**Parameters**

- `current` `number` — Current value.
- `goal` `number` — Target value.
- `tau` `number` — Time constant in seconds; 0 snaps.
- `dt` `number` — Frame delta in seconds.

**Returns** `number` — The damped value, which never overshoots the goal.

```lua
pos.x = CameraRig.damp(pos.x, goal.x, 0.2, dt)
```

## typed/builtin//controller/camera_rig/R/pullIn {#typed-builtin-controller-camera-rig-r-pullin}

```lua
R.pullIn(pivotX: number, pivotY: number, pivotZ: number, camX: number, camY: number, camZ: number, radius: number, excludeId: string?) -> (number, number, number)
```

Pull a camera position in toward the pivot when geometry intervenes.

**Parameters**

- `pivotX` `number` — Pivot X.
- `pivotY` `number` — Pivot Y.
- `pivotZ` `number` — Pivot Z.
- `camX` `number` — Desired camera X.
- `camY` `number` — Desired camera Y.
- `camZ` `number` — Desired camera Z.
- `radius` `number` — Sphere radius used for the cast; 0 disables the pull-in.
- `excludeId` `string` _(optional)_ — Entity whose subtree never blocks the camera (the subject).

**Returns** `(number, number, number)` — The corrected camera position.

```lua
local x, y, z = CameraRig.pullIn(px, py, pz, cx, cy, cz, 0.3, bodyId)
```

## typed/builtin//controller/camera_rig/R/resolveFollow {#typed-builtin-controller-camera-rig-r-resolvefollow}

```lua
R.resolveFollow(selfId: string, followField: any?) -> string?
```

Resolve the entity this rig follows: the explicit field, else the
standard `Camera.follow` slot.

**Parameters**

- `selfId` `string` — This rig's entity id.
- `followField` `any` _(optional)_ — The rig's own `follow` field value.

**Returns** `string?` — Entity id, or `nil` when nothing resolvable is set.

```lua
local target = CameraRig.resolveFollow(public.entity.id, public.follow)
```

## typed/builtin//controller/camera_rig/R/ringAt {#typed-builtin-controller-camera-rig-r-ringat}

```lua
R.ringAt(rings: Rings, t: number) -> (number, number)
```

Height and radius of the orbit at a point along the three-ring spline.

**Parameters**

- `rings` `Rings` — The bottom / center / top rings.
- `t` `number` — Position along the spline, 0 at the bottom ring and 1 at the top.

**Returns** `(number, number)` — Height and radius at `t`.

```lua
local h, rad = CameraRig.ringAt(rings, 0.5)
```

## typed/builtin//controller/camera_rig/R/visibleForward {#typed-builtin-controller-camera-rig-r-visibleforward}

```lua
R.visibleForward(targetId: string) -> (number, number, number)
```

The direction a subject visibly faces, in world space.
A body declares its own visible forward (`Locomotion.forward`), because a
mesh faces whichever way its source authored it: a Synty/FBX body carries
`{0,0,1}`, a glTF body `{0,0,-1}`. Reading that declaration is what lets a
rig sit behind ANY subject rather than behind one particular art pipeline.
Falls back to the entity's own transform forward when nothing declares one.

**Parameters**

- `targetId` `string` — The subject to read.

**Returns** `(number, number, number)` — Unit world-space forward as three numbers.

```lua
local fx, fy, fz = CameraRig.visibleForward(bodyId)
```

## typed/builtin//controller/orbital_follow/public/onFollowChanged {#typed-builtin-controller-orbital-follow-public-onfollowchanged}

```lua
public.onFollowChanged(newFollow: any?, oldFollow: any?)
```

Re-pose after the Camera's `follow` slot changed. `follow` lives on the
Camera, so this rig receives no property notification of its own for it and
the Camera calls this instead. A target assigned after the rig attached is
picked up here, in edit mode as well as play.

**Parameters**

- `newFollow` `any` _(optional)_ — The entity the camera now follows.
- `oldFollow` `any` _(optional)_ — The entity it followed before.

```lua
-- called by Camera.onPropertyChanged, not usually by hand
```

## typed/builtin//editor/edui/editorPanel/behavior/M/onChange {#typed-builtin-editor-edui-editorpanel-behavior-m-onchange}

```lua
M.onChange(self: any?, change: any?)
```

**Parameters**

- `self` `any` _(optional)_
- `change` `any` _(optional)_

## typed/builtin//editor/edui/editorPanel/behavior/M/onRegister {#typed-builtin-editor-edui-editorpanel-behavior-m-onregister}

```lua
M.onRegister(self: any?)
```

**Parameters**

- `self` `any` _(optional)_

## typed/builtin//modules/api/editor/agents/ensureSlot {#typed-builtin-modules-api-editor-agents-ensureslot}

```lua
ensureSlot(i: number)
```

Ensure slot `i`'s agent process is running, spawning it (and waiting on
the agent host's boot dependency) when it is not. Opening a slot's panel
calls this; calling it again on a running slot is a no-op, so it is also
how a panel relaunches an exited agent.

**Parameters**

- `i` `number`

## typed/builtin//modules/api/editor/agents/slotCount {#typed-builtin-modules-api-editor-agents-slotcount}

```lua
slotCount() -> number
```

How many concurrent agent slots the editor offers.

**Returns** `number` — The slot count.

## typed/builtin//modules/api/editor/agents/slotStatus {#typed-builtin-modules-api-editor-agents-slotstatus}

```lua
slotStatus(i: number) -> any
```

Slot `i`'s terminal and live state, for a panel to render: drains the
slot lifecycle events, then reports the backing terminal id (created on
first ask), whether its process is running, the slot's display label, and
how many automatic relaunches it has spent.

**Parameters**

- `i` `number`

**Returns** `any` — `{termId, running, label, relaunches}`.

## typed/builtin//modules/api/editor/agents/spec {#typed-builtin-modules-api-editor-agents-spec}

```lua
spec(kickoffPrompt: string?) -> any
```

The process spec the launcher runs for the active agent — the command,
its flags, its working directory, and the environment it inherits.

**Parameters**

- `kickoffPrompt` `string` _(optional)_ — Text submitted as the agent's first message.

**Returns** `any` — A `terminal.spawn` spec: `{cmd, args, cwd, env, envRemove}`.

## typed/builtin//modules/api/engine/animation/animation/animating {#typed-builtin-modules-api-engine-animation-animation-animating}

```lua
animation.animating() -> { AnimationBody }
```

The bodies the engine measured a changing pose on — what is animating
right now.

**Returns** `{ AnimationBody }` — An array of `AnimationBody`.

```lua
for _, b in animation.animating() do print(b.entity, b.clips[1] and b.clips[1].name) end
```

## typed/builtin//modules/api/engine/animation/animation/bodies {#typed-builtin-modules-api-engine-animation-animation-bodies}

```lua
animation.bodies() -> { AnimationBody }
```

Every body the engine holds animation state for.

**Returns** `{ AnimationBody }` — An array of `AnimationBody`.

```lua
for _, b in animation.bodies() do print(b.entity, b.matched .. "/" .. b.total) end
```

## typed/builtin//modules/api/engine/animation/animation/body {#typed-builtin-modules-api-engine-animation-animation-body}

```lua
animation.body(entityId: string | EntityRef) -> AnimationBody?
```

The report for one body, or nil when the engine holds no animation
state for it. Accepts the body itself or any ancestor of it, so a character
root answers for the skinned body underneath it.

**Parameters**

- `entityId` `string | EntityRef` — The entity's stable id, or an EntityRef.

**Returns** `AnimationBody?` — An `AnimationBody`, or nil.

```lua
local b = animation.body(hero.id); print(b and b.reason)
```

## typed/builtin//modules/api/engine/animation/animation/clips {#typed-builtin-modules-api-engine-animation-animation-clips}

```lua
animation.clips(entityId: string | EntityRef) -> { AnimationClip }
```

The clips contributing to a body's pose right now, with their playheads
and their retarget coverage.

**Parameters**

- `entityId` `string | EntityRef` — The entity's stable id, or an EntityRef.

**Returns** `{ AnimationClip }` — An array of `AnimationClip`.

```lua
for _, c in animation.clips(hero.id) do print(c.name, c.time, c.matched) end
```

## typed/builtin//modules/api/engine/animation/animation/coverage {#typed-builtin-modules-api-engine-animation-animation-coverage}

```lua
animation.coverage(entityId: string | EntityRef) -> (number, number)
```

How many of a body's bones the clips driving it actually reach.
Returns `(matched, total)`. A clip that retargets onto nothing reads
`(0, 50)` while its playhead advances; a partial retarget reads its own
count, so 3 of 50 is as visible as none.

**Parameters**

- `entityId` `string | EntityRef` — The entity's stable id, or an EntityRef.

**Returns** `(number, number)` — `(matched, total)`.

```lua
local m, t = animation.coverage(hero.id); print(m .. "/" .. t)
```

## typed/builtin//modules/api/engine/animation/animation/declare {#typed-builtin-modules-api-engine-animation-animation-declare}

```lua
animation.declare(entityId: string, facts: { [string]: any })
```

Publish what an animator is running on a body, so the observation names
its clips, playheads and retarget coverage beside the pose the engine
measures. The shipped animators declare through `AnimGraph:publish`; a
custom animator calls this itself, once per frame it runs.

**Parameters**

- `entityId` `string` — The body the animator drives.
- `facts` `{ [string]: any }` — `{ driver, bound, playing, outputKind, failure, clips }`, where
each clip is `{ name, nodeKind, time, duration, playing, finished, looping,
weight, matched, total, unmatched }`.

```lua
animation.declare(body.id, { driver = "MyAnimator", playing = true, clips = {} })
```

## typed/builtin//modules/api/engine/animation/animation/forget {#typed-builtin-modules-api-engine-animation-animation-forget}

```lua
animation.forget(entityId: string)
```

Drop the declaration and the pose evidence the engine holds for one
body. An animator calls this when it releases a body, so the observation
reports the body as undriven from the next frame.

**Parameters**

- `entityId` `string` — The body to drop.

```lua
animation.forget(body.id)
```

## typed/builtin//modules/api/engine/animation/animation/observe {#typed-builtin-modules-api-engine-animation-animation-observe}

```lua
animation.observe() -> AnimationObservation
```

Report what the engine is posing right now and why a body is not
moving. One read covering every body the engine holds animation state for,
each with the pose evidence the engine measured on its armature beside the
clips the animator driving it declared. Answers in edit mode as well as
play mode.

**Returns** `AnimationObservation` — An `AnimationObservation`.

```lua
local a = animation.observe(); print(a.animatingCount, a.riggedBodyCount)
for _, b in animation.observe().bodies do print(b.entity, b.animating, b.reason) end
```

## typed/builtin//modules/api/engine/animation/animation/whyStill {#typed-builtin-modules-api-engine-animation-animation-whystill}

```lua
animation.whyStill(entityId: string | EntityRef) -> (string?, string?)
```

Why the body on an entity is not animating. Returns nil when it IS
animating, and otherwise one of `deactivated`, `noRiggedSkeleton`,
`noGraph`, `clipUnreadable`, `noOutputNode`, `retargetMatchedNoRoles`,
`stopped`, `finished`, `paused`, `poseNotApplied`, `poseUnchanged` — the
nearest cause, so the answer names the thing to change. A second return
carries the animator's own words when it could not build a graph.

An entity the engine holds no animation state for is answered from the
entity itself, in the same order the engine resolves a body it does hold:
one carrying no rigged `Skeleton` is `noRiggedSkeleton`, and a rigged one
nothing drives is `noGraph`. An id no entity carries is neither — the
reason is nil and the detail says so.

**Parameters**

- `entityId` `string | EntityRef` — The entity's stable id, or an EntityRef.

**Returns** `(string?, string?)` — `(reason, detail)`.

```lua
local why, detail = animation.whyStill(hero.id); if why then print(why, detail) end
```

## typed/builtin//modules/api/engine/asset/asset/add_tag {#typed-builtin-modules-api-engine-asset-asset-add-tag}

```lua
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.

**Parameters**

- `ref` `RefArg` — Any name the asset has.
- `tag` `string` — Tag to add.

```lua
asset.add_tag("brick", "wip")
```

## typed/builtin//modules/api/engine/asset/asset/alias {#typed-builtin-modules-api-engine-asset-asset-alias}

```lua
asset.alias(ref: RefArg, alias: string) -> boolean
```

Add a name the asset answers to. `asset.resolve`, leaf
shorthand, and the typed-argument coercion that content refs
travel through all reach the asset by the alias from here on,
exactly as they do by its identity — so a material naming a
shader by its alias resolves, and content written against an
older name keeps working after a rename. The name survives
writes to the asset's own files.
Raises when the name already resolves to a DIFFERENT asset — an
alias extends the identity namespace and never takes a name out
of another asset's hands — and when it is shaped like a guid or
a VFS path, forms that resolve before identity lookup, so an
alias in that shape could never answer.

**Parameters**

- `ref` `RefArg` — The asset gaining the name.
- `alias` `string` — The additional name. Any identity form: a bare leaf
(`standard`) or a scope-qualified path (`@builtin::shaders.legacy`).

**Returns** `boolean` — True when newly added, false when the asset already answered to it.

```lua
asset.alias("@builtin::shaders.pbr", "standard")
```

## typed/builtin//modules/api/engine/asset/asset/aliases {#typed-builtin-modules-api-engine-asset-asset-aliases}

```lua
asset.aliases(ref: RefArg) -> { string }
```

The additional names this asset answers to, beyond its own
identity — what `asset.alias` registered, plus the
package-relative `~pkg.tail` form when the asset lives inside a
package.

**Parameters**

- `ref` `RefArg` — Any name the asset has.

**Returns** `{ string }` — Array of alias names in canonical identity form.

```lua
for _, n in asset.aliases("pbr") do print(n) end
```

## typed/builtin//modules/api/engine/asset/asset/canCreate {#typed-builtin-modules-api-engine-asset-asset-cancreate}

```lua
asset.canCreate(typeName: string) -> boolean
```

Whether `asset.create` can instance `typeName`: the type declares
creation logic (a `behavior.luau` `onCreate` hook) or ships a
`template/` skeleton the hookless fallback clones. A type with neither
— one whose instances only arrive by import — answers false. The query
a creation UI derives its offering from, so what it offers is what
`asset.create` accepts.

**Parameters**

- `typeName` `string` — Registered asset type (e.g. "material", "scene").

**Returns** boolean — true when `asset.create(typeName, …)` can produce one.

```lua
if asset.canCreate(kind) then asset.create(kind, name) end
```

## typed/builtin//modules/api/engine/asset/asset/categories {#typed-builtin-modules-api-engine-asset-asset-categories}

```lua
asset.categories() -> { string }
```

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

**Returns** `{ string }` — Array of category names.

```lua
for _, c in asset.categories() do print(c) end
```

## typed/builtin//modules/api/engine/asset/asset/containing {#typed-builtin-modules-api-engine-asset-asset-containing}

```lua
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.

**Parameters**

- `path` `string` — VFS path to inspect.

**Returns** `AssetRef?` — AssetRef handle, or nil.

```lua
local a = asset.containing("/source/scenes/main.scene/scene.json")
```

## typed/builtin//modules/api/engine/asset/asset/cpuResident {#typed-builtin-modules-api-engine-asset-asset-cpuresident}

```lua
asset.cpuResident(ref: RefArg, typeName: string?) -> boolean
```

True when the asset is CPU-resident — a live script-component context
holds it (a component's assetRef field, or an imperative
`asset.resolve`/`ref` made while a component is the caller), which is what
warms its bytes into memory. The CPU pool is a different pool from the
device's: `asset.observe().cpu` lists it, `asset.observe().textures` /
`.meshes` list what the device holds, and an asset can be in one and not
the other.

**Parameters**

- `ref` `RefArg` — Any name the asset has — handle, identity, guid, name or path.
- `typeName` `string` _(optional)_ — Category to restrict the match to. Omit to search every category.

**Returns** boolean — true when a live context holds it.

```lua
if asset.cpuResident(ref) then print("bytes are warm") end
```

## typed/builtin//modules/api/engine/asset/asset/create {#typed-builtin-modules-api-engine-asset-asset-create}

```lua
asset.create(typeName: string, name: string, opts: { [string]: any }?) -> (AssetRef, { durable: boolean, warning: string?, playShadow: string?, shadowed: { string }? })
```

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.

A create made from a script component's callback or a scene entrypoint is
output the world reproduces on every load, so it is filed in the ephemeral
`/runtime/assets/` store instead, where the saved manifest never carries a
second copy of it. `name` and `folder` spell the same IDENTITY in either
store, so a reference written against that identity resolves the asset
wherever the call filed it, and one generator run from an `execute` and
from a component names one asset.

**Parameters**

- `typeName` `string` — Registered asset type to instance (e.g. "material", "texture").
- `name` `string` — Destination asset name (becomes `/source/<name>.<typeName>`). A
bare identity — pass `opts.folder` to place it in a subfolder rather than
spelling a path here. The accepted shape is the type's to declare:
`^[A-Za-z][A-Za-z0-9_]*$` unless its `behavior.luau` exports a
`namePattern`, as `guide` does to take `getting-started` and `01-overview`.
This call names the category FIRST and the asset second. Every other
`asset.*` call taking both names them the other way round —
`asset.exists(name, category)`, `asset.tryResolve(ref, category)` — so a
create-then-check pair reads `if not asset.exists(n, t) then
asset.create(t, n, opts) end`. A call whose two arguments are read into
each other, at either end of that pair, is refused and told which way
round the call reads.
- `opts` `{ [string]: any }` _(optional)_ — Optional table forwarded to the type's `onCreate` hook, minus four
framework keys consumed here and never seen by the hook:
`folder` (a relative subfolder under `/source` to author the asset in, so
generated content groups instead of accumulating at the source root, and
the asset's identity carries that folder as its dotted prefix),
`into` (author INSIDE a resolved container ref), `dest` (an absolute
destination path), and `overwrite` (re-author in place, keeping the guid).

**Returns** `(AssetRef, { durable: boolean, warning: string?, playShadow: string?, shadowed: { string }? })` — The created asset's `AssetRef` — the SAME interned instance `asset.resolve` returns (guid/__ref/path + the type's ref methods: `:getBytes`, `:ensureHandle`, `:serialize`, …). Disk-only: nothing is uploaded to CPU/GPU. Where the bytes this call landed went, as a SECOND return value: `{ durable = true }` when the files are where the call filed them, and `{ durable = false, warning = …, playShadow = …, shadowed = { … } }` when the play shadow took them — live in this session, disk source untouched, discarded on a guarded play-exit unless kept, with `playShadow` naming the routes that keep them and `shadowed` the paths. `durable` is present whatever the answer is, so its absence is never a reading, and one call answers once for every file it wrote. It is the same answer, off the same shadow set and in the same words, that the MCP `write_file` / `edit_file` / `capture` tools attach to their own results — ask `vfs.durability` for it directly at any other write site.

```lua
local m = asset.create("material", "brick", { shader = "pbr" })
local mesh = asset.create("mesh", "tree", { positions = {...}, indices = {...} })
local mesh = asset.create("mesh", "rock", { positions = {...}, indices = {...}, folder = "terrain/props" })
local mesh = asset.create("mesh", name, { positions = p, indices = i, overwrite = true }) -- idempotent rebuild
local clip, d = asset.create("soundClip", "hit", { pcm = buf, sampleRate = 48000, channels = 1 })
if not d.durable then log.warn(d.warning .. " " .. d.playShadow) end
```

## typed/builtin//modules/api/engine/asset/asset/declareReferenceArg {#typed-builtin-modules-api-engine-asset-asset-declarereferencearg}

```lua
asset.declareReferenceArg(call: string, position: number, assetType: string)
```

Declare that `call`'s argument at 1-based `position` names an
asset of `type`, so a string literal written there is recorded as a
reference. The positional counterpart of
`asset.declareReferenceField`, for a call that takes its asset as a
plain argument — including a world's own spawn helper, which is
where a name most often stops being visible to the reference graph.
A lookup whose asset is its FIRST argument (`asset.resolve` and its
siblings) is already read and needs no declaration. Only a literal —
or a name the file holds in a top-level string constant — is
recorded; anything computed is reported as a dynamic resolve.

**Parameters**

- `call` `string` — The callee as it is written at a call site.
- `position` `number` — Which argument holds the name, counting from 1.
- `assetType` `string`

```lua
asset.declareReferenceArg("spawnModel", 3, "mesh")
```

## typed/builtin//modules/api/engine/asset/asset/declareReferenceField {#typed-builtin-modules-api-engine-asset-asset-declarereferencefield}

```lua
asset.declareReferenceField(call: string, field: string, assetType: string)
```

Declare that `call`'s options table names an asset of `type` in
its `field`, so a string literal written there is recorded as a
reference by whatever writes the file. This is what puts an API
that takes an asset BY NAME into the reference graph: the named
asset becomes a dependency, travels with the content that names it
into a pack or a pull, and a name nothing answers to becomes an
unresolved dependency `worldValidation` reports and the push gate
refuses. A field holding a TABLE of names — a material's `textures`
— records every name in it. Declare once, beside the API; a call
taking its asset as the FIRST positional argument is already read
and needs no declaration. Only a literal is recorded; a computed
name resolves at runtime and is reported as a dynamic resolve.

**Parameters**

- `call` `string` — The callee as it is written at a call site.
- `field` `string` — The options-table field holding the name, read at the
table's own level.
- `assetType` `string`

```lua
asset.declareReferenceField("fx.beam", "material", "material")
```

## typed/builtin//modules/api/engine/asset/asset/declareReferenceKey {#typed-builtin-modules-api-engine-asset-asset-declarereferencekey}

```lua
asset.declareReferenceKey(assetType: string, key: string, refType: string)
```

Declare that, in a data file belonging to an `assetType` asset,
the top-level `key` names an asset of `type` — a `.material`'s
`mat.yaml` naming the shader it draws with and the textures it
binds. The names a format holds are references as surely as ones
written in code: recording them carries a material's shader along
with the material into a pack or a pull, and turns a name nothing
answers to into an unresolved dependency instead of a surface that
renders as the magenta error material. A key holding a table of
names records one per entry.

**Parameters**

- `assetType` `string` — The category owning the file, e.g. "material".
- `key` `string` — The top-level key holding the name(s).
- `refType` `string`

```lua
asset.declareReferenceKey("material", "shader", "shader")
```

## typed/builtin//modules/api/engine/asset/asset/deps {#typed-builtin-modules-api-engine-asset-asset-deps}

```lua
asset.deps(ref: RefArg, type: string?) -> DepsResult
```

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

**Parameters**

- `ref` `RefArg` — Any name the asset has.
- `type` `string` _(optional)_ — Category hint (optional).

**Returns** `DepsResult` — `{ deps = { { asset_guid, origin, literal, via, ... } } }`.

```lua
for _, d in asset.deps("main.scene").deps do print(d.asset_guid) end
```

## typed/builtin//modules/api/engine/asset/asset/describe {#typed-builtin-modules-api-engine-asset-asset-describe}

```lua
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.

**Parameters**

- `typeName` `string` — Registered asset type to describe (e.g. "texture").

**Returns** DescribeResult — the creation contract.

```lua
local contract = asset.describe("texture").contract
```

## typed/builtin//modules/api/engine/asset/asset/diagnose {#typed-builtin-modules-api-engine-asset-asset-diagnose}

```lua
asset.diagnose(ref: RefArg) -> any
```

Why one asset can or cannot be used, read from the engine rather than
from what the caller asked for. Always carries `usable`; when false,
`reason` is one of `asset.unusableReasons()` and `detail` is the engine's
own message. `primary` names the file the type's declared `primary` list
resolved to, so an asset that loaded a preview image instead of its
payload shows the wrong filename rather than a successful load. The
payload's bytes are read by the engine's own decoder wherever it has one
for that container, so `usable` is the verdict a load would reach and the
call costs that decode.

**Parameters**

- `ref` `RefArg` — Any name the asset has — handle, identity, guid, name or path.

**Returns** `any` — DiagnoseRecord

```lua
local d = asset.diagnose("myTex") if not d.usable then print(d.reason, d.detail) end
```

## typed/builtin//modules/api/engine/asset/asset/exists {#typed-builtin-modules-api-engine-asset-asset-exists}

```lua
asset.exists(name: string, typeName: string) -> boolean
```

**Parameters**

- `name` `string`
- `typeName` `string`

**Returns** `boolean`

## typed/builtin//modules/api/engine/asset/asset/get_field {#typed-builtin-modules-api-engine-asset-asset-get-field}

```lua
asset.get_field(ref: RefArg, key: string) -> any
```

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

**Parameters**

- `ref` `RefArg` — Any name the asset has.
- `key` `string` — Field name.

**Returns** `any` — Field value or nil.

```lua
local author = asset.get_field("brick", "author")
local settings = asset.get_field("tree", "settings") -- → a Luau table
```

## typed/builtin//modules/api/engine/asset/asset/gpuResident {#typed-builtin-modules-api-engine-asset-asset-gpuresident}

```lua
asset.gpuResident(ref: RefArg) -> boolean
```

True when the device holds a texture or mesh under this asset's guid,
read off the inventory the renderer publishes.

**Parameters**

- `ref` `RefArg` — Any name the asset has — handle, identity, guid, name or path.

**Returns** boolean — true when the device holds it.

```lua
print(asset.gpuResident("@builtin::models.Sample.DamagedHelmet"))
```

## typed/builtin//modules/api/engine/asset/asset/guid {#typed-builtin-modules-api-engine-asset-asset-guid}

```lua
asset.guid(ref: RefArg, type: string?) -> string
```

Return the guid for an asset.

**Parameters**

- `ref` `RefArg` — Any name the asset has.
- `type` `string` _(optional)_ — Category hint (optional).

**Returns** `string` — Guid.

```lua
local g = asset.guid("@builtin::components.Camera")
```

## typed/builtin//modules/api/engine/asset/asset/has_field {#typed-builtin-modules-api-engine-asset-asset-has-field}

```lua
asset.has_field(ref: RefArg, key: string) -> boolean
```

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

**Parameters**

- `ref` `RefArg` — Any name the asset has.
- `key` `string` — Field name.

**Returns** `boolean` — True when present.

```lua
if asset.has_field("brick", "author") then end
```

## typed/builtin//modules/api/engine/asset/asset/has_tag {#typed-builtin-modules-api-engine-asset-asset-has-tag}

```lua
asset.has_tag(ref: RefArg, tag: string) -> boolean
```

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

**Parameters**

- `ref` `RefArg` — Any name the asset has.
- `tag` `string` — Tag to check for.

**Returns** `boolean` — True when present.

```lua
if asset.has_tag("brick", "wip") then end
```

## typed/builtin//modules/api/engine/asset/asset/identity {#typed-builtin-modules-api-engine-asset-asset-identity}

```lua
asset.identity(ref: RefArg, type: string?) -> string
```

Return the canonical identity for an asset.

**Parameters**

- `ref` `RefArg` — Any name the asset has.
- `type` `string` _(optional)_ — Category hint (optional).

**Returns** `string` — Canonical identity.

```lua
local id = asset.identity("brick")
```

## typed/builtin//modules/api/engine/asset/asset/import {#typed-builtin-modules-api-engine-asset-asset-import}

```lua
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.

**Parameters**

- `path` `string` — The raw source VFS path to import (e.g. a just-written `.glb`).

**Returns** `string?` — The produced asset path, or nil when nothing claimed it.

```lua
local bundle = asset.import("/zero/source/generated/chest.glb")
```

## typed/builtin//modules/api/engine/asset/asset/inspect {#typed-builtin-modules-api-engine-asset-asset-inspect}

```lua
asset.inspect(ref: RefArg, type: string?) -> InspectRecord
```

Everything known about one asset in a single record: identity, guid,
source, type, scope and origin, its description and tags, the ref methods
its type exposes, and the type's own `inspect` detail when it declares one.
The read-everything counterpart to `asset.resolve`, which hands back a ref.

**Parameters**

- `ref` `RefArg` — An `AssetRef`, an identity string, or a path.
- `type` `string` _(optional)_ — Narrow the resolve to one asset type when assets of several
categories answer to the same bare name.

**Returns** `InspectRecord` — The inspect record.

```lua
local rec = asset.inspect("@builtin::materials.default")
local rec = asset.inspect(name, "mesh"); print(rec.guid, #rec.tags)
```

## typed/builtin//modules/api/engine/asset/asset/list {#typed-builtin-modules-api-engine-asset-asset-list}

```lua
asset.list(type_or_opts: (AssetCategory | ListOpts)?, scope: string?, opts: ListOpts?) -> ListResult
```

Query registered assets, returning each match as a resolved
`AssetRef` handle. Every filter narrows the same enumeration and
they compose: `path` selects a VFS subtree (the folder and
everything under it), `type` keeps only those asset types within
it, `scope` keeps only that scope, and `fields` keeps only assets
whose `.metadata` matches. `type` and `path` each take one value or
a list matching any of its entries, and `all` / `any` / `none`
group whole filters — `none` excludes what it matches. `order`,
`limit`, and `offset` shape the result: matches come back ordered
by identity unless `order` names another field
(`name` / `path` / `type` / `guid`).
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, and the result carries
`:first()` / `:random()` / `:filter()` / `:sort()` and friends.
`type` takes the same values `asset.categories()` lists. The first
positional argument is a path when it is absolute, a type
otherwise. An unknown key raises, as does a table setting both
`type` and its older spelling `category`.
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.

**Parameters**

- `type_or_opts` `(AssetCategory | ListOpts)` _(optional)_ — Type or VFS path filter (a static literal so the
enumeration can be captured for publish), or the full query table.
- `scope` `string` _(optional)_ — Scope filter (when first arg is a type).
- `opts` `ListOpts` _(optional)_ — The query table — see `ListOpts`.

**Returns** `ListResult` — The matched AssetRef handles, as a result carrying query methods.

```lua
local hero = asset.list({ path = "/zero/source/props", type = "mesh", fields = { tags = "hero" } }):first()
```

## typed/builtin//modules/api/engine/asset/asset/list_field_values {#typed-builtin-modules-api-engine-asset-asset-list-field-values}

```lua
asset.list_field_values(key: string) -> { any }
```

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

**Parameters**

- `key` `string` — Field name.

**Returns** `{ any }` — Array of distinct values.

```lua
local authors = asset.list_field_values("author")
```

## typed/builtin//modules/api/engine/asset/asset/list_fields {#typed-builtin-modules-api-engine-asset-asset-list-fields}

```lua
asset.list_fields() -> { string }
```

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

**Returns** `{ string }` — Array of field names.

```lua
for _, k in asset.list_fields() do print(k) end
```

## typed/builtin//modules/api/engine/asset/asset/meta {#typed-builtin-modules-api-engine-asset-asset-meta}

```lua
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`.

**Parameters**

- `ref` `RefArg` — Any name the asset has.
- `type` `string` _(optional)_ — Category hint (optional).

**Returns** `AssetMeta` — Metadata table.

```lua
local m = asset.meta("brick") -- { guid = ..., checksum = ... }
```

## typed/builtin//modules/api/engine/asset/asset/metadata {#typed-builtin-modules-api-engine-asset-asset-metadata}

```lua
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).

**Parameters**

- `ref` `RefArg` — Any name the asset has.
- `type` `string` _(optional)_ — Category hint (optional).

**Returns** `AssetMeta` — JSON-shaped table; empty when no sidecar exists.

```lua
local md = asset.metadata("brick")
```

## typed/builtin//modules/api/engine/asset/asset/observe {#typed-builtin-modules-api-engine-asset-asset-observe}

```lua
asset.observe() -> any
```

What the engine is holding for content right now, in one reading:
`textures` and `meshes` (one row per resource the device holds, each with
the bytes it costs, its dimensions or buffer split, and where it came
from), `cpu` (one row per asset a live script-component context holds),
and `totals` — the aggregates those rows sum to, so the listing reconciles
against `renderer.textureMemory()` and `renderer.gpuMemory()`.

Each pool is named because they are different pools: an asset can be on
the device and not CPU-resident, or the reverse. `devicePublished` is
false when no renderer has published an inventory and `cpuPublished` when
the scripting VM has not published its pool — an engine that cannot answer
reads differently from one answering with nothing resident.

**Returns** `any` — ResidencyReading

```lua
local r = asset.observe() print(#r.textures, r.totals.textureBytes)
```

## typed/builtin//modules/api/engine/asset/asset/preview {#typed-builtin-modules-api-engine-asset-asset-preview}

```lua
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").

**Parameters**

- `ref` `RefArg` — Any name the asset has.
- `opts` `{ [string]: any }` _(optional)_ — Optional `{ size = { width, height }, angle = { yaw, pitch } }`.
- `type` `string` _(optional)_ — Category hint (optional).

**Returns** `{ [string]: any }` — `{ available, imageBase64?, width?, height?, bounds?, stats?, reason? }`.

```lua
local p = asset.preview("@builtin::materials.gold", { size = { width = 512, height = 512 } })
```

## typed/builtin//modules/api/engine/asset/asset/primaryFile {#typed-builtin-modules-api-engine-asset-asset-primaryfile}

```lua
asset.primaryFile(ref: RefArg) -> any
```

The file the asset type's declared `primary` list resolves to inside
this asset, as the loader itself resolves it. `resolved` is false when no
declaration matched and `path` is then absent; `declared` is the type's
own primary list in match order.

**Parameters**

- `ref` `RefArg` — Any name the asset has — handle, identity, guid, name or path.

**Returns** `any` — `{ path: string?, resolved: boolean, isFolder: boolean, declared: { string } }`

```lua
print(asset.primaryFile("myTex").path)
```

## typed/builtin//modules/api/engine/asset/asset/ref {#typed-builtin-modules-api-engine-asset-asset-ref}

```lua
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).

Naming the asset here reads exactly as naming it in `asset.resolve`,
down to raising on a miss: a literal is recorded as this source's
dependency, a computed name is a dynamic resolve — free in a tool,
refused on the gameplay path. `asset.exists(name, type)` is the probe a
computed name can ask.

## typed/builtin//modules/api/engine/asset/asset/reloadPending {#typed-builtin-modules-api-engine-asset-asset-reloadpending}

```lua
asset.reloadPending(ref: RefArg, typeName: string?) -> boolean
```

True while a write to this asset still owes it a reload — the write is
inside the settle window that collects one authoring step's writes, or its
reload is queued and the engine has not run it yet. False means every
content change written so far has reached its subscribers, so a consumer
bound to the asset now cannot be interrupted by a reload the earlier
writes already earned. The recording is synchronous with the write, so a
call made right after one already reads true.

**Parameters**

- `ref` `RefArg` — Any name the asset has — handle, identity, guid, name or path.
- `typeName` `string` _(optional)_ — Category to restrict the match to. Omit to search every category.

**Returns** boolean — true while a content-change reload is still owed.

```lua
repeat task.wait() until not asset.reloadPending(ref)
```

## typed/builtin//modules/api/engine/asset/asset/reloadSeq {#typed-builtin-modules-api-engine-asset-asset-reloadseq}

```lua
asset.reloadSeq(ref: RefArg, typeName: string?) -> number
```

How many content-change reloads this asset has been through — the
count of `onAssetReload` dispatches the engine has RUN for it. A write to
a file inside an asset does not reload it on the spot: the writes of one
authoring step are collected for a settle window and the reload runs on a
later frame. Read this, write, then poll for a larger number to learn the
write's reload has actually reached subscribers. Monotonic per asset and
session-scoped; 0 for an asset whose content has not changed since boot.

**Parameters**

- `ref` `RefArg` — Any name the asset has — handle, identity, guid, name or path.
- `typeName` `string` _(optional)_ — Category to restrict the match to. Omit to search every category.

**Returns** number — content-change reloads dispatched for this asset.

```lua
local at = asset.reloadSeq(ref)
vfs.write(asset.source(ref) .. "/graph.json", encoded)
repeat task.wait() until asset.reloadSeq(ref) > at
```

## typed/builtin//modules/api/engine/asset/asset/remove_field {#typed-builtin-modules-api-engine-asset-asset-remove-field}

```lua
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.

**Parameters**

- `ref` `RefArg` — Any name the asset has.
- `key` `string` — Field name.

```lua
asset.remove_field("brick", "author")
```

## typed/builtin//modules/api/engine/asset/asset/remove_tag {#typed-builtin-modules-api-engine-asset-asset-remove-tag}

```lua
asset.remove_tag(ref: RefArg, tag: string)
```

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

**Parameters**

- `ref` `RefArg` — Any name the asset has.
- `tag` `string` — Tag to remove.

```lua
asset.remove_tag("brick", "wip")
```

## typed/builtin//modules/api/engine/asset/asset/resolve {#typed-builtin-modules-api-engine-asset-asset-resolve}

```lua
asset.resolve(ref: RefArg, type: (C & string)?) -> AssetRef<C>
```

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 `ref` reaches more than one
asset, where it names the candidates for you to pick from instead of
picking one of them. A `<scope>::`-qualified identity reaches exactly one:
`@root::name` for the asset this world holds at its source root, the
library identity (`@builtin::…`) for a library's. For the same lookup
answering a miss with nil, use `asset.tryResolve(ref, type)`.

A name written as a string LITERAL is recorded as this source's
dependency on that asset, so the asset travels with the content and
still resolves once someone installs it in another world. A COMPUTED
name cannot be written down, so nothing pins what it reaches: that is a
dynamic resolve — free in a tool, refused on the gameplay path (a
component or scene entrypoint). `asset.tryResolve`, `asset.ref` and
`asset.source` read the name they are given exactly this way too, so
which of the four you reach for changes neither answer. To ask whether a
computed name has files without reaching a handle, use
`asset.exists(name, type)`.

**Parameters**

- `ref` `RefArg` — The asset to find — an identity, a guid, a VFS path, or a handle.
- `type` `(C & string)` _(optional)_ — Category to restrict the match to (optional). Separates a bare
name that assets of different categories share (`asset.resolve("cube",
"mesh")`); where several assets of the SAME category answer to it, the
scope-qualified identity is what separates them.
A reference naming a file an importer has since promoted (`wall.png`
after the texture importer turned it into `wall.texture`) resolves to the
promoted asset, and says so in the log once per reference.

**Returns** `AssetRef<C>` — Asset handle, carrying the category when one was named — so the methods that category defines are checked on the result. Raises (rather than returning nil) on a miss, and on a name that reaches more than one asset.

```lua
local a = asset.resolve("@builtin::components.Camera")
```

## typed/builtin//modules/api/engine/asset/asset/set_field {#typed-builtin-modules-api-engine-asset-asset-set-field}

```lua
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`.

**Parameters**

- `ref` `RefArg` — Any name the asset has.
- `key` `string` — Field name.
- `value` `any` _(optional)_ — Field value (any JSON-serialisable Lua value).

```lua
asset.set_field("brick", "author", "me")
asset.set_field("tree", "settings", { keepCpu = true }) -- merges; sibling settings kept
```

## typed/builtin//modules/api/engine/asset/asset/set_metadata {#typed-builtin-modules-api-engine-asset-asset-set-metadata}

```lua
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.

**Parameters**

- `ref` `RefArg` — Any name the asset has.
- `data` `AssetMeta` — Full JSON-shaped contents for the sidecar.

```lua
asset.set_metadata("brick", { author = "me", tags = { "wip" } })
```

## typed/builtin//modules/api/engine/asset/asset/source {#typed-builtin-modules-api-engine-asset-asset-source}

```lua
asset.source(ref: RefArg, type: string?) -> string
```

Return the VFS source path for an asset.

It reaches the asset, so the name carries the same reference contract
`asset.resolve`'s does: a literal is recorded as this source's
dependency, a computed name is a dynamic resolve — free in a tool,
refused on the gameplay path. `asset.exists(name, type)` is the probe a
computed name can ask.

**Parameters**

- `ref` `RefArg` — Any name the asset has.
- `type` `string` _(optional)_ — Category hint (optional).

**Returns** `string` — VFS source path.

```lua
local p = asset.source("brick") -- "/source/brick.material"
```

## typed/builtin//modules/api/engine/asset/asset/tags {#typed-builtin-modules-api-engine-asset-asset-tags}

```lua
asset.tags(ref: RefArg) -> { string }
```

Convenience read of the `.metadata.tags` array.

**Parameters**

- `ref` `RefArg` — Any name the asset has.

**Returns** `{ string }` — Array of tag strings.

```lua
for _, t in asset.tags("brick") do print(t) end
```

## typed/builtin//modules/api/engine/asset/asset/tryResolve {#typed-builtin-modules-api-engine-asset-asset-tryresolve}

```lua
asset.tryResolve(ref: RefArg, type: string?, base: string?) -> AssetRef?
```

The same lookup `asset.resolve` performs, answering a miss with nil
instead of raising. Every name form, the same `type` narrowing, and the
same handle on success — so "use it if it is there" needs no `pcall`
around a call whose failure would otherwise be indistinguishable from a
real error.

This consults the asset REGISTRY, so it sees registered assets wherever
their files live, `@builtin::` ones included. `asset.exists(name, type)`
answers the narrower question of whether an asset's files are present in
the current mode's store.

A name that reaches more than one asset still raises — that is a question
about the reference, not about presence, and a nil there would report
absence for content that is present twice.

It reaches the asset, so the name carries the same reference contract
`asset.resolve`'s does: a literal is recorded as this source's
dependency, a computed name is a dynamic resolve — free in a tool,
refused on the gameplay path. `asset.exists(name, type)` is the probe a
computed name can ask.

**Parameters**

- `ref` `RefArg` — The asset to look up — an identity, a guid, a VFS path, or a handle.
- `type` `string` _(optional)_ — Category to restrict the match to (optional).
A reference naming a file an importer has since promoted resolves to the
promoted asset, the same as `asset.resolve`.
- `base` `string` _(optional)_ — Referring VFS path a `~` / `~.tail` ref expands against, the same
as `asset.resolve`'s — so the two answer the same question and differ only
in what a miss is.

**Returns** `AssetRef?` — Asset handle, or nil when the reference resolves to no asset.

```lua
local mat = asset.tryResolve(name, "material")
```

## typed/builtin//modules/api/engine/asset/asset/typeRef {#typed-builtin-modules-api-engine-asset-asset-typeref}

```lua
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.

## typed/builtin//modules/api/engine/asset/asset/unusableReasons {#typed-builtin-modules-api-engine-asset-asset-unusablereasons}

```lua
asset.unusableReasons() -> { string }
```

Every reason `asset.diagnose` can report an asset unusable for, sorted.

**Returns** `{ string }` — Array of reason names.

```lua
for _, r in ipairs(asset.unusableReasons()) do print(r) end
```

## typed/builtin//modules/api/engine/asset/asset/validate {#typed-builtin-modules-api-engine-asset-asset-validate}

```lua
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.

**Parameters**

- `ref` `RefArg` — Any name the asset has.
- `type` `string` _(optional)_ — Category hint (optional).

**Returns** `ValidateResult` — `{ ok, typeName, validated, problems }`.

```lua
local v = asset.validate("@builtin::components.Camera")
```

## typed/builtin//modules/api/engine/asset/asset/warmup {#typed-builtin-modules-api-engine-asset-asset-warmup}

```lua
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`).

**Parameters**

- `ref` `RefArg` — Any name the root asset has — handle, identity, guid, or path.
- `opts` `WarmupOpts` _(optional)_ — Optional `{ vias, max }` — restrict ref-edge kinds / cap closure size.

**Returns** `WarmupResult` — `{ closure, count }` — the deduped guid closure warmed and its size.

```lua
local w = asset.warmup("@builtin::scenes.test_arena")
```

## typed/builtin//modules/api/engine/audio/audio/decode {#typed-builtin-modules-api-engine-audio-audio-decode}

```lua
audio.decode(zaud: buffer | string) -> (string?, number?, number?)
```

Decode a ZAUD payload into interleaved f32 PCM. A PCM payload comes
back as the frames its header accounts for, held to the whole frames the
bytes behind it fill, so the sample count is always a whole number of
`channels` and a consumer walking it `channels` at a time ends on a frame.

**Parameters**

- `zaud` `buffer | string` — A ZAUD payload — a buffer or a binary string.

**Returns** `(string?, number?, number?)` — `(pcm, sampleRate, channels)`, or `(nil, err)`.

## typed/builtin//modules/api/engine/audio/audio/device {#typed-builtin-modules-api-engine-audio-audio-device}

```lua
audio.device() -> AudioDeviceStatus
```

What the engine's audio output is doing: `state` is `"open"` while a
stream is running on an output device and `"silent"` while none is, and
`device` names the device an open stream runs on. The counters record
what the engine has been through keeping one open — `faults` a live
stream reported, `changes` of the host's default output, `reopens` the
engine made, `failedOpens` the platform refused, and the `glitches` a
listener heard as dropouts, with `lastError` carrying what the platform
said. A device that goes away leaves the mixer running and the engine
opening a stream again as soon as one is there.

**Returns** `AudioDeviceStatus` — An `AudioDeviceStatus`.

```lua
local d = audio.device(); print(d.state, d.device, d.reopens)
```

## typed/builtin//modules/api/engine/audio/audio/encode {#typed-builtin-modules-api-engine-audio-audio-encode}

```lua
audio.encode(sourceBytes: buffer | string, opts: { [string]: any }?) -> (string?, string?)
```

Encode container audio bytes (ogg / mp3 / wav / flac) into a ZAUD
payload. Every decoded sample must be finite; a source whose samples carry
a NaN or an infinity comes back as `(nil, err)` naming how many fail and
where the first one sits.

**Parameters**

- `sourceBytes` `buffer | string` — Encoded source audio bytes — a buffer or a binary string.
- `opts` `{ [string]: any }` _(optional)_ — `{ codec: "opus"|"pcm"?, bitrateKbps: number?, vbr: boolean?, sampleRate: number?, forceMono: boolean?, loopStart: number?, loopEnd: number? }`

**Returns** `(string?, string?)` — The ZAUD bytes, or `(nil, err)`.

```lua
local zaud = audio.encode(oggBytes, { bitrateKbps = 96 })
```

## typed/builtin//modules/api/engine/audio/audio/encodePcm {#typed-builtin-modules-api-engine-audio-audio-encodepcm}

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

Encode raw interleaved f32 PCM into a ZAUD payload. Every sample must
be finite; a buffer carrying a NaN or an infinity comes back as
`(nil, err)` naming how many fail and where the first one sits, so a
filter that diverged over part of a bake is caught before it is written.
The sample count is a whole number of `channels`: a buffer with a tail
over comes back as `(nil, err)` naming the whole frames it holds and the
samples past them.

**Parameters**

- `pcm` `any` _(optional)_ — Interleaved f32 samples — a buffer or a binary string of
little-endian f32, the shape `microphone.samples` and `audio.decode` hand
back, or a flat number array. A byte payload's samples are its 4-byte
lanes, and a length that stops partway through one comes back as
`(nil, err)` naming the whole samples it holds and the bytes past them.
- `sampleRate` `number` — Source sample rate in Hz.
- `channels` `number` — 1 or 2, and a divisor of the sample count.
- `opts` `{ [string]: any }` _(optional)_ — Same shape as `audio.encode`.

**Returns** `(string?, string?)` — The ZAUD bytes, or `(nil, err)`.

```lua
local s = microphone.status(); local zaud = audio.encodePcm(microphone.samples(), s.sampleRate, 1)
```

## typed/builtin//modules/api/engine/audio/audio/info {#typed-builtin-modules-api-engine-audio-audio-info}

```lua
audio.info(zaud: buffer | string) -> (AudioInfo?, string?)
```

Read a ZAUD payload's header. A PCM payload's samples are its bytes, and
the header is read against them: a sample count differing from
`frames * channels` comes back as `(nil, err)` naming both counts, and a
sample carrying a NaN or an infinity comes back as `(nil, err)` naming how
many fail and where the first one sits, so the header handed back describes
a clip that is as long as it says and can sound. The header describes the
clip's shape — rate, channels, frames, duration, codec, loop points. What
the samples do where a whole-clip loop wraps is a reading of its own,
`audio.loopSeam`, which is the call that answers whether a bed cycles
without a click.

**Parameters**

- `zaud` `buffer | string` — A ZAUD payload — a buffer or a binary string.

**Returns** `(AudioInfo?, string?)` — An `AudioInfo` table, or `(nil, err)`.

```lua
local info = audio.info(zaud); print(info.durationMs)
```

## typed/builtin//modules/api/engine/audio/audio/levels {#typed-builtin-modules-api-engine-audio-audio-levels}

```lua
audio.levels() -> AudioLevels
```

The master mix's peak and RMS over the meter's most recent closed
window, measured without recording anything.

**Returns** `AudioLevels` — An `AudioLevels`.

```lua
local l = audio.levels(); print(l.peak, l.rms, l.windowMs)
```

## typed/builtin//modules/api/engine/audio/audio/listener {#typed-builtin-modules-api-engine-audio-audio-listener}

```lua
audio.listener() -> AudioListenerState
```

Where the scene is heard from, how many active listeners exist, and
which entity's listener drives the ears.

**Returns** `AudioListenerState` — An `AudioListenerState`.

```lua
local l = audio.listener(); print(l.present, l.count, l.entity)
```

## typed/builtin//modules/api/engine/audio/audio/loopSeam {#typed-builtin-modules-api-engine-audio-audio-loopseam}

```lua
audio.loopSeam(zaud: buffer | string) -> (AudioLoopSeam?, string?)
```

Measure what a clip's samples do where a whole-clip loop wraps, so a bed
can be judged before anyone hears it tick. The wrap's own step
(`|x[1] - x[frames]|`) is reported against the step the signal ordinarily
makes between neighbouring samples, as `ratio = step / meanStep` — a figure
in the units the signal itself moves in, so a quiet ambience and a loud
drone are read the same way. A bed whose partials wrap reads near 1; one
carrying a strike at its head and silence at its tail reads in the tens.
`ratio` and the `step` / `meanStep` / `maxStep` beside it belong to the
worst channel, `channel` names it, and `channels` carries every channel's
own reading. `seamless` is `ratio <= threshold`, the same threshold
`asset.create("soundClip", ...)` warns past. The reading is taken on the
DECODED samples, so it answers for what the codec left behind and for a
clip that arrived already encoded and whose source buffer nobody holds.
Costs a decode of the whole payload; `audio.info` reads a header without
one.

**Parameters**

- `zaud` `buffer | string` — A ZAUD payload — a buffer or a binary string.

**Returns** `(AudioLoopSeam?, string?)` — An `AudioLoopSeam` table, or `(nil, err)`.

```lua
local seam = audio.loopSeam(clipRef:getBytes()); print(seam.ratio, seam.seamless)
```

## typed/builtin//modules/api/engine/audio/audio/mixer {#typed-builtin-modules-api-engine-audio-audio-mixer}

```lua
audio.mixer() -> AudioMixerLevels
```

The levels the mixer is applying to the mix right now: the master
level, whether the mix is muted, and the level of every channel one has
been set on. A channel absent from `channels` plays at unity, so a
source naming it is heard at the volume it asks for.

**Returns** `AudioMixerLevels` — An `AudioMixerLevels`.

```lua
local m = audio.mixer(); print(m.master, m.muted, m.channels.music)
```

## typed/builtin//modules/api/engine/audio/audio/observe {#typed-builtin-modules-api-engine-audio-audio-observe}

```lua
audio.observe() -> AudioObservation
```

Report what the mixer is making audible right now, and why a source
is not. One read covering every live voice with the mixer's own playback
state and effective gain, the master mix's level, the mixer's voice
accounting, the listener, the output device the mix is reaching, and what
the subsystem costs. Answers in edit mode as well as play mode.

**Returns** `AudioObservation` — An `AudioObservation`.

```lua
local a = audio.observe(); print(a.audibleCount, a.levels.rms)
for _, v in audio.observe().voices do print(v.entity, v.mixerState, v.silence) end
```

## typed/builtin//modules/api/engine/audio/audio/peakSince {#typed-builtin-modules-api-engine-audio-audio-peaksince}

```lua
audio.peakSince(window: number) -> number?
```

The loudest peak the master mix reached across the meter's windows
that closed after its `windows` count stood at `window`. `audio.levels()`
carries the window that closed last, so a reader sees the windows its own
frames happen to land on; this spans all of them, which is what measuring
a sound shorter than the gap between two reads takes. Take the mark from
`audio.levels().windows` before the sound starts, wait until `windows` has
advanced past the sound's length, then read the span.

**Parameters**

- `window` `number` — A `windows` count taken from `audio.levels()` earlier.

**Returns** `number?` — The loudest window peak in the span, or nil when the meter holds no peak for it — nothing has closed since `window`, or the span reaches further back than the meter's history of recent windows, so a reader that came back too late learns that instead of reading the maximum of the part that survived.

```lua
local mark = audio.levels().windows
local peak = audio.peakSince(mark)
```

## typed/builtin//modules/api/engine/audio/audio/profile {#typed-builtin-modules-api-engine-audio-audio-profile}

```lua
audio.profile() -> AudioProfile
```

What the audio subsystem has cost since the profiling window opened —
the streaming pump, clip decode, clip encode, voice starts, and building
the observation itself. Every total is a SUM across that window rather
than a per-frame figure, and the window runs from the last
`audio.resetProfile()` or from engine start. For what a frame costs now,
reset, let frames pass, then divide by the `frames` the window reports.

**Returns** `AudioProfile` — An `AudioProfile`.

```lua
audio.resetProfile(); task.wait(1); local p = audio.profile()
print("per frame:", (p.pump.totalMs + p.observe.totalMs) / p.frames)
```

## typed/builtin//modules/api/engine/audio/audio/resetProfile {#typed-builtin-modules-api-engine-audio-audio-resetprofile}

```lua
audio.resetProfile()
```

Open a new audio profiling window, discarding what the previous one
measured. Call this before timing a stretch of frames: without it
`audio.profile()` reports totals reaching back to engine start.

```lua
audio.resetProfile()
```

## typed/builtin//modules/api/engine/audio/audio/setChannelVolume {#typed-builtin-modules-api-engine-audio-audio-setchannelvolume}

```lua
audio.setChannelVolume(channel: string, volume: number)
```

Set the level of one mixer channel — the `channel` an `Audio`
component names, such as "sfx", "music" or "ambient", or any name the
scene invents. It scales every voice on that channel and nothing else,
reaches voices that are already playing, and comes back per voice as
`gain.channel`. A channel no level has been set on plays at unity.

**Parameters**

- `channel` `string` — The channel name, matching `Audio.channel`.
- `volume` `number` — Channel level, 0..1.

```lua
audio.setChannelVolume("music", 0.3)
for _, v in audio.voices() do print(v.channel, v.gain.channel) end
```

## typed/builtin//modules/api/engine/audio/audio/setMasterVolume {#typed-builtin-modules-api-engine-audio-audio-setmastervolume}

```lua
audio.setMasterVolume(volume: number)
```

Set the master level of the mix, on the engine's 0..1 amplitude
scale. It scales every voice whatever channel it plays on, reaches
voices that are already playing, and comes back per voice as
`gain.master`.

**Parameters**

- `volume` `number` — Master level, 0..1.

```lua
audio.setMasterVolume(0.5)
```

## typed/builtin//modules/api/engine/audio/audio/setMuted {#typed-builtin-modules-api-engine-audio-audio-setmuted}

```lua
audio.setMuted(muted: boolean)
```

Silence or unsilence the whole mix. A muted mix sounds nothing
whatever its master and channel levels read, every voice reports
`masterSilent`, and unmuting hands the levels back untouched.

**Parameters**

- `muted` `boolean` — Whether the mix is silenced.

```lua
audio.setMuted(true)
```

## typed/builtin//modules/api/engine/audio/audio/voice {#typed-builtin-modules-api-engine-audio-audio-voice}

```lua
audio.voice(entityId: string) -> AudioVoice?
```

The voice on one entity, or nil when that entity carries no audio
source.

**Parameters**

- `entityId` `string` — The entity's stable id.

**Returns** `AudioVoice?` — An `AudioVoice`, or nil.

```lua
local v = audio.voice(e.id); print(v and v.mixerState)
```

## typed/builtin//modules/api/engine/audio/audio/voiceAccounting {#typed-builtin-modules-api-engine-audio-audio-voiceaccounting}

```lua
audio.voiceAccounting() -> AudioVoiceAccounting
```

How many voices the mixer can hold, how many are in use, how many
are free — read off the mixer's own tracks, so the free count is the one
a play call is granted or refused against. The two pools are reported
apart: `capacity` / `inUse` / `free` are the main track, which carries
the NON-spatial voices, while a spatial voice plays through its own
sub-track and is counted by `spatialInUse` instead. `sourcesHolding`
counts both pools from the sources that own them, so it equals
`inUse + spatialInUse` while every voice answers to a source.

**Returns** `AudioVoiceAccounting` — An `AudioVoiceAccounting`.

```lua
local v = audio.voiceAccounting(); print(v.inUse .. "/" .. v.capacity)
local v = audio.voiceAccounting(); print(v.sourcesHolding - (v.inUse + v.spatialInUse))
```

## typed/builtin//modules/api/engine/audio/audio/voices {#typed-builtin-modules-api-engine-audio-audio-voices}

```lua
audio.voices() -> { AudioVoice }
```

Every live audio source with the mixer's opinion of it.

**Returns** `{ AudioVoice }` — An array of `AudioVoice`.

```lua
for _, v in audio.voices() do print(v.clip, v.gain.effective) end
```

## typed/builtin//modules/api/engine/audio/audio/whySilent {#typed-builtin-modules-api-engine-audio-audio-whysilent}

```lua
audio.whySilent(entityId: string) -> (string?, string?)
```

Why the source on an entity is making no sound. Returns nil when it
IS sounding, and one of `noBackend`, `noDevice`, `notResident`, `neverStarted`,
`refused`, `paused`, `ended`, `gainZero`, `channelSilent`,
`masterSilent`, `outOfRange` when it is not — the nearest cause, so the
answer names the thing to change. A second
return carries the mixer's own words when it refused the source, and
`"no audio source on this entity"` when nothing there plays at all.

**Parameters**

- `entityId` `string` — The entity's stable id.

**Returns** `(string?, string?)` — `(reason, detail)`.

```lua
local why = audio.whySilent(e.id); if why then print(why) end
```

## typed/builtin//modules/api/engine/av/av/is_live {#typed-builtin-modules-api-engine-av-av-is-live}

```lua
av.is_live() -> boolean
```

True if a live-stream session is currently active.

**Returns** `boolean` — Whether the live encoder is running.

```lua
if av.is_live() then av.stop_live() end
```

## typed/builtin//modules/api/engine/av/av/is_recording {#typed-builtin-modules-api-engine-av-av-is-recording}

```lua
av.is_recording() -> boolean
```

True if a recording session is currently active.

**Returns** `boolean` — Whether a recording is in progress.

```lua
print("recording:", av.is_recording())
```

## typed/builtin//modules/api/engine/av/av/live {#typed-builtin-modules-api-engine-av-av-live}

```lua
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.

**Parameters**

- `opts` `LiveOpts` _(optional)_ — Encoder options.

**Returns** `string?` — Stream URL or nil.

```lua
local url = av.live({ width = 1280, height = 720, fps = 60 })
```

## typed/builtin//modules/api/engine/av/av/record {#typed-builtin-modules-api-engine-av-av-record}

```lua
av.record(path: string, opts: RecordOpts?) -> (string?, string?)
```

Start recording the engine output to a VFS path. Default dir
is `/zero/runtime/recordings/` when `path` is not absolute. The
take runs until `av.stop_recording()` unless `opts` bounds it
with `max_duration_sec` (seconds of the take's own clock) or
`frames` (captured frames); `max_duration_sec` wins when both are
given, and the bound in force reads back as
`av.status().recordingBound`. With
no `chroma`/`range` opts the format defaults to full-range 4:4:4
HEVC where the GPU supports it, else 4:2:0. On the `"software"`
backend the take is H.264 encoded on the CPU, which costs the run
it records: read `av.status().recordingAchievedFps` against
`recordingRequestedFps` to see the rate it reached. What the take
did with the master mix reads back as
`av.status().recordingAudio`. `cadence` picks the clock the take
stamps its frames from. `"realtime"` (the default) stamps each
frame with the wall-clock slot it was captured in, so a recorded
session is watched back at the speed it happened and an engine
ticking under `fps` leaves slots empty. `"frame"` stamps every
rendered frame one fixed slot after the last, so a timeline whose
own clock advances a step per rendered frame — a cutscene, a
scripted demo, anything on a fixed timestep — is delivered at the
length that timeline runs to, however slowly the engine drew it: a
take of `frames = n` at `fps` is `n / fps` seconds of film, and a
`max_duration_sec` bound counts that film's seconds. A `"frame"`
take records silent, because the master mix plays in wall-clock
seconds and cannot share a file with a fixed-step picture;
`recordingAudio` says so, and an explicit `audio = true` beside it
is refused. Record the sound as a second `"realtime"` take.
`camera` names the camera the take draws its film from — an entity
proxy, an entity id, or an entity name. That camera holds the viewport
for as long as the take runs, above the priority contest and above
`camera.setEditorOverride`, so the film is its view and the frames
carry everything the presented frame carries. Only frames that camera
drew go into the film, and a camera that never draws the viewport ends
the take with the reason on `av.status().recordingError` — so a take is
the view it named or it is no take. The camera belongs to the take:
nothing is written to it, and the viewport is back under its own
contest the moment the take ends. It reads back as
`av.status().recordingCamera` while the take runs. Omitted, the take
records whichever camera holds the viewport, which in an engine on the
editor profile is the editor's own fly camera rather than the scene's.
`renderLayers` is the render-layer include spec the viewport is
drawn under for as long as the take runs — the same token string a
capture takes: `all` seeds every layer, `name` adds one and `!name`
drops one, so `"all !EditorUI !debug"` films the scene without the
editor's chrome or the authoring overlays (gizmos, light and probe
icons, frustums, collider wireframes) over it, and
`"all !ui !EditorUI !debug"` drops the authored HUD as well. The
viewport admits geometry and screens by that one spec, so it states
the whole picture. It belongs to the take: nothing is written to the
camera it is stated against, and the moment the take ends — its
bound reached, stopped, or refused — the viewport is back under the
camera's own spec. While a take states layers, the window shows what
the film holds, and `av.status().recordingLayers` reads the spec
back. Omitted, the take records the engine output as presented.
Returns the destination path of a session that is open and
recording, or nil
and the reason it is not — an adapter that cannot encode, a take
already running, an option the encoder rejects, a resolution the
device refuses. The engine opens the session, so the call waits
for it: run it where it can yield, wrapping it in `task.spawn`
from a callback that cannot. How a take finished reads back as
`av.status().recordingEnd`; a refused request puts its reason
there and on `recordingError` and leaves no take report behind,
while a request refused because a take is already running leaves
that take's report as it is.

**Parameters**

- `path` `string` — VFS destination path.
- `opts` `RecordOpts` _(optional)_ — Encoder options (optional).

**Returns** `(string?, string?)` — Destination VFS path of the open recording, or nil. Why the recording was refused, when it was.

```lua
local clip = av.record("intro.mp4", { fps = 60 })
local film = av.record("cut.mp4", { fps = 24, frames = 24 * 181, cadence = "frame" })
local clean = av.record("take.mp4", { fps = 24, renderLayers = "all !EditorUI !debug" })
local shot = av.record("film.mp4", { fps = 24, frames = 240, camera = "FilmCamera" })
```

## typed/builtin//modules/api/engine/av/av/status {#typed-builtin-modules-api-engine-av-av-status}

```lua
av.status() -> AvStatus
```

Report the encoder subsystem's state. Always available
regardless of GPU support. `backend` is the encode backend in use
— `"vulkan"` or `"vaapi"` on an adapter with a media engine,
`"software"` where encode runs on the CPU — and `hardware` is true
for the first two, so a caller that pays for the take in engine
time knows which it is getting. `codecs` lists what the backend
encodes with the recording default first. `live` is true while the
`av.live` stream is running. A take of its own reads back on the
recording fields: `recording` is the destination of the take in
flight, `recordingBound` what will end it, `recordingEnd` how the
most recent one ended, and `recordingError` why one produced no
file. `recordingAudio` is the codec the take is writing the master
mix with (`"opus"`), or the reason the file carries no audio track
— read it to tell a film with a soundtrack from a silent one.
`recordingLayers` is the render-layer include spec the armed take is
drawing the viewport under, in the words its caller wrote, and nil for
a take that stated none — the reading that answers what is in the
picture rather than how much of it there is. `recordingCamera` is the
entity id of the camera the take's most recent captured frame was drawn
from, and stands as the source of the most recent take once that take
has ended — it is read off the frame the engine drew, so it answers
which view a film holds whether or not the take named a camera.
`recordingCadence` is the clock the take stamps its frames from,
`"realtime"` or `"frame"`, and so what the tally below is a reading
against. What the take produced reads off `recordingFrames`,
`recordingBytes` (every byte the take has produced so far, climbing
while it runs and ending equal to the size of the file),
`recordingSeconds` (the timeline those frames cover),
`recordingAchievedFps` (the rate they arrived at) and
`recordingRequestedFps` (the rate asked for) — live while a take
runs, and its final tally once it ends. On `"realtime"` the
requested rate is a ceiling and an engine ticking under it reaches
less; on `"frame"` every rendered frame is a slot of the recorded
timeline, so `recordingSeconds` is that timeline's length and
`recordingAchievedFps` is the rate it plays back at.

**Returns** `AvStatus` — Encoder status table.

```lua
local s = av.status(); print(s.backend, s.hardware, s.recordingAudio)
```

## typed/builtin//modules/api/engine/av/av/stop_live {#typed-builtin-modules-api-engine-av-av-stop-live}

```lua
av.stop_live() -> boolean
```

Stop any active live-stream session.

**Returns** `boolean` — True if a session was stopped, false if none was active.

```lua
av.stop_live()
```

## typed/builtin//modules/api/engine/av/av/stop_recording {#typed-builtin-modules-api-engine-av-av-stop-recording}

```lua
av.stop_recording(handle: string?) -> (boolean, string?)
```

Stop the active recording (or the one for the given promise
handle). Returns true when a recording was armed at call time. A
false return carries a second value naming how the most recent
recording already ended — the bound it reached, or the failure
that cut it short — and nil when no recording has run at all. The
engine finalizes the take on its next tick: wait for
`av.is_recording()` to go false, then read what it produced off
`av.status()`.

**Parameters**

- `handle` `string` _(optional)_ — Promise handle of a specific recording (optional).

**Returns** `(boolean, string?)` — True if a recording was stopped. How the most recent recording ended, when nothing was armed.

```lua
local stopped, ended = av.stop_recording()
```

## typed/builtin//modules/api/engine/base64/base64/decode {#typed-builtin-modules-api-engine-base64-base64-decode}

```lua
base64.decode(text: string) -> (string?, string?)
```

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

**Parameters**

- `text` `string` — Base64 text to decode.

**Returns** `(string?, string?)` decoded bytes on success, or (nil, errmsg).

```lua
local bytes = base64.decode(text)
```

## typed/builtin//modules/api/engine/base64/base64/encode {#typed-builtin-modules-api-engine-base64-base64-encode}

```lua
base64.encode(bytes: buffer | string) -> string
```

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

**Parameters**

- `bytes` `buffer | string` — Binary bytes to encode.

**Returns** `string` — Base64 text.

```lua
local text = base64.encode(jpegBytes)
```

## typed/builtin//modules/api/engine/blend/blend/destroyLayout {#typed-builtin-modules-api-engine-blend-blend-destroylayout}

```lua
blend.destroyLayout(handle: number) -> boolean
```

Drop the layout from the registry.

**Parameters**

- `handle` `number` — Layout handle.

**Returns** `boolean` — True if the layout existed and was removed.

## typed/builtin//modules/api/engine/blend/blend/layout {#typed-builtin-modules-api-engine-blend-blend-layout}

```lua
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.

**Parameters**

- `slots` `{ BlendSlot }` — Array of slot tables.
- `totalStride` `number` _(optional)_ — Optional explicit record stride.

**Returns** `number?` — Layout handle, or nil.

```lua
local l = blend.layout({ { offset = 0, stride = 3, op = "lerp" } })
```

## typed/builtin//modules/api/engine/blend/blend/lerpInto {#typed-builtin-modules-api-engine-blend-blend-lerpinto}

```lua
blend.lerpInto(outBuffer: Substrate.TypedBuffer, layout: number, aBuffer: Substrate.TypedBuffer, bBuffer: Substrate.TypedBuffer, 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.

**Parameters**

- `outBuffer` `Substrate.TypedBuffer` — The buffer written into.
- `layout` `number` — Layout handle.
- `aBuffer` `Substrate.TypedBuffer` — The A side of the fade.
- `bBuffer` `Substrate.TypedBuffer` — The B side of the fade.
- `t` `number` — Crossfade weight on B (0..1).

**Returns** `boolean` — True on success.

## typed/builtin//modules/api/engine/blend/blend/weightedInto {#typed-builtin-modules-api-engine-blend-blend-weightedinto}

```lua
blend.weightedInto(outBuffer: Substrate.TypedBuffer, 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.

**Parameters**

- `outBuffer` `Substrate.TypedBuffer` — The buffer written into.
- `layout` `number` — Layout handle.
- `inputs` `{ BlendInput }` — Array of `{ buffer, weight }`.

**Returns** `boolean` — True on success.

## typed/builtin//modules/api/engine/camera/camera/active {#typed-builtin-modules-api-engine-camera-camera-active}

```lua
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.

**Returns** `string?` — Entity id of the on-screen camera, or nil if none is active — including the frame after that camera's entity is despawned.

```lua
local camId = camera.active()
```

## typed/builtin//modules/api/engine/camera/camera/cut {#typed-builtin-modules-api-engine-camera-camera-cut}

```lua
camera.cut()
```

Declare that the camera on screen cuts: the next frame it draws stands
somewhere it did not travel to. Motion vectors are the difference between
where a surface projects now and where it projected on the camera's
previous frame, and everything temporal reads that difference — the shutter
reconstructs the frame by walking it, a temporal resolve reprojects its
history along it. Across a cut that difference describes a displacement no
surface made, so the frame is reconstructed from taps a whole screen away
and belongs to neither shot. A declared cut leaves the camera with no
previous frame for exactly one frame, which is the state its very first
frame is already in, so every consumer reads zero motion across the cut.
Declare it in the same step that places the camera at the new station;
declaring it again before that frame draws still costs the one frame.
Handing the viewport from one camera to another is already a cut without
being declared one: the incoming camera stands where it always stood, and
the engine performs the handover, so it is what states it.

```lua
camera.cut(); entity(camId).position = { 40, 6, -12 }
```

## typed/builtin//modules/api/engine/camera/camera/editor {#typed-builtin-modules-api-engine-camera-camera-editor}

```lua
camera.editor() -> string?
```

Entity id of the editor fly-camera (the EditorOnly authoring camera), or
nil if the scene has none. This is the camera the editor viewport renders
through, so it is the one a `capture` of the screen sees. Its pose is its
entity transform: assign `entity(id).position` to move it and aim it with
the camera toolbox's `lookAt`, which makes a screen capture repeatable
instead of whatever pose the instance booted with.

**Returns** `string?` — Entity id of the editor camera, or nil.

```lua
local camId = camera.editor()
local id = camera.editor(); entity(id).position = { 12, 8, 12 }; tools.use("camera", "lookAt", id, { 0, 0, 0 })
```

## typed/builtin//modules/api/engine/camera/camera/editorOverride {#typed-builtin-modules-api-engine-camera-camera-editoroverride}

```lua
camera.editorOverride() -> string?
```

Entity id currently overriding viewport selection, or nil when the
viewport is decided by highest-priority-wins.

**Returns** `string?` — Entity id of the overriding camera, or nil.

```lua
local owner = camera.editorOverride()
```

## typed/builtin//modules/api/engine/camera/camera/get {#typed-builtin-modules-api-engine-camera-camera-get}

```lua
camera.get(target: (string | EntityRef)) -> CameraReport?
```

One camera's report from the observation — the same record
`camera.list` yields, for the camera the caller names. Takes an entity id,
an entity name, or an entity proxy, the same way the camera tools do.

## typed/builtin//modules/api/engine/camera/camera/list {#typed-builtin-modules-api-engine-camera-camera-list}

```lua
camera.list() -> { CameraReport }
```

Every camera in the world as a compact row each, ordered the way the
renderer resolves the on-screen camera: highest priority first. Reads the
same observation `camera.observe` does, so a row can never disagree with
the full report about whether a camera is `enabled` or which one drew.

**Returns** `{ CameraReport }` — One row per camera entity, or an empty list before the first frame.

```lua
for _, c in ipairs(camera.list()) do print(c.name, c.enabled, c.rendering) end
```

## typed/builtin//modules/api/engine/camera/camera/main {#typed-builtin-modules-api-engine-camera-camera-main}

```lua
camera.main() -> string?
```

Entity id of the main scene camera — the scene camera the viewport is
drawn from, and while the editor fly-camera holds the screen, the scene
camera that would take it. 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. It comes off the same
selection the frame does, so writing a pose to it moves what is drawn
whenever a scene camera is on screen. The scene camera with the highest
authored `priority` takes it; cameras tied on priority settle on the order
the frame visits them, so a scene that needs a specific camera — a
prototype and the clone play makes of it both stand at 0 — states a
distinct priority rather than resting on that order. For the camera drawn
on screen whichever partition owns it, use `camera.active()`.

**Returns** `string?` — Entity id of the main scene camera, or nil — including the frame after that camera's entity is despawned, before the scene elects another.

```lua
local camId = camera.main(); local cam = camId and entity(camId)
```

## typed/builtin//modules/api/engine/camera/camera/motionTally {#typed-builtin-modules-api-engine-camera-camera-motiontally}

```lua
camera.motionTally() -> { frames: number, withoutHistory: number }
```

Frames the camera on screen has drawn, and how many of them had no
previous frame to difference their motion vectors against — its first
frame, every declared cut, and every frame the viewport changes hands on.
Both counts are monotonic across the session, so two readings either side
of a run say what happened in between.

**Returns** `{ frames: number, withoutHistory: number }` — `{ frames, withoutHistory }`.

```lua
local before = camera.motionTally().withoutHistory
```

## typed/builtin//modules/api/engine/camera/camera/observe {#typed-builtin-modules-api-engine-camera-camera-observe}

```lua
camera.observe() -> CameraObservation?
```

Every camera in the world, for the frame that has just been drawn.
Answers "why is this camera not showing what I expect" in one call:
`rendering` says whether each camera drew and `reason` names the single
cause when it did not — `"disabled"`, `"entityInactive"`, `"targetMissing"`,
`"noLayers"`, `"outranked"`, `"notDrawn"`. Each camera carries both
projections: `authored` is what the Camera component holds and `frame` is
what the renderer actually built, with `mismatch` naming every field the
two disagree on — so a clip range or a lens the frame did not use is one
field read. `frame`, `viewProj`, `frustum` and the `cost` numbers describe
a camera that drew; every cost is for that one frame.
One snapshot is published per drawn frame, from after the frame is drawn,
so a read describes the last frame rather than the world at the instant of
the call — a write and a read in one script step return the frame that ran
before the write. Put a `task.wait()` between them to compare a camera
either side of a change; `frame` counts the frames observed, so a poll can
wait for it to advance.

**Returns** `CameraObservation?` — The observation, or nil before the first frame has been drawn.

```lua
local obs = camera.observe(); for _, c in ipairs(obs.cameras) do print(c.name, c.rendering, c.reason) end
local dark = {}; for _, c in ipairs(camera.observe().cameras) do if not c.rendering then table.insert(dark, c.name .. ": " .. tostring(c.reason)) end end
```

## typed/builtin//modules/api/engine/camera/camera/setEditorOverride {#typed-builtin-modules-api-engine-camera-camera-seteditoroverride}

```lua
camera.setEditorOverride(entityId: string?)
```

Give one camera the viewport outright, or pass nil to clear it. While
set, that camera IS the on-screen camera and priority is never consulted,
so no authored priority can take the viewport from it — which is what makes
an authoring camera safe to fly over a scene holding a camera at any
priority. An override naming a camera that is despawned or disabled falls
back to highest-priority-wins rather than blanking the screen.

**Parameters**

- `entityId` `string` _(optional)_ — Entity id of the camera to route the viewport to, or nil to clear.

```lua
camera.setEditorOverride(camera.editor())
camera.setEditorOverride(nil)
```

## typed/builtin//modules/api/engine/camera/camera/viewData {#typed-builtin-modules-api-engine-camera-camera-viewdata}

```lua
camera.viewData(target: ((string | EntityRef)?)?) -> CameraView?
```

Camera render data. Called with no argument it is the active viewport
camera's data for this frame: world position, which projection it drew and
the field describing that frame, 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`.
Called with an entity id it is that camera's data, read from the frame's
camera observation, and carries the identity the bare form has no room for:
which camera it describes, which frame it was built for, what it rendered
into, and the render layers it resolved to.

**Parameters**

- `target` `((string | EntityRef)?)` _(optional)_ — Entity id, name, or proxy of the camera to read, or nil for the
viewport camera.

**Returns** `CameraView?` — The camera view data, or nil when that camera drew no frame.

```lua
local c = camera.viewData(); if c then print(c.position.x, c.fovY) end
local minimap = camera.viewData("minimapCam"); print(minimap.output.target, minimap.viewport.w)
```

## typed/builtin//modules/api/engine/channel/channel/create {#typed-builtin-modules-api-engine-channel-channel-create}

```lua
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.

**Parameters**

- `opts` `ChannelOpts` — `{ times, values, stride, interp }`.

**Returns** `number?` — Channel handle, or nil.

```lua
local h = channel.create({ times = ts, values = vs, stride = 3, interp = "linear" })
```

## typed/builtin//modules/api/engine/channel/channel/destroy {#typed-builtin-modules-api-engine-channel-channel-destroy}

```lua
channel.destroy(handle: number) -> boolean
```

Drop the channel from the registry.

**Parameters**

- `handle` `number` — Channel handle.

**Returns** `boolean` — True if the channel existed and was removed.

## typed/builtin//modules/api/engine/channel/channel/sampleInto {#typed-builtin-modules-api-engine-channel-channel-sampleinto}

```lua
channel.sampleInto(ch: number, time: number, buf: Substrate.TypedBuffer, offset: number) -> boolean
```

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

**Parameters**

- `ch` `number` — Channel handle.
- `time` `number` — Sample time in seconds.
- `buf` `Substrate.TypedBuffer` — The buffer written into.
- `offset` `number` — Starting f32 index in the buffer.

**Returns** `boolean` — True on success.

## typed/builtin//modules/api/engine/channel/channel/sampleManyInto {#typed-builtin-modules-api-engine-channel-channel-samplemanyinto}

```lua
channel.sampleManyInto(ch: number, time: number, buf: Substrate.TypedBuffer, 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.

**Parameters**

- `ch` `number` — Channel handle.
- `time` `number` — Sample time in seconds.
- `buf` `Substrate.TypedBuffer` — The buffer written into.
- `offsets` `{ number }` — Array of f32 indices.

**Returns** `boolean` — True on success.

## typed/builtin//modules/api/engine/channel/channel/sampleQuat {#typed-builtin-modules-api-engine-channel-channel-samplequat}

```lua
channel.sampleQuat(ch: number, time: number) -> (number?, number?, number?, number?)
```

Convenience accessor for stride-4 quaternion channels.

**Parameters**

- `ch` `number` — Channel handle.
- `time` `number` — Sample time.

**Returns** `(number?, number?, number?, number?)` — `(x, y, z, w)` or nil.

## typed/builtin//modules/api/engine/channel/channel/sampleVec3 {#typed-builtin-modules-api-engine-channel-channel-samplevec3}

```lua
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.

**Parameters**

- `ch` `number` — Channel handle.
- `time` `number` — Sample time.

**Returns** `(number?, number?, number?)` — `(x, y, z)` or nil.

```lua
local x, y, z = channel.sampleVec3(h, t)
```

## typed/builtin//modules/api/engine/color/color/coerce {#typed-builtin-modules-api-engine-color-color-coerce}

```lua
color.coerce(value: any?) -> Color?
```

Read a value written in any of the shapes a colour is authored
in — a hex string, an `{r=,g=,b=,a=}` map, or an `{r,g,b,a}` array
— as an sRGB color table. Returns `nil` when the value does not
describe a colour, so a caller can name the value it was handed
instead of substituting one. Channels absent from a map or array
read as 0; alpha absent reads as 1.

**Parameters**

- `value` `any` _(optional)_ — Value to read as a colour.

**Returns** `Color?` — sRGB color table, or `nil` when `value` is not a colour.

```lua
local c = color.coerce("#5a5a62") or color.coerce({ 0.2, 0.7, 0.2 })
```

## typed/builtin//modules/api/engine/color/color/complementary {#typed-builtin-modules-api-engine-color-color-complementary}

```lua
color.complementary(c: Color) -> Color
```

Complementary color — rotate hue 180° in Oklch space.

**Parameters**

- `c` `Color` — Input color.

**Returns** `Color` — Complementary sRGB color.

```lua
local accent = color.complementary(primary)
```

## typed/builtin//modules/api/engine/color/color/darken {#typed-builtin-modules-api-engine-color-color-darken}

```lua
color.darken(c: Color, amount: number) -> Color
```

Decrease the lightness of a color in Oklch perceptual space.

**Parameters**

- `c` `Color` — Input color.
- `amount` `number` — Lightness decrease 0-1.

**Returns** `Color` — Darkened sRGB color.

```lua
local pressed = color.darken(base, 0.1)
```

## typed/builtin//modules/api/engine/color/color/desaturate {#typed-builtin-modules-api-engine-color-color-desaturate}

```lua
color.desaturate(c: Color, amount: number) -> Color
```

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

**Parameters**

- `c` `Color` — Input color.
- `amount` `number` — Chroma decrease (typically 0-0.2).

**Returns** `Color` — Less saturated sRGB color.

```lua
local muted = color.desaturate(base, 0.05)
```

## typed/builtin//modules/api/engine/color/color/hex {#typed-builtin-modules-api-engine-color-color-hex}

```lua
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.

**Parameters**

- `hexString` `string` — Hex color string.

**Returns** `Color?` — sRGB color table or `nil`.

```lua
local fromCss = color.hex("#ff8800")
```

## typed/builtin//modules/api/engine/color/color/hsl {#typed-builtin-modules-api-engine-color-color-hsl}

```lua
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.

**Parameters**

- `h` `number` — Hue (degrees, 0-360).
- `s` `number` — Saturation (0-1).
- `l` `number` — Lightness (0-1).

**Returns** `Color` — sRGB color table `{ r, g, b, a = 1 }`.

```lua
local teal = color.hsl(180, 0.5, 0.5)
```

## typed/builtin//modules/api/engine/color/color/hsla {#typed-builtin-modules-api-engine-color-color-hsla}

```lua
color.hsla(h: number, s: number, l: number, a: number) -> Color
```

Build a color from HSLA, returned as sRGB.

**Parameters**

- `h` `number` — Hue (0-360).
- `s` `number` — Saturation (0-1).
- `l` `number` — Lightness (0-1).
- `a` `number` — Alpha (0-1).

**Returns** `Color` — sRGB color table `{ r, g, b, a }`.

```lua
local fadedTeal = color.hsla(180, 0.5, 0.5, 0.3)
```

## typed/builtin//modules/api/engine/color/color/hsv {#typed-builtin-modules-api-engine-color-color-hsv}

```lua
color.hsv(h: number, s: number, v: number) -> Color
```

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

**Parameters**

- `h` `number` — Hue (0-360).
- `s` `number` — Saturation (0-1).
- `v` `number` — Value / brightness (0-1).

**Returns** `Color` — sRGB color table `{ r, g, b, a = 1 }`.

```lua
local primary = color.hsv(220, 0.7, 0.9)
```

## typed/builtin//modules/api/engine/color/color/lighten {#typed-builtin-modules-api-engine-color-color-lighten}

```lua
color.lighten(c: Color, amount: number) -> Color
```

Increase the lightness of a color in Oklch perceptual space.

**Parameters**

- `c` `Color` — Input color.
- `amount` `number` — Lightness increase 0-1.

**Returns** `Color` — Lightened sRGB color.

```lua
local hover = color.lighten(base, 0.1)
```

## typed/builtin//modules/api/engine/color/color/linear {#typed-builtin-modules-api-engine-color-color-linear}

```lua
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.

**Parameters**

- `r` `number` — Linear red (0-1).
- `g` `number` — Linear green (0-1).
- `b` `number` — Linear blue (0-1).
- `a` `number` _(optional)_ — Alpha (0-1, default 1).

**Returns** `Color` — sRGB color table `{ r, g, b, a }`.

```lua
local gpuBlue = color.linear(0.0, 0.0, 1.0)
```

## typed/builtin//modules/api/engine/color/color/mix {#typed-builtin-modules-api-engine-color-color-mix}

```lua
color.mix(c1: Color, c2: Color, t: number) -> Color
```

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

**Parameters**

- `c1` `Color` — First color.
- `c2` `Color` — Second color.
- `t` `number` — Blend factor 0-1 (0 = c1, 1 = c2).

**Returns** `Color` — Blended sRGB color.

```lua
local mid = color.mix(color.rgb(255, 0, 0), color.rgb(0, 0, 255), 0.5)
```

## typed/builtin//modules/api/engine/color/color/mixRgb {#typed-builtin-modules-api-engine-color-color-mixrgb}

```lua
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.

**Parameters**

- `c1` `Color` — First color.
- `c2` `Color` — Second color.
- `t` `number` — Blend factor 0-1.

**Returns** `Color` — Blended sRGB color.

```lua
local plain = color.mixRgb(a, b, 0.5)
```

## typed/builtin//modules/api/engine/color/color/oklch {#typed-builtin-modules-api-engine-color-color-oklch}

```lua
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.

**Parameters**

- `l` `number` — Lightness (0-1).
- `c` `number` — Chroma / saturation (0-0.4).
- `h` `number` — Hue (0-360).

**Returns** `Color` — sRGB color table `{ r, g, b, a = 1 }`.

```lua
local accent = color.oklch(0.7, 0.15, 30)
```

## typed/builtin//modules/api/engine/color/color/rgb {#typed-builtin-modules-api-engine-color-color-rgb}

```lua
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.

**Parameters**

- `r` `number` — Red channel (0-255).
- `g` `number` — Green channel (0-255).
- `b` `number` — Blue channel (0-255).

**Returns** `Color` — sRGB color table `{ r, g, b, a = 1 }`, normalised to 0-1.

```lua
local red = color.rgb(255, 0, 0)
```

## typed/builtin//modules/api/engine/color/color/rgba {#typed-builtin-modules-api-engine-color-color-rgba}

```lua
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.

**Parameters**

- `r` `number` — Red channel (0-255).
- `g` `number` — Green channel (0-255).
- `b` `number` — Blue channel (0-255).
- `a` `number` — Alpha (0-1).

**Returns** `Color` — sRGB color table `{ r, g, b, a }`.

```lua
local halfRed = color.rgba(255, 0, 0, 0.5)
```

## typed/builtin//modules/api/engine/color/color/rotateHue {#typed-builtin-modules-api-engine-color-color-rotatehue}

```lua
color.rotateHue(c: Color, degrees: number) -> Color
```

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

**Parameters**

- `c` `Color` — Input color.
- `degrees` `number` — Hue rotation (positive or negative).

**Returns** `Color` — Hue-rotated sRGB color.

```lua
local triadic = color.rotateHue(base, 120)
```

## typed/builtin//modules/api/engine/color/color/saturate {#typed-builtin-modules-api-engine-color-color-saturate}

```lua
color.saturate(c: Color, amount: number) -> Color
```

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

**Parameters**

- `c` `Color` — Input color.
- `amount` `number` — Chroma increase (typically 0-0.2).

**Returns** `Color` — More saturated sRGB color.

```lua
local pop = color.saturate(base, 0.05)
```

## typed/builtin//modules/api/engine/color/color/toHex {#typed-builtin-modules-api-engine-color-color-tohex}

```lua
color.toHex(c: Color) -> string
```

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

**Parameters**

- `c` `Color` — Input color.

**Returns** `string` — Hex color string.

```lua
print(color.toHex(color.rgb(255, 136, 0))) -- "#ff8800"
```

## typed/builtin//modules/api/engine/color/color/toHsl {#typed-builtin-modules-api-engine-color-color-tohsl}

```lua
color.toHsl(c: Color) -> HslColor
```

Convert a color to HSL.

**Parameters**

- `c` `Color` — Input color.

**Returns** `HslColor` — HSL color table `{ h, s, l, a }` (h: 0-360, s/l: 0-1).

```lua
local hsl = color.toHsl(base)
```

## typed/builtin//modules/api/engine/color/color/toLinear {#typed-builtin-modules-api-engine-color-color-tolinear}

```lua
color.toLinear(c: Color) -> Color
```

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

**Parameters**

- `c` `Color` — Input sRGB color.

**Returns** `Color` — Linear RGB color table.

```lua
local gpu = color.toLinear(base)
```

## typed/builtin//modules/api/engine/color/color/toOklch {#typed-builtin-modules-api-engine-color-color-tooklch}

```lua
color.toOklch(c: Color) -> OklchColor
```

Convert a color to Oklch perceptual color space.

**Parameters**

- `c` `Color` — Input color.

**Returns** `OklchColor` — Oklch color table `{ l, c, h, a }` (l: 0-1, c: 0-0.4, h: 0-360).

```lua
local okl = color.toOklch(base)
```

## typed/builtin//modules/api/engine/color/color/withAlpha {#typed-builtin-modules-api-engine-color-color-withalpha}

```lua
color.withAlpha(c: Color, a: number) -> Color
```

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

**Parameters**

- `c` `Color` — Input color.
- `a` `number` — New alpha (0-1).

**Returns** Color with modified alpha.

```lua
local ghost = color.withAlpha(base, 0.3)
```

## typed/builtin//modules/api/engine/compute/compute/absentReasons {#typed-builtin-modules-api-engine-compute-compute-absentreasons}

```lua
compute.absentReasons() -> { string }
```

Every reason `compute.diagnose` reports, sorted. `resident` is the one
that means the resource is there.

**Returns** `{ string }` — The closed set, as strings.

```lua
for _, r in ipairs(compute.absentReasons()) do print(r) end
```

## typed/builtin//modules/api/engine/compute/compute/beginBvh {#typed-builtin-modules-api-engine-compute-compute-beginbvh}

```lua
compute.beginBvh(instances: { any }, opts: { [string]: any }?) -> (number?, string?)
```

Start the build `compute.buildBvh` runs, without running any of it.
Takes the same instances and options and reports the same non-resident
guids, and returns an id `compute.stepBvh` advances a bounded slice at a
time and `compute.finishBvh` collects. Each mesh the instances name is
copied as this is called — once per guid however many instances share it
— so the CPU mesh may be unloaded on the next line and the build still
finishes on the copy it holds. `compute.buildBvhSliced` is the whole loop
as one call.

**Parameters**

- `instances` `{ any }` — Array of `{ guid, transform, attributes? }` mesh instances.
- `opts` `{ [string]: any }` _(optional)_ — Optional `{ maxLeaf? }` — max triangles per leaf.

**Returns** `(number?, string?)` — The build id, or `(nil, err)` naming any non-resident guid.

```lua
local id = compute.beginBvh(gather.instances)
```

## typed/builtin//modules/api/engine/compute/compute/buildBvh {#typed-builtin-modules-api-engine-compute-compute-buildbvh}

```lua
compute.buildBvh(instances: { any }, opts: { [string]: any }?) -> (any, string?)
```

Build a bounding-volume hierarchy over the world-space triangles of a
set of mesh instances and upload it as two named compute buffers —
geometry never passes through the scripting heap. Each instance is
`{ guid, transform, attributes? }`: `guid` names a mesh resident in the
meshcpu store (materialise with `ref:load()` / `meshcpu.load`),
`transform` is 16 numbers, row-major, translation in slots 4/8/12, and
`attributes` is up to 40 floats stamped onto every triangle of that
instance (surface colors, material ids, physics tags — whatever the
consuming shader wants per-surface). Triangles pack 18 vec4 each
(v0/v1/v2, n0/n1/n2, uvs, then 10 attribute vec4s — float slots 32..
carry the instance attributes, zero when absent) in BVH leaf order;
nodes 2 vec4 each (min + first-or-left, max + leaf-tagged
count-or-right). Consumers: GI baking, ray-traced passes, GPU picking,
navmesh and SDF generation.

**Parameters**

- `instances` `{ any }` — Array of `{ guid, transform, attributes? }` mesh instances.
- `opts` `{ [string]: any }` _(optional)_ — Optional `{ maxLeaf? }` — max triangles per leaf.

**Returns** `(any, string?)` — `{ nodes, tris, nodeCount, triCount }` — `nodes` and `tris` are buffer handles the caller owns, passed to a dispatch like any other and destroyed when the hierarchy is done with. Or `(nil, err)` naming any non-resident guid.

```lua
local bvh = compute.buildBvh(instances)
shader:dispatch({ buffers = { bvh.nodes, bvh.tris }, workgroups = { 64, 1, 1 } })
```

## typed/builtin//modules/api/engine/compute/compute/buildBvhSliced {#typed-builtin-modules-api-engine-compute-compute-buildbvhsliced}

```lua
compute.buildBvhSliced(instances: { any }, opts: { [string]: any }?) -> (any, string?)
```

The hierarchy `compute.buildBvh` builds, spread over as many frames as
it takes: a slice of the build per frame, so a scene's triangle count
costs the frame loop `budgetMs` at a time instead of the whole build at
once. Yields, so it is called from a task. The result is the same pair of
buffers and the same counts `compute.buildBvh` returns.

**Parameters**

- `instances` `{ any }` — Array of `{ guid, transform, attributes? }` mesh instances.
- `opts` `{ [string]: any }` _(optional)_ — Optional `{ maxLeaf?, budgetMs? }` — max triangles per leaf, and
the wall time one frame may spend on the build (default 4 ms).

**Returns** `(any, string?)` — `{ nodes, tris, nodeCount, triCount }`, or `(nil, err)`.

```lua
local built, err = compute.buildBvhSliced(gather.instances, { budgetMs = 4 })
```

## typed/builtin//modules/api/engine/compute/compute/bvhBuilds {#typed-builtin-modules-api-engine-compute-compute-bvhbuilds}

```lua
compute.bvhBuilds() -> { any }
```

What the builds started by `compute.beginBvh` and not yet finished are
costing, oldest id first. Each row is `{ id, phase, triangles, units,
slices, cpuMs, uploadedBytes }`: `phase` is `"gather"`, `"build"`,
`"serialize"`, `"upload"` or `"ready"`, `triangles` how many have been
gathered, `units` the work units run, `slices` the `compute.stepBvh`
calls they ran in, `cpuMs` the wall time spent inside those calls, and
`uploadedBytes` how much of the hierarchy has reached the GPU.

**Returns** `{ any }` — Array of build rows.

```lua
print(#compute.bvhBuilds(), "hierarchies in flight")
```

## typed/builtin//modules/api/engine/compute/compute/cancelBvh {#typed-builtin-modules-api-engine-compute-compute-cancelbvh}

```lua
compute.cancelBvh(id: number) -> boolean
```

Drop a build along with the triangles it has gathered.

**Parameters**

- `id` `number` — Build id from `compute.beginBvh`.

**Returns** `boolean` — True when the id named a build.

```lua
compute.cancelBvh(id)
```

## typed/builtin//modules/api/engine/compute/compute/compile {#typed-builtin-modules-api-engine-compute-compute-compile}

```lua
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.

**Parameters**

- `nameOrHandle` `string | { [string]: any } | AssetRef` — Shader identity to register under (string or asset handle).
- `opts` `{ [string]: any }` _(optional)_ — `{ source, entryPoint?, bindings, params? }` — `bindings` is an
ordered list of `{ name, kind, access?, element?, format?, array? }`.

**Returns** `boolean` — True on success.

```lua
compute.compile("my_sim", { source = WGSL, bindings = { { name = "data", kind = "buffer", access = "read_write", element = "f32" } } })
```

## typed/builtin//modules/api/engine/compute/compute/compileByName {#typed-builtin-modules-api-engine-compute-compute-compilebyname}

```lua
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).

**Parameters**

- `ref` `string | { [string]: any } | AssetRef` — A `.computeShader` identity/guid string, or a resolved asset handle.

```lua
compute.compileByName("@builtin::shaders.compute_double")
```

## typed/builtin//modules/api/engine/compute/compute/copyBufferToTexture {#typed-builtin-modules-api-engine-compute-compute-copybuffertotexture}

```lua
compute.copyBufferToTexture(bufferName: string, textureKey: string, width: number, height: number, format: string?) -> boolean
```

Copy a compute buffer into a cached GPU texture under
`textureKey`, staying on the GPU. The path for an image a compute
pass produced: the buffer holds tightly-packed rows in the format's
texel layout, and the result is an ordinary cached texture — sample
it from a material, or pack it into the shared feature-texture array.
Rows must be a multiple of 256 bytes (at `rgba16f`, any width from 32
up in powers of two).

**Parameters**

- `bufferName` `string` — Source compute buffer.
- `textureKey` `string` — Cache key to register the texture under.
- `width` `number` — Texture width in texels.
- `height` `number` — Texture height in texels.
- `format` `string` _(optional)_ — Texel format: `"rgba16f"` (default), `"rgba32f"`, `"rgba8"`.

**Returns** `boolean` — True when the copy was queued.

```lua
compute.copyBufferToTexture("gi_resolved", "lm_wall", 128, 128)
```

## typed/builtin//modules/api/engine/compute/compute/createBuffer {#typed-builtin-modules-api-engine-compute-compute-createbuffer}

```lua
compute.createBuffer(name: string, opts: { [string]: any }) -> boolean
```

Allocate a buffer under `name`, sized in bytes.

**Parameters**

- `name` `string` — The name a dispatch binds it by.
- `opts` `{ [string]: any }` — `{ size, readback? }` — `size` in bytes.

**Returns** `boolean` — True once allocated.

## typed/builtin//modules/api/engine/compute/compute/createSampler {#typed-builtin-modules-api-engine-compute-compute-createsampler}

```lua
compute.createSampler(name: string, opts: { [string]: any }?) -> boolean
```

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

**Parameters**

- `name` `string`
- `opts` `{ [string]: any }` _(optional)_

**Returns** `boolean`

## typed/builtin//modules/api/engine/compute/compute/createStorageTexture2D {#typed-builtin-modules-api-engine-compute-compute-createstoragetexture2d}

```lua
compute.createStorageTexture2D(name: string, opts: { [string]: any }) -> boolean
```

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

**Parameters**

- `name` `string`
- `opts` `{ [string]: any }`

**Returns** `boolean`

## typed/builtin//modules/api/engine/compute/compute/createTexture3D {#typed-builtin-modules-api-engine-compute-compute-createtexture3d}

```lua
compute.createTexture3D(name: string, opts: { [string]: any }) -> boolean
```

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

**Parameters**

- `name` `string` — Unique volume name.
- `opts` `{ [string]: any }` — Dimensions + format (`r8`/`r16f`/`r32f`/`rgba8`/`rgba16f`/`rgba32f`).

**Returns** `boolean` — True on success (mutation queued).

## typed/builtin//modules/api/engine/compute/compute/createTextureHistory {#typed-builtin-modules-api-engine-compute-compute-createtexturehistory}

```lua
compute.createTextureHistory(name: string, opts: { [string]: any }) -> boolean
```

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

**Parameters**

- `name` `string`
- `opts` `{ [string]: any }`

**Returns** `boolean`

## typed/builtin//modules/api/engine/compute/compute/destroyBuffer {#typed-builtin-modules-api-engine-compute-compute-destroybuffer}

```lua
compute.destroyBuffer(name: string) -> boolean
```

Release the buffer allocated under `name`.

**Parameters**

- `name` `string` — The name it was created under.

**Returns** `boolean` — True if a buffer under that name was released.

## typed/builtin//modules/api/engine/compute/compute/destroySampler {#typed-builtin-modules-api-engine-compute-compute-destroysampler}

```lua
compute.destroySampler(name: string) -> boolean
```

Release a named sampler created by `compute.createSampler` and free
it. The counterpart to that call, alongside `destroyBuffer`,
`destroyTexture`, `destroyTexture3D`, `destroyStorageTexture2D` and
`destroyTextureHistory`. The manager's own defaults (`linear_clamp`,
`linear_repeat`, `nearest_clamp`) are kept for the session, since a
compute pass binds them by name.

**Parameters**

- `name` `string` — Sampler name.

**Returns** `boolean` — True when the release was queued.

```lua
compute.createSampler("soft", { filter = true }); compute.destroySampler("soft")
```

## typed/builtin//modules/api/engine/compute/compute/destroyShader {#typed-builtin-modules-api-engine-compute-compute-destroyshader}

```lua
compute.destroyShader(name: string) -> boolean
```

Destroy a named compute shader pipeline.

**Parameters**

- `name` `string` — Shader name.

**Returns** `boolean` — True on success.

## typed/builtin//modules/api/engine/compute/compute/destroyShaderEx {#typed-builtin-modules-api-engine-compute-compute-destroyshaderex}

```lua
compute.destroyShaderEx(name: string) -> boolean
```

Destroy a shader registered via `registerShaderEx`.

**Parameters**

- `name` `string`

**Returns** `boolean`

## typed/builtin//modules/api/engine/compute/compute/destroyStorageTexture2D {#typed-builtin-modules-api-engine-compute-compute-destroystoragetexture2d}

```lua
compute.destroyStorageTexture2D(name: string) -> boolean
```

Destroy a named 2D storage texture.

**Parameters**

- `name` `string`

**Returns** `boolean`

## typed/builtin//modules/api/engine/compute/compute/destroyTexture {#typed-builtin-modules-api-engine-compute-compute-destroytexture}

```lua
compute.destroyTexture(textureKey: string) -> boolean
```

Release the cached GPU texture `copyBufferToTexture` registered
under `textureKey`, freeing its memory. Call it once the image is no
longer sampled. Writing the same key again replaces the texture, so a
key you keep re-using holds one allocation.

**Parameters**

- `textureKey` `string` — Cache key the texture was registered under.

**Returns** `boolean` — True when the release was queued.

```lua
compute.destroyTexture("lm_wall")
```

## typed/builtin//modules/api/engine/compute/compute/destroyTexture3D {#typed-builtin-modules-api-engine-compute-compute-destroytexture3d}

```lua
compute.destroyTexture3D(name: string) -> boolean
```

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

**Parameters**

- `name` `string`

**Returns** `boolean`

## typed/builtin//modules/api/engine/compute/compute/destroyTextureHistory {#typed-builtin-modules-api-engine-compute-compute-destroytexturehistory}

```lua
compute.destroyTextureHistory(name: string) -> boolean
```

Destroy a named texture-history buffer.

**Parameters**

- `name` `string`

**Returns** `boolean`

## typed/builtin//modules/api/engine/compute/compute/diagnose {#typed-builtin-modules-api-engine-compute-compute-diagnose}

```lua
compute.diagnose(key: string) -> { [string]: any }
```

Whether a resource is filed under `key` right now, and when none is,
which state the inventory says the key is in. A key out of a dispatch
failure resolves here; a mistyped one reports why it does not.

**Parameters**

- `key` `string` — The resource key, verbatim.

**Returns** `{ [string]: any }` — `{ key, exists, reason, resource?, current? }`. `resource` is the row when one is filed under the key. `reason` is one of `compute.absentReasons()`. `current` names the live key when the owner holds a resource under the same name at a different serial.

```lua
local d = compute.diagnose(key)
if not d.exists then print(d.reason, d.current) end
```

## typed/builtin//modules/api/engine/compute/compute/dispatch {#typed-builtin-modules-api-engine-compute-compute-dispatch}

```lua
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()`.

**Parameters**

- `shaderNameOrHandle` `string | { [string]: any } | AssetRef` — Shader name or asset handle.
- `opts` `DispatchOpts` — `{ buffers, workgroups }`.
A zero in any workgroup dimension is refused and recorded as a dispatch
failure — clamp a computed count with `math.max(1, math.ceil(n / 64))`.

**Returns** `boolean` — True once the dispatch is queued. What the engine then did with it is in `compute.failing()`.

```lua
compute.dispatch("blur", { buffers = { "src", "dst" }, workgroups = { 8, 8 } })
```

## typed/builtin//modules/api/engine/compute/compute/dispatchEx {#typed-builtin-modules-api-engine-compute-compute-dispatchex}

```lua
compute.dispatchEx(shaderNameOrHandle: string | { [string]: any } | AssetRef, opts: { [string]: any }) -> boolean
```

Dispatch a compute shader with extended texture/storage/sampler bindings.
Asset-backed `.computeShader`s resolve to their stable guid (collision-safe,
lazily compiled on first dispatch); raw `registerShaderEx` names pass through.
`resources` covers the bindings the shader DECLARES. A `params:` block's
uniform is engine-owned — the compile creates and packs it, `setParam`
writes it, and the dispatch binds it — so it takes no entry here.

**Parameters**

- `shaderNameOrHandle` `string | { [string]: any } | AssetRef` — Shader name or asset handle.
- `opts` `{ [string]: any }` — `{ resources, workgroups }` — each resource is `{ kind, name }`.
A zero in any workgroup dimension is refused and recorded as a dispatch
failure — clamp a computed count with `math.max(1, math.ceil(n / 64))`.

**Returns** `boolean` — True once the dispatch is queued. What the engine then did with it is in `compute.failing()`.

## typed/builtin//modules/api/engine/compute/compute/dispatchOnVertices {#typed-builtin-modules-api-engine-compute-compute-dispatchonvertices}

```lua
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. Asset-backed `.computeShader`s resolve to their stable guid
(collision-safe, lazily compiled on first dispatch); raw
`registerShader` names pass through.

**Parameters**

- `shaderNameOrHandle` `string | { [string]: any } | AssetRef` — Shader name or asset handle.
- `opts` `DispatchOnVerticesOpts` — `{ model, buffers?, workgroups }`.
A zero in any workgroup dimension is refused and recorded as a dispatch
failure — clamp a computed count with `math.max(1, math.ceil(n / 64))`.

**Returns** `boolean` — True once the dispatch is queued. What the engine then did with it is in `compute.failing()`.

```lua
compute.dispatchOnVertices("flatten", { model = "@user/mesh", workgroups = { 64 } })
```

## typed/builtin//modules/api/engine/compute/compute/failing {#typed-builtin-modules-api-engine-compute-compute-failing}

```lua
compute.failing() -> { { [string]: any } }
```

Every compute dispatch whose most recent run FAILED, one record per
`(shader, target)` pair. A dispatch is recorded into a command encoder
frames after the call that asked for it returned, so a pass that stops
running reports here rather than through that call's return value: each
record carries the shader key, the target it writes (a mesh guid for a
dispatch over vertices, the buffers it bound for one that writes only
those), how
many dispatches and failures it has had, and `lastError`. An empty result
means every dispatch the engine has been given is running.

**Returns** `{ { [string]: any } }` — Array of `{ shader, target, dispatches, failures, ok, lastFrame, lastFailedFrame?, lastError? }`.

```lua
for _, d in ipairs(compute.failing()) do print(d.shader, d.lastError) end
```

## typed/builtin//modules/api/engine/compute/compute/finishBvh {#typed-builtin-modules-api-engine-compute-compute-finishbvh}

```lua
compute.finishBvh(id: number) -> (any, string?)
```

Hand over a finished build's hierarchy as the same two buffers
`compute.buildBvh` returns, and release the build. The slices put every
byte of it on the GPU as they ran, so this costs the frame it is called
in the handover and nothing of the scene.

**Parameters**

- `id` `number` — Build id from `compute.beginBvh`, stepped until `"ready"`.

**Returns** `(any, string?)` — `{ nodes, tris, nodeCount, triCount }`, or `(nil, err)` when the id names no build or the build still has work left.

```lua
local built = compute.finishBvh(id)
```

## typed/builtin//modules/api/engine/compute/compute/getReadbackResult {#typed-builtin-modules-api-engine-compute-compute-getreadbackresult}

```lua
compute.getReadbackResult(resultKey: string) -> { number }?
```

Poll for a completed read-back and return its bytes as a
1-indexed array of f32 values, nil if pending. The f32
reinterpretation applies to whatever the buffer holds: bytes
written as u32 `1, 2, 3, 4` read back here as `1.4e-45, 2.8e-45,
4.2e-45, 5.6e-45` — use `getReadbackResultU32()` for those, or
`getReadbackResultBytes()` for a `buffer` the rest of the buffer
surface accepts. Result is consumed on retrieval, and polling a key
that was never issued raises rather than reading as forever-pending.

**Parameters**

- `resultKey` `string` — Key returned by `readBuffer()`.

**Returns** `{ number }?` — 1-indexed array of f32 values, or nil if not ready.

```lua
local floats = compute.getReadbackResult(key)
```

## typed/builtin//modules/api/engine/compute/compute/getReadbackResultBytes {#typed-builtin-modules-api-engine-compute-compute-getreadbackresultbytes}

```lua
compute.getReadbackResultBytes(resultKey: string) -> buffer?
```

Poll for a completed read-back and get its raw bytes as a
`buffer`, copied once. The read counterpart of `writeBufferBytes`:
read values out with `buffer.readf32` / `buffer.readu32`, or hand the
buffer straight to `writeBuffer` — a payload that stays packed never
becomes a table. Result is consumed on retrieval.

**Parameters**

- `resultKey` `string` — Key returned by `readBuffer()`.

**Returns** `buffer?` — The read-back's bytes, or nil if not ready.

```lua
local bytes = compute.getReadbackResultBytes(key)
local firstTexel = buffer.readf32(bytes, 0)
```

## typed/builtin//modules/api/engine/compute/compute/getReadbackResultU32 {#typed-builtin-modules-api-engine-compute-compute-getreadbackresultu32}

```lua
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.

**Parameters**

- `resultKey` `string` — Key returned by `readBuffer()`.

**Returns** `{ number }?` — Array of u32 values, or nil if not ready.

## typed/builtin//modules/api/engine/compute/compute/isReadbackReady {#typed-builtin-modules-api-engine-compute-compute-isreadbackready}

```lua
compute.isReadbackReady(resultKey: string) -> boolean
```

Check if a readback result is available without consuming it.
Raises for a key this engine never issued, or whose result was already
drained — `nil`/`false` already means "still in flight", so a mistyped
key reports itself instead of polling forever. Use `readbackState()`
to test that case without raising.

**Parameters**

- `resultKey` `string` — Key returned by `readBuffer()`.

**Returns** `boolean` — True if the result is ready.

## typed/builtin//modules/api/engine/compute/compute/observe {#typed-builtin-modules-api-engine-compute-compute-observe}

```lua
compute.observe() -> { [string]: any }
```

Every GPU resource the compute subsystem is holding right now — its
storage and uniform buffers, its 3D textures, its 2D storage targets, its
history pairs and its samplers — with what each one costs and which shader
asked for it. This is the call to reach for when compute is holding memory
and you do not know what, or when a key out of a dispatch failure needs
matching against what exists.

**Returns** `{ [string]: any }` — `{ published, generation, resources, totals }`. Each row of `resources` carries `key`, `kind` (`buffer` / `uniformBuffer` / `texture3d` / `storageTexture2d` / `textureHistory` / `sampler`), `owner` (`{ shader, name, serial }`, read off the key), `bytes`, `format`, `width`, `height`, `depth`, `usage` (the bits it was created with — `storage`, `copySrc`, `copyDst`, `vertex`, `index`, `indirect`, `uniform`, `sampled`, `sampler`) and `createdFrame`. `totals` is `{ count, bytes, byKind }`, what the rows sum to — and `totals.bytes` is the `compute` figure of `renderer.gpuMemory()`, read off the same registries. `published` is false when no renderer has published a reading yet, which is the engine saying it cannot answer rather than answering with nothing. The reading is the one the renderer published, republished on a frame where a registry gained or lost an entry: a resource created earlier in this same script is in the next reading, so wait a frame before asking about it, and `generation` moves when it arrives.

```lua
local r = compute.observe()
print(r.totals.count, r.totals.bytes)
for _, res in ipairs(r.resources) do print(res.key, res.kind, res.bytes) end
```

## typed/builtin//modules/api/engine/compute/compute/program/compile {#typed-builtin-modules-api-engine-compute-compute-program-compile}

```lua
compute.program.compile(key: string, spec: { [string]: any }) -> boolean
```

Register a compiled program under `key` from WGSL plus a declared
binding schema. The engine generates the `@group`/`@binding` declarations
from the schema, expands `#include`s, naga-validates, and registers the
result.

**Parameters**

- `key` `string` — The key to register under.
- `spec` `{ [string]: any }` — `{ source, entryPoint?, bindings, params }` — the parsed schema.

**Returns** `boolean` — True on success.

## typed/builtin//modules/api/engine/compute/compute/program/destroy {#typed-builtin-modules-api-engine-compute-compute-program-destroy}

```lua
compute.program.destroy(key: string) -> boolean
```

Release the program registered under `key`.

**Parameters**

- `key` `string` — The program's key.

**Returns** `boolean` — True on success.

## typed/builtin//modules/api/engine/compute/compute/program/dispatch {#typed-builtin-modules-api-engine-compute-compute-program-dispatch}

```lua
compute.program.dispatch(key: string, opts: { [string]: any }) -> boolean
```

Dispatch the program under `key` with one buffer per declared storage
binding, in declaration order.

**Parameters**

- `key` `string` — The program's key.
- `opts` `{ [string]: any }` — `{ buffers, workgroups }`.
A zero in any workgroup dimension is refused and recorded as a dispatch
failure — clamp a computed count with `math.max(1, math.ceil(n / 64))`.

**Returns** `boolean` — True once the dispatch is queued. What the engine then did with it is in `compute.program.status(key)`.

## typed/builtin//modules/api/engine/compute/compute/program/dispatchEx {#typed-builtin-modules-api-engine-compute-compute-program-dispatchex}

```lua
compute.program.dispatchEx(key: string, opts: { [string]: any }) -> boolean
```

Dispatch the program under `key` with explicit resources — one
`{ kind, name }` per declared binding, in declaration order.

**Parameters**

- `key` `string` — The program's key.
- `opts` `{ [string]: any }` — `{ resources, workgroups }`.
A zero in any workgroup dimension is refused and recorded as a dispatch
failure — clamp a computed count with `math.max(1, math.ceil(n / 64))`.

**Returns** `boolean` — True once the dispatch is queued. What the engine then did with it is in `compute.program.status(key)`.

## typed/builtin//modules/api/engine/compute/compute/program/dispatchOnVertices {#typed-builtin-modules-api-engine-compute-compute-program-dispatchonvertices}

```lua
compute.program.dispatchOnVertices(key: string, opts: { [string]: any }) -> boolean
```

Dispatch the program under `key` over a mesh's vertices. The mesh
`opts.model` names fills the shader's `vertices` binding, and `opts.buffers`
fills the remaining storage bindings.

**Parameters**

- `key` `string` — The program's key.
- `opts` `{ [string]: any }` — `{ model, buffers?, workgroups }`.
A zero in any workgroup dimension is refused and recorded as a dispatch
failure — clamp a computed count with `math.max(1, math.ceil(n / 64))`.

**Returns** `boolean` — True once the dispatch is queued. What the engine then did with it is in `compute.program.status(key)`.

## typed/builtin//modules/api/engine/compute/compute/program/setParam {#typed-builtin-modules-api-engine-compute-compute-program-setparam}

```lua
compute.program.setParam(key: string, prop: string, value: number) -> boolean
```

Write one scalar of the program's `params:` uniform. A value set before
the program's first compile is the value it starts with.

**Parameters**

- `key` `string` — The program's key.
- `prop` `string` — Parameter name as declared.
- `value` `number` — New scalar value.

**Returns** `boolean` — True on success.

## typed/builtin//modules/api/engine/compute/compute/program/status {#typed-builtin-modules-api-engine-compute-compute-program-status}

```lua
compute.program.status(key: string) -> { { [string]: any } }
```

What the engine did with the dispatches of the program under `key`,
one record per target.

**Parameters**

- `key` `string` — The program's key.

**Returns** `{ { [string]: any } }` — Array of dispatch records, most recently dispatched first.

## typed/builtin//modules/api/engine/compute/compute/programState {#typed-builtin-modules-api-engine-compute-compute-programstate}

```lua
compute.programState(ref: string | { [string]: any } | AssetRef) -> (string, string?)
```

Where a shader's compiled program stands. A registration is queued
from script and the pipeline is built on the render side frames later,
so the call that asked for the compile cannot say whether it produced a
program: `"absent"` (the engine holds nothing under this key and nothing
is in flight — never asked for, or released), `"pending"` (asked for, not
on the device yet — a recompile of a resident program reads pending too,
because what it produces is a different program from the one bound now),
`"ready"` (compiled and resident, so a dispatch binds it), or `"failed"`
(the most recent registration produced no program), returned with the
reason as a second value. Wait for `"ready"` before a dispatch whose
result is read back, rather than for a count of frames.

**Parameters**

- `ref` `string | { [string]: any } | AssetRef` — A `.computeShader` identity/guid string, a resolved asset handle,
or the name a raw registration chose.

**Returns** `(string, string?)` — `"absent"`, `"pending"`, `"ready"` or `"failed"`, and the reason when `"failed"`.

```lua
if compute.programState(carve) == "ready" then carve:dispatch(opts) end
```

## typed/builtin//modules/api/engine/compute/compute/readBuffer {#typed-builtin-modules-api-engine-compute-compute-readbuffer}

```lua
compute.readBuffer(name: string) -> string
```

Start a GPU→CPU read of the buffer under `name`.

**Parameters**

- `name` `string` — The name it was created under.

**Returns** `string` — The result key to poll with `getReadbackResult*`. A read that could not start answers with the empty key, which every drain reports as unknown — the same shape a caller already handles.

## typed/builtin//modules/api/engine/compute/compute/readTexture3D {#typed-builtin-modules-api-engine-compute-compute-readtexture3d}

```lua
compute.readTexture3D(name: string) -> string
```

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

**Parameters**

- `name` `string`

**Returns** `string`

## typed/builtin//modules/api/engine/compute/compute/readbackState {#typed-builtin-modules-api-engine-compute-compute-readbackstate}

```lua
compute.readbackState(resultKey: string) -> string
```

Where a readback key stands, without consuming it and without
raising: `"pending"` (issued, GPU has not delivered), `"ready"`
(delivered, waiting to be drained), or `"unknown"` (never issued by
`readBuffer()`, or already drained — a result is delivered once).

**Parameters**

- `resultKey` `string` — Key returned by `readBuffer()`.

**Returns** `string` — `"pending"`, `"ready"`, or `"unknown"`.

```lua
if compute.readbackState(key) == "ready" then ... end
```

## typed/builtin//modules/api/engine/compute/compute/registerShader {#typed-builtin-modules-api-engine-compute-compute-registershader}

```lua
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.

**Parameters**

- `nameOrHandle` `string | { [string]: any } | AssetRef` — Shader name or asset handle.
- `opts` `ShaderOpts` _(optional)_ — Shader options. `bindings` comes from the source's own
`@group(0) @binding(n)` declarations when omitted; supplying a count that
disagrees with them raises. Every `readOnlyBindings` entry names one of
those declared bindings, as a whole number from 0 to `bindings - 1`; an
entry outside that run raises.

**Returns** `boolean` — True on success.

```lua
compute.registerShader("blur", { source = WGSL, entryPoint = "main" })
```

## typed/builtin//modules/api/engine/compute/compute/registerShaderEx {#typed-builtin-modules-api-engine-compute-compute-registershaderex}

```lua
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.

**Parameters**

- `nameOrHandle` `string | { [string]: any } | AssetRef`
- `opts` `{ [string]: any }` _(optional)_

**Returns** `boolean`

## typed/builtin//modules/api/engine/compute/compute/resources {#typed-builtin-modules-api-engine-compute-compute-resources}

```lua
compute.resources(owner: any?) -> { any }
```

The resource rows on their own, optionally narrowed to what one shader
owns.

**Parameters**

- `owner` `any` _(optional)_ — A `.computeShader` ref, its guid, or its asset identity. Omit for
every resource compute holds. A value carrying no shader raises, so a
narrowing that cannot be done reads as an error rather than as the whole
inventory. A guid stands for itself, so resources outlive the asset that
made them and stay reachable by their owner.

**Returns** `{ any }` — An array of rows in the shape `compute.observe().resources` carries. Empty when the owner holds nothing.

```lua
for _, r in ipairs(compute.resources(shaderRef)) do print(r.key, r.bytes) end
```

## typed/builtin//modules/api/engine/compute/compute/setParam {#typed-builtin-modules-api-engine-compute-compute-setparam}

```lua
compute.setParam(nameOrHandle: string | { [string]: any } | AssetRef, 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.

**Parameters**

- `nameOrHandle` `string | { [string]: any } | AssetRef` — Shader identity (the `.computeShader` asset name), or the
handle `asset.load` / `asset.resolve` returns — the same forms `dispatch`
takes.
- `prop` `string` — Parameter name as declared in `bindings.yaml`.
- `value` `number` — New scalar value (numbers only).

**Returns** `boolean` — True on success.

```lua
compute.setParam("my_sim", "scale", 4.0)
```

## typed/builtin//modules/api/engine/compute/compute/stepBvh {#typed-builtin-modules-api-engine-compute-compute-stepbvh}

```lua
compute.stepBvh(id: number, budgetMs: number?) -> (string?, string?)
```

Advance a build by as many work units as `budgetMs` buys, and report
whether it has finished: `"pending"` means there is work left,
`"ready"` means `compute.finishBvh` will hand over the buffers. The
slices carry the hierarchy onto the GPU as well as building it, so a
build that reads `"ready"` has already uploaded every byte of itself. A
slice always runs at least one unit, so a budget of 0 advances the build
by exactly one and the largest single unit sets the floor under a slice.

**Parameters**

- `id` `number` — Build id from `compute.beginBvh`.
- `budgetMs` `number` _(optional)_ — Wall time this slice may spend, in milliseconds (default 4).

**Returns** `(string?, string?)` — `"pending"` or `"ready"`, or `(nil, err)` when the id names no build.

```lua
while compute.stepBvh(id, 4) == "pending" do task.wait() end
```

## typed/builtin//modules/api/engine/compute/compute/textureFormatBytes {#typed-builtin-modules-api-engine-compute-compute-textureformatbytes}

```lua
compute.textureFormatBytes(format: string) -> number
```

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

**Parameters**

- `format` `string`

**Returns** `number`

## typed/builtin//modules/api/engine/compute/compute/writeBuffer {#typed-builtin-modules-api-engine-compute-compute-writebuffer}

```lua
compute.writeBuffer(name: string, values: { number } | buffer | string, offset: number?) -> boolean
```

Write words into the buffer under `name`.

**Parameters**

- `name` `string` — The name it was created under.
- `values` `{ number } | buffer | string` — The floats to write, or a `buffer` / binary string already holding them.
- `offset` `number` _(optional)_ — 32-bit word offset to write at.

**Returns** `boolean` — True on success.

## typed/builtin//modules/api/engine/compute/compute/writeBufferBytes {#typed-builtin-modules-api-engine-compute-compute-writebufferbytes}

```lua
compute.writeBufferBytes(name: string, bytes: buffer | string, offsetBytes: number?) -> boolean
```

Write packed bytes into the buffer under `name`.

**Parameters**

- `name` `string` — The name it was created under.
- `bytes` `buffer | string` — The payload.
- `offsetBytes` `number` _(optional)_ — Byte offset to write at.

**Returns** `boolean` — True on success.

## typed/builtin//modules/api/engine/compute/compute/writeBufferU32 {#typed-builtin-modules-api-engine-compute-compute-writebufferu32}

```lua
compute.writeBufferU32(name: string, values: { number } | buffer | string, offsetBytes: number?) -> boolean
```

Write 32-bit words into the buffer under `name`.

**Parameters**

- `name` `string` — The name it was created under.
- `values` `{ number } | buffer | string` — The words to write.
- `offsetBytes` `number` _(optional)_ — Byte offset to write at.

**Returns** `boolean` — True on success.

## typed/builtin//modules/api/engine/compute/compute/writeFloatsTexture3D {#typed-builtin-modules-api-engine-compute-compute-writefloatstexture3d}

```lua
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).

**Parameters**

- `name` `string`
- `floats` `{ number }`
- `formatOrOpts` `(string | { [string]: any })` _(optional)_

**Returns** `boolean`

## typed/builtin//modules/api/engine/compute/compute/writeTexture3D {#typed-builtin-modules-api-engine-compute-compute-writetexture3d}

```lua
compute.writeTexture3D(name: string, data: buffer | string | { number }) -> boolean
```

Upload raw bytes (u8) into a named 3D volume. A `buffer` or a binary
string holds the volume's byte layout verbatim and crosses in one copy —
the shape a file's voxel payload arrives in; an array carries one byte
value (0..255) per entry.

**Parameters**

- `name` `string` — Volume name.
- `data` `buffer | string | { number }` — Voxel bytes as a `buffer`, a binary string, or an array of bytes.

**Returns** `boolean` — True on success (mutation queued).

## typed/builtin//modules/api/engine/debugger/debugger/__diagnostics {#typed-builtin-modules-api-engine-debugger-debugger-diagnostics}

```lua
debugger.__diagnostics() -> DebuggerDiagnostics
```

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

**Returns** `DebuggerDiagnostics` — Diagnostic counters.

## typed/builtin//modules/api/engine/debugger/debugger/addWatch {#typed-builtin-modules-api-engine-debugger-debugger-addwatch}

```lua
debugger.addWatch(expr: string) -> number
```

Register an expression to re-evaluate on every pause.

**Parameters**

- `expr` `string` — Luau expression.

**Returns** `number` — Watch id.

## typed/builtin//modules/api/engine/debugger/debugger/continue_ {#typed-builtin-modules-api-engine-debugger-debugger-continue}

```lua
debugger.continue_() -> boolean
```

Resume the paused thread.

**Returns** `boolean` — True if a thread was paused, false if nothing was paused.

## typed/builtin//modules/api/engine/debugger/debugger/disableAll {#typed-builtin-modules-api-engine-debugger-debugger-disableall}

```lua
debugger.disableAll()
```

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

## typed/builtin//modules/api/engine/debugger/debugger/disconnect {#typed-builtin-modules-api-engine-debugger-debugger-disconnect}

```lua
debugger.disconnect(handle: number) -> boolean
```

Disconnect an onBreak or onResume callback.

**Parameters**

- `handle` `number` — Handle returned by onBreak/onResume.

**Returns** `boolean` — True if the handle existed.

## typed/builtin//modules/api/engine/debugger/debugger/enableAll {#typed-builtin-modules-api-engine-debugger-debugger-enableall}

```lua
debugger.enableAll()
```

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

## typed/builtin//modules/api/engine/debugger/debugger/evaluate {#typed-builtin-modules-api-engine-debugger-debugger-evaluate}

```lua
debugger.evaluate(expr: string, frame: number?) -> (string?, string?)
```

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

**Parameters**

- `expr` `string` — Luau expression.
- `frame` `number` _(optional)_ — 1-based frame index (default 1).

**Returns** `(string?, string?)` — `(value, error)`.

## typed/builtin//modules/api/engine/debugger/debugger/getLocals {#typed-builtin-modules-api-engine-debugger-debugger-getlocals}

```lua
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.

**Parameters**

- `frame` `number` _(optional)_ — 1-based frame index (default 1).

**Returns** `{ [string]: string }` — `{ [name] = string }`.

## typed/builtin//modules/api/engine/debugger/debugger/getPauseInfo {#typed-builtin-modules-api-engine-debugger-debugger-getpauseinfo}

```lua
debugger.getPauseInfo() -> PauseInfo?
```

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

**Returns** `PauseInfo?` — `{ path, line, reason }` or nil.

## typed/builtin//modules/api/engine/debugger/debugger/getStack {#typed-builtin-modules-api-engine-debugger-debugger-getstack}

```lua
debugger.getStack() -> { Frame }
```

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

**Returns** `{ Frame }` — Array of Frame tables.

## typed/builtin//modules/api/engine/debugger/debugger/getUpvalues {#typed-builtin-modules-api-engine-debugger-debugger-getupvalues}

```lua
debugger.getUpvalues(frame: number?) -> { [string]: string }
```

Upvalues captured at the active pause for the given frame.

**Parameters**

- `frame` `number` _(optional)_ — 1-based frame index.

**Returns** `{ [string]: string }` — `{ [name] = string }`.

## typed/builtin//modules/api/engine/debugger/debugger/getWatchValue {#typed-builtin-modules-api-engine-debugger-debugger-getwatchvalue}

```lua
debugger.getWatchValue(id: number) -> (string?, string?)
```

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

**Parameters**

- `id` `number` — Watch id.

**Returns** `(string?, string?)` — `(value, error)`.

## typed/builtin//modules/api/engine/debugger/debugger/getWatches {#typed-builtin-modules-api-engine-debugger-debugger-getwatches}

```lua
debugger.getWatches() -> { Watch }
```

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

**Returns** `{ Watch }` — Array of Watch tables.

## typed/builtin//modules/api/engine/debugger/debugger/isPauseOnError {#typed-builtin-modules-api-engine-debugger-debugger-ispauseonerror}

```lua
debugger.isPauseOnError() -> boolean
```

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

**Returns** `boolean` — True if enabled.

## typed/builtin//modules/api/engine/debugger/debugger/isPaused {#typed-builtin-modules-api-engine-debugger-debugger-ispaused}

```lua
debugger.isPaused() -> boolean
```

Whether the debugger currently has a paused thread.

**Returns** `boolean` — True if paused.

## typed/builtin//modules/api/engine/debugger/debugger/listBreakpoints {#typed-builtin-modules-api-engine-debugger-debugger-listbreakpoints}

```lua
debugger.listBreakpoints() -> { Breakpoint }
```

Snapshot of every registered breakpoint, sorted by id
ascending. Each entry reports whether it is installed:
`chunkNames` lists the loaded chunks carrying it, and
`pendingReason` says why an empty list is empty.

**Returns** `{ Breakpoint }` — Array of breakpoint tables.

## typed/builtin//modules/api/engine/debugger/debugger/onBreak {#typed-builtin-modules-api-engine-debugger-debugger-onbreak}

```lua
debugger.onBreak(fn: (PauseInfo) -> ()) -> number
```

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

**Parameters**

- `fn` `(PauseInfo) -> ()` — Callback.

**Returns** `number` — Handle.

## typed/builtin//modules/api/engine/debugger/debugger/onResume {#typed-builtin-modules-api-engine-debugger-debugger-onresume}

```lua
debugger.onResume(fn: () -> ()) -> number
```

Register a callback invoked when the paused thread is
resumed.

**Parameters**

- `fn` `() -> ()` — Callback.

**Returns** `number` — Handle.

## typed/builtin//modules/api/engine/debugger/debugger/removeBreakpoint {#typed-builtin-modules-api-engine-debugger-debugger-removebreakpoint}

```lua
debugger.removeBreakpoint(id: number) -> boolean
```

Remove the breakpoint with the given id.

**Parameters**

- `id` `number` — Breakpoint id returned by setBreakpoint.

**Returns** `boolean` — True if removed, false if the id was unknown.

## typed/builtin//modules/api/engine/debugger/debugger/removeWatch {#typed-builtin-modules-api-engine-debugger-debugger-removewatch}

```lua
debugger.removeWatch(id: number) -> boolean
```

Remove the watch with the given id.

**Parameters**

- `id` `number` — Watch id.

**Returns** `boolean` — True if removed.

## typed/builtin//modules/api/engine/debugger/debugger/setBreakpoint {#typed-builtin-modules-api-engine-debugger-debugger-setbreakpoint}

```lua
debugger.setBreakpoint(path: string, line: number, opts: BreakpointOpts?) -> Breakpoint
```

Set a breakpoint at `line` in the script `path` names — its
VFS path, its require identity, or the chunk name it loaded
under. An installed breakpoint carries `resolvedLine` and lists
the loaded chunks holding it in `chunkNames`; one whose script is
not loaded carries `pendingReason`, an empty `chunkNames`, and
installs itself when that script loads.

**Parameters**

- `path` `string` — VFS path, require identity, or chunk name.
- `line` `number` — 1-based source line.
- `opts` `BreakpointOpts` _(optional)_ — `{ condition?, logMessage?, hitCount?, enabled? }`.

**Returns** `Breakpoint` — The breakpoint table.

```lua
local bp = debugger.setBreakpoint("/zero/source/main.luau", 42)
print(bp.pendingReason or ("installed in " .. bp.chunkNames[1]))
```

## typed/builtin//modules/api/engine/debugger/debugger/setPauseOnError {#typed-builtin-modules-api-engine-debugger-debugger-setpauseonerror}

```lua
debugger.setPauseOnError(enabled: boolean)
```

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

**Parameters**

- `enabled` `boolean` — Toggle state.

## typed/builtin//modules/api/engine/debugger/debugger/stepInto {#typed-builtin-modules-api-engine-debugger-debugger-stepinto}

```lua
debugger.stepInto() -> boolean
```

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

**Returns** `boolean` — True if a step was scheduled.

## typed/builtin//modules/api/engine/debugger/debugger/stepOut {#typed-builtin-modules-api-engine-debugger-debugger-stepout}

```lua
debugger.stepOut() -> boolean
```

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

**Returns** `boolean` — True if a step was scheduled.

## typed/builtin//modules/api/engine/debugger/debugger/stepOver {#typed-builtin-modules-api-engine-debugger-debugger-stepover}

```lua
debugger.stepOver() -> boolean
```

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

**Returns** `boolean` — True if a step was scheduled.

## typed/builtin//modules/api/engine/debugger/debugger/toggleBreakpoint {#typed-builtin-modules-api-engine-debugger-debugger-togglebreakpoint}

```lua
debugger.toggleBreakpoint(path: string, line: number) -> Breakpoint?
```

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

**Parameters**

- `path` `string` — VFS path, require identity, or chunk name.
- `line` `number` — 1-based line.

**Returns** `Breakpoint?` — Breakpoint table if added, nil if removed.

## typed/builtin//modules/api/engine/ecs/blobs/blobs/clear {#typed-builtin-modules-api-engine-ecs-blobs-blobs-clear}

```lua
blobs.clear(handle: string)
```

Drop a staged payload that will not be consumed, freeing its memory.

**Parameters**

- `handle` `string` — Handle returned by `ecs.blobs.set`.

```lua
ecs.blobs.clear(handle)
```

## typed/builtin//modules/api/engine/ecs/blobs/blobs/get {#typed-builtin-modules-api-engine-ecs-blobs-blobs-get}

```lua
blobs.get(handle: string) -> string?
```

Read back a copy of the bytes staged under `handle` without removing
them. Returns nil for an unknown or already-cleared handle.

## typed/builtin//modules/api/engine/ecs/blobs/blobs/set {#typed-builtin-modules-api-engine-ecs-blobs-blobs-set}

```lua
blobs.set(bytes: string) -> string
```

Stage binary bytes and return a handle to pass through a component
field; a native consumer reads the bytes back by that handle.

## typed/builtin//modules/api/engine/effects/effects/backends {#typed-builtin-modules-api-engine-effects-effects-backends}

```lua
effects.backends() -> { string }
```

The backend kinds an effect can be built out of, in name order. The
runtime ships `emitter`, `geometry`, `material`, `decal` and `feature`.

**Returns** `{ string }` — Array of kind names.

```lua
print(table.concat(effects.backends(), ", "))
```

## typed/builtin//modules/api/engine/effects/effects/describe {#typed-builtin-modules-api-engine-effects-effects-describe}

```lua
effects.describe(identity: string) -> { [string]: any }
```

What an effect declares about itself: its family, a one-line summary,
every parameter with its type, default and documented range, and the cost
one unpooled play of it was measured to draw. The one call to make against
an unfamiliar effect before playing it.

**Parameters**

- `identity` `string` — The effect's canonical identity, or a short name.

**Returns** `{ [string]: any }` — `{ identity, family, summary, cost, params }`.

```lua
local d = effects.describe("explosion"); print(d.family, d.cost.gpuMs)
```

## typed/builtin//modules/api/engine/effects/effects/drain {#typed-builtin-modules-api-engine-effects-effects-drain}

```lua
effects.drain() -> { [string]: number }
```

Free every backend the pool is holding idle. The pool keeps what it has
leased for as long as the engine runs — that is what makes repeated firing
cost nothing after the first — and this is the one call that gives it back.
A backend a live play still holds is left to that play's own end.

**Returns** `{ [string]: number }` — `{ freed, kept }`.

```lua
print(effects.drain().freed)
```

## typed/builtin//modules/api/engine/effects/effects/families {#typed-builtin-modules-api-engine-effects-effects-families}

```lua
effects.families() -> { string }
```

Every family the effects in this world declare, sorted — the values
`list { family = … }` filters on. An effect declaring no family is not one
of them.

**Returns** `{ string }` — Array of family names.

```lua
for _, f in ipairs(effects.families()) do print(f, #effects.list({ family = f })) end
```

## typed/builtin//modules/api/engine/effects/effects/list {#typed-builtin-modules-api-engine-effects-effects-list}

```lua
effects.list(opts: table?) -> { string }
```

The canonical identity of every effect this world can play, sorted.
These are the exact strings `play` takes. Pass `{ family = "combat" }` to
get only the effects of one family — the catalogue filtered the way an
effect declares itself.

**Parameters**

- `opts` `table` _(optional)_ — `{ family? = string }`. A family is matched without regard to case.

**Returns** `{ string }` — Array of identities.

```lua
for _, id in ipairs(effects.list()) do print(id) end
for _, id in ipairs(effects.list({ family = "combat" })) do print(id) end
```

## typed/builtin//modules/api/engine/effects/effects/observe {#typed-builtin-modules-api-engine-effects-effects-observe}

```lua
effects.observe() -> { [string]: any }
```

What the runtime is holding and driving right now — every live play with
the reason it is silent when it is, plus what the pool has leased out and
what it is keeping idle, in instances and in GPU bytes. This is how a caller
and a test tell a working effect from a silent one, and how they tell a pool
warming to a wider burst from something leaking: the pool is sized by the
most effects it has had to cover at once, which `peakLive` and `peakLeased`
report beside the current totals.

**Returns** `{ [string]: any }` — The observation.

```lua
local o = effects.observe(); print(o.live, o.leased, o.pooled, o.bytes)
print(o.peakLive, o.peakLeased)   -- the widest burst the pool covers
```

## typed/builtin//modules/api/engine/effects/effects/play {#typed-builtin-modules-api-engine-effects-effects-play}

```lua
effects.play(identity: string, opts: table?) -> any
```

Play an effect once at a world position. The effect allocates what it
needs from the shared pool, draws itself, and gives everything back when it
ends — with no update loop on the caller's side.

## typed/builtin//modules/api/engine/effects/effects/playOn {#typed-builtin-modules-api-engine-effects-effects-playon}

```lua
effects.playOn(identity: string, target: any?, opts: table?) -> any
```

Play an effect on an entity: it starts where the entity stands and ends
if the entity leaves the world. Move it with the entity by calling
`handle:retarget(theEntity)` as it goes.

**Parameters**

- `identity` `string` — The effect's canonical identity, or a short name.
- `target` `any` _(optional)_ — An entity proxy or entity id.
- `opts` `table` _(optional)_ — The same options `play` takes; `position` is read from the entity.

**Returns** `any` — The play handle.

```lua
local h = effects.playOn("explosion", drum, { params = { scale = 3 } })
```

## typed/builtin//modules/api/engine/effects/effects/registerBackend {#typed-builtin-modules-api-engine-effects-effects-registerbackend}

```lua
effects.registerBackend(kind: string, backend: table)
```

Register a new way of drawing under a kind name, so an effect family
that needs one the runtime does not ship adds it rather than widening the
runtime. Every effect reaches it through `ctx.lease(kind, spec)`.

**Parameters**

- `kind` `string` — The kind name a spec asks for.
- `backend` `table` — The backend — `key`, `acquire`, `seat`, `start`, `stop`, `quiet`,
`place`, `bytes`, `active`, `silence` and `free`.

```lua
effects.registerBackend("ribbonTrail", myBackend)
```

## typed/builtin//modules/api/engine/effects/effects/silenceReasons {#typed-builtin-modules-api-engine-effects-effects-silencereasons}

```lua
effects.silenceReasons() -> { { reason: string, means: string } }
```

The closed set of reasons a play can be producing nothing, in the order
a reading resolves them — nearest cause first — each with what it means.
Every `reason` an observation reports is one of these.

**Returns** `{ { reason: string, means: string } }` — Array of `{ reason, means }`.

```lua
for _, r in ipairs(effects.silenceReasons()) do print(r.reason, r.means) end
```

## typed/builtin//modules/api/engine/egress/egress/credentialNames {#typed-builtin-modules-api-engine-egress-egress-credentialnames}

```lua
egress.credentialNames() -> { string }
```

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

**Returns** `{ string }` — Array of configured credential names.

```lua
for _, n in ipairs(egress.credentialNames()) do print(n) end
```

## typed/builtin//modules/api/engine/egress/egress/fetch {#typed-builtin-modules-api-engine-egress-egress-fetch}

```lua
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.

**Parameters**

- `name` `string` — Credential name registered by the trusted VM.
- `method` `string` — HTTP method, e.g. "GET" or "POST".
- `url` `string` — Request URL (must start with the credential's `base_url`).
- `headers` `Headers` _(optional)_ — Extra header key-value pairs.
- `body` `JsonBody` _(optional)_ — JSON body (encoded automatically).
- `response` `EgressResponseType` _(optional)_ — `"json"` (default) or `"bytes"`.

**Returns** `string?` — Promise handle for `task.await()`, or nil if refused.

```lua
local h = egress.fetch("meshy", "POST", url, nil, { prompt = p })
```

## typed/builtin//modules/api/engine/egress/egress/hasCredential {#typed-builtin-modules-api-engine-egress-egress-hascredential}

```lua
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.

**Parameters**

- `name` `string` — Credential name.

**Returns** `boolean` — True if configured.

```lua
if not egress.hasCredential("meshy") then error("set MESHY_API_KEY") end
```

## typed/builtin//modules/api/engine/engine/M/markScriptingBaseline {#typed-builtin-modules-api-engine-engine-m-markscriptingbaseline}

```lua
M.markScriptingBaseline() -> number
```

Record the scripting registries — world-event subscriptions, the
four lifecycle-watcher lists, and the require cache — as they stand
right now, and make that the point `engine.resetScriptingState()`
restores to. Replaces any previous mark. Returns the new mark's
generation, counting from 1.
Mark once the engine is serving rather than while it boots: the
registries keep growing as the prelude subscribes, the world
entrypoint runs and the startup scene loads, so a mark taken partway
through sits below the rest of that work and the first reset would
remove it.

**Returns** `number`

```lua
engine.markScriptingBaseline()
world.on("player_join", function() end)
engine.resetScriptingState() -- the subscription above is gone
```

## typed/builtin//modules/api/engine/engine/M/offDeviceRebuilt {#typed-builtin-modules-api-engine-engine-m-offdevicerebuilt}

```lua
M.offDeviceRebuilt(id: number) -> boolean
```

Remove an `engine.onDeviceRebuilt` subscriber by its watcher id.
Returns true when a live watcher carried that id, false when it named
none — already removed, or never registered.

**Parameters**

- `id` `number` — Watcher id returned by `engine.onDeviceRebuilt`.

**Returns** `boolean`

```lua
local id = engine.onDeviceRebuilt(function() end)
engine.offDeviceRebuilt(id)
```

## typed/builtin//modules/api/engine/engine/M/offModeChange {#typed-builtin-modules-api-engine-engine-m-offmodechange}

```lua
M.offModeChange(id: number) -> boolean
```

Remove an `engine.onModeChange` subscriber by its watcher id.
Returns true when a live watcher carried that id, false when it
named none — already removed, or never registered.

**Parameters**

- `id` `number` — Watcher id returned by `engine.onModeChange`.

**Returns** `boolean`

```lua
local id = engine.onModeChange(function() end)
engine.offModeChange(id)
```

## typed/builtin//modules/api/engine/engine/M/offPauseChange {#typed-builtin-modules-api-engine-engine-m-offpausechange}

```lua
M.offPauseChange(id: number) -> boolean
```

Remove an `engine.onPauseChange` subscriber by its watcher id.
Returns true when a live watcher carried that id, false when it
named none.

**Parameters**

- `id` `number` — Watcher id returned by `engine.onPauseChange`.

**Returns** `boolean`

## typed/builtin//modules/api/engine/engine/M/offWorldLoaded {#typed-builtin-modules-api-engine-engine-m-offworldloaded}

```lua
M.offWorldLoaded(id: number) -> boolean
```

Remove an `onWorldLoaded` subscriber by its watcher id.

**Parameters**

- `id` `number`

**Returns** `boolean`

## typed/builtin//modules/api/engine/engine/M/offWorldReady {#typed-builtin-modules-api-engine-engine-m-offworldready}

```lua
M.offWorldReady(id: number) -> boolean
```

Remove an `engine.onWorldReady` subscriber by its watcher id.
Returns true when a live watcher carried that id, false when it
named none.

**Parameters**

- `id` `number` — Watcher id returned by `engine.onWorldReady`.

**Returns** `boolean`

## typed/builtin//modules/api/engine/engine/M/offWorldUnloading {#typed-builtin-modules-api-engine-engine-m-offworldunloading}

```lua
M.offWorldUnloading(id: number) -> boolean
```

Remove an `engine.onWorldUnloading` subscriber by its watcher
id. Returns true when a live watcher carried that id, false when it
named none.

**Parameters**

- `id` `number` — Watcher id returned by `engine.onWorldUnloading`.

**Returns** `boolean`

## typed/builtin//modules/api/engine/engine/M/onDeviceRebuilt {#typed-builtin-modules-api-engine-engine-m-ondevicerebuilt}

```lua
M.onDeviceRebuilt(callback: (number) -> ()) -> number
```

Register a callback that fires after the engine has answered a lost
render device by building another one. The callback receives the new
device generation — a number that counts the devices this session has run
on, and moves exactly once per rebuild. Returns a watcher id.

A device is lost when the driver resets, when the GPU is taken away, or
when a browser reclaims a WebGPU context. Everything the engine can
re-derive by itself it does: meshes, materials, shaders, render passes and
the UI are all back on the new device before this fires. What it cannot
re-derive is what YOUR content made and only the GPU held — a texture
uploaded from pixels a script computed, a compute buffer it filled, a
render target it created. Make those again here.

Content that owns no GPU resource of its own needs no subscriber: asset
handles re-materialise on their next use.

**Parameters**

- `callback` `(number) -> ()` — Function invoked as `(generation: number)`.

**Returns** `number`

```lua
engine.onDeviceRebuilt(function(generation)
-- the noise field lived only on the GPU, so it is computed again
regenerateNoiseTexture()
end)
```

## typed/builtin//modules/api/engine/engine/M/onModeChange {#typed-builtin-modules-api-engine-engine-m-onmodechange}

```lua
M.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.

**Parameters**

- `callback` `(string, string) -> ()` — Function invoked as `(newMode: string, oldMode: string)`.

**Returns** `number`

```lua
local id = engine.onModeChange(function(new, old)
print("flipped " .. old .. " -> " .. new)
end)
```

## typed/builtin//modules/api/engine/engine/M/onPauseChange {#typed-builtin-modules-api-engine-engine-m-onpausechange}

```lua
M.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.

**Parameters**

- `callback` `(boolean, boolean) -> ()` — Function invoked as `(newPaused: boolean, oldPaused: boolean)`.

**Returns** `number`

```lua
local id = engine.onPauseChange(function(paused)
print(paused and "frozen" or "running")
end)
```

## typed/builtin//modules/api/engine/engine/M/onWorldLoaded {#typed-builtin-modules-api-engine-engine-m-onworldloaded}

```lua
M.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`.

**Parameters**

- `callback` `() -> ()` — Function invoked with no arguments.

**Returns** `number`

## typed/builtin//modules/api/engine/engine/M/onWorldReady {#typed-builtin-modules-api-engine-engine-m-onworldready}

```lua
M.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.

**Parameters**

- `callback` `() -> ()` — Function invoked with no arguments.

**Returns** `number`

## typed/builtin//modules/api/engine/engine/M/onWorldUnloading {#typed-builtin-modules-api-engine-engine-m-onworldunloading}

```lua
M.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.

**Parameters**

- `callback` `() -> ()` — Function invoked with no arguments.

**Returns** `number`

## typed/builtin//modules/api/engine/engine/M/resetScriptingState {#typed-builtin-modules-api-engine-engine-m-resetscriptingstate}

```lua
M.resetScriptingState() -> { [string]: number }
```

Drop every world-event subscription, lifecycle watcher and
cached module registered since the last
`engine.markScriptingBaseline()`, leaving everything registered
before it in place — including the builtin world-entrypoint loader,
which subscribes at VM boot and so always sits below any mark.
Raises when no mark has been taken. Returns per-registry counts of
what was removed: `worldEvents`, `modeWatchers`,
`worldReadyWatchers`, `worldUnloadingWatchers`, `pauseWatchers`,
`modules`, and `total`.

**Returns** `{ [string]: number }`

## typed/builtin//modules/api/engine/engine/M/scriptingRegistryCounts {#typed-builtin-modules-api-engine-engine-m-scriptingregistrycounts}

```lua
M.scriptingRegistryCounts() -> { [string]: number }
```

How many subscriptions each scripting registry holds right now,
plus the size of the require cache and the generation of the mark in
force. Keys: `worldEvents`, `modeWatchers`, `worldReadyWatchers`,
`worldUnloadingWatchers`, `pauseWatchers`, `modules`, and
`baselineGeneration` (nil when no mark has been taken).

**Returns** `{ [string]: number }`

## typed/builtin//modules/api/engine/engine/M/setMode {#typed-builtin-modules-api-engine-engine-m-setmode}

```lua
M.setMode(mode: string, options: { strict: boolean? }?) -> { mode: string, bypassed: { any } }
```

Change the engine mode with per-call control over the play gate, and
read back what the change went past. `engine.mode = value` is the same
flip with the defaults.

`options.strict = false` lets THIS call enter play while your own content
carries error-severity diagnostics. It settles with the call: the world's
`lsp.strict_mode` is untouched, so no other session and no later session
of the world sees a different gate. The returned `bypassed` array holds
the diagnostics the call went past — each `{ path, line, col, code,
message, severity }` — and the engine log carries the same list. An
error in content another session wrote never gates the flip, so it never
appears here; a push still refuses to publish while any of them stands.

**Parameters**

- `mode` `string` — `"edit"` or `"play"`.
- `options` `{ strict: boolean? }` _(optional)_ — `{ strict: boolean? }`. `strict = false` waives the play gate
for this call; `true` or omitted honours the world's `lsp.strict_mode`.

**Returns** `{ mode: string, bypassed: { any } }` — `{ mode, bypassed }` — the mode now in force and the diagnostics this call entered play past (empty when it went past none).

```lua
local report = engine.setMode("play", { strict = false })
for _, d in ipairs(report.bypassed) do
print(("entered play past %s:%d — %s"):format(d.path, d.line, d.message))
end
```

## typed/builtin//modules/api/engine/engine/engine/discardPlayChanges {#typed-builtin-modules-api-engine-engine-engine-discardplaychanges}

```lua
engine.discardPlayChanges() -> ()
```

Arm the leave-play safeguard's deliberate discard for the play session this is called from, so that session's play to edit flip proceeds and discards its unaccepted changes.

**Returns** `()`

## typed/builtin//modules/api/engine/engine/engine/gameplayReady {#typed-builtin-modules-api-engine-engine-engine-gameplayready}

```lua
engine.gameplayReady -> boolean
```

Whether gameplay simulation is running: not paused, and the play scene materialized. Read-only.

**Returns** `boolean`

## typed/builtin//modules/api/engine/engine/engine/gpuCompute {#typed-builtin-modules-api-engine-engine-engine-gpucompute}

```lua
engine.gpuCompute -> boolean
```

Whether this process holds a live GPU device, so compute dispatch is available. Read-only.

**Returns** `boolean`

## typed/builtin//modules/api/engine/engine/engine/headless {#typed-builtin-modules-api-engine-engine-engine-headless}

```lua
engine.headless -> boolean
```

Whether this boot renders offscreen with no window a person can see. Content that only serves someone at a display stands down when it reads true. Read-only.

**Returns** `boolean`

## typed/builtin//modules/api/engine/engine/engine/mode {#typed-builtin-modules-api-engine-engine-engine-mode}

```lua
engine.mode -> "edit" | "play"
```

The engine mode this process is in, `edit` or `play`. Assigning it takes the flip, side effects and all.

**Returns** `"edit" | "play"`

## typed/builtin//modules/api/engine/engine/engine/paused {#typed-builtin-modules-api-engine-engine-engine-paused}

```lua
engine.paused -> boolean
```

Whether gameplay is paused: `update(dt)` component callbacks are gated off while `editorUpdate(dt)` keeps firing in edit mode.

**Returns** `boolean`

## typed/builtin//modules/api/engine/engine/engine/profile {#typed-builtin-modules-api-engine-engine-engine-profile}

```lua
engine.profile -> "editor" | "runtime"
```

The boot profile this process started under, `editor` or `runtime`. Read-only.

**Returns** `"editor" | "runtime"`

## typed/builtin//modules/api/engine/engine/engine/timeScale {#typed-builtin-modules-api-engine-engine-engine-timescale}

```lua
engine.timeScale -> number
```

The global time scale applied to the fixed-timestep accumulator and to `update(dt)`: 1.0 is real time, 0.0 frozen, 2.0 double speed.

**Returns** `number`

## typed/builtin//modules/api/engine/engine/engine/vertexStride {#typed-builtin-modules-api-engine-engine-engine-vertexstride}

```lua
engine.vertexStride -> number
```

Byte stride of the engine's standard GPU Vertex layout, which a mesh built from a compute buffer sizes and strides its writes to. Read-only.

**Returns** `number`

## typed/builtin//modules/api/engine/engine/engine/worldLoaded {#typed-builtin-modules-api-engine-engine-engine-worldloaded}

```lua
engine.worldLoaded -> boolean
```

Whether the world entrypoint's `onWorldLoad` has run to completion. Read-only.

**Returns** `boolean`

## typed/builtin//modules/api/engine/entity/E/batchAddComponent {#typed-builtin-modules-api-engine-entity-e-batchaddcomponent}

```lua
E.batchAddComponent(targets: { string | entityRef }, type_name: string, data: table?) -> number
```

Add the same component type to many entities in one call. Returns the
count of entities the component was added to — an entity already
carrying an unnamed instance of the same type is skipped rather than
double-added.

**Parameters**

- `targets` `{ string | entityRef }` — Array of entity ids or entity proxies (e.g. the return of
`entity.batchSpawn` or `entity.findAll`).
- `type_name` `string` — Component type to add to every entity.
- `data` `table` _(optional)_ — Init data table, applied identically to every entity — the same
shape the second arg to `entity(id).component.add(type, data)` takes.

**Returns** `number` — How many entities had the component added.

```lua
local n = entity.batchAddComponent(ids, "Debris", { lifetime = 5 })
```

## typed/builtin//modules/api/engine/entity/E/batchDespawn {#typed-builtin-modules-api-engine-entity-e-batchdespawn}

```lua
E.batchDespawn(targets: { string | entityRef }) -> number
```

Despawn many entities in one call. Locked or unresolvable entities
are skipped. Returns the count queued for despawn.

**Parameters**

- `targets` `{ string | entityRef }` — Array of entity ids, entity proxies, or display names (e.g.
the return of `entity.batchSpawn` / `entity.findAll`).

**Returns** `number` — Count of entities queued for despawn.

```lua
local n = entity.batchDespawn(ids)
```

## typed/builtin//modules/api/engine/entity/E/batchProxy {#typed-builtin-modules-api-engine-entity-e-batchproxy}

```lua
E.batchProxy(targets: { string | entityRef }) -> { entityRef? }
```

Resolve an array of entity ids to proxies in one call. Each output
slot is the standard `entity(id)` proxy; ids missing from the frame
cache surface as nil at that index. Use when iterating over a snapshot
of entities so per-id lookups don't dominate the hot path.

**Parameters**

- `targets` `{ string | entityRef }` — Array of entity ids or entity proxies.

**Returns** `{ entityRef? }` — Array of proxies (nil for missing ids).

```lua
local proxies = entity.batchProxy(ids)
```

## typed/builtin//modules/api/engine/entity/E/batchRead {#typed-builtin-modules-api-engine-entity-e-batchread}

```lua
E.batchRead(target: { string | entityRef } | binding, component: string?, field: string?, sink: buffer?) -> { any? } | number
```

Read a component-field across many entities in one call.
Polymorphic on the shape of `target` and `sink`:
- `entity.batchRead(ids)` / `(ids, comp)` / `(ids, comp, field)` —
returns one value per entity (a whole snapshot, one component table,
or one field value). Missing entities/components/fields surface as
nil at that slot.
- `entity.batchRead(binding, comp, field, buffer)` — reads each
entity's field directly into a typed CPU substrate buffer
(`substrate.createBuffer({type="vec3"})`, etc.) with no per-entity
Lua table allocation. Returns the count of successful reads.
`target` accepts an entity-id array or a `ecs.bindEntities(ids)`
handle. Buffer sinks require a binding — the typed kernel is
binding-only.

**Parameters**

- `target` `{ string | entityRef } | binding` — Array of entity ids or entity proxies, or a binding handle
from `ecs.bindEntities(ids)`.
- `component` `string` _(optional)_ — Component type name (e.g. "Transform").
- `field` `string` _(optional)_ — Field name (e.g. "position").
- `sink` `buffer` _(optional)_ — Typed CPU buffer from `substrate.createBuffer({...})` to memcpy
field values into. Required when `target` is a binding.

**Returns** `{ any? } | number` — Per-entity values when reading into Lua tables; count of reads when reading into a buffer.

```lua
local snapshot = entity.batchRead(ids)
local positions = entity.batchRead(ids, "Transform", "position")
```

## typed/builtin//modules/api/engine/entity/E/batchReadToBuffer {#typed-builtin-modules-api-engine-entity-e-batchreadtobuffer}

```lua
E.batchReadToBuffer(binding: number, component: string, field: string, buffer: number) -> number
```

FFI primitive backing `entity.batchRead(binding, ..., buffer)`.
Prefer the unified `entity.batchRead`, which auto-dispatches by
argument shape. Reads each entity's component field directly into a
typed CPU substrate buffer, with no per-entity Lua table allocation.
After the call, read the buffer via `buf:read(0, count*stride)`.

**Parameters**

- `binding` `number` — Binding id from `ecs.bindEntities(ids).id`.
- `component` `string` — Component type name.
- `field` `string` — Field name to read.
- `buffer` `number` — Destination buffer id (must be the matching type).

**Returns** `number` — Count of successful reads.

```lua
entity.batchReadToBuffer(binding.id, "Transform", "position", buf.id)
```

## typed/builtin//modules/api/engine/entity/E/batchSpawn {#typed-builtin-modules-api-engine-entity-e-batchspawn}

```lua
E.batchSpawn(count: number, name_prefix: string?) -> { string }
```

Spawn `count` entities in one call. Returns an array of the new
entity ids in spawn order. Each entity is given a display name of
`<name_prefix><i>` (or `entity<i>` if the prefix is omitted). Prefer this
over looping `entity.spawn` when creating large entity counts.

**Parameters**

- `count` `number` — How many entities to spawn (capped at 1,000,000).
- `name_prefix` `string` _(optional)_ — Display-name prefix appended with the 1-based index.
Defaults to "entity".

**Returns** `{ string }` — Array of newly-spawned entity ids.

```lua
local ids = entity.batchSpawn(100, "grass_")
```

## typed/builtin//modules/api/engine/entity/E/batchWrite {#typed-builtin-modules-api-engine-entity-e-batchwrite}

```lua
E.batchWrite(target: { string | entityRef } | binding, component: string, field: string, source: { any? } | buffer) -> number
```

Write a single component-field across many entities in one call.
Polymorphic on the shape of `target` and `source`:
- `entity.batchWrite(ids, comp, field, values)` — per-call entity-id
resolution; `values` is an array the same length as `ids` (nil slots
are skipped). Use for one-shot writes.
- `entity.batchWrite(binding, comp, field, values)` — binding handle
from `ecs.bindEntities(ids)`; skips per-call id resolution. Use for
per-frame writes against a stable entity set.
- `entity.batchWrite(binding, comp, field, buffer)` — typed CPU buffer
source (`substrate.createBuffer({type="vec3"})`, etc.), with no
per-entity table allocation.
Returns the count of successful writes. Buffer sources require a
binding — the typed kernel is binding-only.

**Parameters**

- `target` `{ string | entityRef } | binding` — Array of entity ids or entity proxies, or a binding handle
from `ecs.bindEntities(ids)`.
- `component` `string` — Component type name.
- `field` `string` — Field name to write.
- `source` `{ any? } | buffer` — Per-entity values array (nil entries are skipped), or a typed
CPU buffer from `substrate.createBuffer({...})`. A buffer source
requires a binding `target`.

**Returns** `number` — Count of successful writes.

```lua
entity.batchWrite(ids, "Transform", "position", positions)
```

## typed/builtin//modules/api/engine/entity/E/batchWriteBound {#typed-builtin-modules-api-engine-entity-e-batchwritebound}

```lua
E.batchWriteBound(binding: number, component: string, field: string, values: { any? }) -> number
```

FFI primitive backing `entity.batchWrite(binding, ...)` with a
per-entity values table. Prefer the unified `entity.batchWrite`, which
auto-dispatches by argument shape; this entry stays for power users /
debug code that wants to skip dispatch overhead.

**Parameters**

- `binding` `number` — Binding id from `ecs.bindEntities(ids).id`.
- `component` `string` — Component type name.
- `field` `string` — Field name to write.
- `values` `{ any? }` — Per-entity source values (nil = skip). Length must match the
binding's entity count.

**Returns** `number` — Count of successful writes.

```lua
entity.batchWriteBound(binding.id, "Transform", "position", values)
```

## typed/builtin//modules/api/engine/entity/E/batchWriteFromBuffer {#typed-builtin-modules-api-engine-entity-e-batchwritefrombuffer}

```lua
E.batchWriteFromBuffer(binding: number, component: string, field: string, buffer: number) -> number
```

FFI primitive backing `entity.batchWrite(binding, ..., buffer)`.
Prefer the unified `entity.batchWrite`, which auto-dispatches by
argument shape. Caller fills a typed substrate buffer
(`substrate.createBuffer({type="vec3"})`) once via `buf:write(...)`,
then this memcpys 12 (vec3) or 16 (quat) bytes per entity into the
component field. Buffer count and binding count should match — a
mismatch processes the smaller of the two.

**Parameters**

- `binding` `number` — Binding id from `ecs.bindEntities(ids).id`.
- `component` `string` — Component type name.
- `field` `string` — Field name to write.
- `buffer` `number` — Buffer id from `substrate.createBuffer({type="vec3", len=N}).id`.

**Returns** `number` — Count of successful writes.

```lua
entity.batchWriteFromBuffer(binding.id, "Transform", "position", buf.id)
```

## typed/builtin//modules/api/engine/entity/E/capture {#typed-builtin-modules-api-engine-entity-e-capture}

```lua
E.capture(builder: () -> ()) -> ({ string }, any?, { string })
```

Run `builder` inside an entity capture scope and return the entity ids
it minted, in creation order, the error it raised (if any), and the ids
among them that a component the builder attached minted in its own
lifecycle. Every id minted while the builder runs is recorded — through
`entity.spawn`, `entity.spawnSynced`, `entity.batchSpawn`, and
`entity.instantiate` alike. Scopes nest: an id minted inside an inner
capture is recorded by that capture AND every enclosing one — the
innermost capture answers, so a nested build shapes its own entities,
not the ones around it. A builder that raises still returns its ids, so
the caller can despawn what a failed build left behind; the scope closes
either way and never outlives this call. While the builder runs, an
operation whose result cannot be composed into a record is refused
rather than applied, and so is any operation aimed at an entity the
builder did not mint — a builder that returned while something it did
was refused comes back with an error naming every refusal.

**Parameters**

- `builder` `() -> ()` — Function run inside the scope; the entities it creates are
what comes back.

**Returns** `({ string }, any?, { string })` — Entity ids minted while the builder ran, in creation order; the error it raised (or the refusals it hit), or nil; and the ids a component the builder attached minted in its own lifecycle.

```lua
local ids, err, reproduced = entity.capture(function() entity.spawn("chair") end)
```

## typed/builtin//modules/api/engine/entity/E/despawn {#typed-builtin-modules-api-engine-entity-e-despawn}

```lua
E.despawn(target: string | entityRef)
```

Despawn an entity and all its components. Pass an id string or an
entity proxy to despawn that ONE entity. Pass a name to despawn EVERY
entity with that name — names are not unique, so a name argument
despawns all matches, not one arbitrary match. A despawned id becomes
invalid after this call. Raises if no entity matches; for a bulk name
despawn, locked entities are skipped with a logged summary and only
raise if every match is locked.

**Parameters**

- `target` `string | entityRef` — Entity id, name, or entity proxy. A name despawns all entities
sharing that name.

```lua
entity.despawn(id)
entity.despawn("Enemy") -- despawns every entity named "Enemy"
```

## typed/builtin//modules/api/engine/entity/E/duplicate {#typed-builtin-modules-api-engine-entity-e-duplicate}

```lua
E.duplicate(sourceId: string | entityRef, name: string?, opts: table?) -> string?
```

Duplicate an entity with all its components (transform, script
components, attributes, visuals, material) and its descendants. Returns
the new entity's id, or nil when `sourceId` names no live entity.
Descendants marked temporary are left out of the copy: they are
scaffolding whatever spawned them re-creates, so a component that
regenerates its own children rebuilds them on the copy rather than the
copy carrying a second set. `includeTemporary` copies them too, for the
hierarchy that IS the temporary thing.

**Parameters**

- `sourceId` `string | entityRef` — Entity id or entity proxy of the source entity to clone.
- `name` `string` _(optional)_ — Display name for the copy (defaults to source name + " (copy)").
- `opts` `table` _(optional)_ — `{ includeTemporary?: boolean, name?: string }` — `name` is the
same field the `name` argument sets, and wins when both are given.

**Returns** `string?` — The new entity's id, or nil when the source is not live.

```lua
local copyId = entity.duplicate(id); if copyId then entity(copyId).position = { 1, 0, 0 } end
local copyId = entity.duplicate(id, "Turret", { includeTemporary = true })
```

## typed/builtin//modules/api/engine/entity/E/exists {#typed-builtin-modules-api-engine-entity-e-exists}

```lua
E.exists(idOrProxy: string | entityRef) -> boolean
```

Check whether an entity currently exists in the scene. Accepts an
entity-id string or an entity proxy, matched by entity id — so it agrees
exactly with `entity(id)`. A name is a different kind of identifier: a
string that misses as an id but names a live entity raises rather than
answering false, since false there is indistinguishable from absence.
Check by name with `entity.find(name) ~= nil`.

**Parameters**

- `idOrProxy` `string | entityRef` — Entity id or an entity proxy.

**Returns** `boolean` — true if the entity exists.

```lua
if entity.exists(id) then ... end
```

## typed/builtin//modules/api/engine/entity/E/find {#typed-builtin-modules-api-engine-entity-e-find}

```lua
E.find(nameOrGlob: string) -> entityRef?
```

Find the first entity matching `nameOrGlob`. A plain string matches
an exact id or Name component; a string containing `*` (any run of
characters) or `?` (any single character) matches Names as a glob, so
`entity.find("enemy_*")` is the first entity whose name starts with
`enemy_`. A glob addresses Names only, never ids. Same-frame pending
spawns are searched too, and anything queued for despawn in the same
frame is skipped. Names are NOT unique — use `entity.findAll` when every
match matters.

**Parameters**

- `nameOrGlob` `string` — Exact entity Name or id, or a `*` / `?` glob over Names.

**Returns** `entityRef?` — First matching entity proxy, or nil.

```lua
local e = entity.find("enemy_*")
```

## typed/builtin//modules/api/engine/entity/E/findAll {#typed-builtin-modules-api-engine-entity-e-findall}

```lua
E.findAll(nameOrGlob: string?) -> { entityRef }
```

Enumerate entity proxies. With a `nameOrGlob` argument, returns every
entity whose Name component or id matches (names are not unique): a
plain string matches exactly, while a `*` / `?` glob matches Names. With
no argument, returns every entity in the current snapshot —
`findAll("")` is the exact-match filter for the empty name, which
normally matches nothing. Same-frame pending spawns are included and
same-frame despawns filtered out. Elements are entity proxies, not id
strings — for ids, wrap the result: `entity.ids(entity.findAll(...))`.

**Parameters**

- `nameOrGlob` `string` _(optional)_ — Exact entity Name or id to filter by, or a `*` / `?` glob
over Names. Omit to enumerate every entity.

**Returns** `{ entityRef }` — Array of entity proxies, possibly empty.

```lua
for _, e in entity.findAll("enemy_*") do e:despawn() end
```

## typed/builtin//modules/api/engine/entity/E/getChildren {#typed-builtin-modules-api-engine-entity-e-getchildren}

```lua
E.getChildren(id: string | entityRef) -> { entityRef }
```

Get an array of the direct children as entity proxies. Each element
carries `.name`, `.id`, `.position`, `.component`, and the rest of the
per-entity surface — the same shape `entity.findAll` returns.

**Parameters**

- `id` `string | entityRef` — Entity id or entity proxy.

**Returns** `{ entityRef }` — Array of child entity proxies, possibly empty.

```lua
for _, c in entity.getChildren(id) do c.internal = true end
```

## typed/builtin//modules/api/engine/entity/E/getDescendants {#typed-builtin-modules-api-engine-entity-e-getdescendants}

```lua
E.getDescendants(id: string | entityRef) -> { entityRef }
```

Get every descendant (children, grandchildren, and deeper) of the
given entity as entity proxies in breadth-first order, excluding the
entity itself. Resolves the whole subtree in one linear pass over the
entity set, so a large subtree costs proportionally to the entity count
rather than to the subtree size times the entity count.

**Parameters**

- `id` `string | entityRef` — Entity id or entity proxy.

**Returns** `{ entityRef }` — Array of descendant entity proxies, possibly empty.

```lua
local all = entity.getDescendants(id)
```

## typed/builtin//modules/api/engine/entity/E/getParent {#typed-builtin-modules-api-engine-entity-e-getparent}

```lua
E.getParent(id: string | entityRef) -> entityRef?
```

Get the parent entity proxy, or nil if the entity is a root entity.
The returned proxy carries `.name`, `.id`, `.position`, `.component`,
and the rest of the per-entity surface — the same shape `entity.find`
returns.

**Parameters**

- `id` `string | entityRef` — Entity id or entity proxy.

**Returns** `entityRef?` — Parent entity proxy, or nil.

```lua
local p = entity.getParent(id)
```

## typed/builtin//modules/api/engine/entity/E/instantiate {#typed-builtin-modules-api-engine-entity-e-instantiate}

```lua
E.instantiate(handle: number, count: number, fn: ((number) -> EntityInstantiateOverrides?)?) -> { string }
```

Spawn `count` instances of a template registered with
`entity.template`. Each instance gets a fresh entity id; the optional
`fn(i)` callback runs per instance (`i` in 1..=count) and may return an
overrides table. Override keys: `name`, `position`, `rotation`, `scale`,
`parent`, `temporary` / `active` / `internal`, `attributes`, `components`
(script components, merged over the template body's data for that type
— a type the template lacks is added fresh), and `ecs` (native
components, merged the same way). Each override supersedes the
template's shared config for that instance. The whole batch crosses in
one call and lands as a single deferred mutation the engine expands
into bulk work — per-instance cost drops from a full round trip to one
callback plus one mutation. Inside `queue()` the batch is deferred onto
the cross-frame ring; outside, it lands in the next frame's drain.
Returns the array of newly-minted entity ids in spawn order.

**Parameters**

- `handle` `number` — Template handle from `entity.template`.
- `count` `number` — Number of instances to spawn (capped at 1,000,000).
- `fn` `((number) -> EntityInstantiateOverrides?)` _(optional)_ — Per-instance override callback `(i) -> table?`.

**Returns** `{ string }` — Array of newly-spawned entity ids in spawn order.

```lua
local ids = entity.instantiate(h, 50, function(i) return { position = { i, 0, 0 } } end)
```

## typed/builtin//modules/api/engine/entity/E/spawn {#typed-builtin-modules-api-engine-entity-e-spawn}

```lua
E.spawn(nameOrOpts: (string | SpawnOpts)?, opts: SpawnOpts?) -> entityRef
```

Spawn a new entity and return its PROXY (the same value entity(id)
yields) — act on it immediately (`entity.spawn(name).component.add(...)`,
`.localPosition = ...`) with no second `entity(id)` round trip. The proxy
still exposes `.id` for the rare site that needs the raw string. An
entity with no components carries only a Transform and is invisible;
pass `components` to give it the components that make it visible in the
same call — `entity.spawn { name = "crate", components = { Model = {
model = "cube" } } }` — or add them afterwards through the returned
proxy. Mirrors `entity.find` / `entity.findAll`, which also return
proxies. The options table can be passed on its own with the name inside
it — `entity.spawn { name = "turret", position = { 1, 2, 3 } }` is the
same call as `entity.spawn("turret", { position = { 1, 2, 3 } })`.

**Parameters**

- `nameOrOpts` `(string | SpawnOpts)` _(optional)_ — Display name for the entity, or the options table itself.
- `opts` `SpawnOpts` _(optional)_ — Options: `components` = component types to attach to the new
entity, keyed by type name with each value the component's init table
(attached in sorted type order; a failing add raises), `internal` = take
the entity out of the default entity listings (it still renders —
`entity(id):hide()` stops the draw), `parent` = parent entity id or
proxy, `temporary` = skip this entity (and descendants) from
scene/world saves, `position` / `rotation` / `scale` = place the
entity's Transform at spawn, `id` = restore a previously-assigned entity
id (scene_loader use; leave unset for a normal spawn). An unrecognised
key is rejected loudly.

**Returns** `entityRef` — Proxy for the new entity (carries `.id`, `.component`, transform properties, etc.).

```lua
local e = entity.spawn("crate", { components = { Model = { model = "cube" } } })
local e = entity.spawn { name = "turret", position = { 1, 2, 3 } }
```

## typed/builtin//modules/api/engine/entity/E/spawnSynced {#typed-builtin-modules-api-engine-entity-e-spawnsynced}

```lua
E.spawnSynced(nameOrOpts: (string | SpawnOpts)?, opts: SpawnOpts?) -> entityRef
```

Spawn an entity already flagged multiplayer-synced at the root — the
explicit form of `entity.spawn` for SHARED, host-authoritative content.
The entity's existence broadcasts to every peer; joiners receive it from
the relay snapshot instead of spawning their own copy. Use this (NOT
`entity.spawn`) for anything that must be the SAME object on all
clients: enemies, pickups, projectiles, dynamic world props. Call it
ONLY where exactly one client runs the code — a scene's `onHostLoad`
(host-only) phase, or behind `multiplayer.isHost()`. Calling it in
all-client code makes every client spawn+sync its own copy — the
double-spawn "explosion". Equivalent to
`entity.spawn(name, { synced = true })`; identical in every other
respect.

**Parameters**

- `nameOrOpts` `(string | SpawnOpts)` _(optional)_ — Display name for the entity, or the options table itself.
- `opts` `SpawnOpts` _(optional)_ — Same options as `entity.spawn` (`synced` is already implied).

**Returns** `entityRef` — Proxy for the new synced entity.

```lua
if multiplayer.isHost() then entity.spawnSynced("Goblin") end
```

## typed/builtin//modules/api/engine/entity/E/template {#typed-builtin-modules-api-engine-entity-e-template}

```lua
E.template(def: EntityTemplateDef) -> number
```

Construct a reusable spawn template. Captures a shared entity config
ONCE and returns a stable handle for `entity.instantiate(handle, count,
fn?)` — one call per batch instead of one per entity. `def` keys:
`components` (script components, `{ [type] = init-data }`), `ecs`
(array of native `ecs.X{...}` components), `temporary` (instances skip
scene/world saves), `active` (spawn state), `internal` (instances are
taken out of the default entity listings; they still render),
`attributes` (`{ key = value }` applied to every instance). Every value
is a shared default; a per-instance `entity.instantiate` override
supersedes it. The template body is captured by value — later edits to
the source table do not affect templates already created.

**Parameters**

- `def` `EntityTemplateDef` — Template definition: `components` / `ecs` / `temporary` /
`active` / `internal` / `attributes`. Per-instance `name` / `position` /
`rotation` / `scale` / `parent` and any override go through the
`instantiate` callback.

**Returns** `number` — Stable template handle for `entity.instantiate`.

```lua
local h = entity.template({ components = { Model = { model = "cube" } } })
```

## typed/builtin//modules/api/engine/entity/E/tree {#typed-builtin-modules-api-engine-entity-e-tree}

```lua
E.tree(opts: { [string]: any }?) -> { [string]: any }
```

A windowed, lean view over the scene's entity tree, in one crossing.
Rows carry id, name, parentId, depth, childCount, active, sceneLayer and
componentNames — names only, never component values — so the call costs
the rows it answers with rather than the size of the scene. Entities group
under scene layers, per-layer roots and children name-sorted; internal
entities and their subtrees stay out. `expanded` names the ids whose
children unfold, and a collapsed node still reports its `childCount`;
`filter` keeps the rows whose name or id contains the needle plus every
ancestor on a path to one, auto-unfolded, with the actual matches flagged
`matched`. `offset` / `limit` window the flattened rows, `layer` scopes the
window and its `total` to one layer while `layers` still reports every
layer's row count, and `revision` echoes
`getEntitiesRevision("structure")`, which moves only on structural change.

**Parameters**

- `opts` `{ [string]: any }` _(optional)_ — `{ layer?, expanded?, filter?, offset?, limit? }`.

**Returns** `{ [string]: any }` — `{ rows, total, layers, revision }`.

```lua
local view = entity.tree({ filter = "crate", limit = 50 })
```

## typed/builtin//modules/api/engine/entity/entityHierarchy/swap {#typed-builtin-modules-api-engine-entity-entityhierarchy-swap}

```lua
entityHierarchy.swap(entityId: string, assetPath: string, opts: { [string]: any }?) -> (string?, string?)
```

Replace a blockout entity with a generated or imported asset, fitting the asset to the source's bounds. Answers the new entity id, or nil and an error string.

**Parameters**

- `entityId` `string`
- `assetPath` `string`
- `opts` `{ [string]: any }` _(optional)_

**Returns** `(string?, string?)`

## typed/builtin//modules/api/engine/entity/members/entityAttributes/get {#typed-builtin-modules-api-engine-entity-members-entityattributes-get}

```lua
entityAttributes.get(key: string) -> any?
```

The value stored under a key, or nil when the entity carries none.

## typed/builtin//modules/api/engine/entity/members/entityAttributes/list {#typed-builtin-modules-api-engine-entity-members-entityattributes-list}

```lua
entityAttributes.list() -> { string }
```

Every attribute key this entity carries.

**Returns** `{ string }`

## typed/builtin//modules/api/engine/entity/members/entityAttributes/remove {#typed-builtin-modules-api-engine-entity-members-entityattributes-remove}

```lua
entityAttributes.remove(key: string) -> ()
```

Drop the value stored under a key.

**Parameters**

- `key` `string`

**Returns** `()`

## typed/builtin//modules/api/engine/entity/members/entityAttributes/set {#typed-builtin-modules-api-engine-entity-members-entityattributes-set}

```lua
entityAttributes.set(key: string, value: any) -> ()
```

Store a value under a key on this entity.

## typed/builtin//modules/api/engine/entity/members/entityComponents/add {#typed-builtin-modules-api-engine-entity-members-entitycomponents-add}

```lua
entityComponents.add(type: AssetRef | string, data: table?) -> table?
```

Attach a component, answering its live public proxy — nil when the add was deferred or skipped as a duplicate.

**Parameters**

- `type` `AssetRef | string`
- `data` `table` _(optional)_

**Returns** `table?`

## typed/builtin//modules/api/engine/entity/members/entityComponents/addSynced {#typed-builtin-modules-api-engine-entity-members-entitycomponents-addsynced}

```lua
entityComponents.addSynced(type: AssetRef | string, data: table?) -> table?
```

Attach a component and replicate it to every peer.

**Parameters**

- `type` `AssetRef | string`
- `data` `table` _(optional)_

**Returns** `table?`

## typed/builtin//modules/api/engine/entity/members/entityComponents/clear {#typed-builtin-modules-api-engine-entity-members-entitycomponents-clear}

```lua
entityComponents.clear() -> ()
```

Detach every component this entity carries.

**Returns** `()`

## typed/builtin//modules/api/engine/entity/members/entityComponents/create {#typed-builtin-modules-api-engine-entity-members-entitycomponents-create}

```lua
entityComponents.create(type: AssetRef | string, data: table?) -> table?
```

Attach a fresh instance even where one of the type is already present.

**Parameters**

- `type` `AssetRef | string`
- `data` `table` _(optional)_

**Returns** `table?`

## typed/builtin//modules/api/engine/entity/members/entityComponents/get {#typed-builtin-modules-api-engine-entity-members-entitycomponents-get}

```lua
entityComponents.get(type: AssetRef | string, instanceName: string?) -> table?
```

This entity's live component proxy of the type, or nil when it carries none.

## typed/builtin//modules/api/engine/entity/members/entityComponents/getAll {#typed-builtin-modules-api-engine-entity-members-entitycomponents-getall}

```lua
entityComponents.getAll(type: (AssetRef | string)?) -> table
```

Every component on this entity, or every instance of one type.

**Parameters**

- `type` `(AssetRef | string)` _(optional)_

**Returns** `table`

## typed/builtin//modules/api/engine/entity/members/entityComponents/getFromChildren {#typed-builtin-modules-api-engine-entity-members-entitycomponents-getfromchildren}

```lua
entityComponents.getFromChildren(type: AssetRef | string) -> table?
```

The first descendant's component of the type, or nil when no descendant carries one.

**Parameters**

- `type` `AssetRef | string`

**Returns** `table?`

## typed/builtin//modules/api/engine/entity/members/entityComponents/getFromParent {#typed-builtin-modules-api-engine-entity-members-entitycomponents-getfromparent}

```lua
entityComponents.getFromParent(type: AssetRef | string) -> table?
```

The nearest ancestor's component of the type, or nil when no ancestor carries one.

**Parameters**

- `type` `AssetRef | string`

**Returns** `table?`

## typed/builtin//modules/api/engine/entity/members/entityComponents/has {#typed-builtin-modules-api-engine-entity-members-entitycomponents-has}

```lua
entityComponents.has(type: AssetRef | string) -> boolean
```

Whether this entity carries a component of the type.

**Parameters**

- `type` `AssetRef | string`

**Returns** `boolean`

## typed/builtin//modules/api/engine/entity/members/entityComponents/list {#typed-builtin-modules-api-engine-entity-members-entitycomponents-list}

```lua
entityComponents.list() -> table
```

The component types this entity carries.

**Returns** `table`

## typed/builtin//modules/api/engine/entity/members/entityComponents/lock {#typed-builtin-modules-api-engine-entity-members-entitycomponents-lock}

```lua
entityComponents.lock(names: { string } | string, flags: { [string]: any }?) -> ()
```

Lock named components on this entity against removal or writes.

**Parameters**

- `names` `{ string } | string`
- `flags` `{ [string]: any }` _(optional)_

**Returns** `()`

## typed/builtin//modules/api/engine/entity/members/entityComponents/locks {#typed-builtin-modules-api-engine-entity-members-entitycomponents-locks}

```lua
entityComponents.locks() -> { [string]: any }
```

The lock state of this entity's components.

**Returns** `{ [string]: any }`

## typed/builtin//modules/api/engine/entity/members/entityComponents/pending {#typed-builtin-modules-api-engine-entity-members-entitycomponents-pending}

```lua
entityComponents.pending(type: AssetRef | string) -> boolean
```

Whether an add of this type is queued and has not landed yet.

**Parameters**

- `type` `AssetRef | string`

**Returns** `boolean`

## typed/builtin//modules/api/engine/entity/members/entityComponents/remove {#typed-builtin-modules-api-engine-entity-members-entitycomponents-remove}

```lua
entityComponents.remove(type: AssetRef | string, instanceName: string?) -> ()
```

Detach a component, by type and optionally by instance name.

**Parameters**

- `type` `AssetRef | string`
- `instanceName` `string` _(optional)_

**Returns** `()`

## typed/builtin//modules/api/engine/entity/members/entityComponents/setEnabled {#typed-builtin-modules-api-engine-entity-members-entitycomponents-setenabled}

```lua
entityComponents.setEnabled(type: AssetRef | string, enabled: boolean) -> ()
```

Enable or disable a component without detaching it.

**Parameters**

- `type` `AssetRef | string`
- `enabled` `boolean`

**Returns** `()`

## typed/builtin//modules/api/engine/entity/members/entityComponents/unlock {#typed-builtin-modules-api-engine-entity-members-entitycomponents-unlock}

```lua
entityComponents.unlock(names: ({ string } | string)?, flags: { [string]: any }?) -> ()
```

Release locks this entity's components hold; every one of them when no name is given.

**Parameters**

- `names` `({ string } | string)` _(optional)_
- `flags` `{ [string]: any }` _(optional)_

**Returns** `()`

## typed/builtin//modules/api/engine/entity/members/entityRef/AddDebris {#typed-builtin-modules-api-engine-entity-members-entityref-adddebris}

```lua
entityRef.AddDebris(self, lifetime: number?) -> ()
```

Despawn this entity after a lifetime, defaulting to 10 seconds.

**Parameters**

- `self`
- `lifetime` `number` _(optional)_

**Returns** `()`

## typed/builtin//modules/api/engine/entity/members/entityRef/active {#typed-builtin-modules-api-engine-entity-members-entityref-active}

```lua
entityRef.active -> boolean
```

Whether this entity is active.

**Returns** `boolean`

## typed/builtin//modules/api/engine/entity/members/entityRef/activeInHierarchy {#typed-builtin-modules-api-engine-entity-members-entityref-activeinhierarchy}

```lua
entityRef.activeInHierarchy -> boolean
```

Whether this entity is active via its ancestors.

**Returns** `boolean`

## typed/builtin//modules/api/engine/entity/members/entityRef/attribute {#typed-builtin-modules-api-engine-entity-members-entityref-attribute}

```lua
entityRef.attribute() -> entityAttributes
```

Free-form key/value attributes stored on this entity.

**Returns** `entityAttributes`

## typed/builtin//modules/api/engine/entity/members/entityRef/bounds {#typed-builtin-modules-api-engine-entity-members-entityref-bounds}

```lua
entityRef.bounds(self) -> { min: any, max: any, center: any, size: any }?
```

This entity's world-axis bounding box.

**Parameters**

- `self`

**Returns** `{ min: any, max: any, center: any, size: any }?`

## typed/builtin//modules/api/engine/entity/members/entityRef/bundleLink {#typed-builtin-modules-api-engine-entity-members-entityref-bundlelink}

```lua
entityRef.bundleLink -> any?
```

This entity's link back to its bundle.

**Returns** `any?`

## typed/builtin//modules/api/engine/entity/members/entityRef/bundleProvenance {#typed-builtin-modules-api-engine-entity-members-entityref-bundleprovenance}

```lua
entityRef.bundleProvenance -> { [string]: any }?
```

Which bundle produced this entity.

**Returns** `{ [string]: any }?`

## typed/builtin//modules/api/engine/entity/members/entityRef/component {#typed-builtin-modules-api-engine-entity-members-entityref-component}

```lua
entityRef.component() -> entityComponents
```

Script components attached to this entity.

**Returns** `entityComponents`

## typed/builtin//modules/api/engine/entity/members/entityRef/despawn {#typed-builtin-modules-api-engine-entity-members-entityref-despawn}

```lua
entityRef.despawn(self) -> ()
```

Remove this entity from the scene.

**Parameters**

- `self`

**Returns** `()`

## typed/builtin//modules/api/engine/entity/members/entityRef/destroy {#typed-builtin-modules-api-engine-entity-members-entityref-destroy}

```lua
entityRef.destroy(self) -> ()
```

Remove this entity from the scene.

**Parameters**

- `self`

**Returns** `()`

## typed/builtin//modules/api/engine/entity/members/entityRef/duplicate {#typed-builtin-modules-api-engine-entity-members-entityref-duplicate}

```lua
entityRef.duplicate(self, name: string?, opts: { [string]: any }?) -> string?
```

Copy this entity.

**Parameters**

- `self`
- `name` `string` _(optional)_
- `opts` `{ [string]: any }` _(optional)_

**Returns** `string?`

## typed/builtin//modules/api/engine/entity/members/entityRef/eulerAngles {#typed-builtin-modules-api-engine-entity-members-entityref-eulerangles}

```lua
entityRef.eulerAngles -> { [string]: any }
```

World rotation, as euler degrees.

**Returns** `{ [string]: any }`

## typed/builtin//modules/api/engine/entity/members/entityRef/exists {#typed-builtin-modules-api-engine-entity-members-entityref-exists}

```lua
entityRef.exists -> boolean
```

Whether this entity is still in the world. Never raises — a proxy over an id nothing carries reads false.

**Returns** `boolean`

## typed/builtin//modules/api/engine/entity/members/entityRef/getChildren {#typed-builtin-modules-api-engine-entity-members-entityref-getchildren}

```lua
entityRef.getChildren(self) -> { entityRef }
```

This entity's direct children.

**Parameters**

- `self`

**Returns** `{ entityRef }`

## typed/builtin//modules/api/engine/entity/members/entityRef/getDescendants {#typed-builtin-modules-api-engine-entity-members-entityref-getdescendants}

```lua
entityRef.getDescendants(self) -> { entityRef }
```

Every entity below this one.

**Parameters**

- `self`

**Returns** `{ entityRef }`

## typed/builtin//modules/api/engine/entity/members/entityRef/getParent {#typed-builtin-modules-api-engine-entity-members-entityref-getparent}

```lua
entityRef.getParent(self) -> entityRef?
```

This entity's parent, or nil.

**Parameters**

- `self`

**Returns** `entityRef?`

## typed/builtin//modules/api/engine/entity/members/entityRef/hide {#typed-builtin-modules-api-engine-entity-members-entityref-hide}

```lua
entityRef.hide(self) -> ()
```

Stop drawing this entity.

**Parameters**

- `self`

**Returns** `()`

## typed/builtin//modules/api/engine/entity/members/entityRef/hierarchyBounds {#typed-builtin-modules-api-engine-entity-members-entityref-hierarchybounds}

```lua
entityRef.hierarchyBounds(self) -> { min: any, max: any, center: any, size: any }?
```

The world-axis box around this entity's subtree.

**Parameters**

- `self`

**Returns** `{ min: any, max: any, center: any, size: any }?`

## typed/builtin//modules/api/engine/entity/members/entityRef/id {#typed-builtin-modules-api-engine-entity-members-entityref-id}

```lua
entityRef.id -> string
```

This entity's id string.

## typed/builtin//modules/api/engine/entity/members/entityRef/internal {#typed-builtin-modules-api-engine-entity-members-entityref-internal}

```lua
entityRef.internal -> boolean
```

Whether default listings skip this entity.

**Returns** `boolean`

## typed/builtin//modules/api/engine/entity/members/entityRef/isLocal {#typed-builtin-modules-api-engine-entity-members-entityref-islocal}

```lua
entityRef.isLocal(self) -> boolean
```

Whether this peer owns this entity.

**Parameters**

- `self`

**Returns** `boolean`

## typed/builtin//modules/api/engine/entity/members/entityRef/localEulerAngles {#typed-builtin-modules-api-engine-entity-members-entityref-localeulerangles}

```lua
entityRef.localEulerAngles -> { [string]: any }
```

Parent-relative euler degrees.

**Returns** `{ [string]: any }`

## typed/builtin//modules/api/engine/entity/members/entityRef/localPosition {#typed-builtin-modules-api-engine-entity-members-entityref-localposition}

```lua
entityRef.localPosition -> { [string]: any }
```

Parent-relative position.

**Returns** `{ [string]: any }`

## typed/builtin//modules/api/engine/entity/members/entityRef/localRotation {#typed-builtin-modules-api-engine-entity-members-entityref-localrotation}

```lua
entityRef.localRotation -> { [string]: any }
```

Parent-relative rotation quaternion.

**Returns** `{ [string]: any }`

## typed/builtin//modules/api/engine/entity/members/entityRef/localScale {#typed-builtin-modules-api-engine-entity-members-entityref-localscale}

```lua
entityRef.localScale -> { [string]: any }
```

Parent-relative scale.

**Returns** `{ [string]: any }`

## typed/builtin//modules/api/engine/entity/members/entityRef/lock {#typed-builtin-modules-api-engine-entity-members-entityref-lock}

```lua
entityRef.lock(self) -> ()
```

Set this entity's destroy lock.

**Parameters**

- `self`

**Returns** `()`

## typed/builtin//modules/api/engine/entity/members/entityRef/lock_components {#typed-builtin-modules-api-engine-entity-members-entityref-lock-components}

```lua
entityRef.lock_components(self, names: { string }, flags: { [string]: any }?) -> ()
```

Lock named components on this entity.

**Parameters**

- `self`
- `names` `{ string }`
- `flags` `{ [string]: any }` _(optional)_

**Returns** `()`

## typed/builtin//modules/api/engine/entity/members/entityRef/locked {#typed-builtin-modules-api-engine-entity-members-entityref-locked}

```lua
entityRef.locked -> boolean
```

Whether this entity carries a destroy lock.

**Returns** `boolean`

## typed/builtin//modules/api/engine/entity/members/entityRef/locks {#typed-builtin-modules-api-engine-entity-members-entityref-locks}

```lua
entityRef.locks(self) -> { destroy: boolean, components: { [string]: any } }
```

This entity's current lock state.

**Parameters**

- `self`

**Returns** `{ destroy: boolean, components: { [string]: any } }`

## typed/builtin//modules/api/engine/entity/members/entityRef/lookAt {#typed-builtin-modules-api-engine-entity-members-entityref-lookat}

```lua
entityRef.lookAt(self, target: any, up: any?) -> (boolean, string?)
```

Aim this entity at a world point: writes the world rotation whose forward points at the target. Takes three coordinates, one point table or vec handle, or an entity by id, name or proxy. The optional `up` decides the roll around the aim.

**Parameters**

- `self`
- `target` `any`
- `up` `any` _(optional)_

**Returns** `(boolean, string?)`

## typed/builtin//modules/api/engine/entity/members/entityRef/lossyScale {#typed-builtin-modules-api-engine-entity-members-entityref-lossyscale}

```lua
entityRef.lossyScale -> { [string]: any }
```

World scale, as the hierarchy leaves it.

**Returns** `{ [string]: any }`

## typed/builtin//modules/api/engine/entity/members/entityRef/name {#typed-builtin-modules-api-engine-entity-members-entityref-name}

```lua
entityRef.name -> string
```

This entity's Name component value.

**Returns** `string`

## typed/builtin//modules/api/engine/entity/members/entityRef/networkScope {#typed-builtin-modules-api-engine-entity-members-entityref-networkscope}

```lua
entityRef.networkScope -> string
```

How far this entity replicates.

**Returns** `string`

## typed/builtin//modules/api/engine/entity/members/entityRef/orientedBounds {#typed-builtin-modules-api-engine-entity-members-entityref-orientedbounds}

```lua
entityRef.orientedBounds(self) -> { min: any, max: any, center: any, size: any }?
```

The subtree's extents in this entity's own frame.

**Parameters**

- `self`

**Returns** `{ min: any, max: any, center: any, size: any }?`

## typed/builtin//modules/api/engine/entity/members/entityRef/origin {#typed-builtin-modules-api-engine-entity-members-entityref-origin}

```lua
entityRef.origin -> string
```

What produced this entity.

**Returns** `string`

## typed/builtin//modules/api/engine/entity/members/entityRef/owner {#typed-builtin-modules-api-engine-entity-members-entityref-owner}

```lua
entityRef.owner(self) -> number
```

The peer owning this entity.

**Parameters**

- `self`

**Returns** `number`

## typed/builtin//modules/api/engine/entity/members/entityRef/participation {#typed-builtin-modules-api-engine-entity-members-entityref-participation}

```lua
entityRef.participation -> string
```

This entity's runtime participation.

**Returns** `string`

## typed/builtin//modules/api/engine/entity/members/entityRef/position {#typed-builtin-modules-api-engine-entity-members-entityref-position}

```lua
entityRef.position -> { [string]: any }
```

World position.

**Returns** `{ [string]: any }`

## typed/builtin//modules/api/engine/entity/members/entityRef/rename {#typed-builtin-modules-api-engine-entity-members-entityref-rename}

```lua
entityRef.rename(self, newName: string) -> ()
```

Change this entity's Name component.

**Parameters**

- `self`
- `newName` `string`

**Returns** `()`

## typed/builtin//modules/api/engine/entity/members/entityRef/renderLayer {#typed-builtin-modules-api-engine-entity-members-entityref-renderlayer}

```lua
entityRef.renderLayer -> string
```

The render layers this entity is on, space-separated.

**Returns** `string`

## typed/builtin//modules/api/engine/entity/members/entityRef/rotation {#typed-builtin-modules-api-engine-entity-members-entityref-rotation}

```lua
entityRef.rotation -> { [string]: any }
```

World rotation, as a quaternion.

**Returns** `{ [string]: any }`

## typed/builtin//modules/api/engine/entity/members/entityRef/saveAs {#typed-builtin-modules-api-engine-entity-members-entityref-saveas}

```lua
entityRef.saveAs(self, name: string) -> any
```

Save this entity as a content asset.

**Parameters**

- `self`
- `name` `string`

**Returns** `any`

## typed/builtin//modules/api/engine/entity/members/entityRef/setActive {#typed-builtin-modules-api-engine-entity-members-entityref-setactive}

```lua
entityRef.setActive(self, active: boolean) -> ()
```

Set whether this entity is active.

**Parameters**

- `self`
- `active` `boolean`

**Returns** `()`

## typed/builtin//modules/api/engine/entity/members/entityRef/setInternal {#typed-builtin-modules-api-engine-entity-members-entityref-setinternal}

```lua
entityRef.setInternal(self, internal: boolean) -> ()
```

Set whether default listings skip this entity.

**Parameters**

- `self`
- `internal` `boolean`

**Returns** `()`

## typed/builtin//modules/api/engine/entity/members/entityRef/setNetworkScope {#typed-builtin-modules-api-engine-entity-members-entityref-setnetworkscope}

```lua
entityRef.setNetworkScope(self, scope: string) -> ()
```

Set how far this entity replicates.

**Parameters**

- `self`
- `scope` `string`

**Returns** `()`

## typed/builtin//modules/api/engine/entity/members/entityRef/setParent {#typed-builtin-modules-api-engine-entity-members-entityref-setparent}

```lua
entityRef.setParent(self, parentId: string, opts: { [string]: any }?) -> ()
```

Reparent this entity.

**Parameters**

- `self`
- `parentId` `string`
- `opts` `{ [string]: any }` _(optional)_

**Returns** `()`

## typed/builtin//modules/api/engine/entity/members/entityRef/setParticipation {#typed-builtin-modules-api-engine-entity-members-entityref-setparticipation}

```lua
entityRef.setParticipation(self, mode: string) -> ()
```

Set this entity's runtime participation.

**Parameters**

- `self`
- `mode` `string`

**Returns** `()`

## typed/builtin//modules/api/engine/entity/members/entityRef/setRenderLayer {#typed-builtin-modules-api-engine-entity-members-entityref-setrenderlayer}

```lua
entityRef.setRenderLayer(self, names: any) -> ()
```

Set this entity's render layer.

**Parameters**

- `self`
- `names` `any`

**Returns** `()`

## typed/builtin//modules/api/engine/entity/members/entityRef/setRenderLayerTree {#typed-builtin-modules-api-engine-entity-members-entityref-setrenderlayertree}

```lua
entityRef.setRenderLayerTree(self, names: any) -> ()
```

Set render layer for this entity and its descendants.

**Parameters**

- `self`
- `names` `any`

**Returns** `()`

## typed/builtin//modules/api/engine/entity/members/entityRef/setRenderLayers {#typed-builtin-modules-api-engine-entity-members-entityref-setrenderlayers}

```lua
entityRef.setRenderLayers(self, names: any) -> ()
```

Set this entity's render layers.

**Parameters**

- `self`
- `names` `any`

**Returns** `()`

## typed/builtin//modules/api/engine/entity/members/entityRef/setSessionScoped {#typed-builtin-modules-api-engine-entity-members-entityref-setsessionscoped}

```lua
entityRef.setSessionScoped(self, scoped: boolean) -> ()
```

Scope this entity to the session.

**Parameters**

- `self`
- `scoped` `boolean`

**Returns** `()`

## typed/builtin//modules/api/engine/entity/members/entityRef/setSynced {#typed-builtin-modules-api-engine-entity-members-entityref-setsynced}

```lua
entityRef.setSynced(self, synced: boolean) -> ()
```

Set whether this entity replicates.

**Parameters**

- `self`
- `synced` `boolean`

**Returns** `()`

## typed/builtin//modules/api/engine/entity/members/entityRef/setSyncedTree {#typed-builtin-modules-api-engine-entity-members-entityref-setsyncedtree}

```lua
entityRef.setSyncedTree(self, synced: boolean) -> ()
```

Set replication for this entity and its descendants.

**Parameters**

- `self`
- `synced` `boolean`

**Returns** `()`

## typed/builtin//modules/api/engine/entity/members/entityRef/setTemporary {#typed-builtin-modules-api-engine-entity-members-entityref-settemporary}

```lua
entityRef.setTemporary(self, temporary: boolean) -> ()
```

Set whether saves skip this entity.

**Parameters**

- `self`
- `temporary` `boolean`

**Returns** `()`

## typed/builtin//modules/api/engine/entity/members/entityRef/show {#typed-builtin-modules-api-engine-entity-members-entityref-show}

```lua
entityRef.show(self) -> ()
```

Resume drawing this entity.

**Parameters**

- `self`

**Returns** `()`

## typed/builtin//modules/api/engine/entity/members/entityRef/synced {#typed-builtin-modules-api-engine-entity-members-entityref-synced}

```lua
entityRef.synced -> boolean
```

Whether this entity replicates.

**Returns** `boolean`

## typed/builtin//modules/api/engine/entity/members/entityRef/temporary {#typed-builtin-modules-api-engine-entity-members-entityref-temporary}

```lua
entityRef.temporary -> boolean
```

Whether saves skip this entity.

**Returns** `boolean`

## typed/builtin//modules/api/engine/entity/members/entityRef/temporaryInHierarchy {#typed-builtin-modules-api-engine-entity-members-entityref-temporaryinhierarchy}

```lua
entityRef.temporaryInHierarchy -> boolean
```

Whether saves skip this entity via an ancestor.

**Returns** `boolean`

## typed/builtin//modules/api/engine/entity/members/entityRef/transform {#typed-builtin-modules-api-engine-entity-members-entityref-transform}

```lua
entityRef.transform -> { [string]: any }
```

This entity's transform.

**Returns** `{ [string]: any }`

## typed/builtin//modules/api/engine/entity/members/entityRef/unlock {#typed-builtin-modules-api-engine-entity-members-entityref-unlock}

```lua
entityRef.unlock(self) -> ()
```

Clear every lock on this entity.

**Parameters**

- `self`

**Returns** `()`

## typed/builtin//modules/api/engine/entity/members/entityRef/unparent {#typed-builtin-modules-api-engine-entity-members-entityref-unparent}

```lua
entityRef.unparent(self, opts: { [string]: any }?) -> ()
```

Detach this entity from its parent.

**Parameters**

- `self`
- `opts` `{ [string]: any }` _(optional)_

**Returns** `()`

## typed/builtin//modules/api/engine/entity/members/entityRef/worldMatrix {#typed-builtin-modules-api-engine-entity-members-entityref-worldmatrix}

```lua
entityRef.worldMatrix -> { number }
```

This entity's world matrix.

**Returns** `{ number }`

## typed/builtin//modules/api/engine/entity/ref/M/build {#typed-builtin-modules-api-engine-entity-ref-m-build}

```lua
M.build(id: string) -> EntityRef
```

Factory that backs `entity(id)`. Returns a cached proxy when one already exists for `id`; otherwise allocates and caches a fresh one. The cache is weak-valued so unreferenced proxies are GC'd.

**Parameters**

- `id` `string` — The entity id string.

**Returns** `EntityRef` — The (cached) entity proxy — an `EntityRef`.

```lua
local proxy = EntityProxy.build("some-entity-id")
```

## typed/builtin//modules/api/engine/environment/environment/capture {#typed-builtin-modules-api-engine-environment-environment-capture}

```lua
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.

**Parameters**

- `x` `number` — World X of the capture position.
- `y` `number` — World Y of the capture position.
- `z` `number` — World Z of the capture position.

**Returns** `boolean` — True — the capture was queued.

```lua
environment.capture(0, 2, 0)
```

## typed/builtin//modules/api/engine/environment/environment/captureSky {#typed-builtin-modules-api-engine-environment-environment-capturesky}

```lua
environment.captureSky(x: number?, y: number?, z: number?) -> boolean
```

Render the SKY alone into the environment's sky slot from `(x, y, z)` and
arm the sky fallback. A reflective surface no probe covers then reflects the
sky rather than black, and a partially covered one blends the shortfall
against it. The capture holds whatever the scene's sky draws — a gradient, a
physical atmosphere, a skybox material — with no geometry in it, so it stays
correct wherever the camera goes. Once captured, the slot follows the sky
the scene draws: a sky that changes is recaptured from the same position.
Queued — takes effect on the next frame.

**Parameters**

- `x` `number` _(optional)_ — World X of the capture position. Defaults to 0.
- `y` `number` _(optional)_ — World Y of the capture position — the altitude a height-dependent
atmosphere is sampled at. Defaults to 0.
- `z` `number` _(optional)_ — World Z of the capture position. Defaults to 0.

**Returns** `boolean` — True — the sky capture was queued.

```lua
environment.captureSky()
```

## typed/builtin//modules/api/engine/environment/environment/captureSlot {#typed-builtin-modules-api-engine-environment-environment-captureslot}

```lua
environment.captureSlot(slot: number, x: number, y: number, z: number) -> boolean
```

Bake the scene into reflection-probe `slot` 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.

**Parameters**

- `slot` `number` — Reflection-probe slot (0-based).
- `x` `number` — World X of the capture position.
- `y` `number` — World Y of the capture position.
- `z` `number` — World Z of the capture position.

**Returns** `boolean` — True — the capture was queued.

```lua
environment.captureSlot(0, 0, 2, 0)
```

## typed/builtin//modules/api/engine/environment/environment/captureSlotToAsset {#typed-builtin-modules-api-engine-environment-environment-captureslottoasset}

```lua
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.

**Parameters**

- `name` `string` — Destination asset identity (writes `/source/<name>.texture/`).
- `slot` `number` — Reflection-probe slot (0-based).
- `x` `number` — World X of the capture position.
- `y` `number` — World Y of the capture position.
- `z` `number` — World Z of the capture position.
- `timeoutFrames` `number` _(optional)_ — Optional max frames to wait for the readback (default 180).

**Returns** `(string?, string?)` — The asset path on success, or `(nil, errorMessage)` on failure.

```lua
environment.captureSlotToAsset("probe_lobby", 0, 0, 2, 0)
```

## typed/builtin//modules/api/engine/environment/environment/captureToAsset {#typed-builtin-modules-api-engine-environment-environment-capturetoasset}

```lua
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.

**Parameters**

- `name` `string` — Destination asset identity (writes `/source/<name>.texture/`).
- `x` `number` — World X of the capture position.
- `y` `number` — World Y of the capture position.
- `z` `number` — World Z of the capture position.

**Returns** `(string?, string?)` — The asset path on success, or `(nil, errorMessage)` on failure.

```lua
environment.captureToAsset("env_main", 0, 2, 0)
```

## typed/builtin//modules/api/engine/environment/environment/ensureSkyFallback {#typed-builtin-modules-api-engine-environment-environment-ensureskyfallback}

```lua
environment.ensureSkyFallback() -> boolean
```

Ensure the scene's sky is in the environment's sky slot: a reflective
surface no probe covers then reflects the sky rather than black, and a
partially covered one blends the shortfall against it. Queues a capture
when the sky slot holds none, and re-arms the fallback when a capture is
there but switched off. The engine's own state answers both questions, so
everything that stands a sky up can call this and one capture is shared
between them. Once captured, the slot follows the sky the scene draws on
its own.

**Returns** `boolean` — True if a capture was queued, false if the sky slot already holds one.

```lua
environment.ensureSkyFallback()
```

## typed/builtin//modules/api/engine/environment/environment/loadFromAsset {#typed-builtin-modules-api-engine-environment-environment-loadfromasset}

```lua
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).

**Parameters**

- `name` `string` — Source asset identity (reads `/source/<name>.texture/`).

**Returns** `(boolean, string?)` — True on success, or `(false, errorMessage)` on failure.

```lua
environment.loadFromAsset("env_main")
```

## typed/builtin//modules/api/engine/environment/environment/loadSlotFromAsset {#typed-builtin-modules-api-engine-environment-environment-loadslotfromasset}

```lua
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.

**Parameters**

- `name` `string` — Source asset identity (reads `/source/<name>.texture/`).
- `slot` `number` — Reflection-probe slot (0-based).

**Returns** `(boolean, string?)` — True on success, or `(false, errorMessage)` on failure.

```lua
environment.loadSlotFromAsset("probe_lobby", 0)
```

## typed/builtin//modules/api/engine/environment/environment/setProbes {#typed-builtin-modules-api-engine-environment-environment-setprobes}

```lua
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 is
probe slot i. Surfaces blend the probe slots by proximity to these
positions, gathering the highest `priority` first — each rank takes the
coverage the ranks above it left, so a small interior probe ranked above a
large exterior one wins outright wherever it reaches full weight. Coverage
left over reflects the sky once `captureSky` has run. Queued for next frame.

**Parameters**

- `probes` `{ any }` — Array of `{ x, y, z, radius, priority? }`, one per active probe
slot. `priority` defaults to 0.

**Returns** `boolean` — True — the probe data was queued.

```lua
environment.setProbes({ { x = 0, y = 2, z = 0, radius = 12 } })
```

## typed/builtin//modules/api/engine/environment/environment/setSkyFallback {#typed-builtin-modules-api-engine-environment-environment-setskyfallback}

```lua
environment.setSkyFallback(active: boolean) -> boolean
```

Arm or disarm the sky fallback against the sky already captured, with no
recapture. Disarmed, reflections come from the probes alone. Arming is
refused while the sky slot holds no capture (`captureSky` fills it), since
an uncaptured slot reflects black; `renderer.reflectionEnvironment()`
reports whether the fallback ended up armed.

**Parameters**

- `active` `boolean` — Whether reflections fall back to the captured sky.

**Returns** `boolean` — True — the change was queued.

```lua
environment.setSkyFallback(false)
```

## typed/builtin//modules/api/engine/font/font/glyph {#typed-builtin-modules-api-engine-font-font-glyph}

```lua
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`).

**Parameters**

- `name` `string` — Registered family name.
- `codepoint` `number` — Unicode codepoint (e.g. `string.byte("A")`).

**Returns** `any` — `{ advance, unitsPerEm, bbox = {xMin,yMin,xMax,yMax}, contours }` where each contour is `{ start = {x,y}, segments = { {kind="line|quad|cubic", ...} } }`, or nil if the font isn't registered.

```lua
local g = font.glyph("Inter", string.byte("A"))
```

## typed/builtin//modules/api/engine/font/font/list {#typed-builtin-modules-api-engine-font-font-list}

```lua
font.list() -> { string }
```

List every registered font family name.

**Returns** `{ string }` — Array of family-name strings.

```lua
for _, fam in font.list() do print(fam) end
```

## typed/builtin//modules/api/engine/font/font/observe {#typed-builtin-modules-api-engine-font-font-observe}

```lua
font.observe() -> { any }
```

What the text system is holding for fonts: one row per family the
shaper can resolve, with its face count, the numeric weights those faces
carry, whether any of them is slanted, and whether the family arrived
through a registration rather than from the platform. `weights` is what a
style's `weight` can name for that family. The same rows are `fonts` in
`text.observe()`.

**Returns** `{ any }` — Array of `{ family, faces, weights, italic, loaded }`.

```lua
for _, f in ipairs(font.observe()) do print(f.family, #f.weights) end
```

## typed/builtin//modules/api/engine/font/font/parse {#typed-builtin-modules-api-engine-font-font-parse}

```lua
font.parse(bytes: buffer | 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.

**Parameters**

- `bytes` `buffer | string` — Raw font-file bytes (binary-safe) — TTF / OTF.

**Returns** `string?` — Baked `ZFNT` payload (binary-safe string), or nil if the bytes don't parse as a font.

```lua
local zfnt = font.parse(vfs.read("/zero/source/Inter.ttf"))
```

## typed/builtin//modules/api/engine/font/font/reconcile {#typed-builtin-modules-api-engine-font-font-reconcile}

```lua
font.reconcile() -> { any }
```

Every family the text shaper can resolve, held against what the shaper
does with it. `family` is the name, `faces` how many faces of it the font
database holds, `weights` the numeric weights those faces carry, `loaded`
whether it arrived through a registration rather than from the platform,
`registered` whether content registered the name, `selectable` whether some
style naming the family reaches it, `matched` whether `fontFamily = family`
on its own reaches it — the family name at the default weight over Latin
text — `weight` the weight it needs when the default is not it, `shapedWith`
the face that answered, and `reason` why when it is not the one asked for. A
family is probed at its own weights and over content from several scripts,
so a family reachable only at one weight or covering only one script is
reported selectable, with `matched` false and `weight` naming what the style
must carry. Every probe object is destroyed again, so the live text-object
count is where it was.

**Returns** `{ any }` — Array of `{ family, faces, weights, loaded, registered, selectable, matched, weight, shapedWith, reason }`.

```lua
for _, f in ipairs(font.reconcile()) do if f.selectable and not f.matched then print(f.family, f.weight) end end
```

## typed/builtin//modules/api/engine/font/font/register {#typed-builtin-modules-api-engine-font-font-register}

```lua
font.register(name: string, zfnt: string, opts: table?) -> 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.
`opts` groups several weight/style faces under one CSS family and maps
web-font names onto it: `opts.family` is the shared group key, `opts.role`
is `"regular" | "bold" | "italic" | "bolditalic"`, and `opts.aliases` is a
list of extra selectable names (web fonts + CSS generics like `"Arial"`,
`"sans-serif"`) that resolve to this group, matched case-insensitively.
With a group set, `font-weight` / `font-style` on a `font-family` pick the
real metric-compatible face instead of a synthesized one.

**Parameters**

- `name` `string` — Family name to register under.
- `zfnt` `string` — Baked `ZFNT` payload from `font.parse` (binary-safe string).
- `opts` `table` _(optional)_ — `{ family: string?, role: string?, aliases: {string}? }` — group key,
weight/style role, and case-insensitive selectable aliases.

**Returns** `any` — `{ family, faces, glyphCount }` on success, or nil on failure.

```lua
local info = font.register("Inter", font.parse(vfs.read("/zero/source/Inter.ttf")))
```

## typed/builtin//modules/api/engine/font/font/textMesh {#typed-builtin-modules-api-engine-font-font-textmesh}

```lua
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).

**Parameters**

- `name` `string` — Registered family name.
- `text` `string` — String to lay out.
- `opts` `table` _(optional)_ — `{ size?=1, depth?=0 (extrude, EM units), tolerance?=0.0015, letterSpacing?=0, lineHeight?=0 }`.

**Returns** `any` — `{ positions, indices, normals, uvs }` as flat float / u32 arrays, or nil if the font isn't registered or the string is all whitespace.

```lua
local geom = font.textMesh("Inter", "Hello", { size = 1, depth = 0.1 })
```

## typed/builtin//modules/api/engine/frameStream/frameStream/attach {#typed-builtin-modules-api-engine-framestream-framestream-attach}

```lua
frameStream.attach(texture: string, stream: string, opts: AttachOpts?) -> (string?, string?)
```

Carry an image the GPU drew out to an open byte stream, frame
after frame. `texture` is the guid of the render target it was
drawn into — `renderer.texture.create({ width = W, height = H })`
makes one, and a Camera component draws into it as its
`textureHandle`; the session reads that target back when a frame
comes due, so what the camera drew last reaches the far end.
`stream` is a handle from `stream.open`. What reaches the stream
is one frame's pixels then the next frame's, with nothing between
them: a frame is `width * height * bytesPerPixel` bytes of tight
rows, written in a single call so a consumer reads a whole frame
or none of it. Each frame is read back off the render thread, so
the stream never holds the renderer up. `fps` caps how often a
frame is taken and defaults to one per rendered frame; `format`
accepts `"rgb24"` (3 bytes per pixel, the default) or `"rgba8"`
(4) — a call with a format outside those two raises, naming both;
`flipY` writes the last texture row first. Returns the session
handle, or nil and the reason an empty texture, a handle naming no
open stream, a stream another session already carries, or a
non-positive fps was refused with.

**Parameters**

- `texture` `string` — Guid of the render target the image was drawn into (a Camera's textureHandle).
- `stream` `string` — Stream handle from stream.open.
- `opts` `AttachOpts` _(optional)_ — Rate, pixel layout and row order (optional).

**Returns** `(string?, string?)` — Session handle, or nil and the refusal reason.

```lua
local session = frameStream.attach(rt.guid, handle, { fps = 30 })
```

## typed/builtin//modules/api/engine/frameStream/frameStream/detach {#typed-builtin-modules-api-engine-framestream-framestream-detach}

```lua
frameStream.detach(handle: string) -> boolean
```

End the session and free the staging buffers it read frames
back through. The stream stays open — whoever opened it closes it.

**Parameters**

- `handle` `string` — Session handle from frameStream.attach.

**Returns** `boolean` — True if a session was ended, false if handle already named none.

```lua
frameStream.detach(session)
```

## typed/builtin//modules/api/engine/frameStream/frameStream/list {#typed-builtin-modules-api-engine-framestream-framestream-list}

```lua
frameStream.list() -> { string }
```

Every live session handle, in a stable order.

**Returns** `{ string }` — Array of session handles.

```lua
for _, h in frameStream.list() do frameStream.detach(h) end
```

## typed/builtin//modules/api/engine/frameStream/frameStream/status {#typed-builtin-modules-api-engine-framestream-framestream-status}

```lua
frameStream.status(handle: string) -> FrameStreamStatus?
```

Report what the session has carried and lost. `frames` counts
the frames the stream accepted and `bytes` the bytes they
carried. `dropped` counts the frames it refused, of which
`droppedBackpressure` is the part refused because the consumer was
behind; `stalledReadbacks` counts the frames that came due while
every staging buffer still held a copy on its way from the GPU.
`achievedFps` is the rate the accepted frames arrived at, across
the span from the first to the most recent, and reads 0 until two
have been accepted — compare it against `requestedFps` to see a
display running slower than it was asked to. `lastOutcome` names
what became of the most recent frame offered. nil when handle
names no live session.

**Parameters**

- `handle` `string` — Session handle from frameStream.attach.

**Returns** `FrameStreamStatus?` — Session status, or nil when handle names no live session.

```lua
local s = frameStream.status(session); print(s.frames, s.dropped, s.achievedFps)
```

## typed/builtin//modules/api/engine/http/http/get_bytes {#typed-builtin-modules-api-engine-http-http-get-bytes}

```lua
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.

**Parameters**

- `url` `string` — Request URL.
- `headers` `Headers` _(optional)_ — Header key-value pairs (optional).

**Returns** `PromiseId` — Promise handle for `task.await()`.

```lua
local bytes = task.await(http.get_bytes("https://example.com/sound.ogg"))
```

## typed/builtin//modules/api/engine/http/http/get_json {#typed-builtin-modules-api-engine-http-http-get-json}

```lua
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.

**Parameters**

- `url` `string` — Request URL.
- `headers` `Headers` _(optional)_ — Header key-value pairs (optional).

**Returns** `PromiseId` — Promise handle for `task.await()`.

```lua
local data = task.await(http.get_json("https://api.example.com/info"))
```

## typed/builtin//modules/api/engine/http/http/post_bytes {#typed-builtin-modules-api-engine-http-http-post-bytes}

```lua
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).

**Parameters**

- `url` `string` — Request URL.
- `headers` `Headers` _(optional)_ — Header key-value pairs (optional).
- `body` `JsonBody` _(optional)_ — JSON body (optional).

**Returns** `PromiseId` — Promise handle for `task.await()`.

```lua
local audio = task.await(http.post_bytes(ttsUrl, nil, { text = "hello" }))
```

## typed/builtin//modules/api/engine/http/http/post_json {#typed-builtin-modules-api-engine-http-http-post-json}

```lua
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.

**Parameters**

- `url` `string` — Request URL.
- `headers` `Headers` _(optional)_ — Header key-value pairs (optional).
- `body` `JsonBody` _(optional)_ — JSON body (optional).

**Returns** `PromiseId` — Promise handle for `task.await()`.

```lua
local r = task.await(http.post_json(url, nil, { name = "Alice" }))
```

## typed/builtin//modules/api/engine/http/http/request {#typed-builtin-modules-api-engine-http-http-request}

```lua
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.

**Parameters**

- `method` `string` — HTTP verb (case-insensitive).
- `url` `string` — Request URL.
- `headers` `Headers` _(optional)_ — Header key-value pairs (optional).
- `body` `JsonBody` _(optional)_ — JSON body (optional).

**Returns** `PromiseId` — Promise handle for `task.await()`.

```lua
local w = task.await(http.request("PATCH", url, hdrs, { description = "hi" }))
```

## typed/builtin//modules/api/engine/http/http/request_raw {#typed-builtin-modules-api-engine-http-http-request-raw}

```lua
http.request_raw(method: string, url: string, headers: Headers?, body: buffer | string | nil?) -> 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.

**Parameters**

- `method` `string` — HTTP verb (case-insensitive).
- `url` `string` — Request URL.
- `headers` `Headers` _(optional)_ — Header key-value pairs (optional).
- `body` `buffer | string | nil` _(optional)_ — Raw binary request body (optional).

**Returns** `PromiseId` — Promise handle for `task.await()`.

```lua
local r = task.await(http.request_raw("POST", blobsUrl, hdrs, pngBytes))
```

## typed/builtin//modules/api/engine/httpServer/httpServer/address {#typed-builtin-modules-api-engine-httpserver-httpserver-address}

```lua
httpServer.address(path: string) -> (string?, string?)
```

The URL a path answers on — scheme, host, port and the `/app` mount,
ready to be fetched or printed for someone to open. Takes the same path
spelling `route` does, and reads the interface and port from the socket
routes answer on: the address `listen` opened while one is open, and the
engine's own server otherwise.

**Parameters**

- `path` `string` — Path under the `/app` mount, e.g. "/status".

**Returns** `(string?, string?)` — The URL, or nil plus the reason there is none — this engine holds no address, or the path is not one a route can be registered at.

```lua
print(httpServer.address("/status")) --> http://127.0.0.1:7607/app/status
```

## typed/builtin//modules/api/engine/httpServer/httpServer/listen {#typed-builtin-modules-api-engine-httpserver-httpserver-listen}

```lua
httpServer.listen(target: string) -> (HttpListener?, string?)
```

Hold an interface and port of this world's own, and answer content
routes on it.

The host in `target` is the interface bound, and the whole of what decides
who can reach those routes: `"127.0.0.1:8080"` answers programs on this
machine, `"0.0.0.0:8080"` answers any host that routes to this machine on
that port — a phone on the same wifi, and whatever else the network lets
through. Bind loopback unless you want that. A port of `0` asks the
operating system for a free one, which the returned record reports, and
`http://` may be spelled out in front.

This address serves the routes registered under the `/app` mount. The
engine's own `/engine/*` tree answers on the loopback server it booted
with, whose interface stays what the boot bound.

The address belongs to the chunk that opened it and is released when that
chunk runs again, so an edited module holds the address its current source
names. Asking for the address already held is the same address back.

**Parameters**

- `target` `string` — Interface and port to hold, e.g. "0.0.0.0:8080".

**Returns** `(HttpListener?, string?)` — The listener record, or nil plus the reason the target or the bind was refused.

```lua
local l = assert(httpServer.listen("0.0.0.0:8080"))
```

## typed/builtin//modules/api/engine/httpServer/httpServer/route {#typed-builtin-modules-api-engine-httpserver-httpserver-route}

```lua
httpServer.route(method: string, path: string, handler: HttpHandler, options: HttpRouteOptions?) -> (number?, string?)
```

Serve one method and path from this engine, answering each matching
request with `handler`.

The path is relative to the `/app` mount, and a trailing `/*` segment
matches the rest of the path — `"/files/*"` answers `/app/files/a/b`, with
`"a/b"` in `request.wildcard`. An exact path answers ahead of a wildcard,
and among wildcards the longest one wins.

One method and path is served by one handler. Registering an address
another chunk serves returns nil and a reason naming the handle and the
chunk holding it; `httpServer.routes()` finds that handle and
`httpServer.unroute` frees the address. Registering an address this same
chunk already serves takes it back and releases the handler it replaces,
so a chunk that runs twice serves the handler it just built.

The handler runs on the script thread. Raising inside it answers 500 and
writes the error to the engine log; returning something that is not a
response table or a string answers 500 saying what arrived.

**Parameters**

- `method` `string` — HTTP verb, e.g. "GET" or "POST".
- `path` `string` — Path under the `/app` mount, e.g. "/status" or "/files/*".
- `handler` `HttpHandler` — Called with the request table; returns a response table or a body string.
- `options` `HttpRouteOptions` _(optional)_ — `{ timeoutMs? }` — how long a request waits for this handler.

**Returns** `(number?, string?)` — The route handle, or nil plus the reason it was not registered.

```lua
local h = httpServer.route("GET", "/status", function(req)
```

## typed/builtin//modules/api/engine/httpServer/httpServer/routes {#typed-builtin-modules-api-engine-httpserver-httpserver-routes}

```lua
httpServer.routes() -> { HttpRoute }
```

Every route this engine currently serves, in registration order —
handle, method, registered path, the address it answers on, its full URL,
the chunk that registered it, and how long a request for it waits.

**Returns** `{ HttpRoute }` — An array of route records.

```lua
for _, r in ipairs(httpServer.routes()) do print(r.method, r.url, r.owner) end
```

## typed/builtin//modules/api/engine/httpServer/httpServer/status {#typed-builtin-modules-api-engine-httpserver-httpserver-status}

```lua
httpServer.status() -> HttpServerStatus
```

Whether this engine serves content routes, on which interface, port
and mount, who can reach them, and how many routes and waiting requests it
holds. `host`, `port`, `url` and `reach` are read from the socket routes
answer on — the one `listen` opened while one is open, and the engine's
own server otherwise — and `listeners` carries every address, each with
its own reach. When `supported` is false, `reason` says why: a browser tab
answers HTTP requests and holds no address of its own.

**Returns** `HttpServerStatus` — `{ supported, reason?, host?, port?, url?, reach?, prefix, routeCount, pending, listeners }`.

```lua
local s = httpServer.status(); print(s.url, s.reach)
```

## typed/builtin//modules/api/engine/httpServer/httpServer/unlisten {#typed-builtin-modules-api-engine-httpserver-httpserver-unlisten}

```lua
httpServer.unlisten() -> boolean
```

Release the address `listen` opened. Returns once the socket is free,
so the same port binds again straight after.

**Returns** `boolean` — True when an address was held.

```lua
httpServer.unlisten()
```

## typed/builtin//modules/api/engine/httpServer/httpServer/unroute {#typed-builtin-modules-api-engine-httpserver-httpserver-unroute}

```lua
httpServer.unroute(handle: number) -> boolean
```

Stop serving a route and release its handler. The address is free for
another registration once this returns true.

**Parameters**

- `handle` `number` — The handle `httpServer.route` returned.

**Returns** `boolean` — True when a route with this handle was registered.

```lua
httpServer.unroute(h)
```

## typed/builtin//modules/api/engine/layers/M/cost {#typed-builtin-modules-api-engine-layers-m-cost}

```lua
M.cost() -> { SceneLayerCost }
```

What each loaded scene's per-frame tick costs, attributed to the layer
that owns it — the `update` / `editorUpdate` its entrypoint declares,
timed where it runs. `totalMs` is a SUM across the window
`layers.observe().window` reports, so divide by `calls` (or read `avgMs`)
for the per-tick figure; a tick that runs every frame makes that the
per-frame figure. Call `layers.resetCostWindow()` first to time a
particular stretch. A layer whose entrypoint declares no tick is absent.

**Returns** `{ SceneLayerCost }` — An array of `SceneLayerCost`.

```lua
layers.resetCostWindow(); task.wait(1); for _, c in layers.cost() do print(c.name, c.avgMs) end
```

## typed/builtin//modules/api/engine/layers/M/find {#typed-builtin-modules-api-engine-layers-m-find}

```lua
M.find(ref: AssetRef<scene> | string) -> any?
```

The loaded layer for a scene, matched on guid — the canonical identity,
since display names can collide and paths drift when assets move. A layer
torn down but not yet pumped out of the engine's loaded list reads as gone.

**Parameters**

- `ref` `AssetRef<scene> | string` — A scene `AssetRef`, or an identity string resolved through `asset.ref`.

**Returns** `any?` — The scene proxy, or nil when that scene has no loaded layer.

```lua
local layer = layers.find("scenes.arena")
```

## typed/builtin//modules/api/engine/layers/M/fireBeforeLoad {#typed-builtin-modules-api-engine-layers-m-firebeforeload}

```lua
M.fireBeforeLoad(proxy: any?) -> nil
```

Announce that a scene layer is about to load: clears any pending
unload for that layer slot, marks the proxy loading, and fans out to every
`layers.onBeforeLoad` subscriber. The scene-load pipeline calls this.

**Parameters**

- `proxy` `any` _(optional)_ — The scene proxy about to load.

**Returns** `nil`

```lua
layers.fireBeforeLoad(sceneProxy)
```

## typed/builtin//modules/api/engine/layers/M/fireLoad {#typed-builtin-modules-api-engine-layers-m-fireload}

```lua
M.fireLoad(proxy: any?) -> nil
```

Announce that a scene layer has loaded, fanning out to every
`layers.onLoad` subscriber. The layer is pinned as the active one for the
duration of the fan-out, so entities a subscriber spawns are attributed to
it rather than landing orphaned. The scene-load pipeline calls this.

**Parameters**

- `proxy` `any` _(optional)_ — The loaded scene proxy.

**Returns** `nil`

```lua
layers.fireLoad(sceneProxy)
```

## typed/builtin//modules/api/engine/layers/M/fireUnload {#typed-builtin-modules-api-engine-layers-m-fireunload}

```lua
M.fireUnload(proxy: any?) -> nil
```

Announce that a scene layer is unloading: fans out to every
`layers.onUnload` subscriber, then drops the layer's cached proxy and
per-layer state so the next load of that scene rebuilds from disk. The
unload path calls this.

**Parameters**

- `proxy` `any` _(optional)_ — The scene proxy being unloaded.

**Returns** `nil`

```lua
layers.fireUnload(sceneProxy)
```

## typed/builtin//modules/api/engine/layers/M/install {#typed-builtin-modules-api-engine-layers-m-install}

```lua
M.install() -> nil
```

Install the `layers` global. `layers.active` is exposed as a property
whose every read resolves the current root scene, so it tracks scene
changes without manual invalidation; other keys resolve against this
module. The prelude calls this once at boot.

**Returns** `nil`

```lua
layers.install()
```

## typed/builtin//modules/api/engine/layers/M/inventory {#typed-builtin-modules-api-engine-layers-m-inventory}

```lua
M.inventory() -> { SceneLayerInventory }
```

What each loaded layer holds: the entities the engine attributes to it,
whether it came up whole, and how many failures it carries. `unattributed`
in `layers.observe().totals` counts what exists in the world that no layer
claims.

**Returns** `{ SceneLayerInventory }` — An array of `SceneLayerInventory`.

```lua
for _, l in layers.inventory() do print(l.name, l.entities, l.ok) end
```

## typed/builtin//modules/api/engine/layers/M/is_loaded {#typed-builtin-modules-api-engine-layers-m-is-loaded}

```lua
M.is_loaded(ref: AssetRef<scene> | string) -> boolean
```

Whether a scene currently has a loaded layer — the boolean form of
`layers.find`. A scene counts as loaded from the frame the engine holds a
layer slot for it — the same slot its entities are attributed to — until
an unload is issued against that slot. So a gate like
`if layers.is_loaded(ref) then layers.unload(ref) end` sees the layer on
the frame its entities exist.

**Parameters**

- `ref` `AssetRef<scene> | string` — A scene `AssetRef`, or an identity string.

**Returns** `boolean` — True when the scene is loaded as a layer.

```lua
if not layers.is_loaded("scenes.hud") then layers.load("scenes.hud", { additive = true }) end
```

## typed/builtin//modules/api/engine/layers/M/lastLoad {#typed-builtin-modules-api-engine-layers-m-lastload}

```lua
M.lastLoad() -> SceneLoadReport?
```

The most recent load's report: what it loaded, what root it replaced
and which overlays went with it, the entity counts on each side, how long
each phase took, and every failure it produced. Nil on an engine that has
loaded nothing — which is how "nothing has loaded" reads differently from
a load that changed nothing.

**Returns** `SceneLoadReport?` — A `SceneLoadReport`, or nil.

```lua
local r = layers.lastLoad(); print(r.name, r.outcome, r.entities.added)
```

## typed/builtin//modules/api/engine/layers/M/lastUnload {#typed-builtin-modules-api-engine-layers-m-lastunload}

```lua
M.lastUnload() -> SceneUnloadReport?
```

The most recent unload's report: the layer it took down under the name
it was loaded with, the overlays it cascaded, and the entities that went
with them. A guid no longer resolves to a name once its layer is gone, so
this is where that name survives.

**Returns** `SceneUnloadReport?` — A `SceneUnloadReport`, or nil.

```lua
local u = layers.lastUnload(); print(u.name, u.entities.removed)
```

## typed/builtin//modules/api/engine/layers/M/list {#typed-builtin-modules-api-engine-layers-m-list}

```lua
M.list() -> { any }
```

Every loaded scene layer as a proxy, root and additive alike, in the
order the engine reports them.

## typed/builtin//modules/api/engine/layers/M/load {#typed-builtin-modules-api-engine-layers-m-load}

```lua
M.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.

## typed/builtin//modules/api/engine/layers/M/loadHistory {#typed-builtin-modules-api-engine-layers-m-loadhistory}

```lua
M.loadHistory() -> { SceneLoadReport }
```

Every load report the engine still holds, oldest first. Bounded — old
reports fall off the front, so a long session's memory does not grow with
how many times a scene was swapped.

**Returns** `{ SceneLoadReport }` — An array of `SceneLoadReport`.

```lua
for _, r in layers.loadHistory() do print(r.name, r.durationMs) end
```

## typed/builtin//modules/api/engine/layers/M/loadInFlight {#typed-builtin-modules-api-engine-layers-m-loadinflight}

```lua
M.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.

**Returns** `number`

## typed/builtin//modules/api/engine/layers/M/observe {#typed-builtin-modules-api-engine-layers-m-observe}

```lua
M.observe() -> SceneObservation
```

What every scene load did, and what each loaded scene costs. One read
covering the last load's report (what it produced, what it replaced, what
it failed to produce and why, and how long each phase took), the load and
unload history, a per-layer inventory of what the engine attributes to
each layer, and the per-frame cost of each layer's entrypoint tick.
Answers in edit mode as well as play.

**Returns** `SceneObservation` — A `SceneObservation`.

```lua
local o = layers.observe(); print(o.lastLoad.outcome, o.lastLoad.durationMs)
for _, c in layers.observe().cost do print(c.name, c.avgMs) end
```

## typed/builtin//modules/api/engine/layers/M/offBeforeLoad {#typed-builtin-modules-api-engine-layers-m-offbeforeload}

```lua
M.offBeforeLoad(h: number) -> boolean
```

Cancel a `layers.onBeforeLoad` subscription.

**Parameters**

- `h` `number` — The handle `layers.onBeforeLoad` returned.

**Returns** `boolean` — True when a subscription was removed.

```lua
layers.offBeforeLoad(h)
```

## typed/builtin//modules/api/engine/layers/M/offEntityChanged {#typed-builtin-modules-api-engine-layers-m-offentitychanged}

```lua
M.offEntityChanged(h: number) -> boolean
```

Remove a subscription made with `layers.onEntityChanged`.

**Parameters**

- `h` `number` — The handle returned by `layers.onEntityChanged`.

**Returns** `boolean` — True when the subscription existed and was removed.

```lua
layers.offEntityChanged(handle)
```

## typed/builtin//modules/api/engine/layers/M/offLoad {#typed-builtin-modules-api-engine-layers-m-offload}

```lua
M.offLoad(h: number) -> boolean
```

Cancel a `layers.onLoad` subscription.

**Parameters**

- `h` `number` — The handle `layers.onLoad` returned.

**Returns** `boolean` — True when a subscription was removed.

```lua
layers.offLoad(h)
```

## typed/builtin//modules/api/engine/layers/M/offUnload {#typed-builtin-modules-api-engine-layers-m-offunload}

```lua
M.offUnload(h: number) -> boolean
```

Cancel a `layers.onUnload` subscription.

**Parameters**

- `h` `number` — The handle `layers.onUnload` returned.

**Returns** `boolean` — True when a subscription was removed.

```lua
layers.offUnload(h)
```

## typed/builtin//modules/api/engine/layers/M/onBeforeLoad {#typed-builtin-modules-api-engine-layers-m-onbeforeload}

```lua
M.onBeforeLoad(cb: (any) -> ()) -> number
```

Run a callback just before a scene layer loads, while the previous
layer's entities are still present.

**Parameters**

- `cb` `(any) -> ()` — Receives the scene proxy about to load.

**Returns** `number` — A handle to pass to `layers.offBeforeLoad`.

```lua
local h = layers.onBeforeLoad(function(scene) print("loading", scene.name) end)
```

## typed/builtin//modules/api/engine/layers/M/onEntityChanged {#typed-builtin-modules-api-engine-layers-m-onentitychanged}

```lua
M.onEntityChanged(cb: (any) -> ()) -> number
```

Subscribe to authored entity changes. The callback runs once per
frame with every entity edited since the previous frame, batched by
layer as `{ { scene = string, entities = { string } } }` — a moved
transform, an edited component field, a spawn, or a despawn (the id
of a despawned entity arrives with `entity.exists` already false).
Any number of subscribers can watch the same edits.

Scope: authored edits in edit mode — what lands in the scene's dirty
overlay. Mutations a component makes from its own `update` are runtime
behavior and do not appear, so a subscriber that rebuilds derived data
cannot re-trigger itself.

**Parameters**

- `cb` `(any) -> ()` — Called with the change batch.

**Returns** `number` — A handle for `layers.offEntityChanged`.

```lua
layers.onEntityChanged(function(batch)
for _, row in ipairs(batch) do
for _, id in ipairs(row.entities) do rebuild(id) end
end
end)
```

## typed/builtin//modules/api/engine/layers/M/onLoad {#typed-builtin-modules-api-engine-layers-m-onload}

```lua
M.onLoad(cb: (any) -> ()) -> number
```

Run a callback once a scene layer has loaded — the point where its
entities exist and player / camera spawners can attach to them.

**Parameters**

- `cb` `(any) -> ()` — Receives the loaded scene proxy.

**Returns** `number` — A handle to pass to `layers.offLoad`.

```lua
local h = layers.onLoad(function(scene) spawnPlayerFor(scene) end)
```

## typed/builtin//modules/api/engine/layers/M/onUnload {#typed-builtin-modules-api-engine-layers-m-onunload}

```lua
M.onUnload(cb: (any) -> ()) -> number
```

Run a callback as a scene layer unloads, while its entities are still
addressable — the place to release anything keyed to them.

**Parameters**

- `cb` `(any) -> ()` — Receives the scene proxy being unloaded.

**Returns** `number` — A handle to pass to `layers.offUnload`.

```lua
local h = layers.onUnload(function(scene) releaseHandlesFor(scene) end)
```

## typed/builtin//modules/api/engine/layers/M/problems {#typed-builtin-modules-api-engine-layers-m-problems}

```lua
M.problems(ref: (AssetRef<scene> | string | any)?) -> { SceneLoadFailure }
```

What a layer failed to produce, and why. Each entry names the phase it
happened in, one reason from the closed set, and the engine's own words —
plus the entity, component or lifecycle hook it is about when it is about
one.

**Parameters**

- `ref` `(AssetRef<scene> | string | any)` _(optional)_ — A scene `AssetRef`, an identity string, or a scene proxy. Omit for
the active root layer.

**Returns** `{ SceneLoadFailure }` — An array of `SceneLoadFailure` — empty for a layer that came up whole.

```lua
for _, f in layers.problems() do print(f.reason, f.entity, f.message) end
```

## typed/builtin//modules/api/engine/layers/M/rebuildInFlight {#typed-builtin-modules-api-engine-layers-m-rebuildinflight}

```lua
M.rebuildInFlight() -> boolean
```

Whether the engine is rebuilding the live scene right now — a scene
load is carrying entities in, or an edit↔play flip's transition is
materialising the layer set. A flip unloads the root layer and loads it
again for the new mode across many frames, and each mode materialises a
different set of entities, so the live entities are a stage of a scene
being built while this reads true. A caller whose answer belongs to the
settled scene — a test taking a root, a validator judging the live tree —
polls it down to false first.

**Returns** `boolean` — true while a load or a mode-flip transition is converging.

```lua
if not layers.rebuildInFlight() then judge(layers.active) end
```

## typed/builtin//modules/api/engine/layers/M/reload {#typed-builtin-modules-api-engine-layers-m-reload}

```lua
M.reload(ref: (AssetRef<scene> | string)?) -> any?
```

Unload and re-load a scene layer in place, so an edited scene asset
takes effect without rebuilding the surrounding layer stack. The scene's
`build.luau` runs against what it resolves right now, so a build script
whose inputs moved — a component that now exists, an asset that now
resolves — produces the scene it describes today.

**Parameters**

- `ref` `(AssetRef<scene> | string)` _(optional)_ — A scene `AssetRef`, or an identity string. Omit to reload the active
root scene.

**Returns** `any?` — What the scene's `build.luau` did — `{ built = true, content, editorOnly }` with the entity counts each half placed, carrying `refused` and a `message` reading them out when an operation the build ran was refused, or `{ built = false, reason, message }` naming what stood in the way. Nil when no layer matched, which is a no-op.

```lua
layers.reload("scenes.arena")
```

## typed/builtin//modules/api/engine/layers/M/resetCostWindow {#typed-builtin-modules-api-engine-layers-m-resetcostwindow}

```lua
M.resetCostWindow() -> nil
```

Open a new cost window, discarding what the previous one measured. Call
this before timing a stretch of frames; the load history is untouched.

**Returns** `nil`

```lua
layers.resetCostWindow()
```

## typed/builtin//modules/api/engine/layers/M/unload {#typed-builtin-modules-api-engine-layers-m-unload}

```lua
M.unload(refOrProxy: (AssetRef<scene> | string | any)?) -> nil
```

Unload a scene layer. Unloading the root cascades through its additive
overlays first, most-recently-loaded first, so none is left as a layer the
engine still lists after its entities are gone; persistent additive layers
survive the cascade. A scene with no loaded layer is a no-op.

**Parameters**

- `refOrProxy` `(AssetRef<scene> | string | any)` _(optional)_ — A scene `AssetRef`, an identity string, or a scene proxy.
Omit to unload the active root scene.

**Returns** `nil`

```lua
layers.unload("scenes.hud")
layers.unload() -- the active root, plus its non-persistent overlays
```

## typed/builtin//modules/api/engine/layers/M/whyPartial {#typed-builtin-modules-api-engine-layers-m-whypartial}

```lua
M.whyPartial(ref: (AssetRef<scene> | string | any)?) -> (string?, string?)
```

Why a layer is not whole. Returns nil when it IS — everything the scene
declared was produced — and otherwise the nearest cause from the closed set
`loaderRaised`, `entrypointCompileFailed`, `entrypointBodyRaised`,
`entrypointRaised`, `buildRaised`, `entityFailed`, `parentMissing`,
`parentRefused`, `parentAbandoned`, `componentUnresolved`,
`componentRefused`, `subscriberRaised`, `updateRaised`. A second return
carries the engine's own words for that cause.

**Parameters**

- `ref` `(AssetRef<scene> | string | any)` _(optional)_ — A scene `AssetRef`, an identity string, or a scene proxy. Omit for
the active root layer.

**Returns** `(string?, string?)` — `(reason, detail)`.

```lua
local why, detail = layers.whyPartial(); if why then print(why, detail) end
```

## typed/builtin//modules/api/engine/layers/layers/active {#typed-builtin-modules-api-engine-layers-layers-active}

```lua
layers.active -> any
```

The root scene's proxy, re-resolved on every read.

**Returns** `any`

## typed/builtin//modules/api/engine/layers/layers/camera {#typed-builtin-modules-api-engine-layers-layers-camera}

```lua
layers.camera -> any
```

The active root scene's camera handle, the same value `layers.active.camera` answers.

**Returns** `any`

## typed/builtin//modules/api/engine/layers/layers/localPlayer {#typed-builtin-modules-api-engine-layers-layers-localplayer}

```lua
layers.localPlayer -> any
```

The active root scene's local player handle, the same value `layers.active.players.localPlayer` answers.

**Returns** `any`

## typed/builtin//modules/api/engine/library/library/has {#typed-builtin-modules-api-engine-library-library-has}

```lua
library.has(path: string) -> boolean
```

Check if a library asset exists at the given path.

**Parameters**

- `path` `string` — Library asset path (e.g. "@builtin/models/Sample/DamagedHelmet").

**Returns** `boolean` — True if the asset exists in the library.

```lua
assert(library.has("@builtin/models/Cube"))
```

## typed/builtin//modules/api/engine/library/library/import {#typed-builtin-modules-api-engine-library-library-import}

```lua
library.import(namespace: string, worldRef: string) -> LibraryImport
```

Import another world as a library under the given namespace.
Resolves the world, pins its current commit, and writes the
library marker at `/source/libs/@<namespace>`. Once the engine has
fetched the pinned commit, the imported tree answers to
`require("@<namespace>::path")`, is listed by `library.list()`, and
is readable under `/zero/source/libs/@<namespace>/`.

**Parameters**

- `namespace` `string` — Library namespace, with or without the leading `@`
(e.g. `"@mylib"` or `"mylib"`).
- `worldRef` `string` — The upstream world's guid, or its name as it appears
in `world.list()`.

**Returns** `LibraryImport` — Record describing the import: the local `name`, the marker `path`, the upstream `world_guid`, and the pinned commit as `version`.

```lua
library.import("@mylib", "my-shared-world")
```

## typed/builtin//modules/api/engine/library/library/list {#typed-builtin-modules-api-engine-library-library-list}

```lua
library.list(assetType: string?) -> { LibraryAsset }
```

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

## typed/builtin//modules/api/engine/logs/logs/clear {#typed-builtin-modules-api-engine-logs-logs-clear}

```lua
logs.clear() -> boolean
```

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

**Returns** `boolean` — True on success.

```lua
logs.clear()
```

## typed/builtin//modules/api/engine/logs/logs/count {#typed-builtin-modules-api-engine-logs-logs-count}

```lua
logs.count(opts: LogQueryOpts?) -> 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. `opts` takes the same filter table
as `logs.query`, and `matched` is how many held entries it selects,
counted without materialising them — `limit` and `newest_first` bound
and order what a query RETURNS, so they leave `matched` alone. `mcp`
is how many held entries record your own tool traffic; a query leaves
those out, so with no `opts`, `matched` + `mcp` is everything held.
`last_seq` is the cursor for
incremental polling: read it before an action, then pass it as
`logs.query({ since = <that> })` afterwards to see only what the
action logged.

**Parameters**

- `opts` `LogQueryOpts` _(optional)_ — Filter options, as `logs.query` takes.

**Returns** `LogCounts` — Counts summary table.

```lua
print("errors:", logs.count().errors)
local before = logs.count().last_seq
```

## typed/builtin//modules/api/engine/logs/logs/errors {#typed-builtin-modules-api-engine-logs-logs-errors}

```lua
logs.errors(limit: number?) -> { LogEntry }
```

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

**Parameters**

- `limit` `number` _(optional)_ — Maximum entries to return.

**Returns** `{ LogEntry }` — Array of ERROR log-entry tables.

```lua
for _, e in ipairs(logs.errors(20)) do print(e.message) end
```

## typed/builtin//modules/api/engine/logs/logs/find {#typed-builtin-modules-api-engine-logs-logs-find}

```lua
logs.find(text: string, limit: number?) -> { LogEntry }
```

Case-insensitive substring search over log messages. `limit`
defaults to 200 (keeps the most recent matches). Searches what the
engine logged, so looking for a marker cannot return the call that
looked for it; `logs.query({ contains = ..., include_mcp = true })`
searches your own tool traffic too.

**Parameters**

- `text` `string` — Substring to search for.
- `limit` `number` _(optional)_ — Maximum entries to return.

**Returns** `{ LogEntry }` — Array of matching log-entry tables in chronological order.

```lua
local hits = logs.find("MY_MARKER")
```

## typed/builtin//modules/api/engine/logs/logs/query {#typed-builtin-modules-api-engine-logs-logs-query}

```lua
logs.query(opts: LogQueryOpts?) -> { LogEntry }
```

Query the engine's in-memory log ring — the filtered view of what
also reads as plain text at `/zero/runtime/logs/engine`. Answers about what the
engine logged: the MCP record of your own tool traffic is left out,
because the call carrying the query is one of those records and an
unqualified search would match itself. `type = "MCP"` selects them;
`include_mcp = true` mixes them in with everything else. On a world
several sessions share, `origin = "local"` narrows the answer to the
lines this session's own authoring caused.

**Parameters**

- `opts` `LogQueryOpts` _(optional)_ — Filter options.

**Returns** `{ LogEntry }` — Array of matching log-entry tables.

```lua
logs.query({ entity = "guard-1", limit = 20 })
logs.query({ level = "error", context = 3 })
for _, e in ipairs(logs.query({ level = "warn", limit = 50 })) do print(e.message) end
```

## typed/builtin//modules/api/engine/logs/logs/tail {#typed-builtin-modules-api-engine-logs-logs-tail}

```lua
logs.tail(limit: number?) -> { LogEntry }
```

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

**Parameters**

- `limit` `number` _(optional)_ — Maximum entries to return.

**Returns** `{ LogEntry }` — Array of the most recent log-entry tables.

```lua
for _, e in ipairs(logs.tail(20)) do print(e.level, e.message) end
```

## typed/builtin//modules/api/engine/logs/logs/template {#typed-builtin-modules-api-engine-logs-logs-template}

```lua
logs.template(message: string) -> string
```

Normalize a message to its template — the same line with the parts
that vary between occurrences (numbers, hashes, entity ids) masked out.
Two messages that differ only in those parts share a template, which is
what turns "this error repeated 400 times" into one row instead of 400.
The engine keys its own error retention by the same normalization, so
grouping built on this agrees with what survives ring eviction.

**Parameters**

- `message` `string` — Log message to normalize.

**Returns** `string` — The message template.

```lua
local key = logs.template(entry.message)
```

## typed/builtin//modules/api/engine/logs/logs/warnings {#typed-builtin-modules-api-engine-logs-logs-warnings}

```lua
logs.warnings(limit: number?) -> { LogEntry }
```

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

**Parameters**

- `limit` `number` _(optional)_ — Maximum entries to return.

**Returns** `{ LogEntry }` — Array of WARN+ log-entry tables.

```lua
print(#logs.warnings(), "warnings")
```

## typed/builtin//modules/api/engine/lsp/lsp/check {#typed-builtin-modules-api-engine-lsp-lsp-check}

```lua
lsp.check(path: string, opts: CheckOpts?) -> DiagnosticsResult
```

Validate a single `.luau` file in the VFS and return its
diagnostics. A path the check could not read comes back as one
`lsp-check-*` error naming the path and the reason, so `errors == 0`
means a code body was read and is clean.

**Parameters**

- `path` `string` — VFS path.
- `opts` `CheckOpts` _(optional)_ — `{ severity?, limit?, context? }`.

**Returns** `DiagnosticsResult` — Array of diagnostic tables.

```lua
local diags = lsp.check("/zero/source/main.luau")
```

## typed/builtin//modules/api/engine/lsp/lsp/checkAll {#typed-builtin-modules-api-engine-lsp-lsp-checkall}

```lua
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. The sweep is
time-budgeted (ZERO_EXECUTE_INLINE_BUDGET_MS, ~20s by default): if
the budget elapses it returns the partial result gathered so far
with `budgetExceeded = true` rather than blocking the engine.

**Parameters**

- `opts` `CheckAllOpts` _(optional)_ — `{ scope?, severity?, limit? }`.

**Returns** `CheckAllResult` — `{ filesChecked, errors, warnings, info, hints, budgetExceeded, diagnostics }`.

## typed/builtin//modules/api/engine/lsp/lsp/checkCode {#typed-builtin-modules-api-engine-lsp-lsp-checkcode}

```lua
lsp.checkCode(source: string, opts: CheckOpts?) -> DiagnosticsResult
```

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

**Parameters**

- `source` `string` — Luau source.
- `opts` `CheckOpts` _(optional)_ — `{ severity?, limit?, context? }`.

**Returns** `DiagnosticsResult` — Array of diagnostic tables.

## typed/builtin//modules/api/engine/lsp/lsp/checkDirty {#typed-builtin-modules-api-engine-lsp-lsp-checkdirty}

```lua
lsp.checkDirty() -> DiagnosticsResult
```

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

**Returns** `DiagnosticsResult` — Array of diagnostic tables.

## typed/builtin//modules/api/engine/lsp/lsp/describe {#typed-builtin-modules-api-engine-lsp-lsp-describe}

```lua
lsp.describe(path: string, opts: DescribeOpts?) -> DocEntry?
```

Inspect a single documented entry. Returns the full doc
table (signature, args, returns, examples, level), or nil.
The path is resolved independently of which root the doc is
registered under and of separator style, so the spelling that reads
off the API surface (`renderer.texture.create`) finds the entry
registered as `globals/renderer/texture/create`. A path naming a
binding the engine registered internally answers with the entry a Luau
module publishes over it where there is one, so the signature is the
call content makes; `opts.includeInternal` answers with the internally
registered entry itself. When a path does not resolve,
`lsp.describePaths` says what the registry holds near it.

**Parameters**

- `path` `string` — Doc path (e.g. `"asset/resolve"`, `"renderer.texture.create"`).
- `opts` `DescribeOpts` _(optional)_ — Optional `{ includeInternal? }` — default prefers the published entry.

**Returns** `DocEntry?` — Full doc table or nil.

```lua
local doc = lsp.describe("renderer.texture.create")
```

## typed/builtin//modules/api/engine/lsp/lsp/describePaths {#typed-builtin-modules-api-engine-lsp-lsp-describepaths}

```lua
lsp.describePaths(path: string) -> { string }
```

List the registered doc paths related to `path`. A path that names
an entry returns every root it is registered under (the first is what
`lsp.describe` resolves to); a path that names a namespace returns the
entries registered under it. Empty when the registry holds nothing
near the path — so a lookup that returns nil can always be turned into
the list of what does exist.

**Parameters**

- `path` `string` — Doc path in any spelling (`"renderer.texture"`, `"ecs/query"`).

**Returns** `{ string }` — Array of registered doc paths, most canonical first.

```lua
for _, p in ipairs(lsp.describePaths("renderer.texture")) do print(p) end
```

## typed/builtin//modules/api/engine/lsp/lsp/describeTool {#typed-builtin-modules-api-engine-lsp-lsp-describetool}

```lua
lsp.describeTool(path: string) -> string?
```

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

**Parameters**

- `path` `string` — Tool path (e.g. `"scene/spawnLight"`).

**Returns** `string?` — Full tool docs or nil.

## typed/builtin//modules/api/engine/lsp/lsp/docsByKind {#typed-builtin-modules-api-engine-lsp-lsp-docsbykind}

```lua
lsp.docsByKind(kind: string) -> { MethodSummary }
```

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

**Parameters**

- `kind` `string` — Registration kind.

**Returns** `{ MethodSummary }` — Array of doc summary tables.

## typed/builtin//modules/api/engine/lsp/lsp/getStrictMode {#typed-builtin-modules-api-engine-lsp-lsp-getstrictmode}

```lua
lsp.getStrictMode() -> StrictMode
```

Return the current strict mode.

**Returns** `StrictMode` — `"off"` | `"soft"` | `"strict"`.

## typed/builtin//modules/api/engine/lsp/lsp/isStrict {#typed-builtin-modules-api-engine-lsp-lsp-isstrict}

```lua
lsp.isStrict() -> boolean
```

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

**Returns** `boolean` — True when fully strict.

## typed/builtin//modules/api/engine/lsp/lsp/lastCheckGen {#typed-builtin-modules-api-engine-lsp-lsp-lastcheckgen}

```lua
lsp.lastCheckGen() -> number
```

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

**Returns** `number` — Generation number.

## typed/builtin//modules/api/engine/lsp/lsp/methods {#typed-builtin-modules-api-engine-lsp-lsp-methods}

```lua
lsp.methods(namespace: string, opts: MethodsOpts?) -> { MethodSummary } | { string }
```

List every documented method / entry under a namespace. A broad
namespace (`ui`, `renderer`) returns a large dump by default, so two
options narrow it: `opts.filter` keeps only methods whose name (or
doc path) contains the substring, case-insensitively; `opts.namesOnly`
returns a plain list of method-name strings instead of the full
per-method summary tables — much smaller, and nothing to unwrap. The
listing answers with the surface content calls: an entry registered
internally is left out where its signature spells the `__` binding or a
Luau module publishes the same member, and `opts.includeInternal` lists
every registered entry instead.

**Parameters**

- `namespace` `string` — Namespace name (e.g. `"entity"`, `"modules/Transform"`).
- `opts` `MethodsOpts` _(optional)_ — Optional `{ filter?, namesOnly?, includeInternal? }`.

**Returns** `{ MethodSummary } | { string }` — Array of method summary tables, or plain name strings when `namesOnly` is set (empty when the namespace is unknown or nothing matches the filter).

```lua
for _, name in ipairs(lsp.methods("ui", { namesOnly = true })) do print(name) end
lsp.methods("renderer", { filter = "shadow" })
```

## typed/builtin//modules/api/engine/lsp/lsp/modules {#typed-builtin-modules-api-engine-lsp-lsp-modules}

```lua
lsp.modules() -> { ModuleEntry }
```

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

## typed/builtin//modules/api/engine/lsp/lsp/namespaces {#typed-builtin-modules-api-engine-lsp-lsp-namespaces}

```lua
lsp.namespaces(opts: NamespacesOpts?) -> { NamespaceEntry }
```

List the documentation namespaces reachable from Luau. By
default only namespaces exposing at least one PUBLIC method are
returned, so the list matches what you can actually call — internal
FFI plumbing (e.g. `pause`, `native_entity`), whose public surface
lives elsewhere (`engine.paused`, the `entity` proxy, …), is left
out. Pass `{ includeInternal = true }` to list every namespace,
internal ones included.

**Parameters**

- `opts` `NamespacesOpts` _(optional)_ — Optional `{ includeInternal? }` — default lists public only.

**Returns** `{ NamespaceEntry }` — Array of namespace summary tables.

```lua
for _, ns in ipairs(lsp.namespaces()) do print(ns.name) end
```

## typed/builtin//modules/api/engine/lsp/lsp/readDirectives {#typed-builtin-modules-api-engine-lsp-lsp-readdirectives}

```lua
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.

**Parameters**

- `source` `string` — Luau source text.

**Returns** `DirectiveBlock` — `{ mode, codes? }`.

## typed/builtin//modules/api/engine/lsp/lsp/search {#typed-builtin-modules-api-engine-lsp-lsp-search}

```lua
lsp.search(query: string, opts: SearchOpts?) -> { MethodSummary }
```

Case-insensitive substring search across every registered
doc's path, signature, and description. Hits answer with the surface
content calls: an entry registered internally is left out where its
signature spells the `__` binding or a Luau module publishes the same
member, and `opts.includeInternal` searches every registered entry.

**Parameters**

- `query` `string` — Substring to search for.
- `opts` `SearchOpts` _(optional)_ — `{ limit? = 50, includeInternal? }`.

**Returns** `{ MethodSummary }` — Array of method summary tables.

## typed/builtin//modules/api/engine/lsp/lsp/setStrict {#typed-builtin-modules-api-engine-lsp-lsp-setstrict}

```lua
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.

**Parameters**

- `enabled` `boolean` — True = strict, false = off.

**Returns** `boolean` — Persistence signal.

## typed/builtin//modules/api/engine/lsp/lsp/setStrictMode {#typed-builtin-modules-api-engine-lsp-lsp-setstrictmode}

```lua
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.

**Parameters**

- `mode` `StrictMode` — `"off"` | `"soft"` | `"strict"`.

**Returns** `boolean` — Persistence signal.

## typed/builtin//modules/api/engine/lsp/lsp/summary {#typed-builtin-modules-api-engine-lsp-lsp-summary}

```lua
lsp.summary() -> Summary
```

Counts only — does not re-run validation.

**Returns** `Summary` — Counts of cached diagnostics by severity.

## typed/builtin//modules/api/engine/lsp/lsp/tools {#typed-builtin-modules-api-engine-lsp-lsp-tools}

```lua
lsp.tools() -> { ToolEntry }
```

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

## typed/builtin//modules/api/engine/lsp/lsp/typeOf {#typed-builtin-modules-api-engine-lsp-lsp-typeof}

```lua
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.

**Parameters**

- `expr_source` `string` — Luau expression source (no surrounding chunk).
- `context_path` `string` _(optional)_ — VFS path whose scope should be visible.

**Returns** `TypeDescriptor` — Type descriptor table.

```lua
local td = lsp.typeOf("Transform.lookAt", "/zero/source/main.luau")
```

## typed/builtin//modules/api/engine/luau_profile/luau_profile/begin {#typed-builtin-modules-api-engine-luau-profile-luau-profile-begin}

```lua
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`.

**Parameters**

- `name` `string` — Region name; aggregated across opens.

**Returns** `number` — Region id.

```lua
local id = luau_profile.begin("walk"); ...; luau_profile.end_region(id)
```

## typed/builtin//modules/api/engine/luau_profile/luau_profile/dump {#typed-builtin-modules-api-engine-luau-profile-luau-profile-dump}

```lua
luau_profile.dump(path: string) -> DumpResult
```

Write the folded-stack dump to `path` on the HOST filesystem,
one line per stack as `<ticks> <stack_csv>` — the format
upstream Luau emits and `tools/perfgraph.py` consumes
unchanged. A path naming the engine filesystem (`/zero/...`, or
a bare root such as `/source/...`) is refused, and says so:
`luau_profile.folded()` with `vfs.write` puts the dump there.

**Parameters**

- `path` `string` — Absolute host filesystem path to write.

**Returns** `DumpResult` — `{ ok, path, samples, stacks, bytes }`.

```lua
local r = luau_profile.dump("/tmp/profile.folded")
```

## typed/builtin//modules/api/engine/luau_profile/luau_profile/dump_regions {#typed-builtin-modules-api-engine-luau-profile-luau-profile-dump-regions}

```lua
luau_profile.dump_regions(path: string) -> DumpRegionsResult
```

Write per-region stats to `path` as JSON, on the HOST
filesystem. A path naming the engine filesystem is refused, the
same way `dump` refuses one.

**Parameters**

- `path` `string` — Absolute host filesystem path to write.

**Returns** `DumpRegionsResult` — `{ ok, path, regions, bytes }`.

```lua
luau_profile.dump_regions("/tmp/regions.json")
```

## typed/builtin//modules/api/engine/luau_profile/luau_profile/end_region {#typed-builtin-modules-api-engine-luau-profile-luau-profile-end-region}

```lua
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).

**Parameters**

- `id` `number` — Region id returned by `begin()`.

```lua
luau_profile.end_region(id)
```

## typed/builtin//modules/api/engine/luau_profile/luau_profile/folded {#typed-builtin-modules-api-engine-luau-profile-luau-profile-folded}

```lua
luau_profile.folded() -> string
```

The folded-stack dump as a string, one line per stack as
`<ticks> <stack_csv>` — the format upstream Luau emits and
`tools/perfgraph.py` consumes unchanged. The same bytes `dump`
writes, handed back instead of written, so the profile can go
wherever the caller keeps it: `vfs.write` puts it in the engine
filesystem, where `bash` and `vfs.read` reach it.

**Returns** `string` — Folded-stack text; empty when nothing was sampled.

```lua
vfs.write("/source/tmp/sample.folded", luau_profile.folded())
```

## typed/builtin//modules/api/engine/luau_profile/luau_profile/is_running {#typed-builtin-modules-api-engine-luau-profile-luau-profile-is-running}

```lua
luau_profile.is_running() -> boolean
```

True iff the background sampler is currently running.

**Returns** `boolean` — Sampler running state.

```lua
if luau_profile.is_running() then luau_profile.stop() end
```

## typed/builtin//modules/api/engine/luau_profile/luau_profile/reset {#typed-builtin-modules-api-engine-luau-profile-luau-profile-reset}

```lua
luau_profile.reset()
```

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

```lua
luau_profile.reset()
```

## typed/builtin//modules/api/engine/luau_profile/luau_profile/sampling_available {#typed-builtin-modules-api-engine-luau-profile-luau-profile-sampling-available}

```lua
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.

**Returns** `boolean` — Whether `start()` would actually spawn a sampler.

```lua
if luau_profile.sampling_available() then luau_profile.start() end
```

## typed/builtin//modules/api/engine/luau_profile/luau_profile/snapshot {#typed-builtin-modules-api-engine-luau-profile-luau-profile-snapshot}

```lua
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`).

**Parameters**

- `top_n` `number` _(optional)_ — Truncate stacks to this many entries; omit for all.

**Returns** `Snapshot` — Profile snapshot.

```lua
local snap = luau_profile.snapshot(10)
```

## typed/builtin//modules/api/engine/luau_profile/luau_profile/start {#typed-builtin-modules-api-engine-luau-profile-luau-profile-start}

```lua
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.

**Parameters**

- `hz` `number` _(optional)_ — Sampling rate in Hz.

**Returns** `StartResult` — Effective sampler state.

```lua
luau_profile.start(500)
```

## typed/builtin//modules/api/engine/luau_profile/luau_profile/stop {#typed-builtin-modules-api-engine-luau-profile-luau-profile-stop}

```lua
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.

```lua
luau_profile.stop()
```

## typed/builtin//modules/api/engine/mathx/mathx/addScaledVec3 {#typed-builtin-modules-api-engine-mathx-mathx-addscaledvec3}

```lua
mathx.addScaledVec3(dstBuffer: Substrate.TypedBuffer, srcBuffer: Substrate.TypedBuffer, 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.

**Parameters**

- `dstBuffer` `Substrate.TypedBuffer` — The buffer written into.
- `srcBuffer` `Substrate.TypedBuffer` — The buffer read from.
- `count` `number` — Number of vec3 elements.
- `scale` `number` — Multiplier applied to every src element.

**Returns** `boolean` — True on success.

```lua
mathx.addScaledVec3(positions, velocities, n, dt)
```

## typed/builtin//modules/api/engine/mathx/mathx/dampScalar {#typed-builtin-modules-api-engine-mathx-mathx-dampscalar}

```lua
mathx.dampScalar(buffer: Substrate.TypedBuffer, 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.

**Parameters**

- `buffer` `Substrate.TypedBuffer` — The buffer to operate on.
- `offset` `number` — Starting f32 index.
- `count` `number` — Number of scalars.
- `target` `number` — Target value all scalars approach.
- `smoothTime` `number` — Time constant (≤ 0 snaps to target).
- `dt` `number` — Frame time in seconds.

**Returns** `boolean` — True on success, false on a bad handle or out-of-range slice.

```lua
mathx.dampScalar(buf, 0, 16, 0.0, 0.16, dt)
```

## typed/builtin//modules/api/engine/mathx/mathx/lerpVec3 {#typed-builtin-modules-api-engine-mathx-mathx-lerpvec3}

```lua
mathx.lerpVec3(buffer: Substrate.TypedBuffer, 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`.

**Parameters**

- `buffer` `Substrate.TypedBuffer` — The buffer to operate on.
- `offset` `number` — Starting f32 index.
- `count` `number` — Number of vec3 elements.
- `tx` `number` — Target X.
- `ty` `number` — Target Y.
- `tz` `number` — Target Z.
- `t` `number` — Blend amount (0..1).

**Returns** `boolean` — True on success.

```lua
mathx.lerpVec3(buf, 0, n, 0, 1, 0, 0.5)
```

## typed/builtin//modules/api/engine/mathx/mathx/normalizeQuat {#typed-builtin-modules-api-engine-mathx-mathx-normalizequat}

```lua
mathx.normalizeQuat(buffer: Substrate.TypedBuffer, 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.

**Parameters**

- `buffer` `Substrate.TypedBuffer` — The buffer to operate on.
- `offset` `number` — Starting f32 index.
- `count` `number` — Number of quaternions.

**Returns** `boolean` — True on success.

```lua
mathx.normalizeQuat(buf, 0, n)
```

## typed/builtin//modules/api/engine/mathx/mathx/slerpQuat {#typed-builtin-modules-api-engine-mathx-mathx-slerpquat}

```lua
mathx.slerpQuat(buffer: Substrate.TypedBuffer, 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.

**Parameters**

- `buffer` `Substrate.TypedBuffer` — The buffer to operate on.
- `offset` `number` — Starting f32 index.
- `count` `number` — Number of quaternions.
- `tx` `number` — Target quat X.
- `ty` `number` — Target quat Y.
- `tz` `number` — Target quat Z.
- `tw` `number` — Target quat W.
- `t` `number` — Slerp amount (0..1).

**Returns** `boolean` — True on success.

```lua
mathx.slerpQuat(buf, 0, n, 0, 0, 0, 1, 0.25)
```

## typed/builtin//modules/api/engine/mathx/mathx/transformVec3 {#typed-builtin-modules-api-engine-mathx-mathx-transformvec3}

```lua
mathx.transformVec3(buffer: Substrate.TypedBuffer, 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.

**Parameters**

- `buffer` `Substrate.TypedBuffer` — The buffer to operate on.
- `offset` `number` — Starting f32 index.
- `count` `number` — Number of vec3 elements.
- `mat16` `{ number }` — Column-major 4x4 matrix as a 16-element array.

**Returns** `boolean` — True on success.

```lua
mathx.transformVec3(positions, 0, n, worldMatrix)
```

## typed/builtin//modules/api/engine/mcpLog/mcpLog/clear {#typed-builtin-modules-api-engine-mcplog-mcplog-clear}

```lua
mcpLog.clear() -> boolean
```

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

**Returns** `boolean` — True on success.

```lua
mcpLog.clear()
```

## typed/builtin//modules/api/engine/mcpLog/mcpLog/query {#typed-builtin-modules-api-engine-mcplog-mcplog-query}

```lua
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).

**Parameters**

- `limit` `number` _(optional)_ — Maximum number of entries to return.

**Returns** `{ McpLogEntry }` — Array of tool-call entry tables.

```lua
for _, e in ipairs(mcpLog.query(50)) do print(e.tool_name, e.status) end
```

## typed/builtin//modules/api/engine/microphone/microphone/awaitRunning {#typed-builtin-modules-api-engine-microphone-microphone-awaitrunning}

```lua
microphone.awaitRunning(timeout: number?) -> (MicState, string?)
```

Wait until the capture settles out of `starting` and
`permissionPending`, and report where it landed. Returns as soon as the
state settles, or when `timeout` seconds have passed, whichever comes
first — a browser permission prompt nobody answers never settles, so
the wait is always bounded.

**Parameters**

- `timeout` `number` _(optional)_ — Seconds to wait at most. Defaults to 10.

**Returns** `(MicState, string?)` — The state reached, and its reason where it has one.

```lua
microphone.start(); local state, why = microphone.awaitRunning()
```

## typed/builtin//modules/api/engine/microphone/microphone/devices {#typed-builtin-modules-api-engine-microphone-microphone-devices}

```lua
microphone.devices() -> { MicDevice }
```

Every input device the platform offers. `id` is what
`microphone.start` takes to select one and is stable across reboots
where the platform provides a stable identifier; `name` is the label a
person recognises.

An empty list is a legitimate answer, not a failure: a machine with no
input hardware offers none, and a browser names none until microphone
access has been granted at least once — the labels are part of what the
permission protects.

**Returns** `{ MicDevice }` — Array of `{ id, name, default }`.

```lua
for _, d in ipairs(microphone.devices()) do print(d.name, d.default) end
```

## typed/builtin//modules/api/engine/microphone/microphone/frequencies {#typed-builtin-modules-api-engine-microphone-microphone-frequencies}

```lua
microphone.frequencies() -> { number }
```

The frequency each spectrum bin is centred on, in Hz, as an array
parallel to `microphone.spectrum()`. Derived from the capture's rate and
transform size, so it changes only when a capture is started with
different ones. Empty while no capture is running.

**Returns** `{ number }` — Array of centre frequencies, one per bin.

```lua
local hz = microphone.frequencies(); print(hz[#hz]) -- the Nyquist frequency
```

## typed/builtin//modules/api/engine/microphone/microphone/level {#typed-builtin-modules-api-engine-microphone-microphone-level}

```lua
microphone.level() -> number
```

Loudness of the most recent analysis window, as an RMS amplitude in
0..1. A full-scale sine reads about 0.707 and silence reads 0.

Measured over only the samples that have arrived, so a capture that has
just started reports the loudness of what it holds rather than a level
diluted by a window it has not filled yet. 0 while no capture is
running.

**Returns** `number` — RMS amplitude, 0..1.

```lua
if microphone.level() > 0.05 then print("someone is talking") end
```

## typed/builtin//modules/api/engine/microphone/microphone/peak {#typed-builtin-modules-api-engine-microphone-microphone-peak}

```lua
microphone.peak() -> { [string]: number }?
```

The bin carrying the most energy and what it says: the frequency it
is centred on, its amplitude, and the loudness of the whole window.
A capture reading silence answers with amplitude 0 at bin 1.

**Returns** `{ [string]: number }?` — `{ bin, hz, amplitude, level }`, or nil while no capture is running.

```lua
local p = microphone.peak(); if p and p.amplitude > 0.05 then print(p.hz) end
```

## typed/builtin//modules/api/engine/microphone/microphone/samples {#typed-builtin-modules-api-engine-microphone-microphone-samples}

```lua
microphone.samples(max: number?) -> buffer?
```

Captured mono PCM no caller has taken yet, oldest sample first, as a
buffer of little-endian f32 read with `buffer.readf32`. The samples are
removed, so successive calls walk forward through the capture and a
caller doing its own analysis sees every frame once.

nil while no capture is running, and a zero-length buffer when the
capture is running and nothing new has arrived. Samples nobody takes
are discarded once the queue fills, and `status().overruns` counts
every one.

**Parameters**

- `max` `number` _(optional)_ — How many samples to take at most. Omitted, everything held comes back.

**Returns** `buffer?` — Buffer of f32 samples, or nil when no capture is running.

```lua
local pcm = microphone.samples(); if pcm then print(buffer.len(pcm) // 4) end
```

## typed/builtin//modules/api/engine/microphone/microphone/spectrum {#typed-builtin-modules-api-engine-microphone-microphone-spectrum}

```lua
microphone.spectrum() -> { number }
```

Amplitude per frequency bin over the most recent analysis window:
`fftSize / 2 + 1` numbers, DC at index 1 through the Nyquist frequency
at the last. Bin `i` covers `(i - 1) * status().binHz` Hz.

Each value is an amplitude estimate rather than a raw transform
magnitude, so a full-scale tone sitting on a bin centre reads about 1.0
and the numbers stay comparable across transform sizes.

The window is multiplied by a **Hann** taper before the transform. An
untapered window ends abruptly at both edges and the transform reads
that as energy spread across every bin, smearing one tone into a skirt
that buries quieter tones beside it. Hann trades a slightly wider main
lobe — a tone occupies about three bins rather than one — for sidelobes
that fall away steeply, which is what lets neighbouring tones be told
apart. Read a peak as "a tone near here", not "a tone exactly here".

Reading this takes no samples away from `microphone.samples()`. Empty
while no capture is running.

**Returns** `{ number }` — Array of amplitudes, one per bin.

```lua
local bins = microphone.spectrum(); print(#bins, bins[1])
```

## typed/builtin//modules/api/engine/microphone/microphone/start {#typed-builtin-modules-api-engine-microphone-microphone-start}

```lua
microphone.start(opts: MicOpts?) -> (MicState?, string?)
```

Open an input device and begin capturing. Returns the state the
capture reached — `"running"` once a device is delivering, or
`"permissionPending"` where the platform must ask for access first,
which is the browser's normal path. Poll `microphone.status()` from
there, or use `microphone.awaitRunning()`.

A request that cannot be made at all returns nil and the reason: an
`fftSize` that is not a whole power of two between 64 and 16384, a
device no machine here offers, a rate the device does not capture at,
or a capture that is already running.

Omitting `device` opens the platform default. Omitting `sampleRate`
takes the device's own rate, which is what avoids a resample.
`fftSize` is how many samples one analysis window covers and defaults
to 1024 — at 48 kHz that spans ~21 ms and resolves ~47 Hz per bin.

**Parameters**

- `opts` `MicOpts` _(optional)_ — `{ device, sampleRate, fftSize }`.

**Returns** `(MicState?, string?)` — The state reached, or nil and the reason the request was refused.

```lua
local state, why = microphone.start({ fftSize = 2048 })
```

## typed/builtin//modules/api/engine/microphone/microphone/status {#typed-builtin-modules-api-engine-microphone-microphone-status}

```lua
microphone.status() -> MicStatus
```

Where the capture stands.

`reason` carries the platform's own message: the refusal for `denied`,
the device's message for `failed`, what is being waited on for
`permissionPending`. `binHz` is the width of one spectrum bin and
`bins` how many `microphone.spectrum()` returns.

`framesCaptured` counts every mono frame the device delivered whether
or not anything drained it, so a silent room reads differently from a
stalled device. `overruns` counts samples discarded because a consumer
did not keep up — it standing still is what says the readings are
continuous, and it climbing is why a caller sees gaps.

**Returns** `MicStatus` — `{ state, reason, device, sampleRate, fftSize, binHz, bins, framesCaptured, overruns }`.

```lua
local s = microphone.status(); print(s.state, s.framesCaptured, s.overruns)
```

## typed/builtin//modules/api/engine/microphone/microphone/stop {#typed-builtin-modules-api-engine-microphone-microphone-stop}

```lua
microphone.stop() -> boolean
```

Stop the capture and release the device. True when a capture was
open or being opened at call time. The device is let go before this
returns, so a stop followed by a start opens it again rather than
finding it held.

**Returns** `boolean` — Whether a capture was active.

```lua
microphone.stop()
```

## typed/builtin//modules/api/engine/mode_flip_guard/M/beginPlaySession {#typed-builtin-modules-api-engine-mode-flip-guard-m-beginplaysession}

```lua
M.beginPlaySession() -> number
```

Open a play session, advancing the play-session id. `engine.module`
calls this from its mode-change watcher as the engine enters play, so
every play session the engine runs carries an id of its own whichever
route flipped the mode.

**Returns** `number` — The id of the play session being opened.

## typed/builtin//modules/api/engine/mode_flip_guard/M/isInFlight {#typed-builtin-modules-api-engine-mode-flip-guard-m-isinflight}

```lua
M.isInFlight() -> boolean
```

Whether a mode-flip transition is materialising the scene. The
transition unloads the root layer and reloads it for the new mode across
many frames, so while this reads `true` the live entities are a partial
rebuild of the scene; code that judges authored scene state waits for it
to clear.

**Returns** `boolean` — `true` while the transition is running.

## typed/builtin//modules/api/engine/mode_flip_guard/M/isOwned {#typed-builtin-modules-api-engine-mode-flip-guard-m-isowned}

```lua
M.isOwned() -> boolean
```

Whether the layers module currently owns the mode-flip reset.

**Returns** `boolean` — `true` while the layers transition owns the flip; spawners stand down.

## typed/builtin//modules/api/engine/mode_flip_guard/M/playSession {#typed-builtin-modules-api-engine-mode-flip-guard-m-playsession}

```lua
M.playSession() -> number
```

The id of the play session the engine is in. State that belongs to a
single play session records this id when it is armed and compares it
before it is spent, so an arm outlives exactly the session that made it.

**Returns** `number` — The current play-session id.

## typed/builtin//modules/api/engine/mode_flip_guard/M/setInFlight {#typed-builtin-modules-api-engine-mode-flip-guard-m-setinflight}

```lua
M.setInFlight(v: boolean) -> nil
```

Set whether a mode-flip transition is materialising the scene.

**Parameters**

- `v` `boolean` — `true` for the span of the transition, `false` once it has settled.

**Returns** `nil`

## typed/builtin//modules/api/engine/mode_flip_guard/M/setOwned {#typed-builtin-modules-api-engine-mode-flip-guard-m-setowned}

```lua
M.setOwned(v: boolean) -> nil
```

Set whether the layers module owns the current mode-flip reset.

**Parameters**

- `v` `boolean` — `true` to claim ownership, `false` to release.

**Returns** `nil`

## typed/builtin//modules/api/engine/modelImport/modelImport/decompose {#typed-builtin-modules-api-engine-modelimport-modelimport-decompose}

```lua
modelImport.decompose(bytes: buffer | 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)`.

**Parameters**

- `bytes` `buffer | string` — Raw model file bytes (from `vfs.readAsync`).
- `format` `string` — The source file extension (lowercase, no dot).

**Returns** `string` — Promise handle for `task.await`.

```lua
local h = modelImport.decompose(bytes, "obj"); task.await(h)
```

## typed/builtin//modules/api/engine/modelImport/modelImport/decomposeFiles {#typed-builtin-modules-api-engine-modelimport-modelimport-decomposefiles}

```lua
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.

**Parameters**

- `files` `{ ModelFile }` — Array of `{ name, bytes }`: the model file plus its companions.
- `mainName` `string` — Basename of the model file to import (one of `files`' names).

**Returns** `string` — Promise handle for `task.await`.

```lua
local h = modelImport.decomposeFiles(files, "CesiumMilkTruck.gltf"); task.await(h)
```

## typed/builtin//modules/api/engine/modelImport/modelImport/extractAnimation {#typed-builtin-modules-api-engine-modelimport-modelimport-extractanimation}

```lua
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.

**Parameters**

- `sourcePath` `string` — VFS path to the source model file.
- `clipName` `string` — Clip name as returned by `result(handle).animations[i].name`.

**Returns** `string` — Promise handle for `task.await`.

## typed/builtin//modules/api/engine/modelImport/modelImport/extractAnimationResult {#typed-builtin-modules-api-engine-modelimport-modelimport-extractanimationresult}

```lua
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.

**Parameters**

- `handle` `string` — Promise handle from `extractAnimation`.

**Returns** `string?` — The clip's `.zanim` payload bytes, or nil.

## typed/builtin//modules/api/engine/modelImport/modelImport/result {#typed-builtin-modules-api-engine-modelimport-modelimport-result}

```lua
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.

**Parameters**

- `handle` `string` — Promise handle from `decompose`.

**Returns** `any?` — `{ nodes, meshes, materials, textures, animations, hasSkeleton, skeletonRootNode?, skeleton? }`, or nil.

## typed/builtin//modules/api/engine/modelImport/modelImport/retryHandle {#typed-builtin-modules-api-engine-modelimport-modelimport-retryhandle}

```lua
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.

**Parameters**

- `makeHandle` `() -> any` — Returns a promise-handle string, or a falsy value on failure.
- `retries` `number` _(optional)_ — Extra attempts after the first (default 3).
- `yield` `(() -> ())` _(optional)_ — Called between attempts (default `task.wait`).

**Returns** `string?` — The handle string, or nil when every attempt failed.

## typed/builtin//modules/api/engine/modelImport/modelImport/rigFromMeshSkin {#typed-builtin-modules-api-engine-modelimport-modelimport-rigfrommeshskin}

```lua
modelImport.rigFromMeshSkin(meshBytes: buffer | 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.

**Parameters**

- `meshBytes` `buffer | string` — Raw ZMSH mesh bytes carrying a skin.

**Returns** `string?` — `.rig` JSON document, or nil.

## typed/builtin//modules/api/engine/modelImport/modelImport/rigFromSkeleton {#typed-builtin-modules-api-engine-modelimport-modelimport-rigfromskeleton}

```lua
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.

**Parameters**

- `skeleton` `AnimationSkeleton` — `{ names, parents, locals }` (a `decompose` result's `skeleton`).

**Returns** `string?` — `.rig` JSON document, or nil.

```lua
local rigJson = modelImport.rigFromSkeleton(data.skeleton)
```

## typed/builtin//modules/api/engine/multiplayer/multiplayer/beginOperation {#typed-builtin-modules-api-engine-multiplayer-multiplayer-beginoperation}

```lua
multiplayer.beginOperation(description: string)
```

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

**Parameters**

- `description` `string` — Human-readable label.

```lua
multiplayer.beginOperation("move cube")
```

## typed/builtin//modules/api/engine/multiplayer/multiplayer/canRedo {#typed-builtin-modules-api-engine-multiplayer-multiplayer-canredo}

```lua
multiplayer.canRedo() -> boolean
```

Check if this client has any redoable operations.

**Returns** `boolean` — True if redo is available.

## typed/builtin//modules/api/engine/multiplayer/multiplayer/canUndo {#typed-builtin-modules-api-engine-multiplayer-multiplayer-canundo}

```lua
multiplayer.canUndo() -> boolean
```

Check if this client has any undoable operations.

**Returns** `boolean` — True if undo is available.

## typed/builtin//modules/api/engine/multiplayer/multiplayer/cancelOperation {#typed-builtin-modules-api-engine-multiplayer-multiplayer-canceloperation}

```lua
multiplayer.cancelOperation()
```

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

```lua
multiplayer.cancelOperation()
```

## typed/builtin//modules/api/engine/multiplayer/multiplayer/claimOwnership {#typed-builtin-modules-api-engine-multiplayer-multiplayer-claimownership}

```lua
multiplayer.claimOwnership(entityId: (string | entityRef)?) -> boolean
```

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

**Parameters**

- `entityId` `(string | entityRef)` _(optional)_ — Entity id or proxy to claim.

**Returns** `boolean` — True if the claim was tentatively accepted.

## typed/builtin//modules/api/engine/multiplayer/multiplayer/clearHistory {#typed-builtin-modules-api-engine-multiplayer-multiplayer-clearhistory}

```lua
multiplayer.clearHistory()
```

Drop this client's whole undo/redo history — for boundaries where
old edits stop being meaningful (a scene load, a test rig reset).

```lua
multiplayer.clearHistory()
```

## typed/builtin//modules/api/engine/multiplayer/multiplayer/commitOperation {#typed-builtin-modules-api-engine-multiplayer-multiplayer-commitoperation}

```lua
multiplayer.commitOperation()
```

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

```lua
multiplayer.commitOperation()
```

## typed/builtin//modules/api/engine/multiplayer/multiplayer/connect {#typed-builtin-modules-api-engine-multiplayer-multiplayer-connect}

```lua
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.

**Parameters**

- `relayUrl` `string` — Relay server URL.

```lua
multiplayer.connect("https://relay.example.com")
```

## typed/builtin//modules/api/engine/multiplayer/multiplayer/disconnect {#typed-builtin-modules-api-engine-multiplayer-multiplayer-disconnect}

```lua
multiplayer.disconnect()
```

Disconnect from the multiplayer relay server.

```lua
multiplayer.disconnect()
```

## typed/builtin//modules/api/engine/multiplayer/multiplayer/explain {#typed-builtin-modules-api-engine-multiplayer-multiplayer-explain}

```lua
multiplayer.explain(entityId: (string | entityRef), componentType: string, property: string) -> DeliveryVerdict
```

Why a synced property is not reaching the peers this client shares
its entity's room with. Answers from the engine's own registry, so a
name the component never registered is reported as such instead of
inferred from a second client's silence.

**Parameters**

- `entityId` `(string | entityRef)` — Entity id or proxy.
- `componentType` `string` — Component type name, e.g. "Health".
- `property` `string` — Property name as written in the component's `sync {}` block.

**Returns** `DeliveryVerdict` — `arriving` true when the property is on its way; otherwise `reason` names the cause and `property` carries the registry's record of it when one exists.

```lua
local v = multiplayer.explain(player, "Health", "hp")
if not v.arriving then print(v.reason) end
```

## typed/builtin//modules/api/engine/multiplayer/multiplayer/getDiagnostics {#typed-builtin-modules-api-engine-multiplayer-multiplayer-getdiagnostics}

```lua
multiplayer.getDiagnostics() -> SyncDiagnostics
```

Get sync diagnostics — traffic counts, bandwidth, link quality,
peer count. The counts — `bytesSent/Received`,
`datagramsSent/Received`, `rpcsSent/Received`, `ownershipChanges` —
are running totals for the session, so a sparse event stays readable
long after it happened; subtract two samples for the rate over the
interval between them. `bytesSentPerSec` / `bytesReceivedPerSec` are
averages over the last completed ~1 second window.
`rttMs` is the smoothed round-trip time to the relay and
`packetLoss` the fraction (0..1) of packets lost over the last 5
seconds; both read 0 until the transport has sampled a live
connection. `messagesAwaitingEntity` counts the sync messages this
peer is holding for an entity it has not received yet — each waits
for the spawn that names it, applies the moment it arrives, and is
released once its wait runs out.

**Returns** `SyncDiagnostics` — Diagnostics table.

```lua
local d = multiplayer.getDiagnostics()
if d.packetLoss > 0.05 then warnThePlayer(d.rttMs) end
print(d.messagesAwaitingEntity .. " message(s) waiting for their entity")
```

## typed/builtin//modules/api/engine/multiplayer/multiplayer/getPeerId {#typed-builtin-modules-api-engine-multiplayer-multiplayer-getpeerid}

```lua
multiplayer.getPeerId() -> number?
```

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

**Returns** `number?` — Local peer ID, or nil if not connected.

## typed/builtin//modules/api/engine/multiplayer/multiplayer/getPeers {#typed-builtin-modules-api-engine-multiplayer-multiplayer-getpeers}

```lua
multiplayer.getPeers() -> { PeerInfo }
```

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

**Returns** `{ PeerInfo }` — Array of peer info tables.

```lua
for _, p in ipairs(multiplayer.getPeers()) do print(p.name) end
```

## typed/builtin//modules/api/engine/multiplayer/multiplayer/getRoomPeers {#typed-builtin-modules-api-engine-multiplayer-multiplayer-getroompeers}

```lua
multiplayer.getRoomPeers(roomKey: string) -> { PeerInfo }
```

Get the peers this client shares the given room with, ordered by
peer id. `getPeers` answers for the whole session — the union of every
room this client is in — while this answers for one room, so a peer
that leaves this room while staying in another disappears from here
and remains in `getPeers`.

**Parameters**

- `roomKey` `string` — Fully-qualified room key
(`{worldGuid}/{profile}/{mode}/{sceneGuid}`).

**Returns** `{ PeerInfo }` — Array of peer info tables for that room.

```lua
for _, p in ipairs(multiplayer.getRoomPeers(key)) do print(p.id) end
```

## typed/builtin//modules/api/engine/multiplayer/multiplayer/getRooms {#typed-builtin-modules-api-engine-multiplayer-multiplayer-getrooms}

```lua
multiplayer.getRooms() -> { string }
```

The relay rooms this client has joined, sorted. A broadcast reaches
only the peers that share one of these.

**Returns** `{ string }` — Room keys.

```lua
for _, key in ipairs(multiplayer.getRooms()) do print(key) end
```

## typed/builtin//modules/api/engine/multiplayer/multiplayer/getTickRate {#typed-builtin-modules-api-engine-multiplayer-multiplayer-gettickrate}

```lua
multiplayer.getTickRate() -> number
```

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

**Returns** `number` — Sync ticks per second (default 20).

## typed/builtin//modules/api/engine/multiplayer/multiplayer/heldMessages {#typed-builtin-modules-api-engine-multiplayer-multiplayer-heldmessages}

```lua
multiplayer.heldMessages() -> { HeldMessage }
```

The sync messages this peer is holding for entities it has not
received — what `getDiagnostics().messagesAwaitingEntity` counts, one
entry each, with the entity sync id it names, its age and the grace it
is held against.

**Returns** `{ HeldMessage }` — Held messages.

```lua
for _, m in ipairs(multiplayer.heldMessages()) do print(m.kind, m.ageMs) end
```

## typed/builtin//modules/api/engine/multiplayer/multiplayer/isConnected {#typed-builtin-modules-api-engine-multiplayer-multiplayer-isconnected}

```lua
multiplayer.isConnected() -> boolean
```

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

**Returns** `boolean` — True if connected.

## typed/builtin//modules/api/engine/multiplayer/multiplayer/isHost {#typed-builtin-modules-api-engine-multiplayer-multiplayer-ishost}

```lua
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'.

**Returns** `boolean` — True on the host / offline / single-player; false on a confirmed joiner. Defaults to true when the role isn't known yet (degrade to host so single-player and pre-join code still run) — pair with a scene's `onHostLoad` hook when exact one-shot timing matters.

```lua
if multiplayer.isHost() then enemy = entity.spawnSynced("enemy") end
```

## typed/builtin//modules/api/engine/multiplayer/multiplayer/isOwner {#typed-builtin-modules-api-engine-multiplayer-multiplayer-isowner}

```lua
multiplayer.isOwner(entityId: (string | entityRef)?) -> 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.

**Parameters**

- `entityId` `(string | entityRef)` _(optional)_ — Entity id or proxy to check (defaults to `self.entityId`
in component context).

**Returns** `boolean` — True if the local client is the owner.

## typed/builtin//modules/api/engine/multiplayer/multiplayer/isRoomCreator {#typed-builtin-modules-api-engine-multiplayer-multiplayer-isroomcreator}

```lua
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.

**Parameters**

- `roomKey` `string` — Fully-qualified room key
(`{worldGuid}/{profile}/{mode}/{sceneGuid}`).

**Returns** `boolean?` — True if this client created the room, false if it joined an existing one, nil if the relay hasn't reported a role yet (offline / not joined).

```lua
if multiplayer.isRoomCreator(key) ~= false then layers.load(scene) end
```

## typed/builtin//modules/api/engine/multiplayer/multiplayer/joinRoom {#typed-builtin-modules-api-engine-multiplayer-multiplayer-joinroom}

```lua
multiplayer.joinRoom(roomKey: string)
```

Join a relay room. Room keys are built as
`{worldGuid}/{profile}/{mode}/{sceneGuid}` — four segments, the
`{profile}` one keeping a runtime peer (published content) and an
editor peer (live content) in separate rooms even when both are in
play mode. Rooms partition the relay's fan-out: only peers in the
same room receive each other's broadcasts. `getRooms()` reports the
keys this client is already in and `roomFor(entity)` the one an
entity broadcasts into, so a key can be read rather than rebuilt.
No-op when not connected or already joined.

**Parameters**

- `roomKey` `string` — Fully-qualified room key.

```lua
multiplayer.joinRoom(worldGuid .. "/" .. engine.profile .. "/play/" .. sceneGuid)
```

## typed/builtin//modules/api/engine/multiplayer/multiplayer/leaveRoom {#typed-builtin-modules-api-engine-multiplayer-multiplayer-leaveroom}

```lua
multiplayer.leaveRoom(roomKey: string)
```

Leave a relay room. The key is reported under
`observe().withdrawnRooms` until `joinRoom` names it again. No-op
when not connected or not joined.

**Parameters**

- `roomKey` `string` — Fully-qualified room key.

## typed/builtin//modules/api/engine/multiplayer/multiplayer/loopback {#typed-builtin-modules-api-engine-multiplayer-multiplayer-loopback}

```lua
multiplayer.loopback() -> { [string]: any }
```

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

**Returns** `{ [string]: any }` — Loopback API table.

## typed/builtin//modules/api/engine/multiplayer/multiplayer/observe {#typed-builtin-modules-api-engine-multiplayer-multiplayer-observe}

```lua
multiplayer.observe() -> ReplicationObservation
```

Report what this peer is replicating and why a property is not
arriving. Carries the rooms this client joined, one record per entity
with a sync id — its owner, the room it broadcasts into, how many
other peers share that room, and every REGISTERED synced component
with its declared property names, wire indices, public/private table
and dirty bits — the messages held for entities that have not arrived,
and the registry's totals. Every property carries `notArriving`: one
name from `reasons`, or nil when it is on its way. Answers in edit
mode as well as play mode, for what the relay carries in each: in
edit mode scene content is left out of the sync-id pass, so its
changes travel to the other clients with the source they are
written into and it reads `entityNotSynced` here.

**Returns** `ReplicationObservation` — The engine's current replication observation.

```lua
local o = multiplayer.observe()
print(#o.entities .. " entities, " .. o.totals.properties .. " synced properties")
```

## typed/builtin//modules/api/engine/multiplayer/multiplayer/observeComponent {#typed-builtin-modules-api-engine-multiplayer-multiplayer-observecomponent}

```lua
multiplayer.observeComponent(entityId: (string | entityRef), componentType: string) -> SyncedComponent?
```

The registered synced component of the named type on an entity's
record. Matches a fully-qualified type (`@builtin::components.Model`)
and the leaf name it ends in (`Model`) alike.

**Parameters**

- `entityId` `(string | entityRef)` — Entity id or proxy.
- `componentType` `string` — Component type name or its leaf.

**Returns** `SyncedComponent?` — The registered component instance, or nil when none of that type is registered on the entity.

```lua
local c = multiplayer.observeComponent(player, "Health")
print(#c.properties .. " declared properties")
```

## typed/builtin//modules/api/engine/multiplayer/multiplayer/observeEntity {#typed-builtin-modules-api-engine-multiplayer-multiplayer-observeentity}

```lua
multiplayer.observeEntity(entityId: (string | entityRef)) -> EntityReplication?
```

The replication record for one entity — its sync id, owner, room,
and the synced components registered on it.

**Parameters**

- `entityId` `(string | entityRef)` — Entity id or proxy.

**Returns** `EntityReplication?` — The entity's record, or nil when the engine holds no sync record for it.

```lua
local r = multiplayer.observeEntity(e)
for _, c in ipairs(r.components) do print(c.componentType) end
```

## typed/builtin//modules/api/engine/multiplayer/multiplayer/on {#typed-builtin-modules-api-engine-multiplayer-multiplayer-on}

```lua
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.

## typed/builtin//modules/api/engine/multiplayer/multiplayer/recordSpawn {#typed-builtin-modules-api-engine-multiplayer-multiplayer-recordspawn}

```lua
multiplayer.recordSpawn(entityId: string)
```

Adopt an existing entity into the open operation as its spawn —
for flows that create an entity before the operation opens (a drag
preview adopted on drop). Undoing the operation despawns it.

**Parameters**

- `entityId` `string` — Entity id to record as spawned by this operation.

```lua
multiplayer.recordSpawn(id)
```

## typed/builtin//modules/api/engine/multiplayer/multiplayer/redo {#typed-builtin-modules-api-engine-multiplayer-multiplayer-redo}

```lua
multiplayer.redo() -> boolean
```

Redo this client's last undone operation.

**Returns** `boolean` — True if an operation was redone.

## typed/builtin//modules/api/engine/multiplayer/multiplayer/releaseOwnership {#typed-builtin-modules-api-engine-multiplayer-multiplayer-releaseownership}

```lua
multiplayer.releaseOwnership(entityId: (string | entityRef)?) -> boolean
```

Release ownership of an entity.

**Parameters**

- `entityId` `(string | entityRef)` _(optional)_ — Entity id or proxy to release.

**Returns** `boolean` — True if ownership was released.

## typed/builtin//modules/api/engine/multiplayer/multiplayer/roomFor {#typed-builtin-modules-api-engine-multiplayer-multiplayer-roomfor}

```lua
multiplayer.roomFor(entityId: (string | entityRef)) -> string?
```

The room key an entity's spawns and property deltas broadcast into.

**Parameters**

- `entityId` `(string | entityRef)` — Entity id or proxy.

**Returns** `string?` — The room key, or nil when the engine has established no scene context for the entity.

```lua
local key = multiplayer.roomFor(player)
if key then multiplayer.joinRoom(key) end
```

## typed/builtin//modules/api/engine/multiplayer/multiplayer/send {#typed-builtin-modules-api-engine-multiplayer-multiplayer-send}

```lua
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.

**Parameters**

- `channel` `string` — Channel name listeners subscribe to via `multiplayer.on`.
- `...` `any` _(optional)_ — Zero or more values delivered to each listener after the sender's peer id.

## typed/builtin//modules/api/engine/multiplayer/multiplayer/syncTotals {#typed-builtin-modules-api-engine-multiplayer-multiplayer-synctotals}

```lua
multiplayer.syncTotals() -> SyncTotals
```

What the sync registry holds across every entity: entities with a
registered synced component, component instances, declared properties,
declared functions, and the component instances holding a dirty
property this tick.

**Returns** `SyncTotals` — The registry totals.

```lua
print(multiplayer.syncTotals().properties .. " synced properties registered")
```

## typed/builtin//modules/api/engine/multiplayer/multiplayer/undo {#typed-builtin-modules-api-engine-multiplayer-multiplayer-undo}

```lua
multiplayer.undo() -> boolean
```

Undo this client's last edit-mode operation.

**Returns** `boolean` — True if an operation was undone.

## typed/builtin//modules/api/engine/notices/notices/post {#typed-builtin-modules-api-engine-notices-notices-post}

```lua
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.

**Parameters**

- `template` `string` — Fixed sentence identifying the notice.
- `params` `{ [string]: any }` _(optional)_ — Optional table of named values rendered alongside the template.
- `opts` `NoticeOpts` _(optional)_ — Optional table: severity ("info" | "warn" | "error"), includeLocation (boolean).

```lua
notices.post("wave complete", { wave = 3 })
notices.post("save slot corrupted, using defaults", { slot = id }, { severity = "warn" })
```

## typed/builtin//modules/api/engine/packages/packages/list {#typed-builtin-modules-api-engine-packages-packages-list}

```lua
packages.list() -> { PackageEntry }
```

List every registered package across scopes.

## typed/builtin//modules/api/engine/packages/packages/lookup {#typed-builtin-modules-api-engine-packages-packages-lookup}

```lua
packages.lookup(name_or_scope: string, name: string?) -> PackageEntry?
```

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

**Parameters**

- `name_or_scope` `string` — Package name, or scope if a second arg is given.
- `name` `string` _(optional)_ — Package name when the first arg is a scope.

**Returns** `PackageEntry?` — Package entry or nil.

```lua
local p = packages.lookup("@builtin", "audio")
```

## typed/builtin//modules/api/engine/particles/particles/create {#typed-builtin-modules-api-engine-particles-particles-create}

```lua
particles.create(spec: table?) -> any
```

Create a GPU particle system from a spec, allocating its buffers and
registering it with the auto-update driver. The handle it returns carries
`:emit`, `:update`, the setters, `:observe`, and `:getCreator`.

## typed/builtin//modules/api/engine/particles/particles/list {#typed-builtin-modules-api-engine-particles-particles-list}

```lua
particles.list(filter: (string | ParticleCreatorFilter)?) -> { any }
```

Every particle system this VM has created and not destroyed, in
creation order — or, given a filter, the ones whose creator matches it.
Answered from the emitter registry, so finding an emitter costs nothing per
entity in the scene.

Called with nothing it answers with every emitter in the VM, which is what
makes it the way to reach one whose creator has lost its handle, and
`:getCreator()` on an entry says whose that one is. A filter narrows it to
one creator's own, so a module clears what a previous load of it left
behind and leaves every other emitter in the world standing.

## typed/builtin//modules/api/engine/particles/particles/observe {#typed-builtin-modules-api-engine-particles-particles-observe}

```lua
particles.observe(system: any?) -> { [string]: any }
```

What the engine is simulating and drawing for particles right now.
With no argument, every live emitter plus the totals they sum to; with an
emitter, that one's reading. An engine holding no emitters answers
`count = 0` with an empty list, which reads differently from an engine
whose emitters are all silent (`count > 0`, `silent = count`).

**Parameters**

- `system` `any` _(optional)_ — Optional particle system handle to read on its own.

**Returns** `{ [string]: any }` — table The observation.

```lua
local o = particles.observe(); print(o.count, o.alive, o.silent)
local r = particles.observe(fire); print(r.alive, r.bytes.total)
```

## typed/builtin//modules/api/engine/particles/particles/silenceReasons {#typed-builtin-modules-api-engine-particles-particles-silencereasons}

```lua
particles.silenceReasons() -> { { reason: string, means: string } }
```

The closed set of reasons an emitter can be producing nothing, in the
order a reading resolves them — nearest cause first — each with what it
means. Every `observe().reason` is one of these.

**Returns** `{ { reason: string, means: string } }` — table Array of `{ reason, means }`.

```lua
for _, r in ipairs(particles.silenceReasons()) do print(r.reason, r.means) end
```

## typed/builtin//modules/api/engine/particles/particles/whySilent {#typed-builtin-modules-api-engine-particles-particles-whysilent}

```lua
particles.whySilent(system: any?) -> (string?, string?)
```

Why one emitter is producing nothing, from the closed set
`silenceReasons()` enumerates — or nil when it is producing. The second
return is the detail line naming what the reason is about.

**Parameters**

- `system` `any` _(optional)_ — The particle system handle to ask about.

**Returns** `(string?, string?)` — string? The reason, or nil. string? The detail line for that reason.

```lua
local why, detail = particles.whySilent(fire)
```

## typed/builtin//modules/api/engine/physics/P/addCollider {#typed-builtin-modules-api-engine-physics-p-addcollider}

```lua
P.addCollider(entityId: string | entityRef, component: string, config: table?)
```

Add a collider component to an entity, naming the shape you want.

**Parameters**

- `entityId` `string | entityRef` — Target entity id.
- `component` `string` — One of `Physics.COLLIDER_COMPONENTS`.
- `config` `table` _(optional)_ — The component's own fields, e.g. `{ radius = 0.5 }` for a sphere.

```lua
Physics.addCollider(id, "SphereCollider", { radius = 0.5 })
```

## typed/builtin//modules/api/engine/physics/P/addConstraint {#typed-builtin-modules-api-engine-physics-p-addconstraint}

```lua
P.addConstraint(entityId: string | entityRef, opts: table?)
```

Add a transform constraint to an entity.

**Parameters**

- `entityId` `string | entityRef` — Target entity id.
- `opts` `table` _(optional)_ — Optional constraint description (targetEntityId, position, rotation, scale, lookAt, targetPosition, axes, weight).

```lua
Physics.addConstraint(id, { targetEntityId = parent, position = true })
```

## typed/builtin//modules/api/engine/physics/P/addJoint {#typed-builtin-modules-api-engine-physics-p-addjoint}

```lua
P.addJoint(entityIdA: string | entityRef, entityIdB: string | entityRef, 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`).

**Parameters**

- `entityIdA` `string | entityRef` — Entity that hosts the Joint component.
- `entityIdB` `string | entityRef` — Connected entity.
- `opts` `table` _(optional)_ — Optional joint description (kind, anchors, axis, stiffness, damping, restLength, maxDistance, breakForce, breakTorque).

```lua
Physics.addJoint(a, b, { kind = "fixed" })
Physics.addJoint(a, b, { kind = "hinge", axis = {x=0,y=1,z=0} })
Physics.addJoint(a, b, { kind = "rope", maxDistance = 8 })
Physics.addJoint(a, b, { kind = "fixed", breakForce = 1200, breakTorque = 800 })
```

## typed/builtin//modules/api/engine/physics/P/addVelocity {#typed-builtin-modules-api-engine-physics-p-addvelocity}

```lua
P.addVelocity(a: string | entityRef | number | vec3, b: (number | vec3)?, c: number?, d: number?)
```

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

**Parameters**

- `a` `string | entityRef | number | vec3` — dx, a `{x, y, z}` delta vector, or an entity id (explicit target).
- `b` `(number | vec3)` _(optional)_ — dy, dx, or the delta vector depending on call form.
- `c` `number` _(optional)_ — dz or dy depending on call form.
- `d` `number` _(optional)_ — Optional dz when targeting an explicit entity.

```lua
Physics.addVelocity(0, 5, 0)
Physics.addVelocity(entityId, 0, 5, 0)
Physics.addVelocity(entityId, {x=0, y=5, z=0})
```

## typed/builtin//modules/api/engine/physics/P/addWheelCollider {#typed-builtin-modules-api-engine-physics-p-addwheelcollider}

```lua
P.addWheelCollider(entityId: string | entityRef, 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.

**Parameters**

- `entityId` `string | entityRef` — Target entity id.
- `config` `table` _(optional)_ — Optional wheel configuration (`radius?`, `suspensionDistance?`, `springRate?`, `damperRate?`, `motorTorque?`, `brakeTorque?`, `steerAngle?`, `forwardFriction?`, `sidewaysFriction?`, `is2D?`).

```lua
Physics.addWheelCollider(id, { radius = 0.35, motorTorque = 500 })
```

## typed/builtin//modules/api/engine/physics/P/applyForce {#typed-builtin-modules-api-engine-physics-p-applyforce}

```lua
P.applyForce(entityIdOrForce: string | entityRef | 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.

**Parameters**

- `entityIdOrForce` `string | entityRef | vec3` — Entity id (when paired with `force`) OR a force vector for the script-context entity.
- `force` `vec3` _(optional)_ — Optional force vector when targeting an explicit entity.

```lua
Physics.applyForce({x=0, y=10, z=0})
Physics.applyForce(entityId, {x=0, y=10, z=0})
```

## typed/builtin//modules/api/engine/physics/P/applyForceAtPoint {#typed-builtin-modules-api-engine-physics-p-applyforceatpoint}

```lua
P.applyForceAtPoint(entityId: string | entityRef, force: vec3, point: vec3)
```

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

**Parameters**

- `entityId` `string | entityRef` — Target entity id.
- `force` `vec3` — Force vector.
- `point` `vec3` — World-space application point.

```lua
Physics.applyForceAtPoint(id, {x=0,y=10,z=0}, {x=1,y=0,z=0})
```

## typed/builtin//modules/api/engine/physics/P/applyImpulse {#typed-builtin-modules-api-engine-physics-p-applyimpulse}

```lua
P.applyImpulse(entityIdOrImpulse: string | entityRef | 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.

**Parameters**

- `entityIdOrImpulse` `string | entityRef | vec3` — Entity id (with `impulse`) OR an impulse vector for the script-context entity.
- `impulse` `vec3` _(optional)_ — Optional impulse vector when targeting an explicit entity.

```lua
Physics.applyImpulse({x=0, y=5, z=0})
Physics.applyImpulse(entityId, {x=0, y=5, z=0})
```

## typed/builtin//modules/api/engine/physics/P/applyTorque {#typed-builtin-modules-api-engine-physics-p-applytorque}

```lua
P.applyTorque(entityIdOrTorque: string | entityRef | 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.

**Parameters**

- `entityIdOrTorque` `string | entityRef | vec3` — Entity id (with `torque`) OR a torque vector for the script-context entity.
- `torque` `vec3` _(optional)_ — Optional torque vector when targeting an explicit entity.

```lua
Physics.applyTorque({x=0, y=1, z=0})
Physics.applyTorque(entityId, {x=0, y=1, z=0})
```

## typed/builtin//modules/api/engine/physics/P/bodyState {#typed-builtin-modules-api-engine-physics-p-bodystate}

```lua
P.bodyState(entityId: string | entityRef) -> PhysicsBodyState?
```

Everything the solver holds for one body — its type, mass, centre of
mass, inertia, gravity scale, damping, lock flags, CCD, collision groups,
sleep state, velocities, the force and torque queued for the next step,
its colliders, contacts, joints and transform constraints, and why it is
not moving.

**Parameters**

- `entityId` `string | entityRef` — Entity id or proxy.

**Returns** `PhysicsBodyState?` — A `PhysicsBodyState` — with `exists = false` for an entity that carries no rigid body — or `nil` when nothing in the scene answers to that id.

```lua
local b = Physics.bodyState(id); print(b.bodyType, b.mass, b.stillness)
if not Physics.bodyState(id).exists then print("no body was built") end
```

## typed/builtin//modules/api/engine/physics/P/boxCast {#typed-builtin-modules-api-engine-physics-p-boxcast}

```lua
P.boxCast(origin: vec3, halfExtents: vec3, direction: vec3, maxDistance: number?, exclude: (string | {string})?) -> table?
```

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

**Parameters**

- `origin` `vec3` — Box center at the start of the cast.
- `halfExtents` `vec3` — Half the size of the box on each axis.
- `direction` `vec3` — Cast direction.
- `maxDistance` `number` _(optional)_ — Optional distance limit.
- `exclude` `(string | {string})` _(optional)_ — Optional entity id, or array of entity ids, to exclude from hits.
Applied while sweeping rather than to the answer, so a cast that starts
inside an excluded collider reports what is behind it.

**Returns** `table?` — Hit table `{ entityId, point, normal, distance, startedInside }`, or `nil` if nothing hit. `startedInside` is `false` for a surface the query crossed on its way there, and `true` when the query's own start already lay inside that collider — where `distance` is 0, `point` is the start itself, and `normal` is the shortest way out of the collider. `normal` is a unit vector either way.

```lua
local hit = Physics.boxCast(o, {x=0.5,y=0.5,z=0.5}, dir, 10)
local hit = Physics.boxCast(o, {x=0.5,y=0.5,z=0.5}, dir, 10, { selfId, carriedId })
```

## typed/builtin//modules/api/engine/physics/P/capsuleCast {#typed-builtin-modules-api-engine-physics-p-capsulecast}

```lua
P.capsuleCast(origin: vec3, radius: number, halfHeight: number, direction: vec3, maxDistance: number?, exclude: (string | {string})?) -> table?
```

Cast an upright capsule along a direction and return the first hit.
This is the sweep that answers whether a body of that shape fits through
a passage: a capsule of radius `r` reports a hit on anything that leaves
it less than `2 * r` of clearance.

**Parameters**

- `origin` `vec3` — Capsule centre at the start of the cast.
- `radius` `number` — Capsule radius.
- `halfHeight` `number` — Distance from the centre to either cap centre. The capsule
stands `halfHeight + radius` tall in each direction.
- `direction` `vec3` — Cast direction.
- `maxDistance` `number` _(optional)_ — Optional distance limit.
- `exclude` `(string | {string})` _(optional)_ — Optional entity id, or array of entity ids, to exclude from hits.
Applied while sweeping rather than to the answer, so a cast that starts
inside an excluded collider reports what is behind it.

**Returns** `table?` — Hit table `{ entityId, point, normal, distance, startedInside }`, or `nil` if nothing hit. `startedInside` is `false` for a surface the query crossed on its way there, and `true` when the query's own start already lay inside that collider — where `distance` is 0, `point` is the start itself, and `normal` is the shortest way out of the collider. `normal` is a unit vector either way.

```lua
local hit = Physics.capsuleCast(o, 0.3, 0.6, dir, 0.5)
local hit = Physics.capsuleCast(o, 0.3, 0.6, dir, 0.5, selfId)
```

## typed/builtin//modules/api/engine/physics/P/colliderCount {#typed-builtin-modules-api-engine-physics-p-collidercount}

```lua
P.colliderCount() -> number
```

How many colliders the physics world holds. Zero means no ray, cast or
overlap fired into this world can hit anything, so it is what separates a
query that MISSED from a query fired into a world that holds nothing to
hit. Read off the collider set itself, so it costs the same whatever the
world holds.

**Returns** `number` — colliders across the whole physics world.

```lua
if Physics.colliderCount() == 0 then print("nothing here is solid") end
```

## typed/builtin//modules/api/engine/physics/P/colliderGeometry {#typed-builtin-modules-api-engine-physics-p-collidergeometry}

```lua
P.colliderGeometry(options: table?) -> table?
```

Read the physics world as drawable triangles: every collider
triangulated in world space into one indexed mesh, in GPU buffers ready to
draw.

Box, sphere, capsule, cylinder, cone, convex, triangle-mesh and heightfield
colliders return their real surface, and a compound returns its children
folded together; a shape with no triangulation returns its bounding box and
reports `exact = false`.

`options.colors` is POSITIONAL over `colliderManifest()` — entry `i` colours
collider `i` — so you can colour by role, shape, entity or anything else you
read there. A position you leave out takes `options.defaultColor`.

The returned buffers are yours: destroy them when you replace them.

**Parameters**

- `options` `table` _(optional)_ — `{ tessellation = "low"|"medium"|"high", colors = { {r,g,b,a}, ... }, defaultColor = {r,g,b,a} }`.

**Returns** `table?` — `{ vertices, indices, vertexCount, indexCount, colliders }` where each entry of `colliders` is `{ entity, colliderName?, shapeType, role, exact, firstIndex, indexCount }`.

```lua
local geo = Physics.colliderGeometry({ tessellation = "high" })
```

## typed/builtin//modules/api/engine/physics/P/colliderManifest {#typed-builtin-modules-api-engine-physics-p-collidermanifest}

```lua
P.colliderManifest() -> table
```

List every physics collider in the world with what it is and what it
takes part in — no geometry, so it is the cheap read to make before
deciding what to do with each one.

`role` is one of `static`, `dynamic`, `kinematic`, `sensor`. A sensor
is a collider the simulation holds as one, reported ahead of the body type
behind it, and a collider with no rigid body is static. `exact` says whether `colliderGeometry` would return this
collider's true surface or its bounding box.

Every collider of one entity shares its `entity`, so this is what to key
per-object decisions on. The order is stable across calls over an unchanged
world, which is what makes `colliderGeometry`'s positional colours usable.

**Returns** `table` — Array of `{ entity, colliderName?, shapeType, role, exact }`.

```lua
for _, c in ipairs(Physics.colliderManifest()) do print(c.entity, c.role) end
```

## typed/builtin//modules/api/engine/physics/P/colliderOn {#typed-builtin-modules-api-engine-physics-p-collideron}

```lua
P.colliderOn(entityId: string | entityRef) -> string?
```

Which collider component an entity carries, or nil when it carries none.

**Parameters**

- `entityId` `string | entityRef` — Target entity id.

**Returns** string? The component name, e.g. "SphereCollider".

```lua
local which = Physics.colliderOn(id)
```

## typed/builtin//modules/api/engine/physics/P/colliderShapes {#typed-builtin-modules-api-engine-physics-p-collidershapes}

```lua
P.colliderShapes(entityId: string | entityRef) -> table
```

Read an entity's resolved physics collider shape(s) as the physics
engine sees them, including auto-sized colliders.

`shapeType` is one of `box`, `sphere`, `capsule`, `convex`, `mesh`,
`heightfield`, `compound`, `other` — the shape the simulation is
running, so a mesh collider reads `mesh`.

`params` carries half-extents for a box, radius for a sphere, radius
and half-height for a capsule, and the collider's bounding half-extents
for the shapes that have no parametric description. A convex collider
reports its outline in `linePoints` instead.

**Parameters**

- `entityId` `string | entityRef` — Target entity id.

**Returns** `table` — Array of resolved collider shapes (empty if none): `{ shapeType, position, rotation, params, linePoints, name? }`.

```lua
local shapes = Physics.colliderShapes(id)
```

## typed/builtin//modules/api/engine/physics/P/contacts {#typed-builtin-modules-api-engine-physics-p-contacts}

```lua
P.contacts(entityId: string | entityRef) -> { PhysicsContact }
```

Every contact one body's colliders are in right now, with the other
entity, the normal, how deeply the two interpenetrate, the impulse the
last step applied, and each contact point.

**Parameters**

- `entityId` `string | entityRef` — Entity id or proxy.

**Returns** `{ PhysicsContact }` — An array of `PhysicsContact` — empty when the body touches nothing, or when the entity carries no rigid body.

```lua
for _, c in Physics.contacts(id) do print(c.other, c.deepestPenetration) end
```

## typed/builtin//modules/api/engine/physics/P/getAngularVelocity {#typed-builtin-modules-api-engine-physics-p-getangularvelocity}

```lua
P.getAngularVelocity(entityId: (string | entityRef)?) -> vec3?
```

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

**Parameters**

- `entityId` `(string | entityRef)` _(optional)_ — Target entity id or proxy; resolves from script context when omitted.

**Returns** `vec3?` — Angular velocity in rad/s, or `nil` if the entity has no rigid body.

```lua
local w = Physics.getAngularVelocity(id)
```

## typed/builtin//modules/api/engine/physics/P/getGravity {#typed-builtin-modules-api-engine-physics-p-getgravity}

```lua
P.getGravity() -> vec3
```

Read the current world gravity vector.

**Returns** `vec3` — Gravity vector in m/s² (negative y is "down" in the default world).

```lua
local g = Physics.getGravity()
```

## typed/builtin//modules/api/engine/physics/P/getVelocity {#typed-builtin-modules-api-engine-physics-p-getvelocity}

```lua
P.getVelocity(entityId: (string | entityRef)?) -> vec3?
```

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

**Parameters**

- `entityId` `(string | entityRef)` _(optional)_ — Target entity id or proxy; resolves from script context when omitted.

**Returns** `vec3?` — Velocity in m/s, or `nil` if the entity has no rigid body.

```lua
local v = Physics.getVelocity(id)
```

## typed/builtin//modules/api/engine/physics/P/getWheelState {#typed-builtin-modules-api-engine-physics-p-getwheelstate}

```lua
P.getWheelState(entityId: string | entityRef) -> table?
```

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

**Parameters**

- `entityId` `string | entityRef` — Target entity id (must carry a WheelCollider component).

**Returns** `table?` — `{ isGrounded, compression, angularVelocity }`, or `nil` if the component is absent.

```lua
local state = Physics.getWheelState(id)
```

## typed/builtin//modules/api/engine/physics/P/hasLineOfSight {#typed-builtin-modules-api-engine-physics-p-haslineofsight}

```lua
P.hasLineOfSight(fromId: string, toId: string) -> boolean
```

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

**Parameters**

- `fromId` `string` — Viewer entity id.
- `toId` `string` — Target entity id.

**Returns** `boolean` — `true` when no collider sits between them (including coincident origins), `false` otherwise.

```lua
if Physics.hasLineOfSight(a, b) then ... end
```

## typed/builtin//modules/api/engine/physics/P/ignoreCollision {#typed-builtin-modules-api-engine-physics-p-ignorecollision}

```lua
P.ignoreCollision(entityIdA: string | entityRef, entityIdB: string | entityRef, ignore: boolean?)
```

Toggle ignored-collision state between two specific entities.

**Parameters**

- `entityIdA` `string | entityRef` — First entity id.
- `entityIdB` `string | entityRef` — Second entity id.
- `ignore` `boolean` _(optional)_ — When `true` (default) collisions between the pair are skipped.

```lua
Physics.ignoreCollision(a, b, true)
```

## typed/builtin//modules/api/engine/physics/P/isSleeping {#typed-builtin-modules-api-engine-physics-p-issleeping}

```lua
P.isSleeping(entityId: (string | entityRef)?) -> 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.

**Parameters**

- `entityId` `(string | entityRef)` _(optional)_ — Target entity id or proxy; resolves from script context when omitted.

**Returns** `boolean?` — `true` if asleep, `false` if awake, or `nil` if the entity has no rigid body.

```lua
if Physics.isSleeping(id) then Physics.wakeUp(id) end
```

## typed/builtin//modules/api/engine/physics/P/jointBreaks {#typed-builtin-modules-api-engine-physics-p-jointbreaks}

```lua
P.jointBreaks() -> table
```

Every joint that has broken since the last call to this function.
A joint breaks when the reaction it carries exceeds the `breakForce`
(newtons of linear reaction) or `breakTorque` (the angular row of the same
reaction) its joint was given; each joint
reports once and its constraint is already released when the record
arrives. The 256 most recent are kept: a structure that comes apart while
nothing reads them drops the oldest beyond that, as the engine's own queue
does beyond 1024.

**Returns** `table` — Array of `{ entityId, connectedEntityId, kind, impulse, angularImpulse, force, torque, position }`, oldest first.

```lua
for _, e in ipairs(Physics.jointBreaks()) do print(e.entityId, e.force) end
```

## typed/builtin//modules/api/engine/physics/P/jointReaction {#typed-builtin-modules-api-engine-physics-p-jointreaction}

```lua
P.jointReaction(entityId: string | entityRef) -> table?
```

The load an entity's joint is carrying right now, as the constraint
solver resolved it on the last physics step. This is the same quantity a
break threshold is measured against, so it is what to size `breakForce`
and `breakTorque` from.

**Parameters**

- `entityId` `string | entityRef` — Entity carrying the Joint component.

**Returns** `table?` — `{ impulse, angularImpulse, force, torque, position }`, or `nil` when the entity owns no joint.

```lua
local r = Physics.jointReaction(id); print(r and r.force)
```

## typed/builtin//modules/api/engine/physics/P/observe {#typed-builtin-modules-api-engine-physics-p-observe}

```lua
P.observe(entityId: (string | entityRef)?, opts: table?) -> PhysicsObservation?
```

Read the solver's own state — the world's accounting, and what it
holds for each body plus why it is not moving one. Every value comes off
the simulation rather than the `Physics` component, so a write the solver
refused or clamped reads back as what it kept. Answers in edit mode as
well as play mode.

**Parameters**

- `entityId` `(string | entityRef)` _(optional)_ — Report on this one entity. Omit for every body in the world.
- `opts` `table` _(optional)_ — `{ bodies: boolean?, contactPoints: boolean? }` — `bodies = false`
builds the world accounting alone, and `contactPoints = false` keeps each
contact pair's normal, depth, impulse and point count while leaving out
the individual points. Both default to true.

**Returns** `PhysicsObservation?` — A `PhysicsObservation`, or `nil` when `entityId` names nothing in the scene. `bodies` is an array, not a table keyed by entity id — each entry names its own entity in `entity`.

```lua
local o = Physics.observe(); for _, b in o.bodies do print(b.entity, b.stillness) end
local o = Physics.observe(id); print(o.bodies[1].stillness, o.bodies[1].stillnessDetail)
```

## typed/builtin//modules/api/engine/physics/P/onJointBreak {#typed-builtin-modules-api-engine-physics-p-onjointbreak}

```lua
P.onJointBreak(fn: (table) -> ()) -> () -> ()
```

Call `fn` for every joint that breaks from now on, with the same record
`jointBreaks` returns.

**Parameters**

- `fn` `(table) -> ()` — Receives one break record per broken joint.

**Returns** `() -> ()` — A function that removes this listener.

```lua
local off = Physics.onJointBreak(function(e) print(e.kind, e.force, e.position) end)
```

## typed/builtin//modules/api/engine/physics/P/overlapSphere {#typed-builtin-modules-api-engine-physics-p-overlapsphere}

```lua
P.overlapSphere(center: vec3, radius: number) -> table
```

Find every entity id whose colliders overlap a sphere.

**Parameters**

- `center` `vec3` — Sphere center in world space.
- `radius` `number` — Sphere radius.

**Returns** `table` — Array of overlapping entity ids.

```lua
local ids = Physics.overlapSphere({x=0,y=0,z=0}, 5)
```

## typed/builtin//modules/api/engine/physics/P/pumpJointBreaks {#typed-builtin-modules-api-engine-physics-p-pumpjointbreaks}

```lua
P.pumpJointBreaks()
```

Deliver every joint break the simulation has recorded to the registered
listeners. An enabled `Joint` component calls this each tick, so listeners
fire on their own wherever joints come from that component. A joint made by
writing `ecs.PhysicsJoint` directly has no such tick behind it — call this
each frame, or poll `jointBreaks`, to deliver its breaks.

```lua
Physics.pumpJointBreaks()
```

## typed/builtin//modules/api/engine/physics/P/raycast {#typed-builtin-modules-api-engine-physics-p-raycast}

```lua
P.raycast(origin: vec3, direction: vec3, maxDistance: number?, exclude: (string | {string})?) -> table?
```

Cast a ray and return the first hit. Answers from COLLIDERS ALONE: a
mesh that renders but carries no collider is not in the physics world, so a
ray fired through it reports the same `nil` a ray through open air does.
`renderer.raycast` answers the same ray against the geometry the renderer
DRAWS, which is what reads the surface of a terrain, a procedurally
generated mesh, or any plain `Model`.

**Parameters**

- `origin` `vec3` — Ray origin in world space.
- `direction` `vec3` — Ray direction (does not need to be unit-length; the engine normalises).
- `maxDistance` `number` _(optional)_ — Maximum distance along the ray (defaults to 1000).
- `exclude` `(string | {string})` _(optional)_ — Optional entity id, or array of entity ids, to exclude from hits.

**Returns** `table?` — Hit table `{ entityId, point, normal, distance, startedInside }`, or `nil` if nothing hit. `startedInside` is `false` for a surface the query crossed on its way there, and `true` when the query's own start already lay inside that collider — where `distance` is 0, `point` is the start itself, and `normal` is the shortest way out of the collider. `normal` is a unit vector either way. A `nil` says the ray met no COLLIDER, which `Physics.colliderCount()` separates from a world that holds none for it to meet.

```lua
local hit = Physics.raycast({x=0,y=2,z=0}, {x=0,y=-1,z=0})
local hit = Physics.raycast(origin, dir, 50, { selfId, carriedId })
if Physics.colliderCount() == 0 then hit = renderer.raycast(eye, down, 200) end
```

## typed/builtin//modules/api/engine/physics/P/raycastAll {#typed-builtin-modules-api-engine-physics-p-raycastall}

```lua
P.raycastAll(origin: vec3, direction: vec3, maxDistance: number?, maxHits: number?, exclude: (string | {string})?) -> table
```

Cast a ray and return every hit up to `maxHits`. Answers from COLLIDERS
ALONE, so a rendered mesh with no collider is absent from the result;
`renderer.raycastAll` answers the same ray against the geometry the
renderer draws.

**Parameters**

- `origin` `vec3` — Ray origin in world space.
- `direction` `vec3` — Ray direction.
- `maxDistance` `number` _(optional)_ — Optional distance limit along the ray.
- `maxHits` `number` _(optional)_ — Optional cap on the number of hits returned.
- `exclude` `(string | {string})` _(optional)_ — Optional entity id, or array of entity ids, to exclude from hits.

**Returns** `table` — Array of hit tables `{ entityId, point, normal, distance, startedInside }` — empty when nothing was hit. `startedInside` is `false` for a surface the query crossed on its way there, and `true` when the query's own start already lay inside that collider — where `distance` is 0, `point` is the start itself, and `normal` is the shortest way out of the collider. `normal` is a unit vector either way.

```lua
local hits = Physics.raycastAll(origin, dir, 50, 4)
```

## typed/builtin//modules/api/engine/physics/P/raycastBetween {#typed-builtin-modules-api-engine-physics-p-raycastbetween}

```lua
P.raycastBetween(fromId: string, toId: string, maxDistance: number?) -> table?
```

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

**Parameters**

- `fromId` `string` — Origin entity id.
- `toId` `string` — Target entity id.
- `maxDistance` `number` _(optional)_ — Optional distance cap (default 1000).

**Returns** `table?` — Hit table, or `nil` if the entities are coincident or nothing was hit.

```lua
local hit = Physics.raycastBetween(a, b)
```

## typed/builtin//modules/api/engine/physics/P/raycastScreen {#typed-builtin-modules-api-engine-physics-p-raycastscreen}

```lua
P.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`.

**Parameters**

- `sx` `number` — Screen X in viewport-local pixels (the space of `input.mouse_position` and `screenToRay`).
- `sy` `number` — Screen Y in viewport-local pixels.
- `maxDistance` `number` _(optional)_ — Maximum distance along the ray (defaults to 1000, matching `raycast`).
- `exclude` `(string | {string})` _(optional)_ — Optional entity id, or array of entity ids, to exclude from hits.

**Returns** `table?` — Hit table `{ entityId, point, normal, distance, startedInside }`, or `nil` on a miss or when no camera has rendered yet. `startedInside` is `false` for a surface the query crossed on its way there, and `true` when the query's own start already lay inside that collider — where `distance` is 0, `point` is the start itself, and `normal` is the shortest way out of the collider. `normal` is a unit vector either way.

```lua
local m = input.mouse_position; local hit = Physics.raycastScreen(m[1], m[2])
```

## typed/builtin//modules/api/engine/physics/P/removeCollider {#typed-builtin-modules-api-engine-physics-p-removecollider}

```lua
P.removeCollider(entityId: string | entityRef) -> string?
```

Remove whichever collider component an entity carries.

**Parameters**

- `entityId` `string | entityRef` — Target entity id.

**Returns** string? The component that was removed, or nil when there was none.

```lua
Physics.removeCollider(id)
```

## typed/builtin//modules/api/engine/physics/P/removeConstraint {#typed-builtin-modules-api-engine-physics-p-removeconstraint}

```lua
P.removeConstraint(entityId: string | entityRef, index: number?)
```

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

**Parameters**

- `entityId` `string | entityRef` — Target entity id.
- `index` `number` _(optional)_ — Optional constraint index (currently ignored — the whole component is removed).

```lua
Physics.removeConstraint(id)
```

## typed/builtin//modules/api/engine/physics/P/removeJoint {#typed-builtin-modules-api-engine-physics-p-removejoint}

```lua
P.removeJoint(entityId: string | entityRef)
```

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

**Parameters**

- `entityId` `string | entityRef` — Target entity id.

```lua
Physics.removeJoint(id)
```

## typed/builtin//modules/api/engine/physics/P/removeWheelCollider {#typed-builtin-modules-api-engine-physics-p-removewheelcollider}

```lua
P.removeWheelCollider(entityId: string | entityRef)
```

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

**Parameters**

- `entityId` `string | entityRef` — Target entity id.

```lua
Physics.removeWheelCollider(id)
```

## typed/builtin//modules/api/engine/physics/P/setAngularDamping {#typed-builtin-modules-api-engine-physics-p-setangulardamping}

```lua
P.setAngularDamping(entityIdOrDamping: string | entityRef | number, damping: number?)
```

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

**Parameters**

- `entityIdOrDamping` `string | entityRef | number` — Entity id (with `damping`) OR damping value (script-context entity).
- `damping` `number` _(optional)_ — Optional explicit damping when targeting another entity.

```lua
Physics.setAngularDamping(0.1)
Physics.setAngularDamping(entityId, 0.1)
```

## typed/builtin//modules/api/engine/physics/P/setAngularVelocity {#typed-builtin-modules-api-engine-physics-p-setangularvelocity}

```lua
P.setAngularVelocity(a: string | entityRef | number | vec3, b: (number | vec3)?, c: number?, d: number?)
```

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

**Parameters**

- `a` `string | entityRef | number | vec3` — x-component, a `{x, y, z}` vector, or an entity id (explicit target).
- `b` `(number | vec3)` _(optional)_ — y-component, x-component, or the vector depending on call form.
- `c` `number` _(optional)_ — z-component or y-component depending on call form.
- `d` `number` _(optional)_ — Optional z-component when targeting an explicit entity.

```lua
Physics.setAngularVelocity(0, 0, 1)
Physics.setAngularVelocity(entityId, 0, 0, 1)
Physics.setAngularVelocity(entityId, {x=0, y=0, z=1})
```

## typed/builtin//modules/api/engine/physics/P/setBodyType {#typed-builtin-modules-api-engine-physics-p-setbodytype}

```lua
P.setBodyType(entityId: string | entityRef, 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.

**Parameters**

- `entityId` `string | entityRef` — Target entity id.
- `bodyType` `string` — One of `"dynamic"`, `"kinematic"`, `"static"`.

```lua
Physics.setBodyType(entityId, "kinematic")
```

## typed/builtin//modules/api/engine/physics/P/setCcdEnabled {#typed-builtin-modules-api-engine-physics-p-setccdenabled}

```lua
P.setCcdEnabled(entityIdOrEnabled: string | entityRef | boolean, enabled: boolean?)
```

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

**Parameters**

- `entityIdOrEnabled` `string | entityRef | boolean` — Entity id (with `enabled`) OR boolean (script-context entity).
- `enabled` `boolean` _(optional)_ — Optional explicit boolean when targeting another entity.

```lua
Physics.setCcdEnabled(true)
Physics.setCcdEnabled(entityId, true)
```

## typed/builtin//modules/api/engine/physics/P/setCollisionGroups {#typed-builtin-modules-api-engine-physics-p-setcollisiongroups}

```lua
P.setCollisionGroups(entityId: string | entityRef, membership: number, filter: number)
```

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

**Parameters**

- `entityId` `string | entityRef` — Target entity id.
- `membership` `number` — Bitmask: which groups this collider belongs to.
- `filter` `number` — Bitmask: which groups this collider can collide with.

```lua
Physics.setCollisionGroups(id, 0x0001, 0xFFFF)
```

## typed/builtin//modules/api/engine/physics/P/setGravity {#typed-builtin-modules-api-engine-physics-p-setgravity}

```lua
P.setGravity(gravity: vec3)
```

Replace the world gravity vector.

**Parameters**

- `gravity` `vec3` — New gravity vector in m/s².

```lua
Physics.setGravity({x=0, y=-9.81, z=0})
```

## typed/builtin//modules/api/engine/physics/P/setGravityScale {#typed-builtin-modules-api-engine-physics-p-setgravityscale}

```lua
P.setGravityScale(entityIdOrScale: string | entityRef | number, scale: number?)
```

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

**Parameters**

- `entityIdOrScale` `string | entityRef | number` — Entity id (with `scale`) OR scale value (script-context entity).
- `scale` `number` _(optional)_ — Optional explicit scale when targeting another entity.

```lua
Physics.setGravityScale(0.5)
Physics.setGravityScale(entityId, 0.5)
```

## typed/builtin//modules/api/engine/physics/P/setJointMotor {#typed-builtin-modules-api-engine-physics-p-setjointmotor}

```lua
P.setJointMotor(entityId: string | entityRef, targetVelocity: number, maxForce: number)
```

Set a motor on an entity's joint.

**Parameters**

- `entityId` `string | entityRef` — Target entity id (must carry a Joint component).
- `targetVelocity` `number` — Desired joint velocity.
- `maxForce` `number` — Maximum force the motor can apply.

```lua
Physics.setJointMotor(id, 5.0, 1000)
```

## typed/builtin//modules/api/engine/physics/P/setLinearDamping {#typed-builtin-modules-api-engine-physics-p-setlineardamping}

```lua
P.setLinearDamping(entityIdOrDamping: string | entityRef | number, damping: number?)
```

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

**Parameters**

- `entityIdOrDamping` `string | entityRef | number` — Entity id (with `damping`) OR damping value (script-context entity).
- `damping` `number` _(optional)_ — Optional explicit damping when targeting another entity.

```lua
Physics.setLinearDamping(0.05)
Physics.setLinearDamping(entityId, 0.05)
```

## typed/builtin//modules/api/engine/physics/P/setMass {#typed-builtin-modules-api-engine-physics-p-setmass}

```lua
P.setMass(entityIdOrMass: string | entityRef | number, mass: number?)
```

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

**Parameters**

- `entityIdOrMass` `string | entityRef | number` — Entity id (with `mass`) OR mass value (script-context entity).
- `mass` `number` _(optional)_ — Optional explicit mass when targeting another entity.

```lua
Physics.setMass(10)
Physics.setMass(entityId, 10)
```

## typed/builtin//modules/api/engine/physics/P/setRotationLocks {#typed-builtin-modules-api-engine-physics-p-setrotationlocks}

```lua
P.setRotationLocks(entityId: string | entityRef, x: boolean, y: boolean, z: boolean)
```

Lock or unlock rotation on specific axes.

**Parameters**

- `entityId` `string | entityRef` — Target entity id.
- `x` `boolean` — Lock rotation about the world X axis.
- `y` `boolean` — Lock rotation about the world Y axis.
- `z` `boolean` — Lock rotation about the world Z axis.

```lua
Physics.setRotationLocks(id, false, true, false)
```

## typed/builtin//modules/api/engine/physics/P/setTranslationLocks {#typed-builtin-modules-api-engine-physics-p-settranslationlocks}

```lua
P.setTranslationLocks(entityId: string | entityRef, x: boolean, y: boolean, z: boolean)
```

Lock or unlock translation on specific axes.

**Parameters**

- `entityId` `string | entityRef` — Target entity id.
- `x` `boolean` — Lock translation along the world X axis.
- `y` `boolean` — Lock translation along the world Y axis.
- `z` `boolean` — Lock translation along the world Z axis.

```lua
Physics.setTranslationLocks(id, false, false, true)
```

## typed/builtin//modules/api/engine/physics/P/setVelocity {#typed-builtin-modules-api-engine-physics-p-setvelocity}

```lua
P.setVelocity(a: string | entityRef | 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`.

**Parameters**

- `a` `string | entityRef | number | vec3` — x-component, a `{x, y, z}` vector, or an entity id (explicit target).
- `b` `(number | vec3)` _(optional)_ — y-component, x-component, or the vector depending on call form.
- `c` `number` _(optional)_ — z-component or y-component depending on call form.
- `d` `number` _(optional)_ — Optional z-component when targeting an explicit entity.

```lua
Physics.setVelocity(0, 10, 0)
Physics.setVelocity(entityId, 0, 10, 0)
Physics.setVelocity(entityId, {x=0, y=10, z=0})
```

## typed/builtin//modules/api/engine/physics/P/sphereCast {#typed-builtin-modules-api-engine-physics-p-spherecast}

```lua
P.sphereCast(origin: vec3, radius: number, direction: vec3, maxDistance: number?, exclude: (string | {string})?) -> table?
```

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

**Parameters**

- `origin` `vec3` — Sphere center at the start of the cast.
- `radius` `number` — Sphere radius.
- `direction` `vec3` — Cast direction.
- `maxDistance` `number` _(optional)_ — Optional distance limit.
- `exclude` `(string | {string})` _(optional)_ — Optional entity id, or array of entity ids, to exclude from hits.
Applied while sweeping rather than to the answer, so a cast that starts
inside an excluded collider reports what is behind it.

**Returns** `table?` — Hit table `{ entityId, point, normal, distance, startedInside }`, or `nil` if nothing hit. `startedInside` is `false` for a surface the query crossed on its way there, and `true` when the query's own start already lay inside that collider — where `distance` is 0, `point` is the start itself, and `normal` is the shortest way out of the collider. `normal` is a unit vector either way.

```lua
local hit = Physics.sphereCast(o, 0.5, dir, 10)
local hit = Physics.sphereCast(o, 0.5, dir, 10, selfId)
```

## typed/builtin//modules/api/engine/physics/P/stepCost {#typed-builtin-modules-api-engine-physics-p-stepcost}

```lua
P.stepCost() -> PhysicsStepCost?
```

What the last physics step cost, stage by stage — the same figures
`worldState().step` carries, for a caller that wants only these. Each
covers that one step rather than a window of them, and consecutive steps
over the same resting scene vary by tens of percent, so several samples
averaged is the honest read of what a step costs.

**Returns** `PhysicsStepCost?` — A `PhysicsStepCost`, or `nil` on a frame where the pipeline did not step — a paused simulation, or a world still bootstrapping.

```lua
local c = Physics.stepCost(); if c then print(c.stepMs, c.narrowPhaseMs) end
```

## typed/builtin//modules/api/engine/physics/P/stillnessReasons {#typed-builtin-modules-api-engine-physics-p-stillnessreasons}

```lua
P.stillnessReasons() -> { string }
```

Every reason `whyStill` can answer with, in the order the engine
considers them. Read from the engine, so the list is the one the answers
come from.

**Returns** `{ string }` — An array of reason names.

```lua
for _, reason in Physics.stillnessReasons() do print(reason) end
```

## typed/builtin//modules/api/engine/physics/P/touching {#typed-builtin-modules-api-engine-physics-p-touching}

```lua
P.touching(entityId: string | entityRef, otherId: string | entityRef) -> (boolean, number, { PhysicsContactPoint })
```

Whether two entities are touching, and how deeply.

**Parameters**

- `entityId` `string | entityRef` — Entity id or proxy.
- `otherId` `string | entityRef` — The other entity id or proxy.

**Returns** `(boolean, number, { PhysicsContactPoint })` — `(touching, deepestPenetration, points)` — `deepestPenetration` is in metres and `0` for surfaces that meet without overlapping.

```lua
local hit, depth = Physics.touching(a, b); print(hit, depth)
```

## typed/builtin//modules/api/engine/physics/P/wakeUp {#typed-builtin-modules-api-engine-physics-p-wakeup}

```lua
P.wakeUp(entityId: (string | entityRef)?)
```

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.

**Parameters**

- `entityId` `(string | entityRef)` _(optional)_ — Target entity id or proxy; resolves from script context when omitted.

```lua
Physics.wakeUp(id)
```

## typed/builtin//modules/api/engine/physics/P/whyStill {#typed-builtin-modules-api-engine-physics-p-whystill}

```lua
P.whyStill(entityId: string | entityRef) -> (string?, string?)
```

Why the solver is not moving a body. Returns `nil` when it IS moving
it, and otherwise one of `noBody`, `simulationNotStepping`, `disabled`,
`static`, `kinematic`, `infiniteMass`, `translationLocked`,
`gravityDisabled`, `asleep`, `outsideIsland`, `resting`, `aboutToMove` —
the nearest cause, so the answer names the thing to change. A second return
carries the detail: which collider it rests on and how deeply, what its
effective gravity works out to, and so on.

**Parameters**

- `entityId` `string | entityRef` — Entity id or proxy.

**Returns** `(string?, string?)` — `(reason, detail)`.

```lua
local why, detail = Physics.whyStill(id); if why then print(why, detail) end
```

## typed/builtin//modules/api/engine/physics/P/worldState {#typed-builtin-modules-api-engine-physics-p-worldstate}

```lua
P.worldState() -> PhysicsWorldState
```

How many bodies, colliders, joints and contacts the simulation holds
right now, with world gravity, the timestep, whether the pipeline is
stepping at all, and what the last step cost. Counted off the solver, so
a body that failed to build is absent here while its `Physics` component
still exists.

**Returns** `PhysicsWorldState` — A `PhysicsWorldState`.

```lua
local w = Physics.worldState(); print(w.bodies.awake .. "/" .. w.bodies.total .. " awake")
print(Physics.worldState().contacts.touchingPairs .. " pairs touching")
```

## typed/builtin//modules/api/engine/playerSetupValidation/M/checkActiveScene {#typed-builtin-modules-api-engine-playersetupvalidation-m-checkactivescene}

```lua
M.checkActiveScene() -> { { entity: string, message: string } }
```

Gather every player-setup validation message for the live active-layer
scene: the per-entity rules across all PlayerSpawn / PlayerPrototype entities,
the competing-camera rule, and the scene-intent rule. Returns a flat list an
agent can read to see what to fix. The verdict belongs to the settled scene,
so the call holds while a scene load or a mode-flip transition is rebuilding
the live tree, and judges what the rebuild lands on.

**Returns** `{ { entity: string, message: string } }` — An array of `{ entity = name/id, message = string }`.

## typed/builtin//modules/api/engine/playerSetupValidation/M/checkEntity {#typed-builtin-modules-api-engine-playersetupvalidation-m-checkentity}

```lua
M.checkEntity(entityId: string) -> { string }
```

Validate a single PlayerSpawn or PlayerPrototype entity, returning
agent-facing messages naming what is wrong and what to do. An entity carrying
neither component (or one that does not exist) yields no messages.

**Parameters**

- `entityId` `string` — The entity to inspect.

**Returns** `{ string }` — An array of message strings; empty when the entity is well-formed.

## typed/builtin//modules/api/engine/playerSetupValidation/M/checkScene {#typed-builtin-modules-api-engine-playersetupvalidation-m-checkscene}

```lua
M.checkScene(opts: { playerIntent: string, spawnCount: number, cameraCount: number }) -> { string }
```

Validate a scene's player intent against its PlayerSpawn / Camera counts,
returning agent-facing messages. A "spawns" scene with no PlayerSpawn, or a
"none" scene with no Camera, yields a message; every other combination is
clean.

**Parameters**

- `opts` `{ playerIntent: string, spawnCount: number, cameraCount: number }` — `{ playerIntent: string, spawnCount: number, cameraCount: number }`.

**Returns** `{ string }` — An array of message strings; empty when the scene is well-formed.

## typed/builtin//modules/api/engine/playerSetupValidation/M/checkSceneJson {#typed-builtin-modules-api-engine-playersetupvalidation-m-checkscenejson}

```lua
M.checkSceneJson(sceneJson: { [string]: any }) -> { { code: string, severity: string, message: string } }
```

Validate a decoded scene.json document statically: the full player-setup
rule set (per-entity, competing-camera, scene-intent) run over the scene's
authored entity tree without loading it. This is what the scene assetType's
`validate` hook calls, so `asset.validate` / `worldValidation` / the
`world.push` gate all report a broken player setup at authoring time.

**Parameters**

- `sceneJson` `{ [string]: any }` — The decoded scene.json table (`{ player, version, entities }`).

**Returns** `{ { code: string, severity: string, message: string } }` — An array of `{ code, severity, message }` problem records.

## typed/builtin//modules/api/engine/playerSetupValidation/M/playReadinessProblems {#typed-builtin-modules-api-engine-playersetupvalidation-m-playreadinessproblems}

```lua
M.playReadinessProblems() -> { { entity: string, message: string } }
```

The player-setup problems that must block a flip into play: the per-entity
spawn/prototype rules (body + camera refs set, resolving to descendants, a
single referenced camera) and the scene-intent rule, over the LIVE active
scene. A "spawns" scene with none of these problems is ready to play. The
competing-camera rule is deliberately excluded — the editor's own free-fly
camera is a live viewport camera outside every prototype, so running it here
would false-positive on every edit session; that rule stays a static /
publish-time concern. Empty for a non-"spawns" scene (no player requirement),
and empty while the active scene is still being materialised — the verdict
belongs to the settled scene, so it waits for the layer to finish loading
and for any mode-flip transition to converge.

**Returns** `{ { entity: string, message: string } }` — An array of `{ entity = name/id, message = string }`; empty = ready.

## typed/builtin//modules/api/engine/player_prototype_spawn/M/applyNetworkScope {#typed-builtin-modules-api-engine-player-prototype-spawn-m-applynetworkscope}

```lua
M.applyNetworkScope(cloneRootId: string, isOwner: boolean, isAuthority: boolean)
```

Prune a clone subtree by each node's networkScope against the caller's
role. Walks the subtree from `cloneRootId`; a node scoped OwnerOnly is
despawned when the caller is not the owner, AuthorityOnly when the caller is
not the authority, and Replicated (or any other value) is kept.

**Parameters**

- `cloneRootId` `string` — The clone's root entity id.
- `isOwner` `boolean` — Whether the caller owns this clone.
- `isAuthority` `boolean` — Whether the caller is the simulation authority for this clone.

## typed/builtin//modules/api/engine/player_prototype_spawn/M/authorDefault {#typed-builtin-modules-api-engine-player-prototype-spawn-m-authordefault}

```lua
M.authorDefault() -> { [string]: string }
```

Author the canonical default player setup into the active scene — the
same shape the default world and the static_player canonical scene ship: a
PrototypeOnly prototype whose body adopts the humanoid avatar and whose
OwnerOnly camera rig runs the orbital follow behavior, plus a spawn at the
origin. Returns the authored entity ids. This is the single builder
scene.player("spawns") and the "player" scene template both resolve to, so
a joining user's avatar always replaces the same authored body.

**Returns** `{ [string]: string }` — `{ setups, prototype, body, camera, spawns, spawn }` — the authored ids.

## typed/builtin//modules/api/engine/player_prototype_spawn/M/captureTemplatesFromEntities {#typed-builtin-modules-api-engine-player-prototype-spawn-m-capturetemplatesfromentities}

```lua
M.captureTemplatesFromEntities(entities: { any })
```

Build the prototype-template registry from a scene's authored entity
records (the parsed scene data, not live entities). This is the primary
capture path: it is independent of scene-load order and runtime
composition, so it captures the clean authored subtree (no composed avatar)
and works in the runtime profile, which boots straight to play. Called by
the scene loader for v7 scenes.

**Parameters**

- `entities` `{ any }` — The scene's authored entity records (each `{ id, name, parent,
networkScope, renderLayer, transform, components }`).

## typed/builtin//modules/api/engine/player_prototype_spawn/M/capturedTemplate {#typed-builtin-modules-api-engine-player-prototype-spawn-m-capturedtemplate}

```lua
M.capturedTemplate(prototypeId: string) -> any
```

The captured authored subtree for a PlayerPrototype — the clone source
`spawnFor` instantiates for each joining player, keyed by the prototype's
authored entity id (the id a PlayerSpawn's `prototype` field carries). Each
node is `{ id, name, participation, networkScope, renderLayer, position,
rotation, scale, components = { [type] = data }, children }`. Where the
materialisation keeps authored prototype subtrees out of the live scene —
play — this template is the authored prototype, and it is the subtree
`spawnFor` clones for each joining player.

**Parameters**

- `prototypeId` `string` — The PlayerPrototype root's authored entity id.

**Returns** `any` — The template node, or nil when no template is captured for that id.

```lua
local proto = player_prototype_spawn.capturedTemplate(spawn.prototype.id)
```

## typed/builtin//modules/api/engine/player_prototype_spawn/M/chooseSpawn {#typed-builtin-modules-api-engine-player-prototype-spawn-m-choosespawn}

```lua
M.chooseSpawn(ctx: any?) -> (string?, { [string]: any }?, string?)
```

Pick the PlayerSpawn-carrying entity to spawn from. Enumerates entities
carrying the PlayerSpawn component in the joining user's ROOT scene, skipping
any that live in an additive overlay layer (editor UI, HUD scenes). When the
root scene resolves (`ctx.rootSceneGuid`, else `layers.active.guid`), only
spawns in that scene's layer are considered; otherwise every non-overlay
spawn is eligible. Spawns with no layer attribution yet belong to the world
root and stay eligible either way. Honors an optional `ctx.spawnId`
override (used for
deterministic selection), otherwise returns the first matching spawn.

**Parameters**

- `ctx` `any` _(optional)_ — A table; `ctx.spawnId` optionally names the spawn entity to select,
`ctx.rootSceneGuid` optionally names the scene layer to scope the search to.

**Returns** `(string?, { [string]: any }?, string?)` — `(spawnEntityId, playerSpawnComponentProxy, spawnSceneLayer)`, or `(nil, nil, nil)` when none match. `spawnSceneLayer` is the chosen spawn's own scene-layer guid — the scene the clone must belong to.

## typed/builtin//modules/api/engine/player_prototype_spawn/M/clearJoinHook {#typed-builtin-modules-api-engine-player-prototype-spawn-m-clearjoinhook}

```lua
M.clearJoinHook(guid: string)
```

Clear a scene's join-hook flag. Called when a "spawns" scene unloads so
the once-registered connect / play-entry handlers stand down (they no-op
while no wired scene remains). Idempotent for an unknown guid.

**Parameters**

- `guid` `string` — The scene guid passed to installJoinHook.

## typed/builtin//modules/api/engine/player_prototype_spawn/M/installJoinHook {#typed-builtin-modules-api-engine-player-prototype-spawn-m-installjoinhook}

```lua
M.installJoinHook(sceneProxy: any?) -> boolean
```

Wire spawnFor to the world's connected-user join event. When a user
connects, the hook picks a PlayerSpawn and instantiates that user's prototype
instance (internal identity + avatar + camera-follow) via spawnFor. The
trigger is `world.connectedUsers.onConnect` — the WORLD-level "a user joined
the session" event — not the room players registry, so the internal identity the
clone becomes (which folds into that registry) does not re-trigger a spawn.
Entering play spawns every already-connected user (their onConnect fired in
edit, ignored then). A scene wired while ALREADY in play — the runtime
profile boots straight into play, or a scene swapped in mid-play — gets that
same sweep immediately, since no play flip follows to trigger it. Every spawn
path is per-user idempotent: a user who already owns a live clone is skipped,
so overlapping paths and re-flips never produce a second player. Idempotent
per scene proxy: a second call for the same scene installs nothing further.

**Parameters**

- `sceneProxy` `any` _(optional)_ — A non-additive Scene proxy.

**Returns** `boolean` — true when the hook was installed (or was already installed), false when the connected-users surface is unavailable.

## typed/builtin//modules/api/engine/player_prototype_spawn/M/runtimeSpawnedInfo {#typed-builtin-modules-api-engine-player-prototype-spawn-m-runtimespawnedinfo}

```lua
M.runtimeSpawnedInfo(id: string) -> { [string]: any }?
```

Read back the runtime provenance stamped on a clone root by spawnFor.

**Parameters**

- `id` `string` — The clone root entity id.

**Returns** `{ [string]: any }?` — `{ sourcePrototype, ownerUserId, ownerPlayer }`, or nil when the entity carries no provenance.

## typed/builtin//modules/api/engine/player_prototype_spawn/M/spawnFor {#typed-builtin-modules-api-engine-player-prototype-spawn-m-spawnfor}

```lua
M.spawnFor(ctx: any?) -> string?
```

Spawn a player instance for a joining user from the chosen PlayerSpawn's
prototype. Chooses a spawn (honoring `ctx.spawnId`), resolves and validates
its prototype, clones the prototype subtree, activates and reveals the clone,
prunes it by networkScope against the caller's owner/authority role (both
default true), marks the clone RuntimeOnly, stamps provenance attributes,
places the clone at the spawn's world transform, and registers it with the
prototype lifecycle so it is despawned on the return to edit.

**Parameters**

- `ctx` `any` _(optional)_ — `{ userId, playerEntityId?, spawnId?, isOwner?, isAuthority? }`.

**Returns** `string?` — The clone root entity id, or nil when no eligible spawn / prototype exists.

## typed/builtin//modules/api/engine/player_prototype_spawn/M/storePrototypeTemplate {#typed-builtin-modules-api-engine-player-prototype-spawn-m-storeprototypetemplate}

```lua
M.storePrototypeTemplate(prototypeId: string)
```

Capture a PlayerPrototype's authored subtree into the template registry.
Called by PlayerPrototype.awake (before its Asset composes and before it
deactivates) so spawnFor can instantiate the authored structure per player.

**Parameters**

- `prototypeId` `string` — The PlayerPrototype root entity id.

## typed/builtin//modules/api/engine/player_prototype_spawn/M/userHasSpawnedPlayer {#typed-builtin-modules-api-engine-player-prototype-spawn-m-userhasspawnedplayer}

```lua
M.userHasSpawnedPlayer(userId: string?) -> boolean
```

Whether a live clone spawned by spawnFor already carries this user's owner
provenance. Scans the live entities for a root whose `ownerUserId` attribute
matches. The idempotency guard the auto-spawn paths use so a user who already
has a spawned player never gets a second one.

**Parameters**

- `userId` `string` _(optional)_ — The joining user's account id.

**Returns** `boolean` — true when a live clone owned by `userId` exists.

## typed/builtin//modules/api/engine/players/playerHandle/avatar {#typed-builtin-modules-api-engine-players-playerhandle-avatar}

```lua
playerHandle.avatar -> entityRef?
```

This player's body in the 3D world, or nil until a live one is bound. Assign a live entity ref to bind a body, or nil to clear it.

**Returns** `entityRef?`

## typed/builtin//modules/api/engine/players/playerHandle/displayName {#typed-builtin-modules-api-engine-players-playerhandle-displayname}

```lua
playerHandle.displayName -> string
```

The name this player shows as, empty until the owner stamps it or it replicates.

**Returns** `string`

## typed/builtin//modules/api/engine/players/playerHandle/identity {#typed-builtin-modules-api-engine-players-playerhandle-identity}

```lua
playerHandle.identity -> string
```

The account id this player belongs to, under the second name it answers to.

**Returns** `string`

## typed/builtin//modules/api/engine/players/playerHandle/isLocal {#typed-builtin-modules-api-engine-players-playerhandle-islocal}

```lua
playerHandle.isLocal -> boolean
```

Whether this session owns this player.

**Returns** `boolean`

## typed/builtin//modules/api/engine/players/playerHandle/ready {#typed-builtin-modules-api-engine-players-playerhandle-ready}

```lua
playerHandle.ready -> boolean
```

Whether this player has a live body bound.

**Returns** `boolean`

## typed/builtin//modules/api/engine/players/playerHandle/userId {#typed-builtin-modules-api-engine-players-playerhandle-userid}

```lua
playerHandle.userId -> string
```

The account id this player belongs to, empty until the owner stamps it or it replicates.

**Returns** `string`

## typed/builtin//modules/api/engine/players/players/count {#typed-builtin-modules-api-engine-players-players-count}

```lua
players.count(self) -> number
```

How many players are connected to this room.

**Parameters**

- `self`

**Returns** `number`

## typed/builtin//modules/api/engine/players/players/exists {#typed-builtin-modules-api-engine-players-players-exists}

```lua
players.exists(self, id: string) -> boolean
```

Whether a player with this account id or identity entity id is connected.

**Parameters**

- `self`
- `id` `string`

**Returns** `boolean`

## typed/builtin//modules/api/engine/players/players/get {#typed-builtin-modules-api-engine-players-players-get}

```lua
players.get(self, key: string) -> playerHandle?
```

The connected player with this account id or identity entity id, or nil.

## typed/builtin//modules/api/engine/players/players/list {#typed-builtin-modules-api-engine-players-players-list}

```lua
players.list(self) -> { playerHandle }
```

Every player connected to this room, as a snapshot.

## typed/builtin//modules/api/engine/players/players/localPlayer {#typed-builtin-modules-api-engine-players-players-localplayer}

```lua
players.localPlayer -> playerHandle?
```

The player this session owns, or nil before its identity has landed.

**Returns** `playerHandle?`

## typed/builtin//modules/api/engine/players/players/localPlayerEntityId {#typed-builtin-modules-api-engine-players-players-localplayerentityid}

```lua
players.localPlayerEntityId -> string?
```

The id of the local identity entity, answerable before its UserIdentity component has attached.

**Returns** `string?`

## typed/builtin//modules/api/engine/players/players/localReady {#typed-builtin-modules-api-engine-players-players-localready}

```lua
players.localReady -> boolean
```

Whether the local player is loaded: its identity exists with a live avatar, or the scene opted the avatar out.

**Returns** `boolean`

## typed/builtin//modules/api/engine/players/players/offJoin {#typed-builtin-modules-api-engine-players-players-offjoin}

```lua
players.offJoin(self, handle: number) -> boolean
```

Remove an onJoin subscription by its handle.

**Parameters**

- `self`
- `handle` `number`

**Returns** `boolean`

## typed/builtin//modules/api/engine/players/players/offLeave {#typed-builtin-modules-api-engine-players-players-offleave}

```lua
players.offLeave(self, handle: number) -> boolean
```

Remove an onLeave subscription by its handle.

**Parameters**

- `self`
- `handle` `number`

**Returns** `boolean`

## typed/builtin//modules/api/engine/players/players/offLocalReady {#typed-builtin-modules-api-engine-players-players-offlocalready}

```lua
players.offLocalReady(self, handle: number) -> boolean
```

Remove an onLocalReady subscription by its handle.

**Parameters**

- `self`
- `handle` `number`

**Returns** `boolean`

## typed/builtin//modules/api/engine/players/players/offPlayerJoined {#typed-builtin-modules-api-engine-players-players-offplayerjoined}

```lua
players.offPlayerJoined(self, handle: number) -> boolean
```

Remove an onPlayerJoined subscription by its handle.

**Parameters**

- `self`
- `handle` `number`

**Returns** `boolean`

## typed/builtin//modules/api/engine/players/players/offPlayerLeft {#typed-builtin-modules-api-engine-players-players-offplayerleft}

```lua
players.offPlayerLeft(self, handle: number) -> boolean
```

Remove an onPlayerLeft subscription by its handle.

**Parameters**

- `self`
- `handle` `number`

**Returns** `boolean`

## typed/builtin//modules/api/engine/players/players/onJoin {#typed-builtin-modules-api-engine-players-players-onjoin}

```lua
players.onJoin(self, cb: (playerHandle) -> ()) -> number
```

Subscribe to players joining the room, under the short name onPlayerJoined also answers to.

**Parameters**

- `self`
- `cb` `(playerHandle) -> ()`

**Returns** `number`

## typed/builtin//modules/api/engine/players/players/onLeave {#typed-builtin-modules-api-engine-players-players-onleave}

```lua
players.onLeave(self, cb: (playerHandle) -> ()) -> number
```

Subscribe to players leaving the room, under the short name onPlayerLeft also answers to.

**Parameters**

- `self`
- `cb` `(playerHandle) -> ()`

**Returns** `number`

## typed/builtin//modules/api/engine/players/players/onLocalReady {#typed-builtin-modules-api-engine-players-players-onlocalready}

```lua
players.onLocalReady(self, cb: (playerHandle) -> ()) -> number
```

Subscribe to the local player becoming ready, firing immediately for a subscriber that arrives after it already has. Answers a handle for offLocalReady.

**Parameters**

- `self`
- `cb` `(playerHandle) -> ()`

**Returns** `number`

## typed/builtin//modules/api/engine/players/players/onPlayerJoined {#typed-builtin-modules-api-engine-players-players-onplayerjoined}

```lua
players.onPlayerJoined(self, cb: (playerHandle) -> ()) -> number
```

Subscribe to players joining the room, firing once for each player already in it. Answers a handle for offPlayerJoined.

**Parameters**

- `self`
- `cb` `(playerHandle) -> ()`

**Returns** `number`

## typed/builtin//modules/api/engine/players/players/onPlayerLeft {#typed-builtin-modules-api-engine-players-players-onplayerleft}

```lua
players.onPlayerLeft(self, cb: (playerHandle) -> ()) -> number
```

Subscribe to players leaving the room. Answers a handle for offPlayerLeft.

**Parameters**

- `self`
- `cb` `(playerHandle) -> ()`

**Returns** `number`

## typed/builtin//modules/api/engine/players/players/ownerOf {#typed-builtin-modules-api-engine-players-players-ownerof}

```lua
players.ownerOf(self, avatar: any) -> playerHandle?
```

The connected player whose body is this avatar, taken as an entity ref or an entity id.

**Parameters**

- `self`
- `avatar` `any`

**Returns** `playerHandle?`

## typed/builtin//modules/api/engine/postprocess/postprocess/add {#typed-builtin-modules-api-engine-postprocess-postprocess-add}

```lua
postprocess.add(name: string, shader: string | AssetRef, opts: PostprocessOpts?) -> boolean
```

Register a fullscreen post-process effect. This call is what
puts a pass into the frame — a `post-process` `.shader` asset defines an
effect, and renders only once registered here. The chain applies the
registration on the caller's own stack and the returned boolean is its
answer, so a `setProperty` or `setTexture` naming the effect in the same
call finds it. `shader` is a `.shader` asset reference whose `shader.wgsl`
provides `fn fragment(in: PostInput) -> vec4<f32>` and whose
`properties.yaml` declares the effect's properties; the engine generates the
group(0) framework + schema-driven group(1) from that schema. Editing that
shader afterwards recompiles this effect in place, keeping its enabled
state, priority, layer and tuned property values. WGSL text is also
accepted, and then `opts.properties` is the whole schema. Effects run in
priority order (lower first, default 100).
A registered effect runs over the live viewport's frame AND over every
offscreen one — a capture from a world-space station, one orbiting an
entity, one of a named camera, a render-to-texture camera. In each of those
the effect's `engine.view_proj` / `engine.prev_view_proj` /
`engine.inv_view_proj` are the camera THAT render was drawn from and
`engine.resolution` is that target's own size, so a pass reconstructing
world space from `zero_scene_depth(uv)` reconstructs against the station
and lens the capture asked for. An offscreen capture is therefore an oracle
for an authored grade: it photographs a chosen station without taking the
on-screen camera from whoever else is driving the scene, and a capture's
`postProcessing = false` is the one control that takes the chain off the
frame it returns. An offscreen render keeps no view history of its own, so
`engine.prev_view_proj` there holds that same matrix rather than the frame
before it, and a pass taking camera motion from the two reads none.

**Parameters**

- `name` `string` — Unique effect name.
- `shader` `string | AssetRef` — A resolved `shader` asset reference, or author WGSL
(`fn fragment(in: PostInput)` only).
- `opts` `PostprocessOpts` _(optional)_ — `{ priority = 100, enabled = true, layer = "all"|"scene", properties = {{name, type, default?, min?, max?, textureDefault?}} }`
— with a shader asset, `properties` layers over the asset's own schema.
`layer` picks which composited image the effect grades: `"scene"` runs it
before the UI is drawn, so it grades the rendered picture and leaves every
widget on screen as authored, and `"all"` (the default) runs it after the UI
has landed, so the interface is graded along with the picture — an effect
that belongs to the world's look wants `"scene"`, since a screen another
author drew is otherwise graded by it too.
`textureDefault` is what a `type = "texture"` property samples while
nothing is bound to it: `"white"` (1,1,1,1 — the default), `"black"`
(0,0,0,1), `"normal"` (0.5,0.5,1,1) or `"transparent"` (0,0,0,0). An
effect that lays its texture over the scene wants `"transparent"`, so the
frame is untouched until `setTexture` binds a texture that exists.

**Returns** `boolean` — True when the chain registered the effect; false when it refused it. A shader that does not compile draws nothing at any property value, so it is not registered and `postprocess.list()` never names it — the compiler's message is in the engine log. A call made from inside `queue()` or `batch()`, where the engine has not run the registration by the time the call returns, answers true for the queued request.

```lua
postprocess.add("vignette", asset.resolve("@builtin::shaders.post.vignette", "shader"))
postprocess.add("vignette", VIGNETTE_WGSL, { properties = {{ name = "intensity", type = "float", default = 0.5 }} })
```

## typed/builtin//modules/api/engine/postprocess/postprocess/describe {#typed-builtin-modules-api-engine-postprocess-postprocess-describe}

```lua
postprocess.describe(name: string) -> PostprocessDescription?
```

One effect by name, read in full: the chain state
`postprocess.status()` lists for it, and on top of that `properties` — the
schema the effect declared, each entry `{ name, type, default?, min?, max?,
textureDefault? }` in the shape `add` takes — and `values`, what each of
those properties currently holds. A property's value is the one the last
`setProperty` wrote, or the schema's own default where nothing has written
one, and it comes back as a number for a scalar and as the array for a
wider value, which is what `setProperty` takes, so a property read here is
written straight back.

This is the read-back for a property write. `setProperty` answers whether
the uniform took the value; this answers what the effect holds now, which
is the reading a pass that writes its properties every frame needs and the
one that tells a mistyped property name from an effect that is not
grading. The schema and the values are the engine's own record of the
effect — the schema it was registered with and every write the chain
accepted into its uniform, the same record `/runtime/fx/<name>/meta.json`
is serialized from. A write the chain refused is not in it, and neither is
one made against a property the schema does not declare.

Before an effect is registered its schema lives on the `.shader` asset it
will render: `asset.resolve("@builtin::shaders.post.bloom",
"shader"):getProperties()` names what that shader declares.

**Parameters**

- `name` `string` — Effect name.

**Returns** `PostprocessDescription?` — The effect's state, schema and live values, or nil when nothing is registered under the name. An effect the renderer registers itself declares no properties of its own, and its `properties` and `values` are empty.

```lua
local e = postprocess.describe("vignette")
print(if e then e.values.intensity else "not registered")
for _, p in ipairs(postprocess.describe("bloom").properties) do
print(p.name, p.type, p.min, p.max)
end
```

## typed/builtin//modules/api/engine/postprocess/postprocess/list {#typed-builtin-modules-api-engine-postprocess-postprocess-list}

```lua
postprocess.list() -> { string }
```

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

## typed/builtin//modules/api/engine/postprocess/postprocess/remove {#typed-builtin-modules-api-engine-postprocess-postprocess-remove}

```lua
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.

**Parameters**

- `name` `string` — Effect name to remove.

**Returns** `boolean` — True — the mutation was queued.

```lua
postprocess.remove("vignette")
```

## typed/builtin//modules/api/engine/postprocess/postprocess/setEnabled {#typed-builtin-modules-api-engine-postprocess-postprocess-setenabled}

```lua
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.

**Parameters**

- `name` `string` — Effect name.
- `enabled` `boolean` — True to enable, false to disable.

**Returns** `boolean` — True — the mutation was queued.

```lua
postprocess.setEnabled("bloom", false)
```

## typed/builtin//modules/api/engine/postprocess/postprocess/setProperty {#typed-builtin-modules-api-engine-postprocess-postprocess-setproperty}

```lua
postprocess.setProperty(name: string, prop: string, value: (number | { number })) -> boolean
```

Set a named material property 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).

**Parameters**

- `name` `string` — Effect name.
- `prop` `string` — Declared property name.
- `value` `(number | { number })` — Number or array of numbers.

**Returns** `boolean` — True when the effect's uniform took the value; false when it did not — an effect that is not registered, or one that declares no property by that name, is named in a WARN in the engine log. A call made from inside `queue()` or `batch()`, where the engine has not run the write by the time the call returns, answers true for the queued request.

```lua
postprocess.setProperty("vignette", "intensity", 0.6)
```

## typed/builtin//modules/api/engine/postprocess/postprocess/setSampler {#typed-builtin-modules-api-engine-postprocess-postprocess-setsampler}

```lua
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.

**Parameters**

- `name` `string` — Effect name.
- `opts` `{ [string]: any }` — `{ filter = "linear"|"nearest", wrap = "clamp"|"repeat"|"mirror" }`.

**Returns** `boolean` — True — the mutation was queued.

```lua
postprocess.setSampler("blur", { filter = "linear", wrap = "clamp" })
```

## typed/builtin//modules/api/engine/postprocess/postprocess/setTexture {#typed-builtin-modules-api-engine-postprocess-postprocess-settexture}

```lua
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, ...). A path whose
texture has not reached the GPU yet — one this same script created — is
held and bound as soon as it does; `postprocess.status()` reports it under
`pendingTextures` until then.

**Parameters**

- `name` `string` — Effect name.
- `prop` `string` — Declared texture-property name.
- `path` `string` — Texture path / spec.

**Returns** `boolean` — True when the slot took the binding, including one held until its texture reaches the GPU; false when it did not — an effect that is not registered, or one that declares no texture property by that name, is named in a WARN in the engine log. A call made from inside `queue()` or `batch()`, where the engine has not run the binding by the time the call returns, answers true for the queued request.

```lua
postprocess.setTexture("__vsky_composite", "cloud", "cloud_target")
```

## typed/builtin//modules/api/engine/postprocess/postprocess/status {#typed-builtin-modules-api-engine-postprocess-postprocess-status}

```lua
postprocess.status() -> { PostprocessStatus }
```

Every registered effect in chain order with the state that decides
whether it reaches the frame — enabled flag, priority, layer, the
shader's compile error when it has one, the `.shader` asset it renders
when it was registered from one, the texture each declared slot is bound
to (`textures`) and the bindings still waiting for their texture
(`pendingTextures`). This is what the renderer draws with, so a survey of
the chain answers "is this one affecting the picture right now?" without
capturing a frame and reading pixels.

An effect this script has just registered is listed with `pending =
true` until the renderer publishes it, since a registration is queued
for the next frame.

**Returns** `{ PostprocessStatus }` — Array of per-effect state, in the order the chain runs them.

```lua
for _, e in ipairs(postprocess.status()) do
print(e.name, e.enabled, e.layer, e.error)
end
```

## typed/builtin//modules/api/engine/profiler/profiler/begin {#typed-builtin-modules-api-engine-profiler-profiler-begin}

```lua
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.

**Parameters**

- `name` `string` — Block name (e.g. "MyComponent.update").

```lua
profiler.begin("MyComponent.update"); ...; profiler.finish()
```

## typed/builtin//modules/api/engine/profiler/profiler/disableRing {#typed-builtin-modules-api-engine-profiler-profiler-disablering}

```lua
profiler.disableRing()
```

Disable the ring buffer and clear its history.

```lua
profiler.disableRing()
```

## typed/builtin//modules/api/engine/profiler/profiler/enableRing {#typed-builtin-modules-api-engine-profiler-profiler-enablering}

```lua
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.

**Parameters**

- `seconds` `number` _(optional)_ — Seconds of history to retain (default 20).

**Returns** `boolean` — True if enabled, false if refused (runtime profile).

```lua
if profiler.enableRing(30) then ... end
```

## typed/builtin//modules/api/engine/profiler/profiler/finish {#typed-builtin-modules-api-engine-profiler-profiler-finish}

```lua
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.

**Parameters**

- `name` `string` _(optional)_ — Block name to finish. Omit to pop the top of the stack.

**Returns** `number?` — Elapsed milliseconds, or nil if no matching block was active.

```lua
local ms = profiler.finish("MyComponent.update")
```

## typed/builtin//modules/api/engine/profiler/profiler/gpuFrame {#typed-builtin-modules-api-engine-profiler-profiler-gpuframe}

```lua
profiler.gpuFrame() -> GpuFrameReport
```

Label-aggregated GPU pass timings over the last `window_frames`
resolved frames, measured with GPU timestamp queries. `supported`
is false when the device lacks timestamp queries — `spans` stays
empty. Each span covers every render/compute pass recorded under
one label — `compute.<shader>` per compute dispatch, `scene.*` for
the scene passes, `post.<effect>` per post-process effect,
`feature.*` for render-feature passes: `ms` is the median of its
per-frame totals, `min_ms`/`max_ms` the range that median sits in,
`count` the passes per frame and `frames` how much of the window
carried it. `at_floor` marks a label whose every sample landed
within a few ticks of the device's timestamp counter (`tick_ms`) —
those passes ran and the device resolved no duration for them,
which is not the same as a measured zero. `ran` is whether the
label recorded a measured pass in the newest resolved frame, and
`last_frame` the newest frame that did. The window outlives the
work it describes, so a pass that stops being recorded leaves a row
standing for up to `window_frames` frames carrying the median of
the frames it did run in: read `ran` to answer whether a pass is
running, `frame - last_frame` for how many resolved frames ago it
last did, and `ms` as the cost of the frames it ran in.
`frame_span_ms` (first pass begin to last pass end) and
`total_ms` are medians too, so
rows do not sum to `total_ms`, and the GPU may overlap passes so
`total_ms` can exceed `frame_span_ms`. The readback is
asynchronous: the window lags the live frame by a few frames.

**Returns** `GpuFrameReport` — GPU timing window, spans ranked by median ms descending.

```lua
local g = profiler.gpuFrame(); print(g.frame_span_ms, g.spans[1] and g.spans[1].label)
```

## typed/builtin//modules/api/engine/profiler/profiler/hits {#typed-builtin-modules-api-engine-profiler-profiler-hits}

```lua
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.

**Parameters**

- `label` `string` _(optional)_ — Capture label to store under (default "watch_hits").

**Returns** `string?` — Capture JSON of the hit frames, or nil if none.

```lua
local json = profiler.hits()
```

## typed/builtin//modules/api/engine/profiler/profiler/isCapturing {#typed-builtin-modules-api-engine-profiler-profiler-iscapturing}

```lua
profiler.isCapturing() -> boolean
```

Check if a profiler capture is currently active.

**Returns** `boolean` — True if a capture is in progress.

```lua
if profiler.isCapturing() then ... end
```

## typed/builtin//modules/api/engine/profiler/profiler/lastCapture {#typed-builtin-modules-api-engine-profiler-profiler-lastcapture}

```lua
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.

**Returns** `string?` — JSON string of the last capture, or nil.

```lua
local last = profiler.lastCapture()
```

## typed/builtin//modules/api/engine/profiler/profiler/retro {#typed-builtin-modules-api-engine-profiler-profiler-retro}

```lua
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 (the `frame` / `hotspots`
tools);
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.

**Parameters**

- `seconds` `number` _(optional)_ — How many seconds back to include (default: whole ring).
- `label` `string` _(optional)_ — Capture label to store under (default "retro").

**Returns** `{ [string]: any }?` — A compact aggregate `{ label, source, frames, seconds, exclude_agent, agent_frames, dt = { avg, p50, p90, p99, max, min }, summary = {...} }`, or nil if the ring holds nothing.

```lua
local agg = profiler.retro(8, "collapse")
```

## typed/builtin//modules/api/engine/profiler/profiler/ringStatus {#typed-builtin-modules-api-engine-profiler-profiler-ringstatus}

```lua
profiler.ringStatus() -> string
```

Ring buffer status as a JSON string:
`{ enabled, frames, capacity, span_seconds }`.

**Returns** `string` — JSON status string.

```lua
local s = profiler.ringStatus()
```

## typed/builtin//modules/api/engine/profiler/profiler/startCapture {#typed-builtin-modules-api-engine-profiler-profiler-startcapture}

```lua
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`.

**Parameters**

- `label` `string` _(optional)_ — Capture label (default `"capture"`).

**Returns** `boolean` — True if capture started, false if a capture is already active.

```lua
if profiler.startCapture("frame-spike") then ... end
```

## typed/builtin//modules/api/engine/profiler/profiler/stats {#typed-builtin-modules-api-engine-profiler-profiler-stats}

```lua
profiler.stats(pattern: string?) -> { ProfilerStat }
```

Get current EMA profiling statistics from the SystemProfiler.
Optional glob pattern filters by metric name (supports `*` and `?`
wildcards). Each entry carries two averages: `avg_ms` averages one
RUN of the block and is folded when the block runs, so a block that
has stopped running keeps the last value it saw; `avg_frame_ms`
averages one FRAME and is folded every frame, including the frames
the block did not run in, so it is the block's share of the current
frame and falls back to zero once the block stops running.

**Parameters**

- `pattern` `string` _(optional)_ — Filter pattern (e.g. "schedule.*", "system.schedule.render.*").

**Returns** `{ ProfilerStat }` — Array of profiler block stats.

```lua
for _, s in ipairs(profiler.stats("schedule.*")) do print(s.name, s.avg_frame_ms) end
```

## typed/builtin//modules/api/engine/profiler/profiler/stopCapture {#typed-builtin-modules-api-engine-profiler-profiler-stopcapture}

```lua
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`.

**Returns** `string?` — JSON capture result, or nil if no capture was active.

```lua
local json = profiler.stopCapture()
```

## typed/builtin//modules/api/engine/profiler/profiler/unwatch {#typed-builtin-modules-api-engine-profiler-profiler-unwatch}

```lua
profiler.unwatch()
```

Disarm the watchdog. Recorded hits are kept for a final
`profiler.hits()`.

```lua
profiler.unwatch()
```

## typed/builtin//modules/api/engine/profiler/profiler/watch {#typed-builtin-modules-api-engine-profiler-profiler-watch}

```lua
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.

**Parameters**

- `ceilingMs` `number` — Effective frame-time ceiling in ms.
- `mode` `string` _(optional)_ — "record" (default) or "pause".
- `excludeAgent` `boolean` _(optional)_ — Subtract agent cost before comparing (default true).
- `maxHits` `number` _(optional)_ — Max frames retained in record mode (default 240).

**Returns** `boolean` — True if armed, false if refused (runtime profile).

```lua
if profiler.watch(50, "pause") then ... end
```

## typed/builtin//modules/api/engine/profiler/profiler/watchStatus {#typed-builtin-modules-api-engine-profiler-profiler-watchstatus}

```lua
profiler.watchStatus() -> string
```

Watchdog status as a JSON string: `{ armed, ceiling_ms, mode,
exclude_agent, hits, dropped_hits, tripped }`.

**Returns** `string` — JSON status string.

```lua
local s = profiler.watchStatus()
```

## typed/builtin//modules/api/engine/prototype_lifecycle/M/activatePrototypes {#typed-builtin-modules-api-engine-prototype-lifecycle-m-activateprototypes}

```lua
M.activatePrototypes()
```

Reactivate and unhide every prototype root and EditorOnly entity.

## typed/builtin//modules/api/engine/prototype_lifecycle/M/deactivatePrototypes {#typed-builtin-modules-api-engine-prototype-lifecycle-m-deactivateprototypes}

```lua
M.deactivatePrototypes()
```

Deactivate and hide every prototype root and EditorOnly entity so play
mode neither simulates nor renders them.

## typed/builtin//modules/api/engine/prototype_lifecycle/M/despawnClones {#typed-builtin-modules-api-engine-prototype-lifecycle-m-despawnclones}

```lua
M.despawnClones()
```

Despawn every still-existing tracked clone and clear the tracking list.

## typed/builtin//modules/api/engine/prototype_lifecycle/M/enterEdit {#typed-builtin-modules-api-engine-prototype-lifecycle-m-enteredit}

```lua
M.enterEdit()
```

Enter edit mode: despawn runtime clones, then reactivate prototypes and
EditorOnly entities.

## typed/builtin//modules/api/engine/prototype_lifecycle/M/enterPlay {#typed-builtin-modules-api-engine-prototype-lifecycle-m-enterplay}

```lua
M.enterPlay()
```

Enter play mode: deactivate and hide prototypes and EditorOnly entities.

## typed/builtin//modules/api/engine/prototype_lifecycle/M/hideEditorSurface {#typed-builtin-modules-api-engine-prototype-lifecycle-m-hideeditorsurface}

```lua
M.hideEditorSurface()
```

Deactivate and hide the EditorOnly authoring surface without touching
player-prototype roots. Used when play mode resumes so the surface
disappears and gameplay cameras take the viewport back.

## typed/builtin//modules/api/engine/prototype_lifecycle/M/install {#typed-builtin-modules-api-engine-prototype-lifecycle-m-install}

```lua
M.install()
```

Keep the play-mode invariant applied for every flip, in every world.
`enterPlay` / `enterEdit` are what make `PrototypeOnly` and `EditorOnly`
mean something at runtime, and until something calls them on the flip a
template stays live: its camera competes for the viewport with the camera
of the player cloned from it, carries no follow target, and holds the shot
at the spawn point; its body answers the same input as a second character.

Registered from the prelude beside the other engine installs rather than
from a scene-load path — a load that does not run leaves the invariant
unapplied with nothing reporting it, and a flip that reloads no scene
never reaches a loader hook at all. Idempotent: a second call registers
nothing, and the current mode is applied once on install so a world opened
straight into play does not start with its templates live.

```lua
PrototypeLifecycle.install()
```

## typed/builtin//modules/api/engine/prototype_lifecycle/M/prototypeRoots {#typed-builtin-modules-api-engine-prototype-lifecycle-m-prototyperoots}

```lua
M.prototypeRoots() -> { string }
```

Ids of every active-layer entity carrying the PlayerPrototype component.

**Returns** `{ string }` — An array of entity ids.

## typed/builtin//modules/api/engine/prototype_lifecycle/M/registerClone {#typed-builtin-modules-api-engine-prototype-lifecycle-m-registerclone}

```lua
M.registerClone(id: string)
```

Track a runtime clone root so it can be despawned on the return to edit.

**Parameters**

- `id` `string` — The clone's root entity id.

## typed/builtin//modules/api/engine/prototype_lifecycle/M/showEditorSurface {#typed-builtin-modules-api-engine-prototype-lifecycle-m-showeditorsurface}

```lua
M.showEditorSurface()
```

Reactivate and unhide the EditorOnly authoring surface (free camera +
editor-only visualizers) without touching player-prototype roots. Used
when play mode is paused so the editor camera returns over the frozen
world.

## typed/builtin//modules/api/engine/reflectionProbe/reflectionProbe/add {#typed-builtin-modules-api-engine-reflectionprobe-reflectionprobe-add}

```lua
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.

**Parameters**

- `x` `number` — World X.
- `y` `number` — World Y.
- `z` `number` — World Z.
- `opts` `{ [string]: any }` _(optional)_ — Optional `{ radius = 12, probeId = "...", name = "..." }`. `probeId`
is the STABLE asset identity (so a re-created probe reloads the same baked
cube); defaults to the entity id. The probe does NOT bake on add — call
`bakeAll()` once the scene is built (baking is an authoring step).

**Returns** `string` — The probe entity id.

```lua
reflectionProbe.add(0, 3, 0, { radius = 15, probeId = "lobby" })
```

## typed/builtin//modules/api/engine/reflectionProbe/reflectionProbe/apply {#typed-builtin-modules-api-engine-reflectionprobe-reflectionprobe-apply}

```lua
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.

**Returns** `number` — The number of active probes applied.

## typed/builtin//modules/api/engine/reflectionProbe/reflectionProbe/bake {#typed-builtin-modules-api-engine-reflectionprobe-reflectionprobe-bake}

```lua
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`).

**Parameters**

- `id` `string` — Probe entity id.

**Returns** `(string?, string?)` — The asset path on success, or `(nil, errorMessage)` on failure.

## typed/builtin//modules/api/engine/reflectionProbe/reflectionProbe/bakeAll {#typed-builtin-modules-api-engine-reflectionprobe-reflectionprobe-bakeall}

```lua
reflectionProbe.bakeAll() -> { baked: number, failed: number, errors: { string } }
```

Bake EVERY registered probe in the active layers, in one call. Captures
the sky into the fallback slot, then 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`).

**Returns** `{ baked: number, failed: number, errors: { string } }` — `{ baked = N, failed = M, errors = { ... } }`.

```lua
reflectionProbe.bakeAll()
```

## typed/builtin//modules/api/engine/reflectionProbe/reflectionProbe/count {#typed-builtin-modules-api-engine-reflectionprobe-reflectionprobe-count}

```lua
reflectionProbe.count() -> number
```

Number of registered probes.

**Returns** `number`

## typed/builtin//modules/api/engine/reflectionProbe/reflectionProbe/ensureSkyFallback {#typed-builtin-modules-api-engine-reflectionprobe-reflectionprobe-ensureskyfallback}

```lua
reflectionProbe.ensureSkyFallback() -> boolean
```

Ensure the scene's sky is in the environment's sky fallback: a reflective
surface no probe covers then reflects the sky rather than black, and a
partially covered one blends the shortfall against it. Queues a capture
when the sky slot holds none, and re-arms the fallback when a capture is
there but switched off. The engine's own state answers both questions, so
calling this on every probe that comes up costs one capture between them,
and a scene that lost its fallback gets it back. Once captured, the
fallback follows the sky the scene draws on its own.

**Returns** `boolean` — True if a capture was queued, false if the sky slot already holds one.

```lua
reflectionProbe.ensureSkyFallback()
```

## typed/builtin//modules/api/engine/reflectionProbe/reflectionProbe/list {#typed-builtin-modules-api-engine-reflectionprobe-reflectionprobe-list}

```lua
reflectionProbe.list() -> { any }
```

List every registered probe: `{ { id, slot, radius, priority, asset, position }, ... }`.

## typed/builtin//modules/api/engine/reflectionProbe/reflectionProbe/loadBaked {#typed-builtin-modules-api-engine-reflectionprobe-reflectionprobe-loadbaked}

```lua
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.

**Parameters**

- `id` `string` — Probe entity id.

**Returns** `boolean` — True if a baked asset was loaded, false if none exists / load failed.

## typed/builtin//modules/api/engine/reflectionProbe/reflectionProbe/register {#typed-builtin-modules-api-engine-reflectionprobe-reflectionprobe-register}

```lua
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.

**Parameters**

- `id` `string` — Probe entity id.
- `radius` `number` — Influence radius (world units) — surfaces within blend it.
- `key` `string` _(optional)_ — Optional STABLE asset identity (the probe's probeId). Defaults to `id`.
The baked cube persists at `probe_<key>.texture` so an authored probe keeps
the same asset across reloads even though its runtime entity id changes.

**Returns** `number?` — The assigned cube slot, or nil if all MAX_PROBES slots are taken.

## typed/builtin//modules/api/engine/reflectionProbe/reflectionProbe/setPriority {#typed-builtin-modules-api-engine-reflectionprobe-reflectionprobe-setpriority}

```lua
reflectionProbe.setPriority(id: string, priority: number)
```

Set a probe's blend rank against the probes it overlaps, and re-apply.
Probes are gathered highest rank first and each rank takes the coverage the
ranks above it left, so a small interior probe ranked above the large
exterior one it sits inside wins outright wherever it reaches full weight,
while probes of equal rank crossfade by proximity as before.

**Parameters**

- `id` `string` — Probe entity id.
- `priority` `number` — Blend rank. Defaults to 0 on every probe.

```lua
reflectionProbe.setPriority(interiorId, 1)
```

## typed/builtin//modules/api/engine/reflectionProbe/reflectionProbe/setProxy {#typed-builtin-modules-api-engine-reflectionprobe-reflectionprobe-setproxy}

```lua
reflectionProbe.setProxy(id: string, kind: string, x: number, y: number, z: number)
```

Anchor a probe's reflections to a proxy volume and re-apply. A cube
records the environment from one point, so sampling it along the raw
reflection vector puts everything it recorded at infinity and the
reflection slides across a surface as the camera moves. Sizing a proxy to
the geometry the probe recorded — a room's walls, say — keeps the
reflection anchored to what it depicts.

**Parameters**

- `id` `string` — Probe entity id.
- `kind` `string` — "box" (sized by all three half-extents), "sphere" (sized by `x`),
or "none" to sample along the raw reflection vector.
- `x` `number` — Half-extent along X, in world units — the sphere radius for "sphere".
- `y` `number` — Half-extent along Y.
- `z` `number` — Half-extent along Z.

```lua
reflectionProbe.setProxy(id, "box", 5, 3, 4)  -- a 10x6x8 room
```

## typed/builtin//modules/api/engine/reflectionProbe/reflectionProbe/setRadius {#typed-builtin-modules-api-engine-reflectionprobe-reflectionprobe-setradius}

```lua
reflectionProbe.setRadius(id: string, radius: number)
```

Update a probe's influence radius and re-apply.

**Parameters**

- `id` `string` — Probe entity id.
- `radius` `number` — New influence radius.

## typed/builtin//modules/api/engine/reflectionProbe/reflectionProbe/unregister {#typed-builtin-modules-api-engine-reflectionprobe-reflectionprobe-unregister}

```lua
reflectionProbe.unregister(id: string)
```

Unregister entity `id`'s probe, freeing its cube slot, and re-apply.

**Parameters**

- `id` `string` — Probe entity id.

## typed/builtin//modules/api/engine/renderer/renderer/anisotropy {#typed-builtin-modules-api-engine-renderer-renderer-anisotropy}

```lua
renderer.anisotropy() -> number
```

The maximum anisotropy material textures are sampled with right now —
the requested level clamped to what this device honours.

**Returns** `number` — The effective level, 1 through 16.

```lua
if renderer.anisotropy() < 4 then ... end
```

## typed/builtin//modules/api/engine/renderer/renderer/atmospherics/held {#typed-builtin-modules-api-engine-renderer-renderer-atmospherics-held}

```lua
renderer.atmospherics.held() -> boolean
```

Whether a hold is standing on the air right now.

**Returns** `boolean` — True while at least one `renderer.atmospherics.hold` stands.

```lua
if renderer.atmospherics.held() then print("clear air") end
```

## typed/builtin//modules/api/engine/renderer/renderer/atmospherics/hold {#typed-builtin-modules-api-engine-renderer-renderer-atmospherics-hold}

```lua
renderer.atmospherics.hold(share: number?) -> () -> ()
```

Hold the air between the camera and every surface at a stated share of
what the scene authored, and return the release. At the default 0 the
media contribute nothing and a surface renders in its own colour, which is
what lets a reader judge an albedo, a tint or a material while another
slice of a shared world drives the weather. The share reaches aerial
perspective, height fog and volumetric light scattering; the sky, the sun
and the light they put on a surface are untouched, because those are what
the surface's colour is made of. Holds nest: the innermost names the
share, and the authored air is back once the last release is called. Each
release ends its own hold whatever order the releases come in, so two
callers holding at once each end their own.

**Parameters**

- `share` `number` _(optional)_ — How much of the authored air reaches the image, in [0, 1].
Defaults to 0 — no air at all.

**Returns** `() -> ()` — A function that releases this hold. Calling it twice releases once.

```lua
local release = renderer.atmospherics.hold() ; local png = tools.use("capture", "fromPosition", { position = { 0, 2, 8 } }) ; release()
```

## typed/builtin//modules/api/engine/renderer/renderer/atmospherics/onChange {#typed-builtin-modules-api-engine-renderer-renderer-atmospherics-onchange}

```lua
renderer.atmospherics.onChange(listener: (number) -> ()) -> () -> ()
```

Register a listener called with the share now in force whenever it
changes — a hold taken, a hold released — and return the unsubscribe. A
system that packs a medium into a GPU buffer registers here and re-packs
what it has already pushed, so the buffer carries the share before the
frame the hold was taken on is drawn rather than a frame later.

**Parameters**

- `listener` `(number) -> ()` — Called with the share now in force, in [0, 1].

**Returns** `() -> ()` — A function that removes this listener.

```lua
local stop = renderer.atmospherics.onChange(function(share) pushParams() end)
```

## typed/builtin//modules/api/engine/renderer/renderer/atmospherics/share {#typed-builtin-modules-api-engine-renderer-renderer-atmospherics-share}

```lua
renderer.atmospherics.share() -> number
```

The share of the authored air that reaches the image: the innermost
hold's share while one stands, and 1 otherwise. A system that packs a
medium multiplies its extinction — `aerial`, a fog `density` — by this,
and a hold then reaches that medium however it is being driven.

**Returns** `number` — A number in [0, 1]. 1 when nothing holds.

```lua
local density = state.density * renderer.atmospherics.share()
```

## typed/builtin//modules/api/engine/renderer/renderer/blendedBatching {#typed-builtin-modules-api-engine-renderer-renderer-blendedbatching}

```lua
renderer.blendedBatching() -> boolean
```

Whether blended neighbours sharing a draw key draw together.

**Returns** `boolean`

## typed/builtin//modules/api/engine/renderer/renderer/bounds/clear {#typed-builtin-modules-api-engine-renderer-renderer-bounds-clear}

```lua
renderer.bounds.clear(id: string) -> boolean
```

Withdraw the box an entity published, so it stops contributing to the
entity's reported extent.

**Parameters**

- `id` `string` — Entity id.

**Returns** `boolean` — True when there was a published box to withdraw.

```lua
renderer.bounds.clear(id)
```

## typed/builtin//modules/api/engine/renderer/renderer/bounds/set {#typed-builtin-modules-api-engine-renderer-renderer-bounds-set}

```lua
renderer.bounds.set(id: string, min: any?, max: any?) -> boolean
```

Publish the local-space box an entity's content-drawn geometry occupies.
`entity:bounds()` and `entity:hierarchyBounds()` union it with whatever
mesh geometry the entity has, each carried out of its own local space, so
framing a camera on the entity frames what a feature actually draws.

## typed/builtin//modules/api/engine/renderer/renderer/captureView/channelId {#typed-builtin-modules-api-engine-renderer-renderer-captureview-channelid}

```lua
renderer.captureView.channelId(name: string) -> number?
```

The debug channel a registered view draws on — what a feature passes as
its pass `debugChannel`. Nil when no view is registered under `name`.

**Parameters**

- `name` `string` — The view name.

**Returns** `number?` — The channel number or nil.

```lua
ctx.enqueue { ..., debugChannel = renderer.captureView.channelId("lightmap") }
```

## typed/builtin//modules/api/engine/renderer/renderer/captureView/list {#typed-builtin-modules-api-engine-renderer-renderer-captureview-list}

```lua
renderer.captureView.list() -> { any }
```

Every registered capture view as `{ name, channel, description }` records
— what backs the discoverability of `capture pass=<name>` and the
unknown-view error's suggestion list.

## typed/builtin//modules/api/engine/renderer/renderer/captureView/ready {#typed-builtin-modules-api-engine-renderer-renderer-captureview-ready}

```lua
renderer.captureView.ready(name: string) -> boolean
```

Whether a registered view can draw yet. A view's passes are enqueued
from the moment its render feature first runs, but they are skipped while
the materials they name have no pipeline — their shader is still compiling —
so for the first frames of a session a camera bound to the view renders the
ORDINARY view into its target, and the image gives no sign of it. This
reports the difference, and reports it before any camera is on the view, so
it is answerable for the first camera bound to one. False for an
unregistered name.

**Parameters**

- `name` `string` — The view name.

**Returns** `boolean` — Whether this view's passes have resolved everything drawing needs.

```lua
repeat task.wait() until renderer.captureView.ready("zfighting")
```

## typed/builtin//modules/api/engine/renderer/renderer/captureView/register {#typed-builtin-modules-api-engine-renderer-renderer-captureview-register}

```lua
renderer.captureView.register(name: string, config: any?) -> number
```

Register (or update) a content capture view under `name` and return the
debug CHANNEL number assigned to it. A render feature gates its pass to this
channel (`debugChannel = channel`) so the pass draws only when a capture
selects the view. Idempotent: re-registering the same name keeps its channel.

**Parameters**

- `name` `string` — The view name, selected via `capture pass=<name>`.
- `config` `any` _(optional)_ — `{ description?, ensure?, warmup?, renderLayers? }`. `ensure` is
called before a capture of this view so the feature that draws it is live
(e.g. create it on demand). `warmup` is how many present frames a capture
lets the view accumulate before it reads — set it when the feature retains
prior-frame state (a temporal diff) so the first capture reads a warm
result. `renderLayers` is the layer spec a capture of this view uses when
the caller named none — a view that draws its own geometry and wants the
scene's kept out of the frame (and out of the depth buffer it tests
against) names only its own layer.

**Returns** `number` — The channel number assigned to the view.

```lua
local ch = renderer.captureView.register("lightmap", { description = "...", ensure = fn })
```

## typed/builtin//modules/api/engine/renderer/renderer/captureView/resolve {#typed-builtin-modules-api-engine-renderer-renderer-captureview-resolve}

```lua
renderer.captureView.resolve(name: string) -> any
```

Resolve a capture view by name to its `{ channel, ensure, description,
warmup }` record, or nil when no view is registered under `name`.

**Parameters**

- `name` `string` — The view name.

**Returns** `any` — The view record or nil.

```lua
local v = renderer.captureView.resolve("lightmap")
```

## typed/builtin//modules/api/engine/renderer/renderer/captureView/unregister {#typed-builtin-modules-api-engine-renderer-renderer-captureview-unregister}

```lua
renderer.captureView.unregister(name: string) -> boolean
```

Withdraw a capture view. A subsequent `capture pass=<name>` no longer
resolves to it (falls through to the unknown-view error).

**Parameters**

- `name` `string` — The view name.

**Returns** `boolean` — True when a view was registered under `name`.

```lua
renderer.captureView.unregister("lightmap")
```

## typed/builtin//modules/api/engine/renderer/renderer/clearShadowHero {#typed-builtin-modules-api-engine-renderer-renderer-clearshadowhero}

```lua
renderer.clearShadowHero() -> boolean
```

Release the hero caster, so the directional shadow is the cascades'
alone again and the layer the hero view rendered into is given back.

**Returns** `boolean` — Whether a caster was registered.

```lua
renderer.clearShadowHero()
```

## typed/builtin//modules/api/engine/renderer/renderer/clearShadowProxy {#typed-builtin-modules-api-engine-renderer-renderer-clearshadowproxy}

```lua
renderer.clearShadowProxy(mesh: string?) -> number
```

Stop proxying `mesh`, so it rasterizes its own geometry into shadow
views again. Called with no argument, drops every registration.

**Parameters**

- `mesh` `string` _(optional)_ — The mesh to stop proxying. Omit to clear all of them.

**Returns** `number` — How many registrations were removed.

```lua
renderer.clearShadowProxy(statueMesh)
print(renderer.clearShadowProxy(), "proxies dropped")
```

## typed/builtin//modules/api/engine/renderer/renderer/collect {#typed-builtin-modules-api-engine-renderer-renderer-collect}

```lua
renderer.collect() -> RuntimeCollection
```

Release every runtime texture, material, mesh and render feature nothing
holds: no handle a script still reaches, no live owner, no reference from
live engine state, no asset backing it, no hold. A root scene load runs this
once the new scene stands, so what the previous scene's content created and
nothing still wears goes with that scene; calling it directly collects at
any other moment. A session material's handle counts as reached while the
entity it was keyed for stands, and stops counting once that entity is
gone.
It reaches the GPU textures the device holds beside the registry's own: a
texture the cache loaded for an asset goes once nothing live names it and
is read back from that asset the next time something asks for it, while one
no asset answers for stays, there being nothing to read it back from — a
render pass's own target, a colour swatch, an atlas the engine built. A
texture the ASSET path uploaded and whose asset has since been removed has
nothing to come back from either, and the collection decides about it from
its holders the way it does about every other resource: a handle a script
still reaches, a live owner, a reference from live engine state, a hold.
Features go first, then materials, then meshes, then textures, so a texture
only a released material named goes with the material. Runs a full garbage
collection first, so a handle nothing reaches counts as let go, and yields
for the frame the census runs on. A handle the calling function still has
in a variable — or in a temporary it has not overwritten — is one a script
reaches, so a resource created in the function that collects is let go by
the next collection rather than this one.

**Returns** `RuntimeCollection` — `{ released = { texture, material, mesh, feature }, kept, entries }` — the counts released per kind, how many stayed, and every resource's status with `action = "released" | "kept"`.

```lua
local c = renderer.collect() print(c.released.texture, c.kept)
```

## typed/builtin//modules/api/engine/renderer/renderer/compiledShaders {#typed-builtin-modules-api-engine-renderer-renderer-compiledshaders}

```lua
renderer.compiledShaders() -> { string }
```

Every name `renderer.compiledSource` answers for — one per name a
shader compile has run under this session, whether it succeeded or failed.
What makes the composed-source surface enumerable rather than something to
guess a key for.

**Returns** `{ string }` — An array of shader names, sorted.

```lua
for _, name in renderer.compiledShaders() do print(name) end
```

## typed/builtin//modules/api/engine/renderer/renderer/compiledSource {#typed-builtin-modules-api-engine-renderer-renderer-compiledsource}

```lua
renderer.compiledSource(shader: string) -> string?
```

The WGSL the shader compiler received under one name, exactly as it
received it — the composed module, which is what a compile error's line
numbers and handle indices are positions in. Answers under any name a
compile ran under (identity, guid, alias, or a `program` from
`renderer.shaderVariants()`), for a shader that declares no features, and
for a shader whose compile FAILED, which is the case it exists for: a
message about a function body carries a position and nothing else, and the
text that position is in is this. The failed text stands for as long as
`shaderRef:compileStatus()` reports that failure under the same name.

**Parameters**

- `shader` `string` — Any name a shader compiled under — identity, guid, alias, or a
`shaderVariants()` program name.

**Returns** `string?` — The composed WGSL, or nil for a name no compile has run under.

```lua
local status = asset.resolve("myShader", "shader"):compileStatus()
if status.status == "failed" then
print(status.error)
print(renderer.compiledSource("myShader"))
end
```

## typed/builtin//modules/api/engine/renderer/renderer/compositeSize {#typed-builtin-modules-api-engine-renderer-renderer-compositesize}

```lua
renderer.compositeSize() -> { width: number, height: number }
```

The size of the image the post-scene phases worked on in the last
presented frame — the target the UI composites onto, which every pass
after the scene reads as `@scene.color` and writes into, and which a
`screenSpace = "composite"` render target follows. While the renderer
presents the viewport itself that is the display's own size, whatever
fraction of it the scene rasterized at; while a UI viewport panel owns
the presentation it is the size the scene rasterized at, since the panel
draws the scene target at its own rect and nothing upscales before the
composite. Both read `0` before a frame has drawn.

**Returns** `{ width: number, height: number }` in pixels.

```lua
local c = renderer.compositeSize()
```

## typed/builtin//modules/api/engine/renderer/renderer/cullStats {#typed-builtin-modules-api-engine-renderer-renderer-cullstats}

```lua
renderer.cullStats() -> {
```

What the last completed frame decided to draw. `total` renderables went
into the frustum test, `culled` fell outside it and `visible` survived. Of
those, occlusion culling measured `occlusionTested` against the depth
pyramid and proved `occlusionCulled` were entirely behind other geometry —
both 0 while `renderer.occlusionCulling()` is false. A renderable the
pyramid has no say over — one that laid no depth in the pre-pass, one whose
bounds were never recorded, one straddling the near plane — is measured
against nothing and counted in neither, so the gap between `visible` and
`occlusionTested` reads how much of the frame the test could speak for.

This answers for the main camera. What a shadow view's own volume did with
the frame's casters is on that view's row in `renderer.shadowViews()`.

**Returns** `{ total: number, culled: number, visible: number, occlusionTested: number, occlusionCulled: number }`

```lua
local s = renderer.cullStats(); print(s.visible - s.occlusionCulled, "drawn")
```

## typed/builtin//modules/api/engine/renderer/renderer/debugPass/builtins {#typed-builtin-modules-api-engine-renderer-renderer-debugpass-builtins}

```lua
renderer.debugPass.builtins() -> { string }
```

The built-in debug-pass names, one per channel in channel order — the
engine's built-in pass vocabulary (final, albedo, normal, depth, …).

**Returns** `{ string }` — An array of built-in pass names.

```lua
for _, n in ipairs(renderer.debugPass.builtins()) do ... end
```

## typed/builtin//modules/api/engine/renderer/renderer/debugPass/channel {#typed-builtin-modules-api-engine-renderer-renderer-debugpass-channel}

```lua
renderer.debugPass.channel(name: string) -> number?
```

The channel a debug-pass NAME renders on: a built-in pass, else a content
capture view registered via `renderer.captureView`. Nil when the name is
neither — the signal a selector uses to reject an unknown pass.

**Parameters**

- `name` `string` — A debug-pass name (e.g. "normal", "depth", "lightmap").

**Returns** `number?` — The channel number, or nil for an unknown name.

```lua
local ch = renderer.debugPass.channel("normal")   -- 7
```

## typed/builtin//modules/api/engine/renderer/renderer/debugPass/list {#typed-builtin-modules-api-engine-renderer-renderer-debugpass-list}

```lua
renderer.debugPass.list() -> { string }
```

Every selectable debug-pass name: the built-in passes plus every
registered content capture view. What a debug-pass selector offers.

## typed/builtin//modules/api/engine/renderer/renderer/debugPass/name {#typed-builtin-modules-api-engine-renderer-renderer-debugpass-name}

```lua
renderer.debugPass.name(channel: number) -> string?
```

The canonical NAME for a debug channel: a built-in pass name for a
built-in channel, else a registered capture view's name. Channel 0 is
"final" (the lit image). Nil when no pass owns the channel.

**Parameters**

- `channel` `number` — The channel number.

**Returns** `string?` — The pass name, or nil.

```lua
local name = renderer.debugPass.name(7)   -- "normal"
```

## typed/builtin//modules/api/engine/renderer/renderer/depthPrepass {#typed-builtin-modules-api-engine-renderer-renderer-depthprepass}

```lua
renderer.depthPrepass() -> boolean
```

Whether the opaque depth pre-pass is currently enabled.

**Returns** `boolean`

## typed/builtin//modules/api/engine/renderer/renderer/depthPrepassOrder {#typed-builtin-modules-api-engine-renderer-renderer-depthprepassorder}

```lua
renderer.depthPrepassOrder() -> { runs: number, reordered: number }
```

What the last frame's depth pre-passes planned, and how far their
sequences were from near-to-far before they ordered. `runs` counts the
instanced draws planned; `reordered` counts the adjacent pairs the sort
moved past each other, taken before it ran. Both are summed over every
pre-pass the frame ran — the window plus each render-target camera, each
ordering against its own camera. Both read `0` while the pre-pass or the
ordering is off, and `reordered` reads `0` for a frame that already stood
in order. The ordering leaves no other trace — the draws, the depth and the
image are the same either way.

**Returns** `{ runs: number, reordered: number }`

```lua
local o = renderer.depthPrepassOrder()  -- o.reordered > 0 → it sorted
```

## typed/builtin//modules/api/engine/renderer/renderer/depthPrepassOrdering {#typed-builtin-modules-api-engine-renderer-renderer-depthprepassordering}

```lua
renderer.depthPrepassOrdering() -> boolean
```

Whether the depth pre-pass is submitted nearest-first.

**Returns** `boolean`

## typed/builtin//modules/api/engine/renderer/renderer/destroy {#typed-builtin-modules-api-engine-renderer-renderer-destroy}

```lua
renderer.destroy(handleOrKind: any?, id: string?) -> boolean
```

Free the GPU resource a renderer resource holds (the GPU-destroy verb).
Takes any of the forms that name it: the handle a create returned, routed
by its `category` so one call releases a mixed set of handles; the id a
listing hands out, whose kind is read back off what the renderer holds
under it — the runtime registry, the material definitions, the live
features, and the device itself for an asset's own texture or mesh; or the
kind with the id beside it, the shape `renderer.hold` and
`renderer.references` take, which is what names the kind for an id two of
them answer to. An id nothing holds anything under releases nothing and
answers false. The on-disk asset, if any, is untouched. A CPU handle's
`:unload()` frees the CPU copy separately.

**Parameters**

- `handleOrKind` `any` _(optional)_ — A `MeshHandle`, `TextureHandle`, `MaterialHandle` or feature
handle; the id itself; or the kind (`"texture"`, `"material"`, `"mesh"`,
`"feature"`) with the id as the second argument.
- `id` `string` _(optional)_ — The guid or registry key, when the first argument is a kind.

**Returns** `boolean` true if a GPU resource was known under the id.

```lua
renderer.destroy(meshHandle); renderer.destroy(materialHandle)
renderer.destroy(renderer.texture.list()[1].guid)
renderer.destroy("mesh", guid)
```

## typed/builtin//modules/api/engine/renderer/renderer/deviceGeneration {#typed-builtin-modules-api-engine-renderer-renderer-devicegeneration}

```lua
renderer.deviceGeneration() -> number
```

Which render device this process is on, counted from the first.

A render device is lost when a driver resets, when the GPU is taken away,
or when a browser reclaims a WebGPU context. The engine answers by building
another device and re-deriving this session's resources onto it, and this
number moves by one each time it does. Anything held across frames that was
built from a GPU resource records this beside it and remakes it when the two
differ; `engine.onDeviceRebuilt` is the hook that fires when it moves.

**Returns** `number` — The current device generation, counting from 1.

```lua
local generation = renderer.deviceGeneration()
engine.onDeviceRebuilt(function(g) print("device " .. g) end)
```

## typed/builtin//modules/api/engine/renderer/renderer/deviceState {#typed-builtin-modules-api-engine-renderer-renderer-devicestate}

```lua
renderer.deviceState() -> string
```

Whether the render device this process draws through is the one it is
using, one it is replacing, or one it has stopped trying to replace.

`"ready"` is a live device. `"rebuilding"` is the window between a device
reporting itself lost and another being in place: every GPU resource built
from the old one is invalid, the frames in that window draw nothing, and
anything reaching the GPU refuses. `"abandoned"` is after the engine gave
up — the adapter refused every attempt, so this session draws no more
frames.

Work that spans the device — build a render target, draw into it, read it
back — reads this to tell an operation that failed because the device went
out from under it, which is worth doing again once
`renderer.deviceGeneration()` moves, from one that failed on its own terms.
The loss is reported before the next device exists, so the two readings
answer different halves: this one says a replacement is coming, the
generation says it arrived.

**Returns** `string` — `"ready"` | `"rebuilding"` | `"abandoned"`.

```lua
if renderer.deviceState() == "rebuilding" then return end
```

## typed/builtin//modules/api/engine/renderer/renderer/drawDiagnostics {#typed-builtin-modules-api-engine-renderer-renderer-drawdiagnostics}

```lua
renderer.drawDiagnostics() -> { DrawDiagnostic }
```

Every renderable that is NOT drawing what its material says — the one
call for "why does this surface look wrong". Three states land here: a
surface rendering as the magenta placeholder (`substituted`), one the
renderer could bind nothing for at all (`outcome = "skipped"`), and one
drawing a program whose most recent compile FAILED (`stale`), which is what
a shader edited into brokenness looks like — the pipeline its last good
compile built keeps drawing, so the picture is intact and answers to none of
the edits since. Each row names the entity, the program asked for, the
program bound, `programStatus` — the compile gate's word about the program
the material NAMED — and the one cause
from `shaderCompileFailed` / `shaderNotRegistered` / `shaderNotCompiledYet`
/ `noGbufferEntry` / `renderStateKeyNotBuilt` / `noPipelineForTarget` /
`unshaded`, with the compiler's own message in `detail` or `programError`.
Covers every renderable the renderer holds, whether or not a camera reached
it: a row with `observed = false` and `outcome = "notDrawn"` carries the
renderer's own resolution for one this frame drew nowhere, so a broken
surface off-screen is reported the same as one in frame. An empty result
means every renderable the renderer holds is drawing the program its
material named and that program compiles. Answers on the deferred path as
well as forward, and in edit mode as well as play.

**Returns** `{ DrawDiagnostic }`

```lua
for _, d in renderer.drawDiagnostics() do print(d.entity, d.reason, d.detail) end
if #renderer.drawDiagnostics() == 0 then print("every surface is drawing what it says") end
```

## typed/builtin//modules/api/engine/renderer/renderer/drawStats {#typed-builtin-modules-api-engine-renderer-renderer-drawstats}

```lua
renderer.drawStats() -> {
```

What the last completed frame actually submitted. `draws` counts every
geometry draw call the frame issued — the camera's passes, each shadow
view a shadow-casting light adds, and whatever a render feature draws —
and `instances` counts the instances those draws covered. The pair is what
separates one draw carrying five hundred instances from five hundred draws
carrying one each, so it reads how well the scene batches rather than how
many objects are in it.

`compacted` is how many of those instances the frame planned through draws
whose instance count the GPU decides: the culler's own per-object answers
packed into a dense run, so an object it rejects is absent from the draw
instead of collapsing to nothing in the vertex stage. `compactedDrawn` is
how many of them survived, counted on the GPU as it packed them — a pass
that then skips a whole draw over its own layer or visibility answer
leaves that draw's instances in both numbers.

The plan is made over the populations the frame draws, and the tests
answer which of their instances the packing keeps. That packing runs
before any pass has resolved the depth occlusion culling is tested
against, so on its own it reads the frustum and screen-size answers
alone. With `setOcclusionCulling` armed the frame packs the same plan a
second time once the test has answered, and `compactedDrawn` then counts
what came through occlusion as well.

`compactedDrawn` comes back from the buffer the GPU wrote, so it describes
a frame that has finished while `compacted` describes the most recent
plan, and it holds the last count the GPU wrote until another arrives — a
frame that compacts nothing reads `compacted` 0 beside the count from the
last frame that did. In a scene standing still the gap between the two is
the front-end work culling removed.

`materialBinds` is how many times the frame's geometry passes set a
material's parameter group, and `materialBindsElided` how many times a
pass reached that decision and found the group already bound. Their sum
is how many times the decision was reached — once per unit of geometry
submitted, which sits at or below `draws`, since a mesh of several
primitives draws once per primitive under one set of binds. The ratio
inside the pair is what material binding costs the frame: the batched
opaque geometry is gathered into runs sharing a material, so a frame of
many such draws over few materials binds about once per material rather
than once per unit. `materialExtraBinds` and `materialExtraBindsElided`
are the same pair for the second group, the storage bindings a shader
declares for itself, which only the shaders that have them ever bind.

`pipelineBinds` and `pipelineBindsElided` are the same pair for the
pipeline itself: how many times the frame's geometry passes set one, and
how many times a pass reached that decision and found the pipeline it
wanted already bound. Which pipeline a unit needs follows its shader, its
material's render state and its mesh's vertex layout together, so a scene
whose units share all three costs one set for the run of them, while units
differing in any one of the three each pay their own. Their sum is how
many units reached the pipeline decision, which sits at or above what the
material pair reports: a unit the pass settles a pipeline for and then
abandons — one whose material group resolved to nothing — counts here and
never reaches the material decision.

Every figure here is the whole frame's, the main camera's draws and every
shadow view's summed together. `renderer.shadowViews()` splits `compacted`
and `compactedDrawn` across the views that made them, and carries the
camera's own share beside them.

**Returns** `{ draws: number, instances: number, compacted: number, compactedDrawn: number, materialBinds: number, materialBindsElided: number, materialExtraBinds: number, materialExtraBindsElided: number, pipelineBinds: number, pipelineBindsElided: number }`

```lua
local d = renderer.drawStats(); print(d.instances / math.max(d.draws, 1), "instances per draw")
print(renderer.drawStats().compactedDrawn, "of", renderer.drawStats().compacted, "survived the cull")
local d = renderer.drawStats(); print(d.materialBinds, "material binds over", d.materialBinds + d.materialBindsElided, "units")
local d = renderer.drawStats(); print(d.pipelineBinds, "pipeline sets over", d.pipelineBinds + d.pipelineBindsElided, "units")
```

## typed/builtin//modules/api/engine/renderer/renderer/feature/create {#typed-builtin-modules-api-engine-renderer-renderer-feature-create}

```lua
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.

## typed/builtin//modules/api/engine/renderer/renderer/feature/destroy {#typed-builtin-modules-api-engine-renderer-renderer-feature-destroy}

```lua
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.

**Parameters**

- `handleOrGuid` `any` _(optional)_ — A `RenderFeatureHandle` or its `guid` string.

**Returns** `boolean`

```lua
renderer.feature.destroy("eb623975-d8bd-47a1-a0a4-5c0e56238e2f")
```

## typed/builtin//modules/api/engine/renderer/renderer/feature/list {#typed-builtin-modules-api-engine-renderer-renderer-feature-list}

```lua
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).

## typed/builtin//modules/api/engine/renderer/renderer/feature/shaded {#typed-builtin-modules-api-engine-renderer-renderer-feature-shaded}

```lua
renderer.feature.shaded() -> { [string]: number }
```

How many pixels each fragment pass a render feature enqueued shaded on
the last drawn frame, keyed by the pass's shader/effect name. A fragment
pass draws one triangle over its target, so it shades the whole screen
whatever its effect actually reaches — unless it declares `bounds` on the
pass spec, the world-space box its effect stays inside, in which case it
shades the rectangle that box projects into for the camera drawing it and
is skipped for a camera that cannot see the box at all. This is the reading
that says which of the two a pass is: it moves when the effect moves, and a
pass absent from it shaded nothing. Summed over every camera the frame drew.

**Returns** `{ [string]: number }` — `{ [shader: string]: number }` — pixels shaded, last drawn frame.

```lua
local px = renderer.feature.shaded(); for name, n in pairs(px) do print(name, n) end
```

## typed/builtin//modules/api/engine/renderer/renderer/featureTexture/configure {#typed-builtin-modules-api-engine-renderer-renderer-featuretexture-configure}

```lua
renderer.featureTexture.configure(width: number, height: number, layers: number)
```

Size the shared feature-texture array — the layers a surface shader reads
through `zero_feature_texture(uv, layer)`, and the layers a `SpotLight`
projects through its cone via `cookieLayer`. Layers are `rgba16f`.
A call for the size the array already has is left alone. One that changes
the size reallocates, and the replacement is zeroed — so it empties every
layer in the array, including the layers other features and other cookies
own. `renderer.featureTexture.state()` reports the extent and the layers
holding content, which is how a feature re-fills the layer a resize took
from it.

**Parameters**

- `width` `number` — Layer width in pixels.
- `height` `number` — Layer height in pixels.
- `layers` `number` — How many layers the array holds.

```lua
renderer.featureTexture.configure(512, 512, 4)
```

## typed/builtin//modules/api/engine/renderer/renderer/featureTexture/setLayer {#typed-builtin-modules-api-engine-renderer-renderer-featuretexture-setlayer}

```lua
renderer.featureTexture.setLayer(layer: number, textureKey: string, x: number, y: number)
```

Copy a texture already on the GPU into one layer of the shared array,
its top-left corner at `(x, y)` — GPU to GPU, with no readback. Several
small images pack into one layer by calling this once per image at
different offsets. The source must be `rgba16f` and fit at that offset.

**Parameters**

- `layer` `number` — Which layer of the array to write into.
- `textureKey` `string` — The source texture's name — the one it was created under.
A `compute.createStorageTexture2D` target, a `compute.createTextureHistory`
pair (its current side), and a texture a `compute.copyBufferToTexture`
wrote all answer to the name they were given.
- `x` `number` — Left edge of the destination rectangle, in pixels.
- `y` `number` — Top edge of the destination rectangle, in pixels.

```lua
compute.createStorageTexture2D("gobo", { width = 256, height = 256, format = "rgba16f" })
renderer.featureTexture.setLayer(0, "gobo", 0, 0)
```

## typed/builtin//modules/api/engine/renderer/renderer/featureTexture/state {#typed-builtin-modules-api-engine-renderer-renderer-featuretexture-state}

```lua
renderer.featureTexture.state() -> {
```

What the shared feature-texture array is right now: the extent every
layer carries, and `filled`, the ascending 0-based indices of the layers a
`setLayer` has landed in since the array was last sized. One array is
shared by every feature and every light cookie in the scene, and it has no
allocator, so this is the call that tells a feature whether the array it
sized and filled is still the array it is writing into — a `configure` that
changed the size reallocates and zeroes every layer, and the layer it
emptied leaves `filled` without it. Measured off the renderer at the end of
the last rendered frame, so a `configure` or `setLayer` issued this frame
reads back on a later one.

What this describes is the array a shader samples. The source texture a
`setLayer` copied FROM is a GPU resource of its own and keeps the bytes it
was written with for as long as it lives, so `filled` is the reading that
answers whether the layer behind a `cookieLayer` is live right now.

**Returns** `{ width, height, layers, filled }`

```lua
local ft = renderer.featureTexture.state()
print(("feature textures: %dx%d over %d layers"):format(ft.width, ft.height, ft.layers))
-- Re-fill the cookie layer this module owns if anything emptied it.
if ft.width ~= myWidth or table.find(ft.filled, myLayer) == nil then
refillMyCookie()
end
```

## typed/builtin//modules/api/engine/renderer/renderer/framePacing {#typed-builtin-modules-api-engine-renderer-renderer-framepacing}

```lua
renderer.framePacing() -> FramePacing?
```

How far the CPU is allowed to run ahead of the GPU, and what holding it
there cost the frame just finished. Submitting work to the GPU returns
before the GPU has done it, and everything that submission holds — its
staging allocations, its bind groups, its command buffer — stays alive
until it completes. A frame that asks for more work than the GPU finishes
in a frame's time therefore leaves that behind it, and unbounded that is
memory growth rather than a lower frame rate.

`framesInFlight` is how many submitted frames have not reported done
through the queue's completion signal, held under `maxFramesInFlight`: a
device that keeps up reads under the bound, one that is behind reads at it.
It counts submissions, which is its own quantity — how many presented
images the swapchain permits in flight is a separate setting.
`mechanism` names how that bound is enforced
here: `submission-wait` waits for the frame that many frames back and
reports the wait in `waitMs`, so a paced frame costs latency and still
draws; `submitted-work-done` counts outstanding frames off the queue's
completion signal and declines to start a frame while the bound is met,
counting those in `pacedFrames` and leaving the last presented image up.
`submittedFrames` counts the frames that were admitted and submitted, so it
rises for as long as the renderer is producing frames — which is what tells
a renderer running slowly under a tight bound from one that has stopped.
`stalled` reads true while that completion signal has stopped arriving and
the pacer stood down rather than hold the image indefinitely; it clears on
the first frame that finds the count back under the bound.

`producing` is whether the renderer is drawing frames at all. A headless
renderer draws into an offscreen framebuffer that nothing presents, so its
image reaches a reader only through something that copies it out: it draws
while a consumer is asking — an MCP call in flight, a queued texture
readback, a recording, a frame-egress session — and declines the frames
between two asks, counting them in `idleSkippedFrames`. Every other
renderer stat answers with the last frame that drew, so `producing` is what
separates a live reading from a frozen one. A windowed renderer presents
every frame it draws and reads `producing = true` throughout.

`presentMode` is what the surface presents with and `presentModes` what it
offers; both are empty of meaning on a headless renderer, which never
presents.

**Returns** `FramePacing?` — `{ framesInFlight, maxFramesInFlight, pacedFrames, submittedFrames, waitMs, mechanism, stalled, producing, idleSkippedFrames, presentMode, presentModes }`, or nil before the renderer has drawn a frame

```lua
local p = renderer.framePacing()
print(("%d of %d frames in flight, paced by %s"):format(p.framesInFlight, p.maxFramesInFlight, p.mechanism))
```

## typed/builtin//modules/api/engine/renderer/renderer/getRaytrace {#typed-builtin-modules-api-engine-renderer-renderer-getraytrace}

```lua
renderer.getRaytrace() -> boolean
```

Whether ray tracing is currently enabled.

**Returns** `boolean`

## typed/builtin//modules/api/engine/renderer/renderer/gpuMemory {#typed-builtin-modules-api-engine-renderer-renderer-gpumemory}

```lua
renderer.gpuMemory() -> GpuMemory
```

Where the renderer's GPU memory went at the last completed frame — the
call to reach for when something is holding memory and you do not know
what.

Three figures answer three different questions, and they are meant to be
read against each other:

* The categories — `shadow`, `textures`, `meshes`, `instances`, `compute`,
summing to `categorised` — are the renderer's own accounting of what it
asked for on purpose. Always present, on every backend.
* `allocator` is the device allocator's ledger, with a row per creation
label largest first, which is what names an allocation no category
claims. It exceeds `categorised` by the per-frame render targets and the
scratch nothing categorises. The allocator hands memory out from blocks
it reserves whole from the device and returns a block only once nothing
is left in it, so `reservedBytes` runs above `allocatedBytes` by what
those blocks hold unused; `blocks` lists them emptiest first with the
labels that keep each one alive, and `emptyBytes` plus `slackBytes` is
that distance exactly — the pool held in empty blocks, and the room
pinned inside blocks something still sits in.
* `driver.deviceLocalBytes` is what the graphics driver charges this
process, out of the kernel's own accounting. It is the biggest of the
three and the one that fills a card, because it also holds the
swapchain, the images the driver keeps on the renderer's behalf, and the
rounding to whole pages and heap blocks that neither figure above sees.
Read it when the question is how much of the machine's GPU this engine
is using; read the two above when the question is what the engine spent
it on. A platform with no per-process accounting reports
`available = false` and the reason.
* `driver.outsideAllocatorBytes` is that charge less everything the
allocator reserved — what the driver holds on its own account, and the
one figure here nothing releases: a dropped pipeline, another scene and
`renderer.collect()` all leave it where it is, and it falls when the
device is destroyed. Read it when a session's device memory has grown
and no ledger row accounts for the growth.

`compute` is what the compute subsystem holds; `compute.observe()` names
each of those resources and what it costs. `renderTargets` counts the
offscreen render targets the renderer holds at that frame, which is what
says a `renderer.destroy` has been applied rather than queued.

**Returns** `GpuMemory` — The accounting — see `GpuMemory`. The category figures are zeroed until the renderer has published its first frame; `driver` is read as the call runs and answers from the first.

```lua
local m = renderer.gpuMemory()
print(("shadows %.1f MiB"):format(m.shadow.total / 1024 / 1024))
-- how much of the card this engine is holding:
if m.driver.available then
print(("driver %.1f MiB"):format(m.driver.deviceLocalBytes / 1024 / 1024))
else
print("no driver figure: " .. m.driver.reason)
end
-- the biggest allocation in the engine:
local top = m.allocator and m.allocator.byLabel[1]
print(top and top.label, top and top.bytes)
-- the block held for the least, and what pins it:
local block = m.allocator and m.allocator.blocks[1]
if block and block.allocationCount > 0 then
print(block.size, block.allocatedBytes, block.byLabel[1].label)
end
```

## typed/builtin//modules/api/engine/renderer/renderer/hold {#typed-builtin-modules-api-engine-renderer-renderer-hold}

```lua
renderer.hold(handleOrKind: any?, id: string?) -> boolean
```

Pin a runtime resource for the session. A held texture, material, mesh
or render feature survives every collection — the one a root scene load
runs and a direct `renderer.collect()` alike — until `renderer.release`
lets it go or its destroy frees it. It is the way to keep an ad-hoc
resource across the scenes that come and go under it. A hold keeps the
resource in the registry; a mesh's GPU buffers are governed by what draws
it, parked as a CPU definition when the last instance naming it goes and
brought back when one names it again, so `renderer.mesh.isResident(guid)`
is the separate question about the buffers.

**Parameters**

- `handleOrKind` `any` _(optional)_ — The resource's handle, or its kind (`"texture"`, `"material"`,
`"mesh"`, `"feature"`) with the guid or key as the second argument.
- `id` `string` _(optional)_ — The guid or key, when the first argument is a kind.

**Returns** `boolean` true when the registry knows the resource.

```lua
renderer.hold(tex)
renderer.hold("material", "swatch")
```

## typed/builtin//modules/api/engine/renderer/renderer/instanceData/clear {#typed-builtin-modules-api-engine-renderer-renderer-instancedata-clear}

```lua
renderer.instanceData.clear(target: string | entityRef)
```

Drop every lane of an entity's per-instance shader data, so its draws
read zero again — how a feature releases a subject it is still holding.
Despawning an entity releases its block too, so this is for a subject that
stays. It takes an entity that has already gone, which is when a feature
releasing its subjects often runs, and does nothing for an entity holding
no block.

**Parameters**

- `target` `string | entityRef` — The entity — a proxy from `entity(...)` / `entity.spawn(...)`, or
an entity-id string.

```lua
renderer.instanceData.clear(subject)
```

## typed/builtin//modules/api/engine/renderer/renderer/instanceData/laneCount {#typed-builtin-modules-api-engine-renderer-renderer-instancedata-lanecount}

```lua
renderer.instanceData.laneCount() -> number
```

How many `vec4` lanes each entity's per-instance block holds, so a lane
index runs `0 .. laneCount() - 1`. The same count a surface shader indexes
`input.shader_data` against.

**Returns** `number` — lanes per entity.

```lua
for lane = 0, renderer.instanceData.laneCount() - 1 do
renderer.instanceData.set(subject, lane, 0)
end
```

## typed/builtin//modules/api/engine/renderer/renderer/instanceData/set {#typed-builtin-modules-api-engine-renderer-renderer-instancedata-set}

```lua
renderer.instanceData.set(target: string | entityRef, lane: number, x: number, y: number?, z: number?, w: number?)
```

Write one `vec4` lane of an entity's per-instance shader data — the
channel that lets ONE material serve many entities that differ in a value.
A surface shader reads the lane back as `input.shader_data[lane]`, so a
dissolve at its own progress per subject, an effect at its own age per
firing, or a per-entity mask costs one material rather than one material
per entity.

The engine attaches no meaning to a lane: a feature picks the lane indices
it owns and packs whatever its shader agrees they carry. Name those indices
in the module that writes them, so the writer and the shader read the block
the same way.

The write reaches the block where it is called, so the entity it names is
the one holding that id at that point in the tick, and the value is on the
draw from the next frame. It is held until the lane is written again, the
entity's block is cleared, or the entity is despawned — a despawned entity
releases its whole block. A lane an entity was never given reads zero.

## typed/builtin//modules/api/engine/renderer/renderer/loseDevice {#typed-builtin-modules-api-engine-renderer-renderer-losedevice}

```lua
renderer.loseDevice()
```

Destroy the render device on the next frame, so the engine meets a real
device loss.

This is the one loss that can be caused on purpose, and it travels the same
path a driver reset does: frames draw nothing until the rebuild lands,
`GET /engine/status` reports the renderer as `recovering` while it does,
`engine.onDeviceRebuilt` fires afterwards, and `renderer.deviceGeneration()`
moves. Use it to prove that a world's content survives a device loss —
anything it holds only on the GPU has to be remade from the rebuild hook, and
this is how you find out whether it is.

```lua
renderer.loseDevice()
-- some frames later:
print(renderer.deviceGeneration()) -- one higher than before
```

## typed/builtin//modules/api/engine/renderer/renderer/mainCameraView {#typed-builtin-modules-api-engine-renderer-renderer-maincameraview}

```lua
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.

**Returns** `{ number }?` 19 numbers, or nil.

## typed/builtin//modules/api/engine/renderer/renderer/material/animatedTexture {#typed-builtin-modules-api-engine-renderer-renderer-material-animatedtexture}

```lua
renderer.material.animatedTexture(texture: string | AssetRef, opts: { [string]: any }?) -> MaterialHandle
```

Build a material that PLAYS a layered texture: its layers bound as the
frames, its timing bound beside them, and the engine's `animatedTexture`
shader turning the clock into the layer showing now. One call from an
imported animated image to a material an entity can wear.

The layer showing is resolved per pixel against the texture's own schedule,
so frames of unequal length are shown for the lengths they were authored
with, and the sequence loops. `speed` scales the clock (2 plays twice as
fast, 0 holds the frame `startTime` lands in) and `startTime` offsets into
the sequence, so two surfaces sharing one texture can run out of phase.

The clock is the engine's, and it runs in edit mode as much as in play and
through a pause, so two screenshots of one surface taken moments apart are
two different frames of it. `speed = 0` holds one frame for as long as it
is set, which is the state to compare two screenshots in.

The returned handle is what a surface wears — `Model:applySessionMaterial`
takes it, and so does a Model's `material` field. The handle's `guid` is
this material's REGISTRY KEY, the currency of `setProperty`, `describe` and
`destroy`; a component field resolves an asset, so a bare key in one leaves
the component waiting for an asset to register under that name.

The builtin `plane` mesh emits `uv = (u, v)` with `v` along its own +Z, so
a quad pitched +90° about X (`Transform.eulerToQuat(0, math.pi / 2)`) shows
the image upright to a camera on +Z, and -90° shows it first-row-last.

A texture whose layers carry no timing is rejected — there is nothing to
play. `renderer.texture.info(bytes).animated` is the test.

**Parameters**

- `texture` `string | AssetRef` — The texture — a guid, an identity, a name, a path, or a texture `AssetRef`.
- `opts` `{ [string]: any }` _(optional)_ — `{ key?, speed?, startTime?, alphaCutoff?, baseColor?, uvScale?, uvOffset? }`.

**Returns** `MaterialHandle`

```lua
local mat = renderer.material.animatedTexture("banner.texture")
local id = entity.spawn("billboard", { rotation = { Transform.eulerToQuat(0, math.pi / 2) } })
entity(id).component.add("Model", { model = "plane" })
entity(id).component.get("Model"):applySessionMaterial(mat)
renderer.material.setProperty(mat.guid, "speed", 2)
```

## typed/builtin//modules/api/engine/renderer/renderer/material/create {#typed-builtin-modules-api-engine-renderer-renderer-material-create}

```lua
renderer.material.create(content: MaterialContent, key: string) -> MaterialHandle
```

## typed/builtin//modules/api/engine/renderer/renderer/material/describe {#typed-builtin-modules-api-engine-renderer-renderer-material-describe}

```lua
renderer.material.describe(key: string | { [string]: any } | AssetRef) -> 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). `properties` and `textures` carry the material's current values:
each `setProperty` / `setTexture` write lands on this record, a texture slot
under the GPU key the slot binds by — these are the WRITES, held here
whether or not the renderer took them up. `renderer` beside them is what the
renderer holds for the same key: the program its prepared bind group was
built against, the render state its draws are looked up under, whether a
pipeline exists for that key, and how many draws the observed frame gave
it. `renderer` is nil when the renderer holds no material under this key at
all, and `resident` states the same fact as a boolean. Writes reach the
screen through both halves: `resident = false` says the renderer holds
nothing to put them in, and `renderer.draws = 0` on a resident material
says it holds them and no renderable is drawing with it. For a material
that is resident AND drawn and still looks wrong,
`renderer.drawDiagnostics()` names the renderable and the cause.

**Parameters**

- `key` `string | { [string]: any } | AssetRef` — The material's registry key, the `MaterialHandle` from
`renderer.material.create`, or an `AssetRef` from `asset.resolve`.

**Returns** `any` — `MaterialContent?` with `resident: boolean` and `renderer: MaterialObservation?` fields

## typed/builtin//modules/api/engine/renderer/renderer/material/destroy {#typed-builtin-modules-api-engine-renderer-renderer-material-destroy}

```lua
renderer.material.destroy(key: string | { [string]: any } | AssetRef) -> 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.

The reach is the registry: after this, `describe` and `list` stop answering
for the key. A surface already wearing the handle goes on drawing what it
was given — `Model:restoreSessionMaterial` is what puts a Model back on its
authored material.

**Parameters**

- `key` `string | { [string]: any } | AssetRef` — The material's registry key (the one passed to `create`), the
`MaterialHandle` `create` returned, or an `AssetRef` from `asset.resolve`.

**Returns** `boolean` true when a definition was known under `key`.

```lua
renderer.material.destroy("__preview_swatch_" .. texGuid)
```

## typed/builtin//modules/api/engine/renderer/renderer/material/list {#typed-builtin-modules-api-engine-renderer-renderer-material-list}

```lua
renderer.material.list() -> { any }
```

Every runtime material currently registered, ordered by registry key.
Each entry carries the key, where it came from, and the shader it binds.
`renderer.references("material", key)` says what is still holding a row,
and `renderer.collect()` releases the rows nothing holds.

## typed/builtin//modules/api/engine/renderer/renderer/material/renderState {#typed-builtin-modules-api-engine-renderer-renderer-material-renderstate}

```lua
renderer.material.renderState(key: string | { [string]: any } | AssetRef) -> MaterialObservation?
```

What the renderer holds for a material, which is a different document
from the values written to it. `shader` is the program its prepared bind
group was built against, `renderState` the blend / cull / topology / queue /
depth key its draws are looked up under, `keyBuilt` whether a pipeline
exists for that key, and `draws` / `instances` / `placeholderDraws` /
`binds` / `bindsElided` what it cost in the frame the renderer last
observed — those five read 0 until something arms per-draw recording, which
`renderer.materialCost()` and
`renderer.drawDiagnostics()` do. `nil` means the renderer holds no material
under this key at all — the writes landed on a record nothing is drawing
with.

**Parameters**

- `key` `string | { [string]: any } | AssetRef` — The material's registry key, the `MaterialHandle` from
`renderer.material.create`, or an `AssetRef` from `asset.resolve`.

**Returns** `MaterialObservation?`

```lua
local r = renderer.material.renderState("water"); print(r.renderState.blend, r.keyBuilt)
```

## typed/builtin//modules/api/engine/renderer/renderer/material/sessionKeyFor {#typed-builtin-modules-api-engine-renderer-renderer-material-sessionkeyfor}

```lua
renderer.material.sessionKeyFor(entityId: string) -> string
```

The canonical registry key for an entity's SESSION material — the
runtime material a system (e.g. GI baking) shows on an entity in place
of its authored material for the lifetime of the engine session. One
session material per entity: create it under this key, hand the handle
to `Model:applySessionMaterial`, and the component re-adopts it across
VM reloads by probing this key with `describe`. The key names the entity
for as long as the entity stands: once it is gone the session store lets
the handle go, and a collection releases the material and whatever its
bindings were the last to hold.

**Parameters**

- `entityId` `string` — The entity carrying the material.

**Returns** `string` — The registry key string.

```lua
local key = renderer.material.sessionKeyFor(entityId)
```

## typed/builtin//modules/api/engine/renderer/renderer/material/setProperty {#typed-builtin-modules-api-engine-renderer-renderer-material-setproperty}

```lua
renderer.material.setProperty(key: string | { [string]: any } | AssetRef, 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. The value written becomes the material's current one: it is
what `describe` reports, and — for a property the material's shader
declares, which is what the uniform buffer is packed by — what a material
`AssetRef` reads back through `getProperty` / `getProperties` and what the
surface is drawn with. A write under any other name reaches the record
`describe` reports, which is where it reads back.

**Parameters**

- `key` `string | { [string]: any } | AssetRef` — The material's registry key, the `MaterialHandle` from
`renderer.material.create`, or an `AssetRef` from `asset.resolve`.
- `name` `string` — Property name.
- `value` `any` _(optional)_ — New value.

**Returns** `()`

```lua
renderer.material.setProperty(asset.resolve("wall", "material"), "roughness", 0.2)
```

## typed/builtin//modules/api/engine/renderer/renderer/material/setTexture {#typed-builtin-modules-api-engine-renderer-renderer-material-settexture}

```lua
renderer.material.setTexture(key: string | { [string]: any } | AssetRef, slot: string, ref: string | { [string]: any } | AssetRef) -> ()
```

Push one changed texture slot to a registered material's GPU record.
Keyed by the material's registry key.

**Parameters**

- `key` `string | { [string]: any } | AssetRef` — The material's registry key, the `MaterialHandle` from
`renderer.material.create`, or an `AssetRef` from `asset.resolve`.
- `slot` `string` — Texture slot name (`"base_color_texture"`, …).
- `ref` `string | { [string]: any } | AssetRef` — Texture reference — a `.texture` guid / identity / name / path, the
image path it was imported from, a `color:` / `default:` form, a live GPU
handle, or a texture `AssetRef` carrying one. An asset reference is
materialised (Disk→CPU→GPU) and bound by the key the upload lands under.

**Returns** `()`

```lua
renderer.material.setTexture("sky", "sky_texture", "panorama.texture")
```

## typed/builtin//modules/api/engine/renderer/renderer/materialCost {#typed-builtin-modules-api-engine-renderer-renderer-materialcost}

```lua
renderer.materialCost() -> { MaterialObservation }
```

What each material cost the frame the renderer last drew, and the state
it holds each one under. One row per material the renderer holds a prepared
bind group for — a material an author wrote and the renderer never prepared
is absent, which is itself the answer to "why is nothing I set reaching the
screen". `draws` and `instances` cover that one frame; `placeholderDraws`
is how many of those draws bound the magenta placeholder instead of this
material's own program; `binds` is how many material-owned bind groups the
frame's passes SET for it and `bindsElided` how many of its draws wanted a
group the pass already held, which is what draw-key sorting buys; a draw
that fell back to the placeholder bound the placeholder's group, so it
counts in `placeholderDraws` and in neither bind count. `uniformBytes` is
the GPU uniform buffer's own size,
which is the reflected property block raised to the 16-byte floor and
rounded up to the copy alignment. `renderer.drawDiagnostics()` names WHICH
renderable is not drawing what its material says, and why.

**Returns** `{ MaterialObservation }`

```lua
for _, m in renderer.materialCost() do print(m.material, m.draws, m.binds, m.bindsElided) end
```

## typed/builtin//modules/api/engine/renderer/renderer/materialIdentity {#typed-builtin-modules-api-engine-renderer-renderer-materialidentity}

```lua
renderer.materialIdentity() -> MaterialIdentity
```

Which material each renderable draws with, as a number a shader can
carry. A material is authored and bound by name, and no shader can read a
string — so every renderable's per-instance record holds a material index
instead. `slots` is the name → index table those indices are drawn from: an
index is assigned the first time the renderer draws with that material and
does not move afterwards, so two renderables that differ only in material
read different indices, and one renderable reads the same index frame after
frame. It follows that the table keeps a row for every material name drawn
this session, whether or not anything still draws with it. `renderables` is
a row per renderable that owns a GPU slot — the entity it belongs to, that
slot, and the index the record at it carries; `populations` is the same for
an instanced draw, whose whole reserved run of slots carries the one
material its registration named. That index is what a shader reads as
`instance_data[slot].material_index`, and the row a ray hit resolves
through `zeroMaterial()`. A renderable draws with the material its entity
references, so one whose entity names none carries index 0.

**Returns** `MaterialIdentity` — `{ slots: { [string]: number }, renderables: { { entity: string, slot: number, index: number, material: string } }, populations: { { slot: number, count: number, index: number, material: string } } }`

```lua
local id = renderer.materialIdentity()
for _, r in id.renderables do print(r.entity, r.slot, r.index, r.material) end
```

## typed/builtin//modules/api/engine/renderer/renderer/materialIndex {#typed-builtin-modules-api-engine-renderer-renderer-materialindex}

```lua
renderer.materialIndex(name: string) -> number?
```

The index standing for a material, or `nil` for one the renderer has not
drawn with yet. Pass it to a shader (or compare it against what a shader
read out of `instance_data[slot].material_index`) to tell which material a
drawing instance carries.

**Parameters**

- `name` `string` — `string` Material name, as `renderer.material.create` filed it.

**Returns** `number?`

```lua
local red = renderer.materialIndex("brick_red")
```

## typed/builtin//modules/api/engine/renderer/renderer/maxAnisotropy {#typed-builtin-modules-api-engine-renderer-renderer-maxanisotropy}

```lua
renderer.maxAnisotropy() -> number
```

The highest anisotropy this device honours: 16 on hardware that filters
anisotropically, 1 on hardware that does not, where a higher request would
be downgraded to trilinear regardless. Read it to report quality honestly —
`renderer.setAnisotropy` clamps for you, so a request never needs guarding.

**Returns** `number` — The device ceiling, 1 or 16.

```lua
local best = renderer.maxAnisotropy()
```

## typed/builtin//modules/api/engine/renderer/renderer/mesh/boundsSource {#typed-builtin-modules-api-engine-renderer-renderer-mesh-boundssource}

```lua
renderer.mesh.boundsSource(mesh: string | { [string]: any } | AssetRef) -> string
```

Where this mesh's culling bounds come from. `"compute"` once a compute
pass has written its vertices: the engine reduces those vertices to an AABB
every frame, so the mesh is culled against the geometry the pass produced
wherever it puts it. `"geometry"` otherwise: the AABB of the geometry the
mesh was created with.

**Parameters**

- `mesh` `string | { [string]: any } | AssetRef` — The mesh — a `MeshHandle`, a `MeshCpuHandle`, a guid, or a mesh `AssetRef`.

**Returns** `string` — `"compute"` or `"geometry"`.

```lua
print(renderer.mesh.boundsSource(mesh))
```

## typed/builtin//modules/api/engine/renderer/renderer/mesh/buildClusters {#typed-builtin-modules-api-engine-renderer-renderer-mesh-buildclusters}

```lua
renderer.mesh.buildClusters(mesh: string | { [string]: any } | AssetRef) -> 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. Returns nil when the mesh is degenerate, and on an engine whose
`renderer.mesh.canBuildClusters` reports false. Pair with
`renderer.mesh.uploadClusters`.

**Parameters**

- `mesh` `string | { [string]: any } | AssetRef` — A mesh loaded into the CPU store (`renderer.mesh.loadCpu`) — the
`MeshCpuHandle`, a `MeshHandle`, a guid, or a mesh `AssetRef`.

**Returns** `string?` — Serialized cluster bytes, or nil.

```lua
local cb = renderer.mesh.buildClusters(cpu)
```

## typed/builtin//modules/api/engine/renderer/renderer/mesh/canBuildClusters {#typed-builtin-modules-api-engine-renderer-renderer-mesh-canbuildclusters}

```lua
renderer.mesh.canBuildClusters() -> boolean
```

Whether this engine bakes cluster-LOD hierarchies. It reads the binding
the running engine registered: every target the engine ships on carries the
builder, so a mesh loaded in a browser bakes its own clusters the same way
one loaded natively does, and an engine built without it reports false and
answers nil from `renderer.mesh.buildClusters`.

**Returns** `boolean` — True if `renderer.mesh.buildClusters` can bake on this platform.

```lua
if renderer.mesh.canBuildClusters() then ... end
```

## typed/builtin//modules/api/engine/renderer/renderer/mesh/clusterBakeBudget {#typed-builtin-modules-api-engine-renderer-renderer-mesh-clusterbakebudget}

```lua
renderer.mesh.clusterBakeBudget(ms: number?) -> number
```

The wall time one frame may spend advancing scheduled cluster bakes, in
milliseconds — set first when `ms` is given. A slice always runs at least
one unit of the build, so the budget bounds what a frame spends by choice
and the largest single unit a mesh imposes sets the floor under it.

**Parameters**

- `ms` `number` _(optional)_ — New per-frame budget in milliseconds, capped at 1000. A value that is
not a positive, finite number raises.

**Returns** `number` — The budget in force after the call.

```lua
renderer.mesh.clusterBakeBudget(2)
```

## typed/builtin//modules/api/engine/renderer/renderer/mesh/clusterBakes {#typed-builtin-modules-api-engine-renderer-renderer-mesh-clusterbakes}

```lua
renderer.mesh.clusterBakes() -> { [string]: any }
```

What the scheduled cluster bakes are costing. `budgetMs` is the slice a
frame may spend, `pending` how many bakes are queued, `completed` how many
have finished since the engine started, `dropped` how many left the queue
because the geometry they were scheduled over stopped being readable, and
`heldBytes` the source geometry the queue is holding across all of them —
the vertex pool and index run the bake at the head is reading, plus a copy
for each queued mesh the engine holds no definition for.
`inFlight` is one row per queued bake —
`{ guid, cpuMs, frames, slices, bytes, state }`: the wall time spent
advancing it, the frames it has been queued for, the slices it has been
advanced by, the geometry it is holding, and `"baking"` for the one being
advanced against `"queued"` for the ones waiting their turn.

**Returns** `{ [string]: any }` — `{ budgetMs, pending, completed, dropped, heldBytes, inFlight }`.

```lua
print(renderer.mesh.clusterBakes().heldBytes)
```

## typed/builtin//modules/api/engine/renderer/renderer/mesh/clusterComponents {#typed-builtin-modules-api-engine-renderer-renderer-mesh-clustercomponents}

```lua
renderer.mesh.clusterComponents(clusterBytes: buffer | string) -> (ClusterComponents?, string?)
```

Split a cluster blob (from `renderer.mesh.buildClusters`) into its
GPU-ready component byte pools — the cluster vertex pool, the
geometry-addressing pool (every cluster's local→global vertex map, then
every cluster's triangle bytes), and the per-cluster record array — plus
their counts. A cluster's triangles address positions inside its own vertex
map one byte at a time, and a record's `vertexOffset` indexes the geometry
pool in `u32` elements while its `indexOffset` indexes it in bytes, so ONE
binding resolves a corner. A pure decode (no GPU work): upload the pools
into buffers a compute shader owns (`shaderRef:createBuffer` +
`buf:writeBytes`) to drive a cluster draw from Luau.

**Parameters**

- `clusterBytes` `buffer | string` — Serialized cluster bytes (binary-safe).

**Returns** `(ClusterComponents?, string?)` — `{ vertices, geometry, records, vertexCount, vertexRefCount, triangleBytes, indexCount, clusterCount }`, or (nil, err).

```lua
local c = renderer.mesh.clusterComponents(cb)
```

## typed/builtin//modules/api/engine/renderer/renderer/mesh/clusters {#typed-builtin-modules-api-engine-renderer-renderer-mesh-clusters}

```lua
renderer.mesh.clusters(mesh: string | { [string]: any } | AssetRef) -> { [string]: any }?
```

The shape of the cluster-LOD hierarchy the renderer holds for a mesh:
`clusterCount` across every level, `levelCount` with the finest counted as
one, and `triangleCount` across every cluster. The renderer keys one entry
per mesh that carries a hierarchy, so this answers whether the mesh has
clusters as well as what they are — nil for a mesh that carries none.

**Parameters**

- `mesh` `string | { [string]: any } | AssetRef` — The mesh to read — a `MeshHandle`, a `MeshCpuHandle`, a guid, or a mesh `AssetRef`.

**Returns** `{ [string]: any }?` — `{ clusterCount: number, levelCount: number, triangleCount: number }?`

```lua
local c = renderer.mesh.clusters(gpu) ; if c then print(c.levelCount) end
```

## typed/builtin//modules/api/engine/renderer/renderer/mesh/create {#typed-builtin-modules-api-engine-renderer-renderer-mesh-create}

```lua
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?, uvs1?, unwrapUvs?,
tangents?, skinning?, skins?}` (a new runtime mesh — `uvs1` is the lightmap
UV set, `unwrapUvs` generates one, `skinning`/`skins` bind a skeleton); GPU
compute buffers `{vertexBuffer, indexBuffer, vertexCount, indexCount,
aabbMin?, aabbMax?, prevVertexBuffer?}` (size the vertex buffer at
`vertexCount * engine.vertexStride` bytes, the engine's standard Vertex
layout); or a `MeshHandle` (returned as-is). NEVER takes an AssetRef —
load the CPU first.

`prevVertexBuffer` is a second buffer of the same size and layout holding
those vertices as they stood on the previous frame. Naming it is what makes
geometry a compute pass moves report a motion vector: the surface
differences the two streams, so every consumer of screen-space velocity —
motion blur, temporal reprojection — sees the movement. The engine fills it
from the current vertices once per frame, ahead of that frame's compute
dispatches, so a frame in which the pass does not run leaves the two
streams equal and the geometry reports standing still.

`morphTargets` are the shapes the mesh can blend towards: a list of
`{ name?, positions, normals? }` records, each holding one offset per vertex
from the base geometry, in the mesh's own vertex order. An entity blends
them with `ecs.MorphWeights`, weight `i` scaling target `i`. A `name` makes
the shape addressable as itself — `renderer.mesh.morphTargets` reads the
names back and `renderer.mesh.morphWeights` drives them by name.

Raw geometry is read against the mesh type's conventions: `indices` count
vertices from 0, and a triangle's FRONT face is the one whose vertices turn
counter-clockwise as the viewer sees them — `cross(v1 - v0, v2 - v0)` points
out of it. A material culls its back faces by default, so a triangle wound
the other way draws nothing where it stands; reverse the index triple, or
give the material `render = { cull = "none" }`, to draw that side. `normals`
give the surface its outward direction and shade the face; the side that
draws comes from the index order alone. `uvs` sample `(0,0)` at the image's
top-left. Model space carries the world's basis: +X right, +Y up, -Z the
direction `transform.forward` points. `guides { path = "types/mesh" }` has
the whole table.
A geometry src carrying `keepCpu = true` also keeps its geometry in the
guid-keyed CPU store, so `renderer.mesh.getVertices` reads it and
`renderer.mesh.setVertices` rewrites its positions in place — the per-frame
deformation path, which sends positions alone where `renderer.mesh.update`
re-sends the whole geometry. `renderer.mesh.unloadCpu(mesh)` releases that
copy. Without it the geometry lives on the GPU alone and
`renderer.mesh.readback(mesh)` is what brings it back.

## typed/builtin//modules/api/engine/renderer/renderer/mesh/decode {#typed-builtin-modules-api-engine-renderer-renderer-mesh-decode}

```lua
renderer.mesh.decode(zmsh: buffer | string) -> (MeshGeometry?, string?)
```

Decode engine-native `ZMSH` bytes back into a `MeshGeometry`. Inverse of
`renderer.mesh.encode`; each optional stream is present only when the blob
carries it. Takes the bytes themselves — the geometry of a mesh the engine
is holding comes from `renderer.mesh.geometry(mesh)`.

**Parameters**

- `zmsh` `buffer | string` — Engine-native ZMSH bytes (binary-safe).

**Returns** `(MeshGeometry?, string?)` the geometry, or (nil, errmsg).

```lua
local geom = renderer.mesh.decode(meshRef:getBytes())
```

## typed/builtin//modules/api/engine/renderer/renderer/mesh/destroy {#typed-builtin-modules-api-engine-renderer-renderer-mesh-destroy}

```lua
renderer.mesh.destroy(mesh: string | { [string]: any } | AssetRef) -> boolean
```

Release the GPU mesh `mesh` names, the release that pairs with
`renderer.mesh.create`. Takes every form that names a mesh — the
`MeshHandle` `create` returned, the guid `renderer.mesh.list` hands out, a
`MeshCpuHandle` or a mesh `AssetRef` — and routes through
`renderer.destroy`, the verb that releases any renderer resource by its
kind. The CPU copy, if one was loaded, is freed separately by the CPU
handle's `:unload()`.

**Parameters**

- `mesh` `string | { [string]: any } | AssetRef` — The mesh to release — a `MeshHandle`, a guid, a `MeshCpuHandle` or a
mesh `AssetRef`.

**Returns** `boolean` true if a GPU mesh was known under the guid.

```lua
local m = renderer.mesh.create(cpu); renderer.mesh.destroy(m)
renderer.mesh.destroy(renderer.mesh.list()[1].guid)
```

## typed/builtin//modules/api/engine/renderer/renderer/mesh/drawInstanced {#typed-builtin-modules-api-engine-renderer-renderer-mesh-drawinstanced}

```lua
renderer.mesh.drawInstanced(mesh: string | { [string]: any } | AssetRef, opts: any?) -> InstancedDraw
```

Draw one mesh `instanceCount` times in a single call, each copy placed by
a world matrix read from a GPU buffer. The population is a renderable in its
own right — it goes through the mesh's ordinary pipeline and the material's
ordinary bind groups, so it appears in the deferred pass, the forward passes
and the shadow maps exactly as an entity-backed draw of that mesh does.

The buffer holds `instanceCount` **column-major** 4x4 matrices, 64 bytes
each, tightly packed — the layout a vertex shader reads as
`array<mat4x4<f32>>`, which puts each matrix's translation in its LAST four
floats (Lua indices 13/14/15 for x/y/z). Packing row-major transposes every
instance.

The matrices are COPIED into the engine's transform slots once per frame,
which is what buys that full-pass parity. Rewrite the buffer between frames
and the instances move — no re-registration, no re-upload.

`material` is what the population draws with, and it is required: a
`MaterialHandle` (`matRef:handle()`), an `AssetRef`, or a registry key.

`instanceDataBuffer` names a second buffer, holding 64 bytes per instance —
four `vec4` lanes, tightly packed, in instance order. Those lanes arrive in
the fragment stage as `zero_object_data(in.instance_id, lane)`, the same
read a per-entity `__instancedata` block answers, so the members of one
population can differ in whatever their material's shader agrees the lanes
carry. Copied every frame like the transforms, from a buffer a compute pass
writes: the values never touch the CPU. Omit it and the lanes read zero.

`reserveCount` sizes the reservation above `instanceCount` so
`renderer.mesh.setInstanceCount` can raise the drawn count later without
re-registering; both buffers must back the reservation, not just the count.

`mobility` states whether the copies stand still — `"static"`, or
`"movable"` when it is left out. It is what a scene gather collecting
geometry for precomputed lighting admits a population on, the same
declaration `Model.mobility` makes for an entity: the transforms live in a
buffer anything may rewrite between frames, so a population that says
nothing is taken as one that moves.

**Parameters**

- `mesh` `string | { [string]: any } | AssetRef` — The mesh the population draws — a `MeshHandle`, the guid
`renderer.mesh.list` hands out, a `MeshCpuHandle` or a mesh `AssetRef`. A
registration holds the mesh on the device for as long as it lives, and takes
a mesh that is currently held off the device — one nothing displays — back
onto it.
- `opts` `any` _(optional)_ — `{ transformBuffer, instanceCount, material, instanceDataBuffer?, reserveCount?, renderLayer?, castsShadows?, mobility? }`.

**Returns** `InstancedDraw` — An `InstancedDraw` handle for `instanceInfo` / `setInstanceCount` / `dropInstanced`.

```lua
local m = renderer.mesh.create({ positions = ..., indices = ... })
local buf = substrate.createBuffer({
name = "crowd.xf", type = "mat4", len = 64, kind = "gpu",
})
-- Column-major: translation lives at indices 13/14/15.
local xf = {}
for i = 0, 63 do
local m4 = { 1,0,0,0, 0,1,0,0, 0,0,1,0, i * 2, 0, 0, 1 }
for _, v in ipairs(m4) do xf[#xf + 1] = v end
end
buf:write(xf)
local rock = asset.resolve("rock", "material"):handle()
local draw = renderer.mesh.drawInstanced(m, { transformBuffer = "crowd.xf", instanceCount = 64, material = rock })
```

## typed/builtin//modules/api/engine/renderer/renderer/mesh/dropClusters {#typed-builtin-modules-api-engine-renderer-renderer-mesh-dropclusters}

```lua
renderer.mesh.dropClusters(mesh: string | { [string]: any } | AssetRef) -> boolean
```

Detach a mesh's cluster-LOD hierarchy and cancel a bake still in flight
for it, so the renderer holds none for it. The inverse of
`renderer.mesh.uploadClusters`.

**Parameters**

- `mesh` `string | { [string]: any } | AssetRef` — The mesh to detach — a `MeshHandle`, a `MeshCpuHandle`, a guid, or a mesh `AssetRef`.

**Returns** `boolean` — True if a hierarchy was attached or a bake was in flight.

```lua
renderer.mesh.dropClusters(gpu)
```

## typed/builtin//modules/api/engine/renderer/renderer/mesh/dropInstanced {#typed-builtin-modules-api-engine-renderer-renderer-mesh-dropinstanced}

```lua
renderer.mesh.dropInstanced(draw: InstancedDraw) -> boolean
```

Release an instanced-draw registration and the transform slots it
reserved. The mesh and the transform buffer outlive it — destroy those
through `renderer.destroy` and the buffer handle's `:destroy()`.

**Parameters**

- `draw` `InstancedDraw` — The `InstancedDraw` to release.

**Returns** `boolean` — True if a registration was live under the handle.

```lua
renderer.mesh.dropInstanced(draw)
```

## typed/builtin//modules/api/engine/renderer/renderer/mesh/encode {#typed-builtin-modules-api-engine-renderer-renderer-mesh-encode}

```lua
renderer.mesh.encode(geom: MeshGeometry) -> (string?, string?)
```

Encode raw geometry into engine-native `ZMSH` bytes (the on-disk mesh
payload). The CPU codec behind the mesh assetType's `onCreate`. Every stream
the format carries — including tangents, per-vertex skinning, and the
skeleton — round-trips back through `renderer.mesh.decode`. This pair moves
DATA the caller is holding; the geometry of a mesh the ENGINE is holding
comes from `renderer.mesh.geometry(mesh)`.

**Parameters**

- `geom` `MeshGeometry` — `MeshGeometry` — flat per-vertex float / u32 arrays plus optional `skinning` and `skins`.

**Returns** `(string?, string?)` engine-native ZMSH bytes (binary-safe), or (nil, errmsg) naming what the geometry could not describe.

```lua
local bytes = renderer.mesh.encode({ positions = {...}, indices = {...} })
local bytes = renderer.mesh.encode(renderer.mesh.geometry(meshHandle))
```

## typed/builtin//modules/api/engine/renderer/renderer/mesh/encodeCpu {#typed-builtin-modules-api-engine-renderer-renderer-mesh-encodecpu}

```lua
renderer.mesh.encodeCpu(mesh: string | { [string]: any } | AssetRef) -> string
```

Encode a mesh's resident CPU copy into `ZMSH` bytes. Reads the ONE
guid-keyed CPU store — `meshRef:load()` populates it for assets, and
`renderer.mesh.readback(mesh)` populates it for a runtime mesh. Errors
loudly when the mesh has no resident CPU copy.

**Parameters**

- `mesh` `string | { [string]: any } | AssetRef` — The mesh — a `MeshHandle`, a `MeshCpuHandle`, a guid, or a mesh `AssetRef`.

**Returns** `string` ZMSH bytes.

```lua
local bytes = renderer.mesh.encodeCpu(handle)
```

## typed/builtin//modules/api/engine/renderer/renderer/mesh/geometry {#typed-builtin-modules-api-engine-renderer-renderer-mesh-geometry}

```lua
renderer.mesh.geometry(mesh: string | { [string]: any } | AssetRef) -> MeshGeometry
```

The complete geometry of a mesh the engine is holding, as a
`MeshGeometry` — the same shape `renderer.mesh.create` and
`renderer.mesh.encode` take, carrying every stream the mesh has
(`positions`, `indices`, and whichever of `normals`, `uvs`, `colors`,
`uvs1`, `tangents`, `skinning`, `skins` it was built with). The read that
pairs with `create`: hand it the `MeshHandle` `create` returned and get the
vertex data back. Reads the resident CPU copy when there is one; for a
runtime mesh that lives only on the GPU it reads the geometry back off the
GPU first (yielding a frame or two) and leaves CPU residency as it found it.
An optional stream is present only when the mesh carries one, so `uvs1 ==
nil` is the answer to whether it has a second UV set. The drawable mesh
the renderer holds carries the tangent basis its positions, uvs and normals
determine — supplied by the caller, or derived at the ingest that made it
drawable — and that is what the GPU read gives back. The CPU store answers
with the streams the bytes it decoded hold, so a `.mesh` written without a
tangent stream reads back `tangents == nil` for as long as a CPU copy of it
is resident.

**Parameters**

- `mesh` `string | { [string]: any } | AssetRef` — The mesh — a `MeshHandle`, a `MeshCpuHandle`, a guid, or a mesh `AssetRef`.

**Returns** `MeshGeometry`

```lua
local geom = renderer.mesh.geometry(renderer.mesh.create({ positions = P, indices = I }))
local tangents = renderer.mesh.geometry(handle).tangents
```

## typed/builtin//modules/api/engine/renderer/renderer/mesh/getVertices {#typed-builtin-modules-api-engine-renderer-renderer-mesh-getvertices}

```lua
renderer.mesh.getVertices(mesh: string | { [string]: any } | AssetRef) -> { any }
```

Read the vertices of a mesh's resident CPU copy — 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 the mesh has no resident CPU copy
— `renderer.mesh.geometry(mesh)` is the read that works wherever the mesh
lives, and returns the tangent, colour and skinning streams too.

**Parameters**

- `mesh` `string | { [string]: any } | AssetRef` — The mesh — a `MeshHandle`, a `MeshCpuHandle`, a guid, or a mesh `AssetRef`.

**Returns** `{ any }` — `{ { pos: {x,y,z}, normal: {x,y,z}, uv: {u,v} }, ... }` Each record carries `pos`, `normal`, `uv` and `uv1` as named channels (`{ x = , y = , z = }`). Geometry going the other way — into `renderer.mesh.create` — is parallel flat arrays (`positions`, `normals`, `uvs`), and `create` accepts this record list under `vertices` so a mesh read back here can go straight into a new one.

## typed/builtin//modules/api/engine/renderer/renderer/mesh/instanceInfo {#typed-builtin-modules-api-engine-renderer-renderer-mesh-instanceinfo}

```lua
renderer.mesh.instanceInfo(draw: InstancedDraw) -> InstancedDrawInfo?
```

What a live instanced-draw registration is drawing: which mesh, which
transform buffer, which per-instance data buffer if it named one, how many
instances, and how many slots it reserved. Returns nil once the
registration has been dropped.

`status` is what the renderer did with it. The fields above it are the
request, made a stage before the renderer sees it; `status` is the answer:
`"drawing"` for a registration the renderer is drawing, `"refused"` for one
it turned away — `error` carries its reason — and `"pending"` for the frame
between the call and the renderer answering. So a registration whose copies
are not being drawn says so here.

**Parameters**

- `draw` `InstancedDraw` — The `InstancedDraw` to report on.

**Returns** `InstancedDrawInfo?` — The registration record, or nil.

```lua
print(renderer.mesh.instanceInfo(draw).instanceCount)
local info = renderer.mesh.instanceInfo(draw)
if info.status == "refused" then error(info.error) end
```

## typed/builtin//modules/api/engine/renderer/renderer/mesh/instanceTransforms {#typed-builtin-modules-api-engine-renderer-renderer-mesh-instancetransforms}

```lua
renderer.mesh.instanceTransforms(draw: InstancedDraw) -> any
```

Read back the world matrices a registration's drawn copies are placed
by: `instanceCount` matrices of 16 floats, column-major and tightly
packed, in the layout the transform buffer holds them. The read is of the
buffer as it stands when it runs, so a population a compute pass rewrites
every frame answers with the placement of the frame the read lands in.

**Parameters**

- `draw` `InstancedDraw` — The `InstancedDraw` whose copies to locate.

**Returns** `any` — A `Readback` to poll — `:ready()` then `:result()` — or nil for a registration that is no longer live.

```lua
local pending = renderer.mesh.instanceTransforms(draw)
while not pending:ready() do task.wait() end
local floats = pending:result()
```

## typed/builtin//modules/api/engine/renderer/renderer/mesh/isCpuResident {#typed-builtin-modules-api-engine-renderer-renderer-mesh-iscpuresident}

```lua
renderer.mesh.isCpuResident(mesh: string | { [string]: any } | AssetRef) -> boolean
```

True if this mesh has a resident CPU copy in the guid-keyed CPU store.

**Parameters**

- `mesh` `string | { [string]: any } | AssetRef` — The mesh — a `MeshHandle`, a `MeshCpuHandle`, a guid, or a mesh `AssetRef`.

**Returns** `boolean`

```lua
if renderer.mesh.isCpuResident(handle) then ... end
```

## typed/builtin//modules/api/engine/renderer/renderer/mesh/isResident {#typed-builtin-modules-api-engine-renderer-renderer-mesh-isresident}

```lua
renderer.mesh.isResident(mesh: string | { [string]: any } | AssetRef) -> boolean
```

True if a GPU mesh is resident under this mesh's guid — the device
holds its buffers, or the upload pass is still going to hand them over.
This is the store the draw paths are gated on, so a mesh this reports
resident is one `renderer.mesh.drawInstanced` and a `Model` can draw.

**Parameters**

- `mesh` `string | { [string]: any } | AssetRef` — The mesh — a `MeshHandle`, a `MeshCpuHandle`, a guid, or a mesh `AssetRef`.

**Returns** `boolean`

```lua
print(renderer.mesh.isResident(handle))
```

## typed/builtin//modules/api/engine/renderer/renderer/mesh/list {#typed-builtin-modules-api-engine-renderer-renderer-mesh-list}

```lua
renderer.mesh.list() -> { any }
```

Every mesh currently registered, ordered by guid — the ones a script
created and the ones that reached the device through an asset alike.
Answers "which mesh is this?" when all that is known is a size: each entry
carries the guid, the vertex/index counts it was created with, where it came
from (`origin` is `"asset"` for a mesh the asset path uploaded), whether the
GPU still holds it, and where its culling bounds come from (`boundsFrom` is
`"compute"` for a mesh a compute pass writes). A resident entry also carries
the bytes its buffers cost. `bytes` is the mesh's whole VRAM footprint and
is the sum of the THREE buffer columns beside it — `vertexBytes +
vertexStorageBytes + indexBytes`, where the storage column is the same
vertices bound as a storage buffer for the passes that read them that way.
Summing only the vertex and index columns understates a mesh by its vertex
size. The `bytes` column is what sums to the `meshes` category of
`renderer.gpuMemory()`.
`renderer.references("mesh", guid)` says what is still holding a row, and
`renderer.collect()` releases the rows nothing holds.

## typed/builtin//modules/api/engine/renderer/renderer/mesh/listInstanced {#typed-builtin-modules-api-engine-renderer-renderer-mesh-listinstanced}

```lua
renderer.mesh.listInstanced() -> { InstancedDrawInfo }
```

Every instanced-draw registration this engine is drawing, in
registration order. Each record is what `instanceInfo` answers with, and
carries a `draw` handle of its own — so a population whose handle its
caller no longer holds is reached here and released, resized or read like
any other.

**Returns** `{ InstancedDrawInfo }` — An array of registration records; empty when nothing is registered.

```lua
for _, pop in ipairs(renderer.mesh.listInstanced()) do
renderer.mesh.dropInstanced(pop.draw)
end
```

## typed/builtin//modules/api/engine/renderer/renderer/mesh/loadCpu {#typed-builtin-modules-api-engine-renderer-renderer-mesh-loadcpu}

```lua
renderer.mesh.loadCpu(ref: string | AssetRef) -> 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.

**Parameters**

- `ref` `string | AssetRef` — A mesh `AssetRef` (carries `.guid` and reads its primary via getBytes),
or any string `asset.ref` resolves to one — the guid `encodeCpu` takes, an
identity, a name or a source path.

**Returns** `MeshCpuHandle`

```lua
local cpu = meshRef:load(); local gpu = renderer.mesh.create(cpu); cpu:unload()
local cpu = renderer.mesh.loadCpu(gpuMesh.guid)
```

## typed/builtin//modules/api/engine/renderer/renderer/mesh/morphTargets {#typed-builtin-modules-api-engine-renderer-renderer-mesh-morphtargets}

```lua
renderer.mesh.morphTargets(mesh: string | { [string]: any } | AssetRef) -> { string }
```

The names of the shapes this mesh blends towards, in the order an
entity's `ecs.MorphWeights` addresses them — weight `i` drives the target
named at `i`. An imported model carries the names its source file gave its
blend shapes, so content drives a face by the shape it means rather than by
the ordinal that shape happened to import at (which moves when the model is
re-exported). A target the source never named reads as an empty string.

Empty for a mesh with no morph targets. Errors when the mesh is neither
GPU- nor CPU-resident — materialise it first (`meshRef:handle()`).

**Parameters**

- `mesh` `string | { [string]: any } | AssetRef` — The mesh — a `MeshHandle`, a `MeshCpuHandle`, a guid, or a mesh `AssetRef`.

**Returns** `{ string }` one name per morph target, in target order.

```lua
for i, name in renderer.mesh.morphTargets(meshRef) do print(i, name) end
```

## typed/builtin//modules/api/engine/renderer/renderer/mesh/morphWeights {#typed-builtin-modules-api-engine-renderer-renderer-mesh-morphweights}

```lua
renderer.mesh.morphWeights(mesh: string | { [string]: any } | AssetRef, weights: { [string]: number }) -> { number }
```

Turn weights named by shape into the ordered weight array
`ecs.MorphWeights` takes — the drive-a-face-by-name call. Every target the
mesh carries gets a slot; the ones `weights` names take their value and the
rest are 0, so the returned array always describes the whole mesh and a
shape left out is a shape at rest.

A name the mesh does not carry is an error listing the names it does: a
mistyped viseme that silently moved nothing would be indistinguishable from
a rig that never had it.

**Parameters**

- `mesh` `string | { [string]: any } | AssetRef` — The mesh — a `MeshHandle`, a `MeshCpuHandle`, a guid, or a mesh `AssetRef`.
- `weights` `{ [string]: number }` — `{ [string]: number }` — how strongly to blend each named shape.

**Returns** `{ number }` one weight per morph target, in target order.

```lua
local w = renderer.mesh.morphWeights(meshRef, { Eyes_Blink = 1, Mouth_Smile = 0.4 })
ecs.set(face, ecs.MorphWeights { weights = w })
```

## typed/builtin//modules/api/engine/renderer/renderer/mesh/readback {#typed-builtin-modules-api-engine-renderer-renderer-mesh-readback}

```lua
renderer.mesh.readback(mesh: string | { [string]: any } | AssetRef) -> 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`, `:geometry`, `:encode`, `:unload` all work. Errors if the mesh
never becomes resident in the vertex pool.

**Parameters**

- `mesh` `string | { [string]: any } | AssetRef` — The mesh — the `MeshHandle` `renderer.mesh.create` returned, a guid, or a mesh `AssetRef`.

**Returns** `MeshCpuHandle`

```lua
local cpu = renderer.mesh.readback(handle); local zmsh = cpu:encode(); cpu:unload()
```

## typed/builtin//modules/api/engine/renderer/renderer/mesh/readbackPosed {#typed-builtin-modules-api-engine-renderer-renderer-mesh-readbackposed}

```lua
renderer.mesh.readbackPosed(requests: { { entity: string, mesh: any } }) -> { [string]: MeshCpuHandle }
```

Read the POSED geometry of skinned entities back to CPU: for each
request, the vertices the skinning pass wrote for that entity this frame,
joined by the indices of the mesh it is posed from. A skinned surface's
world-space triangles are produced on the GPU from the entity's joint
matrices, so the mesh asset holds the bind pose and only this reads where
the surface actually is. The posed vertices are in model space, so the
entity's own world transform still places them — the same transform the
raster draw uses.

Takes a LIST and answers a map, because the readbacks are queued together
and polled together: a scene's worth of characters costs the frames of one
readback rather than one entity's after another. Each posed mesh lands in
the CPU store under a guid of its own, derived from the entity, so
`compute.buildBvh`, `meshcpu.*` and every other guid-keyed reader takes it
like any other mesh. Call `handle:unload()` when done with it.

An entity the map omits holds no live pose — nothing skinned it this frame,
which is also what makes its draws read the source mesh, so its bind-pose
geometry is what stands for it.

**Parameters**

- `requests` `{ { entity: string, mesh: any } }` — `{ { entity = <id>, mesh = <mesh> } }` — the entity to read, and the mesh it is posed from (a guid, `MeshHandle` or mesh `AssetRef`).

**Returns** `{ [string]: MeshCpuHandle }` — A map from entity id to the `MeshCpuHandle` holding that entity's posed geometry.

```lua
local posed = renderer.mesh.readbackPosed({ { entity = id, mesh = ecs.get(id, ecs.Mesh).mesh } })
local tris = posed[id]:getTriangles()
```

## typed/builtin//modules/api/engine/renderer/renderer/mesh/scheduleClusters {#typed-builtin-modules-api-engine-renderer-renderer-mesh-scheduleclusters}

```lua
renderer.mesh.scheduleClusters(mesh: string | { [string]: any } | AssetRef) -> boolean
```

Queue a cluster-LOD bake for the static CPU mesh held under `guid`, and
attach the DAG to the GPU mesh of that same guid on the frame it finishes.
The CPU mesh may be unloaded on the very next line; the DAG is then built
one bounded slice per frame, so a dense mesh virtualizes without the frame
loop stopping for the whole bake.

One bake is advanced per frame — the one at the head of the queue — and the
geometry is read on the frame a bake gets there, from the definition the
engine holds for the mesh. A queue of meshes the engine holds definitions
for therefore holds one mesh's geometry rather than one per mesh, whatever
its depth. A mesh the engine holds no definition for is copied into the
queue as it is scheduled, since the CPU store is then the only thing
holding it. `renderer.mesh.clusterBakes().heldBytes` reports what the queue
is holding, and its `inFlight` rows report which bakes it is holding for.
This is what the `.mesh` assetType materialisation path uses; reach for
`renderer.mesh.buildClusters` when you want the bytes in hand instead.
Scheduling the same mesh again replaces the bake already in flight for it.

**Parameters**

- `mesh` `string | { [string]: any } | AssetRef` — A mesh loaded into the CPU store (`renderer.mesh.loadCpu`) — the
`MeshCpuHandle`, a `MeshHandle`, a guid, or a mesh `AssetRef`.

**Returns** `boolean` — True if a bake was queued.

```lua
renderer.mesh.scheduleClusters(cpu) ; cpu:unload()
```

## typed/builtin//modules/api/engine/renderer/renderer/mesh/setInstanceCount {#typed-builtin-modules-api-engine-renderer-renderer-mesh-setinstancecount}

```lua
renderer.mesh.setInstanceCount(draw: InstancedDraw, count: number) -> InstancedDraw
```

Change how many of a registration's instances draw. Constant time — the
reservation, the transform buffer and the pipeline all stay put, so this is
the verb for a population whose size changes per frame. The new count must
fit the reservation `drawInstanced` was given.

**Parameters**

- `draw` `InstancedDraw` — The `InstancedDraw` to reconfigure.
- `count` `number` — Instances to draw, at least 1 and within the reservation.

**Returns** `InstancedDraw` — The same `InstancedDraw`.

```lua
renderer.mesh.setInstanceCount(draw, visibleCount)
```

## typed/builtin//modules/api/engine/renderer/renderer/mesh/setInstanceRenderLayer {#typed-builtin-modules-api-engine-renderer-renderer-mesh-setinstancerenderlayer}

```lua
renderer.mesh.setInstanceRenderLayer(draw: InstancedDraw, renderLayer: number) -> InstancedDraw
```

Change which render layers a registration's copies belong to. Constant
time — the reservation, the transform buffer and the pipeline all stay put,
and the next frame drawn tests the copies against the new membership. It is
the verb for a population that follows something whose membership moves: a
camera or a capture including the layer draws the copies, one excluding it
does not.

**Parameters**

- `draw` `InstancedDraw` — The `InstancedDraw` to reconfigure.
- `renderLayer` `number` — The membership bitmask, the same value `drawInstanced` takes
as `renderLayer`. At least one bit must be set.

**Returns** `InstancedDraw` — The same `InstancedDraw`.

```lua
renderer.mesh.setInstanceRenderLayer(draw, mask)
```

## typed/builtin//modules/api/engine/renderer/renderer/mesh/setVertices {#typed-builtin-modules-api-engine-renderer-renderer-mesh-setvertices}

```lua
renderer.mesh.setVertices(mesh: string | { [string]: any } | AssetRef, positions: { number })
```

Replace a mesh's resident CPU vertex positions (flat `{ x,y,z, ... }`)
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 positions alone travel, so this is the per-frame deformation path where
`renderer.mesh.update` re-sends the whole geometry. The mesh must be
CPU-resident: `renderer.mesh.create({ ..., keepCpu = true })` keeps a copy
from the start, `renderer.mesh.readback(mesh)` recovers one from the GPU,
and `meshRef:load()` loads one for a `.mesh` asset. Errors with the reason
otherwise, or when the vertex count doesn't match.

**Parameters**

- `mesh` `string | { [string]: any } | AssetRef` — The mesh — a `MeshHandle`, a `MeshCpuHandle`, a guid, or a mesh `AssetRef`.
- `positions` `{ number }` — Flat `{ x,y,z, ... }` — one xyz per vertex; count must match the mesh.

```lua
local m = renderer.mesh.create({ positions = P, indices = I, keepCpu = true })
renderer.mesh.setVertices(m, P) -- P mutated in place each frame
```

## typed/builtin//modules/api/engine/renderer/renderer/mesh/unloadCpu {#typed-builtin-modules-api-engine-renderer-renderer-mesh-unloadcpu}

```lua
renderer.mesh.unloadCpu(mesh: string | { [string]: any } | AssetRef)
```

Drop a mesh's resident CPU copy from the guid-keyed CPU store.
The explicit release for a runtime geometry mesh's recoverable definition.

**Parameters**

- `mesh` `string | { [string]: any } | AssetRef` — The mesh — a `MeshHandle`, a `MeshCpuHandle`, a guid, or a mesh `AssetRef`.

## typed/builtin//modules/api/engine/renderer/renderer/mesh/update {#typed-builtin-modules-api-engine-renderer-renderer-mesh-update}

```lua
renderer.mesh.update(mesh: string | { [string]: any } | AssetRef, src: any?) -> MeshHandle
```

Overwrite the GPU resource `mesh` names 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 the guid reflects the change with no
re-bind. Takes every form that names a mesh — the `MeshHandle` `create`
returned, the guid `renderer.mesh.list` hands out, a `MeshCpuHandle` or a
mesh `AssetRef`. Returns a handle carrying the bounds the new geometry has:
the handle it was given, refreshed, and a handle over the guid otherwise.

**Parameters**

- `mesh` `string | { [string]: any } | AssetRef` — The mesh to update — a `MeshHandle`, a guid, a `MeshCpuHandle` or a
mesh `AssetRef`.
- `src` `any` _(optional)_ — New geometry `{positions, indices, ...}` or compute buffers
`{vertexBuffer, indexBuffer, vertexCount, indexCount, prevVertexBuffer?}`.

**Returns** `MeshHandle` — A `MeshHandle` for the updated mesh.

## typed/builtin//modules/api/engine/renderer/renderer/mesh/uploadClusters {#typed-builtin-modules-api-engine-renderer-renderer-mesh-uploadclusters}

```lua
renderer.mesh.uploadClusters(mesh: string | { [string]: any } | AssetRef, 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.

**Parameters**

- `mesh` `string | { [string]: any } | AssetRef` — The mesh the clusters belong to — a `MeshHandle`, a `MeshCpuHandle`, a guid, or a mesh `AssetRef`.
- `clusters` `string` — Serialized cluster bytes (binary-safe).

**Returns** `boolean` — True if the upload was queued.

```lua
renderer.mesh.uploadClusters(gpu, cb)
```

## typed/builtin//modules/api/engine/renderer/renderer/minScreenSize {#typed-builtin-modules-api-engine-renderer-renderer-minscreensize}

```lua
renderer.minScreenSize() -> number
```

The on-screen radius, in pixels, an object must reach to be drawn. `0`
while the cutoff is off.

**Returns** `number`

```lua
local px = renderer.minScreenSize()
```

## typed/builtin//modules/api/engine/renderer/renderer/morphStats {#typed-builtin-modules-api-engine-renderer-renderer-morphstats}

```lua
renderer.morphStats() -> {
```

The morph state the last frame drew with. A mesh carries the shapes it
can blend towards and an entity carries how strongly each is blended
(`ecs.MorphWeights`); where both are present, the vertex stage adds the
weighted deltas to the base geometry.

`instances` is how many render slots that happened at, and `blends` how
many single-target blends those slots carry between them: a slot
contributes one per target its weights move, or that they moved the frame
before, so the number of targets a mesh can be given is bounded by the
buffer the blends live in. `meshes` is how
many meshes hold a delta block and `targets` how many targets those blocks
cover between them; `deltaBytes` is what the shared buffer they are
appended into holds. A morph-target mesh whose weights are all zero reads a
`meshes` above zero beside an `instances` and `blends` of zero.

**Returns** `{ instances: number, blends: number, meshes: number, targets: number, deltaBytes: number }`

```lua
local m = renderer.morphStats()
print(("%d instances carrying %d blends over %d meshes"):format(m.instances, m.blends, m.meshes))
```

## typed/builtin//modules/api/engine/renderer/renderer/observe {#typed-builtin-modules-api-engine-renderer-renderer-observe}

```lua
renderer.observe() -> RenderObservation
```

Everything the renderer knows about the frame it last drew: what
program it bound for each renderable, the render state it holds each
material under, and what each program has cost in pipeline builds.
`renderables` is one row per renderable in the renderer's draw list,
carrying the program its material named (`requestedProgram`) beside the one
that was bound (`boundProgram`) — `__error__` wherever the lookup missed
and the draw went ahead on the magenta placeholder — plus `substituted`,
the `outcome` (`drew` / `drewPlaceholder` / `skipped` / `notDrawn`), the
`reason` that forced it and the compiler's own `detail` for a failed
compile. `observed` says which of two answers a row is: `true` for a
resolution a geometry pass took as it drew, `false` for the renderer's own
resolution of a renderable this frame drew nowhere, which is what a
renderable outside every camera's frustum or layer mask reports.
`materials` is one row per
material the renderer holds a prepared bind group for; `shaders` is one row
per program pipelines have been built for. `frame` names the frame every
per-frame count covers; `retainedFrames` how many frames a resolution a
pass took is kept for after the last frame that drew it; `window` and
`costWindow` state both in the document itself. Recording is armed by the
first read, so this waits for the frame that first records rather than
answering empty.

**Returns** `RenderObservation`

```lua
local o = renderer.observe(); print(o.placeholderDraws, "renderables drew the placeholder in frame", o.frame)
```

## typed/builtin//modules/api/engine/renderer/renderer/occlusionCulling {#typed-builtin-modules-api-engine-renderer-renderer-occlusionculling}

```lua
renderer.occlusionCulling() -> boolean
```

Whether occlusion culling is currently enabled.

**Returns** `boolean`

## typed/builtin//modules/api/engine/renderer/renderer/passSchedule {#typed-builtin-modules-api-engine-renderer-renderer-passschedule}

```lua
renderer.passSchedule() -> {
```

The schedule check over this frame's enqueued render passes. Passes
declare what they read (`inputs`) and what they write (`output` /
`outputs` / `storage`), and the frame runs them in phase order and, inside
a phase, in `order` order. `violations` holds every input bound to a
resource the frame produces LATER: that read samples the resource as it
stands ahead of that pass, which is the previous frame's contents for a
render target that persists, an empty target for one just created, and the
scene draw's own output for a `@scene.*` buffer — and the pass renders
either way. The frame's own buffers are checked on the same terms as a
render target: bind `@scene.motion` at a phase ahead of the pass that
writes it and the read is reported, naming the buffer and its writer.
A pass reading a resource ahead of that write on purpose declares that slot
in its enqueue's `readsPrevious` and drops out of the list;
`unboundPrevious` holds declared slots the pass binds no such resource to,
which cover nothing.
A resource no queued pass writes is not reported — a camera rendering to
texture and `compute.dispatch` both fill targets outside the pass queue,
and the scene draw fills the `@scene.*` buffers every frame.
A read the frame has only one order for is not reported either: where the
writing pass consumes something the reading pass produces, the reader runs
first or the writer has nothing to write, which is what a pass reading a
buffer into a target of its own and a second pass copying that target back
over the buffer forms.
`unreachable` holds passes at a phase that does not run their kind: every
phase drains its fragment and compute passes, while `afterLighting` is the
one that draws geometry, draw and splat passes, so one of those enqueued
elsewhere sits in the queue and never runs.
Each finding is also stated in the engine log the first time it appears.

**Returns** `{ violations, unboundPrevious, unreachable }`

```lua
local s = renderer.passSchedule()
for _, v in s.violations do print(v.message) end
```

## typed/builtin//modules/api/engine/renderer/renderer/pipelineCache {#typed-builtin-modules-api-engine-renderer-renderer-pipelinecache}

```lua
renderer.pipelineCache() -> PipelineCache?
```

What the driver's compiled-pipeline store held, built, and wrote back.
A pipeline is machine code the GPU driver compiles from the shader bound
into it, and that compile is what a launch pays before the first frame
drawing with each pipeline can appear. The store keeps that compiled code
across runs, so a launch whose shaders have not changed reads back what the
previous one compiled.

`restoredBytes` is what a previous run left for this GPU and this launch
read; `pipelinesBuilt` counts the pipelines built since startup and
`buildMs` is what they cost together, which is the number the store lowers.
`saves` and `savedBytes` describe writing it back — deferred until a burst
of builds settles, so one launch is one write — and `dirty` is true while
pipelines have been built that the file does not hold, including after a
write that failed, which `lastError` then names. `path` is the file, named
after the GPU it belongs to.

`supported` is false where the platform holds no store a program can carry:
a browser keeps its own and hands none out, and an adapter can lack the
capability. `reason` says which, and the build count and timing still read
true there. `lastError` names a read or write failure; a failed store costs
the saved compile and never the frame, since every pipeline is built from
its source either way.
`pipelinesBuilt` and `buildMs` are engine-wide totals; `renderer.shaderCost()`
is the same cost broken down per program, with each one's permutation count.

**Returns** `PipelineCache?` — `{ supported, reason, path, restoredBytes, pipelinesBuilt, buildMs, saves, savedBytes, dirty, lastError }`, or nil before the renderer has drawn a frame

```lua
local c = renderer.pipelineCache()
print(("%d pipelines in %.1f ms, %d bytes restored"):format(c.pipelinesBuilt, c.buildMs, c.restoredBytes))
```

## typed/builtin//modules/api/engine/renderer/renderer/pointShadowBudget {#typed-builtin-modules-api-engine-renderer-renderer-pointshadowbudget}

```lua
renderer.pointShadowBudget() -> PointShadowBudget
```

The point-light shadow pool now in force. A point light with
`castsShadows` renders an omnidirectional cube map, six faces of depth,
and `slots` is how many of them fit — a further caster is lit but throws
no shadow, and the engine log names how many were turned away. The slot
count is bought rather than authored: `megabytes` of VRAM at `resolution`
texels per face is what decides it.

**Returns** `PointShadowBudget` — The pool — see `PointShadowBudget`.

```lua
local p = renderer.pointShadowBudget()
print(("%d shadowed point lights, %.1f MiB"):format(p.slots, p.bytes / 1024 / 1024))
```

## typed/builtin//modules/api/engine/renderer/renderer/projectionOffset {#typed-builtin-modules-api-engine-renderer-renderer-projectionoffset}

```lua
renderer.projectionOffset() -> (number, number)
```

The sub-pixel projection offset in force for the main camera, in NDC.

**Returns** `(number, number)` — The x and y offset, both 0 when the projection samples pixel centres.

```lua
local ox, oy = renderer.projectionOffset()
```

## typed/builtin//modules/api/engine/renderer/renderer/raycast {#typed-builtin-modules-api-engine-renderer-renderer-raycast}

```lua
renderer.raycast(origin: vec3, direction: vec3, maxDistance: number?, exclude: (string | { string })?) -> RenderRayHit?
```

Cast a ray against the geometry the renderer DRAWS and return the
nearest surface it meets. Every visible mesh answers, whether or not
anything gave it a rigid body — so a terrain, a procedurally generated
mesh, or any plain `Model` reports the surface at a point, which is what a
camera station, a prop, a sound source or a scatter standing on the ground
needs to know. The answer is the nearest triangle of the mesh, so a sloped
or terraced surface reports its height where it was asked rather than the
extent of its bounding box.

`distance` is measured from `origin` along the direction given, so it is a
world-space distance whenever that direction is a unit vector, and it is
directly comparable to a `physics.raycast` distance along the same ray.
`normal` is a unit vector turned to face back along the ray. `exact` is
true when the answer is a triangle and false when it is the object's
bounding box, which is what a mesh whose vertices live only in GPU buffers
answers with. The triangles are the mesh's own, placed by the entity's
transform and by the mesh's bind pose, so a surface a skinning or morph
pass deforms on the GPU answers as the geometry the mesh holds.

EVERYTHING drawn is in scope — the ground you meant, and equally a
character standing on it, a prop, a placeholder floor. The hit names its
entity in `entityId`, `exclude` steps over the ones you do not want, and
`renderer.raycastAll` hands back the whole column so you can pick the
surface yourself. A height you did not expect is usually a nearer surface
you did not mean to ask about, so read `entityId` before trusting a number.

**Parameters**

- `origin` `vec3` — `vec3` ray start in world space
- `direction` `vec3` — `vec3` ray direction; any length, the engine normalises
- `maxDistance` `number` _(optional)_ — `number?` how far the ray reaches, in world units. Default 1000
- `exclude` `(string | { string })` _(optional)_ — `(string | { string })?` entity id, or ids, to step over

**Returns** `RenderRayHit?`

```lua
local hit = renderer.raycast({ x, 100, z }, { 0, -1, 0 }, 200)
if hit then camera.position = { x, hit.point.y + 1.7, z } end
```

## typed/builtin//modules/api/engine/renderer/renderer/raycastAll {#typed-builtin-modules-api-engine-renderer-renderer-raycastall}

```lua
renderer.raycastAll(origin: vec3, direction: vec3, maxDistance: number?, maxHits: number?, exclude: (string | { string })?) -> { RenderRayHit }
```

Cast a ray against the geometry the renderer draws and return every
surface along it, nearest first. One entry per renderable the ray crosses —
the nearest intersection with each — so a stack of surfaces reads as the
order they stand in, and a caller after one particular surface finds it by
`entityId` rather than hoping it is the nearest. Each entry carries the
fields `renderer.raycast` returns.

**Parameters**

- `origin` `vec3` — `vec3` ray start in world space
- `direction` `vec3` — `vec3` ray direction; any length, the engine normalises
- `maxDistance` `number` _(optional)_ — `number?` how far the ray reaches, in world units. Default 1000
- `maxHits` `number` _(optional)_ — `number?` how many surfaces to return. Default 32
- `exclude` `(string | { string })` _(optional)_ — `(string | { string })?` entity id, or ids, to step over

**Returns** `{ RenderRayHit }`

```lua
for _, hit in renderer.raycastAll(eye, look, 500) do print(hit.entityId, hit.distance) end
```

## typed/builtin//modules/api/engine/renderer/renderer/raytraceCapability {#typed-builtin-modules-api-engine-renderer-renderer-raytracecapability}

```lua
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.

**Returns** `string` "hardware" | "compute"

```lua
if renderer.raytraceCapability() == "hardware" then ... end
```

## typed/builtin//modules/api/engine/renderer/renderer/raytraceStats {#typed-builtin-modules-api-engine-renderer-renderer-raytracestats}

```lua
renderer.raytraceStats() -> { [string]: any }
```

What the ray-tracing acceleration structure holds, and what this
session's frames have spent building it. A ray walks a structure built over
the scene's geometry, and keeping it current is work a frame pays before it
traces anything. On the `"compute"` backend geometry that has stood still
long enough is filed under a static partition the frames after it leave
alone: `staticTriangles` + `dynamicTriangles` = `triangles`, `nodes` is the
hierarchy over them, `fullRebuilds` / `partialRebuilds` / `reusedFrames`
count what the session's frames did, and `trianglesRebuilt` is what those
rebuilds re-emitted, summed. On the `"hardware"` backend `blas` is the
bottom-level structures cached, `blasBuilt` how many the last frame built,
and `tlasInstances` what the top-level structure names. The counters are
cumulative — sample, run the scene, sample again.

**Returns** `{ [string]: any }` — `table` {backend, triangles, staticTriangles, dynamicTriangles, nodes, fullRebuilds, partialRebuilds, reusedFrames, trianglesRebuilt, blas, blasBuilt, tlasInstances}

```lua
local before = renderer.raytraceStats().trianglesRebuilt
```

## typed/builtin//modules/api/engine/renderer/renderer/references {#typed-builtin-modules-api-engine-renderer-renderer-references}

```lua
renderer.references(handleOrKind: any?, id: string?) -> RuntimeResourceStatus?
```

What holds a runtime resource right now — the answer a root scene load
reads before releasing it. `references` names each live consumer the engine
found: `{ by = "entity", id }` for an entity wearing the material or mesh,
`"material"` for a material whose slot names the texture, `"instancedDraw"`,
`"camera"`, `"sky"`, `"lightmap"`, `"ui"` (a screen drawing it) and
`"postProcess"` (an effect sampling it). `handleHeld` says whether a script
still reaches a handle to it, `assetBacked` whether an asset stands behind
it, `ownerLive` whether the component instance, scene load or feature that
created it still stands, and `held` whether a hold pins it. `origin` reads
`"device"` for a GPU texture the device holds that no script created — the
one the cache loaded for an asset, the atlas the engine built — whose
holders are the references, a handle and the asset. Runs a full garbage
collection first, the same one `renderer.collect` runs, so a handle nothing
reaches counts as let go and the row says what the next collection does
with the resource. Yields for the frame the census runs on.

**Parameters**

- `handleOrKind` `any` _(optional)_ — The resource's handle, or its kind with the id second.
- `id` `string` _(optional)_ — The guid or key, when the first argument is a kind.

**Returns** `RuntimeResourceStatus?` — The resource's status, or nil for a key the registry does not record and the device holds no texture under.

```lua
local s = renderer.references(mat) for _, r in s.references do print(r.by, r.id) end
```

## typed/builtin//modules/api/engine/renderer/renderer/reflectionEnvironment {#typed-builtin-modules-api-engine-renderer-renderer-reflectionenvironment}

```lua
renderer.reflectionEnvironment() -> {
```

What a reflective surface is reflecting. `probes` is how many reflection
probes the shading blends; they are gathered highest `priority` first, each
rank taking the coverage the ranks above it left, so a small interior probe
ranked above the large exterior one it sits inside wins outright wherever it
reaches full weight. `ranks` is the priority each of those probe slots was
published with, in slot order. `sky` is whether the sky fallback is armed:
with it, coverage no probe claims reflects the captured sky, and without it
a surface outside every probe's radius falls back to the nearest probe
alone. `skyCaptured` is whether the sky slot holds a capture — arming is
refused until it does, since an uncaptured slot reflects black.
`slots` is how many cube slots the environment array holds right now: the
sky's alone, at index `skySlot`, until a probe is captured into it, then
that one plus one per probe. `maxProbes` is how many of them probes may
take, and `resident` whether the array has grown past the sky's single
slot. Capture the sky with `environment.captureSky()`.

**Returns** `{ probes, ranks, sky, skyCaptured, resident, slots, skySlot, maxProbes }`

```lua
local env = renderer.reflectionEnvironment()
print(("%d probes, sky fallback %s"):format(env.probes, tostring(env.sky)))
```

## typed/builtin//modules/api/engine/renderer/renderer/release {#typed-builtin-modules-api-engine-renderer-renderer-release}

```lua
renderer.release(handleOrKind: any?, id: string?) -> boolean
```

Let go of the hold `renderer.hold` placed. The resource stays until
nothing else holds it and a collection releases it — the one a root scene
load runs, or a direct `renderer.collect()`.

**Parameters**

- `handleOrKind` `any` _(optional)_ — The resource's handle, or its kind with the id second.
- `id` `string` _(optional)_ — The guid or key, when the first argument is a kind.

**Returns** `boolean` true when the registry knows the resource.

```lua
renderer.release(tex)
```

## typed/builtin//modules/api/engine/renderer/renderer/renderTargetLimits {#typed-builtin-modules-api-engine-renderer-renderer-rendertargetlimits}

```lua
renderer.renderTargetLimits() -> {
```

The size a render target may be on this device. `maxDimension` is the
device's own maximum 2D texture dimension — the largest either side of a
render target may take. `maxPixels` is how many pixels one render target
may hold, so the RGBA8 image it reads back as fits in a single buffer on
every platform the engine runs on, and `maxSquare` is the largest square
that budget buys. A capture, a `renderer.texture.create({ width, height })`
or a render-to-texture camera past either bound is refused at the call with
the reason, so ask here for the size to request.

**Returns** `{ maxDimension, maxPixels, maxSquare }`

```lua
local lim = renderer.renderTargetLimits()
local w = math.min(want, lim.maxSquare)
```

## typed/builtin//modules/api/engine/renderer/renderer/renderTargets {#typed-builtin-modules-api-engine-renderer-renderer-rendertargets}

```lua
renderer.renderTargets() -> {
```

Every render target the renderer owns and what each one costs, measured
from the texture that is allocated. One row per target, each carrying its
`name`, whether it is `resident`, the `bytes` it holds while it is, its
`width`/`height`/`layers`/`mipLevels`, and `onDemand`.
An `onDemand` target exists only while something needs it: a target nothing
writes into reads `resident = false` and `bytes = 0` and appears again the
frame something writes it, and one sized by content — the reflection-probe
cube array — holds the slots content asked for. The scratch the draws into
a render target have needed is reported as `camera[<handle>].*` rows:
depth and motion vectors under any rasterized pass, and the occlusion
channel and G-buffer over them under a camera's scene render. A draw builds
what it needs, and the set goes once no live camera names the target and
sixty frames have passed without a draw, so a target nothing draws into
carries no such row; the colour image drawn into belongs to the texture
cache and outlives every one of those releases.
`totalBytes` is what the resident targets hold together. Measured at the
end of the last rendered frame.

**Returns** `{ targets, totalBytes, residentCount }`

```lua
local rt = renderer.renderTargets()
print(("render targets: %.1f MiB over %d resident"):format(rt.totalBytes / 1048576, rt.residentCount))
for _, t in rt.targets do
if t.onDemand then print(t.name, t.resident, t.bytes) end
end
```

## typed/builtin//modules/api/engine/renderer/renderer/resolutionScale {#typed-builtin-modules-api-engine-renderer-renderer-resolutionscale}

```lua
renderer.resolutionScale() -> number
```

The fraction of the display resolution the scene is currently rendered
at. `1` until something sets it.

**Returns** `number`

```lua
local s = renderer.resolutionScale()
```

## typed/builtin//modules/api/engine/renderer/renderer/setAnisotropy {#typed-builtin-modules-api-engine-renderer-renderer-setanisotropy}

```lua
renderer.setAnisotropy(level: number) -> number
```

Set the maximum anisotropy material textures are sampled with. Takes
effect on the next frame for content already on screen — no reload, no
texture re-upload. 1 is plain trilinear.

**Parameters**

- `level` `number` — One of 1, 2, 4, 8, 16. Any other value is an error.

**Returns** `number` — The EFFECTIVE level after clamping to `renderer.maxAnisotropy()`, so asking for more than the device offers reports what was actually applied.

```lua
renderer.setAnisotropy(16)
```

## typed/builtin//modules/api/engine/renderer/renderer/setBlendedBatching {#typed-builtin-modules-api-engine-renderer-renderer-setblendedbatching}

```lua
renderer.setBlendedBatching(enabled: boolean) -> ()
```

Whether neighbours in a view's back-to-front blended order draw
together. On by default: alpha-blended geometry is submitted farthest-first,
and a stretch of neighbours in that order sharing a mesh, a material, a
shader and a pose is submitted as one instanced draw over those neighbours,
which puts the same members on screen in the same order out of a single
submission. A run stops wherever a differently-drawn renderable sorts
between two of its members, and a mesh of several primitives keeps a draw
per renderable — both would otherwise move fragments through each other.
Off, every blended renderable draws on its own at its own slot, so a
transparent crowd costs a draw per member. The image is the same either way,
which is what makes this the comparison a frame suspected of being formed by
the batching is made against; `renderer.drawStats().draws` counts the
difference.

**Parameters**

- `enabled` `boolean` — `boolean`

**Returns** `()`

```lua
renderer.setBlendedBatching(false)  -- a draw per blended renderable
```

## typed/builtin//modules/api/engine/renderer/renderer/setDepthPrepass {#typed-builtin-modules-api-engine-renderer-renderer-setdepthprepass}

```lua
renderer.setDepthPrepass(enabled: boolean) -> ()
```

Enable or disable the opaque depth pre-pass. While enabled the renderer
resolves opaque depth in its own pass before shading, so each shaded pixel
runs its material once instead of once per surface stacked behind it, and
the resolved depth is what occlusion culling reads. Enabled by default.

**Parameters**

- `enabled` `boolean` — `boolean`

**Returns** `()`

```lua
renderer.setDepthPrepass(false) -- shade every layer, for comparison
```

## typed/builtin//modules/api/engine/renderer/renderer/setDepthPrepassOrdering {#typed-builtin-modules-api-engine-renderer-renderer-setdepthprepassordering}

```lua
renderer.setDepthPrepassOrdering(enabled: boolean) -> ()
```

Submit the depth pre-pass nearest-first. Renderables reach the pre-pass
in the order they were registered, which stands in no relation to where the
camera is: a scene built back-to-front makes every layer write depth and be
overwritten by the layer in front of it. Ordered, the nearest surface
writes first and the surfaces behind it are rejected by the depth test
before they write. The same draws go out either way and the depth that
comes out is the same, so `scene.depth_prepass` in `profiler.gpuFrame()` is
what moves. Enabled by default.

**Parameters**

- `enabled` `boolean` — `boolean`

**Returns** `()`

```lua
renderer.setDepthPrepassOrdering(false) -- submit in registration order
```

## typed/builtin//modules/api/engine/renderer/renderer/setGpuMemoryTracking {#typed-builtin-modules-api-engine-renderer-renderer-setgpumemorytracking}

```lua
renderer.setGpuMemoryTracking(frames: number?) -> number
```

Set how often the GPU allocator sampler reads — one reading every
`frames` frames — or turn it off with 0. It starts at 60, a reading a
second at 60 Hz, so `renderer.gpuMemory().allocator` answers without
anything arming it. Building the ledger walks every live allocation, which
is why it is sampled rather than read every frame; the category figures
cost nothing either way, and a reader between samples sees the most recent
ledger, so a slow interval still answers.

Called with no argument it reports the interval in force and changes
nothing, which is how something that retimes the sampler puts it back
afterwards instead of restoring a number it assumed was the default.

**Parameters**

- `frames` `number` _(optional)_ — `number?` Frames between readings; 0 turns the sampler off. Omit
to read the interval without changing it.

**Returns** `number` — The interval now in force.

```lua
renderer.setGpuMemoryTracking(60)
local was = renderer.setGpuMemoryTracking()
renderer.setGpuMemoryTracking(1)
-- ... take a tight reading ...
renderer.setGpuMemoryTracking(was)
```

## typed/builtin//modules/api/engine/renderer/renderer/setMaxFramesInFlight {#typed-builtin-modules-api-engine-renderer-renderer-setmaxframesinflight}

```lua
renderer.setMaxFramesInFlight(frames: number) -> number
```

Set how many frames of GPU work may be outstanding before the renderer
stops running ahead. One is the least overlap this can express — a frame's
work is waited for as soon as the next frame has been submitted — which is
the lowest latency and the lowest throughput; higher values let a slow
frame build a longer backlog, and that backlog is memory. Takes effect on
the next frame.

Answers the bound after clamping to [1, 8], so asking for more than the
renderer honours reports what you actually got.

**Parameters**

- `frames` `number` — number Frames of GPU work that may be outstanding, 1 through 8.

**Returns** `number` — The bound that took effect, after clamping.

```lua
renderer.setMaxFramesInFlight(1) -- lowest latency
print(renderer.setMaxFramesInFlight(99), "was clamped")
```

## typed/builtin//modules/api/engine/renderer/renderer/setMinScreenSize {#typed-builtin-modules-api-engine-renderer-renderer-setminscreensize}

```lua
renderer.setMinScreenSize(pixels: number) -> ()
```

Stop drawing an object once its on-screen radius falls below this many
pixels. A few pixels across, an object carries no detail a viewer can
resolve while still costing a full vertex and submission pass, and the
cutoff drops it from the camera's draws entirely — `0`, the default,
keeps every object however small it lands. Measured from the object's own
bounds against the camera's projection, so the same threshold means the
same apparent size at any distance or field of view. Shadow casters have
their own threshold in `renderer.setShadowCasterCutoff`.

**Parameters**

- `pixels` `number` — `number` — smallest on-screen radius still drawn; 0 disables.

**Returns** `()`

```lua
renderer.setMinScreenSize(4) -- drop anything under 4 px of radius
print(renderer.drawStats().compactedDrawn, "instances survived it")
```

## typed/builtin//modules/api/engine/renderer/renderer/setOcclusionCulling {#typed-builtin-modules-api-engine-renderer-renderer-setocclusionculling}

```lua
renderer.setOcclusionCulling(enabled: boolean) -> ()
```

Enable or disable occlusion culling. While enabled the renderer reduces
the pre-pass depth into a pyramid each frame and tests every renderable
that cleared the frustum against it, dropping the ones another surface
entirely covers before their geometry is submitted. The pyramid describes
the frame being drawn, so an object that becomes visible this frame is
never held back a frame. Requires the depth pre-pass.

**Parameters**

- `enabled` `boolean` — `boolean`

**Returns** `()`

```lua
renderer.setOcclusionCulling(true); print(renderer.cullStats().occlusionCulled)
```

## typed/builtin//modules/api/engine/renderer/renderer/setPointShadowBudget {#typed-builtin-modules-api-engine-renderer-renderer-setpointshadowbudget}

```lua
renderer.setPointShadowBudget(cfg: {
    megabytes: number?,
    resolution: number?,
}) -> number
```

Set how much VRAM the point-light shadow atlas may hold, and at what
per-face resolution. An omitted field keeps its current value. The atlas
is reallocated on the next frame, so `renderer.pointShadowBudget().slots`
reports the new pool one frame later; the returned number is what this
budget buys. Raising `resolution` sharpens every point shadow and spends
the same memory on fewer of them — doubling it quarters the slot count.
Values are clamped: megabytes [1, 1024], resolution [64, 4096], and the
pool never exceeds `renderer.pointShadowBudget().maxSlots`. One slot is
always granted, so a budget too small for a single cube shadows one light
and the pool costs what that slot costs rather than what was asked for —
`{ megabytes = 1, resolution = 4096 }` buys 384 MiB of ceiling. Read
`pointShadowBudget().bytes` back to see what a budget actually bought, and
`renderer.shadowMemory().point` to see what the scene has made resident.

**Parameters**

- `cfg` `{
    megabytes: number?,
    resolution: number?,
}` — The fields to change — `megabytes` and/or `resolution`.

**Returns** `number` — Cube slots this budget buys.

```lua
renderer.setPointShadowBudget({ megabytes = 96 })
renderer.setPointShadowBudget({ resolution = 1024, megabytes = 96 })
```

## typed/builtin//modules/api/engine/renderer/renderer/setPresentMode {#typed-builtin-modules-api-engine-renderer-renderer-setpresentmode}

```lua
renderer.setPresentMode(mode: string) -> string
```

Set how a presented frame reaches the display. `fifo` queues every frame
and shows it on a vertical blank, which never tears and never drops one;
`mailbox` replaces the queued frame with the newest, which does not tear
and does not hold the renderer to the refresh rate; `immediate` presents as
soon as a frame is ready and can tear; `fifo_relaxed` is `fifo` that tears
rather than stall when a frame misses its blank; `auto_vsync` and
`auto_no_vsync` leave the choice to the backend.

A surface that does not offer the mode presents `fifo` instead, so read
`renderer.framePacing().presentMode` for what took effect and
`.presentModes` for what this surface offers. Takes effect on the next
frame.

**Parameters**

- `mode` `string` — string One of "fifo", "fifo_relaxed", "mailbox", "immediate", "auto_vsync", "auto_no_vsync".

**Returns** `string` — The canonical spelling of the request — `renderer.framePacing().presentMode` is what the surface presents with, and differs when the surface does not offer the request.

```lua
renderer.setPresentMode("mailbox")
print(renderer.framePacing().presentMode, "is what the surface took")
```

## typed/builtin//modules/api/engine/renderer/renderer/setProjectionOffset {#typed-builtin-modules-api-engine-renderer-renderer-setprojectionoffset}

```lua
renderer.setProjectionOffset(x: number, y: number)
```

Offset the main camera's projection by a sub-pixel amount, in NDC, for
the frames until it is set again. The offset is in NDC because that is the
space it is constant in: one pixel is `2.0 / width` across, so half a pixel
is `1.0 / width`. Velocity (`@scene.motion`) is measured against the
offset-free projection, so a still scene reports no motion however the
samples are placed — and picking resolves a click to the same ray either
way. `(0, 0)` samples pixel centres.

**Parameters**

- `x` `number` — Horizontal offset in NDC. One pixel is `2.0 / width`.
- `y` `number` — Vertical offset in NDC. One pixel is `2.0 / height`.

```lua
renderer.setProjectionOffset(0.5 * 2 / w, -0.25 * 2 / h)
```

## typed/builtin//modules/api/engine/renderer/renderer/setRaytrace {#typed-builtin-modules-api-engine-renderer-renderer-setraytrace}

```lua
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.

**Parameters**

- `enabled` `boolean` — `boolean`

**Returns** `()`

```lua
renderer.setRaytrace(true); renderer.feature.create("rt_shadows")
```

## typed/builtin//modules/api/engine/renderer/renderer/setResolutionScale {#typed-builtin-modules-api-engine-renderer-renderer-setresolutionscale}

```lua
renderer.setResolutionScale(scale: number) -> number
```

Render the scene at a fraction of the display's resolution and present
it at the display's own size. Shading cost scales with pixel count and with
nothing else, so this trades sharpness for frame time without taking
anything out of the scene: at `0.5` the scene rasterizes a quarter of the
pixels. UI and text are unaffected — they are drawn after the scene is
brought back up to size. The scene rows in `profiler.gpuFrame()` are what
move.

**Parameters**

- `scale` `number` — `number` — fraction of the display resolution, clamped to [0.25, 1].

**Returns** `number` — the scale in force after clamping.

```lua
renderer.setResolutionScale(0.7)
```

## typed/builtin//modules/api/engine/renderer/renderer/setShadowCaching {#typed-builtin-modules-api-engine-renderer-renderer-setshadowcaching}

```lua
renderer.setShadowCaching(enabled: boolean) -> ()
```

Whether a shadow map that nothing changed is kept rather than drawn
again. On by default: a shadow view — one directional cascade, one atlas
layer of spot tiles, one face of a point light's cube — is rasterized on
the frames its own inputs change and holds the depth it drew on the ones
they do not.
Off, every view is drawn on every pass, which is what a shadow suspected of
holding a stale image is compared against.

**Parameters**

- `enabled` `boolean` — `boolean`

**Returns** `()`

```lua
renderer.setShadowCaching(false)  -- draw every shadow view, every frame
```

## typed/builtin//modules/api/engine/renderer/renderer/setShadowCasterBatching {#typed-builtin-modules-api-engine-renderer-renderer-setshadowcasterbatching}

```lua
renderer.setShadowCasterBatching(enabled: boolean) -> ()
```

Whether a shadow view draws every caster of one mesh together. On by
default: a view — one directional cascade, one atlas layer of spot tiles,
one face of a point light's cube — submits one draw per geometry over every
caster of it the view admits, wherever those casters sit in render order
and whatever transform slots they hold. Off, a view draws the runs of render-order
neighbours that share a mesh AND hold consecutive slots, so a scene that has
spawned and despawned anything fragments into many more draws. The image is
the same either way, which is what makes this the comparison a shadow
suspected of being placed by the batching is made against.

**Parameters**

- `enabled` `boolean` — `boolean`

**Returns** `()`

```lua
renderer.setShadowCasterBatching(false)  -- draw the runs the scene presents
```

## typed/builtin//modules/api/engine/renderer/renderer/setShadowCasterCutoff {#typed-builtin-modules-api-engine-renderer-renderer-setshadowcastercutoff}

```lua
renderer.setShadowCasterCutoff(cfg: {
    minRadiusPx: number?,
    maxDistance: number?,
}) -> ShadowCasterCutoff
```

Set the shadow-caster cutoff. An omitted field keeps its current value,
so a call can adjust one threshold without restating the other. Both are
measured against the camera the frame draws from rather than against each
light, so one setting covers every cascade, spot and cube face, and a
caster that stops casting is one whose shadow the viewer could not have
resolved. `maxDistance` is measured to the near side of the caster's
bounding sphere, so a large object keeps casting while any part of it is in
range. 0 releases a threshold; releasing both draws the casters the frame
drew before either was set.

**Parameters**

- `cfg` `{
    minRadiusPx: number?,
    maxDistance: number?,
}` — The fields to change — `minRadiusPx` and/or `maxDistance`.

**Returns** `ShadowCasterCutoff` — The cutoff now in force.

```lua
renderer.setShadowCasterCutoff({ minRadiusPx = 2 })
renderer.setShadowCasterCutoff({ minRadiusPx = 1.5, maxDistance = 120 })
```

## typed/builtin//modules/api/engine/renderer/renderer/setShadowConfig {#typed-builtin-modules-api-engine-renderer-renderer-setshadowconfig}

```lua
renderer.setShadowConfig(cfg: {
    resolution: number?,
    cascades: number?,
    distance: number?,
    splitLambda: number?,
    fadeFraction: number?,
    softness: number?,
}) -> ShadowConfig
```

Set the directional shadow quality. Any omitted field keeps its current
value, so a call can adjust one knob without restating the rest. Values are
clamped: resolution [64, 8192], cascades [1, 4], distance >= 0, splitLambda
[0, 1], fadeFraction [0, 1], softness [0, 1]. Changing `resolution` or
`cascades` reallocates the depth array; the rest are per-frame values. A
`distance` of 0 hands the range to the frame — the splits are cut over the
depth its own shadow-taking renderables reach — and a positive one caps it,
which is what a scene bounding its shadow cost states.

**Parameters**

- `cfg` `{
    resolution: number?,
    cascades: number?,
    distance: number?,
    splitLambda: number?,
    fadeFraction: number?,
    softness: number?,
}` — The fields to change — see `ShadowConfig`.

**Returns** `ShadowConfig` — The full config now in force.

```lua
renderer.setShadowConfig({ softness = 0.65, fadeFraction = 0.28 })
renderer.setShadowConfig({ cascades = 4, resolution = 2048, distance = 240 })
```

## typed/builtin//modules/api/engine/renderer/renderer/setShadowHero {#typed-builtin-modules-api-engine-renderer-renderer-setshadowhero}

```lua
renderer.setShadowHero(entity: string, padding: number?) -> ()
```

Give one caster a directional shadow view of its own, fit to its world
bounds.

A cascade covers the slab of world the camera sees, so its texels are spread
over tens of metres and one character standing in the middle of it is
resolved by a handful of them. The hero view is the same light and the same
depth range zoomed onto that entity's bounds, so the whole map goes into the
shadow it and the ground under it carry — `renderer.shadowHero().zoom` is
the factor its texel density gains.

It renders beside the cascades, into a layer of the same texture allocated
while a hero is registered, and every surface inside it reads it in place of
the cascade, crossing back at its edge. Nothing else about the shadow
changes: the same casters reach it, at the same depth range, through the
same filter.

**Parameters**

- `entity` `string` — The entity whose renderables the view is fit around.
- `padding` `number` _(optional)_ — How much room the fit leaves around those bounds — for a pose that
leaves the bind-pose box and for the filter that samples outside a
silhouette. 1.0 fits them exactly.

**Returns** `()`

```lua
renderer.setShadowHero(player.id)
print(("hero shadow: %.1f texels/unit vs %.1f"):format(
renderer.shadowHero().texelsPerUnit, renderer.shadowHero().cascadeTexelsPerUnit))
```

## typed/builtin//modules/api/engine/renderer/renderer/setShadowProxy {#typed-builtin-modules-api-engine-renderer-renderer-setshadowproxy}

```lua
renderer.setShadowProxy(mesh: string, proxy: string) -> ()
```

Rasterize `proxy` in place of `mesh` in every shadow view. A shadow is a
silhouette resolved at the resolution of a shadow map, so the triangles that
carry a mesh's close-up detail write depth no reader can resolve — a
decimated version of the shape, a level of its own LOD chain, or a
hand-built hull casts the same shadow for a fraction of the geometry.

The registration is keyed by MESH, so one call covers every instance of it —
entities and GPU-driven populations alike — and a crowd sharing that mesh
stays one draw. The proxy is placed by whatever places the caster, its
instance's own transforms, so it stands where the caster stands, at the
caster's scale.

An entity caster keeps its own geometry where a stand-in could not be placed
or deformed correctly: it is skinned (it rasterizes the post-skinned
vertices written for its own mesh), it blends morph targets (whose deltas
describe its own mesh and are read by vertex id), or its proxy would be
placed by a different node of its model than the source mesh is. Either
caster keeps it where the renderer holds no geometry under the proxy's
guid. Each of those is counted in `renderer.shadowProxies()`.

Nothing else in the scene draws a proxy, so this call is what brings it onto
the GPU, and it raises where it cannot. A proxy already resident there is
registered as it stands.

**Parameters**

- `mesh` `string` — The mesh a caster draws, as a guid or any mesh reference.
- `proxy` `string` — The mesh it rasterizes into shadow views instead.

**Returns** `()`

```lua
renderer.setShadowProxy(statueMesh, statueHullMesh)
print(renderer.shadowProxies().triangles, "vs", renderer.shadowProxies().sourceTriangles)
```

## typed/builtin//modules/api/engine/renderer/renderer/setSkinnedBatching {#typed-builtin-modules-api-engine-renderer-renderer-setskinnedbatching}

```lua
renderer.setSkinnedBatching(enabled: boolean) -> ()
```

Whether skinned instances holding one pose draw together. On by default:
instances of one mesh wearing one material and posed alike read the same
post-skinned vertices, so the camera's colour passes submit them as a single
instanced draw, and so does each shadow view and the velocity pass while
`renderer.shadowCasterBatching()` is on — that switch is what makes a depth
view form its draws by geometry at all. The camera depth pre-pass submits
its casters nearest-first, which is a run per span of neighbours rather than
a draw per geometry, so a crowd costs a draw per member there. Off, each
skinned instance draws on its own at its own slot in every pass that
rasterizes it. The image is the same either way, which is what makes this
the comparison a frame suspected of being formed by the batching is made
against — `renderer.drawStats().draws` counts the difference and
`renderer.skinningStats().poses` says how many distinct poses it holds.

**Parameters**

- `enabled` `boolean` — `boolean`

**Returns** `()`

```lua
renderer.setSkinnedBatching(false)  -- a draw per skinned instance
```

## typed/builtin//modules/api/engine/renderer/renderer/setSkinningPoseHold {#typed-builtin-modules-api-engine-renderer-renderer-setskinningposehold}

```lua
renderer.setSkinningPoseHold(enabled: boolean) -> ()
```

Whether a pose the skinning pass already wrote is read as it stands. On
by default: the pass produces an instance's vertices from its joint
matrices, its node transforms, its blend weight and its blend model, so the
slice holding a pose already holds what running the pass over those same
inputs would write. A frame binding a pose whose slice still holds it reads
the slice and dispatches nothing, and skinning costs what the frame's poses
CHANGED — a paused clip, a skeleton nothing drives, a cast standing in one
pose, each cost compute the frame the pose arrived and nothing after it.
Off, every pose a frame binds is dispatched again, which is the comparison a
frame suspected of reading a slice that no longer holds its pose is made
against; the image is the same either way and
`renderer.skinningStats()` counts the difference as `dispatches` against
`held`. A mesh whose vertices a compute pass writes is dispatched every
frame however this stands.

**Parameters**

- `enabled` `boolean` — `boolean`

**Returns** `()`

```lua
renderer.setSkinningPoseHold(false)  -- dispatch every pose, every frame
```

## typed/builtin//modules/api/engine/renderer/renderer/setSpotShadowBudget {#typed-builtin-modules-api-engine-renderer-renderer-setspotshadowbudget}

```lua
renderer.setSpotShadowBudget(cfg: {
    megabytes: number?,
    resolution: number?,
}) -> number
```

Set how much VRAM the spot/area shadow atlas may hold, and the per-side
resolution of one layer. An omitted field keeps its current value. The
atlas is reallocated on the next frame, so `renderer.spotShadowBudget()`
reports it one frame later; the returned number is what this budget buys.
Raising `resolution` sharpens the lights that cover the most screen and
spends the same memory on fewer layers — doubling it quarters the layer
count. Raising `megabytes` buys layers, which is what lets several lights
hold a large tile at once. Values are clamped: megabytes [1, 1024],
resolution [64, 4096], and the atlas never exceeds
`spotShadowBudget().maxLayers`. One layer is always granted, so a budget
too small for one still shadows lights and the atlas costs what that layer
costs rather than what was asked for.

**Parameters**

- `cfg` `{
    megabytes: number?,
    resolution: number?,
}` — The fields to change — `megabytes` and/or `resolution`.

**Returns** `number` — Atlas layers this budget buys.

```lua
renderer.setSpotShadowBudget({ megabytes = 64 })
renderer.setSpotShadowBudget({ resolution = 2048, megabytes = 64 })
```

## typed/builtin//modules/api/engine/renderer/renderer/setTextureBudget {#typed-builtin-modules-api-engine-renderer-renderer-settexturebudget}

```lua
renderer.setTextureBudget(opts: TextureBudgetOpts) -> TextureBudget
```

Bound the VRAM a world's textures occupy, by keeping only the mip levels
the frame is actually sampling. Pass `{ megabytes = 256 }`; `0` — the
default — leaves texture residency alone and every texture stays fully
resident the way it uploaded.

With a budget armed, each frame measures how many screen pixels ONE
traversal of a texture's coordinate range covers on the surface that spans
it widest, and asks for the mip level that serves that span one texel per
pixel — the level the GPU picks from the fragment's own derivatives. A
material with `uvScale = 8` lays eight copies of its texture across a
surface, so each copy spans an eighth of the surface and asks for three
levels coarser than the surface's own size would. A shader that declares
`// @uv_space: world` advances its coordinate over world units rather than
over the mesh's UVs, so how many copies a surface carries follows how large
that surface is. The textures whose surfaces cover the fewest pixels give
up levels until the set fits. Detail climbs one level per frame, from the
image already on screen, so a surface the camera approaches sharpens rather
than popping, and no texture is taken below the level whose longest side is
64 texels.

`bias` shifts every measurement by whole mip levels either way — negative
for finer than the sampling implies, positive for coarser — over a world
whose look wants a different trade than one texel per pixel.

The plan moves a texture whose demand the frame can measure: one at least
256 texels on its narrowest side, worn by a surface an entity draws. A
texture a UI image, a post-process property or a render feature holds a
view of stays whole, because nothing measures how much of the screen those
cover.

Which textures the budget governs follows the surfaces the frame draws. A
texture whose asset still holds its bytes is enrolled the frame a measured
surface wears it — whenever it loaded, and whenever the budget was armed —
because a level change reads the levels it needs back from the asset; when
the last such surface goes it leaves the set whole, at the level it
uploaded at, and a surface reaching it again takes it back up. A texture a
script uploaded has its pixels nowhere else, so one enrolled while it is
resident holds them in system memory
(`renderer.textureMemory().streamSourceBytes`) from the upload until a
surface has worn it and gone, and releases them then, which is what keeps
it out for the rest of the session; one whose pixels were already released
when the budget was armed is out from the start.
`renderer.textureMemory().pinnedTextures` counts those, together with the
textures whose asset could not be read back and the ones a UI image, a
post-process property or a render feature holds a view of. Disarming
returns every texture to the level it uploaded at, and arming again governs
the textures the frame's surfaces are wearing then.

**Parameters**

- `opts` `TextureBudgetOpts` — `{ megabytes: number?, bias: number? }`

**Returns** `TextureBudget` — `{ megabytes, bias }` — the budget now in force

```lua
renderer.setTextureBudget({ megabytes = 128 })
renderer.setTextureBudget({ megabytes = 128, bias = -1 })  -- one level finer everywhere
renderer.setTextureBudget({ megabytes = 0 })               -- leave residency alone
```

## typed/builtin//modules/api/engine/renderer/renderer/setTransmissionShadows {#typed-builtin-modules-api-engine-renderer-renderer-settransmissionshadows}

```lua
renderer.setTransmissionShadows(enabled: boolean) -> ()
```

Let translucent casters tint the sunlight they block instead of blocking
it outright. A shadow map holds one depth per texel and is compared as a
yes-or-no test, so stained glass, water and thin fabric all project the same
black silhouette a wall does. With this on, a caster whose material declares
opacity (`base_color` alpha under a transparent blend) or `transmission`
also draws into a light-space transmittance map, and the colour it lets
through multiplies into the directional light reaching whatever stands
behind it. Stacked casters compose. Opaque casters are unaffected, and a
scene with no translucent caster allocates nothing and records no pass.

**Parameters**

- `enabled` `boolean` — `boolean`

**Returns** `()`

```lua
renderer.setTransmissionShadows(true)  -- stained glass tints the floor
```

## typed/builtin//modules/api/engine/renderer/renderer/shaderCache {#typed-builtin-modules-api-engine-renderer-renderer-shadercache}

```lua
renderer.shaderCache() -> ShaderCache?
```

What the shader compile gate's store of baked WGSL held, answered and
wrote back. Compiling a `.shader` wraps the author's body in its framework,
expands every `#include`, and hands the result to naga to parse and
validate — work that is a pure function of the text going in, and that a
launch would otherwise repeat for every shader it draws with. The store
keeps that baked text across launches.

`restoredEntries` and `restoredBytes` are what a previous launch left that
this one read back. `hits` counts the compiles answered out of the store
and `misses` those that ran in full; `savedMs` sums what each hit's own
recorded compile had cost, against `compileMs`, what the misses spent.
`stale` counts the misses whose key was held but whose `#include`d modules
had changed underneath — an entry records every module its expansion
consumed, so editing a module invalidates exactly the shaders that included
it and leaves the rest.

`entries` and `bytes` are what the store now holds, `evictions` how many a
write dropped to stay inside its bounds, and `saves` / `savedBytes` /
`dirty` describe writing it back, deferred until a burst of compiles
settles. `persistent` is false where a launch has nowhere to keep
artifacts and `reason` says why; `location` is the file, or the browser
store, they are kept in. `restoreState` is how the read of what a previous
launch left has gone — `pending` while it is still out (a browser answers
through a promise, so a launch reaches its first frames before it lands),
`restored` once entries came back, `empty` when there were none to come
back, `failed` when what was there could not be read, and `none` where a
launch keeps nothing. A cold, missing or corrupt store leaves every
shader compiling from source with identical output, and `lastError` then
names what went wrong.

**Returns** `ShaderCache?` — `{ persistent, reason, restoreState, location, restoredEntries, restoredBytes, hits, misses, stale, entries, bytes, compileMs, savedMs, saves, savedBytes, dirty, evictions, lastError }`, or nil on a build with no renderer

```lua
local c = renderer.shaderCache()
print(("%d hits, %d misses, %.1f ms saved"):format(c.hits, c.misses, c.savedMs))
```

## typed/builtin//modules/api/engine/renderer/renderer/shaderCost {#typed-builtin-modules-api-engine-renderer-renderer-shadercost}

```lua
renderer.shaderCost() -> { ShaderCost }
```

What each program has cost in pipeline builds, beside the compile
gate's most recent word about it. `variants` is how many pipelines this
engine has built for it — one per (target format, vertex layout,
render-state key) permutation reached — and `buildMs` what those builds
cost, both summed since engine start. A pipeline the driver's own store
restored is not built and so is not counted, so a second launch on the same
adapter reports less than the first. `status` is `compiled`, `failed` or
`pending`, and `error` carries the compiler's message for a failure.
Ordered by cost, most expensive first.

**Returns** `{ ShaderCost }`

```lua
local top = renderer.shaderCost()[1]; print(top.shader, top.variants, top.buildMs)
```

## typed/builtin//modules/api/engine/renderer/renderer/shaderVariants {#typed-builtin-modules-api-engine-renderer-renderer-shadervariants}

```lua
renderer.shaderVariants() -> { ShaderVariants }
```

Every shader that declares optional features, and the programs its
materials have made it compile. Each row carries the features the shader
declares, the base program it ships as, and one entry per variant with the
features that variant holds — so the permutation count a scene's materials
are spending is a number to read rather than something to infer from
compile time. A shader whose variants reach `budget` compiles no more; the
materials asking for further feature sets draw with the base program.

**Returns** `{ ShaderVariants }` — An array of `ShaderVariants`, one per feature-declaring shader.

```lua
for _, s in renderer.shaderVariants() do print(s.shader, #s.variants, s.budget) end
```

## typed/builtin//modules/api/engine/renderer/renderer/shadingOf {#typed-builtin-modules-api-engine-renderer-renderer-shadingof}

```lua
renderer.shadingOf(subject: string | { [string]: any }) -> ShadingReading
```

What the renderer is shading ONE subject with, taken from the document
the renderer publishes — the call a system holding a handle makes to find
out whether what reaches the screen is its own material or the magenta
placeholder standing in for it, without reading the engine log. `subject` is
an entity that draws or the registry key of a material. `state` reads
`itsMaterial` where the renderer bound the program the material names,
`errorMaterial` where it bound the placeholder instead, `stalePipeline`
where the pipeline drawing it was built before that program's most recent
compile, `nothingBound` where the renderer resolved no pipeline for it,
`pending` where this call is the one that armed per-draw recording and the
frame after it publishes, and `unknown` where the renderer holds a
resolution under no such subject. A fault state carries the renderer's own
`reason` from the closed set `renderer.drawDiagnostics()` names — plus
`materialNotPrepared`, which a material subject reads where the renderer
prepared nothing under that key — the compiler's `detail`, the `program`
the material asked for and the `bound` one; `means` states the reading in a
sentence. A material subject answers from the renderables drawing with it,
and from the renderer's record for the material itself where a draw
registered against the material carries no row of its own; a subject that
several renderables draw answers with a refused one wherever there is one.
The reading follows the renderer, so a program that compiles on a later
edit puts the subject back on `itsMaterial` from the frame the renderer
draws it with again.

**Parameters**

- `subject` `string | { [string]: any }` — The entity — a proxy from `entity(...)` or an entity-id string —
or the material, as its registry key or the `MaterialHandle`
`renderer.material.create` returned.

**Returns** `ShadingReading`

```lua
local s = renderer.shadingOf(emitter); if s.state ~= "itsMaterial" then print(s.means) end
```

## typed/builtin//modules/api/engine/renderer/renderer/shadowCacheStats {#typed-builtin-modules-api-engine-renderer-renderer-shadowcachestats}

```lua
renderer.shadowCacheStats() -> {
```

What the last frame did with the shadow maps it already had. A shadow
view — one directional cascade, one atlas layer of spot tiles, one face of
a point light's cube — is drawn again only when something it draws from
changed:
its light moved, a caster it can see moved or appeared or vanished, a
caster's geometry or material changed, a caster changed pose or moved the
nodes its parts are placed by, or the map it writes into was reallocated.
Anything else keeps the depth already in the texture, so a scene that stops
moving reads `rendered` 0 while `cached` keeps climbing. A mesh whose
vertices a compute pass writes — a population, or a mesh built from a
compute buffer — re-renders the views it stands in every frame. A shadowed
point light contributes six views, one per cube face, so a caster moving on
one side of it re-renders the face that can see it and leaves the other
five holding what they have. Counted per light kind, plus the totals across
all three.

These are totals over every view of a kind. `renderer.shadowViews()` is the
same frame one view at a time, each row naming the light that owns it and
what it drew.

**Returns** `{ directionalRendered, directionalCached, spotRendered, spotCached, pointRendered, pointCached, rendered, cached }`

```lua
local s = renderer.shadowCacheStats()
print(("shadow views: %d drawn, %d cached"):format(s.rendered, s.cached))
```

## typed/builtin//modules/api/engine/renderer/renderer/shadowCaching {#typed-builtin-modules-api-engine-renderer-renderer-shadowcaching}

```lua
renderer.shadowCaching() -> boolean
```

Whether a shadow view may keep the depth it already holds.

**Returns** `boolean`

## typed/builtin//modules/api/engine/renderer/renderer/shadowCasterBatching {#typed-builtin-modules-api-engine-renderer-renderer-shadowcasterbatching}

```lua
renderer.shadowCasterBatching() -> boolean
```

Whether a shadow view draws every caster of one mesh together.

**Returns** `boolean`

## typed/builtin//modules/api/engine/renderer/renderer/shadowCasterCutoff {#typed-builtin-modules-api-engine-renderer-renderer-shadowcastercutoff}

```lua
renderer.shadowCasterCutoff() -> ShadowCasterCutoff
```

How small, and how far away, a caster may get before it stops writing
depth into any shadow view. A shadow view rasterizes a caster's whole
triangle count whatever the shadow it produces ends up covering, so an
object the viewer resolves a fraction of a pixel of, and one past the range
the scene cares about, each cost a full depth pass per shadowed light for
detail nothing reads. Both thresholds are 0 — released — until something
sets them.

**Returns** `ShadowCasterCutoff` — The cutoff in force — see `ShadowCasterCutoff`.

```lua
local c = renderer.shadowCasterCutoff(); print(c.minRadiusPx, c.maxDistance)
```

## typed/builtin//modules/api/engine/renderer/renderer/shadowConfig {#typed-builtin-modules-api-engine-renderer-renderer-shadowconfig}

```lua
renderer.shadowConfig() -> ShadowConfig
```

The directional shadow quality now in force. `resolution` and `cascades`
size the cascade depth array; `distance` and `splitLambda` place the splits
along the view; `fadeFraction` and `softness` shape how the result is
sampled.

**Returns** `ShadowConfig` — The full config — see `ShadowConfig`.

```lua
print(renderer.shadowConfig().cascades)
```

## typed/builtin//modules/api/engine/renderer/renderer/shadowHero {#typed-builtin-modules-api-engine-renderer-renderer-shadowhero}

```lua
renderer.shadowHero() -> ShadowHeroReport
```

The registered hero caster and what the last frame's fit produced. A
frame that fit nothing says why in `decline`.

**Returns** `ShadowHeroReport` — See `ShadowHeroReport`.

```lua
local h = renderer.shadowHero()
print(h.active, h.zoom, h.decline)
```

## typed/builtin//modules/api/engine/renderer/renderer/shadowMemory {#typed-builtin-modules-api-engine-renderer-renderer-shadowmemory}

```lua
renderer.shadowMemory() -> {
```

How much GPU memory the shadow maps hold right now, in bytes, by the
light kind that owns them. The spot atlas and the point pool are sized to
the casters in the scene rather than to the budget, so `spot` and `point`
move as lights that cast shadows appear and leave, and a scene with one
shadowed light holds far less than one that fills every slot. A budget is
the ceiling they grow within — `renderer.spotShadowBudget().layers` and
`renderer.pointShadowBudget().slots` report that ceiling, unmoved by how
many casters exist. Raising shadow resolution costs the square of the
change across every cascade.

**Returns** `{ directional, spot, point, total }` in bytes

```lua
local m = renderer.shadowMemory()
print(("shadows: %.1f MiB"):format(m.total / 1024 / 1024))
```

## typed/builtin//modules/api/engine/renderer/renderer/shadowProxies {#typed-builtin-modules-api-engine-renderer-renderer-shadowproxies}

```lua
renderer.shadowProxies() -> ShadowProxyReport
```

The shadow proxies in force and what the last frame's shadow passes did
with them. `triangles` and `sourceTriangles` are what those passes
submitted and what they would have submitted from the source meshes — the
before/after of every registration, equal while nothing is proxied.

**Returns** `ShadowProxyReport` — See `ShadowProxyReport`.

```lua
local p = renderer.shadowProxies()
print(("shadow triangles: %d of %d"):format(p.triangles, p.sourceTriangles))
```

## typed/builtin//modules/api/engine/renderer/renderer/shadowViews {#typed-builtin-modules-api-engine-renderer-renderer-shadowviews}

```lua
renderer.shadowViews() -> ShadowViewReport?
```

Every shadow view the last rendered frame considered, and what each one
cost.

A frame rasterizes a depth view per directional cascade, one for the hero
caster, one per shadow-casting spot and six per shadow-casting point.
`renderer.shadowCacheStats()` counts those views by light kind,
`renderer.drawStats()` sums their draws with the camera's, and
`profiler.gpuFrame()` carries one `scene.shadow` span across all of them.
This is the same frame read one view at a time.

Each row names the view and the light that owns it, says whether it drew or
kept the depth it already held, and carries the draws, the instances and the
casters that went into it. `span` is the label the view's pass is timed
under, so its GPU time is a lookup in `profiler.gpuFrame()`; every one of
those labels is a variant of `scene.shadow`, which still carries their
total. `camera` carries the same instance counters for the main camera, so
the camera's share of a frame-wide total is a read rather than a measurement
taken by turning every light's shadow off.

A cascade's `near` and `far` are where the split scheme cut its slice, not
the world it covers: the fit takes the bounding sphere of that slice and
rasterizes the ortho box around it, and both reach past `far`. What the
cascade covers is `center` and `radius`, with `viewProj` the exact test;
`coversNear` and `coversFar` read that volume back along one ray, the
camera's view axis. `directional` states the axis reading for the set —
how far it reaches (`coversFar`), the range the splits were run over
(`distance`), how far the camera draws (`cameraFar`), and the
depth past the reach the camera still draws (`uncovered`). A receiver
further along the axis than `coversFar` has no directional depth map over
it and is shaded as if the sun reached it, so `uncovered` is the room a
missing shadow has and a surface standing in that room is what makes one;
`@builtin::systems.proxyOcclusion` occludes past the cascades. The box is
bounded in every direction, so a receiver standing wide of the axis leaves
it at its own distance even where `uncovered` is 0 — `viewProj` is what
answers for that receiver.

The list is rebuilt every frame: a view whose light stopped casting is
absent from the next report rather than standing at the numbers it last had,
and a frame that drew no shadow view answers a report whose `views` is
empty. `views` grouped the way the shadow cache decides — a row per cascade,
per spot atlas layer, per point cube — counts what
`renderer.shadowCacheStats()` reports as `rendered + cached`.

The frame names its views only while something is reading them, so this
call asks the frames after it to name theirs and waits out the first one.
Nil on an engine that renders no frame at all.

**Returns** `ShadowViewReport?` — See `ShadowViewReport`.

```lua
local report = renderer.shadowViews()
print(("camera submitted %d of %d instances"):format(
report.camera.submittedInstances, renderer.drawStats().compactedDrawn))
for _, view in report.views do
print(("%s %d (%s): %d draws, %d instances, %s"):format(
view.role, view.index, view.light, view.draws, view.instances,
view.rendered and "drew" or "cached"))
end
local d = report.directional
if d ~= nil and d.uncovered > 0 then
print(("sun shadows stop at %.0f; the camera draws to %.0f"):format(
d.coversFar, d.cameraFar))
end
```

## typed/builtin//modules/api/engine/renderer/renderer/skinnedBatching {#typed-builtin-modules-api-engine-renderer-renderer-skinnedbatching}

```lua
renderer.skinnedBatching() -> boolean
```

Whether skinned instances holding one pose draw together.

**Returns** `boolean`

## typed/builtin//modules/api/engine/renderer/renderer/skinningPoseHold {#typed-builtin-modules-api-engine-renderer-renderer-skinningposehold}

```lua
renderer.skinningPoseHold() -> boolean
```

Whether a pose already written into its slice skips its dispatch.

**Returns** `boolean`

## typed/builtin//modules/api/engine/renderer/renderer/skinningStats {#typed-builtin-modules-api-engine-renderer-renderer-skinningstats}

```lua
renderer.skinningStats() -> {
```

What the last frame's skinned instances cost. A skinned instance is
posed by a compute pass that writes its vertices into a shared pool, and
instances holding the same pose read one slice of that pool and the single
dispatch that fills it. `instances` is how many were posed, `poses` how
many distinct poses they held, and `dispatches` how many dispatches those
poses cost this frame — so a crowd whose members move together costs what
its poses cost rather than what its head count does, while members at
different animation times each hold their own pose and pay for it.

`held` is how many of the frame's poses cost no dispatch at all. The pass
produces a slice from what the pose is made of, so a slice an earlier frame
filled already holds what running it again would write, and a pose still
wearing that slice is read as it stands. Skinning is paid for by the poses
that CHANGED: a cast standing still reads `dispatches` 0 beside a `held`
equal to its `poses`, and the two add up to `poses` in any frame.

`reusedSlices` is how many of the frame's poses took a slice the pool
already held — one a retired pose gave back, or one a pose nothing has
asked for this frame was holding — rather than one cut from pool the
engine had never used. A scene whose poses keep changing reads a non-zero
count beside a `poolBytes` that stays where it was.

`liveBytes` is what the slices holding this frame's poses occupy, against
`unsharedBytes` — what the same instances would occupy with a slice each.
`poolBytes` is what the pool holds; a previous-position buffer of the same
size rides alongside it so skinned deformation reaches motion vectors.

**Returns** `{ instances: number, poses: number, dispatches: number, held: number, reusedSlices: number, liveBytes: number, unsharedBytes: number, poolBytes: number }`

```lua
local s = renderer.skinningStats()
print(("%d instances over %d poses"):format(s.instances, s.poses))
print(("%d poses dispatched, %d read as they stood"):format(s.dispatches, s.held))
print(("skinned vertex storage: %d B of an unshared %d B"):format(s.liveBytes, s.unsharedBytes))
```

## typed/builtin//modules/api/engine/renderer/renderer/splat/components {#typed-builtin-modules-api-engine-renderer-renderer-splat-components}

```lua
renderer.splat.components(bytes: any?, convention: string?) -> (SplatComponents?, string?)
```

Decode a Gaussian splat capture — a Niantic `.spz` (gzipped or raw) or a
3DGS `.ply` — into the GPU-ready byte pools a render feature uploads.
`records` is the packed splat array at `recordBytes` per splat (position,
log scale, quaternion, DC colour + opacity); `sh` is the quantized
higher-order spherical-harmonics pool at `shStrideWords` u32 words per
splat, empty at degree 0. A pure decode (no GPU work): upload the pools with
`shaderRef:createBuffer` + `buf:writeBytes` and draw them with a
`kind = "splat"`, `channel = "gaussian"` pass.

**Parameters**

- `bytes` `any` _(optional)_ — Capture bytes — `.spz` or `.ply`, as a `buffer` or a binary string.
- `convention` `string` _(optional)_ — Source axis convention: `"rightDownFront"` (the default, what
COLMAP-trained captures use) or `"engineNative"` for a capture already in
engine space.

**Returns** `(SplatComponents?, string?)` — `{ records, sh, count, shDegree, shStrideWords, recordBytes, boundsMin?, boundsMax?, antialiased, format }`, or (nil, err).

```lua
local c = renderer.splat.components(vfs.readBytes("captures/ceramic.spz"))
```

## typed/builtin//modules/api/engine/renderer/renderer/spotShadowBudget {#typed-builtin-modules-api-engine-renderer-renderer-spotshadowbudget}

```lua
renderer.spotShadowBudget() -> SpotShadowBudget
```

The spot and area-light shadow atlas now in force. Each shadow-casting
spot is given a tile of it every frame, sized to what the camera can
resolve: a light filling the view gets a whole layer at `resolution`, one
far away gets a `minResolution` tile, and the atlas holds `tiles` of the
smallest kind. That is what lets one budget serve a close hero light and a
street of distant ones without either the memory or the sharpness being set
for the worst case.

**Returns** `SpotShadowBudget` — The atlas — see `SpotShadowBudget`.

```lua
local s = renderer.spotShadowBudget()
print(("%d layers of %d, %.1f MiB"):format(s.layers, s.resolution, s.bytes / 1024 / 1024))
```

## typed/builtin//modules/api/engine/renderer/renderer/temporal/held {#typed-builtin-modules-api-engine-renderer-renderer-temporal-held}

```lua
renderer.temporal.held() -> boolean
```

Whether a hold is pinning the per-frame clock right now.

**Returns** `boolean` — True while at least one `renderer.temporal.hold` stands.

```lua
if renderer.temporal.held() then print("frame is pinned") end
```

## typed/builtin//modules/api/engine/renderer/renderer/temporal/hold {#typed-builtin-modules-api-engine-renderer-renderer-temporal-hold}

```lua
renderer.temporal.hold(at: number?, options: TemporalHoldOptions?) -> () -> ()
```

Pin the clock every per-frame effect draws itself against, and return
the release. While the hold stands, `renderer.temporal.now` answers `at`
instead of the running clock, so film grain and every other field redrawn
each frame is redrawn as the same field. Two renders taken under holds at
the same instant therefore agree pixel for pixel wherever the scene itself
has not moved, which is what makes one frame comparable with another.
Holds nest: the innermost names the instant, and the clock runs again once
the last release is called. Each release takes its own hold off the stack
whatever order the releases come in, so two callers holding at once — two
captures in flight together — each end their own hold and the clock runs
again when both have.
`exclusive` takes the clock for the `owner` key the call states: while
that hold stands, a hold is admitted only when it states the same key, and
every other one is refused with an error naming the key and the instant
holding it. That is what lets one caller wind the clock to the second it
means to photograph and keep it there while another agent drives the same
engine. The key is what an owner presents to take a nested hold of its
own, and what `renderer.temporal.release` hands the clock back by. A
capture taken while the hold stands renders at the held instant; a
`deterministic` capture takes a hold of its own that states no key, so it
runs once the clock is handed back.

**Parameters**

- `at` `number` _(optional)_ — The instant to pin the clock at, in seconds. Two holds that state the
same instant produce the same field; the default 0 is that shared instant.
- `options` `TemporalHoldOptions` _(optional)_ — `owner` is the key this hold is taken under, and an exclusive
hold states one. A hold that states no key is labelled with the agent the
call is attributed to, which is the account the caller presented a token
for and is shared by every session driving this engine under it.
`exclusive` takes the clock for the stated key until the hold is released.

**Returns** `() -> ()` — A function that releases this hold. Calling it twice releases once.

```lua
local release = renderer.temporal.hold() ; local png = tools.use("capture", "fromPosition", { position = { 0, 2, 8 } }) ; release()
local release = renderer.temporal.hold(46.0, { exclusive = true, owner = "stage-air" })
```

## typed/builtin//modules/api/engine/renderer/renderer/temporal/now {#typed-builtin-modules-api-engine-renderer-renderer-temporal-now}

```lua
renderer.temporal.now() -> number
```

The instant a per-frame effect should draw itself at: the innermost
hold's instant while one stands, and seconds since boot otherwise. A
system that redraws a field every frame reads this rather than the running
clock, and a capture asking for a repeatable frame then gets one.

**Returns** `number` — Seconds — pinned while a hold stands, running otherwise.

```lua
local params = { grainTime = renderer.temporal.now() }
```

## typed/builtin//modules/api/engine/renderer/renderer/temporal/onChange {#typed-builtin-modules-api-engine-renderer-renderer-temporal-onchange}

```lua
renderer.temporal.onChange(listener: (number) -> ()) -> () -> ()
```

Register a listener called with the pinned instant whenever it changes
— a hold taken, a hold released — and return the unsubscribe. A system
whose shader reads the clock out of a GPU buffer registers here, so the
buffer carries the pinned instant before the frame that hold was taken on
is drawn rather than a frame later.

**Parameters**

- `listener` `(number) -> ()` — Called with the instant now in force, in seconds.

**Returns** `() -> ()` — A function that removes this listener.

```lua
local stop = renderer.temporal.onChange(function(t) pushClock(t) end)
```

## typed/builtin//modules/api/engine/renderer/renderer/temporal/owner {#typed-builtin-modules-api-engine-renderer-renderer-temporal-owner}

```lua
renderer.temporal.owner() -> { id: string?, name: string?, at: number, exclusive: boolean }?
```

The hold naming the instant the clock answers right now: who took it,
what instant it pinned, and whether it took the clock exclusively. Several
agents drive one engine at once and a hold any of them takes moves the
clock every registered field is redrawn against, so this is how a caller
sees that another agent holds it before its own instant is quietly
replaced — and, when `exclusive` is true, `id` is the key a hold of its
own states to be admitted, and the key `renderer.temporal.release` hands
the clock back by. `id` and `name` are nil for a hold that stated no key
and that the engine attributes to no agent.

**Returns** `{ id: string?, name: string?, at: number, exclusive: boolean }?` — `{ id, name, at, exclusive }` for the standing hold, or nil when the clock is running.

```lua
local who = renderer.temporal.owner()
if who ~= nil and who.exclusive then print(who.name, "holds the clock at", who.at) end
```

## typed/builtin//modules/api/engine/renderer/renderer/temporal/release {#typed-builtin-modules-api-engine-renderer-renderer-temporal-release}

```lua
renderer.temporal.release(owner: string) -> number
```

Hand the clock back by the key its holds were taken under, and report
how many came off. A hold stands until its release is called, and the
release is a closure the call that took the hold holds: a caller that
takes a hold in one call and comes back in another, and a task that ends
between the two, both leave the clock pinned with nobody holding a release
for it. Naming the key is how the clock runs again, and how a caller
refused by an exclusive hold takes one over.

**Parameters**

- `owner` `string` — The key the holds to release were taken under — what `owner`
stated when they were taken, which `renderer.temporal.owner` reports.

**Returns** `number` — How many holds came off the stack.

```lua
renderer.temporal.release("stage-air")
```

## typed/builtin//modules/api/engine/renderer/renderer/texture/capture {#typed-builtin-modules-api-engine-renderer-renderer-texture-capture}

```lua
renderer.texture.capture(texture: string | { [string]: any } | AssetRef) -> string
```

Request a CPU readback of the GPU texture `texture` names (e.g. a
camera's rendered output). Returns a result key to pass to a
TextureCpuHandle's `:encode()` once the readback completes. Takes every form
that names a texture — the `TextureHandle` `create` returned, the guid
`renderer.texture.list` hands out, a `TextureCpuHandle` or a texture
`AssetRef`.

**Parameters**

- `texture` `string | { [string]: any } | AssetRef` — The texture to read back — a `TextureHandle`, a guid, a
`TextureCpuHandle` or a texture `AssetRef`.

**Returns** string The capture result key.

```lua
local key = renderer.texture.capture(cameraTarget)
```

## typed/builtin//modules/api/engine/renderer/renderer/texture/cpuCreate {#typed-builtin-modules-api-engine-renderer-renderer-texture-cpucreate}

```lua
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.

**Parameters**

- `width` `number` — number Canvas width in pixels.
- `height` `number` — number Canvas height in pixels.
- `fill` `any` _(optional)_ — Optional `{ r, g, b, a }` (0-255) solid fill; defaults to opaque white.

**Returns** `TextureCpuHandle`

```lua
local c = renderer.texture.cpuCreate(1024, 576, { 255, 255, 255, 255 })
```

## typed/builtin//modules/api/engine/renderer/renderer/texture/cpuFromBytes {#typed-builtin-modules-api-engine-renderer-renderer-texture-cpufrombytes}

```lua
renderer.texture.cpuFromBytes(bytes: buffer | string, encodeOpts: any?) -> TextureCpuHandle
```

Load engine-native ZTEX bytes — or an encoded image (png / jpg / webp)
— into the CPU store under a fresh guid and answer the CPU handle, for
pixels that come from somewhere other than a texture asset: a `data.ztex`
read as a file, a payload held in memory. The pixels stay at the format
they were encoded in. DEFAULT: `handle:unload()` once done with them.

**Parameters**

- `bytes` `buffer | string` — The ZTEX or image bytes.
- `encodeOpts` `any` _(optional)_ — `{ format?, srgb?, generateMipmaps?, maxDimension? }` applied
when the bytes are an encoded image and need the engine-native encode.

**Returns** `TextureCpuHandle`

```lua
local cpu = renderer.texture.cpuFromBytes(vfs.read(path)); local png = cpu:encodePng(); cpu:unload()
```

## typed/builtin//modules/api/engine/renderer/renderer/texture/create {#typed-builtin-modules-api-engine-renderer-renderer-texture-create}

```lua
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?, format?}` (a
flat width*height*4 byte payload, 0-255, row-major, top-to-bottom, RGBA —
a `buffer`, a binary string, or a number array; `format = "rgba16f"`
uploads an HDR texture instead, where `rgba` carries float channel
values); a `TextureHandle` (returned as-is);
or render-target dimensions `{width, height, name?, format?}` with no pixel
source — an empty GPU texture a render pass writes into (camera output,
UI surface) and that samples like any other texture. `format` names the
colour format the target is allocated in, and the passes drawing into it
are built for that format: `"rgba8unorm"` / `"bgra8unorm"` (the two
eight-bit channel orders, either of which a surface may carry),
`"rgba16f"` / `"rgba32f"`, `"rg16f"` / `"rg32f"`, `"r16f"` / `"r32f"`.
Each also answers to its spelled-out width (`"rgba16float"`, `"r32float"`,
and so on), in any case. Omit it to take the surface's own. A float format
carries what eight bits quantize — positions, velocities, HDR. Any other
`format` raises an error naming every name that works, so a target is
allocated in the format it was asked for or not at all. A render target
takes `filter` the way raw pixels do: `"nearest"` keeps its own pixels square
wherever something draws it larger than it is — a viewport widget, a
magnified capture — which is what an image whose pixels ARE the subject
needs, since a 64x32 panel holds no detail between its pixels to
interpolate; `"linear"` (the default) smooths between them. It also
takes `screen` (the engine keeps it the size of the image being drawn),
`screenScale` (the fraction of that size it takes) and `screenSpace`
(`"scene"`, the default, or `"composite"` — the image the post-scene
phases draw into, which is the display's own resolution while the renderer
presents the viewport itself and the scene's size while a UI viewport panel
owns the presentation). A scene-space target is resized for every render
target drawn and cleared before an offscreen one; a composite-space target
follows the presented frame alone, which is what lets a pass keep an
accumulation in it. One scene-space `screen` target is therefore one
resource every render target draws through in turn, so its guid holds the
last one's image at the last one's size, and a value read back from it
belongs to whichever render target was drawn last. A reading that has to
be the viewport's own comes from `screenSpace = "composite"`, or from a
target created without `screen`. NEVER takes an AssetRef — load the CPU
first.

## typed/builtin//modules/api/engine/renderer/renderer/texture/createFromAsset {#typed-builtin-modules-api-engine-renderer-renderer-texture-createfromasset}

```lua
renderer.texture.createFromAsset(ref: string | AssetRef, encodeOpts: any?, keepCpu: boolean?) -> TextureHandle
```

Put a `.texture` asset on the GPU under its own guid and answer its
handle at once. The asset's bytes are decoded off the frame and the
texture lands on the device when the decode finishes, a frame or more
later: a material naming the guid draws the shader's default for that
slot until then and rebinds when it arrives, and
`renderer.texture.isResident` reports the arrival. The decoded pixels are
dropped once uploaded unless `keepCpu` holds them in the CPU store for
`textureRef:load()`-style reads. An asset the device already holds is
answered from the shape the device reports, without reading the asset's
bytes and without a second decode.

**Parameters**

- `ref` `string | AssetRef` — A texture `AssetRef`, or a string naming one (guid, identity, name
or source path).
- `encodeOpts` `any` _(optional)_ — `{ format?, srgb?, generateMipmaps?, maxDimension?, filter? }`
applied when the primary is an encoded source image and needs the
engine-native encode (a `.ztex` primary is decoded as-is).
- `keepCpu` `boolean` _(optional)_ — Keep the decoded pixels in the CPU store after the upload.

**Returns** `TextureHandle`

```lua
local h = renderer.texture.createFromAsset(texRef) -- bind h.guid on a material; it draws once resident
```

## typed/builtin//modules/api/engine/renderer/renderer/texture/decode {#typed-builtin-modules-api-engine-renderer-renderer-texture-decode}

```lua
renderer.texture.decode(bytes: buffer | string) -> (any, any, any, any)
```

Decode a texture payload to its pixel buffer. Takes the two shapes the
renderer's own texture loader takes, told apart by their leading bytes:

* an engine-native `ZTEX` payload — handed back at the texel format the
payload was written in, so a height field read back here keeps every bit
it was authored with. A `ZTEX` holding block-compressed or verbatim
source-image levels decodes to `"rgba8"`.
* source image bytes — png, jpeg, gif or webp, straight off disk or out of
a `capture` — decoded to `"rgba8"` at whatever colour type, bit depth or
interlacing the file was written with. This is the call that reads the
pixels of a screenshot.

The fourth return names the format the buffer came back in: `"rgba8"` (4
bytes/texel, channels 0-255), `"rgba16"` (8 bytes/texel, 16-bit unsigned
normalized channels 0-65535) or `"rgba32f"` (16 bytes/texel, float
channels).

**Parameters**

- `bytes` `buffer | string` — A `ZTEX` payload or source image bytes.

**Returns** `(any, any, any, any)` — `(string?, number?, number?, string?)` pixels, width, height, format — or (nil, errmsg) where errmsg is in the 2nd slot.

```lua
local pixels, w, h = renderer.texture.decode(vfs.read("/source/tmp/shot.png"))
```

## typed/builtin//modules/api/engine/renderer/renderer/texture/destroy {#typed-builtin-modules-api-engine-renderer-renderer-texture-destroy}

```lua
renderer.texture.destroy(texture: string | { [string]: any } | AssetRef) -> boolean
```

Release the GPU texture `texture` names. 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).
After this, `renderer.texture.list` stops answering for the guid. Takes
every form that names a texture — the `TextureHandle` `create` returned, the
guid the listing hands out, a `TextureCpuHandle` or a texture `AssetRef`.

**Parameters**

- `texture` `string | { [string]: any } | AssetRef` — The texture to release — a `TextureHandle`, a guid, a
`TextureCpuHandle` or a texture `AssetRef`.

**Returns** `boolean` true when a texture was known under the guid.

```lua
renderer.texture.destroy(rt)
renderer.texture.destroy(renderer.texture.list()[1].guid)
```

## typed/builtin//modules/api/engine/renderer/renderer/texture/encode {#typed-builtin-modules-api-engine-renderer-renderer-texture-encode}

```lua
renderer.texture.encode(rgba: any?, width: number, height: number, opts: any?) -> (string?, string?)
```

Encode raw pixels into an engine-native `ZTEX` payload (the on-disk
texture content). The CPU codec behind the texture assetType's `onCreate`.
`opts.format` selects the on-disk precision: `"rgba8"` / `"srgb"` (default,
8 bits/channel, `rgba` is width*height*4 bytes) or the high-precision data
formats `"rgba16"` (16-bit unsigned normalized, width*height*8 bytes) /
`"rgba32f"` (32-bit float, width*height*16 bytes) — for height/displacement
fields, baked lightmaps, and other data rasters an 8-bit format quantizes
visibly. The two high-precision formats store `rgba` verbatim and reject
`opts.generateMipmaps` / `opts.maxDimension`.

**Parameters**

- `rgba` `any` _(optional)_ — Pixel payload at `opts.format`'s native byte width — a `buffer`, a binary string, or a number array.
- `width` `number` — number
- `height` `number` — number
- `opts` `any` _(optional)_ — `{ format?, srgb?, generateMipmaps?, maxDimension? }`

**Returns** `(string?, string?)` ZTEX bytes, or (nil, errmsg).

## typed/builtin//modules/api/engine/renderer/renderer/texture/encodeFromImage {#typed-builtin-modules-api-engine-renderer-renderer-texture-encodefromimage}

```lua
renderer.texture.encodeFromImage(bytes: buffer | 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`.

**Parameters**

- `bytes` `buffer | string` — source image bytes.
- `opts` `any` _(optional)_ — `{ format?, srgb?, generateMipmaps?, maxDimension? }`

**Returns** `(string?, string?)` ZTEX bytes, or (nil, errmsg).

## typed/builtin//modules/api/engine/renderer/renderer/texture/frameSchedule {#typed-builtin-modules-api-engine-renderer-renderer-texture-frameschedule}

```lua
renderer.texture.frameSchedule(texture: string | AssetRef) -> { number }?
```

The times at which each layer of a timed texture stops being shown,
in seconds from the start of the sequence — the running total of the layer
display times, so the last entry is the length of one pass.

This is the form a sampler reads a sequence through: a time is turned into
a layer by finding the first entry it has not passed, whatever the
individual layer times are. It is what the `schedule` slot of the builtin
`animatedTexture` shader holds, one entry per layer.

A texture whose layers carry no timing — a still image, a sprite sheet, a
LUT stack — has no schedule and answers nil.

**Parameters**

- `texture` `string | AssetRef` — The texture — a guid, an identity, a name, a path, or a texture `AssetRef`.

**Returns** `{ number }?` one cumulative end time per layer, or nil.

```lua
local ends = renderer.texture.frameSchedule(texRef) -- {0.1, 0.15, 0.35}
```

## typed/builtin//modules/api/engine/renderer/renderer/texture/info {#typed-builtin-modules-api-engine-renderer-renderer-texture-info}

```lua
renderer.texture.info(ztex: buffer | string) -> (any, any)
```

Read the header of an engine-native `ZTEX` payload without copying the
pixels. Returns its format, dimensions, mip count, `filter` ("nearest"
or "linear" — the sampler baked into the blob from the asset's
`settings.filter`), and the payload's layer shape.

`layers` counts the array layers the payload carries and `isArray` is true
past one — the answer to "am I about to sample a `texture_2d_array`?",
available before anything samples it. `animated` is true when those layers
are a sequence in time; then `frameDelaysMs` lists each layer's display
time in milliseconds in display order, and `durationMs` totals one pass.
An animated image imports as one layer per frame, so `layers` is its frame
count. A still texture reports `layers = 1`, `isArray = false`.

**Parameters**

- `ztex` `buffer | string` — ZTEX bytes.

**Returns** `(any, any)` — `(table?, string?)` `{ format, width, height, mipCount, filter, layers, isArray, animated, frameDelaysMs?, durationMs? }`, or (nil, errmsg).

```lua
local i = renderer.texture.info(bytes); if i.animated then print(i.layers, "frames", i.durationMs, "ms") end
```

## typed/builtin//modules/api/engine/renderer/renderer/texture/isResident {#typed-builtin-modules-api-engine-renderer-renderer-texture-isresident}

```lua
renderer.texture.isResident(texture: string | { [string]: any } | AssetRef) -> boolean
```

True if a GPU texture is resident under this texture's guid.

**Parameters**

- `texture` `string | { [string]: any } | AssetRef` — The texture — a `TextureHandle`, a `TextureCpuHandle`, a guid, or a texture `AssetRef`.

**Returns** `boolean`

```lua
print(renderer.texture.isResident(handle))
```

## typed/builtin//modules/api/engine/renderer/renderer/texture/list {#typed-builtin-modules-api-engine-renderer-renderer-texture-list}

```lua
renderer.texture.list() -> { any }
```

Every texture currently registered, ordered by guid — the ones a script
created and the ones that reached the device through an asset alike. Each
entry carries the guid, where it came from (`origin` is `"asset"` for a
texture the asset path uploaded), and whether the GPU still holds it. A
resident entry also carries the bytes it costs, its dimensions and its
texel format, so the listing sums to `renderer.textureMemory()`. A
streamable one carries `streamOrigin` — `"asset"` when a level change reads
the levels it needs back from the asset, `"retained"` when the cache holds
the pixels for it.
A script-created entry also carries `held` — whether `renderer.hold` pins
it for the session — and `scene`, the load that created it.
`renderer.references("texture", guid)` says what is still holding a row,
and `renderer.collect()` releases the rows nothing holds.

## typed/builtin//modules/api/engine/renderer/renderer/texture/loadCpu {#typed-builtin-modules-api-engine-renderer-renderer-texture-loadcpu}

```lua
renderer.texture.loadCpu(ref: string | AssetRef, 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, dims and texel
format plus the read/write/encode/unload ops (which read the Rust store).
The pixels stay at the format they were authored in: `handle.format` is
`"rgba8"`, `"rgba16"` or `"rgba32f"`, and `:readPixel` reports channels in
that format's own units. Called by `texRef:load()`. DEFAULT: upload to the
GPU then `handle:unload()`.

**Parameters**

- `ref` `string | AssetRef` — A texture `AssetRef` (carries `.guid`, reads its primary via getBytes),
or any string `asset.ref` resolves to one — a guid, an identity, a name or a
source path.
- `encodeOpts` `any` _(optional)_ — `{ format?, srgb?, generateMipmaps?, maxDimension? }` applied
when the primary is an encoded source image and needs the engine-native
encode (a `.ztex` primary is loaded as-is).

**Returns** `TextureCpuHandle`

```lua
local cpu = texRef:load(); local r,g,b,a = cpu:readPixel(3, 4); cpu:unload()
```

## typed/builtin//modules/api/engine/renderer/renderer/texture/readback {#typed-builtin-modules-api-engine-renderer-renderer-texture-readback}

```lua
renderer.texture.readback(texture: string | { [string]: any } | AssetRef) -> 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 the
texture never becomes GPU-resident.

A SCENE-space `screen`-sized render target is one resource shared by every
render target drawn — the viewport, an offscreen capture, a camera
rendering into a texture — resized and re-derived for each of them in
turn. The copy is taken ahead of all of them for the frame, so what a
readback of its guid answers is the content of the last frame the renderer
drew: the presented view's own image at the presented resolution, since
the presented view is the sink that draws last. A request made while the
renderer is holding frames back is carried to the next frame it draws
rather than being answered from a target another sink left standing, so a
readback can wait a frame longer than the copy itself takes.

**Parameters**

- `texture` `string | { [string]: any } | AssetRef` — The texture — the `TextureHandle` `renderer.texture.create` returned, a guid, or a texture `AssetRef`.

**Returns** `TextureCpuHandle`

```lua
local cpu = renderer.texture.readback(handle); local ztex = cpu:encode(); cpu:unload()
```

## typed/builtin//modules/api/engine/renderer/renderer/texture/tone {#typed-builtin-modules-api-engine-renderer-renderer-texture-tone}

```lua
renderer.texture.tone(histogram: any?) -> TextureTone
```

Reduce a histogram to what the picture's tone IS: where its darkest and
brightest pixels sit, where the body of it sits, and how much of it is
standing on the floor or the ceiling — all in code values on the 0-255
scale the pixels were delivered at.

`span` (`max - min`) is the whole range including a single stray pixel;
`spread` (`p95 - p5`) is the range the body of the picture occupies, which
is the reading that says whether a shot is legible. A frame whose subject is
modelled and shaded but delivered inside a few code values reads a large
`mean` and a tiny `spread`, and no mean alone can tell that apart from a
frame with a subject in it.

`crushed` and `clipped` are the shares of the picture at code 0 and at code
255, each 0..1 — what a shot loses to the floor and to the ceiling.

**Parameters**

- `histogram` `any` _(optional)_ — A histogram from `cpu:histogram()`.

**Returns** `TextureTone`

```lua
local t = cpu:tone(); if t.spread < 24 then error("the shot is flat") end
```

## typed/builtin//modules/api/engine/renderer/renderer/texture/update {#typed-builtin-modules-api-engine-renderer-renderer-texture-update}

```lua
renderer.texture.update(texture: string | { [string]: any } | AssetRef, src: any?) -> TextureHandle
```

Overwrite the GPU texture `texture` names IN PLACE, under the same guid,
from new raw pixels. Never writes a `.texture` file — the play-mode mutate
path. Takes every form that names a texture — the `TextureHandle` `create`
returned, the guid `renderer.texture.list` hands out, a `TextureCpuHandle`
or a texture `AssetRef`. Returns a handle carrying the new dimensions: the
handle it was given, refreshed, and a handle over the guid otherwise.

**Parameters**

- `texture` `string | { [string]: any } | AssetRef` — The texture to update — a `TextureHandle`, a guid, a
`TextureCpuHandle` or a texture `AssetRef`.
- `src` `any` _(optional)_ — New raw pixels `{rgba, width, height, srgb?, format?}` — `rgba` as a
`buffer`, a binary string, or a number array.

**Returns** `TextureHandle` — A `TextureHandle` for the updated texture.

## typed/builtin//modules/api/engine/renderer/renderer/textureMemory {#typed-builtin-modules-api-engine-renderer-renderer-texturememory}

```lua
renderer.textureMemory() -> {
```

What the GPU texture cache holds, split by whether the texture is
block-compressed. `compressedBytes` and `uncompressedBytes` are what those
textures cost in VRAM, measured from each texture's own format and mip
chain — so a `.texture` whose settings name `format = "bc7"` appears in the
compressed columns at a quarter of what the same image costs as RGBA8.
`blockCompressionSupported` is whether this adapter can hold
block-compressed textures at all; where it is false a BC7 payload is
uploaded decoded and lands in the uncompressed columns instead, so the
texture is present everywhere and compressed where the hardware allows it.
Measured at the end of the last rendered frame.
`streamableTextures` is how many of them a texture budget can move the
base mip level of, split by where a level change reads the levels it needs
from: `assetStreamedTextures` are read back from the asset they came from
and hold nothing in system memory, `retainedTextures` hold the payload
because a script uploaded their pixels and the GPU copy is the only other
one there is. `streamSourceBytes` is what those held payloads occupy in
system memory — bytes that are not VRAM — so it is a reading on the
retained half alone. `pinnedTextures` counts the textures big enough to
stream that stand at a level nothing can move: their pixels were released
and no asset holds them, the asset behind them could not be read back, or a
UI image, a post-process property or a render feature holds a view of them.
A texture out of the streamable set only because no measured surface wears
it stands in neither count: a surface reaching it takes it back up, so its
level moves again as soon as there is a footprint to move it by. It reads 0
while no budget is armed.

**Returns** `{ blockCompressionSupported, compressedTextures, compressedBytes, uncompressedTextures, uncompressedBytes, streamableTextures, assetStreamedTextures, retainedTextures, pinnedTextures, streamSourceBytes }`

```lua
local tm = renderer.textureMemory()
print(("%d compressed textures hold %.1f MiB"):format(tm.compressedTextures, tm.compressedBytes / 1048576))
print(("%d textures stream from their asset, %d hold %.1f MiB of pixels"):format(
tm.assetStreamedTextures, tm.retainedTextures, tm.streamSourceBytes / 1048576))
```

## typed/builtin//modules/api/engine/renderer/renderer/textureStreaming {#typed-builtin-modules-api-engine-renderer-renderer-texturestreaming}

```lua
renderer.textureStreaming() -> TextureStreaming
```

What the last frame's texture-residency plan decided. `budgetBytes` is
the armed budget, and `0` means residency is left alone. `streamable` is
how many textures the plan can move. `residentBytes` is what those textures
occupy now, measured from the textures that are allocated; `demandedBytes`
is what the frame's demand alone would have cost, so the two part exactly
where the budget is doing something. `starved` counts the textures left
coarser than the frame asked for, `promoted` the ones that climbed a level
this frame, and `changed` the ones whose GPU texture was replaced. A camera
approaching a surface reads `promoted` above zero for a few frames and then
zero once it settles.

`textures` is one row per streamable texture, ordered by key, carrying the
level each one was asked for and the measurement that asked. Two byte
totals can agree while a single texture sits several levels off what its
surface samples, so read the row when the question is which level a texture
holds and why.

With `budgetBytes` at 0 nothing holds a level back, so `residentBytes`,
`plannedBytes` and `demandedBytes` all read the whole chain of every
texture still enrolled and `textures` is empty — which is how a session
that armed a budget and dropped it reads back that the levels came home.

**Returns** `TextureStreaming` — `{ budgetBytes, streamable, residentBytes, plannedBytes, demandedBytes, starved, promoted, changed, textures }`

```lua
local ts = renderer.textureStreaming()
print(("textures: %.1f MiB resident of %.1f MiB demanded, %d starved"):format(
ts.residentBytes / 1048576, ts.demandedBytes / 1048576, ts.starved))
```

## typed/builtin//modules/api/engine/renderer/renderer/transmissionShadows {#typed-builtin-modules-api-engine-renderer-renderer-transmissionshadows}

```lua
renderer.transmissionShadows() -> boolean
```

Whether translucent casters tint the directional light they block.

**Returns** `boolean`

## typed/builtin//modules/api/engine/renderer/renderer/uploadStats {#typed-builtin-modules-api-engine-renderer-renderer-uploadstats}

```lua
renderer.uploadStats() -> {
```

What the last completed frame spent re-describing its renderables to the
GPU. Every renderable owns a slot in the per-instance data a draw reads —
its world matrix, the bounds the culler tests it by, and the flags that
decide which passes and which culling stages see it — and a frame uploads
only the slots whose contents changed. `bytes` is what those uploads
carried, `fullBytes` what re-sending every slot would have cost, and
`writes` how many buffer writes carried it. The three numbers cover that
per-renderable data alone, so a scene standing still reads `bytes = 0`
against a `fullBytes` that grows with the scene, and the ratio says how much
of it the scene's own churn — rather than its size — is paying for.

**Returns** `{ writes: number, bytes: number, fullBytes: number }`

```lua
local u = renderer.uploadStats()
print(("instance upload: %d B of %d B in %d writes"):format(u.bytes, u.fullBytes, u.writes))
```

## typed/builtin//modules/api/engine/renderer/renderer/variantSource {#typed-builtin-modules-api-engine-renderer-renderer-variantsource}

```lua
renderer.variantSource(program: string) -> string?
```

The WGSL one of the programs `renderer.shaderVariants()` lists holds,
exactly as the shader compiler received it. `program` is the `program`
field of a row's `base` or of one of its `variants`. Reading a base
alongside a variant shows what a feature set selected: each program's text
holds the code its own features guard. The variant-report spelling of
`renderer.compiledSource`, which answers the same for every other shader.

**Parameters**

- `program` `string` — A `program` name from `renderer.shaderVariants()`.

**Returns** `string?` — The compiled WGSL, or nil for a name no compile has run under.

```lua
local row = renderer.shaderVariants()[1]
local base = renderer.variantSource(row.base.program)
```

## typed/builtin//modules/api/engine/retarget/retarget/animation {#typed-builtin-modules-api-engine-retarget-retarget-animation}

```lua
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.

**Parameters**

- `clipRef` `any` _(optional)_ — Animation asset to retarget.
- `targetMeshRef` `any` _(optional)_ — Target rig mesh whose skin defines the destination skeleton.
- `sourceMeshRef` `any` _(optional)_ — Source rig mesh the clip was authored for; omit to use the clip's embedded rig.

**Returns** `(boolean, string)` — Success flag and the retargeted clip's VFS path (empty on failure).

```lua
local ok, path = retarget.animation(clipRef, targetMeshRef)
```

## typed/builtin//modules/api/engine/retarget/retarget/extractRig {#typed-builtin-modules-api-engine-retarget-retarget-extractrig}

```lua
retarget.extractRig(meshBytes: buffer | 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.

**Parameters**

- `meshBytes` `buffer | string` — Raw ZMSH mesh bytes carrying a skin.

**Returns** `string?` — Skin-only ZMSH rig bytes, or nil when the mesh has no skin.

```lua
local rig = retarget.extractRig(meshBytes)
```

## typed/builtin//modules/api/engine/retarget/retarget/humanoidProfile {#typed-builtin-modules-api-engine-retarget-retarget-humanoidprofile}

```lua
retarget.humanoidProfile(meshBytes: buffer | 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. A rig whose bone hierarchy loops answers nil and a
message naming the bone edge that closes the loop, so a caller reading the
second return value can tell malformed input from a plain non-humanoid.

**Parameters**

- `meshBytes` `buffer | string` — Raw ZMSH mesh bytes carrying a skin.

**Returns** `HumanoidHolder?` — `{ base, boneCount, roles = { [role] = boneName } }`, or nil when the rig is not a humanoid; nil and a message naming the closing bone edge when its hierarchy loops.

```lua
local holder = retarget.humanoidProfile(meshBytes)
```

## typed/builtin//modules/api/engine/retarget/retarget/isHumanoid {#typed-builtin-modules-api-engine-retarget-retarget-ishumanoid}

```lua
retarget.isHumanoid(meshBytes: buffer | 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.

**Parameters**

- `meshBytes` `buffer | string` — Raw ZMSH mesh bytes carrying a skin.

**Returns** `boolean` — True when the rig has the essential humanoid structure.

```lua
if retarget.isHumanoid(meshBytes) then ... end
```

## typed/builtin//modules/api/engine/retarget/retarget/serializeProfile {#typed-builtin-modules-api-engine-retarget-retarget-serializeprofile}

```lua
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.

**Parameters**

- `holder` `HumanoidHolder` — A holder from `humanoidProfile`.

**Returns** `string` — The YAML body to store as `humanoid.profile`.

```lua
files["humanoid.profile"] = retarget.serializeProfile(holder)
```

## typed/builtin//modules/api/engine/runtime_participation/M/isSaved {#typed-builtin-modules-api-engine-runtime-participation-m-issaved}

```lua
M.isSaved(mode: string) -> boolean
```

Whether an entity with this mode is written to the persisted world.
True for WorldEntity, PrototypeOnly, and EditorOnly; false for RuntimeOnly.

**Parameters**

- `mode` `string` — A RuntimeParticipation mode string.

**Returns** `boolean` — true when the mode is persisted on scene save.

## typed/builtin//modules/api/engine/runtime_participation/M/liveInEdit {#typed-builtin-modules-api-engine-runtime-participation-m-liveinedit}

```lua
M.liveInEdit(mode: string) -> boolean
```

Whether an entity with this mode is live while authoring in edit mode.
True for WorldEntity, PrototypeOnly, and EditorOnly; false for RuntimeOnly.

**Parameters**

- `mode` `string` — A RuntimeParticipation mode string.

**Returns** `boolean` — true when the mode is present in edit mode.

## typed/builtin//modules/api/engine/runtime_participation/M/liveInPlay {#typed-builtin-modules-api-engine-runtime-participation-m-liveinplay}

```lua
M.liveInPlay(mode: string) -> boolean
```

Whether an entity with this mode is live during play.
True for WorldEntity and RuntimeOnly; false for PrototypeOnly and EditorOnly.

**Parameters**

- `mode` `string` — A RuntimeParticipation mode string.

**Returns** `boolean` — true when the mode is present in play mode.

## typed/builtin//modules/api/engine/runtime_participation/M/modeOf {#typed-builtin-modules-api-engine-runtime-participation-m-modeof}

```lua
M.modeOf(entityId: string) -> string
```

The entity's RuntimeParticipation mode. Defaults to "WorldEntity".

**Parameters**

- `entityId` `string` — Entity id to read.

**Returns** `string` — One of "WorldEntity" / "PrototypeOnly" / "EditorOnly" / "RuntimeOnly".

## typed/builtin//modules/api/engine/runtime_participation/M/set {#typed-builtin-modules-api-engine-runtime-participation-m-set}

```lua
M.set(entityId: string, mode: string)
```

Sets the RuntimeParticipation mode on an entity. A mode that is not
saved marks the entity temporary so the scene-save exclusion drops it.

## typed/builtin//modules/api/engine/runtime_participation/M/standsDown {#typed-builtin-modules-api-engine-runtime-participation-m-standsdown}

```lua
M.standsDown(mode: string, engineMode: string) -> boolean
```

Whether an entity with this mode stands down — stops rendering and
ticking — when an EDITOR session is in `engineMode`. This is the question a
mode flip actually asks, and it is not `liveInPlay`: that answers which
entities a SHIPPED RUNTIME contains, where there is no authoring surface at
all. A session able to flip modes is an editor session by construction (the
runtime profile forbids mode swaps), so the editor's own cameras, panels and
gizmos are present in both of its modes and stand down in neither. What
stands down in play is a template, whose clones are what runs; what stands
down in edit is a runtime entity.

**Parameters**

- `mode` `string` — A RuntimeParticipation mode string.
- `engineMode` `string` — The engine mode the session is in, "play" or "edit".

**Returns** `boolean` — true when the mode should not be participating in that mode.

```lua
if rp.standsDown(entity(id).participation, tostring(engine.mode)) then ... end
```

## typed/builtin//modules/api/engine/service/service/authenticated {#typed-builtin-modules-api-engine-service-service-authenticated}

```lua
service.authenticated() -> boolean
```

Whether a platform identity (JWT) is available to attach to
service calls. Returns only a boolean — never the token.

**Returns** `boolean` — True if a caller identity is available.

```lua
if not service.authenticated() then error("link ZeroMind") end
```

## typed/builtin//modules/api/engine/service/service/balance {#typed-builtin-modules-api-engine-service-service-balance}

```lua
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.

**Returns** `string?` — Promise handle for `task.await()`, or nil if not ready.

```lua
local h = service.balance(); local raw = h and task.await(h)
```

## typed/builtin//modules/api/engine/service/service/gatewayConfigured {#typed-builtin-modules-api-engine-service-service-gatewayconfigured}

```lua
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.

**Returns** `boolean` — True if the gateway base URL is set.

```lua
if not service.gatewayConfigured() then error("no gateway") end
```

## typed/builtin//modules/api/engine/service/service/invoke {#typed-builtin-modules-api-engine-service-service-invoke}

```lua
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.

**Parameters**

- `offering` `string` — Fully-qualified offering identity `provider/name` (e.g. "origozero/mesh_gen").
- `endpoint` `string` — Logical endpoint name (e.g. "create_preview").
- `opts` `InvokeOpts` _(optional)_ — `{ params?, headers?, body?, idempotency_key? }`.

**Returns** `string?` — Promise handle for `task.await()`, or nil if not ready.

```lua
local h = service.invoke("origozero/mesh_gen", "create_preview", { body = { prompt = p } })
```

## typed/builtin//modules/api/engine/service/service/jobStatus {#typed-builtin-modules-api-engine-service-service-jobstatus}

```lua
service.jobStatus(jobId: string) -> string?
```

Poll a submitted service job. Returns a promise handle for
`task.await()` resolving the JobStatusResponse JSON `{ job_id, status,
result?, error? }`: `status` walks `pending`/`running` -> `succeeded`
(with `result`, the same InvokeResponse `invoke` returns) or `failed`
(with `error`). nil when the gateway is unconfigured or no caller
identity is available.

**Parameters**

- `jobId` `string` — Job id returned by `submitJob`.

**Returns** `string?` — Promise handle resolving the job status JSON, or nil if not ready.

```lua
local h = service.jobStatus(jobId); local raw = h and task.await(h)
```

## typed/builtin//modules/api/engine/service/service/submitJob {#typed-builtin-modules-api-engine-service-service-submitjob}

```lua
service.submitJob(offering: string, endpoint: string, opts: InvokeOpts?) -> string?
```

Submit a durable async invocation of an offering endpoint. Same
arguments as `invoke`, but the provider round-trip runs server-side
(off this connection), so a slow synchronous provider or a dropped
link no longer loses the result. Returns a promise handle for
`task.await()` resolving `{ job_id, status }`; poll it with
`jobStatus`. nil when the gateway is unconfigured or no caller
identity is available.

**Parameters**

- `offering` `string` — Fully-qualified offering identity `provider/name` (e.g. "origozero/mesh_gen").
- `endpoint` `string` — Logical endpoint name (e.g. "create_preview").
- `opts` `InvokeOpts` _(optional)_ — `{ params?, headers?, body?, idempotency_key? }`.

**Returns** `string?` — Promise handle resolving `{ job_id, status }`, or nil if not ready.

```lua
local h = service.submitJob("origozero/mesh_gen", "create_preview", { body = { prompt = p } })
```

## typed/builtin//modules/api/engine/shader/shader/compile {#typed-builtin-modules-api-engine-shader-shader-compile}

```lua
shader.compile(keys: string | { string }, opts: { [string]: any }) -> boolean
```

Compile a zero-scaffolding SURFACE shader: the author wrote only
`vertex()` / `fragment()` and declared its material properties, and the
engine generates the group(1) material interface plus every render-mode
entry point. Compiles once and registers the result under every key.

**Parameters**

- `keys` `string | { string }` — One registration key, or the array of keys (guid, identity,
aliases) the one compiled program answers to.
- `opts` `{ [string]: any }` — `{ source, domain?, properties? }` — the author's WGSL, its
`@domain`, and the declared property schema.

**Returns** `boolean` — True when the compile was queued.

```lua
shader.compile({ ref.guid, ref.identity }, { source = wgsl, properties = props })
```

## typed/builtin//modules/api/engine/shader/shader/registerModule {#typed-builtin-modules-api-engine-shader-shader-registermodule}

```lua
shader.registerModule(keys: string | { string }, source: string) -> boolean
```

Register a block of WGSL other shaders include. Every key names the same
source, so a shader includes it by whichever name it holds — its guid, its
identity, or an alias. Registering again replaces it, and the shaders that
include it recompile.

**Parameters**

- `keys` `string | { string }` — One key, or the array of keys this module answers to.
- `source` `string` — The module's WGSL.

**Returns** `boolean` — True when the registration was queued.

```lua
shader.registerModule({ ref.guid, ref.identity }, wgsl)
```

## typed/builtin//modules/api/engine/shader/shader/status {#typed-builtin-modules-api-engine-shader-shader-status}

```lua
shader.status(name: string) -> (string, string?)
```

A shader's latest compile outcome, without reading the engine log:
`"compiled"`, `"failed"` (with the compiler error second), or `"pending"`.
Compilation is async, so a `"pending"` straight after a write means ask
again next frame.

**Parameters**

- `name` `string` — Shader identity or guid — the key it compiled under.

**Returns** `(string, string?)` — Status, and the compiler error when it failed.

```lua
local status, err = shader.status(ref.guid)
```

## typed/builtin//modules/api/engine/shell/shell/run {#typed-builtin-modules-api-engine-shell-shell-run}

```lua
shell.run(command: string) -> ShellResult
```

Execute a command in the engine's emulated Unix shell and
return once it has completed. This is the same shell as the MCP
`bash` tool — 60+ builtins (ls, cat, grep, find, echo, ...)
operating on the virtual scene filesystem. A command that runs
Luau (`run`, `luau`, `zm`, `zero`) needs the engine's frame loop,
so from a coroutine it is queued to run off the frame loop and
this yields until it finishes; everything else runs inline. That
queueing runs the whole line, so a line that also ran a command
of its own comes back with the explanation in `stderr` and
`shell.runAsync` as the way to run it whole.

**Parameters**

- `command` `string` — Shell command to execute.

**Returns** `ShellResult` — Command result `{ stdout, stderr, exitCode, ok }`.

```lua
local r = shell.run("ls /zero/source")
```

## typed/builtin//modules/api/engine/shell/shell/runAsync {#typed-builtin-modules-api-engine-shell-shell-runasync}

```lua
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()`.

**Parameters**

- `command` `string` — Shell command to execute.

**Returns** `string` — Promise ID — pass to `task.await()` to get the JSON result.

```lua
local json = task.await(shell.runAsync("find /zero -name '*.luau'"))
```

## typed/builtin//modules/api/engine/skeleton/skeleton/applyPose {#typed-builtin-modules-api-engine-skeleton-skeleton-applypose}

```lua
skeleton.applyPose(sinkHandle: number, poseBuffer: Substrate.TypedBuffer) -> 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.

**Parameters**

- `sinkHandle` `number` — Sink handle from `bindPose`.
- `poseBuffer` `Substrate.TypedBuffer` — The pose buffer to apply.

**Returns** `boolean` — True on success.

## typed/builtin//modules/api/engine/skeleton/skeleton/bindClip {#typed-builtin-modules-api-engine-skeleton-skeleton-bindclip}

```lua
skeleton.bindClip(zanimBytes: buffer | 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.

**Parameters**

- `zanimBytes` `buffer | string` — The clip's `data.zanim` payload bytes (binary-safe).
- `boneOrder` `{ string }` — Output bone names — one stride-10 record per bone.

**Returns** `ClipBindInfo?` — `{ handle, matched, total, duration }`, or nil.

## typed/builtin//modules/api/engine/skeleton/skeleton/bindPose {#typed-builtin-modules-api-engine-skeleton-skeleton-bindpose}

```lua
skeleton.bindPose(entityId: (string | entityRef)?, 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.

**Parameters**

- `entityId` `(string | entityRef)` _(optional)_ — Engine entity id or proxy, or nil for the current entity.
- `opts` `SkeletonLayout` — `{ boneOrder, stride }`.

**Returns** `number?` — Sink handle, or nil.

```lua
local h = skeleton.bindPose(nil, { boneOrder = bones, stride = 10 })
```

## typed/builtin//modules/api/engine/skeleton/skeleton/clipBones {#typed-builtin-modules-api-engine-skeleton-skeleton-clipbones}

```lua
skeleton.clipBones(zanimBytes: buffer | 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.

**Parameters**

- `zanimBytes` `buffer | string` — The clip's `data.zanim` payload bytes (binary-safe).

**Returns** `{ string }?` — Bone names referenced by the clip, or nil.

```lua
local names = skeleton.clipBones(vfs.read(path .. "/data.zanim"))
```

## typed/builtin//modules/api/engine/skeleton/skeleton/clipDecode {#typed-builtin-modules-api-engine-skeleton-skeleton-clipdecode}

```lua
skeleton.clipDecode(zanimBytes: buffer | 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`.

**Parameters**

- `zanimBytes` `buffer | string` — The clip's `data.zanim` payload bytes (binary-safe).

**Returns** `string?` — The clip as a JSON string, or nil.

```lua
local clip = json.decode(skeleton.clipDecode(bytes))
```

## typed/builtin//modules/api/engine/skeleton/skeleton/clipEncode {#typed-builtin-modules-api-engine-skeleton-skeleton-clipencode}

```lua
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.

**Parameters**

- `jsonString` `string` — A clip JSON document.

**Returns** `string?` — The clip's `zanim` payload bytes, or nil.

```lua
local bytes = skeleton.clipEncode(json.encode(clip))
```

## typed/builtin//modules/api/engine/skeleton/skeleton/jointTransforms {#typed-builtin-modules-api-engine-skeleton-skeleton-jointtransforms}

```lua
skeleton.jointTransforms(entityId: string | entityRef) -> table
```

Read a skinned entity's per-joint world transforms for the
current animated pose.

**Parameters**

- `entityId` `string | entityRef` — Engine entity id or proxy of a skinned entity.

**Returns** `table` — Array of joint transforms: `{ position, matrix, parent, name }`.

```lua
local joints = skeleton.jointTransforms(meshId)
```

## typed/builtin//modules/api/engine/skeleton/skeleton/sampleClip {#typed-builtin-modules-api-engine-skeleton-skeleton-sampleclip}

```lua
skeleton.sampleClip(handle: number, time: number, poseBuffer: Substrate.TypedBuffer) -> 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.

**Parameters**

- `handle` `number` — Sampler handle from `bindClip`.
- `time` `number` — Sample time in seconds.
- `poseBuffer` `Substrate.TypedBuffer` — The stride-10 pose buffer written into.

**Returns** `boolean` — True on success.

## typed/builtin//modules/api/engine/skeleton/skeleton/unbindClip {#typed-builtin-modules-api-engine-skeleton-skeleton-unbindclip}

```lua
skeleton.unbindClip(handle: number) -> boolean
```

Drop the bound clip sampler from the registry.

**Parameters**

- `handle` `number` — Sampler handle to remove.

**Returns** `boolean` — True if the sampler existed.

## typed/builtin//modules/api/engine/skeleton/skeleton/unbindPose {#typed-builtin-modules-api-engine-skeleton-skeleton-unbindpose}

```lua
skeleton.unbindPose(sinkHandle: number) -> boolean
```

Remove the sink from the registry.

**Parameters**

- `sinkHandle` `number` — Sink handle to remove.

**Returns** `boolean` — True if the sink was present.

## typed/builtin//modules/api/engine/sky/sky/get {#typed-builtin-modules-api-engine-sky-sky-get}

```lua
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]`.

## typed/builtin//modules/api/engine/sky/sky/getTimeOfDay {#typed-builtin-modules-api-engine-sky-sky-gettimeofday}

```lua
sky.getTimeOfDay() -> number
```

Get the current time of day in hours (0-24).

**Returns** `number` — Current time of day.

```lua
local t = sky.getTimeOfDay()
```

## typed/builtin//modules/api/engine/sky/sky/preset {#typed-builtin-modules-api-engine-sky-sky-preset}

```lua
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.

**Parameters**

- `name` `string` — Preset name (case-sensitive).

```lua
sky.preset("sunset")
```

## typed/builtin//modules/api/engine/sky/sky/set {#typed-builtin-modules-api-engine-sky-sky-set}

```lua
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`.

## typed/builtin//modules/api/engine/sky/sky/setSunDirection {#typed-builtin-modules-api-engine-sky-sky-setsundirection}

```lua
sky.setSunDirection(dir: SkyColor)
```

Set an explicit sun direction and disable time-based sun
positioning. The directional light is updated to match.

**Parameters**

- `dir` `SkyColor` — Normalized sun direction vector.

```lua
sky.setSunDirection({ 0.5, -1, 0.3 })
```

## typed/builtin//modules/api/engine/sky/sky/setTimeOfDay {#typed-builtin-modules-api-engine-sky-sky-settimeofday}

```lua
sky.setTimeOfDay(time: number)
```

Set the time of day (0-24 hours). 0 = midnight, 6 = sunrise,
12 = noon, 18 = sunset.

**Parameters**

- `time` `number` — Time of day in hours.

```lua
sky.setTimeOfDay(18.5)
```

## typed/builtin//modules/api/engine/stream/stream/accept {#typed-builtin-modules-api-engine-stream-stream-accept}

```lua
stream.accept(listener: string) -> string?
```

Take the connection that has waited longest on the listener, as a
stream handle that reads, writes, and closes exactly like one
`stream.open` returned. Returns nil when nothing is waiting, so call
it in a loop each tick to take every peer that arrived.
`stream.listenerStatus(listener).pending` is how many are still
waiting.

**Parameters**

- `listener` `string` — Listener handle from stream.listen.

**Returns** `string?` — The connection's stream handle, or nil when none is waiting.

```lua
while true do local h = stream.accept(listener); if not h then break end; table.insert(peers, h) end
```

## typed/builtin//modules/api/engine/stream/stream/close {#typed-builtin-modules-api-engine-stream-stream-close}

```lua
stream.close(handle: string) -> boolean
```

Finish whatever `handle` names — a stream or a listener — and
drop it from the registry.

Closing a stream refuses every later write and carries the bytes
already queued to the peer before the connection ends, so a write and
a close in the same tick deliver — the shape a request answered with
one response has. A peer that has stopped reading altogether holds
that finish for thirty seconds; past that the connection ends and
what is still queued ends with it, so a caller that must know its
bytes went out watches `stream.status(handle).pending` reach zero
before it closes.

Closing a listener stops it answering new peers and closes the
connections nobody took; the connections `stream.accept` already
handed over keep running until they are closed themselves.

**Parameters**

- `handle` `string` — Stream handle from stream.open or stream.accept, or listener handle from stream.listen.

**Returns** `boolean` — True if a stream or listener was closed, false if handle already named none.

```lua
stream.write(peer, response); stream.close(peer)
```

## typed/builtin//modules/api/engine/stream/stream/listen {#typed-builtin-modules-api-engine-stream-stream-listen}

```lua
stream.listen(url: string, opts: StreamListenOpts?) -> string
```

Hold the address `url` names and answer the peers that dial it —
the other direction from `stream.open`, for when the thing you are
talking to starts the conversation and restarts on its own schedule.
Returns a promise handle: `task.await()` it to get the listener
handle once the address is held, or it raises the reason a malformed
url, a scheme that cannot listen, or a failed bind was refused with.
Take the connections with `stream.accept`.

**The host in the url is the interface bound, and the whole of what
decides who can reach it.** `tcp://127.0.0.1:9000` answers only
programs on this same machine. `tcp://0.0.0.0:9000` answers any host
that can route to this machine on that port — every device on the
wifi, and anything beyond it the network lets through. Write the one
you mean; there is no default, and `stream.listenerStatus` reports
which of the two you got. A port of `0` asks the operating system to
choose one, which that same status then reports.

`opts.inboundCapacity` and `opts.outboundCapacity` bound each
answered connection (65536 bytes each by default);
`opts.backlog` bounds the connections held for `stream.accept`
before the listener stops taking them from the operating system,
which leaves the rest queued in the kernel rather than answered and
forgotten (16 by default, and at least 1).

The listener belongs to the chunk that opened it — the chunk whose
own code called `stream.listen`, which is the module holding that
line even when something else called into it. When that chunk runs
again — a module hot-reload, a cleared require cache — the listener
and the connections it answered are closed, and the new run binds the
address for itself. Peers see the connection close and dial again.
`stream.listeners()` names that chunk as each entry's `owner`.

**Parameters**

- `url` `string` — Listen URL — scheme://host:port.
- `opts` `StreamListenOpts` _(optional)_ — Per-connection capacities and the accept backlog (optional).

**Returns** `string` — Promise handle for task.await().

```lua
local pending = stream.listen("tcp://127.0.0.1:9000"); local listener = task.await(pending)
```

## typed/builtin//modules/api/engine/stream/stream/listenerStatus {#typed-builtin-modules-api-engine-stream-stream-listenerstatus}

```lua
stream.listenerStatus(listener: string) -> ListenerStatus?
```

Report what the listener holds and has handed over. `address` is
the address the operating system resolved the bind to, port
included — the one to hand a peer. `reach` says who can connect to
it: `"thisMachine"` when it is a loopback address and only programs
on this machine can, `"network"` when any host that can route here
can. `accepted` counts the connections `stream.accept` handed over,
`pending` the ones still waiting, and `capacity` the value `pending`
may reach before the listener stops taking connections from the
operating system. nil when handle names no open listener.

**Parameters**

- `listener` `string` — Listener handle from stream.listen.

**Returns** `ListenerStatus?` — Listener status, or nil when handle names no open listener.

```lua
local s = stream.listenerStatus(listener); print(s.address, s.reach, s.pending)
```

## typed/builtin//modules/api/engine/stream/stream/listeners {#typed-builtin-modules-api-engine-stream-stream-listeners}

```lua
stream.listeners() -> { OpenListener }
```

Every listener this engine currently holds an address for, in the
order they were opened. Each entry is what `stream.listenerStatus`
reports about it, plus the `handle` it is addressed by and the `owner`
chunk its life follows.

This is how an address is reached again once nothing holds its handle:
filter on `address` for the port you want and close the entry by its
`handle`, rather than guessing at handles.

**Returns** `{ OpenListener }` — An array of open listeners.

```lua
for _, l in stream.listeners() do if l.address == want then stream.close(l.handle) end end
```

## typed/builtin//modules/api/engine/stream/stream/open {#typed-builtin-modules-api-engine-stream-stream-open}

```lua
stream.open(url: string, opts: StreamOpenOpts?) -> string
```

Open a byte stream at url (`scheme://target[?k=v]`). `loopback`
carries written bytes back out of the same stream and works on
every platform; `tcp` dials `host:port`; `tty` opens a serial
device node — `/dev/ttyACM0` or `/dev/ttyUSB0` for a USB CDC board
such as an ESP32, `/dev/rfcomm0` for a Bluetooth controller paired
over classic SPP (both present as a tty on Linux, so one transport
serves either peer), `COM5` on Windows. `tty` query parameters:
`baud` (default 115200), `dataBits` (5-8, default 8), `parity`
(`none` | `odd` | `even`, default `none`), `stopBits` (1 or 2,
default 1).

`ble` connects to a Bluetooth Low Energy device over GATT, on a
desktop engine and in a browser alike — the wireless transport a
web world reaches a device through:
`ble://<device>?service=<uuid>&write=<uuid>&notify=<uuid>`. The
device is the name it advertises, `*` any device offering the
service, a trailing `*` a name prefix (`Paw*`). `write` is the
characteristic this engine writes to and `notify` the one it
subscribes to, which on a Nordic UART peripheral are that
peripheral's RX and TX; a module with one bidirectional
characteristic names it for both. UUIDs may be 16-bit (`ffe0`),
32-bit, or full. Optional: `chunk` (bytes per packet, 1-512 —
otherwise what the connection carries), `writeMode`
(`withResponse` | `withoutResponse`, default `withResponse`),
`timeout` (seconds to find and connect to the device, default
15).

`opts` bounds the stream's undrained inbound buffer
and in-flight outbound bytes (default 65536 each). Returns a
promise handle: `task.await()` it
to get the stream handle once the transport is open, or it raises
the reason a malformed url, an unknown or unsupported scheme, or a
failed connect was refused with. A `ble` stream resolves as soon as
it exists and reports the rest as state — watch
`stream.status(handle).state` go `opening`, `permissionPending`
while the browser asks the person at the machine to pick a device,
then `open`; writes made meanwhile are queued and go out when it
connects. Check `stream.transports()` first
to tell a mistyped scheme from one this build does not carry.

**Parameters**

- `url` `string` — Stream URL — scheme://target[?k=v&k=v].
- `opts` `StreamOpenOpts` _(optional)_ — Buffer capacities (optional).

**Returns** `string` — Promise handle for task.await().

```lua
local pending = stream.open("loopback://echo"); local handle = task.await(pending)
local paw = task.await(stream.open("ble://Paw*?service=ffe0&write=ffe1&notify=ffe1"))
```

## typed/builtin//modules/api/engine/stream/stream/read {#typed-builtin-modules-api-engine-stream-stream-read}

```lua
stream.read(handle: string, max: number?) -> string
```

Drain up to max buffered inbound bytes from the stream.

## typed/builtin//modules/api/engine/stream/stream/serialPorts {#typed-builtin-modules-api-engine-stream-stream-serialports}

```lua
stream.serialPorts() -> SerialPorts
```

Every serial device this machine has, for picking the one to open.
`ports` is an array ordered by path. Each entry carries the `path` the
device is at (`/dev/ttyACM0` on Linux, `COM3` on Windows), the `url`
that opens it, the `kind` of bus it attaches by, and — for a USB
device — the `vendorId`, `productId`, `serialNumber`, `manufacturer`
and `product` it advertises.

A device's path moves with enumeration order: a board that came up at
`/dev/ttyACM0` is at `/dev/ttyACM1` once something else is plugged in
first, and moves across `COM3`-`COM5` on Windows. What the device
advertises holds still across those moves, so match on
`vendorId`/`productId` — or on `serialNumber` to tell two of the same
board apart — and open the `url` that entry carries, appending the
port settings `stream.open` documents.

Three answers are distinct. `supported` false with a `reason` means
this platform has no serial bus to enumerate at all. `error` set means
it has one and the operating system refused this enumeration, so a
later call may answer. An empty `ports` with neither means the machine
has no serial device attached, which is an ordinary result.

**Returns** `SerialPorts` — { supported, reason, error, ports } — the platform's answer, this enumeration's, and the devices it found.

```lua
for _, p in stream.serialPorts().ports do if p.vendorId == 0x303A then print(p.url, p.product) end end
```

## typed/builtin//modules/api/engine/stream/stream/status {#typed-builtin-modules-api-engine-stream-stream-status}

```lua
stream.status(handle: string) -> StreamStatus?
```

Report what the stream has carried and lost. `state` is where
the stream is in its life: `opening`, `permissionPending` while the
platform asks the person at the machine to allow the connection,
`open`, `denied` when that permission was refused, and `closed`
when it is finished. `pending` is bytes
accepted and not yet handed to the peer; `capacity` is the value
`pending` may reach before a write is refused. `error` holds the
most recent transport failure and the refusal a `denied` stream
carries, retained for the life of the
stream. nil when handle names no open stream.

**Parameters**

- `handle` `string`

**Returns** `StreamStatus?` — Stream status, or nil when handle names no open stream.

```lua
local s = stream.status(handle); print(s.pending, s.capacity)
```

## typed/builtin//modules/api/engine/stream/stream/streams {#typed-builtin-modules-api-engine-stream-stream-streams}

```lua
stream.streams() -> { OpenStream }
```

Every open stream, dialled or answered, in the order they were
opened. Each entry is what `stream.status` reports about it, plus the
`handle` it is addressed by and the `owner` chunk its life follows —
a connection `stream.accept` handed over carries the owner of the
listener that answered it.

**Returns** `{ OpenStream }` — An array of open streams.

```lua
for _, s in stream.streams() do print(s.handle, s.transport, s.pending, s.owner) end
```

## typed/builtin//modules/api/engine/stream/stream/transports {#typed-builtin-modules-api-engine-stream-stream-transports}

```lua
stream.transports() -> { [string]: TransportSupport }
```

Every stream scheme this build knows about — a capability
probe, in both directions. `supported` answers `stream.open` and
`listen` answers `stream.listen`, since a scheme can carry one and
not the other. Each reason is nil when its direction works,
otherwise it names why not: an unbuilt transport names its own
absence, a transport this platform lacks (`tcp` and `tty` on wasm;
`ble` in a browser without Web Bluetooth or with the radio off,
which the page itself answers) names that, and a loopback stream,
whose peer is itself, names that nothing dials it. A typo'd scheme
is absent from this table entirely, which is what tells it apart
from a real transport this build lacks.

**Returns** `{ [string]: TransportSupport }` — Map of scheme name to { supported, reason, listen, listenReason }.

```lua
local t = stream.transports(); if not t.tcp.listen then warn(t.tcp.listenReason) end
```

## typed/builtin//modules/api/engine/stream/stream/write {#typed-builtin-modules-api-engine-stream-stream-write}

```lua
stream.write(handle: string, bytes: string) -> WriteOutcome
```

Queue bytes for the stream's peer. Never blocks. `"accepted"`
means the bytes were queued. `"full"` means the outbound queue has
no room right now — backpressure, not failure: the peer is alive
and draining slower than this call is producing, so a retry after
it catches up can succeed. Compare `pending` against `capacity` on
`stream.status()` to see it coming before a write is refused.
`"closed"` means the stream is finished, or handle names no open
stream — reopen to continue, retrying never succeeds. `"tooLarge"`
means bytes is bigger than the stream's whole outbound capacity, so
it can never fit at any queue depth — retrying the same write
returns this again.

**Parameters**

- `handle` `string` — Stream handle from stream.open.
- `bytes` `string` — Bytes to queue, byte-safe.

**Returns** `WriteOutcome` — "accepted" | "full" | "closed" | "tooLarge"

```lua
local outcome = stream.write(handle, data)
```

## typed/builtin//modules/api/engine/streaming/streaming/cells {#typed-builtin-modules-api-engine-streaming-streaming-cells}

```lua
streaming.cells() -> { [string]: any }
```

What the spatial-streaming store has resident: the configured radii and
budget, the counters the store keeps, and one row per cell with how many of
its groups are standing, what it costs, and whether a release wrote it to a
file it now reads back from.

**Returns** `{ [string]: any }` — `{ config, stats, sources, cells, proxies }`.

```lua
local s = streaming.cells()
```

## typed/builtin//modules/api/engine/streaming/streaming/levels {#typed-builtin-modules-api-engine-streaming-streaming-levels}

```lua
streaming.levels(scene: any?) -> { [string]: any }
```

Which level every mesh-LOD receiver is drawing at, and the screen
fraction that selection was measured from.
A receiver whose entity the scene no longer holds is reported as
`standing = false`: the chain is registered and there is nothing left for
it to draw.

**Parameters**

- `scene` `any` _(optional)_ — The scene walk to read against. Omitted, the call takes its own.

**Returns** `{ [string]: any }` — `{ count, receivers }`.

```lua
local l = streaming.levels()
```

## typed/builtin//modules/api/engine/streaming/streaming/observe {#typed-builtin-modules-api-engine-streaming-streaming-observe}

```lua
streaming.observe() -> { [string]: any }
```

The whole reading in one document: terrain, voxel, streaming cells and
mesh LOD, plus the totals those rows sum to.

Built by this call and published as its last act, so
`/zero/runtime/observations/streaming` serves the same document rather
than a second derivation of it.

**Returns** `{ [string]: any }` — `{ terrain, voxel, cells, levels, totals }`.

```lua
local r = streaming.observe()
```

## typed/builtin//modules/api/engine/streaming/streaming/reasons {#typed-builtin-modules-api-engine-streaming-streaming-reasons}

```lua
streaming.reasons() -> { string }
```

Every reason `whyNotDrawn` can answer with, so a caller can enumerate
the set rather than meeting it one failure at a time.

**Returns** `{ string }` — Sorted array of reason names.

```lua
local r = streaming.reasons()
```

## typed/builtin//modules/api/engine/streaming/streaming/terrain {#typed-builtin-modules-api-engine-streaming-streaming-terrain}

```lua
streaming.terrain(scene: any?) -> { [string]: any }
```

What each terrain entity is drawing: whether a heightfield is bound to
it, the LOD cut it settled on, what that cut costs in indices and in the
vertex pool, and the eye the cut was refined under.

**Parameters**

- `scene` `any` _(optional)_ — The scene walk to read against. Omitted, the call takes its own,
which is what makes a whole reading one walk rather than four.

**Returns** `{ [string]: any }` — `{ count, entities }` — one row per entity carrying a `Terrain`.

```lua
local t = streaming.terrain()
```

## typed/builtin//modules/api/engine/streaming/streaming/voxel {#typed-builtin-modules-api-engine-streaming-streaming-voxel}

```lua
streaming.voxel(scene: any?) -> { [string]: any }
```

What became of every chunk of every voxel world: how many are meshed,
queued, failed or empty, and one row per chunk carrying the state, the
engine's reason when a build failed, and what the build reserved on the
device.

**Parameters**

- `scene` `any` _(optional)_ — The scene walk to read against. Omitted, the call takes its own.

**Returns** `{ [string]: any }` — `{ count, worlds }` — one entry per entity carrying a `VoxelWorld`.

```lua
local v = streaming.voxel()
```

## typed/builtin//modules/api/engine/streaming/streaming/whyNotDrawn {#typed-builtin-modules-api-engine-streaming-streaming-whynotdrawn}

```lua
streaming.whyNotDrawn(subject: any?) -> { [string]: any }
```

Why a piece of a world's detail is not on screen, as one reason from
the closed set `streaming.reasons()` enumerates, with a detail line naming
what that reason is about.

The subject picks which system answers:
* an entity ref, id or name — whichever of the four systems holds it
* `{ entity = ..., chunk = "cx_cy_cz" }` — one chunk of a voxel world
* `{ entity = ..., level = n }` — one level of a mesh-LOD chain
* `{ cell = "x_z" }` — one cell of the spatial-streaming store

**Parameters**

- `subject` `any` _(optional)_ — The entity, chunk, level or cell to answer about.

**Returns** `{ [string]: any }` — `{ kind, reason, detail }`.

```lua
local w = streaming.whyNotDrawn({ entity = "Vox", chunk = "0_0_0" })
```

## typed/builtin//modules/api/engine/stringx/stringx/scanNumbers {#typed-builtin-modules-api-engine-stringx-stringx-scannumbers}

```lua
stringx.scanNumbers(s: string, pos: number?) -> ({ number }, number)
```

Read the run of numbers starting at `pos` — separated by commas and/or
whitespace — and report where the run ended.

The run stops at the first character that neither continues a number nor
separates two of them (`]`, `}`, a quote, a letter), and `nextPos` is that
character's index, so the caller's own parser resumes exactly there. A
token that is not a valid number also ends the run, with `nextPos` left ON
it rather than past it, so nothing is skipped without the caller seeing it.

**Parameters**

- `s` `string` — The text to read.
- `pos` `number` _(optional)_ — 1-based index to start at. Defaults to 1.

**Returns** `({ number }, number)` — The numbers found, and the 1-based position just past them.

```lua
-- A JSON array of numbers, in one crossing instead of one per token.
local values, nextPos = stringx.scanNumbers(payload, afterBracket)
-- A whitespace-separated block (OBJ, PLY, a matrix dump).
local m = stringx.scanNumbers("1 0 0 0  0 1 0 0", 1)
```

## typed/builtin//modules/api/engine/subscriptions/subscriptions/cancel {#typed-builtin-modules-api-engine-subscriptions-subscriptions-cancel}

```lua
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.

**Parameters**

- `id` `string` — Subscription id to cancel.

**Returns** `boolean` — True when a live subscription was disconnected.

```lua
subscriptions.cancel(conn.id)
```

## typed/builtin//modules/api/engine/subscriptions/subscriptions/get {#typed-builtin-modules-api-engine-subscriptions-subscriptions-get}

```lua
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).

## typed/builtin//modules/api/engine/subscriptions/subscriptions/list {#typed-builtin-modules-api-engine-subscriptions-subscriptions-list}

```lua
subscriptions.list(filter: SubscriptionFilter?) -> { SubscriptionRow }
```

Every tracked subscription row, optionally filtered by publisher
instance id, publisher entity id, event name, and/or connected state.

## typed/builtin//modules/api/engine/subscriptions/subscriptions/publishers {#typed-builtin-modules-api-engine-subscriptions-subscriptions-publishers}

```lua
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.

**Returns** `{ PublisherRow }` — Array of publisher rows.

```lua
for _, p in ipairs(subscriptions.publishers()) do print(p.component, p.entityName) end
```

## typed/builtin//modules/api/engine/substrate/substrate/createBuffer {#typed-builtin-modules-api-engine-substrate-substrate-createbuffer}

```lua
substrate.createBuffer(opts: BufferOpts) -> TypedBuffer?
```

Allocate a typed buffer and return its handle.

A `"gpu"` buffer is storage a compute shader binds; `usage` adds
`"vertex"`, `"index"`, `"indirect"` or `"readback"` on top of the storage
it always has. A `"cpu"` buffer lives in the scripting heap and reads back
as a flat array of floats.

The handle's `write` answers whether the words landed: a payload whose end
falls past the end of the buffer is refused whole on both kinds, so the
buffer keeps what it held and the call answers false. `writeU32` and
`writeBytes` answer the same way, against the same extent.

**Parameters**

- `opts` `BufferOpts` — `{ type, len, kind?, usage?, name? }` — `type` is `"f32"`, `"vec3"`,
`"vec4"`, `"quat"` or `"mat4"`; `kind` is `"cpu"` (the default) or `"gpu"`.
`name` is the name a dispatch binds a `"gpu"` buffer by, and the name
`substrate.getBuffer` and `substrate.destroyBuffer` reach it under.

**Returns** `TypedBuffer?` — The buffer handle, or nil when the allocation failed — an unknown `type` or `kind`, a zero length, or a `name` that already holds a GPU buffer of another shape. A `name` holding a buffer of the SAME type and length hands that buffer back, contents and all; `substrate.destroyBuffer` frees a name whose buffer is the wrong shape.

```lua
local pose = substrate.createBuffer({ type = "mat4", len = boneCount })
local field = substrate.createBuffer({ type = "vec3", len = 4096, kind = "gpu" })
local values = pose:read(0, 16):result()
```

## typed/builtin//modules/api/engine/substrate/substrate/destroyBuffer {#typed-builtin-modules-api-engine-substrate-substrate-destroybuffer}

```lua
substrate.destroyBuffer(name: string) -> boolean
```

Free the GPU buffer `name` denotes, whatever else still holds a handle
to it.

The allocation goes and the name is free to be created again at any type
and length; every handle that pointed at it answers `:alive()` false. This
is what releases a name whose creating handle is gone, so a build that
re-runs at a different size gets its name back.

**Parameters**

- `name` `string` — The name the buffer was created under.

**Returns** `boolean` — True when a GPU buffer under that name was freed.

```lua
substrate.destroyBuffer("env.town.xf")
```

## typed/builtin//modules/api/engine/substrate/substrate/getBuffer {#typed-builtin-modules-api-engine-substrate-substrate-getbuffer}

```lua
substrate.getBuffer(name: string) -> TypedBuffer?
```

The GPU buffer `name` denotes, as a handle you now hold.

A name is how a dispatch binds a buffer, so the name is what an owner asks
by once the handle it created with has gone out of scope — a `.module`
that hot-reloaded, a build that ran in an earlier `execute`. The handle
carries everything `createBuffer`'s does and releases its reference with
`:destroy()`.

**Parameters**

- `name` `string` — The name the buffer was created under.

**Returns** `TypedBuffer?` — The buffer handle, or nil when no GPU buffer holds that name.

```lua
local xf = substrate.getBuffer("env.town.xf")
local shape = xf and { xf:type(), xf:length() }
```

## typed/builtin//modules/api/engine/substrate/substrate/gpuReadback {#typed-builtin-modules-api-engine-substrate-substrate-gpureadback}

```lua
substrate.gpuReadback(key: string?) -> Readback?
```

Wrap the key an FFI read handed back as the `Readback` that polls it.
Every GPU→CPU read reaches the caller through this, so a texture's read
and a buffer's read answer with the same thing.

**Parameters**

- `key` `string` _(optional)_ — The key the read returned.

**Returns** `Readback?` — The `Readback`, or nil when the read did not start.

```lua
local pending = substrate.gpuReadback(compute.readTexture3D(handle))
```

## typed/builtin//modules/api/engine/substrate/substrate/listBuffers {#typed-builtin-modules-api-engine-substrate-substrate-listbuffers}

```lua
substrate.listBuffers() -> { NamedBuffer }
```

Every named GPU buffer the engine holds, in name order.

Each record states `id`, `name`, `type` (`"F32"`, `"Vec3"`, `"Vec4"`,
`"Quat"`, `"Mat4"`), `len` in records, and `refs` — how many holders it
has. This is what states which names are taken and at what shape.

**Returns** `{ NamedBuffer }` — Array of `{ id, name, type, len, refs }`.

```lua
for _, b in ipairs(substrate.listBuffers()) do print(b.name, b.type, b.len) end
```

## typed/builtin//modules/api/engine/text/text/alive {#typed-builtin-modules-api-engine-text-text-alive}

```lua
text.alive(handle: any?) -> boolean
```

Whether the text system still holds this handle — true between
`text.create` and the `text.destroy` that released it.

**Parameters**

- `handle` `any` _(optional)_ — Text handle from `text.create`.

**Returns** `boolean` — True while the handle is live.

```lua
if not text.alive(h) then h = text.create({ content = "again" }) end
```

## typed/builtin//modules/api/engine/text/text/count {#typed-builtin-modules-api-engine-text-text-count}

```lua
text.count() -> number
```

How many text objects the text system is holding — the number that
moves when `text.create` and `text.destroy` are called.

**Returns** `number` — The live text-object count.

```lua
local before = text.count()
```

## typed/builtin//modules/api/engine/text/text/create {#typed-builtin-modules-api-engine-text-text-create}

```lua
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.

## typed/builtin//modules/api/engine/text/text/destroy {#typed-builtin-modules-api-engine-text-text-destroy}

```lua
text.destroy(handle: any?) -> boolean
```

Destroy a text handle and release its raster + glyph layout.

**Parameters**

- `handle` `any` _(optional)_ — Text handle from `text.create`.

**Returns** `boolean` — True when the text system held the handle and released it; false for a handle it did not have.

```lua
text.destroy(h)
```

## typed/builtin//modules/api/engine/text/text/face {#typed-builtin-modules-api-engine-text-text-face}

```lua
text.face(handle: any?) -> any
```

Which font face one handle actually shaped with, and whether that is
the family its style asked for. `requested` is what was asked, `resolved`
is the face that answered, `matched` says whether they agree and `reason`
says why when they do not — one of `text.faceReasons()`. A style that named
no family reports `noFamilyRequested`: it got the default because it asked
for nothing, so `reason` rather than `matched` is what an alert switches
on. `faces` lists
every face the shaper used, most glyphs first, so a fallback that covered
part of the string is visible alongside the face that covered the rest.

**Parameters**

- `handle` `any` _(optional)_ — Text handle from `text.create`.

**Returns** `any` — `{ requested, resolved, postScriptName, matched, reason, faces, glyphCount }`, or nil for a handle the text system does not hold.

```lua
local r = text.face(h).reason; if r == "familyUnknown" or r == "familyNotSelectable" then print(r) end
```

## typed/builtin//modules/api/engine/text/text/faceReasons {#typed-builtin-modules-api-engine-text-text-facereasons}

```lua
text.faceReasons() -> { string }
```

Every reason the face readings give for a label or a family not being
in the family a style named, nearest cause first. `text.face` gives them
for one label; `font.reconcile()` also gives `familyCoveredNoGlyph`, which
it can only reach by laying the family out under its own weights and over
several scripts.

**Returns** `{ string }` — Array of reason strings.

```lua
for _, r in ipairs(text.faceReasons()) do print(r) end
```

## typed/builtin//modules/api/engine/text/text/listFonts {#typed-builtin-modules-api-engine-text-text-listfonts}

```lua
text.listFonts() -> { string }
```

List the font families currently available to the text system.

**Returns** `{ string }` — Array of font-family name strings.

```lua
local fonts = text.listFonts()
```

## typed/builtin//modules/api/engine/text/text/loadFont {#typed-builtin-modules-api-engine-text-text-loadfont}

```lua
text.loadFont(ref: any?) -> any
```

Load a font from an asset reference so it becomes available to
`setStyle`'s `fontFamily`.

**Parameters**

- `ref` `any` _(optional)_ — Font asset reference or path.

**Returns** `any` — The loaded font-family name, or nil on failure.

```lua
text.loadFont(asset.ref("fonts.inter", "font"))
```

## typed/builtin//modules/api/engine/text/text/measure {#typed-builtin-modules-api-engine-text-text-measure}

```lua
text.measure(handle: any?) -> any
```

Measure the rasterised text in pixels without producing a texture.

**Parameters**

- `handle` `any` _(optional)_ — Text handle from `text.create`.

**Returns** `any` — Table with `width` and `height` in pixels.

```lua
local size = text.measure(h)
```

## typed/builtin//modules/api/engine/text/text/observe {#typed-builtin-modules-api-engine-text-text-observe}

```lua
text.observe() -> any
```

Everything the text system is holding right now. `count` is the live
text objects; `objects` is one row each, carrying its content, the style
it was laid out with, its measured extent, whether it is dirty, the `face`
the shaper actually used, the `owner` entity whose component created it
with whether that entity is still there, and the `raster` texture its last
rasterisation landed in with the bytes it costs. `orphans` is the subset
whose owning entity is gone, `fonts` the families the shaper can resolve,
and `raster` the glyph-raster bytes with the pool they belong to named.
Built when you ask, so it costs nothing per frame and reads the same in
edit mode as in play.

**Returns** `any` — `{ count, objects, orphans, fonts, dirty, raster }`.

```lua
local live = text.observe().count
```

## typed/builtin//modules/api/engine/text/text/orphans {#typed-builtin-modules-api-engine-text-text-orphans}

```lua
text.orphans() -> { any }
```

The text objects whose owning entity no longer exists — a quad the
engine is still holding for something that has been despawned. Each row is
the same shape `text.observe().objects` carries.

**Returns** `{ any }` — Array of text-object rows with a dead owner.

```lua
print(#text.orphans() .. " labels outlived their entity")
```

## typed/builtin//modules/api/engine/text/text/rasterMemory {#typed-builtin-modules-api-engine-text-text-rastermemory}

```lua
text.rasterMemory() -> any
```

The glyph-raster bytes, broken out of the runtime GPU texture pool.
`bytes` is summed off the same map `renderer.gpuMemory().textures` is
totalled from, so `shareOfPool` is a share of that number rather than a
second count of the same memory.

**Returns** `any` — `{ pool, bytes, textures, poolBytes, shareOfPool }`.

```lua
local r = text.rasterMemory(); print(r.bytes .. " of " .. r.poolBytes)
```

## typed/builtin//modules/api/engine/text/text/rasterize {#typed-builtin-modules-api-engine-text-text-rasterize}

```lua
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.

**Parameters**

- `handle` `any` _(optional)_ — Text handle from `text.create`.
- `texture` `any` _(optional)_ — Destination GPU texture handle (`renderer.texture.create`) or its
guid string — WHERE the raster lands.
- `scale` `number` _(optional)_ — World/pixel scale factor for the raster (default 1.0).

**Returns** `any` — Table with `width` and `height` (in pixels), or nil if nothing rasterised.

```lua
local tex = renderer.texture.create({ width = 256, height = 64 })
local r = text.rasterize(h, tex, 1.0)
```

## typed/builtin//modules/api/engine/text/text/setStyle {#typed-builtin-modules-api-engine-text-text-setstyle}

```lua
text.setStyle(handle: any?, style: table) -> boolean
```

Replace the handle's style. Fields not present keep their current
value.

**Parameters**

- `handle` `any` _(optional)_ — Text handle from `text.create`.
- `style` `table` — Style table (fontSize, color, alignment, outline, ...).

**Returns** `boolean` — True when the text system held the handle and took the style; false when it did not.

```lua
text.setStyle(h, { fontSize = 64, color = "yellow" })
```

## typed/builtin//modules/api/engine/text/text/setText {#typed-builtin-modules-api-engine-text-text-settext}

```lua
text.setText(handle: any?, content: string) -> boolean
```

Replace the handle's text content.

**Parameters**

- `handle` `any` _(optional)_ — Text handle from `text.create`.
- `content` `string` — New text string.

**Returns** `boolean` — True when the text system held the handle and took the content; false when it did not, which is how a caller learns its handle went away.

```lua
if not text.setText(h, "HP: 100") then h = text.create({ content = "HP: 100" }) end
```

## typed/builtin//modules/api/engine/text/text/textureGuid {#typed-builtin-modules-api-engine-text-text-textureguid}

```lua
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.

**Parameters**

- `handle` `any` _(optional)_ — Text handle from `text.create`.

**Returns** `string?` — The texture guid string, or nil for a handle the text system does not hold.

```lua
entity(id).component.get("Material"):setTexture("base_color_texture", text.textureGuid(h))
```

## typed/builtin//modules/api/engine/ui/ui/blur {#typed-builtin-modules-api-engine-ui-ui-blur}

```lua
ui.blur()
```

Surrender keyboard focus from whichever widget currently
holds it.

## typed/builtin//modules/api/engine/ui/ui/bringAreaToFront {#typed-builtin-modules-api-engine-ui-ui-bringareatofront}

```lua
ui.bringAreaToFront(id: string)
```

Raise a movable `area` to the top of the window stacking order —
the programmatic equivalent of clicking it. Areas sharing a stacking
band order by interaction, so this is the call that brings one forward
from code: use it when a taskbar button, focus change, or app launch
should raise a window. Moving a screen to a higher `layer` band raises
it over the bands below.

**Parameters**

- `id` `string` — Area widget id.

## typed/builtin//modules/api/engine/ui/ui/captureWindow {#typed-builtin-modules-api-engine-ui-ui-capturewindow}

```lua
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).

**Parameters**

- `screen` `string` — Screen id containing the target Window.
- `window` `string` — Widget id of the Window.
- `opts` `CaptureOpts` _(optional)_ — `{ width, height }` (optional).

**Returns** `CaptureResult?` — `{ rtHandle, texturePath }` or nil.

## typed/builtin//modules/api/engine/ui/ui/click {#typed-builtin-modules-api-engine-ui-ui-click}

```lua
ui.click(callbackId: string, value: any?)
```

Simulate a widget click / interaction by its callback id. The call
carries no screen, so an id that names widgets on several screens reaches
every component that declared it, once each.

**Parameters**

- `callbackId` `string` — Callback id assigned to the widget.
- `value` `any` _(optional)_ — Optional value to pass with the callback.

## typed/builtin//modules/api/engine/ui/ui/defineStyle {#typed-builtin-modules-api-engine-ui-ui-definestyle}

```lua
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.

**Parameters**

- `name` `string` — Style name.
- `style` `StyleProps` — Style properties table.

## typed/builtin//modules/api/engine/ui/ui/defineStyles {#typed-builtin-modules-api-engine-ui-ui-definestyles}

```lua
ui.defineStyles(styles: { [string]: StyleProps })
```

Define multiple named styles at once.

**Parameters**

- `styles` `{ [string]: StyleProps }` — Map of style name to style properties.

## typed/builtin//modules/api/engine/ui/ui/defineWidget {#typed-builtin-modules-api-engine-ui-ui-definewidget}

```lua
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`.

**Parameters**

- `name` `string` — Custom widget kind name.
- `builderFn` `(WidgetTree, { WidgetTree }) -> WidgetTree` — Builder closure `(props, children) -> widgetTable`.

## typed/builtin//modules/api/engine/ui/ui/diagnose {#typed-builtin-modules-api-engine-ui-ui-diagnose}

```lua
ui.diagnose(widgetId: string) -> WidgetPaint?
```

Why one widget did or did not reach the last frame. Returns that
widget's row from `ui.observe()` — the same fields, resolved against the
same reading. An id no registered screen carries reads `noSuchWidget`,
which is how a misspelling separates from a widget whose screen is
hidden and from one the frame laid out no box for.

**Parameters**

- `widgetId` `string` — The id the widget records layout under.

**Returns** `WidgetPaint?` — The widget's row, or nil before the UI has published a frame.

```lua
"hud-healthbar"
```

## typed/builtin//modules/api/engine/ui/ui/dragState {#typed-builtin-modules-api-engine-ui-ui-dragstate}

```lua
ui.dragState() -> { payload: string, x: number, y: number }?
```

The in-flight drag-and-drop payload while a `dragPayload` widget is
being dragged, else nil. `x`/`y` are the pointer's position in the
logical space `ui.getLayoutInfo` rects live in, so the reading resolves
directly against widget rects. Poll during a drag to drive live
feedback (a placement ghost following the cursor); the drop itself
still lands through the target's `onDrop`. Snapshotted each frame.

**Returns** `{ payload: string, x: number, y: number }?` — `{ payload, x, y }` during a drag, nil otherwise.

## typed/builtin//modules/api/engine/ui/ui/elementTree {#typed-builtin-modules-api-engine-ui-ui-elementtree}

```lua
ui.elementTree(screenName: string) -> ElementNode?
```

Introspect a screen's rendered widget hierarchy with each
element's layout rect. Every node the renderer draws appears, nested
exactly as the widgets nest, under the id it records layout against:
the `id` set on the node when the author gave it one, otherwise
`<screen>/<type>@<path>`. `bounds` is that element's rect — the same
table `ui.getLayoutInfo(id)` returns — and appears once the element has
been measured. Kinds registered through `ui.defineWidget` appear
expanded into the primitives they build. Feeds the `gui.captureElement`
tool: list the tree, pick the ids to frame, capture their region.

**Parameters**

- `screenName` `string` — Screen id passed to `ui.registerScreen`.

**Returns** `ElementNode?` — An `ElementNode` tree, or nil when no screen is registered under that name.

## typed/builtin//modules/api/engine/ui/ui/focus {#typed-builtin-modules-api-engine-ui-ui-focus}

```lua
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()`.

**Parameters**

- `widgetId` `string` — Widget id to focus.

## typed/builtin//modules/api/engine/ui/ui/focusedWidget {#typed-builtin-modules-api-engine-ui-ui-focusedwidget}

```lua
ui.focusedWidget() -> string?
```

Return the widget id of whichever widget currently holds
keyboard focus, or nil. Snapshotted post-render each frame.

**Returns** `string?` — Focused widget id or nil.

## typed/builtin//modules/api/engine/ui/ui/getAreaPos {#typed-builtin-modules-api-engine-ui-ui-getareapos}

```lua
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.

**Parameters**

- `id` `string` — Area widget id.

**Returns** `AreaPos?` — `{ x, y }` or nil.

## typed/builtin//modules/api/engine/ui/ui/getAreaSize {#typed-builtin-modules-api-engine-ui-ui-getareasize}

```lua
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.

**Parameters**

- `id` `string` — Area widget id.

**Returns** `AreaSize?` — `{ w, h }` or nil.

## typed/builtin//modules/api/engine/ui/ui/getDockLayout {#typed-builtin-modules-api-engine-ui-ui-getdocklayout}

```lua
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.

**Parameters**

- `id` `string` — DockArea widget id.

**Returns** `string?` — Serialized DockState JSON string, or nil.

## typed/builtin//modules/api/engine/ui/ui/getLayoutInfo {#typed-builtin-modules-api-engine-ui-ui-getlayoutinfo}

```lua
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.

**Parameters**

- `widgetId` `string` _(optional)_ — Optional widget id to query.

**Returns** `LayoutInfo?` — Layout info table or nil.

## typed/builtin//modules/api/engine/ui/ui/getScreenTree {#typed-builtin-modules-api-engine-ui-ui-getscreentree}

```lua
ui.getScreenTree(screenName: string) -> WidgetTree?
```

Return the last widget tree table passed to
`registerScreen` / `updateScreen` for `screenName`.

**Parameters**

- `screenName` `string` — Screen name to query.

**Returns** `WidgetTree?` — Widget tree or nil.

## typed/builtin//modules/api/engine/ui/ui/getTheme {#typed-builtin-modules-api-engine-ui-ui-gettheme}

```lua
ui.getTheme() -> string
```

Get the name of the currently active theme.

**Returns** `string` — Active theme name.

## typed/builtin//modules/api/engine/ui/ui/getToken {#typed-builtin-modules-api-engine-ui-ui-gettoken}

```lua
ui.getToken(name: string) -> string?
```

Look up a single design token value from the active theme.

**Parameters**

- `name` `string` — Token name (without `$` prefix).

**Returns** `string?` — Token value or nil.

## typed/builtin//modules/api/engine/ui/ui/getTokens {#typed-builtin-modules-api-engine-ui-ui-gettokens}

```lua
ui.getTokens() -> { [string]: string }
```

Get all design tokens from the active theme as a key-value
map.

**Returns** `{ [string]: string }` — Token map.

## typed/builtin//modules/api/engine/ui/ui/getWidgetProps {#typed-builtin-modules-api-engine-ui-ui-getwidgetprops}

```lua
ui.getWidgetProps(typeName: string) -> { WidgetPropDescriptor }?
```

Get the property definitions for a widget type.

**Parameters**

- `typeName` `string` — Widget type name.

**Returns** `{ WidgetPropDescriptor }?` — Array of property descriptors, or nil if type not found.

## typed/builtin//modules/api/engine/ui/ui/getWidgetTypes {#typed-builtin-modules-api-engine-ui-ui-getwidgettypes}

```lua
ui.getWidgetTypes() -> { string }
```

Get all available widget type names that can be used in
widget trees.

**Returns** `{ string }` — Array of widget type names.

## typed/builtin//modules/api/engine/ui/ui/hideScreen {#typed-builtin-modules-api-engine-ui-ui-hidescreen}

```lua
ui.hideScreen(name: string) -> boolean
```

Hide a registered screen, and report whether a screen by that name
is registered. The engine applies the hide later in the frame;
`listScreens` reflects it from the next call onwards.

**Parameters**

- `name` `string` — Screen identifier to hide.

**Returns** `boolean` — True when a screen by this name is registered.

## typed/builtin//modules/api/engine/ui/ui/hitTest {#typed-builtin-modules-api-engine-ui-ui-hittest}

```lua
ui.hitTest(x: number, y: number) -> PaintHitTest?
```

Which widget a pointer at `(x, y)` reaches, and the stack beneath it.
Coordinates are in the space `ui.screenSize()` reports — the same space
`getLayoutInfo` rects and `gui.clickAt` use.

**Parameters**

- `x` `number` — Logical X.
- `y` `number` — Logical Y.

**Returns** `PaintHitTest?` — `{ widget, screen, stack, x, y }` — `widget` nil when the point is over no UI — or nil before the UI has published a frame.

```lua
640, 360
```

## typed/builtin//modules/api/engine/ui/ui/invisibilityReasons {#typed-builtin-modules-api-engine-ui-ui-invisibilityreasons}

```lua
ui.invisibilityReasons() -> { string }
```

Every verdict `ui.diagnose` can report, as a closed list.

**Returns** `{ string }` — The reason names.

## typed/builtin//modules/api/engine/ui/ui/lastRegistration {#typed-builtin-modules-api-engine-ui-ui-lastregistration}

```lua
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.

**Returns** `{ name: string, layer: number? }?` — `{ name, layer }` for the last registration, or nil if none yet.

## typed/builtin//modules/api/engine/ui/ui/lastValidation {#typed-builtin-modules-api-engine-ui-ui-lastvalidation}

```lua
ui.lastValidation(screenName: string?) -> any
```

Validation diagnostics produced at the most recent
`registerScreen` / `updateScreen`, plus what the render stage
found while painting — `unknown-font-family` reports a
`style.fontFamily` that named no registered font family, once
per family per screen. 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"`).

**Parameters**

- `screenName` `string` _(optional)_ — Optional screen name.

**Returns** `any` — Validation entry, full map, or nil.

## typed/builtin//modules/api/engine/ui/ui/listFonts {#typed-builtin-modules-api-engine-ui-ui-listfonts}

```lua
ui.listFonts() -> { FontFamilyInfo }
```

Every font family a `style.fontFamily` can select. Read from
the registry the UI text renderer resolves a family token
through, so a family this returns is one a label renders in.
`family` and every name in `aliases` are accepted as a
`fontFamily`, case-insensitively; `aliases` carries the
web-font names, CSS generic families and face names that
select the same group. `faces` names the concrete face in each
weight/style slot, so a `fontWeight = 700` against a family
with no `bold` face gets a synthesised heavy. `system = true`
marks a family taken from the host OS — present on this
machine, absent on one without it, and absent on WASM — so a
UI that must look the same everywhere picks a family with
`system = false`. A `fontFamily` naming nothing in this list
is reported as an `unknown-font-family` warning through
`ui.lastValidation(screen)` once the screen paints, and the
text renders in the default proportional face.

**Returns** `{ FontFamilyInfo }` — Array of `{ family, aliases, faces, system }`, by family.

```lua
for _, f in ui.listFonts() do print(f.family) end
```

## typed/builtin//modules/api/engine/ui/ui/listScreens {#typed-builtin-modules-api-engine-ui-ui-listscreens}

```lua
ui.listScreens() -> { ScreenSummary }
```

List every registered screen with its current visibility,
layer, and whether the screen has a populated root widget tree,
including the register / show / hide / unregister calls the running
script has already made. Sorted by layer ascending, then name.

**Returns** `{ ScreenSummary }` — Array of screen summaries.

## typed/builtin//modules/api/engine/ui/ui/listThemes {#typed-builtin-modules-api-engine-ui-ui-listthemes}

```lua
ui.listThemes() -> { string }
```

List all registered theme names.

**Returns** `{ string }` — Array of theme names.

## typed/builtin//modules/api/engine/ui/ui/observe {#typed-builtin-modules-api-engine-ui-ui-observe}

```lua
ui.observe(screenName: string?) -> PaintObservation?
```

What the last UI frame painted. Returns
`{ generation, viewport, pointer, pointerOverUi, pointerWidget, widgets }`
with one `widgets` row per widget any registered screen holds — its
layout box, the clip chain it painted under, the part of that box which
reached the frame (`visible`), the order it painted in (`paintIndex`),
and its `reason` from the closed set `ui.invisibilityReasons()` lists.
`generation` advances once per re-rendered frame, so two calls reporting
the same number describe the same frame.

**Parameters**

- `screenName` `string` _(optional)_ — Narrow the rows to one screen. Omit for every screen.

**Returns** `PaintObservation?` — The reading; nil before the UI has published a frame, and nil for a `screenName` no registered screen answers to.

```lua
"hud"
```

## typed/builtin//modules/api/engine/ui/ui/paintOrder {#typed-builtin-modules-api-engine-ui-ui-paintorder}

```lua
ui.paintOrder(a: string, b: string) -> number?
```

Which of two widgets paints later: `-1` when `a` paints before `b`,
`1` when after, `0` when level. This is what separates two widgets whose
rects are identical.

**Parameters**

- `a` `string` — First widget id.
- `b` `string` — Second widget id.

**Returns** `number?` — -1, 0, 1, or nil when the reading holds no row for one of them.

```lua
"panel-a", "panel-b"
```

## typed/builtin//modules/api/engine/ui/ui/pixelRatio {#typed-builtin-modules-api-engine-ui-ui-pixelratio}

```lua
ui.pixelRatio() -> number
```

Physical pixels per logical point — the factor between the logical
space `ui.screenSize()` / `getLayoutInfo` rects live in and the physical
space `input.mousePosition`, the camera viewport rect and
`input.simulateMouse*` coordinates live in. Multiply a layout coordinate
by this to aim a simulated pointer at a widget.

**Returns** `number` — Physical pixels per logical point (1.0 when unscaled).

## typed/builtin//modules/api/engine/ui/ui/pointerWidget {#typed-builtin-modules-api-engine-ui-ui-pointerwidget}

```lua
ui.pointerWidget() -> PointerRead?
```

Whether the UI is consuming the pointer, and which widget holds it —
the pointer counterpart of `ui.focusedWidget()`.

**Returns** `PointerRead?` — `{ x, y, overUi, widget, screen }`, or nil before the UI has published a frame.

## typed/builtin//modules/api/engine/ui/ui/registerBackgroundShader {#typed-builtin-modules-api-engine-ui-ui-registerbackgroundshader}

```lua
ui.registerBackgroundShader(shaderHandle: any?, width: number?, height: number?)
```

Register a screen-domain `.shader` as a UI background, drawn
via the `backgroundShader` style. Takes the shader's asset handle
from `asset.resolve`.

**Parameters**

- `shaderHandle` `any` _(optional)_ — The screen `.shader`'s asset handle, from `asset.resolve`.
- `width` `number` _(optional)_ — Render target width (default 1280).
- `height` `number` _(optional)_ — Render target height (default 720).

## typed/builtin//modules/api/engine/ui/ui/registerCallbackEnv {#typed-builtin-modules-api-engine-ui-ui-registercallbackenv}

```lua
ui.registerCallbackEnv(key: string, env: { [string]: any })
```

Register an environment table to receive widget-callback
broadcasts: its global `onCallback(id, value)` fires for any widget
callback not owned by a specific component instance — the same
broadcast a component's `onCallback` receives. Keyed by `key`;
re-registering the same key replaces the previous env. A component
instance is folded into the callback dispatch automatically, so reach
for this from a non-component context that hosts a UI surface (a scene
entrypoint registering its own screen). Pair with
`ui.unregisterCallbackEnv(key)` so the ref is released.

**Parameters**

- `key` `string` — Stable identifier for this registration (re-register replaces).
- `env` `{ [string]: any }` — Environment table whose `onCallback` receives the broadcasts.

## typed/builtin//modules/api/engine/ui/ui/registerScreen {#typed-builtin-modules-api-engine-ui-ui-registerscreen}

```lua
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), in bands: below 0
behind everything, 0-99 ordinary app depth, 100-999 always-on-top
chrome, 1000+ menu and popup depth. A screen in a higher band
covers one in a lower band whatever their roots are; inside a band
a floating `area` or `window` root sits over ordinary content, and
a `modal` root sits over the whole stack. Tag-based
grouping lives in `Z.tags` (`Z.tags.set(name, { "editor" })`
after register).

**Parameters**

- `name` `string` — Unique screen identifier.
- `widgetTree` `WidgetTree` — Root widget table.
- `layer` `number` _(optional)_ — Z-order layer (optional).

```lua
ui.registerScreen("hud", tree)
```

## typed/builtin//modules/api/engine/ui/ui/registerTheme {#typed-builtin-modules-api-engine-ui-ui-registertheme}

```lua
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.

**Parameters**

- `name` `string` — Theme name to register.
- `theme` `ThemeDefinition` — Flat-resolved theme table.

## typed/builtin//modules/api/engine/ui/ui/removeScreen {#typed-builtin-modules-api-engine-ui-ui-removescreen}

```lua
ui.removeScreen(name: string) -> boolean
```

Alias for `ui.unregisterScreen`.

**Parameters**

- `name` `string` — Screen identifier to remove.

**Returns** `boolean` — True when a screen by this name was registered.

## typed/builtin//modules/api/engine/ui/ui/resetAreaSize {#typed-builtin-modules-api-engine-ui-ui-resetareasize}

```lua
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.

**Parameters**

- `id` `string` — Area widget id.

## typed/builtin//modules/api/engine/ui/ui/response {#typed-builtin-modules-api-engine-ui-ui-response}

```lua
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.

**Parameters**

- `widgetId` `string` — The widget id (NOT the onClick / onChange callback id).

**Returns** `WidgetResponse?` — WidgetResponse or nil.

## typed/builtin//modules/api/engine/ui/ui/screen {#typed-builtin-modules-api-engine-ui-ui-screen}

```lua
ui.screen(name: string) -> { [string]: any }?
```

Get a screen proxy with methods like `setResolution` and
`rasterize`.

**Parameters**

- `name` `string` — Screen name.

**Returns** `{ [string]: any }?` — Screen proxy table, or nil.

## typed/builtin//modules/api/engine/ui/ui/screenSize {#typed-builtin-modules-api-engine-ui-ui-screensize}

```lua
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.

**Returns** `{ width: number, height: number }` — `{ width, height }` in logical UI points.

## typed/builtin//modules/api/engine/ui/ui/scroll {#typed-builtin-modules-api-engine-ui-ui-scroll}

```lua
ui.scroll(deltaX: number, deltaY: number)
```

Simulate a mouse-wheel scroll event on the UI.

**Parameters**

- `deltaX` `number` — Horizontal scroll delta.
- `deltaY` `number` — Vertical scroll delta.

## typed/builtin//modules/api/engine/ui/ui/setAreaPos {#typed-builtin-modules-api-engine-ui-ui-setareapos}

```lua
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.

**Parameters**

- `id` `string` — Area widget id.
- `x` `number` — Target pivot x (screen coords).
- `y` `number` — Target pivot y (screen coords).

## typed/builtin//modules/api/engine/ui/ui/setAreaSize {#typed-builtin-modules-api-engine-ui-ui-setareasize}

```lua
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.

**Parameters**

- `id` `string` — Area widget id.
- `w` `number` — Target width (screen coords).
- `h` `number` — Target height (screen coords).

## typed/builtin//modules/api/engine/ui/ui/setDockWindowRect {#typed-builtin-modules-api-engine-ui-ui-setdockwindowrect}

```lua
ui.setDockWindowRect(dockId: string, panelId: string, x: number, y: number, width: number, height: number)
```

Place the floating window of a `dockArea` panel at `(x, y)` with
size `(width, height)`. Applies once the panel occupies a window —
a request made before then waits for it.

**Parameters**

- `dockId` `string` — DockArea widget id.
- `panelId` `string` — Id of the panel held by the window to place.
- `x` `number` — Window left edge (screen coords).
- `y` `number` — Window top edge (screen coords).
- `width` `number` — Window width (screen coords).
- `height` `number` — Window height (screen coords).

## typed/builtin//modules/api/engine/ui/ui/setScreenRenderLayer {#typed-builtin-modules-api-engine-ui-ui-setscreenrenderlayer}

```lua
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)`.

**Parameters**

- `name` `string` — Screen identifier.
- `mask` `number` — Render-layer membership bitmask.

## typed/builtin//modules/api/engine/ui/ui/setScrollPosition {#typed-builtin-modules-api-engine-ui-ui-setscrollposition}

```lua
ui.setScrollPosition(widgetId: string, offsetY: number)
```

Set the scroll offset of a scrollArea widget.

**Parameters**

- `widgetId` `string` — Scroll area widget id.
- `offsetY` `number` — Vertical scroll offset in pixels.

## typed/builtin//modules/api/engine/ui/ui/setShaderUniforms {#typed-builtin-modules-api-engine-ui-ui-setshaderuniforms}

```lua
ui.setShaderUniforms(name: string, uniforms: { [string]: number })
```

Set uniform values on a registered background shader.

**Parameters**

- `name` `string` — Shader name identifier.
- `uniforms` `{ [string]: number }` — Map of uniform name to number value.

## typed/builtin//modules/api/engine/ui/ui/setTheme {#typed-builtin-modules-api-engine-ui-ui-settheme}

```lua
ui.setTheme(name: string)
```

Switch the active global theme by name.

**Parameters**

- `name` `string` — Theme name to activate.

## typed/builtin//modules/api/engine/ui/ui/showScreen {#typed-builtin-modules-api-engine-ui-ui-showscreen}

```lua
ui.showScreen(name: string) -> boolean
```

Make a registered screen visible, and report whether a screen by
that name is registered. The engine applies the show later in the
frame; `listScreens` reflects it from the next call onwards.

**Parameters**

- `name` `string` — Screen identifier to show.

**Returns** `boolean` — True when a screen by this name is registered.

## typed/builtin//modules/api/engine/ui/ui/unregisterCallbackEnv {#typed-builtin-modules-api-engine-ui-ui-unregistercallbackenv}

```lua
ui.unregisterCallbackEnv(key: string)
```

Remove an environment registered with `ui.registerCallbackEnv`. Its
`onCallback` stops receiving broadcasts. No-op if `key` isn't registered.

**Parameters**

- `key` `string` — The key passed to `ui.registerCallbackEnv`.

## typed/builtin//modules/api/engine/ui/ui/unregisterScreen {#typed-builtin-modules-api-engine-ui-ui-unregisterscreen}

```lua
ui.unregisterScreen(name: string) -> boolean
```

Remove a screen from the registry entirely. Unlike
`hideScreen`, this deletes the entry so it no longer appears in
`listScreens` or render iteration.

**Parameters**

- `name` `string` — Screen identifier to unregister.

**Returns** `boolean` — True when a screen by this name was registered.

## typed/builtin//modules/api/engine/ui/ui/unregisterWidget {#typed-builtin-modules-api-engine-ui-ui-unregisterwidget}

```lua
ui.unregisterWidget(name: string)
```

Drop a registered custom widget kind. Subsequent references
produce an `unknown-widget-type` diagnostic.

**Parameters**

- `name` `string` — Custom widget kind name.

## typed/builtin//modules/api/engine/ui/ui/updateScreen {#typed-builtin-modules-api-engine-ui-ui-updatescreen}

```lua
ui.updateScreen(name: string, widgetTree: WidgetTree)
```

Replace the widget tree of an already-registered screen.

**Parameters**

- `name` `string` — Screen identifier to update.
- `widgetTree` `WidgetTree` — New root widget table.

## typed/builtin//modules/api/engine/ui/ui/useStyles {#typed-builtin-modules-api-engine-ui-ui-usestyles}

```lua
ui.useStyles(themeName: string)
```

Apply a registered style file's classes additively without
changing the active theme.

**Parameters**

- `themeName` `string` — Name of the registered style / theme asset.

## typed/builtin//modules/api/engine/ui/ui/widgetState {#typed-builtin-modules-api-engine-ui-ui-widgetstate}

```lua
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.

**Parameters**

- `widgetId` `string` — Widget id whose state to read.
- `key` `string` — State key.
- `default` `any` _(optional)_ — Value to return when nothing has been written.

**Returns** `any` — Stored value, default, or nil.

## typed/builtin//modules/api/engine/ui/ui/widgetStateClear {#typed-builtin-modules-api-engine-ui-ui-widgetstateclear}

```lua
ui.widgetStateClear(widgetId: string, key: string)
```

Remove a per-widget state entry.

**Parameters**

- `widgetId` `string` — Widget id whose state to clear.
- `key` `string` — State key.

## typed/builtin//modules/api/engine/ui/ui/widgetStateSet {#typed-builtin-modules-api-engine-ui-ui-widgetstateset}

```lua
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.

**Parameters**

- `widgetId` `string` — Widget id to scope the state under.
- `key` `string` — State key.
- `value` `any` _(optional)_ — Value to store (must be non-nil).

## typed/builtin//modules/api/engine/userfile/userfile/pick {#typed-builtin-modules-api-engine-userfile-userfile-pick}

```lua
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.

**Parameters**

- `opts` `PickOpts` _(optional)_ — Picker options (optional): multiple, folder, title, filters, writeTo.

**Returns** `PickResult` — The decoded result table.

```lua
local r = userfile.pick({ filters = {{ name = "Images", extensions = {"png","jpg"} }} })
if not r.cancelled then vfs.write("/source/textures/wall.png", r.files[1].bytes) end
```

## typed/builtin//modules/api/engine/userfile/userfile/pickFolder {#typed-builtin-modules-api-engine-userfile-userfile-pickfolder}

```lua
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.

**Parameters**

- `opts` `PickOpts` _(optional)_ — Picker options (optional); `folder` is forced true.

**Returns** `PickResult` — The decoded result table.

```lua
local r = userfile.pickFolder({ writeTo = "/source/imported/" })
```

## typed/builtin//modules/api/engine/vfs/vfs/clearPlayShadow {#typed-builtin-modules-api-engine-vfs-vfs-clearplayshadow}

```lua
vfs.clearPlayShadow() -> boolean
```

Forget the entire play-shadow set after a bulk promote or discard.
Tracking only — never touches the bytes.

**Returns** `boolean` — Always true.

```lua
vfs.clearPlayShadow()
```

## typed/builtin//modules/api/engine/vfs/vfs/copy {#typed-builtin-modules-api-engine-vfs-vfs-copy}

```lua
vfs.copy(src: string, dst: string) -> (boolean, string?)
```

Copy a file OR directory from `src` to `dst`, `cp -r` style. A
directory recurses — every descendant is replicated at the same
relative path under `dst`, `.refs` sidecars included. `.meta`
sidecars are minted fresh, so a copy is a distinct asset with its
own identity. Both paths are absolute. The source may live in any
layer (writable, library mount, builtin, runtime-generated); the
destination must be a writable route.

**Parameters**

- `src` `string` — Source absolute VFS path (file or directory).
- `dst` `string` — Destination absolute VFS path.

**Returns** `(boolean, string?)` — True on success; (false, errmsg) on failure.

```lua
vfs.copy("/zero/runtime/recordings/take1.mp4", "/zero/source/clips/take1.mp4")
```

## typed/builtin//modules/api/engine/vfs/vfs/currentAuthor {#typed-builtin-modules-api-engine-vfs-vfs-currentauthor}

```lua
vfs.currentAuthor() -> { id: string, name: string? }?
```

The agent this call is attributed to — the author a `/source` write
made right now would be recorded under in the play shadow. Nil when the
call carries no actor identity, which is the case for engine-authored
work and for a caller that presented no token. Compare its `id` against
`vfs.playShadowAuthors()` to separate your own pending edits from a
co-author's.

**Returns** `{ id: string, name: string? }?` — `{ id, name }` for the acting agent, or nil when unattributed.

```lua
local me = vfs.currentAuthor()
print(if me ~= nil then me.id else "unattributed")
```

## typed/builtin//modules/api/engine/vfs/vfs/durability {#typed-builtin-modules-api-engine-vfs-vfs-durability}

```lua
vfs.durability(paths: string | { string }) -> { durable: boolean, warning: string?, playShadow: string?, shadowed: { string }? }
```

What became of the bytes just written at `paths` — one path, or an
array of them answered as ONE write. `durable` is true when they are where
the call filed them, and false when the play shadow took any of them: live
in this session, disk source untouched, discarded on a guarded play-exit
unless kept. `durable` is present whatever the answer is, so its absence is
never a reading. A non-durable answer carries `warning` (the state, for a
reader scanning values rather than checking a field), `playShadow` (the
routes to disk and what each costs a session other people are running in)
and `shadowed` (which of the given paths the shadow holds).

This is the answer, off the same shadow set and in the same words, that the
`write_file` / `edit_file` / `capture` tools attach to their own results and
that `asset.create` reports as its second return value. Ask it here at any
other site that lands files, so every write surface states where the bytes
went in one set of terms.

**Parameters**

- `paths` `string | { string }` — One VFS path, or an array of paths answered together as one
write. A path resolves the way `vfs.write` resolves its own — absolute or
`@`-rooted as it stands, a bare one under `/source/` — so the answer is
about the file that write landed. A value that is not a path — an
AssetRef, a record, a number, a string with nothing in it — raises rather
than being answered off the empty set it reads as; a list with no entries
names nothing and answers durable.

**Returns** `{ durable: boolean, warning: string?, playShadow: string?, shadowed: { string }? }` — `{ durable, warning?, playShadow?, shadowed? }` — the last three present exactly when `durable` is false.

```lua
local ok = vfs.write(path, body)
local d = vfs.durability(path)
if not d.durable then log.warn(d.warning .. " " .. d.playShadow) end
```

## typed/builtin//modules/api/engine/vfs/vfs/evict {#typed-builtin-modules-api-engine-vfs-vfs-evict}

```lua
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.

**Parameters**

- `path` `string` — VFS path whose bytes should be evicted.
- `opts` `VfsOpts` _(optional)_ — `{ root = "/source/" }`.

**Returns** `boolean` — True if MemFs bytes were dropped; false otherwise.

```lua
vfs.evict("/zero/source/textures/imported_big.png")
```

## typed/builtin//modules/api/engine/vfs/vfs/exists {#typed-builtin-modules-api-engine-vfs-vfs-exists}

```lua
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.

**Parameters**

- `path` `string` — VFS path to check.
- `opts` `VfsOpts` _(optional)_ — `{ root = "/source/" }`.

**Returns** `boolean` — True if the path is known regardless of byte cache state.

```lua
assert(vfs.exists("@builtin/models/Cube"))
```

## typed/builtin//modules/api/engine/vfs/vfs/isDirectory {#typed-builtin-modules-api-engine-vfs-vfs-isdirectory}

```lua
vfs.isDirectory(path: string, opts: VfsOpts?) -> boolean
```

Is ONE path a directory? Answers from reality — the writable
layer's children, a resolver-served folder listing, an explicit
empty-directory marker — so a loose file whose extension collides
with an assetType name (`notes.json`) reads as the file it is while
a real `<name>.<type>/` folder reads as a folder. Costs the same
whatever the containing folder holds; use `vfs.list` when you want
every entry's kind, this when you hold one path.

**Parameters**

- `path` `string` — VFS path to classify.
- `opts` `VfsOpts` _(optional)_ — `{ root = "/source/" }`.

**Returns** `boolean` — True if the path is a directory.

```lua
if vfs.isDirectory("/zero/source/Goblin.dynamicAsset") then print("folder asset") end
```

## typed/builtin//modules/api/engine/vfs/vfs/isSaveExcluded {#typed-builtin-modules-api-engine-vfs-vfs-issaveexcluded}

```lua
vfs.isSaveExcluded(path: string, opts: VfsOpts?) -> boolean
```

Does this path hold content the machine keeps to itself?
`/source/tmp/` is session scratch and `/source/local/` is this
machine's own durable content — each directory itself included,
and everything under it. Both are writable, hot-reloadable and
enumerable like the rest of `/source/`; what separates them is
where they stop. The engine filters them out of every world save
and every peer broadcast, so they reach no world, carry no
manifest row there, and a staging verb handed one refuses it by
name. The match reads a whole path segment, so
`/source/tmpfoo/` is ordinary content. Ask here whenever your
code has to agree with what a world can hold.

**Parameters**

- `path` `string` — VFS path to classify.
- `opts` `VfsOpts` _(optional)_ — `{ root = "/source/" }`.

**Returns** `boolean` — True when the path is held back from world saves and sync.

```lua
if not vfs.isSaveExcluded(p) then table.insert(publishable, p) end
```

## typed/builtin//modules/api/engine/vfs/vfs/list {#typed-builtin-modules-api-engine-vfs-vfs-list}

```lua
vfs.list(path: string?) -> { VfsListEntry }
```

List entries in a VFS directory.

## typed/builtin//modules/api/engine/vfs/vfs/memResident {#typed-builtin-modules-api-engine-vfs-vfs-memresident}

```lua
vfs.memResident() -> { { path: string, bytes: number, kind: string } }
```

List the MemFs entries that are NOT resident-by-default — the writable
in-memory layer's binary blobs and its large text files (text at or above
the inline-text size threshold). These are the bytes `vfs.evict` can
reclaim: the ones kept in RAM rather than left to fall through to the
on-disk BlobStore cache. Small text (resident by default) is omitted. The
audit counterpart to `vfs.evict` and to reading with `{ keep = true }` —
use it to see what encoded bytes are held in RAM, and why.

**Returns** `{ { path: string, bytes: number, kind: string } }` — Array of `{ path, bytes, kind }`; `kind` is `"binary"` for non-text content and `"large-text"` for oversized text. Empty when the VFS isn't up.

```lua
for _, e in ipairs(vfs.memResident()) do print(e.path, e.bytes, e.kind) end
```

## typed/builtin//modules/api/engine/vfs/vfs/mkdir {#typed-builtin-modules-api-engine-vfs-vfs-mkdir}

```lua
vfs.mkdir(path: string, opts: VfsOpts?) -> boolean
```

Create a directory. `mkdir -p` semantics — idempotent.
Errors if a file already exists at the same path. While play is
running an authored `/source` directory waits for the lock to
lift and the refusal RAISES with the reason; writing a file under
the path creates it as part of that write, and scratch under
`/source/tmp/` creates as in edit mode.

**Parameters**

- `path` `string` — Directory path.
- `opts` `VfsOpts` _(optional)_ — `{ root = "/source/" }`.

**Returns** `boolean` — True if the directory exists after the call. A creation the running play session refuses raises with the whole reason.

```lua
vfs.mkdir("/zero/source/scenes/")
```

## typed/builtin//modules/api/engine/vfs/vfs/move {#typed-builtin-modules-api-engine-vfs-vfs-move}

```lua
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.
While play is running a move takes the source away, so authored
`/source` content that predates play is refused and the refusal
RAISES with the reason; content this play session created moves and
stays tracked on the play shadow.

**Parameters**

- `src` `string` — Source absolute VFS path.
- `dst` `string` — Destination absolute VFS path.
- `opts` `{ quiet: boolean? }` _(optional)_ — Optional `{ quiet: boolean? }`.

**Returns** `(boolean, string?)` — True on success; (false, errmsg) when the paths themselves refuse it. A move the running play session refuses raises with the whole reason instead.

```lua
vfs.move("/zero/source/a.luau", "/zero/source/b.luau")
```

## typed/builtin//modules/api/engine/vfs/vfs/mutationSeq {#typed-builtin-modules-api-engine-vfs-vfs-mutationseq}

```lua
vfs.mutationSeq() -> number
```

Lifetime count of VFS mutations the engine has APPLIED — the drain's
clock. A write queues its side effects (an asset's content reload, the
assetType's `onChange`, a component or scene registration) and a later
frame runs them; this number advances as each one completes. Read it,
write, then poll for a larger value to learn the queue has moved past the
point you wrote at — instead of waiting a guessed number of frames. It
counts every mutation kind, so it answers about the pipeline rather than
about one file; `asset.reloadSeq(ref)` is the per-asset reading.

**Returns** `number` — Count of applied VFS mutations this session. Monotonic.

```lua
local at = vfs.mutationSeq()
vfs.write("/zero/source/tmp/note.txt", "hi")
repeat task.wait() until vfs.mutationSeq() > at
```

## typed/builtin//modules/api/engine/vfs/vfs/pendingWrites {#typed-builtin-modules-api-engine-vfs-vfs-pendingwrites}

```lua
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.

**Returns** `{ string }` — Array of VFS paths with pending (unconfirmed) local writes.

```lua
for _, p in ipairs(vfs.pendingWrites()) do print(p) end
```

## typed/builtin//modules/api/engine/vfs/vfs/playShadowAuthors {#typed-builtin-modules-api-engine-vfs-vfs-playshadowauthors}

```lua
vfs.playShadowAuthors() -> { [string]: { id: string, name: string? } }
```

The agent behind each currently-shadowed `/source` path: the ZeroMind
user id the write was attributed to, and the username to show for it.
Several agents drive one engine at once and every one of their in-play
source edits sits in the same shadow set, so this is how a review, a
refusal or a verdict tells one agent's pending work from another's. A
path written with no actor identity carries no entry — it belongs to no
agent in particular, and stays settleable by any of them.

**Returns** `{ [string]: { id: string, name: string? } }` — Map of shadowed path to `{ id, name }`.

```lua
local mine = vfs.currentAuthor()
for path, who in pairs(vfs.playShadowAuthors()) do
if mine == nil or who.id ~= mine.id then print(path, "belongs to", who.name) end
end
```

## typed/builtin//modules/api/engine/vfs/vfs/playShadowPaths {#typed-builtin-modules-api-engine-vfs-vfs-playshadowpaths}

```lua
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.

**Returns** `{ string }` — Array of normalized VFS paths currently shadowed.

```lua
for _, p in ipairs(vfs.playShadowPaths()) do print(p) end
```

## typed/builtin//modules/api/engine/vfs/vfs/promotePlayShadow {#typed-builtin-modules-api-engine-vfs-vfs-promoteplayshadow}

```lua
vfs.promotePlayShadow(path: string) -> 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. Takes ONE file
path, and needs the write lock released, so run it inside a pause you
take and hand back. A promotion that cannot happen raises with the
reason: the path is not shadowed, the path is a folder covering
shadowed edits, play is running, the workspace is read-only, or the
write-through failed. A shadow entry whose bytes are gone is dropped
as promoted, so the path comes back with nothing written for it.

**Parameters**

- `path` `string` — Shadowed VFS path to promote (one of vfs.playShadowPaths()).

**Returns** `string` — The path the call settled — it is no longer shadowed.

```lua
engine.paused = true
local promoted = vfs.promotePlayShadow("/zero/source/cover.jpg")
engine.paused = false
```

## typed/builtin//modules/api/engine/vfs/vfs/read {#typed-builtin-modules-api-engine-vfs-vfs-read}

```lua
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.

## typed/builtin//modules/api/engine/vfs/vfs/readAsync {#typed-builtin-modules-api-engine-vfs-vfs-readasync}

```lua
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.

**Parameters**

- `path` `string` — VFS path.
- `opts` `VfsOpts` _(optional)_ — `{ root = "/source/" }`.

**Returns** `string` — Promise ID — pass to `task.await()`.

```lua
local data = task.await(vfs.readAsync("/zero/runtime/screenshots/last.png"))
```

## typed/builtin//modules/api/engine/vfs/vfs/reload {#typed-builtin-modules-api-engine-vfs-vfs-reload}

```lua
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.

**Parameters**

- `modulePath` `string` _(optional)_ — Module identity to reload (omit to reload all).

**Returns** `boolean` — For a single identity, whether a module was cached under that name and has now been dropped — `false` says the name matched nothing. The no-arg form returns true.

```lua
vfs.reload("@mylib/utils.helpers")
```

## typed/builtin//modules/api/engine/vfs/vfs/remove {#typed-builtin-modules-api-engine-vfs-vfs-remove}

```lua
vfs.remove(path: string, opts: VfsOpts?) -> (boolean, string?)
```

Remove a file. Refuses to remove directories unless
`opts.recursive = true`. Refuses protected system roots. While
play is running, authored `/source` content that predates play is
refused and the refusal RAISES with the reason; content this play
session created is removable, a folder included.

**Parameters**

- `path` `string` — VFS path to remove.
- `opts` `VfsOpts` _(optional)_ — `{ root = "/source/", recursive = false }`.

**Returns** `(boolean, string?)` — True on success; (false, errmsg) when the path itself refuses the removal. A removal the running play session refuses raises with the whole reason instead, so a `pcall` around the call reads it — and the lock answers ahead of whether the path is there, so a locked `/source` path raises whether or not it holds anything.

```lua
vfs.remove("/zero/source/scratch.luau")
```

## typed/builtin//modules/api/engine/vfs/vfs/revertPlayShadow {#typed-builtin-modules-api-engine-vfs-vfs-revertplayshadow}

```lua
vfs.revertPlayShadow(path: string) -> 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. Takes ONE file path,
and needs the write lock released, so run it inside a pause you take
and hand back. A revert that cannot happen raises with the reason, on
the same terms as vfs.promotePlayShadow.

**Parameters**

- `path` `string` — Shadowed VFS path to revert (one of vfs.playShadowPaths()).

**Returns** `string` — The path that is now reverted and no longer shadowed.

```lua
engine.paused = true
local reverted = vfs.revertPlayShadow("/zero/source/Foo.component/init.luau")
engine.paused = false
```

## typed/builtin//modules/api/engine/vfs/vfs/unmarkPlayShadow {#typed-builtin-modules-api-engine-vfs-vfs-unmarkplayshadow}

```lua
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.

**Parameters**

- `path` `string` — VFS path to unmark.

**Returns** `boolean` — Always true.

```lua
vfs.unmarkPlayShadow("/zero/source/Foo.component/init.luau")
```

## typed/builtin//modules/api/engine/vfs/vfs/unwatch {#typed-builtin-modules-api-engine-vfs-vfs-unwatch}

```lua
vfs.unwatch(watcherId: number) -> boolean
```

Remove a previously registered VFS watcher.

**Parameters**

- `watcherId` `number` — Watcher id returned by `vfs.watch`.

**Returns** `boolean` — True if the watcher was found and removed.

```lua
vfs.unwatch(id)
```

## typed/builtin//modules/api/engine/vfs/vfs/watch {#typed-builtin-modules-api-engine-vfs-vfs-watch}

```lua
vfs.watch(path: string, callback: (string, string) -> ()) -> number
```

Register a callback that fires when a VFS path is written or
removed. Two match modes: exact, or folder/prefix (key ends with
`/`, and fires for any descendant). The callback runs in the VM
that registered it. Returns a watcher id for `vfs.unwatch`.

**Parameters**

- `path` `string` — Exact path, or folder path ending in `/`.
- `callback` `(string, string) -> ()` — `(mutated_path, kind) -> ()`, kind `"write"` or `"remove"`.

**Returns** `number` — Watcher id.

```lua
local id = vfs.watch("/zero/source/", function(path, kind) print(kind, path) end)
```

## typed/builtin//modules/api/engine/vfs/vfs/write {#typed-builtin-modules-api-engine-vfs-vfs-write}

```lua
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. While play is running a `/source` write lands on the play
shadow: it succeeds and reads back, live in the session with disk
source untouched, and is discarded on a guarded play-exit unless
accepted. Scratch under `/source/tmp/` writes through untouched.
Pass `opts.durable = true` to say these bytes ARE the source: the
write reaches canonical `/source` with play still running and the
session still in play, hot-reloading the modules and components that
read it, so the edit is observed running in the same play session
with nothing left to promote. A durable write RAISES with the reason
when the bytes cannot become canonical source.

**Parameters**

- `path` `string` — VFS path to write to.
- `content` `string` — File content (binary-safe).
- `opts` `VfsOpts` _(optional)_ — `{ root = "/source/", overwrite = true, quiet = false, durable = false }`.

**Returns** `(boolean, string?)` — True on success; on failure returns false + error message. A durable write raises instead of returning false.

```lua
vfs.write("/zero/source/notes.md", body)
vfs.write("/zero/source/game/Vent.component/init.luau", src, { durable = true })
```

## typed/builtin//modules/api/engine/video/video/create {#typed-builtin-modules-api-engine-video-video-create}

```lua
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.

## typed/builtin//modules/api/engine/video/video/destroy {#typed-builtin-modules-api-engine-video-video-destroy}

```lua
video.destroy(handle: string) -> boolean
```

Destroy a video player and free the render target and all
resources.

**Parameters**

- `handle` `string` — Video handle from `video.create`.

**Returns** `boolean` — True if the player was found and destroyed.

```lua
video.destroy(rt)
```

## typed/builtin//modules/api/engine/video/video/getInfo {#typed-builtin-modules-api-engine-video-video-getinfo}

```lua
video.getInfo(handle: string) -> VideoInfo?
```

Get video information and current playback state.

**Parameters**

- `handle` `string` — Video handle.

**Returns** `VideoInfo?` — `{ width, height, duration, currentTime, state, rate, loop }` or nil if the handle is invalid.

```lua
local i = video.getInfo(rt); print(i.currentTime, "/", i.duration)
```

## typed/builtin//modules/api/engine/video/video/pause {#typed-builtin-modules-api-engine-video-video-pause}

```lua
video.pause(handle: string) -> boolean
```

Pause video playback. Can be resumed with `video.play`.

**Parameters**

- `handle` `string` — Video handle.

**Returns** `boolean` — True if the video was playing and is now paused.

```lua
video.pause(rt)
```

## typed/builtin//modules/api/engine/video/video/play {#typed-builtin-modules-api-engine-video-video-play}

```lua
video.play(handle: string) -> boolean
```

Start or resume video playback.

## typed/builtin//modules/api/engine/video/video/seek {#typed-builtin-modules-api-engine-video-video-seek}

```lua
video.seek(handle: string, time: number) -> boolean
```

Seek to a specific time (seconds) in the video.

**Parameters**

- `handle` `string` — Video handle.
- `time` `number` — Target time in seconds.

**Returns** `boolean` — True if the seek was performed.

```lua
video.seek(rt, 30.5)
```

## typed/builtin//modules/api/engine/video/video/setLoop {#typed-builtin-modules-api-engine-video-video-setloop}

```lua
video.setLoop(handle: string, loop: boolean) -> boolean
```

Enable or disable looping.

**Parameters**

- `handle` `string` — Video handle.
- `loop` `boolean` — Whether to loop playback.

**Returns** `boolean` — True if the setting was applied.

```lua
video.setLoop(rt, true)
```

## typed/builtin//modules/api/engine/video/video/setRate {#typed-builtin-modules-api-engine-video-video-setrate}

```lua
video.setRate(handle: string, rate: number) -> boolean
```

Set the playback speed multiplier. 1.0 = normal, 2.0 = double
speed, 0.5 = half speed.

**Parameters**

- `handle` `string` — Video handle.
- `rate` `number` — Playback rate.

**Returns** `boolean` — True if the rate was set.

```lua
video.setRate(rt, 2.0)
```

## typed/builtin//modules/api/engine/video/video/stop {#typed-builtin-modules-api-engine-video-video-stop}

```lua
video.stop(handle: string) -> boolean
```

Stop video playback and reset to the beginning.

**Parameters**

- `handle` `string` — Video handle.

**Returns** `boolean` — True if the command was accepted.

```lua
video.stop(rt)
```

## typed/builtin//modules/asset_ref/M/build {#typed-builtin-modules-asset-ref-m-build}

```lua
M.build(envelope: any?) -> any
```

Attach the AssetRef method metatable to an envelope table. Invoked
by the Rust factory (`push_asset_ref_handle` →
`_G.__build_asset_ref_proxy`) immediately after the six envelope
fields (`__ref`, `type`, `name`, `guid`, `identity`, `path`) have
been set, so the metatable's `__index` only ever fires for method /
property lookups, never for the literal envelope fields.

**Parameters**

- `envelope` `any` _(optional)_ — The freshly-built envelope table.

**Returns** `any` — The same table with `AssetRefMT` attached. Returning the table rather than relying on side-effects makes the Rust factory's pcall-then-replace flow simpler.

```lua
local r = require("modules.asset_ref").build({ type = "material", path = "/zero/source/Gold.material", ... })
```

## typed/builtin//modules/asset_ref/M/flushPendingPersists {#typed-builtin-modules-asset-ref-m-flushpendingpersists}

```lua
M.flushPendingPersists()
```

Write out every asset whose edit-mode persistence is still coalesced,
spending no allowance and waiting on no refill. The runtime-state wipe on a
mode flip calls this first, so a change made in the last window before the
flip reaches the asset instead of being cleared with the overlay it lives
in. Call it before reading an asset's file for a value a runtime write may
have just changed.

```lua
require("modules.asset_ref").flushPendingPersists()
```

## typed/builtin//modules/asset_ref/M/forgetRuntime {#typed-builtin-modules-asset-ref-m-forgetruntime}

```lua
M.forgetRuntime(guid: string) -> boolean
```

Forget everything a type derived from ONE asset's content — the values
it cached in `ref.runtime` off the bytes that asset used to hold. Called
when an asset's content is REPLACED under a guid live consumers already
hold: a type memoizes its parse, its GPU handle, its settings against the
content it read, and each of those describes the previous bytes the moment
the new ones land. Emptying the table in place rather than replacing it is
what makes the clear reach every holder — the runtime table is shared by
every resolver of the guid, and a type may be holding it directly.

**Parameters**

- `guid` `string` — The asset's stable guid.

**Returns** `boolean` — True when there was runtime state to forget.

```lua
require("modules.asset_ref").forgetRuntime(ref.guid)
```

## typed/builtin//modules/asset_ref/M/loadTypeBehavior {#typed-builtin-modules-asset-ref-m-loadtypebehavior}

```lua
M.loadTypeBehavior(asset_type: string) -> ({ [string]: any }?, string?)
```

Load an asset type's `behavior.luau` module table, reporting a
behavior that raised while loading. The first return is the module (nil
when the type ships no `behavior.luau`); the second is set when the type
HAS a `behavior.luau` that raised, and carries the require key plus the
error it raised.
A caller that runs the type's hooks — `asset.create` runs `onCreate` —
reads the second return to tell "this type declares no behavior" from
"this type's behavior is broken", which are opposite situations for the
asset it is about to write.

**Parameters**

- `asset_type` `string` — The type name (e.g. `"dynamicAsset"`, `"material"`).

**Returns** `({ [string]: any }?, string?)` — The type module table, or nil. The load error, or nil.

```lua
local mod, err = require("modules.asset_ref").loadTypeBehavior("dialogue")
```

## typed/builtin//modules/asset_ref/M/loadTypeModule {#typed-builtin-modules-asset-ref-m-loadtypemodule}

```lua
M.loadTypeModule(asset_type: string) -> { [string]: any }?
```

Load the full `behavior.luau` module table for an asset type
(`{ ref?, global?, onChange? }`), or nil when the type ships no
`behavior.luau`. Registry-driven resolution — same path the per-type
`ref` dispatch uses. Exposed so the asset-change dispatcher
(`modules/asset_change_dispatch`) can reach a type's `onChange`
hook without duplicating the resolution logic.

**Parameters**

- `asset_type` `string` — The type name (e.g. `"dynamicAsset"`, `"material"`).

**Returns** `{ [string]: any }?` — The type module table, or nil.

```lua
local m = require("modules.asset_ref").loadTypeModule("dynamicAsset")
```

## typed/builtin//modules/asset_ref/M/persistInEditMode {#typed-builtin-modules-asset-ref-m-persistineditmode}

```lua
M.persistInEditMode(self: any?)
```

Generic edit-mode persistence hook an assetType calls when a change of
its own is meant to reach the file. In EDIT mode, flush a ref's transient
runtime overlay (`ref.runtime`) to its backing asset file by invoking the
type's own `saveDefinition(self)`, so the change syncs to peers and is
saved. Works for any assetType that defines a `saveDefinition`; whether a
given type's runtime writes route through here is that type's own
contract. The write-through is
rate-limited per asset: an asset carries an allowance of 8 writes that
refills at one per 250ms. Changes made in one frame are coalesced onto a
single re-emit, and a caller that changes a value and moves on has it on
disk a frame or two later. A caller that keeps changing the same asset
runs the allowance down to its refill rate, so over any span the asset
costs at most that allowance plus one write per 250ms, whatever cadence
the changes arrive at.
In PLAY mode this is a deliberate no-op: runtime overlays stay transient
(frame-fast) and are persisted back to the source asset on demand. An
assetType opts in simply by exposing `ref.saveDefinition`; no per-type
branching lives here.

**Parameters**

- `self` `any` _(optional)_ — Any AssetRef.

```lua
require("modules.asset_ref").persistInEditMode(matRef)
```

## typed/builtin//modules/asset_ref/assetRef/canInstantiate {#typed-builtin-modules-asset-ref-assetref-caninstantiate}

```lua
assetRef.canInstantiate(self) -> boolean
```

Whether this asset can be instantiated into a scene, which is true exactly when its type defines an instantiate method.

**Parameters**

- `self`

**Returns** `boolean`

## typed/builtin//modules/asset_ref/assetRef/cpu_resident {#typed-builtin-modules-asset-ref-assetref-cpu-resident}

```lua
assetRef.cpu_resident -> boolean
```

Whether this asset's bytes are warm in memory for a live script-component context.

**Returns** `boolean`

## typed/builtin//modules/asset_ref/assetRef/deps {#typed-builtin-modules-asset-ref-assetref-deps}

```lua
assetRef.deps(self) -> { deps: { any }, unresolved_deps: { any }, problems: { any } }
```

This asset's outbound references, the literals nothing answered, and the problems attached to it.

**Parameters**

- `self`

**Returns** `{ deps: { any }, unresolved_deps: { any }, problems: { any } }`

## typed/builtin//modules/asset_ref/assetRef/events {#typed-builtin-modules-asset-ref-assetref-events}

```lua
assetRef.events() -> { [string]: any }?
```

The subscribe-only view over the events this asset's type declares, each entry carrying connect / once / wait.

**Returns** `{ [string]: any }?`

## typed/builtin//modules/asset_ref/assetRef/exists {#typed-builtin-modules-asset-ref-assetref-exists}

```lua
assetRef.exists(self) -> boolean
```

Whether this asset's path reads back as content.

**Parameters**

- `self`

**Returns** `boolean`

## typed/builtin//modules/asset_ref/assetRef/getBytes {#typed-builtin-modules-asset-ref-assetref-getbytes}

```lua
assetRef.getBytes(self, filename: string?) -> string?
```

This asset's content bytes, or the bytes of one named file inside a composite asset.

**Parameters**

- `self`
- `filename` `string` _(optional)_

**Returns** `string?`

## typed/builtin//modules/asset_ref/assetRef/getSource {#typed-builtin-modules-asset-ref-assetref-getsource}

```lua
assetRef.getSource(self, filename: string?) -> string?
```

This asset's content bytes, or the bytes of one named file inside a composite asset.

**Parameters**

- `self`
- `filename` `string` _(optional)_

**Returns** `string?`

## typed/builtin//modules/asset_ref/assetRef/getText {#typed-builtin-modules-asset-ref-assetref-gettext}

```lua
assetRef.getText(self, filename: string?) -> string?
```

This asset's content bytes, or the bytes of one named file inside a composite asset.

**Parameters**

- `self`
- `filename` `string` _(optional)_

**Returns** `string?`

## typed/builtin//modules/asset_ref/assetRef/gpu_resident {#typed-builtin-modules-asset-ref-assetref-gpu-resident}

```lua
assetRef.gpu_resident -> boolean
```

Whether the device holds a texture or mesh under this asset's guid.

**Returns** `boolean`

## typed/builtin//modules/asset_ref/assetRef/has_backing_asset {#typed-builtin-modules-asset-ref-assetref-has-backing-asset}

```lua
assetRef.has_backing_asset -> boolean
```

Whether a `/zero/source/` asset backs this ref.

**Returns** `boolean`

## typed/builtin//modules/asset_ref/assetRef/has_runtime_changes {#typed-builtin-modules-asset-ref-assetref-has-runtime-changes}

```lua
assetRef.has_runtime_changes -> boolean
```

Whether a runtime copy of this asset exists under `/zero/runtime/assets/`.

**Returns** `boolean`

## typed/builtin//modules/asset_ref/assetRef/meta {#typed-builtin-modules-asset-ref-assetref-meta}

```lua
assetRef.meta -> { [string]: any }?
```

This asset's `.meta` sidecar, parsed.

**Returns** `{ [string]: any }?`

## typed/builtin//modules/asset_ref/assetRef/modules {#typed-builtin-modules-asset-ref-assetref-modules}

```lua
assetRef.modules() -> { [string]: any }?
```

The shared modules this asset's type ships, reached as `ref.modules.<name>`.

## typed/builtin//modules/asset_ref/assetRef/runtime {#typed-builtin-modules-asset-ref-assetref-runtime}

```lua
assetRef.runtime -> { [string]: any }
```

The live per-asset table every resolver of this asset shares, for values that do not round-trip through the asset's bytes.

**Returns** `{ [string]: any }`

## typed/builtin//modules/asset_ref/assetRef/typeRef {#typed-builtin-modules-asset-ref-assetref-typeref}

```lua
assetRef.typeRef -> string?
```

The guid of the asset type this asset was authored against, read from its `.refs` sidecar.

## typed/builtin//modules/bundle_update/M/installInto {#typed-builtin-modules-bundle-update-m-installinto}

```lua
M.installInto(bundle: BundleNamespace)
```

Install `update` onto the supplied `bundle`-shaped namespace.
The prelude calls this once at boot with the engine's `bundle`
global; users reach the result as `bundle.update`.

**Parameters**

- `bundle` `BundleNamespace` — The target namespace table. No-op when given a
non-table value.

```lua
require("modules.bundle_update").installInto(bundle)
```

## typed/builtin//modules/bundle_update/bundle/update {#typed-builtin-modules-bundle-update-bundle-update}

```lua
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.

**Parameters**

- `entityId` `string` — The entity whose hierarchy is captured into the bundle.
- `bundleRef` `BundleRef` _(optional)_ — Optional. When omitted, the ref is inferred from the
entity's `Asset.source` field. When given, the explicit ref wins.

**Returns** `any` — True on success (forwarded from the bundle assetType's `:update`).

```lua
bundle.update(entityId)                     -- infer from Asset
bundle.update(entityId, { guid = "..." })   -- explicit ref
```

## typed/builtin//modules/colorSequence/M/deserialize {#typed-builtin-modules-colorsequence-m-deserialize}

```lua
M.deserialize(data: any?) -> ColorSequenceObj
```

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

**Parameters**

- `data` `any` _(optional)_ — The serialized payload.

**Returns** `ColorSequenceObj` — A fresh ColorSequenceObj with the deserialized keypoints.

```lua
local c = ColorSequence.deserialize(savedData)
```

## typed/builtin//modules/colorSequence/M/new {#typed-builtin-modules-colorsequence-m-new}

```lua
M.new(...: any?) -> ColorSequenceObj
```

Construct a ColorSequence from 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. An entry of that array is a named `{ time =, value =, envelope? = }` record, a `{ time, {r,g,b}, envelope? }` pair, or a bare `{r,g,b}` colour whose time is its place in the list — so a list of colours is a ramp through them. `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. `@builtin::systems.particles.curves` reads the same three keypoint shapes.

**Parameters**

- `...` `any` _(optional)_ — `(color)`, `(c0, c1)`, or `({ keypoint, ... })` where a keypoint is `{time =, value =, envelope? =}`, `{time, {r,g,b}, envelope?}`, or `{r,g,b}`.

**Returns** `ColorSequenceObj` — A ColorSequenceObj with `:evaluate`, `:sample`, `:keypoints`, `:duration`, `:serialize`, `:destroy`.

```lua
local solid = ColorSequence.new({ 1, 0.5, 0.25 })
local fade  = ColorSequence.new({ 1, 1, 1 }, { 0, 0, 0 })
local bow   = ColorSequence.new({ { time = 0, value = {1,0,0} }, { time = 0.5, value = {0,1,0} }, { time = 1, value = {0,0,1} } })
local stops = ColorSequence.new({ { 0, {1,0,0} }, { 1, {0,0,1} } })
local ramp  = ColorSequence.new({ { 1, 0.85, 0.35 }, { 1, 0.35, 0.05 } })
```

## typed/builtin//modules/component_field_route/M/componentRef {#typed-builtin-modules-component-field-route-m-componentref}

```lua
M.componentRef(entityId: string, component: string) -> ComponentRef?
```

The component ref serving `component` on `entity`, or `nil` when the
entity is gone or does not carry it.

**Parameters**

- `entityId` `string` — The entity id.
- `component` `string` — The component name.

**Returns** `ComponentRef?` — The component ref, or `nil`.

```lua
local ref = Route.componentRef(id, "Model")
```

## typed/builtin//modules/component_field_route/M/declaredFields {#typed-builtin-modules-component-field-route-m-declaredfields}

```lua
M.declaredFields(ref: ComponentRef) -> { [string]: boolean }
```

The public and private field names `ref` declares, as a set.

**Parameters**

- `ref` `ComponentRef` — A component ref.

**Returns** `{ [string]: boolean }` — `{ [fieldName] = true }`.

```lua
local names = Route.declaredFields(ref)
```

## typed/builtin//modules/component_field_route/M/isReflected {#typed-builtin-modules-component-field-route-m-isreflected}

```lua
M.isReflected(component: string) -> boolean
```

Whether `component` is backed by an engine struct the reflect registry
resolves. A component declared in Luau answers `false` and is served by
the component ref instead.

**Parameters**

- `component` `string` — The component name.

**Returns** `boolean` — `true` when the reflect registry holds this component.

```lua
if Route.isReflected("Transform") then ... end
```

## typed/builtin//modules/component_field_route/M/readField {#typed-builtin-modules-component-field-route-m-readfield}

```lua
M.readField(api: string, entityId: string, component: string, field: string) -> any
```

Read one component field, through whichever route serves it.

**Parameters**

- `api` `string` — The calling API, named in any diagnostic.
- `entityId` `string` — The entity id.
- `component` `string` — The component name.
- `field` `string` — The field name.

**Returns** `any` — The field value, or `nil` when the entity, the component or the field is missing.

```lua
local blend = Route.readField("Entity.getField", id, "Model", "tintBlend")
```

## typed/builtin//modules/component_field_route/M/reportEntitiesWithoutComponent {#typed-builtin-modules-component-field-route-m-reportentitieswithoutcomponent}

```lua
M.reportEntitiesWithoutComponent(api: string, component: string, missing: number, total: number, outcome: string)
```

Report the entities of one call that do not carry the named component,
as a single line for the call rather than one per entity.

**Parameters**

- `api` `string` — The calling API, named in the line.
- `component` `string` — The component name.
- `missing` `number` — How many of the named entities do not carry it.
- `total` `number` — How many entities the call named.
- `outcome` `string` — What the call did for them, e.g. `"nothing written"`.

```lua
Route.reportEntitiesWithoutComponent("entity.batchWrite", "Model", 3, 8, "nothing written")
```

## typed/builtin//modules/component_field_route/M/reportEntityWithoutComponent {#typed-builtin-modules-component-field-route-m-reportentitywithoutcomponent}

```lua
M.reportEntityWithoutComponent(api: string, entityId: string, component: string, outcome: string)
```

Report one entity that does not carry the named component, at most
once per interval per `(api, component)`.

**Parameters**

- `api` `string` — The calling API, named in the line.
- `entityId` `string` — The entity that does not carry it.
- `component` `string` — The component name.
- `outcome` `string` — What the call did instead, e.g. `"nothing written"`.

```lua
Route.reportEntityWithoutComponent("Entity.setField", id, "Model", "nothing written")
```

## typed/builtin//modules/component_field_route/M/reportMissingField {#typed-builtin-modules-component-field-route-m-reportmissingfield}

```lua
M.reportMissingField(api: string, component: string, field: string, outcome: string)
```

Report a field the component does not declare, at most once per
interval per `(api, component, field)`.

**Parameters**

- `api` `string` — The calling API, named in the line.
- `component` `string` — The component name.
- `field` `string` — The field name that resolved to nothing.
- `outcome` `string` — What the call did instead, e.g. `"nothing written"`.

```lua
Route.reportMissingField("entity.batchWrite", "Model", "tintBlnd", "nothing written")
```

## typed/builtin//modules/component_field_route/M/requireComponentType {#typed-builtin-modules-component-field-route-m-requirecomponenttype}

```lua
M.requireComponentType(api: string, component: string)
```

Raise unless `component` names a component this engine knows — either
an engine struct in the reflect registry or a declared `.component`.

**Parameters**

- `api` `string` — The calling API, named in the error so the message points at the call.
- `component` `string` — The component name to check.

```lua
Route.requireComponentType("entity.batchWrite", "Model")
```

## typed/builtin//modules/component_field_route/M/writeField {#typed-builtin-modules-component-field-route-m-writefield}

```lua
M.writeField(api: string, entityId: string, component: string, field: string, value: any?) -> boolean
```

Write one component field, through whichever route serves it.

**Parameters**

- `api` `string` — The calling API, named in any diagnostic.
- `entityId` `string` — The entity id.
- `component` `string` — The component name.
- `field` `string` — The field name.
- `value` `any` _(optional)_ — The value to write.

**Returns** `boolean` — `true` when the write landed.

```lua
Route.writeField("Entity.setField", id, "Model", "tintBlend", 0.5)
```

## typed/builtin//modules/component_proxy/M/computed {#typed-builtin-modules-component-proxy-m-computed}

```lua
M.computed(fn: (any) -> any) -> string
```

Mark a function as a computed property. The function takes
`self` (the proxy) and returns the computed value. Returns a string
sentinel that the Rust-side public_index dispatches through the
registry on every read.

**Parameters**

- `fn` `(any) -> any` — The getter — receives the proxy and returns the computed value.

**Returns** `string` — The sentinel string to store in the proxy's `public` table.

```lua
public.area = computed(function(self) return self.w * self.h end)
```

## typed/builtin//modules/component_proxy/M/installGlobal {#typed-builtin-modules-component-proxy-m-installglobal}

```lua
M.installGlobal()
```

Install `computed` as a global so component modules can write
`public.X = computed(fn)` without an explicit require. Called by the
prelude.

```lua
require("modules.component_proxy").installGlobal()
```

## typed/builtin//modules/component_proxy/M/isComputedSentinel {#typed-builtin-modules-component-proxy-m-iscomputedsentinel}

```lua
M.isComputedSentinel(v: any?) -> boolean
```

True iff `v` is a computed-property sentinel — the string a
`computed(fn)` declaration stores in a proxy's `public` table. Reads
of the property resolve the sentinel to the getter's value, but a raw
`pairs()` over the backing table yields the sentinel itself. Serializers
call this to skip computed (derived) fields, which are re-derived on load.

**Parameters**

- `v` `any` _(optional)_ — The value to test.

**Returns** `boolean` — `true` for a computed sentinel, `false` otherwise.

## typed/builtin//modules/connected_users/connectedUser/data {#typed-builtin-modules-connected-users-connecteduser-data}

```lua
connectedUser.data() -> { [string]: any }
```

This user's per-player runtime-data store, bound to their identity.

**Returns** `{ [string]: any }`

## typed/builtin//modules/connected_users/connectedUser/displayName {#typed-builtin-modules-connected-users-connecteduser-displayname}

```lua
connectedUser.displayName -> string
```

This user's human-readable name, falling back to their identity.

**Returns** `string`

## typed/builtin//modules/connected_users/connectedUser/entity {#typed-builtin-modules-connected-users-connecteduser-entity}

```lua
connectedUser.entity -> entityRef?
```

This user's world-presence body: the avatar bound to them in the active scene, resolved on access.

## typed/builtin//modules/connected_users/connectedUser/identity {#typed-builtin-modules-connected-users-connecteduser-identity}

```lua
connectedUser.identity -> string
```

This user's account id, the `sub` claim of their session JWT.

**Returns** `string`

## typed/builtin//modules/connected_users/connectedUser/isLocal {#typed-builtin-modules-connected-users-connecteduser-islocal}

```lua
connectedUser.isLocal -> boolean
```

Whether this record is the user signed in on this engine.

**Returns** `boolean`

## typed/builtin//modules/connected_users/connectedUsers/count {#typed-builtin-modules-connected-users-connectedusers-count}

```lua
connectedUsers.count() -> number
```

How many users are connected.

**Returns** `number`

## typed/builtin//modules/connected_users/connectedUsers/exists {#typed-builtin-modules-connected-users-connectedusers-exists}

```lua
connectedUsers.exists(identity: string) -> boolean
```

Whether a user carrying an identity is connected.

**Parameters**

- `identity` `string`

**Returns** `boolean`

## typed/builtin//modules/connected_users/connectedUsers/get {#typed-builtin-modules-connected-users-connectedusers-get}

```lua
connectedUsers.get(identity: string) -> connectedUser?
```

The user carrying an identity, or nil when nobody connected carries it.

## typed/builtin//modules/connected_users/connectedUsers/list {#typed-builtin-modules-connected-users-connectedusers-list}

```lua
connectedUsers.list() -> { connectedUser }
```

Every connected user, ordered by identity.

## typed/builtin//modules/connected_users/connectedUsers/localUser {#typed-builtin-modules-connected-users-connectedusers-localuser}

```lua
connectedUsers.localUser -> connectedUser?
```

The user signed in on this engine, re-read on each access; nil for an anonymous session.

**Returns** `connectedUser?`

## typed/builtin//modules/connected_users/connectedUsers/offConnect {#typed-builtin-modules-connected-users-connectedusers-offconnect}

```lua
connectedUsers.offConnect(handle: number) -> boolean
```

Drop a connect subscription by its handle. True when a live subscription carried it.

**Parameters**

- `handle` `number`

**Returns** `boolean`

## typed/builtin//modules/connected_users/connectedUsers/offDisconnect {#typed-builtin-modules-connected-users-connectedusers-offdisconnect}

```lua
connectedUsers.offDisconnect(handle: number) -> boolean
```

Drop a disconnect subscription by its handle. True when a live subscription carried it.

**Parameters**

- `handle` `number`

**Returns** `boolean`

## typed/builtin//modules/connected_users/connectedUsers/offLocalConnect {#typed-builtin-modules-connected-users-connectedusers-offlocalconnect}

```lua
connectedUsers.offLocalConnect(handle: number) -> boolean
```

Drop a local-connect subscription by its handle. True when a live subscription carried it.

**Parameters**

- `handle` `number`

**Returns** `boolean`

## typed/builtin//modules/connected_users/connectedUsers/onConnect {#typed-builtin-modules-connected-users-connectedusers-onconnect}

```lua
connectedUsers.onConnect(callback: (connectedUser) -> ()) -> number
```

Run a callback each time a user connects. Answers the handle `offConnect` takes.

**Parameters**

- `callback` `(connectedUser) -> ()`

**Returns** `number`

## typed/builtin//modules/connected_users/connectedUsers/onDisconnect {#typed-builtin-modules-connected-users-connectedusers-ondisconnect}

```lua
connectedUsers.onDisconnect(callback: (connectedUser) -> ()) -> number
```

Run a callback each time a user disconnects. Answers the handle `offDisconnect` takes.

**Parameters**

- `callback` `(connectedUser) -> ()`

**Returns** `number`

## typed/builtin//modules/connected_users/connectedUsers/onLocalConnect {#typed-builtin-modules-connected-users-connectedusers-onlocalconnect}

```lua
connectedUsers.onLocalConnect(callback: (connectedUser) -> ()) -> number
```

Run a callback once the local user's session is established, firing immediately when it already is.

**Parameters**

- `callback` `(connectedUser) -> ()`

**Returns** `number`

## typed/builtin//modules/content_version/M/bump {#typed-builtin-modules-content-version-m-bump}

```lua
M.bump(path: string)
```

Bump `path`'s version counter, invalidating every reader memoized
against its previous value. Called by the `vfs.*` write surface and the
asset-change dispatcher; content code rarely calls it directly.

**Parameters**

- `path` `string` — VFS path whose content changed.

```lua
require("modules.content_version").bump(p)
```

## typed/builtin//modules/content_version/M/get {#typed-builtin-modules-content-version-m-get}

```lua
M.get(path: string) -> number
```

The current version counter for `path` (0 if never written this VM).
A memoized reader stores the value it saw when it parsed, and treats a
later call as a cache hit exactly while `get(path)` still returns it.

## typed/builtin//modules/data_schema/M/applyDefaults {#typed-builtin-modules-data-schema-m-applydefaults}

```lua
M.applyDefaults(merged: { [string]: FieldSpec }, values: { [string]: any }) -> { [string]: any }
```

Produce a NEW value table with every schema default filled in
where `values` has no explicit entry — recursively: struct values
gain their subfield defaults and array elements gain their item
defaults, at every depth. Neither input is mutated.

**Parameters**

- `merged` `{ [string]: FieldSpec }` — Merged field map from `mergeChain`.
- `values` `{ [string]: any }` — The instance's raw value table.

**Returns** `{ [string]: any }` — New table: explicit values + defaults.

```lua
local filled = DS.applyDefaults(merged, rawValues)
```

## typed/builtin//modules/data_schema/M/mergeChain {#typed-builtin-modules-data-schema-m-mergechain}

```lua
M.mergeChain(chain: { Schema? }) -> ({ [string]: FieldSpec }?, { string })
```

Merge an extends chain of parsed schemas into one field map. The
chain is ordered ROOT PARENT FIRST, derived contract LAST. A child
redeclaring a parent field is a problem — shared shape comes from
the parent, per-child shape from new fields.

**Parameters**

- `chain` `{ Schema? }` — Array of Schema, root parent first. A nil hole (e.g. a
failed `parseSchema` result passed straight in) is a problem entry.

**Returns** `({ [string]: FieldSpec }?, { string })` — Merged `{ [string]: FieldSpec }`, or nil if any problem was found. Array of problem strings (empty on success).

```lua
local merged, problems = DS.mergeChain({ itemSchema, weaponSchema })
```

## typed/builtin//modules/data_schema/M/parseSchema {#typed-builtin-modules-data-schema-m-parseschema}

```lua
M.parseSchema(raw: any?) -> (Schema?, { string })
```

Parse a decoded `schema.yaml` table into a Schema. Returns
`(schema, problems)` — schema is nil when any problem was found. `fields`
may be written as a map (name -> spec) or as a sequence of specs each
carrying its own `name:`; both key the resulting fields by name.

**Parameters**

- `raw` `any` _(optional)_ — The decoded document (`{ extends?, fields }`).

**Returns** `(Schema?, { string })` — The parsed Schema, or nil if any problem was found. Array of problem strings (empty on success).

```lua
local schema, problems = DS.parseSchema(Yaml.decode(bytes))
```

## typed/builtin//modules/data_schema/M/validateValues {#typed-builtin-modules-data-schema-m-validatevalues}

```lua
M.validateValues(merged: { [string]: FieldSpec }, values: { [string]: any }, resolvers: Resolvers) -> { Violation }
```

Validate a raw value table against a merged field map. Checks
missing required fields (a field with a default is never missing),
per-field constraints, unknown top-level fields, and ref fields via
the injected resolvers.

**Parameters**

- `merged` `{ [string]: FieldSpec }` — Merged field map from `mergeChain`.
- `values` `{ [string]: any }` — The instance's raw value table.
- `resolvers` `Resolvers` — assetExists / contractSatisfied callbacks.

**Returns** `{ Violation }` — Array of `{ path, message }` violations (empty = valid).

```lua
local violations = DS.validateValues(merged, rawValues, resolvers)
```

## typed/builtin//modules/debris/M/add {#typed-builtin-modules-debris-m-add}

```lua
M.add(id: any?, lifetime: number?) -> DebrisHandle
```

Schedule the entity for despawn after `lifetime` seconds (default 10). Calling again on the same entity replaces the prior deadline. Negative or zero lifetime despawns immediately. Returns a handle for cancel(), or 0 if the entity id couldn't be resolved.

**Parameters**

- `id` `any` _(optional)_ — Entity id, name, or proxy table.
- `lifetime` `number` _(optional)_ — Seconds before despawn — defaults to 10 when nil.

**Returns** `DebrisHandle` — Cancel handle (0 if entity not found).

```lua
local bullet = entity.spawn("Bullet"); debris.add(bullet.id, 2.0)
local h = debris.add(target.id, 5); debris.cancel(h)
```

## typed/builtin//modules/debris/M/cancel {#typed-builtin-modules-debris-m-cancel}

```lua
M.cancel(handleOrId: any?) -> boolean
```

Cancel a pending despawn. Accepts either a handle from `debris.add` or an entity id / proxy. Returns true if a pending record was actually removed.

**Parameters**

- `handleOrId` `any` _(optional)_ — Cancel handle, or entity id / name / proxy.

**Returns** `boolean` — Whether a pending record was removed.

```lua
debris.cancel(handle); debris.cancel(target.id)
```

## typed/builtin//modules/debris/M/clear {#typed-builtin-modules-debris-m-clear}

```lua
M.clear() -> boolean
```

Drop every pending entry. Used by the test suite to isolate cases — not part of the user-facing surface.

**Returns** `boolean` — Always true.

## typed/builtin//modules/debris/M/count {#typed-builtin-modules-debris-m-count}

```lua
M.count() -> number
```

Number of currently pending debris entries — handy for diagnostics overlays.

**Returns** `number` — Pending count.

```lua
print(debris.count(), "pending despawns")
```

## typed/builtin//modules/debris/M/list {#typed-builtin-modules-debris-m-list}

```lua
M.list() -> { DebrisEntry }
```

Snapshot every pending entry as a flat array of `{id, remainingSecs, handle}` records. Order is not stable — don't rely on it.

## typed/builtin//modules/debris/M/pending {#typed-builtin-modules-debris-m-pending}

```lua
M.pending(id: any?) -> number?
```

Return the number of seconds remaining before the entity is despawned, or nil if it isn't scheduled.

**Parameters**

- `id` `any` _(optional)_ — Entity id, name, or proxy.

**Returns** `number?` — Seconds remaining, or nil.

```lua
local s = debris.pending(bullet.id); if s then print("dies in", s) end
```

## typed/builtin//modules/deprecated/zui/theme/M/activate {#typed-builtin-modules-deprecated-zui-theme-m-activate}

```lua
M.activate(name: string) -> boolean
```

Activate a registered theme. Thin wrapper over `ui.setTheme(name)`
for symmetry with `register` / `load`.

**Parameters**

- `name` `string` — The registered theme name to activate.

**Returns** `boolean` — `true` on success, `false` when name is invalid or the FFI binding is missing.

```lua
Theme.activate("dark")
```

## typed/builtin//modules/deprecated/zui/theme/M/defaults {#typed-builtin-modules-deprecated-zui-theme-m-defaults}

```lua
M.defaults() -> TokenMap
```

Return the raw fallback token map shipped with this module. Used
by tests / introspection; not part of the cascade.

**Returns** `TokenMap` — The static `DEFAULTS` table — same reference each call.

```lua
local d = Theme.defaults()
```

## typed/builtin//modules/deprecated/zui/theme/M/load {#typed-builtin-modules-deprecated-zui-theme-m-load}

```lua
M.load(name: string) -> (boolean, string?)
```

Convenience: `require("@builtin::themes." .. name)` then register.
Built-in themes (dark, light, debug) live at
`src/lua/lib/themes/<name>.module/init.luau`.

## typed/builtin//modules/deprecated/zui/theme/M/register {#typed-builtin-modules-deprecated-zui-theme-m-register}

```lua
M.register(name: string, theme: any?) -> (boolean, string?)
```

Register a theme with the engine under `name`. Walks the theme's
tokens + styles, resolves every `$variable` reference (with cycle
detection), and pushes flat values to the active `ThemeRegistry`.

**Parameters**

- `name` `string` — The name to register the theme under.
- `theme` `any` _(optional)_ — The theme table `{ tokens, styles }` — `name` is overridden by the caller-supplied `name`.

**Returns** `(boolean, string?)` — `(true, nil)` on success, or `(false, errMsg)` on cascade error or missing FFI binding.

```lua
local ok, err = Theme.register("dark", themeTable)
```

## typed/builtin//modules/deprecated/zui/theme/M/resolve {#typed-builtin-modules-deprecated-zui-theme-m-resolve}

```lua
M.resolve(theme: any?) -> (ResolvedTheme?, string?)
```

Resolve `$variable` references in a theme table and return the
flat `{ name, tokens, styles }` shape the engine consumes. Pure
function — used by `register` and exposed for tests.

**Parameters**

- `theme` `any` _(optional)_ — A theme table with `name`, `tokens`, `styles`.

**Returns** `(ResolvedTheme?, string?)` — `(resolved, nil)` on success or `(nil, errMsg)` on cascade failure.

```lua
local res, err = Theme.resolve({ name = "dark", tokens = {...} })
```

## typed/builtin//modules/deprecated/zui/theme/M/tokenNames {#typed-builtin-modules-deprecated-zui-theme-m-tokennames}

```lua
M.tokenNames() -> { string }
```

Return the sorted list of token names shipped with this module.
Useful for theme editors / token pickers.

**Returns** `{ string }` — Sorted array of token name strings.

```lua
for _, n in ipairs(Theme.tokenNames()) do print(n) end
```

## typed/builtin//modules/deprecated/zui/theme/M/with {#typed-builtin-modules-deprecated-zui-theme-m-with}

```lua
M.with(overrides: TokenMap?) -> ThemeView
```

Build a read-only theme view that overlays the given overrides on
top of the engine-or-defaults token map. Module functions are
exposed alongside tokens so the view doubles as the namespace.

**Parameters**

- `overrides` `TokenMap` _(optional)_ — Optional table of `{ [tokenName] = value }` overrides.

**Returns** `ThemeView` — A read-only view — index returns override / function / token.

```lua
local view = Theme.with({ accent = "#ff0" })
local view = Theme.with(nil)  -- defaults only
```

## typed/builtin//modules/deprecated/zui/theme/cascade/M/resolveStyles {#typed-builtin-modules-deprecated-zui-theme-cascade-m-resolvestyles}

```lua
M.resolveStyles(theme: any?, resolvedTokens: any?) -> (StyleMap?, string?)
```

Walk `theme.styles` and resolve every `$reference` inside style
values against `resolvedTokens`. Returns a `{ [selector]: { [prop]:
value } }` map with no remaining `$variable` strings. Selector and
property keys pass through unchanged (cascade ordering is the
caller's concern).

**Parameters**

- `theme` `any` _(optional)_ — A theme-shaped table with a `styles` field.
- `resolvedTokens` `any` _(optional)_ — Pre-flattened tokens (output of `resolveTokens`).

**Returns** `(StyleMap?, string?)` — `(flatStyles, nil)` on success or `(nil, errMsg)` on first cycle / unknown reference.

```lua
local styles, err = Cascade.resolveStyles({ styles = { ["btn"] = { color = "$accent" } } }, tokens)
```

## typed/builtin//modules/deprecated/zui/theme/cascade/M/resolveTokens {#typed-builtin-modules-deprecated-zui-theme-cascade-m-resolvetokens}

```lua
M.resolveTokens(theme: any?) -> (TokenMap?, string?)
```

Walk `theme.tokens` and resolve every `$reference` to a literal.
Tokens that reference other tokens are flattened — after this pass,
every value is a literal string / number / etc.

**Parameters**

- `theme` `any` _(optional)_ — A theme-shaped table with a `tokens` field.

**Returns** `(TokenMap?, string?)` — `(flatTable, nil)` on success or `(nil, errMsg)` on first cycle / unknown reference. Errors include the offending key for debugging.

```lua
local tokens, err = Cascade.resolveTokens({ tokens = { a = "$b", b = "#fff" } })
```

## typed/builtin//modules/deprecated/zui/widget/canvas/canvas {#typed-builtin-modules-deprecated-zui-widget-canvas-canvas}

```lua
canvas(id: string?, opts: CanvasOpts?) -> any
```

Build a 2D-paint canvas widget. The widget body is a list of paint
commands (line, bezier, polyline, rect, circle, text) drawn in
widget-local coords. Pointer/keyboard/scroll handlers are wired
through as engine props.

**Parameters**

- `id` `string` _(optional)_ — Widget id used by the engine for event routing and DOM mirror.
- `opts` `CanvasOpts` _(optional)_ — Options table — commands array plus optional width/height,
interaction handlers, role/tag overrides, ARIA passthroughs (any
`aria*` key), and a style table.

**Returns** `any` — A widget node consumable by the renderer.

```lua
canvas("my-canvas", { commands = { { kind = "circle", center = {50,50}, radius = 20, fill = "#FF8855" } } })
canvas("plot", { commands = {}, onDrag = "plot:drag", style = { width = 400, height = 200 } })
```

## typed/builtin//modules/deprecated/zui/widget/node/node {#typed-builtin-modules-deprecated-zui-widget-node-node}

```lua
node(widgetType: string, opts: Opts?, children: any?) -> any
```

Build a generic widget table with optional id, classes, props,
style, and children. The constructor every zui widget composes on.
Accepts either a single child or an array of children — single
children get wrapped automatically, matching the `scroll.module`
precedent.

**Parameters**

- `widgetType` `string` — The widget kind string (e.g. `"label"`, `"panel"`,
`"canvas"`).
- `opts` `Opts` _(optional)_ — Optional. `id`, `classes` (or `class`), `props`, `style`.
- `children` `any` _(optional)_ — Optional widget table or array of widget tables.

**Returns** `any` — The widget table — interoperable with hand-written trees.

```lua
local n = node("label", { props = { text = "Hi" } })
local n = node("panel", { id = "p1" }, { childWidget })
```

## typed/builtin//modules/editor/component_inspectors/M/get {#typed-builtin-modules-editor-component-inspectors-m-get}

```lua
M.get(typeName: string) -> InspectorView?
```

Look up the registered view for a component type. Returns nil when the
type has no custom inspector (the caller renders the generic fields alone).

## typed/builtin//modules/editor/component_inspectors/M/register {#typed-builtin-modules-editor-component-inspectors-m-register}

```lua
M.register(typeName: string, view: InspectorView)
```

Register a custom inspector view for a component type. Idempotent —
re-registering replaces the previous view (hot-reload re-runs component
load code, so last-write-wins is the correct semantic).

**Parameters**

- `typeName` `string` — The component's short authored name (e.g. "Generator").
- `view` `InspectorView` — `{ sections = fn(entityId, proxy) -> { fields, actions }? }`.

```lua
Inspectors.register("Generator", require("~.generator_inspector"))
```

## typed/builtin//modules/entity_hierarchy/M/swap {#typed-builtin-modules-entity-hierarchy-m-swap}

```lua
M.swap(entityId: string, assetPath: string, opts: SwapOpts?) -> (string?, string?)
```

Replace a blockout entity with a generated/imported asset, fitting the asset to the source's bounds and inheriting the source's world rotation. The new entity is reparented to the source's parent, optionally inherits the source name, and the original is despawned.

**Parameters**

- `entityId` `string` — The entity to replace (must exist). Must be a non-empty string.
- `assetPath` `string` — The asset path to spawn. Must be a non-empty string.
- `opts` `SwapOpts` _(optional)_ — Optional `SwapOpts`. Fields: `fit` (`"bounds"` default | `"bounds_xy"` | `"none"`), `source_origin` (`"bottom"` default | `"center"` | `"top"`), `asset_origin` (same set), `keep` (e.g. `{"name"}`), `timeout` (optional seconds override for the async asset-bounds wait; default is a generous load-scaled poll budget — leave unset).

**Returns** `(string?, string?)` — `(newEntityId, nil)` on success; `(nil, errmsg)` on failure (invalid args, missing source, asset bounds timeout).

```lua
local id, err = EntityHierarchy.swap("blockout", "@builtin::meshes.cube")
local id, err = EntityHierarchy.swap("blockout", asset, { fit = "bounds_xy", keep = { "name" } })
```

## typed/builtin//modules/entity_records/M/authoredComponentData {#typed-builtin-modules-entity-records-m-authoredcomponentdata}

```lua
M.authoredComponentData(rid: string, componentType: string, instanceName: string?, data: any?) -> any
```

A component instance's snapshot with the fields the instance wrote
about its own runtime removed, leaving what states how it was CONFIGURED.
A capture reads it to build the record, and whoever diffs a live entity
against that record reads it too, so both sides speak the same fields.

**Parameters**

- `rid` `string` — Runtime entity id carrying the instance.
- `componentType` `string` — Component type name as the entity reports it.
- `instanceName` `string` _(optional)_ — Name of the instance, or nil for an anonymous one.
- `data` `any` _(optional)_ — Snapshot of the instance's public data.

**Returns** `any` — The snapshot without the instance's own runtime bookkeeping.

```lua
local d = EntityRecords.authoredComponentData(id, ty, nil, snapshot)
```

## typed/builtin//modules/entity_records/M/captureRecord {#typed-builtin-modules-entity-records-m-capturerecord}

```lua
M.captureRecord(rid: string, parentOriginalId: string?) -> any
```

Capture ONE entity into a template record. Reads LIVE component public
state (serialized component snapshots), not init data, so the record
matches what is on screen. Each component INSTANCE gets its own entry,
carrying `instance_name` when the instance has one, so a type the entity
carries several of comes back as the same several. The record also
carries the entity's own
`active` flag, every attribute it holds, and its lifecycle mode and
replication scope when either is other than the default. The entity's
runtime id IS its record `original_id`, so cross-entity component
references — which already point at runtime ids — round-trip and get
remapped on the next instantiate. Each component entry names the fields
holding such a reference in `entity_fields`, taken from the component's
declared field kinds, so a rebuild resolves exactly those.

**Parameters**

- `rid` `string` — Runtime entity id to capture.
- `parentOriginalId` `string` _(optional)_ — Parent's original_id, or nil for a root record.

**Returns** `any` — One record table.

```lua
local rec = EntityRecords.captureRecord(id, nil)
```

## typed/builtin//modules/entity_records/M/componentIsCodeAttached {#typed-builtin-modules-entity-records-m-componentiscodeattached}

```lua
M.componentIsCodeAttached(rid: string, componentType: string) -> boolean
```

Whether another component's lifecycle attached this component instance,
rather than an author putting it there. A composed asset brings its own
machinery with it — a humanoid avatar attaches a character controller to
the body it expands into — and that machinery comes back on its own
wherever the composition does. A record that named it would put a second
one beside the one the expansion just produced, and a rebuild that removed
every component its records leave unnamed would tear the expansion off the
entity it belongs to. Both sides of a rebuild ask this.

Reached through the `_G` singleton the origin module publishes, which is
the same answer the scene serializer takes for the same question; a load
order that has not published it yet reads every component as authored.

**Parameters**

- `rid` `string` — Runtime entity id carrying the instance.
- `componentType` `string` — Component type name as the entity reports it.

**Returns** `boolean` — True when a component's lifecycle attached it.

```lua
if EntityRecords.componentIsCodeAttached(id, "Humanoid") then continue end
```

## typed/builtin//modules/entity_records/M/compose {#typed-builtin-modules-entity-records-m-compose}

```lua
M.compose(rootId: string, rank: { [string]: number }?, skip: { [string]: boolean }?) -> { any }
```

Build the flat record array by walking `rootId`'s hierarchy. Skips
`temporary` entities and their descendants — scaffolding and editor-only
tooling stay out of a baked result. The explicit root is always captured:
the caller named THAT entity as the thing to serialize, so temporary
pruning applies to descendants.

**Parameters**

- `rootId` `string` — Runtime entity id to walk from.
- `rank` `{ [string]: number }` _(optional)_ — Optional map of entity id → integer. Each node's children are
visited in ascending rank, so a caller holding the order its entities were
created in gets that order back. Omitted, the walk orders siblings by name
and then by id.
- `skip` `{ [string]: boolean }` _(optional)_ — Optional set of entity ids, keyed by id. An id it names is left out
along with everything under it — what another owner produces and puts back
itself, which a record here would describe a second time.

**Returns** `{ any }` — Flat array of records, root first, parents before children.

```lua
local records = EntityRecords.compose(rootId)
```

## typed/builtin//modules/entity_records/M/composeMany {#typed-builtin-modules-entity-records-m-composemany}

```lua
M.composeMany(rootIds: { string }, rank: { [string]: number }?, skip: { [string]: boolean }?) -> { any }
```

Compose several roots into one flat record array. A build captures a
SET of roots (a builder may spawn several unparented entities), not the
single root a bundle composes from. The roots are ordered the same way
siblings are — by `rank`, then name, then id.

**Parameters**

- `rootIds` `{ string }` — Array of runtime entity ids.
- `rank` `{ [string]: number }` _(optional)_ — Optional map of entity id → integer, applied to the roots and to
every node's children alike.
- `skip` `{ [string]: boolean }` _(optional)_ — Optional set of entity ids, keyed by id, pruned wherever the walk
reaches one — same rule as `compose`.

**Returns** `{ any }` — Flat array of records covering every root's hierarchy.

```lua
local records = EntityRecords.composeMany({ idA, idB })
```

## typed/builtin//modules/entity_reflect/E/allTypes {#typed-builtin-modules-entity-reflect-e-alltypes}

```lua
E.allTypes() -> { string }
```

List all registered reflectable component types in this engine instance.

**Returns** `{ string }` — Array of component name strings.

```lua
local types = Entity.allTypes()
```

## typed/builtin//modules/entity_reflect/E/distance {#typed-builtin-modules-entity-reflect-e-distance}

```lua
E.distance(entityIdA: string, entityIdB: string) -> number?
```

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

**Parameters**

- `entityIdA` `string` — First entity id.
- `entityIdB` `string` — Second entity id.

**Returns** `number?` — The distance, or `nil` when either entity is missing a position.

```lua
local d = Entity.distance("player", "enemy")
```

## typed/builtin//modules/entity_reflect/E/getComponents {#typed-builtin-modules-entity-reflect-e-getcomponents}

```lua
E.getComponents(entityId: string) -> { string }?
```

List all reflected component types on an entity.

**Parameters**

- `entityId` `string` — The entity id.

**Returns** `{ string }?` — Array of component name strings, or `nil` when the entity has no reflected components.

```lua
local comps = Entity.getComponents("player")
```

## typed/builtin//modules/entity_reflect/E/getField {#typed-builtin-modules-entity-reflect-e-getfield}

```lua
E.getField(entityId: string, component: string, field: string) -> any
```

Get a specific component field value. An engine-struct component
reads through reflection; a component declared in Luau reads through its
component ref, so one call serves both.

**Parameters**

- `entityId` `string` — The entity id.
- `component` `string` — The component name (e.g. `"Transform"`, `"Model"`).
- `field` `string` — The field name (e.g. `"position"`, `"tintBlend"`).

**Returns** `any` — The field value, or `nil` when the entity/component/field is missing. A component name this engine does not declare raises.

```lua
local pos = Entity.getField("player", "Transform", "position")
```

## typed/builtin//modules/entity_reflect/E/getName {#typed-builtin-modules-entity-reflect-e-getname}

```lua
E.getName(entityId: string) -> string?
```

Get the name of an entity from its `Name` component.

**Parameters**

- `entityId` `string` — The entity id.

**Returns** `string?` — The name string, or `nil` when the entity has no `Name` component.

```lua
local name = Entity.getName("player")
```

## typed/builtin//modules/entity_reflect/E/getPosition {#typed-builtin-modules-entity-reflect-e-getposition}

```lua
E.getPosition(entityId: string) -> Vec3?
```

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

**Parameters**

- `entityId` `string` — The entity id.

**Returns** `Vec3?` — The position `{ x, y, z }`, or `nil` when the entity has no Transform.

```lua
local pos = Entity.getPosition("player")
```

## typed/builtin//modules/entity_reflect/E/getRotation {#typed-builtin-modules-entity-reflect-e-getrotation}

```lua
E.getRotation(entityId: string) -> Quat?
```

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

**Parameters**

- `entityId` `string` — The entity id.

**Returns** `Quat?` — The rotation quaternion `{ x, y, z, w }`, or `nil` when the entity has no Transform.

```lua
local rot = Entity.getRotation("player")
```

## typed/builtin//modules/entity_reflect/E/getScale {#typed-builtin-modules-entity-reflect-e-getscale}

```lua
E.getScale(entityId: string) -> Vec3?
```

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

**Parameters**

- `entityId` `string` — The entity id.

**Returns** `Vec3?` — The scale `{ x, y, z }`, or `nil` when the entity has no Transform.

```lua
local scale = Entity.getScale("player")
```

## typed/builtin//modules/entity_reflect/E/getSchema {#typed-builtin-modules-entity-reflect-e-getschema}

```lua
E.getSchema(componentName: string) -> { ComponentFieldSchema }?
```

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

**Parameters**

- `componentName` `string` — The component name.

**Returns** `{ ComponentFieldSchema }?` — Array of `{ name, type }` schema entries, or `nil` when the component is not registered.

```lua
local schema = Entity.getSchema("Transform")
```

## typed/builtin//modules/entity_reflect/E/isVisible {#typed-builtin-modules-entity-reflect-e-isvisible}

```lua
E.isVisible(entityId: string) -> boolean
```

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

**Parameters**

- `entityId` `string` — The entity id.

**Returns** `boolean` — `true` when visible (or no `Visible` component is present), `false` when explicitly hidden.

```lua
local visible = Entity.isVisible("player")
```

## typed/builtin//modules/entity_reflect/E/patch {#typed-builtin-modules-entity-reflect-e-patch}

```lua
E.patch(entityId: string, component: string, fields: { [string]: any }) -> boolean
```

Patch multiple fields on a single component at once. Serves an
engine-struct component and a component declared in Luau alike.

**Parameters**

- `entityId` `string` — The entity id.
- `component` `string` — The component name.
- `fields` `{ [string]: any }` — `{ fieldName = value, ... }` map of fields to write.

**Returns** `boolean` — `true` when every named field was written. A component name this engine does not declare raises.

```lua
Entity.patch("player", "Transform", { position = pos, scale = scl })
```

## typed/builtin//modules/entity_reflect/E/setField {#typed-builtin-modules-entity-reflect-e-setfield}

```lua
E.setField(entityId: string, component: string, field: string, value: any?) -> boolean
```

Set a specific component field value. An engine-struct component
writes through reflection; a component declared in Luau writes through its
component ref, so one call serves both.

**Parameters**

- `entityId` `string` — The entity id.
- `component` `string` — The component name.
- `field` `string` — The field name.
- `value` `any` _(optional)_ — The new value.

**Returns** `boolean` — `true` when the write succeeded, `false` otherwise. A component name this engine does not declare raises.

```lua
Entity.setField("player", "Transform", "position", { x = 0, y = 1, z = 0 })
```

## typed/builtin//modules/entity_reflect/E/setPosition {#typed-builtin-modules-entity-reflect-e-setposition}

```lua
E.setPosition(entityId: string, pos: Vec3)
```

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

**Parameters**

- `entityId` `string` — The entity id.
- `pos` `Vec3` — The new position `{ x, y, z }`.

```lua
Entity.setPosition("player", { x = 0, y = 1, z = 0 })
```

## typed/builtin//modules/entity_reflect/E/setScale {#typed-builtin-modules-entity-reflect-e-setscale}

```lua
E.setScale(entityId: string, scale: Vec3)
```

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

**Parameters**

- `entityId` `string` — The entity id.
- `scale` `Vec3` — The new scale `{ x, y, z }`.

```lua
Entity.setScale("player", { x = 1, y = 1, z = 1 })
```

## typed/builtin//modules/entity_reflect/E/snapshot {#typed-builtin-modules-entity-reflect-e-snapshot}

```lua
E.snapshot(entityId: string) -> any
```

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

**Parameters**

- `entityId` `string` — The entity id.

**Returns** `any` — The snapshot table, or `nil` when the entity does not exist.

```lua
local snap = Entity.snapshot("player")
```

## typed/builtin//modules/entity_signals/M/get {#typed-builtin-modules-entity-signals-m-get}

```lua
M.get(entityId: string, phase: string) -> any
```

Return the `onDestroying`/`onDestroyed` signal for an entity,
creating it on first access. `phase` is "destroying" or "destroyed".

## typed/builtin//modules/field/Field/alias {#typed-builtin-modules-field-field-alias}

```lua
Field.alias(target: string | { string }, description: string?) -> FieldDesc<any>
```

Alias for one or more existing fields. An alias is an
ACCEPTED key that is not stored itself — it routes the
written value to the real field(s) it points at, so a component
answers to a caller's natural key without hand-rolling translation
code, and both the runtime and the LSP recognise the key.

The key works everywhere the fields it targets do: as a
`component.add` init key, and as a read and a write on the live
component. Reading it returns what the target(s) hold right now.

Two forms:
- `Field.alias("radius")` — rename. The value is written verbatim
to the single target field (running that field's normal
coercion, so an alias onto an assetRef field resolves the ref),
and reads back as that field's value.
- `Field.alias({ "colorR", "colorG", "colorB" })` — fan-out. The
value is destructured across the targets: an array `{a, b, c}`
positionally, or a named `{r=, g=, b=}` / `{x=, y=, z=}` table
by the target's position (r/x, g/y, b/z, a/w). It reads back as
an array in target order, so `c.color = c.color` round-trips.

An alias never replicates and is never persisted — the fields it
targets own their own Sync/NoSync, so no mode argument is taken.

**Parameters**

- `target` `string | { string }` — A single target field name, or an array of target field names.
- `description` `string` _(optional)_ — Documents the alias for the LSP; nil to leave it undocumented.

**Returns** `FieldDesc<any>` — FieldDesc descriptor with `kind = "alias"`.

```lua
type  = Field.alias("kind")
color = Field.alias({ "colorR", "colorG", "colorB" })
```

## typed/builtin//modules/field/Field/assetRef {#typed-builtin-modules-field-field-assetref}

```lua
Field.assetRef(category: C & string, default: AssetRef<C> | I | nil?, mode: SyncMode, marker: (SerializedMode | string | FieldOptions)?) -> FieldDesc<AssetRef<C, I>>
```

Typed asset reference field. `C` is the asset category — a
singleton string type inferred from the `category` argument
(`"material"`, `"mesh"`, `"@user/customCategory"`, etc.). One
constructor handles every category, including user-registered ones.

Default accepts a resolved `AssetRef<C>` handle, an identity string
(full `@library::path` form OR a bare leaf name resolved
category-locally via `asset.resolve(identity, category)`), or `nil`.

At registration the engine resolves any string default through the
same category-aware resolver `public_newindex` uses for runtime
writes, so the first read of `public.<field>` already returns a
resolved envelope — not a raw string.

**Parameters**

- `category` `C & string` — Asset category as a string literal (`"material"`, `"mesh"`, etc.). Inferred into `C`.
- `default` `AssetRef<C> | I | nil` _(optional)_ — AssetRef envelope, identity string, or nil.
- `mode` `SyncMode` — `Sync` or `NoSync` — required.
- `marker` `(SerializedMode | string | FieldOptions)` _(optional)_ — `Serialized`, a description string, or a `{ serialized, description }` options table; omit for neither.

**Returns** FieldDesc<AssetRef<C, I>> descriptor.

```lua
material = Field.assetRef("material", "@my-library::materials.gold", Sync)
source = Field.assetRef("bundle", nil, Sync)
```

## typed/builtin//modules/field/Field/bitmask {#typed-builtin-modules-field-field-bitmask}

```lua
Field.bitmask(bits: number, default: number?, mode: SyncMode, marker: (SerializedMode | string | FieldOptions)?) -> FieldDesc<number>
```

Bit-mask number field. `bits` declares the width the consumer can
address; a default or a write that is not a whole number in
`0 .. 2^bits - 1` is rejected, naming the width. Use it wherever a numeric
field is read as a set of bits rather than as a quantity — what the field
reads back is then a mask, so a read-back is evidence the value took.

**Parameters**

- `bits` `number` — How many bits wide the mask is, 1..53.
- `default` `number` _(optional)_ — Numeric default for `public.<field>`, or nil to leave it unset.
- `mode` `SyncMode` — `Sync` or `NoSync` — required.
- `marker` `(SerializedMode | string | FieldOptions)` _(optional)_ — `Serialized`, a description string, or a `{ serialized, description }` options table; omit for neither.

**Returns** FieldDesc<number> descriptor carrying a `bitmask` constraint.

```lua
lightChannels = Field.bitmask(32, 0, Sync)
```

## typed/builtin//modules/field/Field/bool {#typed-builtin-modules-field-field-bool}

```lua
Field.bool(default: boolean?, mode: SyncMode, marker: (SerializedMode | string | FieldOptions)?) -> FieldDesc<boolean>
```

Boolean field. `nil` leaves the field unset.

**Parameters**

- `default` `boolean` _(optional)_ — Boolean default for `public.<field>`, or nil to leave it unset.
- `mode` `SyncMode` — `Sync` or `NoSync` — required.
- `marker` `(SerializedMode | string | FieldOptions)` _(optional)_ — `Serialized`, a description string, or a `{ serialized, description }` options table; omit for neither.

**Returns** FieldDesc<boolean> descriptor.

```lua
enabled = Field.bool(true, Sync)
```

## typed/builtin//modules/field/Field/color {#typed-builtin-modules-field-field-color}

```lua
Field.color(default: color?, mode: SyncMode, marker: (SerializedMode | string | FieldOptions)?) -> FieldDesc<color>
```

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

**Parameters**

- `default` `color` _(optional)_ — color default for `public.<field>`.
- `mode` `SyncMode` — `Sync` or `NoSync` — required.
- `marker` `(SerializedMode | string | FieldOptions)` _(optional)_ — `Serialized`, a description string, or a `{ serialized, description }` options table; omit for neither.

**Returns** FieldDesc<color> descriptor.

```lua
tint = Field.color({ 1, 1, 1, 1 }, Sync)
```

## typed/builtin//modules/field/Field/componentRef {#typed-builtin-modules-field-field-componentref}

```lua
Field.componentRef(componentType: T & string, default: ComponentRef<T> | nil?, mode: SyncMode, marker: (SerializedMode | string | FieldOptions)?) -> 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.

**Parameters**

- `componentType` `T & string` — Component type name as a string literal. Inferred into `T`.
- `default` `ComponentRef<T> | nil` _(optional)_ — ComponentRef envelope or nil.
- `mode` `SyncMode` — `Sync` or `NoSync` — required.
- `marker` `(SerializedMode | string | FieldOptions)` _(optional)_ — `Serialized`, a description string, or a `{ serialized, description }` options table; omit for neither.

**Returns** FieldDesc<ComponentRef<T>> descriptor.

```lua
aimCam = Field.componentRef("Camera", nil, NoSync)
```

## typed/builtin//modules/field/Field/dataRef {#typed-builtin-modules-field-field-dataref}

```lua
Field.dataRef(contract: C & string, default: AssetRef<"data"> | string | nil?, mode: SyncMode, marker: (SerializedMode | string | FieldOptions)?) -> 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.

**Parameters**

- `contract` `C & string` — The required dataType contract identity. Inferred into `C`.
- `default` `AssetRef<"data"> | string | nil` _(optional)_ — AssetRef envelope, identity string, or nil.
- `mode` `SyncMode` — `Sync` or `NoSync` — required.
- `marker` `(SerializedMode | string | FieldOptions)` _(optional)_ — `Serialized`, a description string, or a `{ serialized, description }` options table; omit for neither.

**Returns** FieldDesc<AssetRef<"data">> descriptor.

```lua
weapon = Field.dataRef("weapon", nil, Sync)
```

## typed/builtin//modules/field/Field/entityRef {#typed-builtin-modules-field-field-entityref}

```lua
Field.entityRef(default: EntityRef | string | nil?, mode: SyncMode, marker: (SerializedMode | string | FieldOptions)?) -> 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.

**Parameters**

- `default` `EntityRef | string | nil` _(optional)_ — Live entity proxy, entity-id string, or nil.
- `mode` `SyncMode` — `Sync` or `NoSync` — required.
- `marker` `(SerializedMode | string | FieldOptions)` _(optional)_ — `Serialized`, a description string, or a `{ serialized, description }` options table; omit for neither.

**Returns** FieldDesc<EntityRef> descriptor.

```lua
target = Field.entityRef(nil, Sync)
```

## typed/builtin//modules/field/Field/enum {#typed-builtin-modules-field-field-enum}

```lua
Field.enum(values: { string }, default: string?, mode: SyncMode, marker: (SerializedMode | string | FieldOptions)?) -> FieldDesc<string>
```

Closed-set string field. `values` declares every member; a default or a
write outside the set is rejected with the whole set named. The editor
renders the members as a choice and the LSP completes them.

**Parameters**

- `values` `{ string }` — The members, as an array of non-empty, distinct strings.
- `default` `string` _(optional)_ — The default member, or nil to leave the field unset.
- `mode` `SyncMode` — `Sync` or `NoSync` — required.
- `marker` `(SerializedMode | string | FieldOptions)` _(optional)_ — `Serialized`, a description string, or a `{ serialized, description }` options table; omit for neither.

**Returns** FieldDesc<string> descriptor carrying an `enum` constraint.

```lua
fit = Field.enum({ "exact", "hull" }, "hull", Sync)
```

## typed/builtin//modules/field/Field/instantiableRef {#typed-builtin-modules-field-field-instantiableref}

```lua
Field.instantiableRef(default: AssetRef<any> | string | nil?, mode: SyncMode, marker: (SerializedMode | string | FieldOptions)?) -> FieldDesc<AssetRef<any>>
```

Scene-instantiable asset reference field — accepts ANY asset whose
type can be instantiated into a scene, gated by CAPABILITY rather than a
hardcoded type list. Rides the assetRef machinery with no category filter
(any asset type resolves), and the generic field-constraint hook rejects,
on every write and on the registration-time default, any asset whose type
defines no `instantiate` method (`ref:canInstantiate()` is false). A
new scene-instantiable asset type is accepted here the moment it defines
the hook — no edit to this field or its consumers. The uniform
`ref:instantiate(target?, opts?)` is how a consumer then instantiates the
assigned asset (`Asset.component`, a viewport drop, a tool argument).

**Parameters**

- `default` `AssetRef<any> | string | nil` _(optional)_ — AssetRef envelope, identity string, or nil.
- `mode` `SyncMode` — `Sync` or `NoSync` — required.
- `marker` `(SerializedMode | string | FieldOptions)` _(optional)_ — `Serialized`, a description string, or a `{ serialized, description }` options table; omit for neither.

**Returns** FieldDesc<AssetRef<any>> descriptor.

```lua
source = Field.instantiableRef(nil, Sync)
```

## typed/builtin//modules/field/Field/list {#typed-builtin-modules-field-field-list}

```lua
Field.list(element: FieldDesc<any>, mode: SyncMode, marker: (SerializedMode | string | FieldOptions)?) -> 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.

## typed/builtin//modules/field/Field/number {#typed-builtin-modules-field-field-number}

```lua
Field.number(default: number?, mode: SyncMode, marker: (SerializedMode | string | FieldOptions)?) -> FieldDesc<number>
```

Number field. `nil` leaves the field unset, so a component can treat an
absent value as "derive this from somewhere else" without a second field
recording whether the first one was authored.

**Parameters**

- `default` `number` _(optional)_ — Numeric default for `public.<field>`, or nil to leave it unset.
- `mode` `SyncMode` — `Sync` or `NoSync` — required.
- `marker` `(SerializedMode | string | FieldOptions)` _(optional)_ — `Serialized`, a description string, or a `{ serialized, description }` options table; omit for neither.

**Returns** FieldDesc<number> descriptor consumed by component registration.

```lua
positionX = Field.number(0, Sync)
```

## typed/builtin//modules/field/Field/quat {#typed-builtin-modules-field-field-quat}

```lua
Field.quat(default: quat?, mode: SyncMode, marker: (SerializedMode | string | FieldOptions)?) -> FieldDesc<quat>
```

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

**Parameters**

- `default` `quat` _(optional)_ — quat default for `public.<field>`.
- `mode` `SyncMode` — `Sync` or `NoSync` — required.
- `marker` `(SerializedMode | string | FieldOptions)` _(optional)_ — `Serialized`, a description string, or a `{ serialized, description }` options table; omit for neither.

**Returns** FieldDesc<quat> descriptor.

```lua
rotation = Field.quat({ 0, 0, 0, 1 }, Sync)
```

## typed/builtin//modules/field/Field/range {#typed-builtin-modules-field-field-range}

```lua
Field.range(min: number?, max: number?, default: number?, mode: SyncMode, marker: (SerializedMode | string | FieldOptions)?) -> FieldDesc<number>
```

Bounded number field. `min` and `max` declare the interval the value
means something in; a default or a write outside it is rejected with the
interval named. Either bound may be nil, leaving that side open. The value
the field reads back is one the system consuming it can use, and a number
that lands outside is reported where it was written.

**Parameters**

- `min` `number` _(optional)_ — Lowest accepted value, or nil to leave the low side open.
- `max` `number` _(optional)_ — Highest accepted value, or nil to leave the high side open.
- `default` `number` _(optional)_ — Numeric default for `public.<field>`, or nil to leave it unset.
- `mode` `SyncMode` — `Sync` or `NoSync` — required.
- `marker` `(SerializedMode | string | FieldOptions)` _(optional)_ — `Serialized`, a description string, or a `{ serialized, description }` options table; omit for neither.

**Returns** FieldDesc<number> descriptor carrying a `range` constraint.

```lua
volume = Field.range(0, 1, 1, Sync)
```

## typed/builtin//modules/field/Field/resource {#typed-builtin-modules-field-field-resource}

```lua
Field.resource(category: C & string, default: AssetRef<C> | Handle<C> | string | nil?, mode: SyncMode, marker: (SerializedMode | string | FieldOptions)?) -> 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.

**Parameters**

- `category` `C & string` — Resource category string literal (`"mesh"`, `"texture"`, `"material"`, ...). Inferred into `C`.
- `default` `AssetRef<C> | Handle<C> | string | nil` _(optional)_ — `AssetRef<C>` / `Handle<C>` / identity string / nil.
- `mode` `SyncMode` — `Sync` or `NoSync` — required.
- `marker` `(SerializedMode | string | FieldOptions)` _(optional)_ — `Serialized`, a description string, or a `{ serialized, description }` options table; omit for neither.

**Returns** FieldDesc<AssetRef<C> | Handle<C>> descriptor.

```lua
model = Field.resource("mesh", nil, Sync)
```

## typed/builtin//modules/field/Field/string {#typed-builtin-modules-field-field-string}

```lua
Field.string(default: string?, mode: SyncMode, marker: (SerializedMode | string | FieldOptions)?) -> FieldDesc<string>
```

String field. `nil` leaves the field unset.

**Parameters**

- `default` `string` _(optional)_ — String default for `public.<field>`, or nil to leave it unset.
- `mode` `SyncMode` — `Sync` or `NoSync` — required.
- `marker` `(SerializedMode | string | FieldOptions)` _(optional)_ — `Serialized`, a description string, or a `{ serialized, description }` options table; omit for neither.

**Returns** FieldDesc<string> descriptor.

```lua
label = Field.string("hello", Sync)
```

## typed/builtin//modules/field/Field/struct {#typed-builtin-modules-field-field-struct}

```lua
Field.struct(schema: FieldSchema, mode: SyncMode, marker: (SerializedMode | string | FieldOptions)?) -> 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.

**Parameters**

- `schema` `FieldSchema` — Map of subfield name to a Field constructor descriptor.
- `mode` `SyncMode` — Sync or NoSync — required.
- `marker` `(SerializedMode | string | FieldOptions)` _(optional)_ — `Serialized`, a description string, or a `{ serialized, description }` options table; omit for neither.

**Returns** `FieldDesc<StructValue>` — FieldDesc whose value is a table of the subfields' values.

## typed/builtin//modules/field/Field/table {#typed-builtin-modules-field-field-table}

```lua
Field.table(default: T, mode: SyncMode, marker: (SerializedMode | string | FieldOptions)?) -> 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.

**Parameters**

- `default` `T` — Table value to use as the default for `public.<field>`.
- `mode` `SyncMode` — `Sync` or `NoSync` — required.
- `marker` `(SerializedMode | string | FieldOptions)` _(optional)_ — `Serialized`, a description string, or a `{ serialized, description }` options table; omit for neither.

**Returns** FieldDesc<T> descriptor.

```lua
idMap = Field.table({} :: { [string]: string }, NoSync)
```

## typed/builtin//modules/field/Field/taggedRef {#typed-builtin-modules-field-field-taggedref}

```lua
Field.taggedRef(tag: string, default: AssetRef<any> | string | nil?, mode: SyncMode, marker: (SerializedMode | string | FieldOptions)?) -> FieldDesc<AssetRef<any>>
```

Tag-constrained asset reference field — accepts any asset carrying
`tag` in its `.metadata.tags`, whatever its type. This is how a slot
states the KIND of asset it takes (a camera behavior, a player visual)
without naming the assets themselves: a new asset becomes assignable the
moment it is tagged, with no edit here or in the consumer. Rides the
assetRef machinery with no category filter — dependency graph, sync and
rehydration behave exactly like Field.assetRef — and the generic
field-constraint hook rejects an untagged asset on every write and on the
registration-time default. `asset.list({ fields = { tags = tag } })`
enumerates what fits the slot.

**Parameters**

- `tag` `string` — The tag an assigned asset must carry.
- `default` `AssetRef<any> | string | nil` _(optional)_ — AssetRef envelope, identity string, or nil.
- `mode` `SyncMode` — `Sync` or `NoSync` — required.
- `marker` `(SerializedMode | string | FieldOptions)` _(optional)_ — `Serialized`, a description string, or a `{ serialized, description }` options table; omit for neither.

**Returns** FieldDesc<AssetRef<any>> descriptor.

```lua
behavior = Field.taggedRef("cameraBehavior", nil, Sync)
```

## typed/builtin//modules/field/Field/vec2 {#typed-builtin-modules-field-field-vec2}

```lua
Field.vec2(default: vec2?, mode: SyncMode, marker: (SerializedMode | string | FieldOptions)?) -> FieldDesc<vec2>
```

**Parameters**

- `default` `vec2` _(optional)_
- `mode` `SyncMode`
- `marker` `(SerializedMode | string | FieldOptions)` _(optional)_

**Returns** `FieldDesc<vec2>`

## typed/builtin//modules/field/Field/vec3 {#typed-builtin-modules-field-field-vec3}

```lua
Field.vec3(default: vec3?, mode: SyncMode, marker: (SerializedMode | string | FieldOptions)?) -> FieldDesc<vec3>
```

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

**Parameters**

- `default` `vec3` _(optional)_ — vec3 default for `public.<field>`.
- `mode` `SyncMode` — `Sync` or `NoSync` — required.
- `marker` `(SerializedMode | string | FieldOptions)` _(optional)_ — `Serialized`, a description string, or a `{ serialized, description }` options table; omit for neither.

**Returns** FieldDesc<vec3> descriptor.

```lua
offset = Field.vec3({ 0, 0, 0 }, Sync)
```

## typed/builtin//modules/frame_bounds/F/cameraAxes {#typed-builtin-modules-frame-bounds-f-cameraaxes}

```lua
F.cameraAxes(dx: number, dy: number, dz: number) -> CameraAxes
```

The camera's own forward / right / up for a view along an orbit
direction, with right and up taken from the world up.

**Parameters**

- `dx` `number` — Orbit direction X (subject toward camera, unit length).
- `dy` `number` — Orbit direction Y.
- `dz` `number` — Orbit direction Z.

**Returns** `CameraAxes` — `{ forward = {x,y,z}, right = {x,y,z}, up = {x,y,z} }`.

```lua
local axes = FrameBounds.cameraAxes(0, 0.34, 0.94)
```

## typed/builtin//modules/frame_bounds/F/fit {#typed-builtin-modules-frame-bounds-f-fit}

```lua
F.fit(box: Aabb, opts: FitOpts?) -> Framed
```

Solve for a camera pose that frames `box` at the given orbit angle.

**Parameters**

- `box` `Aabb` — The AABB to frame.
- `opts` `FitOpts` _(optional)_ — `{ fov, aspect, margin, angle = { yawDeg, pitchDeg } }`.

**Returns** `Framed` — `{ px, py, pz, cx, cy, cz, distance, radius, fov, near, far, center, size }`.

```lua
local f = FrameBounds.fit(b, { fov = 60, angle = { 0, 20 } })
```

## typed/builtin//modules/frame_bounds/F/fitDistance {#typed-builtin-modules-frame-bounds-f-fitdistance}

```lua
F.fitDistance(hx: number, hy: number, hz: number, dx: number, dy: number, dz: number, tanH: number, tanV: number) -> number
```

Smallest distance along the orbit direction that keeps all eight
corners of a half-extent box inside the frustum.

**Parameters**

- `hx` `number` — Half-extent on X.
- `hy` `number` — Half-extent on Y.
- `hz` `number` — Half-extent on Z.
- `dx` `number` — Orbit direction X (subject toward camera, unit length).
- `dy` `number` — Orbit direction Y.
- `dz` `number` — Orbit direction Z.
- `tanH` `number` — Tangent of the half horizontal FOV.
- `tanV` `number` — Tangent of the half vertical FOV.

**Returns** `number` — The fitting distance.

```lua
local d = FrameBounds.fitDistance(1, 1, 1, 0, 0.34, 0.94, 1.03, 0.58)
```

## typed/builtin//modules/frame_bounds/F/fitDistanceAxes {#typed-builtin-modules-frame-bounds-f-fitdistanceaxes}

```lua
F.fitDistanceAxes(hx: number, hy: number, hz: number, axes: CameraAxes, tanH: number, tanV: number) -> number
```

Smallest distance that keeps all eight corners of a half-extent box
inside the frustum, projected onto explicitly-given camera axes. Callers
that aim by a named station rather than an orbit angle pass their own axes;
`fitDistance` derives them from a direction and calls this.

**Parameters**

- `hx` `number` — Half-extent on the first extent axis.
- `hy` `number` — Half-extent on the second.
- `hz` `number` — Half-extent on the third.
- `axes` `CameraAxes` — `{ forward, right, up }`, in the SAME frame the half-extents are measured in.
- `tanH` `number` — Tangent of the half horizontal FOV.
- `tanV` `number` — Tangent of the half vertical FOV.

**Returns** `number` — The fitting distance, before any margin.

```lua
local d = FrameBounds.fitDistanceAxes(7, 0.25, 7, axes, 1.03, 0.58)
```

## typed/builtin//modules/frame_bounds/F/ofEntity {#typed-builtin-modules-frame-bounds-f-ofentity}

```lua
F.ofEntity(target: any?) -> Aabb?
```

World-space bounds of an entity and its descendants, falling back to
the entity's own mesh bounds.

**Parameters**

- `target` `any` _(optional)_ — An entity proxy.

**Returns** `Aabb?` — AABB or `nil` when the target has no renderable geometry.

```lua
local b = FrameBounds.ofEntity(entity.find("player"))
```

## typed/builtin//modules/frame_bounds/F/union {#typed-builtin-modules-frame-bounds-f-union}

```lua
F.union(boxes: { Aabb }) -> Aabb?
```

Union a list of AABBs into one.

**Parameters**

- `boxes` `{ Aabb }` — Array of `{ min = vec3, max = vec3 }`.

**Returns** `Aabb?` — The enclosing AABB, or `nil` when the list is empty.

```lua
local u = FrameBounds.union({ a:hierarchyBounds(), b:hierarchyBounds() })
```

## typed/builtin//modules/highlight/M/dispatch {#typed-builtin-modules-highlight-m-dispatch}

```lua
M.dispatch(language: string, text: string) -> { Segment }
```

Dispatch a highlighter by language name, with `yml` and `md`
aliases matching the engine's pre-Phase-3 `parse_editor_language`.
Unknown languages return a single default-colored segment so callers
can pass arbitrary user input without crashing.

**Parameters**

- `language` `string` — Language name (`"lua"`, `"json"`, `"yaml"`, `"wgsl"`, `"markdown"`, or aliases `"yml"`/`"md"`).
- `text` `string` — Source text to tokenize.

**Returns** `{ Segment }` — An array of `Segment` records.

```lua
local segs = Z.highlight.dispatch("lua", source)
local segs = Z.highlight.dispatch("md", readme)
```

## typed/builtin//modules/highlight/json/highlightJson {#typed-builtin-modules-highlight-json-highlightjson}

```lua
highlightJson(text: string) -> { Segment }
```

Tokenize a JSON string into colored text segments for the zui
code renderer. Distinguishes object keys (via lookahead for `:`)
from string values, colors numbers (including scientific notation),
bool/null literals, and structural punctuation.

**Parameters**

- `text` `string` — The JSON source to highlight. Coerced via `tostring` and
defaults to `""` when nil.

**Returns** `{ Segment }` — An array of `{ text, color, monospace }` segments suitable for the zui code renderer.

```lua
local segments = highlight('{"a": 1, "b": "two"}')
```

## typed/builtin//modules/highlight/lua/highlightLua {#typed-builtin-modules-highlight-lua-highlightlua}

```lua
highlightLua(text: string) -> { Segment }
```

Tokenize a Luau source string into colored text segments for the
zui code renderer. Walks lines, dispatching the pre-comment portion
through the code tokenizer (string/number/keyword/identifier) and
the `--`-introduced comment tail through the comment color.

**Parameters**

- `text` `string` — The Luau source to highlight. Coerced via `tostring` and
defaults to `""` when nil.

**Returns** `{ Segment }` — An array of `{ text, color, monospace }` segments suitable for the zui code renderer.

```lua
local segments = highlight("local x = 1 -- pi-ish")
```

## typed/builtin//modules/highlight/markdown/highlightMarkdown {#typed-builtin-modules-highlight-markdown-highlightmarkdown}

```lua
highlightMarkdown(text: string) -> { Segment }
```

Tokenize a Markdown source string into colored text segments
for the zui code renderer. Block-level pass recognises fenced code
(```), headings (#), blockquotes (>), bullet and ordered lists;
inline pass within each non-block line recognises inline code,
bold, and links.

**Parameters**

- `text` `string` — The Markdown source to highlight. Coerced via `tostring`
and defaults to `""` when nil.

**Returns** `{ Segment }` — An array of `{ text, color, monospace }` segments suitable for the zui code renderer.

```lua
local segments = highlight("# Title\n**bold**\n")
```

## typed/builtin//modules/highlight/wgsl/highlightWgsl {#typed-builtin-modules-highlight-wgsl-highlightwgsl}

```lua
highlightWgsl(text: string) -> { Segment }
```

Tokenize a WGSL source string into colored text segments for the
zui code renderer. Handles `//` and `/* */` comments, `"..."`
strings with backslash escapes, `@attribute` tokens, numeric
literals with suffixes (`1u`, `0xFF`, `1.0_f32`), and identifiers
dispatched against the WGSL keyword and built-in type tables.

**Parameters**

- `text` `string` — The WGSL source to highlight. Coerced via `tostring` and
defaults to `""` when nil.

**Returns** `{ Segment }` — An array of `{ text, color, monospace }` segments suitable for the zui code renderer.

```lua
local segments = highlight("@vertex fn main() -> vec4<f32> {}")
```

## typed/builtin//modules/highlight/yaml/highlightYaml {#typed-builtin-modules-highlight-yaml-highlightyaml}

```lua
highlightYaml(text: string) -> { Segment }
```

Tokenize a YAML source string into colored text segments for
the zui code renderer. Splits each line on a `#` comment first,
then on the first `:` to extract a key from its value; the value
is then classified as quoted string / bool / null / numeric / plain.

**Parameters**

- `text` `string` — The YAML source to highlight. Coerced via `tostring` and
defaults to `""` when nil.

**Returns** `{ Segment }` — An array of `{ text, color, monospace }` segments suitable for the zui code renderer.

```lua
local segments = highlight("name: zero\n# comment\n")
```

## typed/builtin//modules/jobs/JobHandle/cancel {#typed-builtin-modules-jobs-jobhandle-cancel}

```lua
JobHandle.cancel(self) -> boolean
```

Drop one refcount. The last drop unregisters the job and the dispatcher stops invoking it.

**Parameters**

- `self`

**Returns** `boolean`

## typed/builtin//modules/jobs/JobHandle/destroy {#typed-builtin-modules-jobs-jobhandle-destroy}

```lua
JobHandle.destroy(self) -> boolean
```

Drop one refcount. The last drop unregisters the job and the dispatcher stops invoking it.

**Parameters**

- `self`

**Returns** `boolean`

## typed/builtin//modules/jobs/JobHandle/id {#typed-builtin-modules-jobs-jobhandle-id}

```lua
JobHandle.id -> number
```

This job's substrate id. Zero once the handle has been cancelled.

## typed/builtin//modules/jobs/JobHandle/info {#typed-builtin-modules-jobs-jobhandle-info}

```lua
JobHandle.info(self) -> JobInfo?
```

This job's latest snapshot row, or nil once the substrate no longer tracks it.

**Parameters**

- `self`

**Returns** `JobInfo?`

## typed/builtin//modules/jobs/JobHandle/pause {#typed-builtin-modules-jobs-jobhandle-pause}

```lua
JobHandle.pause(self) -> boolean
```

Skip this job on subsequent ticks, leaving it registered. False once the substrate no longer tracks it.

**Parameters**

- `self`

**Returns** `boolean`

## typed/builtin//modules/jobs/JobHandle/resume {#typed-builtin-modules-jobs-jobhandle-resume}

```lua
JobHandle.resume(self) -> boolean
```

Run this job again, clearing an errored status. False once the substrate no longer tracks it.

**Parameters**

- `self`

**Returns** `boolean`

## typed/builtin//modules/jobs/JobHandle/status {#typed-builtin-modules-jobs-jobhandle-status}

```lua
JobHandle.status(self) -> JobStatus?
```

This job's scheduler status, or nil once the substrate no longer tracks it.

**Parameters**

- `self`

**Returns** `JobStatus?`

## typed/builtin//modules/jobs/JobHandle/valid {#typed-builtin-modules-jobs-jobhandle-valid}

```lua
JobHandle.valid(self) -> boolean
```

Whether the substrate still tracks this job.

**Parameters**

- `self`

**Returns** `boolean`

## typed/builtin//modules/jobs/M/find {#typed-builtin-modules-jobs-m-find}

```lua
M.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.

**Parameters**

- `name` `string` — Job name supplied to `jobs.register`.

**Returns** `JobHandle?` — JobHandle or nil.

```lua
local job = jobs.find("animation_blend_main")
```

## typed/builtin//modules/jobs/M/inspect {#typed-builtin-modules-jobs-m-inspect}

```lua
M.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.

**Parameters**

- `target` `JobHandle | string` — JobHandle, or job name string.

**Returns** `JobInfo?` — Snapshot row or nil.

```lua
local info = jobs.inspect("animation_blend_main")
```

## typed/builtin//modules/jobs/M/list {#typed-builtin-modules-jobs-m-list}

```lua
M.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.

## typed/builtin//modules/jobs/M/register {#typed-builtin-modules-jobs-m-register}

```lua
M.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  - `"compute"` → the shader reference resolves to its registration key, and the job queues one dispatch per frame.\n\n`origin` 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.

**Parameters**

- `descriptor` `table` — Job declaration with the `JobDescriptor` shape — `name?`, `phase`, `reads?`, `writes?`, `executor`, `ordering?`, `pure?`, `origin?`, `metadata?`. Param is typed as `table` rather than `JobDescriptor` because the LSP doesn't yet narrow string literals to their literal types in record fields, so a `JobDescriptor` annotation rejects the tagged-union `executor` discriminator on every call site (literal `kind = "kernel"` infers as `kind: string`, doesn't subtype `KernelExecutor.kind: "kernel"`). Runtime validation in `__jobs.register` enforces the actual structure; see the `JobDescriptor` type alias above for the canonical shape.

**Returns** `JobHandle?` — JobHandle or nil.

```lua
local job = jobs.register({ phase = "main", executor = { kind = "kernel", kernel = "copy_buffer" }, reads = {{resource={kind="buffer",id=src.id},mode="r"}}, writes = {{resource={kind="buffer",id=dst.id},mode="w"}} })
local job = jobs.register({ phase = "main", executor = { kind = "luau", run = function() print("tick") end } })
local job = jobs.register({ phase = "main", executor = { kind = "compute", shader = asset.resolve("carve", "computeShader"), buffers = { "heights" }, workgroups = { 64 } } })
```

## typed/builtin//modules/jobs/jobhandle_cancel {#typed-builtin-modules-jobs-jobhandle-cancel}

```lua
jobhandle_cancel(self: JobHandle) -> boolean
```

Cancel the job — drops one refcount, last drop unregisters and the dispatcher stops invoking it. Symmetric with `vfs.remove("/runtime/jobs/<phase>/<id>")`.

**Parameters**

- `self` `JobHandle` — JobHandle returned by `jobs.register`.

**Returns** `boolean` — True if the substrate still tracked the job at call time.

```lua
job:cancel()
```

## typed/builtin//modules/jobs/jobhandle_info {#typed-builtin-modules-jobs-jobhandle-info}

```lua
jobhandle_info(self: JobHandle) -> JobInfo?
```

Latest snapshot row for this job (id, name, phase, status, origin, metadata, reads, writes…). Single FFI crossing — pulls only this job's row, not the full registry.

**Parameters**

- `self` `JobHandle` — JobHandle returned by `jobs.register`.

**Returns** `JobInfo?` — Snapshot row or nil if the job is no longer tracked.

```lua
local info = job:info(); print(info.origin)
```

## typed/builtin//modules/jobs/jobhandle_pause {#typed-builtin-modules-jobs-jobhandle-pause}

```lua
jobhandle_pause(self: JobHandle) -> boolean
```

Pause the job — skipped on subsequent ticks but stays registered.

**Parameters**

- `self` `JobHandle` — JobHandle returned by `jobs.register`.

**Returns** `boolean` — True if the substrate still tracked the job.

```lua
local job = jobs.register({...}); job:pause()
```

## typed/builtin//modules/jobs/jobhandle_resume {#typed-builtin-modules-jobs-jobhandle-resume}

```lua
jobhandle_resume(self: JobHandle) -> boolean
```

Resume a paused or errored job (clears `Errored` → `Pending`).

**Parameters**

- `self` `JobHandle` — JobHandle returned by `jobs.register`.

**Returns** `boolean` — True if the substrate still tracked the job.

```lua
job:resume()
```

## typed/builtin//modules/jobs/jobhandle_status {#typed-builtin-modules-jobs-jobhandle-status}

```lua
jobhandle_status(self: JobHandle) -> JobStatus?
```

Read the job's current scheduler status.

**Parameters**

- `self` `JobHandle` — JobHandle returned by `jobs.register`.

**Returns** `JobStatus?` — "pending" / "running" / "errored", or nil if the id is no longer tracked.

```lua
local s = job:status() -- "pending"
```

## typed/builtin//modules/jobs/jobhandle_valid {#typed-builtin-modules-jobs-jobhandle-valid}

```lua
jobhandle_valid(self: JobHandle) -> boolean
```

Whether the substrate still tracks this job (false after :cancel/:destroy).

**Parameters**

- `self` `JobHandle` — JobHandle returned by `jobs.register`.

**Returns** `boolean` — True if the underlying job is still registered.

```lua
if not job:valid() then return end
```

## typed/builtin//modules/json/Json/decode {#typed-builtin-modules-json-json-decode}

```lua
Json.decode(str: string) -> any
```

Decode a JSON string to a Lua value. Returns the decoded value, or `nil` + error message on failure.

**Parameters**

- `str` `string` — The JSON string to decode.

**Returns** `any` — The decoded Lua value. On failure, returns `nil` (and the error message in the second return value).

```lua
local v = Json.decode('{"a":1,"b":"hi"}') -- → { a = 1, b = "hi" }
local v, err = Json.decode("bad")        -- → nil, "Invalid literal..."
```

## typed/builtin//modules/json/Json/encode {#typed-builtin-modules-json-json-encode}

```lua
Json.encode(value: any?, indent: string?, currentIndent: string?) -> string
```

Encode a Lua value to a compact JSON string. Functions and unknown types serialise to `null`; NaN/Inf serialise to `null` (JSON has no representation for them).

**Parameters**

- `value` `any` _(optional)_ — Any Lua value (nil, boolean, number, string, table).
- `indent` `string` _(optional)_ — Optional indent string. Reserved — the compact encoder ignores it; use `encodePretty` for indented output.
- `currentIndent` `string` _(optional)_ — Optional current-depth indent string. Reserved.

**Returns** `string` — The encoded JSON string.

```lua
local s = Json.encode({ type = "button", text = "Click Me" })
```

## typed/builtin//modules/json/Json/encodeArgs {#typed-builtin-modules-json-json-encodeargs}

```lua
Json.encodeArgs(...: any?) -> string
```

Encode a list of arguments as a JSON array string. Useful when forwarding varargs to a JSON-based bridge.

**Parameters**

- `...` `any` _(optional)_ — Any number of values to encode.

**Returns** `string` — The encoded JSON array string.

```lua
local s = Json.encodeArgs("foo", 1, true) -- '["foo",1,true]'
```

## typed/builtin//modules/json/Json/encodePretty {#typed-builtin-modules-json-json-encodepretty}

```lua
Json.encodePretty(value: any?, indentStr: string?) -> string
```

Encode a Lua value to a pretty-printed JSON string. Indents nested values and sorts object keys for diff-friendly output.

**Parameters**

- `value` `any` _(optional)_ — Any Lua value.
- `indentStr` `string` _(optional)_ — Indent string per level (default `"  "`).

**Returns** `string` — The pretty-printed JSON string.

```lua
local s = Json.encodePretty({ a = 1, b = { c = 2 } })
```

## typed/builtin//modules/json_utils/M/decodeOrEmptyTable {#typed-builtin-modules-json-utils-m-decodeoremptytable}

```lua
M.decodeOrEmptyTable(jsonStr: string?) -> { [any]: any }
```

Decode a JSON string safely, returning an empty table on any failure (instead of nil). Returns the table when the decode succeeds AND the result is a table; otherwise `{}`.

**Parameters**

- `jsonStr` `string` _(optional)_ — The JSON input.

**Returns** `{ [any]: any }` — A table — never nil.

```lua
local t = JsonUtils.decodeOrEmptyTable(engineJson)
```

## typed/builtin//modules/json_utils/M/decodeOrNil {#typed-builtin-modules-json-utils-m-decodeornil}

```lua
M.decodeOrNil(jsonStr: string?) -> any
```

Decode a JSON string safely. Returns the decoded value or `nil` on any failure (empty input, literal `"null"`, parse error).

**Parameters**

- `jsonStr` `string` _(optional)_ — The JSON input. `nil`, empty, or `"null"` short-circuit to `nil`.

**Returns** `any` — The decoded value, or `nil`.

```lua
local v = JsonUtils.decodeOrNil('{"a":1}') -- → { a = 1 }
local v = JsonUtils.decodeOrNil("null")    -- → nil
```

## typed/builtin//modules/json_utils/M/formatNumber {#typed-builtin-modules-json-utils-m-formatnumber}

```lua
M.formatNumber(n: number, decimals: number?) -> string
```

Truncate a number to N decimal places using only string operations. WASM-safe — does NOT use `string.format` numeric specifiers.

**Parameters**

- `n` `number` — The number to format.
- `decimals` `number` _(optional)_ — Decimal places to keep (default 2). Use 0 to drop the fractional part entirely; a count below 0 reads the same as 0, and a fractional count counts the whole places in it.

**Returns** `string` — The truncated number rendered as a string.

```lua
local label = JsonUtils.formatNumber(3.14159, 2) -- "3.14"
local whole = JsonUtils.formatNumber(3.14159, 0) -- "3"
```

## typed/builtin//modules/json_utils/M/safeDecode {#typed-builtin-modules-json-utils-m-safedecode}

```lua
M.safeDecode(jsonStr: string?) -> any
```

Historical alias for `decodeOrNil`. Kept for back-compat with callers that used the older name.

**Parameters**

- `jsonStr` `string` _(optional)_ — The JSON input.

**Returns** `any` — The decoded value, or `nil`.

```lua
local v = JsonUtils.safeDecode(jsonStr)
```

## typed/builtin//modules/luau_introspect/M/docstrings {#typed-builtin-modules-luau-introspect-m-docstrings}

```lua
M.docstrings(src: string) -> DocMap
```

Scans `src` for `--!desc` / `--!arg` / `--!return` / `--!example`
doc-comment runs and binds each run to the name of the declaration on
the next code line (the identifier after `function`, `public:`,
`local function`, `M.`, `public.<name>`, or a `<name> = Field.<...>` /
`<name> = Event(...)` field/event declaration). A continuation line
("--!  " with no tag word) extends whichever field the run's last tag
opened. Blank and plain `--` comment lines between the run and the
declaration are skipped without terminating the run.

**Parameters**

- `src` `string` — Luau/asset source text.

**Returns** `DocMap` — Map of declaration name to its parsed doc entry.

```lua
local d = I.docstrings(src); print(d.takeDamage.desc)
```

## typed/builtin//modules/luau_introspect/M/events {#typed-builtin-modules-luau-introspect-m-events}

```lua
M.events(src: string) -> { EventEntry }
```

Parses `events = { name = Event(payloadSchema?, syncMode?), ... }`
table-literal entries. The payload schema — a `{ k = Field.<kind>(...) }`
table — is parsed like `publicFields` and reduced to `{name, type}`
pairs; a payloadless `Event()` yields an empty payload. `sync` is true
only when the SECOND positional `Event` argument is the literal
identifier `Sync`. Comments and string literals never register. Folds in
`desc` from `docstrings(src)`.

**Parameters**

- `src` `string` — Luau/asset source text.

**Returns** `{ EventEntry }` — Ordered array of event entries, source order preserved.

```lua
local e = I.events(src); print(e[1].name, e[1].sync)
```

## typed/builtin//modules/luau_introspect/M/forSource {#typed-builtin-modules-luau-introspect-m-forsource}

```lua
M.forSource(src: string, computeFn: (string) -> any) -> any
```

Memoises `computeFn(src)` keyed on `src` itself in a bounded
module-local table. The same source text returns the cached result
without re-invoking `computeFn`; different source text recomputes. The
cache is capped (oldest key evicted first), so an evicted key
recomputes on its next request.

**Parameters**

- `src` `string` — Source text — both the memo key and the argument passed to
`computeFn`.
- `computeFn` `(string) -> any` — Called as `computeFn(src)` on a cache miss.

**Returns** `any` — The (possibly cached) result of `computeFn(src)`.

```lua
local detail = I.forSource(src, buildDetail)
```

## typed/builtin//modules/luau_introspect/M/lifecycleHooks {#typed-builtin-modules-luau-introspect-m-lifecyclehooks}

```lua
M.lifecycleHooks(src: string, catalog: { string }) -> { string }
```

Finds top-level `function <name>(` declarations whose name is in
the caller-supplied `catalog`. Excludes `local function`, `public:`
methods, and `M.` exports — only a bare top-level `function NAME(`
declaration matches. Never hardcodes the lifecycle-callback catalog;
the caller passes the list of names to match against. Commented-out
declarations never match.

**Parameters**

- `src` `string` — Luau/asset source text.
- `catalog` `{ string }` — Array of lifecycle-callback names to match against.

**Returns** `{ string }` — Array of matched hook names, source order preserved.

```lua
local hooks = I.lifecycleHooks(src, { "awake", "update" })
```

## typed/builtin//modules/luau_introspect/M/maskNonCode {#typed-builtin-modules-luau-introspect-m-masknoncode}

```lua
M.maskNonCode(src: string) -> string
```

A same-length copy of `src` where comment bodies and string-literal
contents are replaced by spaces (delimiters and newlines preserved),
so structural pattern matching over the result never registers a
comment or string body. Index-aligned with `src` — a match position in
the mask is the same position in `src`.

**Parameters**

- `src` `string` — Luau/asset source text.

**Returns** `string` — The comment/string-masked copy.

```lua
local mask = I.maskNonCode(src); string.find(mask, "operations%s*=%s*{")
```

## typed/builtin//modules/luau_introspect/M/methods {#typed-builtin-modules-luau-introspect-m-methods}

```lua
M.methods(src: string) -> { MethodEntry }
```

Parses `function public:<name>(<params>)` and `typed function
public:<name>(<params>)` declarations — with an optional `: <ret>`
return-type annotation immediately after the closing paren — into
`{name, params, returns}`. Each param is split on top-level commas
into `{name, type?}`; a `...` variadic is captured with `name = "..."`.
Folds in `desc` from `docstrings(src)`.

**Parameters**

- `src` `string` — Luau/asset source text.

**Returns** `{ MethodEntry }` — Ordered array of method entries, source order preserved.

```lua
local m = I.methods(src); print(m[1].name, m[1].returns)
```

## typed/builtin//modules/luau_introspect/M/moduleExports {#typed-builtin-modules-luau-introspect-m-moduleexports}

```lua
M.moduleExports(src: string) -> { ExportEntry }
```

Parses `M.<name> = function(...)` assignments, `function
M.<name>(...)` declarations, and a trailing `return { foo = foo, ... }`
export table into `{name, kind, signature?, desc?}`. `kind` is
`"function"` for a function assignment/declaration, `"value"` for any
other `M.<name> = <expr>` assignment (a `==` comparison is not an
assignment). A name that appears only in the `return { ... }` table
infers its kind from whether a same-named `function <name>(` /
`local function <name>(` declaration exists. Folds in `desc` from
`docstrings(src)`.

**Parameters**

- `src` `string` — Luau/asset source text.

**Returns** `{ ExportEntry }` — Array of export entries, in source-scan order.

```lua
local exports = I.moduleExports(src); print(exports[1].name)
```

## typed/builtin//modules/luau_introspect/M/publicFields {#typed-builtin-modules-luau-introspect-m-publicfields}

```lua
M.publicFields(src: string) -> { FieldEntry }
```

Parses `public = { name = Field.<kind>(...), ... }` table-literal
entries and module-scope `public.<name> = Field.<kind>(...)`
assignments. For a ref constructor (`assetRef` / `dataRef` /
`resource` / `componentRef`) the first positional argument is captured
as `category` and the second as `default`; for every other kind the
first argument is the `default`. Both are raw trimmed source-text
slices, comments stripped. A trailing `Sync`/`NoSync` identifier
becomes `sync`. Entries whose key is a computed/indirect expression
(`[expr] = Field...`) are omitted. Comments and string literals never
register as entries. Folds in `desc` from `docstrings(src)`.

**Parameters**

- `src` `string` — Luau/asset source text.

**Returns** `{ FieldEntry }` — Ordered array of field entries, source order preserved.

```lua
local f = I.publicFields(src); print(f[1].name, f[1].category)
```

## typed/builtin//modules/luau_introspect/M/refMethods {#typed-builtin-modules-luau-introspect-m-refmethods}

```lua
M.refMethods(src: string) -> { MethodEntry }
```

Parses the methods a `behavior.luau`-style module exposes on a
`M.ref = { name = fn, ... }` table — the assetType's per-asset behavior
surface (`ref:method(...)`). Each entry's key maps to its backing
`local function <fn>(self, <params>): <ret>` (or `function <fn>(...)`)
declaration: the leading `self` parameter is dropped (it is the ref the
method is called on), the remaining params + return annotation + the
declaration's `--!desc` are captured. A key whose value is a table
literal or an expression other than a bare function name is skipped.
Runs over the comment/string-aware mask, so a commented `M.ref` never
registers.

**Parameters**

- `src` `string` — Luau/asset source text.

**Returns** `{ MethodEntry }` — Ordered array of method entries (source order of the `M.ref` keys).

```lua
local api = I.refMethods(behaviorSrc); print(api[1].name, api[1].returns)
```

## typed/builtin//modules/luau_introspect/M/tableLiteral {#typed-builtin-modules-luau-introspect-m-tableliteral}

```lua
M.tableLiteral(src: string, assignmentName: string) -> TableNode?
```

Parses a named table literal `assignmentName = { ... }` into a nested
`TableNode` — each top-level `key = value` becomes an entry whose value is
either a `scalar` (the trimmed source text of a non-table value, quotes
included) or a nested `table` (`TableNode`) when the value is itself a
`{ ... }`. Runs over the comment/string-aware mask, so a `key`, `{`, or
`}` inside a comment or string never registers. Computed (`[expr] =`) and
positional entries are skipped. Returns nil when the assignment is absent.

**Parameters**

- `src` `string` — Luau/asset source text.
- `assignmentName` `string` — The table's assignment name (a Lua pattern, e.g.
"operations" or "M%.tokens").

**Returns** `TableNode?` — The parsed `TableNode`, or nil.

```lua
local ops = I.tableLiteral(src, "operations")
```

## typed/builtin//modules/luau_introspect/M/tableLiteralKeys {#typed-builtin-modules-luau-introspect-m-tableliteralkeys}

```lua
M.tableLiteralKeys(src: string, assignmentName: string) -> { string }
```

Finds `<assignmentName> = { ... }` in `src` and returns the top-level
literal-identifier keys of that table (e.g. `tableLiteralKeys(src,
"operations")` on `operations = { generate = {...}, from_image =
{...} }` returns `{"generate","from_image"}`). Runs over the
comment/string-aware mask, so a `--` comment or string literal
mentioning the assignment name never registers. Comment/string/nesting
inside a value never breaks the scan (balanced brace matching, same as
`publicFields`/`events`). A computed `["key"]` entry is omitted — only
bare identifier keys are recognised. Returns `{}` when the assignment
is absent.

**Parameters**

- `src` `string` — Luau/asset source text.
- `assignmentName` `string` — The table's assignment name (e.g. "operations").

**Returns** `{ string }` — Array of top-level key names, source order preserved.

```lua
local ops = I.tableLiteralKeys(src, "operations")
```

## typed/builtin//modules/material_utils/M/Apply {#typed-builtin-modules-material-utils-m-apply}

```lua
M.Apply(entityId: string, materialRef: MaterialRefOrName) -> boolean
```

PascalCase back-compat alias for `apply`.

**Parameters**

- `entityId` `string` — Target entity id.
- `materialRef` `MaterialRefOrName` — Either an AssetRef envelope or a material-name string.

**Returns** `boolean` — True on success.

## typed/builtin//modules/material_utils/M/Create {#typed-builtin-modules-material-utils-m-create}

```lua
M.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)`.

## typed/builtin//modules/material_utils/M/Exists {#typed-builtin-modules-material-utils-m-exists}

```lua
M.Exists(name: MaterialRefOrName) -> boolean
```

PascalCase back-compat alias for `exists`.

**Parameters**

- `name` `MaterialRefOrName` — AssetRef envelope or material-name string.

**Returns** `boolean` — True when the material is registered.

## typed/builtin//modules/material_utils/M/GetProperty {#typed-builtin-modules-material-utils-m-getproperty}

```lua
M.GetProperty(materialName: MaterialRefOrName, propertyName: string) -> any
```

PascalCase back-compat alias for `getProperty`.

**Parameters**

- `materialName` `MaterialRefOrName` — AssetRef envelope or material-name string.
- `propertyName` `string` — Property name.

**Returns** `any` — The property value, or nil when not found.

## typed/builtin//modules/material_utils/M/GetPropertyNames {#typed-builtin-modules-material-utils-m-getpropertynames}

```lua
M.GetPropertyNames(materialName: MaterialRefOrName) -> { string }?
```

PascalCase back-compat alias for `getPropertyNames`.

**Parameters**

- `materialName` `MaterialRefOrName` — AssetRef envelope or material-name string.

**Returns** `{ string }?` — Array of property names, or nil when the material is not found.

## typed/builtin//modules/material_utils/M/SetProperty {#typed-builtin-modules-material-utils-m-setproperty}

```lua
M.SetProperty(materialName: MaterialRefOrName, property: string, value: any?) -> any
```

PascalCase alias. Writes the property on the material ASSET by name/ref (a runtime change every entity using it takes; `matRef:saveDefinition()` writes it into `mat.yaml`) — distinct from `M.setProperty`, which targets the material on one entity's model.

**Parameters**

- `materialName` `MaterialRefOrName` — AssetRef envelope or material-name string.
- `property` `string` — Property name.
- `value` `any` _(optional)_ — New value.

**Returns** `any` — True on success.

```lua
Material.SetProperty("gold", "roughness", 0.1)
```

## typed/builtin//modules/material_utils/M/SetTexture {#typed-builtin-modules-material-utils-m-settexture}

```lua
M.SetTexture(materialName: MaterialRefOrName, slot: string, textureRef: string) -> boolean
```

PascalCase back-compat alias for `setTexture`.

**Parameters**

- `materialName` `MaterialRefOrName` — AssetRef envelope or material-name string.
- `slot` `string` — Texture slot name (`"albedo"`, `"normal"`, etc.).
- `textureRef` `string` — Texture reference string.

**Returns** `boolean` — True on success.

## typed/builtin//modules/material_utils/M/Update {#typed-builtin-modules-material-utils-m-update}

```lua
M.Update(target: any?, props: { [string]: any }) -> number
```

PascalCase alias for `update`.

**Parameters**

- `target` `any` _(optional)_ — Material name / AssetRef, OR an entity — a proxy, an entity-id, or the display name the entity carries.
- `props` `{ [string]: any }` — Table of `{ [propertyName] = value }` pairs.

**Returns** `number` — Number of properties applied.

```lua
Material.Update("gold", { base_color = { 1, 0, 0 }, roughness = 0.15 })
```

## typed/builtin//modules/material_utils/M/apply {#typed-builtin-modules-material-utils-m-apply}

```lua
M.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.

**Parameters**

- `entity` `any` _(optional)_ — The entity to apply to — an entity proxy (recommended: a validated handle to a real entity), an entity-id string, or the display name the entity carries.
- `materialRef` `MaterialRefOrName` — Either an AssetRef envelope or a material-name string.

**Returns** `boolean` — True on success.

```lua
Material.apply(entityId, "gold")
local mat = Material.create("gold", { ... }); Material.apply(entityId, mat)
```

## typed/builtin//modules/material_utils/M/create {#typed-builtin-modules-material-utils-m-create}

```lua
M.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.

## typed/builtin//modules/material_utils/M/exists {#typed-builtin-modules-material-utils-m-exists}

```lua
M.exists(name: MaterialRefOrName) -> boolean
```

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

**Parameters**

- `name` `MaterialRefOrName` — AssetRef envelope or material-name string.

**Returns** `boolean` — True when the material is registered.

```lua
if Material.exists("gold") then ... end
```

## typed/builtin//modules/material_utils/M/getProperty {#typed-builtin-modules-material-utils-m-getproperty}

```lua
M.getProperty(materialName: MaterialRefOrName, propertyName: string) -> any
```

Read the current value of a material property.

**Parameters**

- `materialName` `MaterialRefOrName` — AssetRef envelope or material-name string.
- `propertyName` `string` — Property name (`"roughness"`, `"metallic"`, `"base_color"`, etc.).

**Returns** `any` — The property value, or nil when not found.

```lua
local r = Material.getProperty("gold", "roughness")
```

## typed/builtin//modules/material_utils/M/getPropertyNames {#typed-builtin-modules-material-utils-m-getpropertynames}

```lua
M.getPropertyNames(materialName: MaterialRefOrName) -> { string }?
```

List the property names exposed by a registered material.

**Parameters**

- `materialName` `MaterialRefOrName` — AssetRef envelope or material-name string.

**Returns** `{ string }?` — Array of property names, or nil when the material is not found.

```lua
local props = Material.getPropertyNames("gold")
```

## typed/builtin//modules/material_utils/M/setProperties {#typed-builtin-modules-material-utils-m-setproperties}

```lua
M.setProperties(target: any?, props: { [string]: any }) -> number
```

Set many material properties in one call. Addresses the target the same
way `setProperty` does: a material name / AssetRef writes the material ASSET
(affecting every entity using it), an entity proxy / entity-id / entity name writes the
material bound to that entity's Model / SkinnedModel. Each key resolves
against the shader's declared vocabulary, so the spellings `create` accepts
reach the same uniforms; a key the shader does not expose is skipped, which
lets one patch table serve materials built on different shaders.

**Parameters**

- `target` `any` _(optional)_ — Material name / AssetRef, OR an entity — a proxy, an entity-id, or the display name the entity carries.
- `props` `{ [string]: any }` — Table of `{ [propertyName] = value }` pairs.

**Returns** `number` — Number of properties applied.

```lua
Material.setProperties("gold", { roughness = 0.2, metallic = 0.9 })
Material.setProperties(entityId, { base_color = { 1, 0, 0 } })
```

## typed/builtin//modules/material_utils/M/setProperty {#typed-builtin-modules-material-utils-m-setproperty}

```lua
M.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 — a proxy, an id, or a display name — to write the material bound to that entity's Model / SkinnedModel. Errors when an entity target has no Model or SkinnedModel.

**Parameters**

- `target` `any` _(optional)_ — Material name / AssetRef, OR an entity — a proxy, an entity-id, or the display name the entity carries.
- `property` `string` — Property name.
- `value` `any` _(optional)_ — New value (type depends on the property).

```lua
Material.setProperty("gold", "roughness", 0.4)     -- by material name
Material.setProperty(entityId, "roughness", 0.4)   -- by entity
```

## typed/builtin//modules/material_utils/M/setTexture {#typed-builtin-modules-material-utils-m-settexture}

```lua
M.setTexture(materialName: MaterialRefOrName, slot: string, textureRef: any?) -> boolean
```

Set a texture slot on a named material.

**Parameters**

- `materialName` `MaterialRefOrName` — AssetRef envelope or material-name string.
- `slot` `string` — Texture slot name (`"albedo"`, `"normal"`, etc.).
- `textureRef` `any` _(optional)_ — Texture reference. Formats: `"color:r,g,b,a"`, `"@builtin::textures.foo"`, or a render-output guid (camera target, video handle).

**Returns** `boolean` — True on success.

```lua
Material.setTexture("gold", "albedo", "@builtin::textures.gold")
```

## typed/builtin//modules/material_utils/M/update {#typed-builtin-modules-material-utils-m-update}

```lua
M.update(target: any?, props: { [string]: any }) -> number
```

Change an existing material from a property table — the counterpart to
`create`, taking the same table shape. Addresses its target and counts its
writes the way `setProperties` does.

**Parameters**

- `target` `any` _(optional)_ — Material name / AssetRef, OR an entity — a proxy, an entity-id, or the display name the entity carries.
- `props` `{ [string]: any }` — Table of `{ [propertyName] = value }` pairs.

**Returns** `number` — Number of properties applied.

```lua
Material.update("gold", { color = { 1, 0.85, 0.2 }, roughness = 0.15 })
```

## typed/builtin//modules/numberSequence/M/deserialize {#typed-builtin-modules-numbersequence-m-deserialize}

```lua
M.deserialize(data: any?) -> NumberSequenceObj
```

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

**Parameters**

- `data` `any` _(optional)_ — The serialized payload.

**Returns** `NumberSequenceObj` — A fresh NumberSequenceObj with the deserialized keypoints.

```lua
local s = NumberSequence.deserialize(savedData)
```

## typed/builtin//modules/numberSequence/M/new {#typed-builtin-modules-numbersequence-m-new}

```lua
M.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.

**Parameters**

- `...` `any` _(optional)_ — `(v)`, `(v0, v1)`, or `({ {time, value, envelope?}, ... })`.

**Returns** `NumberSequenceObj` — A NumberSequenceObj with `:evaluate`, `:sample`, `:keypoints`, `:duration`, `:serialize`, `:destroy`.

```lua
local fade = NumberSequence.new(1.0)
local fadeOut = NumberSequence.new(1.0, 0.0)
local size = NumberSequence.new({{time=0,value=0.5,envelope=0.1},{time=0.5,value=1.5},{time=1,value=0}})
```

## typed/builtin//modules/number_range/M/new {#typed-builtin-modules-number-range-m-new}

```lua
M.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.

**Parameters**

- `min` `number` — Lower bound.
- `max` `number` _(optional)_ — Upper bound; defaults to `min`.

**Returns** `any`

```lua
local lifetime = NumberRange.new(1.0)        -- always 1.0
local speed    = NumberRange.new(0.5, 2.0)   -- random
```

## typed/builtin//modules/nx/gpu/M/fft1d {#typed-builtin-modules-nx-gpu-m-fft1d}

```lua
M.fft1d(opts: Fft1dOpts) -> boolean
```

1D complex FFT over a power-of-two-sized interleaved complex
GPU buffer. `size` is the number of complex samples (must be
a power of two ≥ 2). Pass the same `input` / `output` handle for
in-place.

**Parameters**

- `opts` `Fft1dOpts` — `{ input, output?, size, inverse? }`. `input` / `output` are GPU buffer handles; `output` defaults to `input`. `inverse=true` runs the inverse transform (scaled by 1/N).

**Returns** `boolean` — `true` on success, `false` on validation failure (non-pow2 size, missing buffers).

```lua
M.fft1d({ input = specIn, output = specOut, size = 1024 })
```

## typed/builtin//modules/nx/gpu/M/fft2d {#typed-builtin-modules-nx-gpu-m-fft2d}

```lua
M.fft2d(opts: Fft2dOpts) -> boolean
```

2D complex FFT over a power-of-two-sized row-major
interleaved complex GPU buffer. Width and height must both
be powers of two ≥ 2.

**Parameters**

- `opts` `Fft2dOpts` — `{ input, output?, width, height, inverse? }`. `input` / `output` are GPU buffer handles; `output` defaults to `input`. `inverse=true` runs the inverse (scaled by 1/(width*height)).

**Returns** `boolean` — `true` on success, `false` on validation failure (non-pow2 dims, missing buffers).

```lua
M.fft2d({ input = imgIn, output = imgOut, width = 256, height = 256 })
```

## typed/builtin//modules/nx/gpu/M/ifft1d {#typed-builtin-modules-nx-gpu-m-ifft1d}

```lua
M.ifft1d(opts: Fft1dOpts) -> boolean
```

Convenience: forward 1D FFT with `inverse=true` — equivalent
to `M.fft1d(opts)` after stamping `opts.inverse = true`.

**Parameters**

- `opts` `Fft1dOpts` — Same as `M.fft1d`. Mutates `opts.inverse`.

**Returns** `boolean` — `true` on success, `false` on validation failure.

```lua
M.ifft1d({ input = specIn, output = specOut, size = 1024 })
```

## typed/builtin//modules/nx/gpu/M/ifft2d {#typed-builtin-modules-nx-gpu-m-ifft2d}

```lua
M.ifft2d(opts: Fft2dOpts) -> boolean
```

Convenience: forward 2D FFT with `inverse=true` — equivalent
to `M.fft2d(opts)` after stamping `opts.inverse = true`.

**Parameters**

- `opts` `Fft2dOpts` — Same as `M.fft2d`. Mutates `opts.inverse`.

**Returns** `boolean` — `true` on success, `false` on validation failure.

```lua
M.ifft2d({ input = imgIn, output = imgOut, width = 256, height = 256 })
```

## typed/builtin//modules/nx/nx/add {#typed-builtin-modules-nx-nx-add}

```lua
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`.

**Parameters**

- `dst` `NxBuffer` — Target buffer (mutated).
- `x` `NxScalarOrBuffer` — Either a scalar or a same-shaped buffer.

**Returns** `boolean` — `true` on success, `false` on type / handle errors.

```lua
nx.add(b, 1.5)
nx.add(dst, src)
```

## typed/builtin//modules/nx/nx/addStrided {#typed-builtin-modules-nx-nx-addstrided}

```lua
nx.addStrided(b: NxBuffer, scalar: number, stride: number, offset: number?) -> boolean
```

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

**Parameters**

- `b` `NxBuffer` — Target buffer (mutated).
- `scalar` `number` — Per-element addend.
- `stride` `number` — Element stride.
- `offset` `number` _(optional)_ — Optional element offset (default 0).

**Returns** `boolean` — `true` on success, `false` on unknown handle.

```lua
nx.addStrided(buf, 1.0, 3, 1)
```

## typed/builtin//modules/nx/nx/addStridedFrom {#typed-builtin-modules-nx-nx-addstridedfrom}

```lua
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]`.

**Parameters**

- `dst` `NxBuffer` — Target buffer (mutated).
- `src` `NxBuffer` — Source buffer.
- `scale` `number` _(optional)_ — Optional `src` scale factor (default 1.0).
- `dst_stride` `number` — Destination element stride.
- `dst_off` `number` _(optional)_ — Optional destination offset (default 0).
- `src_stride` `number` — Source element stride.
- `src_off` `number` _(optional)_ — Optional source offset (default 0).

**Returns** `boolean` — `true` on success, `false` on shape mismatch / unknown handle.

```lua
nx.addStridedFrom(dst, src, 1, 3, 0, 3, 0)
```

## typed/builtin//modules/nx/nx/applyAbs {#typed-builtin-modules-nx-nx-applyabs}

```lua
nx.applyAbs(b: NxBuffer) -> boolean
```

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

**Parameters**

- `b` `NxBuffer` — Target buffer.

**Returns** `boolean` — `true` on success, `false` on unknown handle.

```lua
nx.applyAbs(b)
```

## typed/builtin//modules/nx/nx/applyCeil {#typed-builtin-modules-nx-nx-applyceil}

```lua
nx.applyCeil(b: NxBuffer) -> boolean
```

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

**Parameters**

- `b` `NxBuffer` — Target buffer.

**Returns** `boolean` — `true` on success, `false` on unknown handle.

```lua
nx.applyCeil(b)
```

## typed/builtin//modules/nx/nx/applyCos {#typed-builtin-modules-nx-nx-applycos}

```lua
nx.applyCos(b: NxBuffer) -> boolean
```

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

**Parameters**

- `b` `NxBuffer` — Target buffer.

**Returns** `boolean` — `true` on success, `false` on unknown handle.

```lua
nx.applyCos(b)
```

## typed/builtin//modules/nx/nx/applyExp {#typed-builtin-modules-nx-nx-applyexp}

```lua
nx.applyExp(b: NxBuffer) -> boolean
```

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

**Parameters**

- `b` `NxBuffer` — Target buffer.

**Returns** `boolean` — `true` on success, `false` on unknown handle.

```lua
nx.applyExp(b)
```

## typed/builtin//modules/nx/nx/applyFloor {#typed-builtin-modules-nx-nx-applyfloor}

```lua
nx.applyFloor(b: NxBuffer) -> boolean
```

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

**Parameters**

- `b` `NxBuffer` — Target buffer.

**Returns** `boolean` — `true` on success, `false` on unknown handle.

```lua
nx.applyFloor(b)
```

## typed/builtin//modules/nx/nx/applyFract {#typed-builtin-modules-nx-nx-applyfract}

```lua
nx.applyFract(b: NxBuffer) -> boolean
```

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

**Parameters**

- `b` `NxBuffer` — Target buffer.

**Returns** `boolean` — `true` on success, `false` on unknown handle.

```lua
nx.applyFract(b)
```

## typed/builtin//modules/nx/nx/applyLog {#typed-builtin-modules-nx-nx-applylog}

```lua
nx.applyLog(b: NxBuffer) -> boolean
```

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

**Parameters**

- `b` `NxBuffer` — Target buffer.

**Returns** `boolean` — `true` on success, `false` on unknown handle.

```lua
nx.applyLog(b)
```

## typed/builtin//modules/nx/nx/applyLog2 {#typed-builtin-modules-nx-nx-applylog2}

```lua
nx.applyLog2(b: NxBuffer) -> boolean
```

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

**Parameters**

- `b` `NxBuffer` — Target buffer.

**Returns** `boolean` — `true` on success, `false` on unknown handle.

```lua
nx.applyLog2(b)
```

## typed/builtin//modules/nx/nx/applyNeg {#typed-builtin-modules-nx-nx-applyneg}

```lua
nx.applyNeg(b: NxBuffer) -> boolean
```

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

**Parameters**

- `b` `NxBuffer` — Target buffer.

**Returns** `boolean` — `true` on success, `false` on unknown handle.

```lua
nx.applyNeg(b)
```

## typed/builtin//modules/nx/nx/applyRecip {#typed-builtin-modules-nx-nx-applyrecip}

```lua
nx.applyRecip(b: NxBuffer) -> boolean
```

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

**Parameters**

- `b` `NxBuffer` — Target buffer.

**Returns** `boolean` — `true` on success, `false` on unknown handle.

```lua
nx.applyRecip(b)
```

## typed/builtin//modules/nx/nx/applyRecipSqrt {#typed-builtin-modules-nx-nx-applyrecipsqrt}

```lua
nx.applyRecipSqrt(b: NxBuffer) -> boolean
```

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

**Parameters**

- `b` `NxBuffer` — Target buffer.

**Returns** `boolean` — `true` on success, `false` on unknown handle.

```lua
nx.applyRecipSqrt(b)
```

## typed/builtin//modules/nx/nx/applyRound {#typed-builtin-modules-nx-nx-applyround}

```lua
nx.applyRound(b: NxBuffer) -> boolean
```

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

**Parameters**

- `b` `NxBuffer` — Target buffer.

**Returns** `boolean` — `true` on success, `false` on unknown handle.

```lua
nx.applyRound(b)
```

## typed/builtin//modules/nx/nx/applySign {#typed-builtin-modules-nx-nx-applysign}

```lua
nx.applySign(b: NxBuffer) -> boolean
```

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

**Parameters**

- `b` `NxBuffer` — Target buffer.

**Returns** `boolean` — `true` on success, `false` on unknown handle.

```lua
nx.applySign(b)
```

## typed/builtin//modules/nx/nx/applySin {#typed-builtin-modules-nx-nx-applysin}

```lua
nx.applySin(b: NxBuffer) -> boolean
```

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

**Parameters**

- `b` `NxBuffer` — Target buffer.

**Returns** `boolean` — `true` on success, `false` on unknown handle.

```lua
nx.applySin(b)
```

## typed/builtin//modules/nx/nx/applySqrt {#typed-builtin-modules-nx-nx-applysqrt}

```lua
nx.applySqrt(b: NxBuffer) -> boolean
```

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

**Parameters**

- `b` `NxBuffer` — Target buffer.

**Returns** `boolean` — `true` on success, `false` on unknown handle.

```lua
nx.applySqrt(b)
```

## typed/builtin//modules/nx/nx/applySquare {#typed-builtin-modules-nx-nx-applysquare}

```lua
nx.applySquare(b: NxBuffer) -> boolean
```

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

**Parameters**

- `b` `NxBuffer` — Target buffer.

**Returns** `boolean` — `true` on success, `false` on unknown handle.

```lua
nx.applySquare(b)
```

## typed/builtin//modules/nx/nx/applyTan {#typed-builtin-modules-nx-nx-applytan}

```lua
nx.applyTan(b: NxBuffer) -> boolean
```

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

**Parameters**

- `b` `NxBuffer` — Target buffer.

**Returns** `boolean` — `true` on success, `false` on unknown handle.

```lua
nx.applyTan(b)
```

## typed/builtin//modules/nx/nx/applyTrunc {#typed-builtin-modules-nx-nx-applytrunc}

```lua
nx.applyTrunc(b: NxBuffer) -> boolean
```

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

**Parameters**

- `b` `NxBuffer` — Target buffer.

**Returns** `boolean` — `true` on success, `false` on unknown handle.

```lua
nx.applyTrunc(b)
```

## typed/builtin//modules/nx/nx/applyWindow {#typed-builtin-modules-nx-nx-applywindow}

```lua
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.

**Parameters**

- `signal` `NxBuffer` — Signal buffer (mutated).
- `window` `NxBuffer` — Window buffer.

**Returns** `boolean` — `true` on success, `false` on unknown handle.

```lua
nx.applyWindow(signal, hann)
```

## typed/builtin//modules/nx/nx/axpby {#typed-builtin-modules-nx-nx-axpby}

```lua
nx.axpby(dst: NxBuffer, a: number, src: NxBuffer, b: number) -> boolean
```

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

**Parameters**

- `dst` `NxBuffer` — Target buffer (mutated).
- `a` `number` — Scale applied to `dst`.
- `src` `NxBuffer` — Source buffer.
- `b` `number` — Scale applied to `src`.

**Returns** `boolean` — `true` on success, `false` on stride mismatch / unknown handle.

```lua
nx.axpby(y, 0.5, x, 2.0)
```

## typed/builtin//modules/nx/nx/clamp {#typed-builtin-modules-nx-nx-clamp}

```lua
nx.clamp(b: NxBuffer, min_v: number, max_v: number) -> boolean
```

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

**Parameters**

- `b` `NxBuffer` — Target buffer (mutated).
- `min_v` `number` — Lower bound.
- `max_v` `number` — Upper bound.

**Returns** `boolean` — `true` on success, `false` on unknown handle.

```lua
nx.clamp(b, 0.0, 1.0)
```

## typed/builtin//modules/nx/nx/copy {#typed-builtin-modules-nx-nx-copy}

```lua
nx.copy(dst: NxBuffer, src: NxBuffer) -> boolean
```

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

**Parameters**

- `dst` `NxBuffer` — Target buffer (mutated).
- `src` `NxBuffer` — Source buffer.

**Returns** `boolean` — `true` on success, `false` on shape mismatch or unknown handle.

```lua
nx.copy(dst, src)
```

## typed/builtin//modules/nx/nx/copyStridedFrom {#typed-builtin-modules-nx-nx-copystridedfrom}

```lua
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]`.

**Parameters**

- `dst` `NxBuffer` — Target buffer (mutated).
- `src` `NxBuffer` — Source buffer.
- `scale` `number` _(optional)_ — Optional `src` scale factor (default 1.0).
- `dst_stride` `number` — Destination element stride.
- `dst_off` `number` _(optional)_ — Optional destination offset (default 0).
- `src_stride` `number` — Source element stride.
- `src_off` `number` _(optional)_ — Optional source offset (default 0).

**Returns** `boolean` — `true` on success, `false` on shape mismatch / unknown handle.

```lua
nx.copyStridedFrom(dst, src, 1, 3, 0, 3, 0)
```

## typed/builtin//modules/nx/nx/create {#typed-builtin-modules-nx-nx-create}

```lua
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.

## typed/builtin//modules/nx/nx/div {#typed-builtin-modules-nx-nx-div}

```lua
nx.div(dst: NxBuffer, x: NxScalarOrBuffer) -> boolean
```

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

**Parameters**

- `dst` `NxBuffer` — Target buffer (mutated).
- `x` `NxScalarOrBuffer` — Either a scalar or a same-shaped buffer.

**Returns** `boolean` — `true` on success, `false` on type / handle errors.

```lua
nx.div(b, 2)
nx.div(dst, src)
```

## typed/builtin//modules/nx/nx/dot {#typed-builtin-modules-nx-nx-dot}

```lua
nx.dot(a: NxBuffer, b: NxBuffer) -> number?
```

Reduction: dot product of two same-shaped buffers.

**Parameters**

- `a` `NxBuffer` — First buffer.
- `b` `NxBuffer` — Second buffer.

**Returns** `number?` — Scalar dot product, or `nil` on shape mismatch / unknown handle.

```lua
local d = nx.dot(a, b)
```

## typed/builtin//modules/nx/nx/fft1d {#typed-builtin-modules-nx-nx-fft1d}

```lua
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`).

**Parameters**

- `re` `NxBuffer` — Real-component buffer (mutated).
- `im` `NxBuffer` — Imaginary-component buffer (mutated).
- `inverse` `boolean` _(optional)_ — When `true` runs the inverse transform.

**Returns** `boolean` — `true` on success, `false` on length mismatch / invalid handle.

```lua
nx.fft1d(re, im)
nx.fft1d(re, im, true)
```

## typed/builtin//modules/nx/nx/fft2d {#typed-builtin-modules-nx-nx-fft2d}

```lua
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)`.

**Parameters**

- `re` `NxBuffer` — Real-component buffer (mutated).
- `im` `NxBuffer` — Imaginary-component buffer (mutated).
- `width` `number` — 2D width in samples.
- `height` `number` — 2D height in samples.
- `inverse` `boolean` _(optional)_ — When `true` runs the inverse transform.

**Returns** `boolean` — `true` on success, `false` on length mismatch / invalid handle.

```lua
nx.fft2d(re, im, w, h)
```

## typed/builtin//modules/nx/nx/fill {#typed-builtin-modules-nx-nx-fill}

```lua
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.

**Parameters**

- `b` `NxBuffer` — Target buffer (mutated).
- `value` `number` _(optional)_ — Fill value (default 0.0).

**Returns** `boolean` — `true` on success, `false` on unknown handle.

```lua
nx.fill(b, 3.5)
```

## typed/builtin//modules/nx/nx/fillRandomNormal {#typed-builtin-modules-nx-nx-fillrandomnormal}

```lua
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.

**Parameters**

- `b` `NxBuffer` — Target buffer (mutated).
- `mean` `number` _(optional)_ — Optional mean (default 0.0).
- `stddev` `number` _(optional)_ — Optional standard deviation (default 1.0).
- `seed` `NxSeed` — Optional seed — number, `"frame"`, or `nil` (0).

**Returns** `boolean` — `true` on success, `false` on unknown handle.

```lua
nx.fillRandomNormal(b, 0, 1, 42)
```

## typed/builtin//modules/nx/nx/fillRandomUniform {#typed-builtin-modules-nx-nx-fillrandomuniform}

```lua
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.

**Parameters**

- `b` `NxBuffer` — Target buffer (mutated).
- `min_v` `number` _(optional)_ — Optional lower bound (default 0.0).
- `max_v` `number` _(optional)_ — Optional upper bound (default 1.0).
- `seed` `NxSeed` — Optional seed — number, `"frame"` (per-frame value), or `nil` (0).

**Returns** `boolean` — `true` on success, `false` on unknown handle.

```lua
nx.fillRandomUniform(b, -1, 1, "frame")
```

## typed/builtin//modules/nx/nx/fillStrided {#typed-builtin-modules-nx-nx-fillstrided}

```lua
nx.fillStrided(b: NxBuffer, value: number, stride: number, offset: number?) -> boolean
```

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

**Parameters**

- `b` `NxBuffer` — Target buffer (mutated).
- `value` `number` — Per-element value.
- `stride` `number` — Element stride.
- `offset` `number` _(optional)_ — Optional element offset (default 0).

**Returns** `boolean` — `true` on success, `false` on unknown handle.

```lua
nx.fillStrided(buf, 0, 3, 2)
```

## typed/builtin//modules/nx/nx/fromTable {#typed-builtin-modules-nx-nx-fromtable}

```lua
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.

**Parameters**

- `arr` `{ number }` — Lua array of numbers.
- `type_` `NxType` _(optional)_ — Optional element layout (default `"f32"`).

**Returns** `NxBuffer?` — Newly allocated buffer holding `arr`, or `nil` on failure.

```lua
local b = nx.fromTable({ 0.1, 0.2, 0.3 })
```

## typed/builtin//modules/nx/nx/full {#typed-builtin-modules-nx-nx-full}

```lua
nx.full(n: number, type_: NxType?, value: number?) -> NxBuffer?
```

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

**Parameters**

- `n` `number` — Record count.
- `type_` `NxType` _(optional)_ — Optional element layout (default `"f32"`).
- `value` `number` _(optional)_ — Fill value (default 0.0).

**Returns** `NxBuffer?` — Buffer initialised to `value`.

```lua
local b = nx.full(1024, "f32", -1.0)
```

## typed/builtin//modules/nx/nx/ifft1d {#typed-builtin-modules-nx-nx-ifft1d}

```lua
nx.ifft1d(re: NxBuffer, im: NxBuffer) -> boolean
```

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

**Parameters**

- `re` `NxBuffer` — Real-component buffer (mutated).
- `im` `NxBuffer` — Imaginary-component buffer (mutated).

**Returns** `boolean` — `true` on success, `false` on length mismatch / invalid handle.

```lua
nx.ifft1d(re, im)
```

## typed/builtin//modules/nx/nx/ifft2d {#typed-builtin-modules-nx-nx-ifft2d}

```lua
nx.ifft2d(re: NxBuffer, im: NxBuffer, width: number, height: number) -> boolean
```

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

**Parameters**

- `re` `NxBuffer` — Real-component buffer (mutated).
- `im` `NxBuffer` — Imaginary-component buffer (mutated).
- `width` `number` — 2D width.
- `height` `number` — 2D height.

**Returns** `boolean` — `true` on success, `false` on length mismatch / invalid handle.

```lua
nx.ifft2d(re, im, w, h)
```

## typed/builtin//modules/nx/nx/integratePosition {#typed-builtin-modules-nx-nx-integrateposition}

```lua
nx.integratePosition(pos: NxBuffer, vel: NxBuffer, dt: number) -> boolean
```

Per-vec3: `pos[i] += vel[i] * dt` — the position half of an
Euler step. Both buffers must be vec3 (stride 3). The velocity step
is the caller's: update `vel` BEFORE this call for semi-implicit
Euler; updating it after gives forward Euler, which gains energy on
stiff systems.

**Parameters**

- `pos` `NxBuffer` — Position buffer (mutated).
- `vel` `NxBuffer` — Velocity buffer.
- `dt` `number` — Time step.

**Returns** `boolean` — `true` on success, `false` on shape mismatch / unknown handle.

```lua
nx.integratePosition(pos, vel, dt)
```

## typed/builtin//modules/nx/nx/irfft1d {#typed-builtin-modules-nx-nx-irfft1d}

```lua
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.

**Parameters**

- `re` `NxBuffer` — Real-component buffer.
- `im` `NxBuffer` — Imaginary-component buffer.

**Returns** `NxBuffer?` — Real-valued output buffer on success, `nil` on failure.

```lua
local out = nx.irfft1d(re, im)
```

## typed/builtin//modules/nx/nx/irfft2d {#typed-builtin-modules-nx-nx-irfft2d}

```lua
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`.

**Parameters**

- `re` `NxBuffer` — Real-component buffer.
- `im` `NxBuffer` — Imaginary-component buffer.
- `width` `number` — 2D width.
- `height` `number` — 2D height.

**Returns** `NxBuffer?` — Real-valued output buffer on success, `nil` on failure.

```lua
local out = nx.irfft2d(re, im, w, h)
```

## typed/builtin//modules/nx/nx/lerpTo {#typed-builtin-modules-nx-nx-lerpto}

```lua
nx.lerpTo(dst: NxBuffer, src: NxBuffer, t: number) -> boolean
```

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

**Parameters**

- `dst` `NxBuffer` — Target buffer (mutated).
- `src` `NxBuffer` — Source buffer.
- `t` `number` — Interpolation factor.

**Returns** `boolean` — `true` on success, `false` on stride mismatch / unknown handle.

```lua
nx.lerpTo(current, target, 0.1)
```

## typed/builtin//modules/nx/nx/max {#typed-builtin-modules-nx-nx-max}

```lua
nx.max(b: NxBuffer) -> number?
```

Reduction: maximum of all elements.

**Parameters**

- `b` `NxBuffer` — Source buffer.

**Returns** `number?` — Scalar max, or `nil` on unknown handle.

```lua
local m = nx.max(b)
```

## typed/builtin//modules/nx/nx/maxOp {#typed-builtin-modules-nx-nx-maxop}

```lua
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).

**Parameters**

- `dst` `NxBuffer` — Target buffer (mutated).
- `x` `NxScalarOrBuffer` — Scalar or same-shaped buffer.

**Returns** `boolean` — `true` on success, `false` on type / handle errors.

```lua
nx.maxOp(b, 0.0)
```

## typed/builtin//modules/nx/nx/mean {#typed-builtin-modules-nx-nx-mean}

```lua
nx.mean(b: NxBuffer) -> number?
```

Reduction: arithmetic mean of all elements.

**Parameters**

- `b` `NxBuffer` — Source buffer.

**Returns** `number?` — Scalar mean, or `nil` on unknown handle.

```lua
local m = nx.mean(b)
```

## typed/builtin//modules/nx/nx/min {#typed-builtin-modules-nx-nx-min}

```lua
nx.min(b: NxBuffer) -> number?
```

Reduction: minimum of all elements.

**Parameters**

- `b` `NxBuffer` — Source buffer.

**Returns** `number?` — Scalar min, or `nil` on unknown handle.

```lua
local m = nx.min(b)
```

## typed/builtin//modules/nx/nx/minOp {#typed-builtin-modules-nx-nx-minop}

```lua
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).

**Parameters**

- `dst` `NxBuffer` — Target buffer (mutated).
- `x` `NxScalarOrBuffer` — Scalar or same-shaped buffer.

**Returns** `boolean` — `true` on success, `false` on type / handle errors.

```lua
nx.minOp(b, 1.0)
```

## typed/builtin//modules/nx/nx/mul {#typed-builtin-modules-nx-nx-mul}

```lua
nx.mul(dst: NxBuffer, x: NxScalarOrBuffer) -> boolean
```

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

**Parameters**

- `dst` `NxBuffer` — Target buffer (mutated).
- `x` `NxScalarOrBuffer` — Either a scalar or a same-shaped buffer.

**Returns** `boolean` — `true` on success, `false` on type / handle errors.

```lua
nx.mul(b, 2)
nx.mul(dst, src)
```

## typed/builtin//modules/nx/nx/mulStrided {#typed-builtin-modules-nx-nx-mulstrided}

```lua
nx.mulStrided(b: NxBuffer, scalar: number, stride: number, offset: number?) -> boolean
```

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

**Parameters**

- `b` `NxBuffer` — Target buffer (mutated).
- `scalar` `number` — Per-element multiplier.
- `stride` `number` — Element stride.
- `offset` `number` _(optional)_ — Optional element offset (default 0).

**Returns** `boolean` — `true` on success, `false` on unknown handle.

```lua
nx.mulStrided(buf, 2, 4, 0)
```

## typed/builtin//modules/nx/nx/normL1 {#typed-builtin-modules-nx-nx-norml1}

```lua
nx.normL1(b: NxBuffer) -> number?
```

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

**Parameters**

- `b` `NxBuffer` — Source buffer.

**Returns** `number?` — Scalar L1 norm, or `nil` on unknown handle.

```lua
local n = nx.normL1(b)
```

## typed/builtin//modules/nx/nx/normL2 {#typed-builtin-modules-nx-nx-norml2}

```lua
nx.normL2(b: NxBuffer) -> number?
```

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

**Parameters**

- `b` `NxBuffer` — Source buffer.

**Returns** `number?` — Scalar L2 norm, or `nil` on unknown handle.

```lua
local n = nx.normL2(b)
```

## typed/builtin//modules/nx/nx/normalizeVec3 {#typed-builtin-modules-nx-nx-normalizevec3}

```lua
nx.normalizeVec3(b: NxBuffer) -> boolean
```

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

**Parameters**

- `b` `NxBuffer` — Vec3 buffer (mutated).

**Returns** `boolean` — `true` on success, `false` on stride mismatch / unknown handle.

```lua
nx.normalizeVec3(directions)
```

## typed/builtin//modules/nx/nx/ones {#typed-builtin-modules-nx-nx-ones}

```lua
nx.ones(n: number, type_: NxType?) -> NxBuffer?
```

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

**Parameters**

- `n` `number` — Record count.
- `type_` `NxType` _(optional)_ — Optional element layout (default `"f32"`).

**Returns** `NxBuffer?` — Buffer initialised to one.

```lua
local b = nx.ones(1024)
```

## typed/builtin//modules/nx/nx/pow {#typed-builtin-modules-nx-nx-pow}

```lua
nx.pow(b: NxBuffer, p: number) -> boolean
```

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

**Parameters**

- `b` `NxBuffer` — Target buffer (mutated).
- `p` `number` — Scalar exponent.

**Returns** `boolean` — `true` on success, `false` on unknown handle.

```lua
nx.pow(b, 2.2)
```

## typed/builtin//modules/nx/nx/quatFromYaw {#typed-builtin-modules-nx-nx-quatfromyaw}

```lua
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).

**Parameters**

- `dst` `NxBuffer` — Quaternion buffer (mutated).
- `yaw` `NxBuffer` — Source yaw scalars buffer.

**Returns** `boolean` — `true` on success, `false` on shape mismatch / unknown handle.

```lua
nx.quatFromYaw(quats, yaws)
```

## typed/builtin//modules/nx/nx/rfft1d {#typed-builtin-modules-nx-nx-rfft1d}

```lua
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`).

**Parameters**

- `signal` `NxBuffer` _(optional)_ — Real-valued input buffer.

**Returns** `(NxBuffer?, NxBuffer?)` — `(re_buf, im_buf)` on success, `nil` otherwise.

```lua
local re, im = nx.rfft1d(signal)
```

## typed/builtin//modules/nx/nx/rfft2d {#typed-builtin-modules-nx-nx-rfft2d}

```lua
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).

**Parameters**

- `signal` `NxBuffer` — Real-valued input buffer (row-major).
- `width` `number` — 2D width.
- `height` `number` — 2D height.

**Returns** `(NxBuffer?, NxBuffer?)` — `(re_buf, im_buf)` on success, `nil` on failure.

```lua
local re, im = nx.rfft2d(image, w, h)
```

## typed/builtin//modules/nx/nx/scale {#typed-builtin-modules-nx-nx-scale}

```lua
nx.scale(b: NxBuffer, s: number) -> boolean
```

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

**Parameters**

- `b` `NxBuffer` — Target buffer (mutated).
- `s` `number` — Scalar multiplier.

**Returns** `boolean` — `true` on success, `false` on unknown handle.

```lua
nx.scale(b, 0.5)
```

## typed/builtin//modules/nx/nx/sinCosTo {#typed-builtin-modules-nx-nx-sincosto}

```lua
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.

**Parameters**

- `src` `NxBuffer` — Source angles buffer.
- `sin_dst` `NxBuffer` — Destination buffer for the sine values.
- `cos_dst` `NxBuffer` — Destination buffer for the cosine values.

**Returns** `boolean` — `true` on success, `false` on stride mismatch / unknown handle.

```lua
nx.sinCosTo(angles, s, c)
```

## typed/builtin//modules/nx/nx/sub {#typed-builtin-modules-nx-nx-sub}

```lua
nx.sub(dst: NxBuffer, x: NxScalarOrBuffer) -> boolean
```

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

**Parameters**

- `dst` `NxBuffer` — Target buffer (mutated).
- `x` `NxScalarOrBuffer` — Either a scalar or a same-shaped buffer.

**Returns** `boolean` — `true` on success, `false` on type / handle errors.

```lua
nx.sub(b, 0.5)
nx.sub(dst, src)
```

## typed/builtin//modules/nx/nx/sum {#typed-builtin-modules-nx-nx-sum}

```lua
nx.sum(b: NxBuffer) -> number?
```

Reduction: sum of all elements.

**Parameters**

- `b` `NxBuffer` — Source buffer.

**Returns** `number?` — Scalar sum, or `nil` on unknown handle.

```lua
local s = nx.sum(b)
```

## typed/builtin//modules/nx/nx/wanderYaw {#typed-builtin-modules-nx-nx-wanderyaw}

```lua
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)`).

**Parameters**

- `args` `NxWanderArgs` — Table with `{ pos, yaw, rot?, step?, yawDelta?, seed }`.

**Returns** `boolean` — `true` on success, `false` on stride / shape failures.

```lua
nx.wanderYaw({ pos = pos, yaw = yaw, step = 0.5, yawDelta = 0.2, seed = "frame" })
```

## typed/builtin//modules/nx/nx/window/blackman {#typed-builtin-modules-nx-nx-window-blackman}

```lua
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).

**Parameters**

- `n` `number` — Number of samples in the window.

**Returns** `NxBuffer?` — Buffer holding the window samples, or `nil` on failure.

```lua
local w = nx.window.blackman(1024)
```

## typed/builtin//modules/nx/nx/window/hamming {#typed-builtin-modules-nx-nx-window-hamming}

```lua
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).

**Parameters**

- `n` `number` — Number of samples in the window.

**Returns** `NxBuffer?` — Buffer holding the window samples, or `nil` on failure.

```lua
local w = nx.window.hamming(1024)
```

## typed/builtin//modules/nx/nx/window/hann {#typed-builtin-modules-nx-nx-window-hann}

```lua
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).

**Parameters**

- `n` `number` — Number of samples in the window.

**Returns** `NxBuffer?` — Buffer holding the window samples, or `nil` on failure.

```lua
local w = nx.window.hann(1024)
```

## typed/builtin//modules/nx/nx/zeros {#typed-builtin-modules-nx-nx-zeros}

```lua
nx.zeros(n: number, type_: NxType?) -> NxBuffer?
```

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

**Parameters**

- `n` `number` — Record count.
- `type_` `NxType` _(optional)_ — Optional element layout (default `"f32"`).

**Returns** `NxBuffer?` — Buffer initialised to zero.

```lua
local b = nx.zeros(2048)
```

## typed/builtin//modules/preset/M/create {#typed-builtin-modules-preset-m-create}

```lua
M.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`.

## typed/builtin//modules/preset/M/load {#typed-builtin-modules-preset-m-load}

```lua
M.load(source: AssetRef<preset>, overrides: table?) -> { [string]: any }
```

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

## typed/builtin//modules/render_visibility/Vis/showing {#typed-builtin-modules-render-visibility-vis-showing}

```lua
Vis.showing(e: any?) -> boolean?
```

Whether the entity's own renderable is showing, or `nil` when the entity
carries no renderable for a frame to reach.

**Parameters**

- `e` `any` _(optional)_ — Entity proxy.

**Returns** `boolean?` — True while the renderable is drawn, false while it is switched off, `nil` when the entity holds no renderable.

```lua
local showing = Vis.showing(entity.find("chunk_0_0_0"))
```

## typed/builtin//modules/render_visibility/Vis/switchedOff {#typed-builtin-modules-render-visibility-vis-switchedoff}

```lua
Vis.switchedOff(e: any?) -> boolean
```

Whether the frame reaches nothing this entity draws — the entity or an
ancestor is inactive, or the mesh it draws through is switched off.

**Parameters**

- `e` `any` _(optional)_ — Entity proxy.

**Returns** `boolean` — True when nothing this entity draws reaches the frame.

```lua
if Vis.switchedOff(entity.find("rock")) then return end
```

## typed/builtin//modules/rigmath/M/axisAngle {#typed-builtin-modules-rigmath-m-axisangle}

```lua
M.axisAngle(axis: { number }, angle: number) -> { number }
```

Quaternion from an axis and an angle in radians. The axis is normalized
internally; a degenerate axis yields identity.

**Parameters**

- `axis` `{ number }` — Rotation axis.
- `angle` `number` — Rotation angle in radians.

**Returns** `{ number }` — The unit quaternion.

```lua
local q = rigmath.axisAngle({ 0, 1, 0 }, math.pi / 2)
```

## typed/builtin//modules/rigmath/M/clamp {#typed-builtin-modules-rigmath-m-clamp}

```lua
M.clamp(v: number, lo: number, hi: number) -> number
```

Clamp `v` into `[lo, hi]`.

**Parameters**

- `v` `number` — The value.
- `lo` `number` — Lower bound.
- `hi` `number` — Upper bound.

**Returns** `number` — The clamped value.

```lua
local w = rigmath.clamp(weight, 0, 1)
```

## typed/builtin//modules/rigmath/M/computeBoneLengths {#typed-builtin-modules-rigmath-m-computebonelengths}

```lua
M.computeBoneLengths(bones: { any }, gPos: { { number } }) -> { number }
```

Each bone's length, measured as the distance to its farthest child.
Retargeting uses this to scale root translation by rig proportion.

**Parameters**

- `bones` `{ any }` — Array of `{ parent }`; `parent` is 0-based, -1 for a root.
- `gPos` `{ { number } }` — Global positions parallel to `bones`, as returned by `computeGlobals`.

**Returns** `{ number }` — Bone lengths, 1-based and parallel to `bones`. A leaf measures zero.

```lua
local lengths = rigmath.computeBoneLengths(rig.bones, gPos)
```

## typed/builtin//modules/rigmath/M/computeGlobals {#typed-builtin-modules-rigmath-m-computeglobals}

```lua
M.computeGlobals(bones: { any }) -> ({ { number } }, { { number } })
```

Resolve every bone's global rest rotation and position by forward
kinematics over the local rest transforms. Handles any bone ordering — a
parent may be listed after its child — by iterating until all resolve. A
malformed cyclic parent falls back to the bone's local transform.

**Parameters**

- `bones` `{ any }` — Array of `{ parent, rest = { t, r } }`; `parent` is 0-based, -1 for a root.

**Returns** `({ { number } }, { { number } })` — Global rotations followed by global positions, both 1-based and parallel to `bones`.

```lua
local gRot, gPos = rigmath.computeGlobals(rig.bones)
```

## typed/builtin//modules/rigmath/M/isFinite {#typed-builtin-modules-rigmath-m-isfinite}

```lua
M.isFinite(n: number) -> boolean
```

Whether a number is finite — neither NaN nor an infinity.

**Parameters**

- `n` `number` — The number to test.

**Returns** `boolean` — True when `n` is finite.

```lua
if not rigmath.isFinite(x) then return end
```

## typed/builtin//modules/rigmath/M/qangle {#typed-builtin-modules-rigmath-m-qangle}

```lua
M.qangle(q: { number }) -> number
```

The rotation angle of a quaternion in radians, in `[0, pi]`.

**Parameters**

- `q` `{ number }` — The quaternion.

**Returns** `number` — Its rotation magnitude.

```lua
local a = rigmath.qangle(delta)
```

## typed/builtin//modules/rigmath/M/qinverse {#typed-builtin-modules-rigmath-m-qinverse}

```lua
M.qinverse(q: { number }) -> { number }
```

Inverse of a unit quaternion, which is its conjugate. Normalizes first
so a bind rotation that drifted slightly off unit still inverts cleanly.

**Parameters**

- `q` `{ number }` — The quaternion to invert.

**Returns** `{ number }` — The inverse quaternion.

```lua
local inv = rigmath.qinverse(parentGlobalRotation)
```

## typed/builtin//modules/rigmath/M/qmul {#typed-builtin-modules-rigmath-m-qmul}

```lua
M.qmul(a: { number }, b: { number }) -> { number }
```

Hamilton product `a * b` — apply `b`, then `a`. Matches glam's Quat
multiplication so results agree with the engine's own rig math.

**Parameters**

- `a` `{ number }` — Outer rotation.
- `b` `{ number }` — Inner rotation.

**Returns** `{ number }` — The composed quaternion.

```lua
local q = rigmath.qmul(parentGlobal, boneLocal)
```

## typed/builtin//modules/rigmath/M/qnormalize {#typed-builtin-modules-rigmath-m-qnormalize}

```lua
M.qnormalize(q: { number }) -> { number }
```

Normalize a quaternion to unit length. A degenerate quaternion returns
identity rather than NaN.

**Parameters**

- `q` `{ number }` — The quaternion.

**Returns** `{ number }` — The unit quaternion.

```lua
local q = rigmath.qnormalize(accumulated)
```

## typed/builtin//modules/rigmath/M/qrotvec {#typed-builtin-modules-rigmath-m-qrotvec}

```lua
M.qrotvec(q: { number }, v: { number }) -> { number }
```

Rotate a 3-vector by a quaternion.

**Parameters**

- `q` `{ number }` — The rotation.
- `v` `{ number }` — The vector to rotate.

**Returns** `{ number }` — The rotated vector.

```lua
local forward = rigmath.qrotvec(boneRotation, { 0, 0, 1 })
```

## typed/builtin//modules/rigmath/M/qslerp {#typed-builtin-modules-rigmath-m-qslerp}

```lua
M.qslerp(a: { number }, b: { number }, t: number) -> { number }
```

Spherical linear interpolation along the shortest arc. `t = 0` returns
`a`, `t = 1` returns `b`. Falls back to normalized lerp for nearly parallel
inputs, where the arc formulation loses precision.

**Parameters**

- `a` `{ number }` — Start rotation.
- `b` `{ number }` — End rotation.
- `t` `number` — Interpolation factor.

**Returns** `{ number }` — The interpolated unit quaternion.

```lua
local blended = rigmath.qslerp(animatedRotation, solvedRotation, weight)
```

## typed/builtin//modules/rigmath/M/shortestArc {#typed-builtin-modules-rigmath-m-shortestarc}

```lua
M.shortestArc(a: { number }, b: { number }) -> { number }
```

Shortest-arc quaternion rotating unit vector `a` onto unit vector `b`.
The antiparallel case resolves to a half turn about an arbitrary
perpendicular axis instead of producing NaN.

Arbitrarily small rotations are represented rather than rounded away. An
iterative solver refines a pose in ever-smaller steps, so a near-parallel
cutoff would stall it at whatever residual the cutoff angle spans — the
bones needing the finest corrections would be exactly the ones ignored.

**Parameters**

- `a` `{ number }` — Source unit vector.
- `b` `{ number }` — Destination unit vector.

**Returns** `{ number }` — The rotation carrying `a` to `b`.

```lua
local q = rigmath.shortestArc(currentDir, wantedDir)
```

## typed/builtin//modules/rigmath/M/signedAngle {#typed-builtin-modules-rigmath-m-signedangle}

```lua
M.signedAngle(a: { number }, b: { number }, axis: { number }) -> number
```

Signed angle in radians from `a` to `b` measured about `axis`. Both
vectors are projected onto the plane perpendicular to `axis` first, so the
result is the roll about that axis.

**Parameters**

- `a` `{ number }` — Source vector.
- `b` `{ number }` — Destination vector.
- `axis` `{ number }` — The axis to measure about; normalized internally.

**Returns** `number` — The signed angle in radians.

```lua
local roll = rigmath.signedAngle(midOffset, poleOffset, chainDirection)
```

## typed/builtin//modules/rigmath/M/swingTwist {#typed-builtin-modules-rigmath-m-swingtwist}

```lua
M.swingTwist(q: { number }, axis: { number }) -> ({ number }, { number })
```

Split a rotation into its twist about `axis` and the remaining swing.
Rotation limits clamp the twist and rebuild, which is what keeps a hinge
joint on its axis.

**Parameters**

- `q` `{ number }` — The rotation to decompose.
- `axis` `{ number }` — The twist axis; normalized internally.

**Returns** `({ number }, { number })` — The twist quaternion followed by the swing quaternion.

```lua
local twist, swing = rigmath.swingTwist(localRotation, hingeAxis)
```

## typed/builtin//modules/rigmath/M/vadd {#typed-builtin-modules-rigmath-m-vadd}

```lua
M.vadd(a: { number }, b: { number }) -> { number }
```

Component-wise sum `a + b`.

**Parameters**

- `a` `{ number }` — First addend.
- `b` `{ number }` — Second addend.

**Returns** `{ number }` — A new vector.

```lua
local p = rigmath.vadd(rootPos, offset)
```

## typed/builtin//modules/rigmath/M/vcross {#typed-builtin-modules-rigmath-m-vcross}

```lua
M.vcross(a: { number }, b: { number }) -> { number }
```

Cross product of two 3-vectors.

**Parameters**

- `a` `{ number }` — First vector.
- `b` `{ number }` — Second vector.

**Returns** `{ number }` — `a` cross `b` as a new vector.

```lua
local n = rigmath.vcross({ 1, 0, 0 }, { 0, 1, 0 })
```

## typed/builtin//modules/rigmath/M/vdot {#typed-builtin-modules-rigmath-m-vdot}

```lua
M.vdot(a: { number }, b: { number }) -> number
```

Dot product of two 3-vectors.

**Parameters**

- `a` `{ number }` — First vector.
- `b` `{ number }` — Second vector.

**Returns** `number` — The scalar dot product.

```lua
local d = rigmath.vdot({ 1, 0, 0 }, { 0, 1, 0 })
```

## typed/builtin//modules/rigmath/M/vlen {#typed-builtin-modules-rigmath-m-vlen}

```lua
M.vlen(v: { number }) -> number
```

Length of a 3-vector.

**Parameters**

- `v` `{ number }` — The vector.

**Returns** `number` — Its Euclidean length.

```lua
local l = rigmath.vlen({ 3, 4, 0 })
```

## typed/builtin//modules/rigmath/M/vnormalize {#typed-builtin-modules-rigmath-m-vnormalize}

```lua
M.vnormalize(v: { number }) -> { number }
```

Normalize a 3-vector. A zero-length vector returns zero rather than NaN.

**Parameters**

- `v` `{ number }` — The vector to normalize.

**Returns** `{ number }` — The unit vector, or `{ 0, 0, 0 }` when `v` is degenerate.

```lua
local dir = rigmath.vnormalize(rigmath.vsub(target, root))
```

## typed/builtin//modules/rigmath/M/vperpendicular {#typed-builtin-modules-rigmath-m-vperpendicular}

```lua
M.vperpendicular(v: { number }) -> { number }
```

A unit vector perpendicular to `v`, chosen deterministically. Used as a
bend axis when a chain is perfectly straight and carries no pole target.

**Parameters**

- `v` `{ number }` — The reference vector.

**Returns** `{ number }` — A unit vector at right angles to `v`.

```lua
local axis = rigmath.vperpendicular(chainDirection)
```

## typed/builtin//modules/rigmath/M/vscale {#typed-builtin-modules-rigmath-m-vscale}

```lua
M.vscale(v: { number }, s: number) -> { number }
```

Scale a 3-vector by a scalar.

**Parameters**

- `v` `{ number }` — The vector.
- `s` `number` — The scalar.

**Returns** `{ number }` — A new scaled vector.

```lua
local half = rigmath.vscale(dir, 0.5)
```

## typed/builtin//modules/rigmath/M/vsub {#typed-builtin-modules-rigmath-m-vsub}

```lua
M.vsub(a: { number }, b: { number }) -> { number }
```

Component-wise difference `a - b`.

**Parameters**

- `a` `{ number }` — Minuend.
- `b` `{ number }` — Subtrahend.

**Returns** `{ number }` — A new vector.

```lua
local d = rigmath.vsub(tipPos, rootPos)
```

## typed/builtin//modules/scene_build/M/attribute {#typed-builtin-modules-scene-build-m-attribute}

```lua
M.attribute(refusals: { Refusal }) -> { Refusal }
```

Read a refusal's traceback for the one frame that belongs to the code
being built. A build composed from several contributors reports this so an
author reads which contributor was refused rather than which build ran.

**Parameters**

- `refusals` `{ Refusal }` — The refusal array `entity.capture` hands back.

**Returns** `{ Refusal }` — The same entries with `source` filled in where a frame names one.

```lua
local named = SceneBuild.attribute(select(4, entity.capture(fn)))
```

## typed/builtin//modules/scene_build/M/buildSurface {#typed-builtin-modules-scene-build-m-buildsurface}

```lua
M.buildSurface(folder: string, sourceDigest: string) -> BuildSurface
```

The `build` surface a build script reads: the operations that belong to
the build itself rather than to the scene it states. `build.asset(kind,
name, produce)` is the asset a build makes — `produce` runs when the build
script changed and its result is authored at `<folder>/<name>.<kind>`,
and every other run hands back that same asset, guid and all, without
running `produce` at all. The returned `AssetRef` is what a component field
names, so the reference survives the save and the reload.

**Parameters**

- `folder` `string` — The build's own folder, which the assets it produces are authored
inside.
- `sourceDigest` `string` — The digest of the build script running now, as `M.digest`
reports it — what decides whether an asset it produced is still the asset
the code states.

**Returns** `BuildSurface` — The table bound as the `build` global for that build.

```lua
local surface = SceneBuild.buildSurface(dir, SceneBuild.digest(src))
```

## typed/builtin//modules/scene_build/M/digest {#typed-builtin-modules-scene-build-m-digest}

```lua
M.digest(source: string) -> string
```

A short, stable digest of a script's source. Two different scripts give
different digests, and the same script gives the same one on every machine
and every run — which is what makes it the answer to "did the code that
produced this change?".

**Parameters**

- `source` `string` — The script body to digest.

**Returns** `string` — The digest, as a hex string.

```lua
local key = SceneBuild.digest(vfs.read(path))
```

## typed/builtin//modules/scene_build/M/drift {#typed-builtin-modules-scene-build-m-drift}

```lua
M.drift(owner: string?) -> { Drift }
```

Where the live scene disagrees with the build that states it. Every
entity a build placed records what that build last said about each of its
properties, so anything an author has changed since reads back differently
— and this is that list: the entity, the property, what the build said, and
what the scene holds now.

These are the values a rebuild KEEPS. A build repeating itself leaves them
alone, and only a build that states something DIFFERENT about that property
takes it back. So this is what to read to know that a scene and its
`build.luau` disagree, and where, before deciding which should win.

Property names are the ones the build records: `n` name, `i` internal,
`p` position, `r` rotation, `s` scale, and `a:<name>` for an attribute.

**Parameters**

- `owner` `string` _(optional)_ — Optional build name, as `M.ownerOf` reports it, to read just that
build. Omitted, every build-owned entity in the scene is read.

**Returns** `{ Drift }` — Array of `{ entity, name, owner, property, baked, live }`, one per drifted property, sorted by entity then property.

```lua
for _, d in ipairs(SceneBuild.drift()) do print(d.name, d.property) end
```

## typed/builtin//modules/scene_build/M/notePreview {#typed-builtin-modules-scene-build-m-notepreview}

```lua
M.notePreview(entityId: string, values: { [string]: any }, componentType: string?) -> nil
```

Record the values an author left on `entityId`, an entity a build owns.
The build states that entity from its own source, so the values hold until
it runs again — and `M.takePreview` is what the next run reads to say which
of them it replaced and with what. Each record REPLACES the one before it:
what it states is everything the entity carries now, so a name dropped
between two records is dropped here too.

**Parameters**

- `entityId` `string` — Runtime entity id of the owned entity.
- `values` `{ [string]: any }` — The values the entity carries now, by name.
- `componentType` `string` _(optional)_ — The component that states them, so a rebuild knows to state
that type again instead of leaving it to the scene.

**Returns** `nil`

```lua
SceneBuild.notePreview(id, { count = 9 }, "SceneModule")
```

## typed/builtin//modules/scene_build/M/ownerOf {#typed-builtin-modules-scene-build-m-ownerof}

```lua
M.ownerOf(entityId: string) -> string?
```

The build that placed `entityId`, or nil when no build placed it. A
reconcile writes the name of the build onto every entity it places, as an
attribute the scene records beside the entity's name and transform, so the
answer holds across a reload — and an entity an author spawned carries no
owner at all.

**Parameters**

- `entityId` `string` — Runtime entity id.

**Returns** `string?` — The `owner` the reconcile that placed it was called with, or nil.

```lua
if SceneBuild.ownerOf(id) ~= nil then print("a build states this") end
```

## typed/builtin//modules/scene_build/M/previewedComponentType {#typed-builtin-modules-scene-build-m-previewedcomponenttype}

```lua
M.previewedComponentType(entityId: string) -> string?
```

The component type that recorded a preview for `entityId`, or nil when
none is waiting. A component that records one is SAYING that a build states
its fields and that it announces the replacement itself — so a rebuild
states that type again rather than leaving it to the scene, which is what
lets the announcement happen. Every other component is merged.

**Parameters**

- `entityId` `string` — Runtime entity id of the owned entity.

**Returns** `string?` — The component type name, or nil.

```lua
if SceneBuild.previewedComponentType(id) == "SceneModule" then end
```

## typed/builtin//modules/scene_build/M/reconcile {#typed-builtin-modules-scene-build-m-reconcile}

```lua
M.reconcile(records: { any }, target: EntityRef | string | { guid: string }, owner: string, opts: { participation: string?, source: string? }?) -> ({ [string]: string }, number)
```

Apply `records` to the scene under `target`, reusing the entities a
previous reconcile left behind. A record that maps to a live entity
updates THAT entity — same runtime id, so every reference to it survives
the rebuild — and only a record with no live entity spawns one. Entities
the previous build held that this one no longer emits are despawned.
Name, transform, hidden, active, attributes, lifecycle mode, network scope,
whether the entity's live state replicates, and components are all made to
match the record, so a rebuild that drops a component or an attribute drops
it from the scene. Each of them is a diff:
what already matches the record is left exactly as it is, so a rebuild that
changed nothing changes nothing — a running component keeps running and the
scene stays clean. Only entities the build owns are touched: anything else
under `target` is left exactly as it was.
A component field holding an entity reference is resolved as the records
are applied: a reference to an entity of the SAME build points at the
entity this reconcile landed it on, and a reference to any other entity
keeps pointing where it did.
`owner` names the build. Every entity it places carries that name and the
record's identity as attributes of its own, which is what lets a rebuild
find the entities the last one placed without anything being remembered
between them — the pair is in the scene, and a reload brings it back with
the entity. Two builds sharing a target stay out of each other's way by
using different owners.
A record's identity is its place in the hierarchy — the chain of names
from the build root down to it — so dropping, inserting or reordering a
sibling leaves every other entity where it was. Several children of
one parent sharing a name are told apart by their rank among those,
counted in the order the builder created them.

**Parameters**

- `records` `{ any }` — Flat record array, parents before children — what `M.run` returns.
- `target` `EntityRef | string | { guid: string }` — Entity ref, entity id, or scene layer every root record lands in.
- `owner` `string` — Name of the build, unique among the builds sharing this target.
- `opts` `{ participation: string?, source: string? }` _(optional)_ — `participation` sets the lifecycle mode every placed entity takes,
ahead of the mode any record carries. `source` names the file the build is
written in, which `M.sourceOf` reports for every entity the build places.

**Returns** `({ [string]: string }, number)` — The ids this reconcile landed on, keyed by record identity, and how many of them it had to create. A reconcile that created nothing landed on entities the saved scene already holds; one that created something is why the saved scene is now behind the live one.

```lua
local ids = SceneBuild.reconcile(records, root, "chairs")
local ids, created = SceneBuild.reconcile(records, layer, "build")
SceneBuild.reconcile(SceneBuild.run(build), layers.active, "build")
```

## typed/builtin//modules/scene_build/M/run {#typed-builtin-modules-scene-build-m-run}

```lua
M.run(builder: () -> ()) -> ({ any }, { Refusal })
```

Run `builder` inside an entity capture scope and return the records for
every entity it created. The builder writes ordinary spawn code — real
`entity.spawn`, real `component.add`, real loops — and the entities it
creates are real for the duration of the call. They are composed into
records and then despawned, so `run` leaves the scene untouched and hands
back data. Reconciling that data into a scene is `M.reconcile`.
The builder's entities are despawned even when it raises, so a failed
build never leaks a half-built hierarchy into the scene.
What a component the builder attached created while running its own
lifecycle belongs to that component: the record names the COMPONENT, and
the same lifecycle runs again wherever the record is put back, so the
entities come from there rather than from records of their own. That covers
a nested build — a placement the builder makes runs its own module and owns
what it lands — and every other component that expands into entities.
An operation the scope refused is refused BEFORE it lands, so the records
describe the live world exactly as the builder left it, and a builder that
ran to its end around a refusal somebody caught for it composes what it
did make. Every such refusal comes back as the second return, naming the
contributor it stopped, for the caller to report alongside what it baked.

**Parameters**

- `builder` `() -> ()` — Function taking no arguments; spawns whatever it wants.

**Returns** `({ any }, { Refusal })` — Flat array of records, parents before children, siblings in the order the builder created them; and the array of refusals the scope issued, each with `message`, `at` and the `source` frame naming who was refused.

```lua
local records, refused = SceneBuild.run(function() entity.spawn("chair") end)
```

## typed/builtin//modules/scene_build/M/sourceOf {#typed-builtin-modules-scene-build-m-sourceof}

```lua
M.sourceOf(owner: string) -> string?
```

The file that states the build named `owner` — what the reconcile
running that build passed as `opts.source`. Nil for a build that has not
run in this session and for one that named no source.

**Parameters**

- `owner` `string` — Build name, as `M.ownerOf` reports it.

**Returns** `string?` — Path of the file the build is written in, or nil.

```lua
local file = SceneBuild.sourceOf(SceneBuild.ownerOf(id))
```

## typed/builtin//modules/scene_build/M/takePreview {#typed-builtin-modules-scene-build-m-takepreview}

```lua
M.takePreview(entityId: string) -> { [string]: any }?
```

Take the values `M.notePreview` recorded for `entityId` and clear them.
Each set of values is read once — by whichever run of the build states that
entity next.

**Parameters**

- `entityId` `string` — Runtime entity id of the owned entity.

**Returns** `{ [string]: any }?` — The recorded values by name, or nil when none are waiting.

```lua
local set = SceneBuild.takePreview(id)
```

## typed/builtin//modules/scopes/M/current {#typed-builtin-modules-scopes-m-current}

```lua
M.current() -> string?
```

The scope the calling code registers a resource under right now — the
module whose body is running, the component instance whose lifecycle hook
is on the stack, or the chunk of this call. Nil when the caller registers
under no context.

**Returns** `string?` — The scope tag, or nil.

```lua
print("resources I register follow", scopes.current())
```

## typed/builtin//modules/scopes/M/list {#typed-builtin-modules-scopes-m-list}

```lua
M.list() -> { LiveResource }
```

Every live resource that follows an owning context, across every
subsystem holding them. A resource registered with no context above it —
the engine's own — is not listed, because no scope reaches it.

## typed/builtin//modules/scopes/M/release {#typed-builtin-modules-scopes-m-release}

```lua
M.release(scope: string) -> { Released }
```

End every resource registered under `scope`, across every subsystem.
Reaches contexts no seam does — the chunk of an `execute` call that
registered something and ended without releasing it.

**Parameters**

- `scope` `string` — A scope tag, as the `scope` field of a `list()` row carries it.

**Returns** `{ Released }` — One row per subsystem that ended something, with how many it ended.

```lua
local ended = scopes.release("exec:__exec_12")
```

## typed/builtin//modules/session/Session/get {#typed-builtin-modules-session-session-get}

```lua
Session.get(key: string) -> any
```

The value stored under `key` this session, or nil.

## typed/builtin//modules/session/Session/set {#typed-builtin-modules-session-session-set}

```lua
Session.set(key: string, value: any?)
```

Store `value` under `key` for the rest of the engine session.
Pass nil to clear the key.

## typed/builtin//modules/settings/settings/all {#typed-builtin-modules-settings-settings-all}

```lua
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.

**Returns** `{ [string]: any }` — A nested table mirroring the TOML document.

```lua
for section, keys in pairs(settings.all()) do
```

## typed/builtin//modules/settings/settings/get {#typed-builtin-modules-settings-settings-get}

```lua
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.

## typed/builtin//modules/settings/settings/getBool {#typed-builtin-modules-settings-settings-getbool}

```lua
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.

**Parameters**

- `key` `string` — Dotted-path key.
- `default` `boolean` _(optional)_ — Optional fallback boolean.

**Returns** `boolean` — The boolean value or the fallback.

```lua
if settings.getBool("render.shadows", true) then ... end
```

## typed/builtin//modules/settings/settings/getNumber {#typed-builtin-modules-settings-settings-getnumber}

```lua
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.

**Parameters**

- `key` `string` — Dotted-path key.
- `default` `number` _(optional)_ — Optional fallback number.

**Returns** `number` — The number value or the fallback.

```lua
local g = settings.getNumber("physics.gravity", -9.81)
```

## typed/builtin//modules/settings/settings/getString {#typed-builtin-modules-settings-settings-getstring}

```lua
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.

**Parameters**

- `key` `string` — Dotted-path key.
- `default` `string` _(optional)_ — Optional fallback string.

**Returns** `string` — The string value or the fallback.

```lua
local mode = settings.getString("render.culling_mode", "gpu")
```

## typed/builtin//modules/settings/settings/set {#typed-builtin-modules-settings-settings-set}

```lua
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.

## typed/builtin//modules/settings/settings/setMany {#typed-builtin-modules-settings-settings-setmany}

```lua
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`.

**Parameters**

- `updates` `{ [string]: any }` — A table of dotted-key → value pairs.

```lua
settings.setMany({
```

## typed/builtin//modules/signal/M/disconnectAllFromEntity {#typed-builtin-modules-signal-m-disconnectallfromentity}

```lua
M.disconnectAllFromEntity(entityId: string) -> number
```

Disconnect every connection that was sourced from `entityId`
(connections made while that entity's script was on the call stack).
Returns the number disconnected. Called by the entity-destroy
dispatch so a destroyed entity's connections never leak.

**Parameters**

- `entityId` `string` — Entity whose sourced connections to drop.

**Returns** `number`

## typed/builtin//modules/signal/M/disconnectAllFromInstance {#typed-builtin-modules-signal-m-disconnectallfrominstance}

```lua
M.disconnectAllFromInstance(instanceId: string) -> number
```

Disconnect every connection sourced from a specific component
instance (connections made while that instance's script was on the
call stack). Returns the number disconnected. Called by the component
hot-reload / teardown path so a reloaded instance's stale connections
don't accumulate.

**Parameters**

- `instanceId` `string` — Component instance whose sourced connections to drop.

**Returns** `number`

## typed/builtin//modules/signal/M/new {#typed-builtin-modules-signal-m-new}

```lua
M.new() -> any
```

Construct a new `Signal`.

**Returns** `any`

```lua
local hit = Signal.new()
hit:Connect(function(dmg) print("hit for", dmg) end)
hit:Fire(10)
```

## typed/builtin//modules/spawnModel/impl/spawnModel {#typed-builtin-modules-spawnmodel-impl-spawnmodel}

```lua
impl.spawnModel(name: string, source: AssetRef<bundle|mesh>) -> string
```

Spawn an entity with a Model (or registered Asset bundle) plus a Collider at a position, in one call. Static physics by default; `opts.physics` (e.g. "dynamic") makes it a dynamic body of that kind. `opts` also accepts `scale` (number or vector) and `rotation` / `rot` (a quaternion when it carries `w`/`[4]`, else euler degrees). A string identity / guid / path is resolved to an AssetRef, so a primitive name ("cube") or a mesh path passes straight through.

**Parameters**

- `name` `string` — Entity name for the spawned model.
- `source` `AssetRef<bundle|mesh>` — Model source: a primitive name, a library identity/guid, a mesh path, or an AssetRef (bundle or mesh).

**Returns** `string` — The spawned entity id.

```lua
"crate", "cube", 0, 1, 0
"rock", meshRef, { 2, 0, 2 }, { physics = "dynamic" }
```

## typed/builtin//modules/substrate_batch/M/installInto {#typed-builtin-modules-substrate-batch-m-installinto}

```lua
M.installInto(entity: EntityNamespace)
```

Install the polymorphic `batchWrite` / `batchRead` wrappers
onto an `entity`-shaped namespace. The prelude calls this once at
boot with the engine's `entity` global; users shouldn't call it
directly. Errors if the namespace is missing any of the five
required FFI primitives.

**Parameters**

- `entity` `EntityNamespace` — The target entity namespace. Must already carry
`batchWrite`, `batchWriteBound`, `batchWriteFromBuffer`,
`batchRead`, and `batchReadToBuffer` as functions.

```lua
require("modules.substrate_batch").installInto(entity)
```

## typed/builtin//modules/text_diff/M/added {#typed-builtin-modules-text-diff-m-added}

```lua
M.added(newText: string?, opts: DiffOpts?) -> FileDiff
```

Pure-add convenience: build a diff representing the full content
of `newText` as added. Equivalent to `M.diff("", newText, opts)`.

**Parameters**

- `newText` `string` _(optional)_ — The full added content.
- `opts` `DiffOpts` _(optional)_ — Same shape as `M.diff`'s opts.

**Returns** `FileDiff` — The structured `FileDiff` describing the addition.

```lua
local d = TextDiff.added(newBytes, { path = "newfile.luau" })
```

## typed/builtin//modules/text_diff/M/diff {#typed-builtin-modules-text-diff-m-diff}

```lua
M.diff(oldText: string?, newText: string?, opts: DiffOpts?) -> FileDiff
```

Diff two strings and return the structured per-file shape. LCS-based;
produces op-tagged hunks rather than unified-diff text so consumers
can pattern-match on `op` instead of parsing prefixes. Files larger
than `M.SIZE_CAP_BYTES` return a size-only summary with `is_text=false`.

**Parameters**

- `oldText` `string` _(optional)_ — The previous text content. `nil` is treated as `""`.
- `newText` `string` _(optional)_ — The new text content. `nil` is treated as `""`.
- `opts` `DiffOpts` _(optional)_ — Optional. `context` overrides the default 3-line context
window; `path` and `action` are folded into the returned table for
caller convenience.

**Returns** `FileDiff` — The structured `FileDiff` table (see module header for shape).

```lua
local d = TextDiff.diff(oldBytes, newBytes)
local d = TextDiff.diff(oldBytes, newBytes, { path = "foo.luau", context = 5 })
```

## typed/builtin//modules/text_diff/M/removed {#typed-builtin-modules-text-diff-m-removed}

```lua
M.removed(oldText: string?, opts: DiffOpts?) -> FileDiff
```

Pure-remove convenience: full removal of `oldText`. Equivalent
to `M.diff(oldText, "", opts)`.

**Parameters**

- `oldText` `string` _(optional)_ — The full removed content.
- `opts` `DiffOpts` _(optional)_ — Same shape as `M.diff`'s opts.

**Returns** `FileDiff` — The structured `FileDiff` describing the removal.

```lua
local d = TextDiff.removed(oldBytes, { path = "gone.luau" })
```

## typed/builtin//modules/text_diff/M/toStatLine {#typed-builtin-modules-text-diff-m-tostatline}

```lua
M.toStatLine(fileDiff: FileDiff) -> string
```

Compact `--stat`-style summary line for a single file. Mirrors
`git diff --stat`'s per-file row.

**Parameters**

- `fileDiff` `FileDiff` — The structured `FileDiff` table.

**Returns** `string` — One-line summary string. Binary/oversize files report `<action> <path> (binary)` instead of +/- counts.

```lua
print(TextDiff.toStatLine(d))
```

## typed/builtin//modules/text_diff/M/toUnifiedText {#typed-builtin-modules-text-diff-m-tounifiedtext}

```lua
M.toUnifiedText(fileDiff: FileDiff) -> string
```

Render a single file's structured diff back into unified-diff
text. Used by `zm diff` / `zm show` shell commands when the user
wants the conventional `+`/`-`/` ` text output instead of structured
hunks. Pure derivation from the structured shape — no second LCS pass.

**Parameters**

- `fileDiff` `FileDiff` — The structured `FileDiff` table. Binary / oversize files
(`is_text == false`) render as a single suppression line including
the size delta when available.

**Returns** `string` — The unified-diff body as a single string (no trailing newline).

```lua
print(TextDiff.toUnifiedText(d))
```

## typed/builtin//modules/toml/toml/encode {#typed-builtin-modules-toml-toml-encode}

```lua
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.

**Parameters**

- `root` `{ [string]: any }` — The table to encode. Must be string-keyed at the root.

**Returns** `string` — A TOML-formatted string suitable for `vfs.write`.

```lua
local body = toml.encode({ render = { culling_mode = "gpu" } })
```

## typed/builtin//modules/toml/toml/parse {#typed-builtin-modules-toml-toml-parse}

```lua
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.

**Parameters**

- `src` `string` — TOML source bytes as a string.

**Returns** `{ [string]: any }` — The parsed root table. Sub-tables are plain Luau tables; arrays are 1-indexed sequence tables.

```lua
local t = toml.parse('[a]\nx = 1\ny = "hi"\n')
```

## typed/builtin//modules/tools/M/bind {#typed-builtin-modules-tools-m-bind}

```lua
M.bind(identity: string, positional: { any }?, named: { [string]: any }?, opts: BindOpts?) -> BindResult
```

Resolve a call's arguments against a tool's declared parameters,
turning named arguments into the positional call the tool actually
takes. This is the binder behind `zero <toolbox> <tool> --name value`
and the `use_tool` MCP tool's named `args`, so a name resolves the
same way whichever surface the caller reached for. Reads the schema
from `tools.get`, matches each name to a parameter (exactly first,
then case-insensitively), and reports the first unresolvable name,
a name that a positional argument already filled, a call longer than
the signature, and a required parameter skipped over while a later
one is filled. Resolves the call only — running it is `tools.use`.

**Parameters**

- `identity` `string` — Tool identity (`"<toolbox>.<name>"`, with or without the
leading `tools.`).
- `positional` `{ any }` _(optional)_ — Arguments already given by position, filling slots from 1.
- `named` `{ [string]: any }` _(optional)_ — Arguments given by name, `{ [parameterName]: value }`.
- `opts` `BindOpts` _(optional)_ — `order` — the order to visit `named` in, so the first problem
reported is the caller's first (defaults to sorted, for a stable
answer). `prefix` — written in front of every argument name in the
failure message, `"--"` for a shell flag. `whole` — read `named` as ONE
table argument when not one of its keys names a parameter, and as the
first argument written inline when only some of them do, for a surface
whose payload is ambiguous between the two readings.
`positionalCount` — how many slots `positional` fills, for a caller
that passed an explicit `nil` and so cannot be measured by length.

**Returns** `BindResult` — `{ ok, call, count, failure? }`. Call the tool with `table.unpack(call, 1, count)`; on failure `call` is empty and `failure` carries the reason.

```lua
bind("camera.lookAt", {}, { target = { 0, 5, 0 } })
bind("MaterialAuthor.fromColor", {}, { color = { 1, 0, 0 } }, { whole = true })
```

## typed/builtin//modules/tools/M/create {#typed-builtin-modules-tools-m-create}

```lua
M.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.

## typed/builtin//modules/tools/M/createToolbox {#typed-builtin-modules-tools-m-createtoolbox}

```lua
M.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.

**Parameters**

- `args` `{ [string]: any }` — Structured toolbox definition.
Required: `name` (the toolbox's leaf name, e.g. `"mytools"` —
becomes `<name>.toolbox/` on disk and the namespace for tool
identities), `description` (one or more sentences describing
the surface this toolbox exposes — what problem space the
tools cover and who calls them).
Optional: `sharedCode` — replacement body for the toolbox's
`shared.module/init.luau`. The toolbox template ALWAYS ships
a `shared.module/` with default `ok`/`fail` result-envelope
constructors so tools in this toolbox can `require(".shared")`
from day one. Supply `sharedCode` only when you want to
override that default with custom cross-tool helpers
(parsers, registries, …); the module body is left untouched
if you omit it. `path` — explicit VFS destination
(`/zero/source/...` form). Defaults to
`/zero/source/tools/<name>` if omitted; pass an explicit path
to author a library-scoped or package-internal toolbox.

**Returns** `{ ok: boolean, path: string?, identity: string?, error: string? }` — `{ ok, path?, identity?, error? }`. `path` — the new `.toolbox/` folder's VFS path. `identity` — the toolbox's registered identity (`<name>`).

```lua
tools.createToolbox({ name = "mytools", description = "Custom tooling for my workflow." })
```

## typed/builtin//modules/tools/M/delete {#typed-builtin-modules-tools-m-delete}

```lua
M.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).

**Parameters**

- `identity` `string` — Tool identity (`"<toolbox>.<name>"`).

**Returns** `{ ok: boolean, path: string?, error: string? }` — Table shaped `{ ok, path?, error? }`.

```lua
tools.delete("mytools.hello")
```

## typed/builtin//modules/tools/M/get {#typed-builtin-modules-tools-m-get}

```lua
M.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.

## typed/builtin//modules/tools/M/list {#typed-builtin-modules-tools-m-list}

```lua
M.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.

## typed/builtin//modules/tools/M/search {#typed-builtin-modules-tools-m-search}

```lua
M.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` + `args`, an array in signature order
or an object naming the parameters), the form each entry's
`examples` are rendered in.

**Parameters**

- `query` `string` _(optional)_ — Free-text search string. Tokenized lowercase on
non-alphanumeric boundaries; each token is matched against tool
name, description, and tags. Empty or nil with no `toolbox`
filter lists every tool.
- `opts` `{ toolbox: string?, limit: number? }` _(optional)_ — Optional filters table.
`toolbox` — keep only tools whose owning toolbox exactly matches.
`limit` — maximum entries to return (default `10`; pass a larger value to
return more, up to every match — there is no upper cap).

**Returns** `{ stdout: string, value: any }` — Table shaped `{ stdout: string, value: { SearchEntry } }`. `value` is the ranked array; each entry is `{ name = "<toolbox>.<tool>", signature?, description, toolbox?, tags?, examples? }`. `stdout` is a one-line human summary of the match count.

```lua
tools.search("spawn camera")
tools.search("material", { limit = 5 })
tools.search("", { toolbox = "physics" })   -- list a toolbox
tools.search("")                             -- list everything
```

## typed/builtin//modules/tools/M/toolboxes {#typed-builtin-modules-tools-m-toolboxes}

```lua
M.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`.

**Returns** `{ stdout: string, value: { { toolbox: string, purpose: string, toolCount: number } } }` — Table shaped `{ stdout: string, value: { { toolbox, purpose, toolCount } } }`. `value` is toolbox-name-sorted; each entry is `{ toolbox = "<name>", purpose = "<one line>", toolCount = <n> }`.

```lua
tools.toolboxes()
```

## typed/builtin//modules/tools/M/tryUse {#typed-builtin-modules-tools-m-tryuse}

```lua
M.tryUse(toolbox: string, tool: string, ...: any?) -> ToolCall
```

Invoke one code-mode tool and report the outcome as a value. Takes the
same arguments as `tools.use` and resolves the toolbox the same way, and
returns `{ ok, value, error, toolbox, tool }` for every outcome — an
unknown toolbox, an unknown tool, a tool that reported failure, and a tool
that raised all arrive as `ok = false` with the reason in `error`. The
fields are the ones the `use_tool` MCP surface reports, so a script
comparing several calls in one pass reads the same names it would over
MCP, and reads them without wrapping each call in `pcall`.

**Parameters**

- `toolbox` `string` — The owning toolbox — an ambient toolbox by its name (`"entityOps"`)
or a library toolbox by its scoped identity (`"@lib::ns"`).
- `tool` `string` — The tool's leaf name within that toolbox (`"spawn"`).
- `...` `any` _(optional)_

**Returns** `ToolCall` — `{ ok, value, error, toolbox, tool }`. `value` carries the tool's own value when `ok` is true; `error` carries the reason when it is false.

```lua
tryUse("entityOps", "spawn", { Model = { model = "cube" } })
```

## typed/builtin//modules/tools/M/use {#typed-builtin-modules-tools-m-use}

```lua
M.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. `tools.tryUse` takes the same arguments and reports the
outcome as a value instead of raising.

**Parameters**

- `toolbox` `string` — The owning toolbox — an ambient toolbox by its name (`"entityOps"`)
or a library toolbox by its scoped identity (`"@lib::ns"`).
- `tool` `string` — The tool's leaf name within that toolbox (`"spawn"`).
- `...` `any` _(optional)_

**Returns** `...any` — Everything the tool returned, in the order it returned it — a tool declaring `(path, reason, frame)` hands back all three, so a second and third value the tool states are read the way the tool's own signature says. Raises on an unknown toolbox / tool or a tool-reported failure. These are the tool's OWN values, not the `{ ok, value }` envelope the `use_tool` MCP surface reports — reach for `tools.tryUse` when the call's outcome is what you want.

```lua
use("entityOps", "spawn", { Model = { model = "cube" } }, { position = {0, 2, 0} })
```

## typed/builtin//modules/transform/T/direction {#typed-builtin-modules-transform-t-direction}

```lua
T.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).

**Parameters**

- `fromX` `number` — From x.
- `fromY` `number` — From y.
- `fromZ` `number` — From z.
- `toX` `number` — To x.
- `toY` `number` — To y.
- `toZ` `number` — To z.

**Returns** `(number, number, number)` — Three numbers `dx, dy, dz` — the unit direction.

```lua
local dx, dy, dz = Transform.direction(0, 0, 0, 1, 0, 0)
```

## typed/builtin//modules/transform/T/directionBetween {#typed-builtin-modules-transform-t-directionbetween}

```lua
T.directionBetween(entityA: string | EntityRef, entityB: string | EntityRef) -> (number, number, number)
```

Normalized world-space direction from one entity to another, read
from their world positions. Returns zeros if either entity can't be
resolved.

**Parameters**

- `entityA` `string | EntityRef` — Source entity (id string or proxy).
- `entityB` `string | EntityRef` — Target entity (id string or proxy).

**Returns** `(number, number, number)` — Three numbers `dx, dy, dz` — the unit direction.

```lua
local dx, dy, dz = Transform.directionBetween("cam", "target")
```

## typed/builtin//modules/transform/T/distance {#typed-builtin-modules-transform-t-distance}

```lua
T.distance(x1: number, y1: number, z1: number, x2: number, y2: number, z2: number) -> number
```

Euclidean distance between two world-space positions.

**Parameters**

- `x1` `number` — First point x.
- `y1` `number` — First point y.
- `z1` `number` — First point z.
- `x2` `number` — Second point x.
- `y2` `number` — Second point y.
- `z2` `number` — Second point z.

**Returns** `number` — The Euclidean distance.

```lua
local d = Transform.distance(0, 0, 0, 1, 1, 1)
```

## typed/builtin//modules/transform/T/distanceBetween {#typed-builtin-modules-transform-t-distancebetween}

```lua
T.distanceBetween(entityA: string | EntityRef, entityB: string | EntityRef) -> number?
```

Distance between two entities in world space. Each entity's world
position is what is measured, so a parent's offset counts toward the
distance the way the scene shows it.

**Parameters**

- `entityA` `string | EntityRef` — First entity (id string or proxy).
- `entityB` `string | EntityRef` — Second entity (id string or proxy).

**Returns** `number?` — The Euclidean distance, or `nil` when either entity can't be resolved.

```lua
local d = Transform.distanceBetween("cam", "box")
```

## typed/builtin//modules/transform/T/euler {#typed-builtin-modules-transform-t-euler}

```lua
T.euler(qx: number, qy: number, qz: number, qw: number) -> (number, number, number)
```

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

**Parameters**

- `qx` `number` — Quaternion x.
- `qy` `number` — Quaternion y.
- `qz` `number` — Quaternion z.
- `qw` `number` — Quaternion w.

**Returns** `(number, number, number)` — Three numbers `yaw, pitch, roll` (Y, X, Z rotations).

```lua
local yaw, pitch, roll = Transform.euler(0, 0, 0, 1)
```

## typed/builtin//modules/transform/T/eulerToQuat {#typed-builtin-modules-transform-t-eulertoquat}

```lua
T.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).

**Parameters**

- `yaw` `number` — Y-axis rotation in radians.
- `pitch` `number` _(optional)_ — X-axis rotation in radians. Defaults to 0.
- `roll` `number` _(optional)_ — Z-axis rotation in radians. Defaults to 0.

**Returns** `(number, number, number, number)` — Four numbers `qx, qy, qz, qw`.

```lua
local qx, qy, qz, qw = Transform.eulerToQuat(math.pi / 2)
```

## typed/builtin//modules/transform/T/lerp {#typed-builtin-modules-transform-t-lerp}

```lua
T.lerp(ax: number, ay: number, az: number, bx: number, by: number, bz: number, t: number) -> (number, number, number)
```

Linearly interpolate between two positions.

**Parameters**

- `ax` `number` — Start x.
- `ay` `number` — Start y.
- `az` `number` — Start z.
- `bx` `number` — End x.
- `by` `number` — End y.
- `bz` `number` — End z.
- `t` `number` — Interpolation factor `[0, 1]`.

**Returns** `(number, number, number)` — Three numbers — the interpolated position.

```lua
local x, y, z = Transform.lerp(0, 0, 0, 1, 1, 1, 0.5)
```

## typed/builtin//modules/transform/T/lerp1 {#typed-builtin-modules-transform-t-lerp1}

```lua
T.lerp1(a: number, b: number, t: number) -> number
```

Linearly interpolate two scalars.

**Parameters**

- `a` `number` — Start value.
- `b` `number` — End value.
- `t` `number` — Interpolation factor `[0, 1]`.

**Returns** `number` — The interpolated scalar.

```lua
local v = Transform.lerp1(0, 10, 0.5)
```

## typed/builtin//modules/transform/T/lerpAngle {#typed-builtin-modules-transform-t-lerpangle}

```lua
T.lerpAngle(a: number, b: number, t: number) -> number
```

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

**Parameters**

- `a` `number` — Start angle in radians.
- `b` `number` — End angle in radians.
- `t` `number` — Interpolation factor `[0, 1]`.

**Returns** `number` — The interpolated angle, normalized to `[-pi, pi]`.

```lua
local a = Transform.lerpAngle(0, math.pi, 0.5)
```

## typed/builtin//modules/transform/T/localToWorld {#typed-builtin-modules-transform-t-localtoworld}

```lua
T.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.

**Parameters**

- `px` `number` — Parent position x.
- `py` `number` — Parent position y.
- `pz` `number` — Parent position z.
- `pqx` `number` — Parent rotation x.
- `pqy` `number` — Parent rotation y.
- `pqz` `number` — Parent rotation z.
- `pqw` `number` — Parent rotation w.
- `lx` `number` — Local x.
- `ly` `number` — Local y.
- `lz` `number` — Local z.

**Returns** `(number, number, number)` — Three numbers `wx, wy, wz` — the world position.

```lua
local wx, wy, wz = Transform.localToWorld(px, py, pz, pqx, pqy, pqz, pqw, lx, ly, lz)
```

## typed/builtin//modules/transform/T/lookAt {#typed-builtin-modules-transform-t-lookat}

```lua
T.lookAt(entityOrId: string | EntityRef, txOrTarget: any?, ty: any?, tz: number?, up: any?) -> (boolean, string?)
```

Make an entity face a world position. The target slot accepts three
explicit coordinates, one point as `{ x, y, z }` / `{ x =, y =, z = }` / a
vector, or an entity — an id string, an entity NAME, or a proxy — whose
WORLD position is resolved. A table carrying an entity id reads as that
entity; any other table reads as the point it spells. The subject slot
takes the three entity spellings.
Everything here is world space: the subject and the target are
read as `entity(id).position` and the aim is written as
`entity(id).rotation`, so a parent under either one moves the entity and
the aim still lands on the point named.
Returns whether the rotation was written, so a caller that named an entity
the scene does not carry learns the aim did not happen instead of reading
a stale orientation back as the answer.

**Parameters**

- `entityOrId` `string | EntityRef` — Entity id, name, or proxy for the entity to rotate.
- `txOrTarget` `any` _(optional)_ — A number (world x), a point table, or an entity id / name /
proxy whose world position is resolved as the look-at target.
- `ty` `any` _(optional)_ — World y of the target. Omitted when `txOrTarget` is a point or an entity.
- `tz` `number` _(optional)_ — World z of the target. Omitted when `txOrTarget` is a point or an entity.
- `up` `any` _(optional)_ — Optional world up hint deciding the roll — `{ x, y, z }`,
`{ x =, y =, z = }` or a vector. World +Y when omitted. It never bends the
aim; it only says which way is up around it. When the target slot is an
entity or a point this is the third argument, and when it is coordinates
the fifth.

**Returns** `(boolean, string?)` — True when the entity's world rotation was written, and nil for the second value. The target and up slots take any value, because naming which of the shapes arrived is this call's own job: a value that is none of them comes back as a reason rather than as an error raised out of the argument check. False plus a reason otherwise: `"unresolved"` when a reference names no entity, `"no-transform"` when one carries no transform, `"incomplete-target"` when the target spells no point — coordinates with a y or z missing, or a table carrying neither three numbers nor x/y/z, `"incomplete-up"` when the up hint spells none either, `"degenerate"` when the two points coincide so no facing direction exists.

```lua
Transform.lookAt("cam", 0, 1, 0)
Transform.lookAt("cam", "box")  -- resolve target entity position
Transform.lookAt(cam, box)      -- entity proxies for both
Transform.lookAt("cam", { 0, 1, 0 })         -- one point table
Transform.lookAt("cam", "box", { 0, 0, 1 })  -- rolled to a +Z up
```

## typed/builtin//modules/transform/T/lookAtQuat {#typed-builtin-modules-transform-t-lookatquat}

```lua
T.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.

**Parameters**

- `fx` `number` — Origin x.
- `fy` `number` — Origin y.
- `fz` `number` — Origin z.
- `tx` `number` — Target x.
- `ty` `number` — Target y.
- `tz` `number` — Target z.

**Returns** `(number?, number?, number?, number?)` — Four numbers `qx, qy, qz, qw` — the look-at quaternion. Nil when degenerate.

```lua
local qx, qy, qz, qw = Transform.lookAtQuat(0, 0, 0, 1, 0, 1)
```

## typed/builtin//modules/transform/T/lookRotation {#typed-builtin-modules-transform-t-lookrotation}

```lua
T.lookRotation(fx: number, fy: number, fz: number, tx: number, ty: number, tz: number, ux: number?, uy: number?, uz: number?) -> (number?, number?, number?, number?)
```

The rotation that aims an entity standing at one world point at another,
with a world up hint deciding the roll. Where `lookAtQuat` derives the aim
from yaw and pitch alone — clamping the pitch just short of vertical, so a
point directly overhead comes back a twentieth of a degree off — this builds
all three axes, so the aim lands on the point at any elevation and straight
up and straight down are ordinary cases.
The aimed axis is the entity's local -Z, the same forward `quatFromBasis`,
`Transform.lookAt` and `entity(id):lookAt` state and the direction
`entity(id).transform.forward` reads back.
The up hint is a world direction the entity's own +Y is turned toward as
far as the aim allows; it never bends the forward axis. A hint parallel to
the aim leaves the roll undetermined, and a hint of no length names no
direction — both fall back to a stable roll rather than a NaN.

**Parameters**

- `fx` `number` — Eye x — where the entity stands.
- `fy` `number` — Eye y.
- `fz` `number` — Eye z.
- `tx` `number` — Target x — the world point it faces.
- `ty` `number` — Target y.
- `tz` `number` — Target z.
- `ux` `number` _(optional)_ — Up hint x. World +Y when the hint is omitted.
- `uy` `number` _(optional)_ — Up hint y.
- `uz` `number` _(optional)_ — Up hint z.

**Returns** `(number?, number?, number?, number?)` — Four numbers `qx, qy, qz, qw`. Nil when the eye and the target coincide, so no facing direction exists.

```lua
local qx, qy, qz, qw = Transform.lookRotation(0, 2, 10, 0, 1, 0)
entity("cam").rotation = { Transform.lookRotation(0, 2, 10, 0, 1, 0) }
-- a dutch tilt: the same aim, rolled by leaning the up hint
local q = { Transform.lookRotation(0, 2, 10, 0, 1, 0, 0.2, 1, 0) }
```

## typed/builtin//modules/transform/T/normalizeAngle {#typed-builtin-modules-transform-t-normalizeangle}

```lua
T.normalizeAngle(a: number) -> number
```

Normalize an angle into `[-pi, pi]`.

**Parameters**

- `a` `number` — The angle in radians.

**Returns** `number` — The same angle wrapped into `[-pi, pi]`.

```lua
local a = Transform.normalizeAngle(3 * math.pi)
```

## typed/builtin//modules/transform/T/orbit {#typed-builtin-modules-transform-t-orbit}

```lua
T.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.

**Parameters**

- `centerX` `number` — Center x.
- `centerY` `number` — Center y.
- `centerZ` `number` — Center z.
- `radius` `number` — Horizontal distance from the center.
- `height` `number` — Vertical offset from `centerY`.
- `angle` `number` — Orbital angle in radians.

**Returns** `(number, number, number, number, number, number, number)` — Seven numbers `x, y, z, qx, qy, qz, qw`.

```lua
local x, y, z, qx, qy, qz, qw = Transform.orbit(0, 1, 0, 5, 2, t)
```

## typed/builtin//modules/transform/T/quatFromAxisAngle {#typed-builtin-modules-transform-t-quatfromaxisangle}

```lua
T.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).

**Parameters**

- `ax` `number` — Axis x.
- `ay` `number` — Axis y.
- `az` `number` — Axis z.
- `angle` `number` — Rotation angle in radians.

**Returns** `(number, number, number, number)` — Four numbers `qx, qy, qz, qw`.

```lua
local qx, qy, qz, qw = Transform.quatFromAxisAngle(0, 1, 0, math.pi)
```

## typed/builtin//modules/transform/T/quatFromBasis {#typed-builtin-modules-transform-t-quatfrombasis}

```lua
T.quatFromBasis(rx: number, ry: number, rz: number, ux: number, uy: number, uz: number, fx: number, fy: number, fz: number) -> (number, number, number, number)
```

Build the rotation whose right, up and forward ARE the given axes. Where
`lookAtQuat` derives a rotation from a direction alone — yaw and pitch, with
pitch clamped just short of straight up or down and no say in the roll — this
states all three axes, so a view straight down has a defined image-up instead
of whatever the yaw implied. The axes are expected orthonormal and are used as
given: `right` and `up` are the entity's local +X and +Y, `forward` its local
-Z (the direction it faces).

**Parameters**

- `rx` `number` — Right axis x.
- `ry` `number` — Right axis y.
- `rz` `number` — Right axis z.
- `ux` `number` — Up axis x.
- `uy` `number` — Up axis y.
- `uz` `number` — Up axis z.
- `fx` `number` — Forward axis x.
- `fy` `number` — Forward axis y.
- `fz` `number` — Forward axis z.

**Returns** `(number, number, number, number)` — x, y, z, w of the rotation quaternion.

```lua
local qx, qy, qz, qw = Transform.quatFromBasis(1,0,0, 0,1,0, 0,0,-1) -- identity
-- looking straight down with the subject's front toward the top of frame
local qx, qy, qz, qw = Transform.quatFromBasis(1,0,0, 0,0,-1, 0,-1,0)
```

## typed/builtin//modules/transform/T/quatFromYaw {#typed-builtin-modules-transform-t-quatfromyaw}

```lua
T.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`.

**Parameters**

- `yaw` `number` — Rotation in radians around the Y axis.

**Returns** `(number, number, number, number)` — Four numbers `qx, qy, qz, qw`.

```lua
local qx, qy, qz, qw = Transform.quatFromYaw(math.pi / 2)
```

## typed/builtin//modules/transform/T/quatFromYawPitch {#typed-builtin-modules-transform-t-quatfromyawpitch}

```lua
T.quatFromYawPitch(yaw: number, pitch: number) -> (number, number, number, number)
```

Create quaternion from yaw and pitch in radians.

**Parameters**

- `yaw` `number` — Y-axis rotation in radians.
- `pitch` `number` — X-axis rotation in radians.

**Returns** `(number, number, number, number)` — Four numbers `qx, qy, qz, qw`.

```lua
local qx, qy, qz, qw = Transform.quatFromYawPitch(0, math.pi / 4)
```

## typed/builtin//modules/transform/T/quatIdentity {#typed-builtin-modules-transform-t-quatidentity}

```lua
T.quatIdentity() -> (number, number, number, number)
```

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

**Returns** `(number, number, number, number)` — Four numbers `qx, qy, qz, qw` — the identity.

```lua
local qx, qy, qz, qw = Transform.quatIdentity()
```

## typed/builtin//modules/transform/T/quatInverse {#typed-builtin-modules-transform-t-quatinverse}

```lua
T.quatInverse(qx: number, qy: number, qz: number, qw: number) -> (number, number, number, number)
```

Quaternion inverse. Equal to the conjugate for unit quaternions.

**Parameters**

- `qx` `number` — Quaternion x.
- `qy` `number` — Quaternion y.
- `qz` `number` — Quaternion z.
- `qw` `number` — Quaternion w.

**Returns** `(number, number, number, number)` — Four numbers `qx, qy, qz, qw` — the inverse.

```lua
local ix, iy, iz, iw = Transform.quatInverse(qx, qy, qz, qw)
```

## typed/builtin//modules/transform/T/quatMul {#typed-builtin-modules-transform-t-quatmul}

```lua
T.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`).

**Parameters**

- `ax` `number` — Left quat x.
- `ay` `number` — Left quat y.
- `az` `number` — Left quat z.
- `aw` `number` — Left quat w.
- `bx` `number` — Right quat x.
- `by` `number` — Right quat y.
- `bz` `number` — Right quat z.
- `bw` `number` — Right quat w.

**Returns** `(number, number, number, number)` — Four numbers `qx, qy, qz, qw` — the composed quaternion.

```lua
local qx, qy, qz, qw = Transform.quatMul(ax, ay, az, aw, bx, by, bz, bw)
```

## typed/builtin//modules/transform/T/quatRotateVec {#typed-builtin-modules-transform-t-quatrotatevec}

```lua
T.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.

**Parameters**

- `qx` `number` — Quaternion x.
- `qy` `number` — Quaternion y.
- `qz` `number` — Quaternion z.
- `qw` `number` — Quaternion w.
- `vx` `number` — Vector x.
- `vy` `number` — Vector y.
- `vz` `number` — Vector z.

**Returns** `(number, number, number)` — Three numbers — the rotated vector.

```lua
local rx, ry, rz = Transform.quatRotateVec(qx, qy, qz, qw, 1, 0, 0)
```

## typed/builtin//modules/transform/T/quatToEuler {#typed-builtin-modules-transform-t-quattoeuler}

```lua
T.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.

**Parameters**

- `qx` `number` — Quaternion x.
- `qy` `number` — Quaternion y.
- `qz` `number` — Quaternion z.
- `qw` `number` — Quaternion w.

**Returns** `(number, number, number)` — Three numbers `yaw, pitch, roll` (Y, X, Z rotations).

```lua
local yaw, pitch, roll = Transform.quatToEuler(qx, qy, qz, qw)
```

## typed/builtin//modules/transform/T/readVec3 {#typed-builtin-modules-transform-t-readvec3}

```lua
T.readVec3(value: Vec3Input, label: string?) -> { number }
```

Normalize a vector a caller wrote to a plain `{ x, y, z }` array.
Accepts a positional array `{1, 2, 3}`, a keyed table
`{x =, y =, z =}`, or a live vec handle. Missing components read as 0.
Raises when the value is not a vector; `label` names the caller in
that error.

**Parameters**

- `value` `Vec3Input` — The vector to normalize.
- `label` `string` _(optional)_ — Name reported in the error when the value is not a vector. Defaults to "Transform".

**Returns** `{ number }` — A three-element array `{ x, y, z }`.

```lua
local v = Transform.readVec3({ x = 1, y = 2, z = 3 })
```

## typed/builtin//modules/transform/T/slerp {#typed-builtin-modules-transform-t-slerp}

```lua
T.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).

**Parameters**

- `ax` `number` — Start quaternion x.
- `ay` `number` — Start quaternion y.
- `az` `number` — Start quaternion z.
- `aw` `number` — Start quaternion w.
- `bx` `number` — End quaternion x.
- `by` `number` — End quaternion y.
- `bz` `number` — End quaternion z.
- `bw` `number` — End quaternion w.
- `t` `number` — Interpolation factor `[0, 1]`.

**Returns** `(number, number, number, number)` — Four numbers `qx, qy, qz, qw` — the interpolated unit quaternion.

```lua
local qx, qy, qz, qw = Transform.slerp(0, 0, 0, 1, 1, 0, 0, 0, 0.5)
```

## typed/builtin//modules/transform/T/snapVec3 {#typed-builtin-modules-transform-t-snapvec3}

```lua
T.snapVec3(v: { number }, step: number | Vec3Input) -> { number }
```

Quantize each component of a vector to the nearest multiple of
`step` — a number for uniform steps, or a vector for per-axis steps.
A step of 0 on an axis leaves that axis at its exact value.

**Parameters**

- `v` `{ number }` — The vector to quantize, as `{ x, y, z }`.
- `step` `number | Vec3Input` — Uniform step size, or a per-axis vector of step sizes.

**Returns** `{ number }` — A three-element array `{ x, y, z }` snapped to the step grid.

```lua
local v = Transform.snapVec3({ 1.4, 2.6, -0.4 }, 1)
```

## typed/builtin//modules/transform/T/toQuaternion {#typed-builtin-modules-transform-t-toquaternion}

```lua
T.toQuaternion(rotation: any?, label: string?) -> { number }
```

Normalize a rotation a caller wrote to a `{ qx, qy, qz, qw }`
quaternion. Accepts a quaternion (`{x,y,z,w}` or `{x=,y=,z=,w=}`) or
euler DEGREES (`{pitch,yaw,roll}` or `{pitch=,yaw=,roll=}`), so one
call site takes whichever form the caller finds natural. This is the
reading every rotation-taking surface in the engine shares, so a
quaternion and euler degrees mean the same thing at all of them.
Raises when the value matches no form; `label` names the caller in that
error, and a value that is one of the shapes a quaternion helper returns
is named as such along with the packing it goes in as.

**Parameters**

- `rotation` `any` _(optional)_ — The rotation to normalize, in any form of the `RotationInput` union.
- `label` `string` _(optional)_ — Name reported in the error when the value is not a rotation. Defaults to "Transform".

**Returns** `{ number }` — A four-element array `{ qx, qy, qz, qw }`.

```lua
local q = Transform.toQuaternion({ pitch = 0, yaw = 90, roll = 0 })
```

## typed/builtin//modules/transform/T/tryQuaternion {#typed-builtin-modules-transform-t-tryquaternion}

```lua
T.tryQuaternion(rotation: any?, label: string?) -> ({ number }?, string?)
```

Read a rotation a caller wrote WITHOUT raising: returns the
canonical `{ qx, qy, qz, qw }`, or nil and the message describing what
arrived. The forms are the `RotationInput` union — a quaternion
(`{x,y,z,w}` or `{x=,y=,z=,w=}`) or euler DEGREES (`{pitch,yaw,roll}` or
`{pitch=,yaw=,roll=}`). Takes any value because reporting on a value that
is none of those forms is the whole job; a setter built on this raises the
returned message itself, so the error points at the line that wrote the
value rather than at the reading.

**Parameters**

- `rotation` `any` _(optional)_ — The value to read as a rotation.
- `label` `string` _(optional)_ — Name reported in the message. Defaults to "Transform".

**Returns** `({ number }?, string?)` — The quaternion `{ qx, qy, qz, qw }`, or nil and the message.

```lua
local q, why = Transform.tryQuaternion(value, "myTool")
```

## typed/builtin//modules/transform/T/vec/add {#typed-builtin-modules-transform-t-vec-add}

```lua
T.vec.add(ax: number, ay: number, az: number, bx: number, by: number, bz: number) -> (number, number, number)
```

Component-wise vec3 addition.

**Parameters**

- `ax` `number` — First vector x.
- `ay` `number` — First vector y.
- `az` `number` — First vector z.
- `bx` `number` — Second vector x.
- `by` `number` — Second vector y.
- `bz` `number` — Second vector z.

**Returns** `(number, number, number)` — Three numbers — the sum.

```lua
local x, y, z = Transform.vec.add(1, 2, 3, 4, 5, 6)
```

## typed/builtin//modules/transform/T/vec/cross {#typed-builtin-modules-transform-t-vec-cross}

```lua
T.vec.cross(ax: number, ay: number, az: number, bx: number, by: number, bz: number) -> (number, number, number)
```

Cross product `a x b`.

**Parameters**

- `ax` `number` — First vector x.
- `ay` `number` — First vector y.
- `az` `number` — First vector z.
- `bx` `number` — Second vector x.
- `by` `number` — Second vector y.
- `bz` `number` — Second vector z.

**Returns** `(number, number, number)` — Three numbers `cx, cy, cz` — the cross product.

```lua
local cx, cy, cz = Transform.vec.cross(1, 0, 0, 0, 1, 0)
```

## typed/builtin//modules/transform/T/vec/dot {#typed-builtin-modules-transform-t-vec-dot}

```lua
T.vec.dot(ax: number, ay: number, az: number, bx: number, by: number, bz: number) -> number
```

Dot product of two vec3s.

**Parameters**

- `ax` `number` — First vector x.
- `ay` `number` — First vector y.
- `az` `number` — First vector z.
- `bx` `number` — Second vector x.
- `by` `number` — Second vector y.
- `bz` `number` — Second vector z.

**Returns** `number` — The scalar dot product.

```lua
local d = Transform.vec.dot(1, 0, 0, 0, 1, 0)
```

## typed/builtin//modules/transform/T/vec/length {#typed-builtin-modules-transform-t-vec-length}

```lua
T.vec.length(x: number, y: number, z: number) -> number
```

Euclidean length of a vec3.

**Parameters**

- `x` `number` — Vector x.
- `y` `number` — Vector y.
- `z` `number` — Vector z.

**Returns** `number` — The length.

```lua
local len = Transform.vec.length(1, 2, 3)
```

## typed/builtin//modules/transform/T/vec/normalize {#typed-builtin-modules-transform-t-vec-normalize}

```lua
T.vec.normalize(x: number, y: number, z: number) -> (number, number, number)
```

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

**Parameters**

- `x` `number` — Vector x.
- `y` `number` — Vector y.
- `z` `number` — Vector z.

**Returns** `(number, number, number)` — Three numbers — the unit-length vec3.

```lua
local nx, ny, nz = Transform.vec.normalize(0, 5, 0)
```

## typed/builtin//modules/transform/T/vec/scale {#typed-builtin-modules-transform-t-vec-scale}

```lua
T.vec.scale(x: number, y: number, z: number, s: number) -> (number, number, number)
```

Component-wise scalar multiplication of a vec3.

**Parameters**

- `x` `number` — Vector x.
- `y` `number` — Vector y.
- `z` `number` — Vector z.
- `s` `number` — Scalar factor.

**Returns** `(number, number, number)` — Three numbers — the scaled vec3.

```lua
local x, y, z = Transform.vec.scale(1, 2, 3, 2)
```

## typed/builtin//modules/transform/T/vec/sub {#typed-builtin-modules-transform-t-vec-sub}

```lua
T.vec.sub(ax: number, ay: number, az: number, bx: number, by: number, bz: number) -> (number, number, number)
```

Component-wise vec3 subtraction (`a - b`).

**Parameters**

- `ax` `number` — First vector x.
- `ay` `number` — First vector y.
- `az` `number` — First vector z.
- `bx` `number` — Second vector x.
- `by` `number` — Second vector y.
- `bz` `number` — Second vector z.

**Returns** `(number, number, number)` — Three numbers — the difference.

```lua
local x, y, z = Transform.vec.sub(4, 5, 6, 1, 2, 3)
```

## typed/builtin//modules/transform/T/worldToLocal {#typed-builtin-modules-transform-t-worldtolocal}

```lua
T.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.

**Parameters**

- `px` `number` — Parent position x.
- `py` `number` — Parent position y.
- `pz` `number` — Parent position z.
- `pqx` `number` — Parent rotation x.
- `pqy` `number` — Parent rotation y.
- `pqz` `number` — Parent rotation z.
- `pqw` `number` — Parent rotation w.
- `wx` `number` — World x.
- `wy` `number` — World y.
- `wz` `number` — World z.

**Returns** `(number, number, number)` — Three numbers `lx, ly, lz` — the local position.

```lua
local lx, ly, lz = Transform.worldToLocal(px, py, pz, pqx, pqy, pqz, pqw, wx, wy, wz)
```

## typed/builtin//modules/tween/easing/E/list {#typed-builtin-modules-tween-easing-e-list}

```lua
E.list() -> { string }
```

List every canonical easing name (camelCase form). Useful for
pickers / UI.

## typed/builtin//modules/tween/easing/E/resolve {#typed-builtin-modules-tween-easing-e-resolve}

```lua
E.resolve(easing: string | EasingFn) -> EasingFn
```

Resolve an easing name (string) or function to an easing
function. Pass-through if `easing` is already a function. Raises
on unknown name or unsupported type.

**Parameters**

- `easing` `string | EasingFn` — Either an easing name (case-insensitive, optional `ease`
prefix), or an `EasingFn` (returned unchanged).

**Returns** `EasingFn` — The resolved `EasingFn`.

```lua
local fn = Easing.resolve("easeInOutQuad")
local fn = Easing.resolve(function(t) return t * t end)
```

## typed/builtin//modules/ui/flamegraph/M/build {#typed-builtin-modules-ui-flamegraph-m-build}

```lua
M.build(opts: BuildOpts) -> any
```

Build a flamegraph canvas widget from a folded-stack snapshot.
The snapshot shape is whatever `luau_profile.snapshot()` returns
(`{ stacks = { { stack, self_us }, ... } }`). Returns a single
`canvas` widget node ready to drop into any parent layout.

**Parameters**

- `opts` `BuildOpts` — Build options — see BuildOpts. `width`/`height` default
to 720x280; `rowHeight` defaults to 18px; `search` dims
non-matching frames; `onClick`/`onDoubleClick` are forwarded to
the canvas event protocol; `background` is the canvas fill.

**Returns** `any` — The widget node.

```lua
local view = Flame.build({ snapshot = luau_profile.snapshot() })
local view = Flame.build({ snapshot = snap, search = "physics", onClick = "flame-click" })
```

## typed/builtin//modules/ui/flamegraph/M/formatFrame {#typed-builtin-modules-ui-flamegraph-m-formatframe}

```lua
M.formatFrame(label: string) -> string
```

Expose the internal frame label extractor — useful for the
region/top-stacks tables in the same tab so they format frames
identically to the flamegraph.

**Parameters**

- `label` `string` — Raw frame label as emitted by the sampler.

**Returns** `string` — Display-friendly string.

```lua
print(Flame.formatFrame("path.luau,foo,42"))  -- "foo:42"
```

## typed/builtin//modules/ui/flamegraph/M/splitFrames {#typed-builtin-modules-ui-flamegraph-m-splitframes}

```lua
M.splitFrames(stack: string) -> { string }
```

Walk a folded stack into its component frames. Convenience
for tabs that want to render the top frame separately from the
full chain.

**Parameters**

- `stack` `string` — Folded-stack string from the sampler.

**Returns** `{ string }` — Array of frame strings, root first.

```lua
local frames = Flame.splitFrames("a;b;c")
```

## typed/builtin//modules/ui_motion_capture/M/register {#typed-builtin-modules-ui-motion-capture-m-register}

```lua
M.register()
```

Register the `ui_motion` (change magnitude) and `ui_motion_flow`
(directional flow) capture views. Idempotent — safe to call at boot and
again later; re-registering keeps each view's channel.

```lua
require("modules.ui_motion_capture").register()
```

## typed/builtin//modules/vfs_async_read/M/installInto {#typed-builtin-modules-vfs-async-read-m-installinto}

```lua
M.installInto(vfs: VfsNamespace)
```

Install the yielding `read` wrapper onto the supplied `vfs`-shaped
namespace. The prelude calls this once at boot with the engine's
`vfs` global; users shouldn't call it directly. No-op if the target
doesn't expose both `read` and `readAsync` as functions.

**Parameters**

- `vfs` `VfsNamespace` — The target namespace table. Must carry `read` and `readAsync`
function fields (the engine's `vfs` global does); otherwise the
install is a no-op.

```lua
require("modules.vfs_async_read").installInto(vfs)
```

## typed/builtin//modules/viz/viz/clear {#typed-builtin-modules-viz-viz-clear}

```lua
viz.clear(vizId: string, channel: string?)
```

Clear a specific visualization by ID (and optional channel).

**Parameters**

- `vizId` `string` — The visualization identifier.
- `channel` `string` _(optional)_ — Optional channel. Empty string means "any".

```lua
viz.clear("flash:box")
```

## typed/builtin//modules/viz/viz/clearAll {#typed-builtin-modules-viz-viz-clearall}

```lua
viz.clearAll()
```

Clear every active visualization.

```lua
viz.clearAll()
```

## typed/builtin//modules/viz/viz/create {#typed-builtin-modules-viz-viz-create}

```lua
viz.create(name: string, duration: number, updateSource: string?) -> VizContext
```

Create a managed visualization context. Returns a context
table with `:spawn(name)`, `:track(id)`, and `:done()`. Entities
created via `:spawn()` are placed in the `__viz` scene layer and
auto-despawned when the viz expires; existing entities can be
marked for auto-despawn via `:track`.

## typed/builtin//modules/viz/viz/flashOutline {#typed-builtin-modules-viz-viz-flashoutline}

```lua
viz.flashOutline(entityId: string, duration: number?, color: Color3?)
```

Flash an outline on an entity (no scale change). Good for
modification feedback.

**Parameters**

- `entityId` `string` — The target entity.
- `duration` `number` _(optional)_ — Flash length in seconds. Defaults to `0.5`.
- `color` `Color3` _(optional)_ — Outline RGB. Defaults to `{1, 0.8, 0}` (gold).

```lua
viz.flashOutline("box")
viz.flashOutline("box", 0.3, { 1, 0.2, 0.2 })
```

## typed/builtin//modules/viz/viz/flashTint {#typed-builtin-modules-viz-viz-flashtint}

```lua
viz.flashTint(entityId: string, duration: number?, color: Color3?)
```

Brief colour tint that fades. Good for property-change feedback.

**Parameters**

- `entityId` `string` — The target entity.
- `duration` `number` _(optional)_ — Tint length in seconds. Defaults to `0.3`.
- `color` `Color3` _(optional)_ — Tint RGB. Defaults to `{0.2, 1, 0.4}` (green).

```lua
viz.flashTint("box")
viz.flashTint("box", 0.2, { 1, 0.3, 0.3 })
```

## typed/builtin//modules/viz/viz/label {#typed-builtin-modules-viz-viz-label}

```lua
viz.label(entityId: string, text: string, duration: number?)
```

Spawn a 3D text label above an entity that fades after duration.
Currently a no-op pending the Luau WASM `-fwasm-exceptions` rebuild
(see #1230) — `viz.label` is purely cosmetic and was breaking the
WASM logic tick when its spawn-chain ran before vtables were
published. Keeps the surface stable so tool scripts can still call
it; behaviour returns when the engine binding is unblocked.

**Parameters**

- `entityId` `string` — The entity to label.
- `text` `string` — The label text.
- `duration` `number` _(optional)_ — How long to show in seconds. Defaults to `1.5`.

```lua
viz.label("box", "selected")
```

## typed/builtin//modules/viz/viz/lightRadius {#typed-builtin-modules-viz-viz-lightradius}

```lua
viz.lightRadius(entityId: string, radius: number, duration: number?, color: Color3?)
```

Light radius indicator — brief sphere outline showing a light's
range. Flashes the light entity itself.

**Parameters**

- `entityId` `string` — The light entity.
- `radius` `number` — Light radius (currently unused — accepted for future expansion).
- `duration` `number` _(optional)_ — How long to show in seconds. Defaults to `0.8`.
- `color` `Color3` _(optional)_ — Indicator RGB. Defaults to `{1, 0.9, 0.4}` (warm yellow).

```lua
viz.lightRadius("lamp", 8)
```

## typed/builtin//modules/viz/viz/popIn {#typed-builtin-modules-viz-viz-popin}

```lua
viz.popIn(entityId: string, duration: number?, color: Color3?)
```

Pop-in animation: entity scales from 0 to 1 with a coloured
outline pulse. Call this right after spawning an entity to give it
a smooth entrance. Uses VizTransform overlay — never touches the
entity's real Transform.

**Parameters**

- `entityId` `string` — The entity to animate.
- `duration` `number` _(optional)_ — Animation length in seconds. Defaults to `0.4`.
- `color` `Color3` _(optional)_ — Outline RGB (3-element array). Defaults to `{0.3, 0.6, 1.0}` (blue).

```lua
viz.popIn("my_entity")
viz.popIn("my_entity", 0.6, { 1, 0.8, 0 })
```

## typed/builtin//modules/viz/viz/shrinkOut {#typed-builtin-modules-viz-viz-shrinkout}

```lua
viz.shrinkOut(entityId: string, duration: number?)
```

Shrink-out animation: entity scales from 1 to 0 with a red
tint. Uses VizTransform overlay — never touches the entity's real
Transform. Call this BEFORE despawning to give a smooth exit; the
actual `entity.despawn` should be issued by the caller after this
duration.

**Parameters**

- `entityId` `string` — The target entity.
- `duration` `number` _(optional)_ — Animation length in seconds. Defaults to `0.3`.

```lua
viz.shrinkOut("box"); task.wait(0.3); entity.despawn("box")
```

## typed/builtin//modules/viz/viz/smooth {#typed-builtin-modules-viz-viz-smooth}

```lua
viz.smooth(entityId: string, duration: number?)
```

Smooth visual transition for any transform change (position,
rotation, scale). Pure visual — never touches the entity's real
Transform. Call this after making any transform change; it
automatically reads `PreviousTransform` (auto-maintained by the
engine) to compute the delta and animate the visual offset back to
identity.

**Parameters**

- `entityId` `string` — The entity to smooth.
- `duration` `number` _(optional)_ — Transition length in seconds. Defaults to `0.25`.

```lua
entity.find("box").localPosition = { 0, 5, 0 }; viz.smooth("box")
```

## typed/builtin//modules/viz/viz/spin {#typed-builtin-modules-viz-viz-spin}

```lua
viz.spin(entityId: string, opts: SpinOpts?)
```

Spin animation: entity rotates around an axis over duration
then stops. Uses VizTransform overlay — never touches the entity's
real Transform.

**Parameters**

- `entityId` `string` — The entity to spin.
- `opts` `SpinOpts` _(optional)_ — Optional spin parameters: `axis` (`"x"`, `"y"`, `"z"` —
default `"y"`), `turns` (default `1`), `duration` (default `0.6`),
`color` (outline RGB, default `{0.8, 0.6, 1.0}`).

```lua
viz.spin("box")
viz.spin("box", { axis = "x", turns = 2, duration = 1.0 })
```

## typed/builtin//modules/viz/viz/trigger {#typed-builtin-modules-viz-viz-trigger}

```lua
viz.trigger(nameOrOpts: string | TriggerOpts, source: string?, duration: number?, updateSource: string?)
```

Trigger a raw visualization. Accepts either a name + positional
args, or an opts table.

**Parameters**

- `nameOrOpts` `string | TriggerOpts` — Either a visualization name (string) or an options
table (`{ name, source, duration, update }`).
- `source` `string` _(optional)_ — Optional Luau source evaluated once at start (ignored when
`nameOrOpts` is a table).
- `duration` `number` _(optional)_ — Optional duration in seconds.
- `updateSource` `string` _(optional)_ — Optional per-frame update callback source.

```lua
viz.trigger("flash:box", "", 0.4)
viz.trigger({ name = "ring", duration = 0.5, update = src })
```

## typed/builtin//modules/world_defaults/M/offLoaded {#typed-builtin-modules-world-defaults-m-offloaded}

```lua
M.offLoaded(handle: number) -> boolean
```

Stop a callback registered with `world.onLoaded` from running.

**Parameters**

- `handle` `number` — The handle `world.onLoaded` returned.

**Returns** `boolean` — `true` when the handle matched a registered callback.

```lua
world.offLoaded(h)
```

## typed/builtin//modules/world_defaults/M/offSaved {#typed-builtin-modules-world-defaults-m-offsaved}

```lua
M.offSaved(handle: number) -> boolean
```

Stop a callback registered with `world.onSaved` from running.

**Parameters**

- `handle` `number` — The handle `world.onSaved` returned.

**Returns** `boolean` — `true` when the handle matched a registered callback.

```lua
world.offSaved(h)
```

## typed/builtin//modules/world_defaults/M/offUnloaded {#typed-builtin-modules-world-defaults-m-offunloaded}

```lua
M.offUnloaded(handle: number) -> boolean
```

Stop a callback registered with `world.onUnloaded` from running.

**Parameters**

- `handle` `number` — The handle `world.onUnloaded` returned.

**Returns** `boolean` — `true` when the handle matched a registered callback.

```lua
world.offUnloaded(h)
```

## typed/builtin//modules/world_defaults/M/onLoaded {#typed-builtin-modules-world-defaults-m-onloaded}

```lua
M.onLoaded(cb: (...any) -> ()) -> number
```

Register a callback to run after a world finishes loading.

**Parameters**

- `cb` `(...any) -> ()` — Called when the event fires, with whatever the event supplies.

**Returns** `number` — Handle for `world.offLoaded`.

```lua
local h = world.onLoaded(function() log.info("loaded") end)
```

## typed/builtin//modules/world_defaults/M/onSaved {#typed-builtin-modules-world-defaults-m-onsaved}

```lua
M.onSaved(cb: (...any) -> ()) -> number
```

Register a callback to run after a world is saved.

**Parameters**

- `cb` `(...any) -> ()` — Called when the event fires, with whatever the event supplies.

**Returns** `number` — Handle for `world.offSaved`.

```lua
local h = world.onSaved(function() log.info("saved") end)
```

## typed/builtin//modules/world_defaults/M/onUnloaded {#typed-builtin-modules-world-defaults-m-onunloaded}

```lua
M.onUnloaded(cb: (...any) -> ()) -> number
```

Register a callback to run after a world is unloaded.

**Parameters**

- `cb` `(...any) -> ()` — Called when the event fires, with whatever the event supplies.

**Returns** `number` — Handle for `world.offUnloaded`.

```lua
local h = world.onUnloaded(function() log.info("unloaded") end)
```

## typed/builtin//modules/world_sync/M/installInto {#typed-builtin-modules-world-sync-m-installinto}

```lua
M.installInto(world: WorldNamespace)
```

Graft `syncStatus` / `resolveConflict` onto the supplied `world`
namespace. The prelude calls this once at boot.

**Parameters**

- `world` `WorldNamespace` — The target namespace — typically the engine's `world` global.

```lua
require("modules.world_sync").installInto(world)
```

## typed/builtin//modules/world_sync/world/resolveConflict {#typed-builtin-modules-world-sync-world-resolveconflict}

```lua
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.

**Parameters**

- `path` `string` — Canonical `/source` path of the conflicted record.
- `mode` `string` — One of merge | apply | take-local | take-backend | discard.
- `content` `string` _(optional)_ — Finalized bytes for `apply` mode.

**Returns** `ResolveResult`

```lua
world.resolveConflict("/zero/source/foo.luau", "take-local")
local r = world.resolveConflict(p, "merge"); if r.clean then world.resolveConflict(p, "apply", r.merged) end
```

## typed/builtin//modules/world_sync/world/syncStatus {#typed-builtin-modules-world-sync-world-syncstatus}

```lua
world.syncStatus() -> SyncStatus
```

Read the durable-sync status: `{ subscribed, content_synced,
progress, pending_writes, unsaved_writes, uploads_abandoned,
conflicts, binding }`. `conflicts` maps each conflicted `/source`
path to `{ base_sha, local_sha, backend_sha, isBinary }`.
`unsaved_writes` lists the `/source` paths this session wrote that
the server does not hold, and `uploads_abandoned` counts the uploads
the queue stopped carrying — read those two to tell a queue working
through a backlog from one that gave content up, which
`pending_writes` alone reads the same for. `binding` names which
world holds `/source` — `bound`, `unbound`, `binding`,
`session_only`, or `unclassified` before the boot has decided — and,
when an authorization attempt is on record,
which attempt is running and what the last one answered. Read
`binding` to tell a world that is still coming from one that was
never asked for: `subscribed` answers `false` for both. Synchronous.

**Returns** `SyncStatus`

```lua
local s = world.syncStatus(); print(s.pending_writes)
local s = world.syncStatus(); for _, p in ipairs(s.unsaved_writes) do print(p) end
local s = world.syncStatus(); if s.binding.awaiting_world then print(s.binding.state, s.binding.attempt) end
```

## typed/builtin//modules/world_vcs/M/__commitOnceWith {#typed-builtin-modules-world-vcs-m-commitoncewith}

```lua
M.__commitOnceWith(held: () -> { string }, rebase: ({ string }) -> (), commit: () -> (boolean, string)) -> (boolean, string)
```

Materialise a staging area, bringing it onto the branch head there is
now if a commit landed under it. An area a caller keeps across another
caller's commit was opened against the head of the moment it was opened,
and the backend refuses to build a commit on a head that has moved.
Rebasing is dropping that area and opening one against the current head,
then staging the paths the old one held — so the commit carries the
caller's own paths and no one else's. Re-staging reads each path's
content as the working tree holds it now, which is what a caller asking
to commit them is asking to freeze. Any other refusal travels back as it
came, and the rebase is attempted once: a second moved head is another
caller committing again, which the caller hears about rather than the
call looping on.

**Parameters**

- `held` `() -> { string }` — Reads the paths the staging area currently holds.
- `rebase` `({ string }) -> ()` — Drops the area and stages `held`'s paths onto a fresh one.
- `commit` `() -> (boolean, string)` — Materialises the area, answering the backend's `(ok, message)`.

**Returns** `(boolean, string)` — The `(ok, message)` pair the surviving attempt produced.

```lua
worldVcs.__commitOnceWith(held, rebase, function() return true, "01J" end)
```

## typed/builtin//modules/world_vcs/M/__hasConflictMarkers {#typed-builtin-modules-world-vcs-m-hasconflictmarkers}

```lua
M.__hasConflictMarkers(text: string) -> boolean
```

True if `text` contains a git-style conflict-marker line
(`<<<<<<<`, `=======`, or `>>>>>>>`) anchored at the start of a
line. The gate's resolution validator: a conflicted row can only
clear once its file has no marker lines left. Anchoring at line
start (not a bare substring search) avoids false-flagging prose
that merely mentions the marker text mid-line.

**Parameters**

- `text` `string` — The file content to scan.

**Returns** `boolean` — `true` when a marker line is present.

```lua
worldVcs.__hasConflictMarkers("<<<<<<< ours\nx\n") --> true
```

## typed/builtin//modules/world_vcs/M/__installVerdict {#typed-builtin-modules-world-vcs-m-installverdict}

```lua
M.__installVerdict(ok: boolean, payload: string) -> AssetInstallableReport
```

Read an installability verdict out of one closure fetch. Pure —
it decides from the fetch outcome and the response body alone, so
the classification is exercisable without a live backend.
`world.assetInstallable` is this function over a real fetch.

**Parameters**

- `ok` `boolean` — Whether the closure procedure returned successfully.
- `payload` `string` — The response body when `ok`, the error message otherwise.

**Returns** `AssetInstallableReport` — An `AssetInstallableReport` with `guid` left empty for the caller to fill: `installable` (would installing this guid alone land content), `verdict`, a one-line `detail`, and the closure's shape as `nodes` / `tree_children` / `deps`.

```lua
worldVcs.__installVerdict(false, "HTTP 404: not found").verdict --> "unpublished"
```

## typed/builtin//modules/world_vcs/M/__reconcileDecision {#typed-builtin-modules-world-vcs-m-reconciledecision}

```lua
M.__reconcileDecision(base: string, ours: string, theirs: string) -> string
```

Decide the three-way reconcile action for one pulled-asset row
from its three content checksums (base = last-known origin checksum,
ours = current local checksum, theirs = latest upstream checksum).
Pure — no I/O, no VCS calls. `world.pullAsset` drives its reconcile
loop off this decision per row.

**Parameters**

- `base` `string` — The origin checksum recorded the last time this row was
pulled or advanced.
- `ours` `string` — This world's current local checksum for the row.
- `theirs` `string` — The latest upstream checksum.

**Returns** `string` — One of `"fast_forward"` (untouched locally — take theirs), `"noop"` (upstream unchanged — nothing to do), `"converged"` (both sides already match — advance provenance only), or `"merge"` (all three differ — three-way merge required).

```lua
worldVcs.__reconcileDecision("A", "A", "B") --> "fast_forward"
```

## typed/builtin//modules/world_vcs/M/__refreshAndStageScope {#typed-builtin-modules-world-vcs-m-refreshandstagescope}

```lua
M.__refreshAndStageScope(scope: { string }, refresh: ({ string }) -> ({ string }, { string }), drain: () -> (), liveStatus: () -> LiveStageStatus, stageRow: (string) -> (), holdBack: (string) -> ())
```

Re-derive the dependency tables of the rows a commit is about to
freeze, and re-stage the ones whose staging carries just that delta.
`scope` is the whole of what the commit re-derives — the paths the
calling staging area holds, plus the members of the scenes the commit
baked — so a row outside it is neither re-derived nor staged, whoever
else in the world is editing it and however far its own table has
drifted.

Of the candidates `refresh` reports, a row is staged when staging it
carries JUST the refreshed table: it is HEAD-clean in the shared
working tree, or the calling area already holds it. A row with an
unstaged byte edit whose table also moved goes to `holdBack` instead,
so a commit stays `git add` semantics rather than `git commit -a`.
A row the live ignore set matches is skipped — an ignored source
publishes nothing, so its table gates nothing.

**Parameters**

- `scope` `{ string }` — The rows this commit freezes, engine-canonical.
- `refresh` `({ string }) -> ({ string }, { string })` — Re-derives the tables of the paths it is given, answering the
candidates it re-derived and the subset whose table moved. Its answer is
narrowed to `scope` before any of it is staged.
- `drain` `() -> ()` — Waits for the re-derived rows to reach the manifest.
- `liveStatus` `() -> LiveStageStatus` — Reads the working tree and the calling area, once, after
the drain.
- `stageRow` `(string) -> ()` — Stages one row into the calling area.
- `holdBack` `(string) -> ()` — Reports a row whose table moved and whose byte edit is the
author's to stage.

```lua
worldVcs.__refreshAndStageScope(staged, refresh, drain, status, add, warn)
```

## typed/builtin//modules/world_vcs/M/__releaseClaimedByOthers {#typed-builtin-modules-world-vcs-m-releaseclaimedbyothers}

```lua
M.__releaseClaimedByOthers(claims: { any }, staged: { string }, unstage: (string) -> (), held: { [string]: boolean }?) -> { string }
```

Release the paths a bulk stage swept out of another caller's hands.
The working tree is one per `(world, branch)` and staging areas are not,
so the dirty set a bulk stage reads spans every caller authoring in the
world. A path another area holds is that caller's claim on it: selected
for a commit of its own and not yet committed. This unstages each such
path from the area the bulk stage filled and answers with the ones it
let go, so the caller learns what its stage does not carry rather than
discovering it in someone else's file.
A path the calling area held before the sweep is that caller's own,
whoever else holds it: naming a path is how a claim is handed over, so
the sweep leaves a path this caller already took where the caller put
it.

**Parameters**

- `claims` `{ any }` — The rows other staging areas hold, `{ path, stage_name, ... }`.
- `staged` `{ string }` — The paths the bulk stage put into the calling area.
- `unstage` `(string) -> ()` — Removes one path from the calling area.
- `held` `{ [string]: boolean }` _(optional)_ — The paths the calling area held before the sweep, as a set.

**Returns** `{ string }` — The released paths, in the order `staged` listed them.

```lua
worldVcs.__releaseClaimedByOthers(claims, staged, unstage, held)
```

## typed/builtin//modules/world_vcs/M/__rowsUnderPrefix {#typed-builtin-modules-world-vcs-m-rowsunderprefix}

```lua
M.__rowsUnderPrefix(dir: string, paths: { string }) -> { string }
```

The rows of `paths` that lie beneath the directory `dir`. `dir` is
taken in either the `/source/…` shorthand or the engine-canonical
`/zero/source/…` form and matched as a whole path segment, so a
directory selects its own contents and never a sibling whose name it is
a prefix of. This is the set a directory stands for when it is staged: a
directory outside any asset carries no manifest row of its own, and the
rows to stage are the ones under it.

**Parameters**

- `dir` `string` — The directory whose contents to select.
- `paths` `{ string }` — The candidate row paths, engine-canonical.

**Returns** `{ string }` — Those of `paths` under `dir`, in the order given.

```lua
worldVcs.__rowsUnderPrefix("/source/hud", { "/zero/source/hud/a.luau" })
```

## typed/builtin//modules/world_vcs/M/__stageBaseMoved {#typed-builtin-modules-world-vcs-m-stagebasemoved}

```lua
M.__stageBaseMoved(msg: string) -> boolean
```

True when the backend refused to build a commit on a stage whose
branch has moved: the area was opened against the commit that was the
branch head then, and another caller's commit is the head now.

**Parameters**

- `msg` `string` — The backend's refusal text.

**Returns** `boolean` — Whether that text is the moved-head answer.

```lua
worldVcs.__stageBaseMoved("ParentCommitMoved: branch \"main\" HEAD is ...") --> true
```

## typed/builtin//modules/world_vcs/M/__stageNameFrom {#typed-builtin-modules-world-vcs-m-stagenamefrom}

```lua
M.__stageNameFrom(opts: any?, verb: string) -> string
```

The staging area a staging call acts on. `opts.stage` names it, and a
call that names none acts on the shared default area. Two callers that
name different areas stage into different rows, so each commits the paths
it staged and leaves the other's staged.

**Parameters**

- `opts` `any` _(optional)_ — The options table the caller passed, or nil.
- `verb` `string` — The calling API's name, quoted in a refusal.

**Returns** `string` — The name of the staging area this call acts on.

```lua
worldVcs.__stageNameFrom({ stage = "fauna" }, "world.add") --> "fauna"
```

## typed/builtin//modules/world_vcs/M/__stageOnceWith {#typed-builtin-modules-world-vcs-m-stageoncewith}

```lua
M.__stageOnceWith(open: () -> string, stageInto: (string) -> (boolean, string)) -> (boolean, string)
```

Run one staging step against the implicit stage, resolving the handle
through `open` immediately before the step so the row cannot retire while
a barrier or a gate runs ahead of it. `stageInto` returns the
`(ok, message)` pair the backend answered with and must carry out the
WHOLE of one step: a retired row takes its entries with it, so when the
backend reports the row is gone a fresh row is opened and `stageInto` runs
once more, landing every path the step names in the stage that exists now
rather than only the ones after the failure. The second run resolves a
handle rather than repeating a caller's operation — staging a path is
idempotent at `(stage, manifest_row)`, so it reaches exactly the state the
first run was asked for. Any other refusal is returned as it came.

**Parameters**

- `open` `() -> string` — Resolves the implicit stage, returning its row id.
- `stageInto` `(string) -> (boolean, string)` — Carries out one whole staging step against a row id.

**Returns** `(boolean, string)` — The `(ok, message)` pair the surviving run produced.

```lua
worldVcs.__stageOnceWith(openStage, function(id) return true, "" end)
```

## typed/builtin//modules/world_vcs/M/__stageRowRetired {#typed-builtin-modules-world-vcs-m-stagerowretired}

```lua
M.__stageRowRetired(msg: string) -> boolean
```

True when the backend's reason for refusing a stage operation is that
the row the handle names is gone. A stage row is deleted the moment a
commit materializes it, and a staging area is one row per
`(world, branch, account, name)`, so a handle onto an area another caller
is also acting on names a row that a commit of theirs has since retired.

**Parameters**

- `msg` `string` — The backend's refusal text.

**Returns** `boolean` — Whether that text is the retired-row answer.

```lua
worldVcs.__stageRowRetired("stage_add: stage 41 does not exist") --> true
```

## typed/builtin//modules/world_vcs/M/__stageableSources {#typed-builtin-modules-world-vcs-m-stageablesources}

```lua
M.__stageableSources(paths: { string }) -> { string }
```

The rows of `paths` a commit can stage: the candidates narrowed to
the paths the world can hold a manifest row for. A save-excluded path is
local to this machine and has no row anywhere, so `stage_add` names it
and refuses — which, from inside a commit, aborts over content the
author never staged and cannot unstage.

**Parameters**

- `paths` `{ string }` — The candidate paths, engine-canonical.

**Returns** `{ string }` — Those of `paths` the world can hold a row for, in the order given.

```lua
worldVcs.__stageableSources({ "/zero/source/a.luau" })
```

## typed/builtin//modules/world_vcs/M/installInto {#typed-builtin-modules-world-vcs-m-installinto}

```lua
M.installInto(world: WorldNamespace)
```

**Parameters**

- `world` `WorldNamespace`

## typed/builtin//modules/world_vcs/world/add {#typed-builtin-modules-world-vcs-world-add}

```lua
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.
`{ stage = "<name>" }` stages into one of the caller's own staging
areas instead of the shared default one, so a commit naming that area
freezes these paths and leaves every other caller's staged.

**Parameters**

- `path` `string` — The path to stage. Must be a non-empty string.
- `opts` `AddOpts` _(optional)_ — Optional `{ force: boolean?, stage: string? }`. Defaults to
`{ force = false }` on the default staging area.

```lua
world.add("/source/foo.luau")
world.add("/source/scene_dirty/entities/42.json", { force = true })
world.add("/source/fauna.module", { stage = "fauna" })
```

## typed/builtin//modules/world_vcs/world/add_all {#typed-builtin-modules-world-vcs-world-add-all}

```lua
world.add_all(opts: StageOpts?) -> { string }
```

Stage the dirty manifest rows this caller can claim, 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.
A path another staging area holds is held back as well: the
working tree is one per branch and staging areas are not, so a
path some other caller has already selected for a commit of its
own belongs to that caller until it commits or hands it over.
`world.add(path)` names a path deliberately and takes it either
way, which is how a claim is handed over — and a path this area
already holds stays staged here, whoever else holds it too.

**Parameters**

- `opts` `StageOpts` _(optional)_ — Optional `{ stage: string? }` naming the staging area to
stage into. Omitted, the call stages into the shared default area.

**Returns** `{ string }` — The paths that were held back — those another staging area holds, then the conflicted ones. Empty when none were.

```lua
world.add_all()
world.add_all({ stage = "fauna" })
```

## typed/builtin//modules/world_vcs/world/affirm {#typed-builtin-modules-world-vcs-world-affirm}

```lua
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.

**Parameters**

- `token` `string` — The affirmation token.

```lua
world.affirm("ABC-DEF-GHI")
```

## typed/builtin//modules/world_vcs/world/assetInstallable {#typed-builtin-modules-world-vcs-world-assetinstallable}

```lua
world.assetInstallable(opts: AssetInstallableOpts) -> AssetInstallableReport
```

Report whether one published asset can be installed on its own,
without raising. `world.previewInstall` plans a real install and
raises when the closure will not resolve; this answers the prior
question — does this guid name something ZeroMind will hand over by
itself — as a verdict a caller can branch on. Content that ships
inside a larger library (a module inside a package, a material
inside a system) carries its own published identity, so the answer
is per asset rather than per library. Reads only.

**Parameters**

- `opts` `AssetInstallableOpts` — `{ guid }` names the asset; `ref` pins a commit-id instead
of the latest.

**Returns** `AssetInstallableReport` — An `AssetInstallableReport` — `installable`, a `verdict`, a one-line `detail`, and the closure's `nodes` / `tree_children` / `deps` shape when one resolved.

```lua
world.assetInstallable({ guid = asset.guid("@builtin::materials.neon") })
```

## typed/builtin//modules/world_vcs/world/awaitOutgoingSync {#typed-builtin-modules-world-vcs-world-awaitoutgoingsync}

```lua
world.awaitOutgoingSync()
```

Wait until every `/source` write this session made has reached
the branch it was written against. Raises naming the paths that did
not land. `add` / `commit` / `push` / `checkout` / `merge` / `pull`
already wait on their own; call this before rebinding after a burst
of writes, which `world.checkout` and `world.swap` refuse over.

**Returns** Nothing. Raises when a write did not land.

```lua
world.awaitOutgoingSync() ; world.checkout("main")
```

## typed/builtin//modules/world_vcs/world/branches {#typed-builtin-modules-world-vcs-world-branches}

```lua
world.branches() -> { { branch: string, commit_id: string, current: boolean } }
```

Every branch this world has, with the commit each one's head
names and which one this session is on — `git branch --list`. Sorted
by name. A branch exists for everyone in the world; which one you are
on is yours alone, so `current` is true for at most one row here and
says nothing about where anybody else is.

**Returns** `{ { branch: string, commit_id: string, current: boolean } }` — Array of `{ branch, commit_id, current }`.

```lua
for _, b in ipairs(world.branches()) do print(b.branch, b.commit_id) end
```

## typed/builtin//modules/world_vcs/world/checkUpdates {#typed-builtin-modules-world-vcs-world-checkupdates}

```lua
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`.

**Returns** `{ UpdateReport }` — An array of `UpdateReport`, one per re-resolved origin asset whose closure produced at least one changed entry. Empty when every pulled row is already current. A root whose closure can't be re-resolved (e.g. the origin world is unreachable) is silently skipped rather than aborting the whole scan.

```lua
local reports = world.checkUpdates()
```

## typed/builtin//modules/world_vcs/world/checkout {#typed-builtin-modules-world-vcs-world-checkout}

```lua
world.checkout(branch: string) -> string
```

Switch this session to another branch — `git checkout <branch>`.
The branch must already exist (create one with `world.createBranch`).
The tree is replaced by the branch's own content. Which branch this
session is on is this session's alone; the branch itself is shared,
so others may be on the one you move onto.
Uncommitted work is not at risk: it already has its row on the
branch it was written against and is in the tree again when you
check that branch out.
Returns only once the branch's content has landed, so `world.head`,
`world.log`, `world.commit` and the VFS all target the new branch
immediately afterwards.

**Parameters**

- `branch` `string` — The branch to switch to.

**Returns** `string` — The branch now checked out.

```lua
world.checkout("feature")
```

## typed/builtin//modules/world_vcs/world/commit {#typed-builtin-modules-world-vcs-world-commit}

```lua
world.commit(message: string, opts: CommitOpts?) -> string
```

Open-or-resume a staging area, set the message, and materialise
the commit. Commits ONLY what's already staged via `world.add` /
`world.add_all` — git semantics, not `git commit -a`. The reducer
auto-deletes the stage row on success so a subsequent
`world.commit` opens a fresh one.

`{ stage = "<name>" }` materialises one of the caller's own staging
areas, so the commit carries the paths staged under that name and
leaves every other caller's staged. When a commit from another
caller has landed since the area was opened, this brings the area
onto the branch head there is now and commits it there.

Pre-flight `.zmignore` refs gate: every staged source's
aggregated deps (via `asset.deps`, which recurses composite
asset folders) are checked against the live ignore set. If
any dep target's path is currently ignored AND the dep target
is not itself in the stage, the commit is refused. This
mirrors the closure invariant — a commit whose deps can't
resolve cleanly shouldn't land. Force-staging the dep
alongside (`world.add(dep, { force = true })`) makes the
ignored dep satisfy the gate.

**Parameters**

- `message` `string` — The commit message.
- `opts` `CommitOpts` _(optional)_ — Optional `{ stage: string? }` naming the staging area to
materialise. Omitted, the commit materialises the shared default
area.

**Returns** `string` — The newly-allocated commit id (ULID string).

```lua
local id = world.commit("feat: ship widget")
local id = world.commit("fauna: the swallow colony", { stage = "fauna" })
```

## typed/builtin//modules/world_vcs/world/conflicts {#typed-builtin-modules-world-vcs-world-conflicts}

```lua
world.conflicts() -> { ConflictEntry }
```

List every locally-pulled row currently flagged conflicted —
the findable surface `world.pullAsset` leaves behind on an
unresolved merge. Read-only.

**Returns** `{ ConflictEntry }` — An array of `ConflictEntry`, one per conflicted row. Empty when nothing is conflicted.

```lua
local list = world.conflicts()
```

## typed/builtin//modules/world_vcs/world/contentRequirements {#typed-builtin-modules-world-vcs-world-contentrequirements}

```lua
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 `world.publishBlockers` reports it as the `content`
class beside the other two. Empty list = every checked asset meets
its type's contract.

**Parameters**

- `scope` `{ string }` _(optional)_ — Asset paths to restrict the check to — pass a status read's
dirty + staged paths to check only content that would actually
publish (a per-file path matches its containing asset; each path
resolves directly, with no world enumeration). Omit for the
full-world walk the push gate performs.

**Returns** `{ { asset: string, typeName: string, detail: string } }` — Array of `{ asset, typeName, detail }` requirement rows.

```lua
for _, r in ipairs(world.contentRequirements()) do print(r.asset, r.detail) end
```

## typed/builtin//modules/world_vcs/world/contribute {#typed-builtin-modules-world-vcs-world-contribute}

```lua
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.

**Parameters**

- `opts` `ContributeOpts` _(optional)_ — Optional `ContributeOpts` — `targets` (origin world guids;
default all ahead), `merge` (default true), `title`,
`description`, `dryRun`.

**Returns** `{ ContributeOutcome }` — Array of `ContributeOutcome`, one per targeted origin.

```lua
local r = world.contribute({})
```

## typed/builtin//modules/world_vcs/world/createBranch {#typed-builtin-modules-world-vcs-world-createbranch}

```lua
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 onto it with
`world.checkout("<branch>")` (`git checkout`).

**Parameters**

- `name` `string` — The new branch name.
- `fromCommit` `string` _(optional)_ — Commit id to start at. Defaults to `world.head()`.

```lua
world.createBranch("feature")
```

## typed/builtin//modules/world_vcs/world/deleteBranch {#typed-builtin-modules-world-vcs-world-deletebranch}

```lua
world.deleteBranch(branch: string)
```

Delete a branch — `git branch -D <name>`. Drops the branch and
the working tree it owns; its commits are left alone, since deleting
a branch is dropping the name and the tree under it, not rewriting
history. Uncommitted work on that branch goes with it and is NOT
recoverable from trash, so the call refuses the first time and
returns the affirmation needed to go through with it — affirm with
`world.affirm(<token>)`. Refuses the branch this session is on
(check out another first) and the world's last branch.

**Parameters**

- `branch` `string` — The branch to delete.

```lua
world.deleteBranch("feature")
```

## typed/builtin//modules/world_vcs/world/diff {#typed-builtin-modules-world-vcs-world-diff}

```lua
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. `--stage=<name>` reads one of the
caller's own staging areas in place of the shared default one.

**Parameters**

- `...` `string` — Variadic string args: flags, commit ids, `--`, path filters.

**Returns** `any` — Array of `DiffFile` tables (or string-list for `--name-only`).

```lua
local files = world.diff()
local files = world.diff("--staged")
local files = world.diff("abc", "def")
local names = world.diff("--name-only")
local files = world.diff("--staged", "--stage=fauna")
```

## typed/builtin//modules/world_vcs/world/discard {#typed-builtin-modules-world-vcs-world-discard}

```lua
world.discard(opts: StageOpts?)
```

Drop a staging area without committing. Live manifest dirty flags
are preserved so the user can re-stage later. No-op if the area
doesn't exist.

**Parameters**

- `opts` `StageOpts` _(optional)_ — Optional `{ stage: string? }` naming the staging area to
drop. Omitted, the call drops the shared default area.

```lua
world.discard()
world.discard({ stage = "fauna" })
```

## typed/builtin//modules/world_vcs/world/discardFile {#typed-builtin-modules-world-vcs-world-discardfile}

```lua
world.discardFile(path: string)
```

Discard one file's unstaged working edits, taking its content
back to what it was staged or committed as — the
`git restore <path>` shape. The stage is the baseline when the
path is staged, the last commit when it is not, and where it is
neither there is nothing to come back to, so the path goes away.
Staging is left exactly as it was; `world.unstage` is the verb
that changes it. One shot: a path that reverts to a committed
version snapshots the discarded bytes to trash first, so that
case is recoverable via `world.restore(<handle>)`. Errors when
the path is not dirty (nothing to discard).

**Parameters**

- `path` `string` — The VFS path whose unstaged edits to discard.

```lua
world.discardFile("/source/foo.luau")
```

## typed/builtin//modules/world_vcs/world/fetch {#typed-builtin-modules-world-vcs-world-fetch}

```lua
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()`.

**Parameters**

- `branch` `string` _(optional)_ — Remote branch to fetch. Defaults to the session branch.

**Returns** `FetchResult` — A `FetchResult` table.

```lua
local f = world.fetch()
```

## typed/builtin//modules/world_vcs/world/forkLive {#typed-builtin-modules-world-vcs-world-forklive}

```lua
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.

**Parameters**

- `opts` `{ source: string, sourceBranch: string?, maxBatches: number? }` — `{ source, sourceBranch?, maxBatches? }` — `source` is the
source world GUID; branches default to `"main"`; `maxBatches`
caps the batch loop (default 60 ⇒ up to ~120k entries).

**Returns** `number` — The number of pulled (dirty) rows now staged-pending on the fork.

```lua
world.forkLive({ source = "e89aa92e-4c1f-460e-acd8-73859dd3a346" })
```

## typed/builtin//modules/world_vcs/world/forkStatus {#typed-builtin-modules-world-vcs-world-forkstatus}

```lua
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`.

**Returns** `{ ForkStatus }` — Array of `ForkStatus` partitions.

```lua
for _, f in ipairs(world.forkStatus()) do print(f.origin_world, #f.entries) end
```

## typed/builtin//modules/world_vcs/world/head {#typed-builtin-modules-world-vcs-world-head}

```lua
world.head() -> string?
```

Return the current branch HEAD commit id, or nil if the
branch has no commits yet.

**Returns** `string?` — The commit id string, or nil.

```lua
local id = world.head()
```

## typed/builtin//modules/world_vcs/world/installAsset {#typed-builtin-modules-world-vcs-world-installasset}

```lua
world.installAsset(opts: InstallAssetOpts) -> InstallAssetResult
```

Install a published asset into this world, pulling the asset and
every dependency it closes over and writing them into the source tree.
Reports what it wrote so a caller can tell a fresh install from a no-op.

**Parameters**

- `opts` `InstallAssetOpts` — `{ guid }` names the root asset to install; `ref` pins a specific
commit-id instead of the latest.

**Returns** `InstallAssetResult` — `{ assets_written, blobs_downloaded, root_guid, root_path, root_version, deps }`.

```lua
local r = world.installAsset({ guid = assetGuid })
```

## typed/builtin//modules/world_vcs/world/installLibrary {#typed-builtin-modules-world-vcs-world-installlibrary}

```lua
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.

**Parameters**

- `opts` `InstallLibraryOpts` — See `InstallLibraryOpts`. `opts.world` is the upstream
world's guid (required). `opts.commit` is the upstream
commit_id to pin (optional; resolves `opts.ref` or `main` if
omitted). `opts.as` is the local library name (defaults to
the upstream world's slug). `opts.ref` is the human-meaningful
ref recorded in the marker.

**Returns** `InstallLibraryResult` summarising the install.

```lua
world.installLibrary({ world = "guid", as = "combat" })
```

## typed/builtin//modules/world_vcs/world/installedAssets {#typed-builtin-modules-world-vcs-world-installedassets}

```lua
world.installedAssets() -> { InstalledAsset }
```

Every asset this world carries from ZeroMind, keyed by the
published guid it was pulled from. The read that answers "what is
actually in this world" by identity rather than by path — an
installed asset's local name can be chosen by the installer, so a
path is not the thing to check a pull against.

**Returns** `{ InstalledAsset }` — An array of `InstalledAsset` sorted by local path, one per pulled row carrying a published guid.

```lua
for _, a in ipairs(world.installedAssets()) do print(a.asset_guid, a.path) end
```

## typed/builtin//modules/world_vcs/world/list {#typed-builtin-modules-world-vcs-world-list}

```lua
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.

## typed/builtin//modules/world_vcs/world/log {#typed-builtin-modules-world-vcs-world-log}

```lua
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.

**Parameters**

- `opts` `LogOpts` _(optional)_ — Optional. `opts.limit` caps the number of commits
(default 50, 0 = all). `opts.path` scopes the log to one file.

**Returns** `{ CommitRow }` — Array of `CommitRow` tables.

```lua
local commits = world.log({ limit = 20 })
local touched = world.log({ path = "/source/foo.luau" })
```

## typed/builtin//modules/world_vcs/world/merge {#typed-builtin-modules-world-vcs-world-merge}

```lua
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.

**Parameters**

- `sourceBranch` `string` — The branch to merge in.

**Returns** `MergeResult` — A `MergeResult` — `status` is `clean` (with `commit`), `conflicts` (with `conflicts`), or `up_to_date`.

```lua
local r = world.merge("feature")
```

## typed/builtin//modules/world_vcs/world/mergeAbort {#typed-builtin-modules-world-vcs-world-mergeabort}

```lua
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.

```lua
world.mergeAbort()
```

## typed/builtin//modules/world_vcs/world/prConflicts {#typed-builtin-modules-world-vcs-world-prconflicts}

```lua
world.prConflicts(worldGuid: string?, number: number) -> any
```

Read a pull request's conflicts — what stands between it and a
merge. Returns the mergeability verdict, the merge base, both
heads, and one entry per conflicting path. A conflicting TEXT path
carries `marked_text`: the same `<<<<<<<` / `=======` / `>>>>>>>`
rendering a merge leaves in the working tree, with the source and
target sides laid against their common ancestor. Resolve a path by
writing the settled bytes back to it and committing on the source
branch; the pull request re-analyses on the next read. A binary
path carries the two sides' hashes and no text — pick a side.
A mergeable pull request returns an empty conflict list.

**Parameters**

- `worldGuid` `string` _(optional)_ — The world the pull request lives in. Defaults to the
bound world.
- `number` `number` — The pull request number.

**Returns** `any` — Decoded ZeroMind conflicts response.

```lua
local c = world.prConflicts(nil, 3)
for _, m in ipairs(world.prConflicts(originGuid, 3).markers) do print(m.path, m.marked_text) end
```

## typed/builtin//modules/world_vcs/world/prList {#typed-builtin-modules-world-vcs-world-prlist}

```lua
world.prList(worldGuid: string?, number: number?) -> any
```

**Parameters**

- `worldGuid` `string` _(optional)_
- `number` `number` _(optional)_

**Returns** `any`

## typed/builtin//modules/world_vcs/world/prMerge {#typed-builtin-modules-world-vcs-world-prmerge}

```lua
world.prMerge(worldGuid: string, number: number, strategy: string?) -> any
```

Merge a pull request — the agent-side merge button.

**Parameters**

- `worldGuid` `string` — The world the pull request lives in.
- `number` `number` — The pull request number.
- `strategy` `string` _(optional)_ — `merge` (default), `squash`, or `fast_forward`.

**Returns** `any` — Decoded ZeroMind merge response.

```lua
world.prMerge(originGuid, 3)
```

## typed/builtin//modules/world_vcs/world/prOpen {#typed-builtin-modules-world-vcs-world-propen}

```lua
world.prOpen(opts: PrOpenOpts) -> any
```

List a world's pull requests, or fetch one.
Open a pull request — `gh pr create`. Proposes the work on one
`(world, branch)` pair to another. Defaults make the common cases one
argument: from a fork, the target is the world it was forked from, so
`world.prOpen({ title = "..." })` proposes your work upstream. In an
ordinary world the target is the same world, so you get a
branch → `main` pull request.
The PR lives in — and is numbered by — the world it targets, exactly
as a forge numbers pull requests on the upstream repository. That is
also where `world.prList` finds it.

**Parameters**

- `opts` `PrOpenOpts` — `title` (required), plus `description`, `sourceWorld`,
`sourceBranch`, `targetWorld`, `targetBranch` to address any leg
explicitly.

**Returns** `any` — Decoded ZeroMind response. The decoded ZeroMind pull request.

```lua
local prs = world.prList()
world.prOpen({ title = "fix the door hinge" })
world.prOpen({ title = "port the fix", targetWorld = otherGuid })
```

## typed/builtin//modules/world_vcs/world/prView {#typed-builtin-modules-world-vcs-world-prview}

```lua
world.prView(worldGuid: string?, number: number) -> any
```

Read one pull request in full — `gh pr view`. Returns the record
plus a LIVE re-analysis against the current branch heads: `mergeability`
(`clean` / `conflicts` / `fast_forwardable` / `up_to_date` /
`unrelated`), `conflict_count`, and `diff` — every path the request
adds, modifies or deletes with its checksums. Read this before merging:
it is what tells you WHAT the request changes.

**Parameters**

- `worldGuid` `string` _(optional)_ — The world the pull request lives in (its target world).
Defaults to the session world.
- `number` `number` — The pull request number.

**Returns** `any` — The decoded pull request view.

```lua
world.prView(nil, 1)
```

## typed/builtin//modules/world_vcs/world/previewInstall {#typed-builtin-modules-world-vcs-world-previewinstall}

```lua
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.

**Parameters**

- `opts` `InstallAssetOpts` — `{ guid, at?, ref? }` — same shape as installAsset.

**Returns** `PreviewResult` — nodes + totals + a truncated flag.

```lua
world.previewInstall({ guid = "..." })
```

## typed/builtin//modules/world_vcs/world/publishBlockers {#typed-builtin-modules-world-vcs-world-publishblockers}

```lua
world.publishBlockers() -> { PublishBlockerClass }
```

List every reason `world.push` would refuse to publish this
world, as one entry per blocker class: script errors in user
content, assets that don't meet their type's content requirements,
and asset references that can't be statically pinned. Each class
carries the same `title` the refusal prints, one `items` entry per
offending subject (an asset identity, or a `<path>:<line>` site),
and the single `remedy` covering that class. This is the account
`world.push` composes its refusal from, so it names the same
blockers with no push attempted — and in full, where a refusal
bounds how many of a class it prints. Empty list = the world
publishes. `zm status` prints this list.

**Returns** `{ PublishBlockerClass }` — Array of `PublishBlockerClass` entries, empty when nothing blocks.

```lua
for _, c in ipairs(world.publishBlockers()) do
for _, i in ipairs(c.items) do print(c.kind, i.subject, i.detail) end
end
```

## typed/builtin//modules/world_vcs/world/pull {#typed-builtin-modules-world-vcs-world-pull}

```lua
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.

**Parameters**

- `branch` `string` _(optional)_ — Remote branch to pull. Defaults to the session branch.

**Returns** `PullResult` — A `PullResult` table.

```lua
local r = world.pull()
```

## typed/builtin//modules/world_vcs/world/pullAsset {#typed-builtin-modules-world-vcs-world-pullasset}

```lua
world.pullAsset(opts: PullAssetOpts?) -> PullAssetResult
```

Pull upstream changes into a previously-installed asset,
three-way reconciling each entry against local edits. Re-resolves
the root's transitive closure at `opts.ref` (default latest),
then for every entry decides `fast_forward` / `noop` / `converged`
/ `merge` from `(row.origin_checksum, localChecksum,
entry.checksum)` (`M.__reconcileDecision`):

- `noop` — upstream hasn't moved; skipped.
- `fast_forward` / `converged` — the entry's latest text is
written to the local path and the row's origin pointer
advances. Binary and composite entries can't be content-synced
through this call's only cross-world read primitive (text
only), so a non-text entry with a real upstream change is
surfaced as a conflict instead of silently going stale.
- `merge` (text entries) — a three-way `vcs.merge3` runs over
(base, local, theirs); a clean result is written and the
origin pointer advances, a conflicted result is written WITH
markers and the row is flagged conflicted (base + theirs
checksums recorded for `world.resolvePullConflict`).
- `merge` (binary / composite entries) — no text merge is
possible; flagged conflicted with the structured base/theirs
checksums (no marker write).

Closure drift: an entry the original install never landed is
pulled fresh (added). A locally-pulled row nested under the
root's own directory whose origin entry disappeared from the
closure is removed when clean (pruned), or flagged conflicted
when it carries local edits.

**Parameters**

- `opts` `PullAssetOpts` _(optional)_ — See `PullAssetOpts`. `opts.guid` or `opts.path` is
required; `opts.ref` pins the re-resolve to a specific upstream
commit (defaults to latest finalized).

**Returns** `PullAssetResult` summarising what merged, conflicted, was pruned, and was newly added.

```lua
world.pullAsset({ guid = "..." })
```

## typed/builtin//modules/world_vcs/world/push {#typed-builtin-modules-world-vcs-world-push}

```lua
world.push(commitId: string?) -> (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).

**Parameters**

- `commitId` `string` _(optional)_ — Optional. A single commit to push verbatim. Omit for
the squash push of the whole unpushed stack (the normal path).

**Returns** `(string?, string)` — Two values: the ZeroMind-allocated commit id, and the verdict. `"published"` with the new commit id when this call published; `"already-published"` when ZeroMind already carries what this call would have published — the state a push asks for, so it returns rather than raising. That verdict carries the commit's existing ZeroMind id when the publish names one (the single-commit form), and a nil id when it names none (the whole-stack form, which reports a chain). A squash whose merged final state carries `dep.unresolved` problems takes the slow path inside the same call: the engine re-resolves each pending literal against its live asset index and submits the resolutions to the publish procedure, which completes the push. A reference literal that still resolves to nothing is published with the asset holding it and stays a problem recorded on that asset, while a dep pin the squash severed raises instead; either way the engine names each one with its path, line, reference and reason. A publish ZeroMind refuses raises naming the condition and the command that clears it — a branch that moved under this push names `world.pull()`.

```lua
local zmId = world.push()
local zmId, verdict = world.push()
world.push("01HABC...")
```

## typed/builtin//modules/world_vcs/world/reset {#typed-builtin-modules-world-vcs-world-reset}

```lua
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.

**Parameters**

- `targetCommitId` `string` — The commit id to rewind to.

**Returns** `string?` — A summary message: the target plus the list of commits rewound past.

```lua
world.reset("01HABC...")
```

## typed/builtin//modules/world_vcs/world/resolvePullConflict {#typed-builtin-modules-world-vcs-world-resolvepullconflict}

```lua
world.resolvePullConflict(path: string, choice: string)
```

Resolve a conflicted row. A TEXT conflict is one where the file
currently contains conflict markers (`world.pullAsset` writes
markers only for a text three-way merge that didn't resolve
cleanly); a BINARY/composite conflict has no markers — the local
bytes were left untouched.

`choice = "theirs"` fetches clean upstream text by content hash
(`conflict_theirs_blob_sha256` — path/rename-independent, since
blobs are content-addressed) and overwrites the local file with it
before clearing the flag. It errors, refusing to guess, when the
row records no theirs blob (a binary/composite conflict — a text
blob read can't address theirs for those; keep `"ours"` or
re-install the asset instead).

`choice = "ours"` keeps the local side. When the file carries
conflict markers, the local side is reconstructed from them (the
marker writers put ours first, so dropping each block's base and
theirs sections restores your bytes exactly) and written back;
a marker-free file is kept as-is. Either way the flag clears.

Either way, staging the resolved file (`world.add`) is the normal
git-add path once this returns — this call only clears the
manifest-level flag and (for `"theirs"`) the file content.

**Parameters**

- `path` `string` — The conflicted row's local VFS path.
- `choice` `string` — `"ours"` or `"theirs"`.

```lua
world.resolvePullConflict("/source/combat/rules.luau", "theirs")
```

## typed/builtin//modules/world_vcs/world/restore {#typed-builtin-modules-world-vcs-world-restore}

```lua
world.restore(handle: any?)
```

Restore one trash entry by row_id. Errors verbatim on
handler-not-yet-implemented / world-mismatch.

**Parameters**

- `handle` `any` _(optional)_ — The trash row id. May be a number or a numeric string.

```lua
world.restore(42)
```

## typed/builtin//modules/world_vcs/world/show {#typed-builtin-modules-world-vcs-world-show}

```lua
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`.

**Parameters**

- `...` `string` — Variadic string args: commit id, optional path, optional flags.

**Returns** `any` — Either a `ShowResult` table or a string (for `commit:/path`).

```lua
local r = world.show("abc123")
local r = world.show("--stat", "abc123")
local bytes = world.show("abc123:/foo.luau")
```

## typed/builtin//modules/world_vcs/world/stash {#typed-builtin-modules-world-vcs-world-stash}

```lua
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.

**Parameters**

- `label` `string` _(optional)_ — Optional. Free-form text label for the stash.

```lua
world.stash("wip widget refactor")
```

## typed/builtin//modules/world_vcs/world/stashDrop {#typed-builtin-modules-world-vcs-world-stashdrop}

```lua
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.

**Parameters**

- `handle` `any` _(optional)_ — The stash row id. May be a number or numeric string.

```lua
world.stashDrop(7)
```

## typed/builtin//modules/world_vcs/world/stashPop {#typed-builtin-modules-world-vcs-world-stashpop}

```lua
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).

**Parameters**

- `handle` `any` _(optional)_ — The stash row id. May be a number or numeric string.

**Returns** `StashSnapshot` containing `dirty` + `staged` entries.

```lua
local snap = world.stashPop(7)
```

## typed/builtin//modules/world_vcs/world/stashes {#typed-builtin-modules-world-vcs-world-stashes}

```lua
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.

**Returns** `{ StashRow }` — Array of `StashRow` tables.

```lua
local rows = world.stashes()
```

## typed/builtin//modules/world_vcs/world/trash {#typed-builtin-modules-world-vcs-world-trash}

```lua
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`.

**Returns** `{ TrashRow }` — Array of `TrashRow` tables.

```lua
local rows = world.trash()
```

## typed/builtin//modules/world_vcs/world/uninstallLibrary {#typed-builtin-modules-world-vcs-world-uninstalllibrary}

```lua
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).

**Parameters**

- `name` `string` — The library name, with or without the leading `@`.

**Returns** `string` — The marker path that was removed.

```lua
world.uninstallLibrary("@combat")
```

## typed/builtin//modules/world_vcs/world/unstage {#typed-builtin-modules-world-vcs-world-unstage}

```lua
world.unstage(path: string, opts: StageOpts?)
```

Remove a path from the staging area. Live manifest dirty
state is untouched.

**Parameters**

- `path` `string` — The path to unstage.
- `opts` `StageOpts` _(optional)_ — Optional `{ stage: string? }` naming the staging area the
path was staged into. Omitted, the call acts on the shared default
area.

```lua
world.unstage("/source/foo.luau")
world.unstage("/source/foo.luau", { stage = "fauna" })
```

## typed/builtin//modules/world_vcs/world/vcsStatus {#typed-builtin-modules-world-vcs-world-vcsstatus}

```lua
world.vcsStatus(opts: StageOpts?) -> StatusResult
```

Return the working-tree VCS status: dirty paths, staged
entries, ignored paths, untracked paths, and any unmerged ones.
An untracked path is one with no committed version behind it, and
it appears in `dirty` as well — `git add .` picks up new files too.
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 identity of the most recent
writer; `dirty_since_micros` is the microsecond timestamp of the
first write of the current dirty run. `local_identity` is this
session's own writer identity in that same namespace — compare
the two to tell your own writes from another account's.
`claimed_by_other_stages` names the paths some other staging area
holds and which area holds each — the grain that tells two callers
apart when they share one writer identity, and the set
`world.add_all` holds back.

**Parameters**

- `opts` `StageOpts` _(optional)_ — Optional `{ stage: string? }` naming the staging area whose
staged set to report. The dirty, ignored and untracked sets are the
world's working tree and read the same whichever area is named.

**Returns** `StatusResult` — A `StatusResult` table.

```lua
local s = world.vcsStatus()
local s = world.vcsStatus({ stage = "fauna" })
```

## typed/builtin//modules/yaml/M/decode {#typed-builtin-modules-yaml-m-decode}

```lua
M.decode(text: string) -> any
```

Decode a YAML document into a Luau value. Raises (with the line
number) on malformed input or constructs outside the supported
subset — never misparses silently.

**Parameters**

- `text` `string` — The YAML document text.

**Returns** `any` — The decoded value (table / scalar / nil for an empty document).

```lua
local doc = Yaml.decode(vfs.read(path))
```

## typed/builtin//modules/yaml/M/encode {#typed-builtin-modules-yaml-m-encode}

```lua
M.encode(value: { [any]: any }) -> string
```

Encode a Luau table as a YAML document (block style, two-space
indent, sorted keys). Raises on values YAML can't represent
(functions, userdata, non-string mapping keys).

**Parameters**

- `value` `{ [any]: any }` — The table to encode.

**Returns** `string` — The YAML text.

```lua
vfs.write(path, Yaml.encode({ contract = "weapon", values = v }))
```

## typed/builtin//modules/zinput/M/_resetLiveArmed {#typed-builtin-modules-zinput-m-resetlivearmed}

```lua
M._resetLiveArmed()
```

Test-only: reset the liveness auto-arm guard so a suite can
exercise the arming decision from a cold state.

```lua
Zin._resetLiveArmed()
```

## typed/builtin//modules/zinput/M/_resetTickGuard {#typed-builtin-modules-zinput-m-resettickguard}

```lua
M._resetTickGuard()
```

Test-only: reset the idempotency guard so the next `tick()`
call runs unconditionally. Suite isolation; not part of the
public contract for production code.

```lua
Zin._resetTickGuard()
```

## typed/builtin//modules/zinput/M/disconnect {#typed-builtin-modules-zinput-m-disconnect}

```lua
M.disconnect(handle: number) -> boolean
```

Disconnect any Zin handle (from `Zin.input.on*` or
`Zin.actions.bind`). Returns true if a handler/subscription was
removed; false on miss.

**Parameters**

- `handle` `number` — The numeric handle.

**Returns** `boolean` — Whether a handler was actually removed.

```lua
Zin.disconnect(h)
```

## typed/builtin//modules/zinput/M/lastTickAt {#typed-builtin-modules-zinput-m-lasttickat}

```lua
M.lastTickAt() -> number
```

Test/debug: wall-clock timestamp of the most recent tick,
or -1 if `Zin.tick` has never been called.

**Returns** `number` — The wall-clock seconds value of the most recent tick, or -1.

```lua
local t = Zin.lastTickAt()
```

## typed/builtin//modules/zinput/M/lastTickFrameId {#typed-builtin-modules-zinput-m-lasttickframeid}

```lua
M.lastTickFrameId() -> number
```

Test/debug: engine frame id of the most recent tick, or -1 if
`Zin.tick` has never been called (or `__zero_input.frameId()` is
unavailable). Used by `Zin.autoTick`'s worker loop to dedup
against explicit ticks.

**Returns** `number` — The engine frame id of the most recent tick, or -1.

```lua
local f = Zin.lastTickFrameId()
```

## typed/builtin//modules/zinput/M/tick {#typed-builtin-modules-zinput-m-tick}

```lua
M.tick(dt: number?)
```

Advance every stateful zinput subsystem by `dt` seconds.
`dt` is the frame delta. Pass the value your host already computes
for animation. If omitted, computed from elapsed wall time since the
last `tick()` call (first call defaults to 1/60). Order each tick:
1. clear chord per-tick fire flags, Gestures per-tick deltas,
Surface per-frame device-class flags, Virtual button edges +
drag deltas
2. route this tick's raw touches into Zin.virtual
(Zin.touchControls._advance() — auto-mounts, writes
stick/button/drag), then run the key-emulation floor over that
fresh state (Zin.emulation._advance()). Both PRODUCE the
Zin.virtual state the binding/axis/action evaluators below
consume THIS tick, so they run before any of them.
3. advance Axes smoothing, Chords window aging, Rebind timeouts,
Gestures time-based recognition (long-press) + pinch/pan deltas
4. drain `__zero_input.events()` once (first tick of the frame only)
5. feed each event into State (held-time), Chords (state machines),
Input (lastInputType tracking), Gestures (contact
tracks + discrete recognition), Surface (device-class flags)
6. resolve Surface's device class for this frame, then dispatch
event subscribers (Zin.events.on / Zin.input.on* callbacks —
priority + sink/pass + gpe)
7. dispatch action handlers (Zin.actions.bind / onPressed /
onReleased / onChanged / onHeld)
8. dispatch chord onFire callbacks and Gestures discrete-gesture
callbacks for anything that fired this tick

**Parameters**

- `dt` `number` _(optional)_ — Optional frame delta in seconds (defaults to elapsed wall time).

```lua
Zin.tick(dt)
```

## typed/builtin//modules/zinput/actions/M/_clearHandlers {#typed-builtin-modules-zinput-actions-m-clearhandlers}

```lua
M._clearHandlers()
```

Test-only: clear every handler (does NOT touch action
definitions).

```lua
Zin.actions._clearHandlers()
```

## typed/builtin//modules/zinput/actions/M/_dispatchHandlers {#typed-builtin-modules-zinput-actions-m-dispatchhandlers}

```lua
M._dispatchHandlers(firstTickThisFrame: boolean?)
```

Internal: dispatch action handlers. Called by `Zin.tick` after
axes/chords advance. Fires `Begin`/`End`/`Change`/`Held` handlers
based on each action's polling state this tick.
`firstTickThisFrame` is `false` on a same-engine-frame re-tick (e.g.
the autoTick worker and an explicit `Zin.tick` both land in one
frame): edge fires (`Begin`/`End`/`Change`) are per-frame events and
must not fire twice, so they are gated to the first tick of the
frame. `Held` is a per-tick redeliver and still fires every call.
A `nil` argument is treated as the first tick (edges fire).

**Parameters**

- `firstTickThisFrame` `boolean` _(optional)_ — Whether this is the frame's first dispatch pass.

```lua
Zin.actions._dispatchHandlers()
```

## typed/builtin//modules/zinput/actions/M/_owns {#typed-builtin-modules-zinput-actions-m-owns}

```lua
M._owns(handle: number) -> boolean
```

Internal: cross-API ownership probe. Used by `Zin.disconnect` to
route handles to the right `disconnect` implementation, since
`Zin.input.on*` and `Zin.actions.bind` share a handle namespace.

**Parameters**

- `handle` `number` — The numeric handle to probe.

**Returns** `boolean` — Whether this module owns the handle.

```lua
if Zin.actions._owns(h) then Zin.actions.disconnect(h) end
```

## typed/builtin//modules/zinput/actions/M/_resetUnknownWarnings {#typed-builtin-modules-zinput-actions-m-resetunknownwarnings}

```lua
M._resetUnknownWarnings()
```

Test-only: forget which names have already been reported as
unregistered, so a fresh suite sees the warning again.

```lua
Zin.actions._resetUnknownWarnings()
```

## typed/builtin//modules/zinput/actions/M/_setAllocator {#typed-builtin-modules-zinput-actions-m-setallocator}

```lua
M._setAllocator(fn: () -> number)
```

Internal: wire a shared id allocator, so handles from this module
and from `Zin.input.on*` never collide. Called once at module-load
time from `zinput/init.luau`.

**Parameters**

- `fn` `() -> number` — The allocator function that returns the next handle id.

```lua
M._setAllocator(allocateZinHandle)
```

## typed/builtin//modules/zinput/actions/M/_setEnsureBindingsFn {#typed-builtin-modules-zinput-actions-m-setensurebindingsfn}

```lua
M._setEnsureBindingsFn(fn: () -> ())
```

Internal: wire the lazy-default-map hook. Called once at module-
load time from `zinput/init.luau`.

**Parameters**

- `fn` `() -> ()` — The hook invoked on a cold read (name not in the registry).

```lua
M._setEnsureBindingsFn(ensureDefaultBindings)
```

## typed/builtin//modules/zinput/actions/M/_setEnsureLiveFn {#typed-builtin-modules-zinput-actions-m-setensurelivefn}

```lua
M._setEnsureLiveFn(fn: () -> ())
```

Internal: wire the liveness hook. Called once at module-load
time from `zinput/init.luau`.

**Parameters**

- `fn` `() -> ()` — The hook invoked on every cold-checked read below.

```lua
M._setEnsureLiveFn(ensureInputLive)
```

## typed/builtin//modules/zinput/actions/M/_settled {#typed-builtin-modules-zinput-actions-m-settled}

```lua
M._settled() -> boolean
```

Internal: whether the most recent dispatch pass delivered
nothing and saw nothing held. The tick's quiescence gate reads it.

**Returns** `boolean` — true when no bound action is doing anything.

```lua
if Zin.actions._settled() then ... end
```

## typed/builtin//modules/zinput/actions/M/active {#typed-builtin-modules-zinput-actions-m-active}

```lua
M.active(name: string) -> boolean
```

True if an action is currently active in the input context
stack. An action is "active" iff its declared context matches the
top of the context stack (so `push("ui")` suppresses every
non-"ui" action).

**Parameters**

- `name` `string` — The action name.

**Returns** `boolean` — Whether the action is currently active.

```lua
if Zin.actions.active("jump") then ... end
```

## typed/builtin//modules/zinput/actions/M/bind {#typed-builtin-modules-zinput-actions-m-bind}

```lua
M.bind(name: string, fn: any?, opts: BindOpts?) -> ActionHandle?
```

Register a handler. Returns a numeric handle (also accepted by
`Zin.input.disconnect`). Returns `nil` if `name` is not a defined
action.

**Parameters**

- `name` `string` — The action name.
- `fn` `any` _(optional)_ — Handler `fn(name, state, io, gpe) -> "sink" | any`.
- `opts` `BindOpts` _(optional)_ — Optional `{ priority, fire, once }`.

**Returns** `ActionHandle?` — The numeric handle, or `nil` when the action isn't defined.

```lua
local h = Zin.actions.bind("jump", function() jump() end)
```

## typed/builtin//modules/zinput/actions/M/clear {#typed-builtin-modules-zinput-actions-m-clear}

```lua
M.clear()
```

Wipe every defined action AND every registered handler.
Primarily for tests.

```lua
Zin.actions.clear()
```

## typed/builtin//modules/zinput/actions/M/define {#typed-builtin-modules-zinput-actions-m-define}

```lua
M.define(spec: ActionSpec)
```

Define one or more actions. Each entry replaces any existing
action under the same name; other actions are preserved.

**Parameters**

- `spec` `ActionSpec` — Map of `name -> binding | { binding... } | { context, binding(s) }`.

```lua
Zin.actions.define({ jump = Zin.bindings.key("Space") })
```

## typed/builtin//modules/zinput/actions/M/disconnect {#typed-builtin-modules-zinput-actions-m-disconnect}

```lua
M.disconnect(handle: ActionHandle) -> boolean
```

Tear down a handler returned by `bind`. Idempotent.

**Parameters**

- `handle` `ActionHandle` — The handle from `bind` (or `onPressed`/`onReleased`/etc).

**Returns** `boolean` — Whether the handler was actually removed.

```lua
Zin.actions.disconnect(h)
```

## typed/builtin//modules/zinput/actions/M/get {#typed-builtin-modules-zinput-actions-m-get}

```lua
M.get(name: string) -> ActionEntry?
```

Internal: the registry record behind a name, for profile capture
and conflict indexing. Returns nil if the action is not defined.

## typed/builtin//modules/zinput/actions/M/handlerCount {#typed-builtin-modules-zinput-actions-m-handlercount}

```lua
M.handlerCount(name: string) -> number
```

Number of registered handlers for an action (0 if none /
unknown).

**Parameters**

- `name` `string` — The action name.

**Returns** `number` — The handler count for this action.

```lua
assert(Zin.actions.handlerCount("jump") == 1)
```

## typed/builtin//modules/zinput/actions/M/has {#typed-builtin-modules-zinput-actions-m-has}

```lua
M.has(name: string) -> boolean
```

True if an action with this name is defined.

**Parameters**

- `name` `string` — The action name to test.

**Returns** `boolean` — Whether the action exists in the registry.

```lua
if Zin.actions.has("jump") then ... end
```

## typed/builtin//modules/zinput/actions/M/held {#typed-builtin-modules-zinput-actions-m-held}

```lua
M.held(name: string) -> boolean
```

True if any binding on the action is currently delivering
input. For boolean bindings: any held. For axis/vector bindings:
non-zero magnitude. Suppressed by context gating.

**Parameters**

- `name` `string` — The action name.

**Returns** `boolean` — Whether the action is held this frame.

```lua
if Zin.actions.held("attack") then swing() end
```

## typed/builtin//modules/zinput/actions/M/heldTime {#typed-builtin-modules-zinput-actions-m-heldtime}

```lua
M.heldTime(name: string) -> number?
```

Seconds the action has been held, taken as the MAX held-time
across the action's boolean bindings. Returns `nil` if no binding
is held or if the action is gated off by the current input
context. Vector / axis bindings are skipped — use a held-time
threshold against `Zin.axes.value` for held-direction analogs.

**Parameters**

- `name` `string` — The action name.

**Returns** `number?` — The longest held-time (seconds) across the action's boolean bindings, or `nil`.

```lua
local t = Zin.actions.heldTime("interact")
```

## typed/builtin//modules/zinput/actions/M/names {#typed-builtin-modules-zinput-actions-m-names}

```lua
M.names() -> { string }
```

All defined action names, in arbitrary order.

**Returns** `{ string }` — A fresh array of action names.

```lua
for _, n in ipairs(Zin.actions.names()) do print(n) end
```

## typed/builtin//modules/zinput/actions/M/onChanged {#typed-builtin-modules-zinput-actions-m-onchanged}

```lua
M.onChanged(name: string, fn: any?, opts: BindOpts?) -> ActionHandle?
```

Fire on axis/vector value delta (state = "Change"). For boolean
actions Change fires on every press AND release transition — use
`onPressed` / `onReleased` instead if you only want edges.

**Parameters**

- `name` `string` — The action name.
- `fn` `any` _(optional)_ — Handler `fn(name, state, io, gpe)`.
- `opts` `BindOpts` _(optional)_ — Optional `{ priority, once }`.

**Returns** `ActionHandle?` — The numeric handle, or `nil` when the action isn't defined.

```lua
Zin.actions.onChanged("move", function(_, _, io) print(io.value) end)
```

## typed/builtin//modules/zinput/actions/M/onHeld {#typed-builtin-modules-zinput-actions-m-onheld}

```lua
M.onHeld(name: string, fn: any?, opts: BindOpts?) -> ActionHandle?
```

Fire every tick while held (state = "Held"). Fires whenever
`held()` is true at dispatch time, regardless of value change.
Inherits the action's context constraint (no per-handler context
filter).

**Parameters**

- `name` `string` — The action name.
- `fn` `any` _(optional)_ — Handler `fn(name, state, io, gpe)`.
- `opts` `BindOpts` _(optional)_ — Optional `{ priority, once }`.

**Returns** `ActionHandle?` — The numeric handle, or `nil` when the action isn't defined.

```lua
Zin.actions.onHeld("interact", function(_, _, io) charge(io.value) end)
```

## typed/builtin//modules/zinput/actions/M/onPressed {#typed-builtin-modules-zinput-actions-m-onpressed}

```lua
M.onPressed(name: string, fn: any?, opts: BindOpts?) -> ActionHandle?
```

Fire on rising edge (state = "Begin"). Sugar for `bind` with
`fire = {"Begin"}`.

**Parameters**

- `name` `string` — The action name.
- `fn` `any` _(optional)_ — Handler `fn(name, state, io, gpe)`.
- `opts` `BindOpts` _(optional)_ — Optional `{ priority, once }`.

**Returns** `ActionHandle?` — The numeric handle, or `nil` when the action isn't defined.

```lua
Zin.actions.onPressed("jump", function() ... end)
```

## typed/builtin//modules/zinput/actions/M/onReleased {#typed-builtin-modules-zinput-actions-m-onreleased}

```lua
M.onReleased(name: string, fn: any?, opts: BindOpts?) -> ActionHandle?
```

Fire on falling edge (state = "End"). Sugar for `bind` with
`fire = {"End"}`.

**Parameters**

- `name` `string` — The action name.
- `fn` `any` _(optional)_ — Handler `fn(name, state, io, gpe)`.
- `opts` `BindOpts` _(optional)_ — Optional `{ priority, once }`.

**Returns** `ActionHandle?` — The numeric handle, or `nil` when the action isn't defined.

```lua
Zin.actions.onReleased("attack", function() ... end)
```

## typed/builtin//modules/zinput/actions/M/pressed {#typed-builtin-modules-zinput-actions-m-pressed}

```lua
M.pressed(name: string) -> boolean
```

True if any boolean binding on the action was just pressed
this frame — the press EDGE, so it fires once per press no matter
how long the input is held. Use it for one-shot input: fire, jump,
pause, undo. For continuous input that should repeat every frame
the input is down, read the level instead with
`Zin.state.keyDown(key)`. Axis/vector bindings do not contribute to
press edges. Suppressed by context gating.

**Parameters**

- `name` `string` — The action name.

**Returns** `boolean` — Whether the action's press edge fired this frame.

```lua
if Zin.actions.pressed("jump") then ... end
```

## typed/builtin//modules/zinput/actions/M/reason {#typed-builtin-modules-zinput-actions-m-reason}

```lua
M.reason(name: string) -> string
```

Why a named action is not delivering, from the closed set this
registry can distinguish: `unknownControl` (no action is registered
under the name — the value readers answer their neutral value, which is
not a reading), `contextInactive` (registered, but its context is not
on top of the stack), `atRest` (live, and the devices it binds are not
being driven), or `delivering`.

**Parameters**

- `name` `string` — The action name.

**Returns** `string` — One of `unknownControl` / `contextInactive` / `atRest` / `delivering`.

```lua
if Zin.actions.reason("jump") == "unknownControl" then ... end
```

## typed/builtin//modules/zinput/actions/M/released {#typed-builtin-modules-zinput-actions-m-released}

```lua
M.released(name: string) -> boolean
```

True if any boolean binding on the action was just released
this frame. Suppressed by context gating.

**Parameters**

- `name` `string` — The action name.

**Returns** `boolean` — Whether the action's release edge fired this frame.

```lua
if Zin.actions.released("attack") then ... end
```

## typed/builtin//modules/zinput/actions/M/remove {#typed-builtin-modules-zinput-actions-m-remove}

```lua
M.remove(name: string)
```

Remove an action by name. Also tears down every handler that
was bound to it. No-op when the action isn't defined.

**Parameters**

- `name` `string` — The action name to remove.

```lua
Zin.actions.remove("jump")
```

## typed/builtin//modules/zinput/actions/M/repeated {#typed-builtin-modules-zinput-actions-m-repeated}

```lua
M.repeated(name: string, opts: { delay: number?, period: number? }?) -> boolean
```

Should a synthetic repeat fire this frame for the action?
Returns true if any of the action's boolean key bindings reports
`State.keyRepeatFired`. Mouse bindings are skipped (use a hold-
time threshold for press-and-hold UX). Suppressed by context
gating.

**Parameters**

- `name` `string` — The action name.
- `opts` `{ delay: number?, period: number? }` _(optional)_ — Optional `{ delay, period }` override of the global repeat defaults.

**Returns** `boolean` — Whether a synthetic repeat should fire this frame.

```lua
if Zin.actions.repeated("scrollLeft") then ... end
```

## typed/builtin//modules/zinput/actions/M/value {#typed-builtin-modules-zinput-actions-m-value}

```lua
M.value(name: string) -> any
```

Read the action's current value.
- Axis binding → number in [-1, 1]
- Vector binding → `{ x, y }` numbers in [-1, 1]
- Boolean binding → 1 when held, 0 when not (consumers usually use
`held()` instead; this exists so a single API works for any kind)
When multiple bindings exist, the first one whose kind matches the
caller's expectation wins (axis > vector > boolean in declaration
order). When suppressed by context, returns the identity value for
the first binding's kind: 0 for axis/boolean, `{ x = 0, y = 0 }`
for vector.

**Parameters**

- `name` `string` — The action name.

**Returns** `any` — The action's current value (shape depends on first binding kind).

```lua
local mv = Zin.actions.value("move")  -- { x, y }
```

## typed/builtin//modules/zinput/arming/M/_resetPress {#typed-builtin-modules-zinput-arming-m-resetpress}

```lua
M._resetPress()
```

Test-only: forget the claim decided for the press in progress, so
the next read searches again. Suite isolation for a simulated press
that never had a release.

```lua
Zin.arming._resetPress()
```

## typed/builtin//modules/zinput/arming/M/gate {#typed-builtin-modules-zinput-arming-m-gate}

```lua
M.gate(opts: Steering?) -> () -> boolean
```

Build the predicate a look-style control uses as its `gate`: the
test for "the player is steering", assembled from the gestures this
scheme means by it.

A locked pointer always arms — a cursor the scheme took is one the
player gave to the camera. Everything else is named in `opts`.

**Parameters**

- `opts` `Steering` _(optional)_ — Which gestures arm this control. Every field is optional; an
empty table reads pointer lock and the right button alone.

**Returns** `() -> boolean` — A predicate to assign to a control's `gate`.

```lua
gate = Zin.arming.gate({ dragZone = "right", stick = "right" })
```

## typed/builtin//modules/zinput/arming/M/rightButtonArms {#typed-builtin-modules-zinput-arming-m-rightbuttonarms}

```lua
M.rightButtonArms(mode: string?) -> boolean
```

Whether the right mouse button is arming a camera gesture right
now, on the terms `mode` names (`"free"` / `"held"` / `"off"`).

Under `"free"` the claim search runs on the frame the button goes
down and its answer holds for that whole press.

**Parameters**

- `mode` `string` _(optional)_ — How the button is read; `"free"` when omitted.

**Returns** `boolean` — True while the button is arming.

```lua
if Zin.arming.rightButtonArms("held") then ... end
```

## typed/builtin//modules/zinput/arming/M/rightButtonClaimants {#typed-builtin-modules-zinput-arming-m-rightbuttonclaimants}

```lua
M.rightButtonClaimants() -> { string }
```

Every control that declares the right mouse button and could
answer on it this frame, other than the engine's own arming gesture —
the controls a `"free"` gate stands down for.

Both layers a world can bind through are searched: the controls of
every live `.inputMap`, and the `Zin.actions` / `Zin.axes`
compatibility registry. A control whose map is standing down for a
suppressor, or whose context is not the one on top, is one the player
cannot reach, and the button is free of it for as long as that holds.

**Returns** `{ string }` — Control names, scheme controls first, each prefixed by the layer it was found in (`map:` / `action:` / `axis:`).

```lua
if #Zin.arming.rightButtonClaimants() > 0 then ... end
```

## typed/builtin//modules/zinput/autoTick/M/_setLastTickFrameIdFn {#typed-builtin-modules-zinput-autotick-m-setlasttickframeidfn}

```lua
M._setLastTickFrameIdFn(fn: () -> number)
```

Internal: register the accessor that returns the engine frame
id of the most recent `M.tick`. Wired by `init.luau` so the
worker can dedup itself against explicit ticks within the same
engine frame. Optional — when nil, the worker ticks
unconditionally.

**Parameters**

- `fn` `() -> number` — The accessor returning the engine frame id of the last tick.

```lua
AutoTick._setLastTickFrameIdFn(M.lastTickFrameId)
```

## typed/builtin//modules/zinput/autoTick/M/_setTickFn {#typed-builtin-modules-zinput-autotick-m-settickfn}

```lua
M._setTickFn(fn: (number?) -> ())
```

Internal: register the function that the auto-tick loop should
call each frame. Wired by `init.luau` at module load.

**Parameters**

- `fn` `(number?) -> ()` — The tick function (typically `Zin.tick`).

```lua
AutoTick._setTickFn(M.tick)
```

## typed/builtin//modules/zinput/autoTick/M/isRunning {#typed-builtin-modules-zinput-autotick-m-isrunning}

```lua
M.isRunning() -> boolean
```

True if the auto-tick loop is currently running.

**Returns** `boolean` — Whether the worker coroutine is live.

```lua
if Zin.autoTick.isRunning() then ... end
```

## typed/builtin//modules/zinput/autoTick/M/start {#typed-builtin-modules-zinput-autotick-m-start}

```lua
M.start() -> boolean
```

Start the auto-tick loop. No-op if already running.

**Returns** `boolean` — `true` when a new loop was started, `false` when it was already up.

```lua
Zin.autoTick.start()
```

## typed/builtin//modules/zinput/autoTick/M/stop {#typed-builtin-modules-zinput-autotick-m-stop}

```lua
M.stop()
```

Stop the auto-tick loop on its next yield. No-op if not running.

```lua
Zin.autoTick.stop()
```

## typed/builtin//modules/zinput/axes/M/_resetGateWarnings {#typed-builtin-modules-zinput-axes-m-resetgatewarnings}

```lua
M._resetGateWarnings()
```

Test-only: reset the once-per-axis gate-error warning state so
a fresh suite can verify warning behavior again.

```lua
Zin.axes._resetGateWarnings()
```

## typed/builtin//modules/zinput/axes/M/_resetUnknownWarnings {#typed-builtin-modules-zinput-axes-m-resetunknownwarnings}

```lua
M._resetUnknownWarnings()
```

Test-only: forget which names have already been reported as
unregistered, so a fresh suite sees the warning again.

```lua
Zin.axes._resetUnknownWarnings()
```

## typed/builtin//modules/zinput/axes/M/_setEnsureBindingsFn {#typed-builtin-modules-zinput-axes-m-setensurebindingsfn}

```lua
M._setEnsureBindingsFn(fn: () -> ())
```

Internal: wire the lazy-default-map hook. Called once at module-
load time from `zinput/init.luau`.

**Parameters**

- `fn` `() -> ()` — The hook invoked on a cold read (name not in the registry).

```lua
M._setEnsureBindingsFn(ensureDefaultBindings)
```

## typed/builtin//modules/zinput/axes/M/_setEnsureLiveFn {#typed-builtin-modules-zinput-axes-m-setensurelivefn}

```lua
M._setEnsureLiveFn(fn: () -> ())
```

Internal: wire the liveness hook. Called once at module-load
time from `zinput/init.luau`.

**Parameters**

- `fn` `() -> ()` — The hook invoked on every cold-checked read below.

```lua
M._setEnsureLiveFn(ensureInputLive)
```

## typed/builtin//modules/zinput/axes/M/_settled {#typed-builtin-modules-zinput-axes-m-settled}

```lua
M._settled() -> boolean
```

Internal: whether every axis sits at zero, current and target
alike. The tick's quiescence gate reads it.

**Returns** `boolean` — true when no axis is moving or being driven.

```lua
if Zin.axes._settled() then ... end
```

## typed/builtin//modules/zinput/axes/M/advance {#typed-builtin-modules-zinput-axes-m-advance}

```lua
M.advance(dt: number)
```

**Parameters**

- `dt` `number`

## typed/builtin//modules/zinput/axes/M/clear {#typed-builtin-modules-zinput-axes-m-clear}

```lua
M.clear()
```

Wipe every axis and its state. Primarily for tests.

```lua
Zin.axes.clear()
```

## typed/builtin//modules/zinput/axes/M/define {#typed-builtin-modules-zinput-axes-m-define}

```lua
M.define(spec: AxisSpec)
```

Define one or more axes. Each entry replaces any existing axis
of the same name; other axes are preserved.

**Parameters**

- `spec` `AxisSpec` — Map of `name -> { binding, deadzone?, smoothing?, curve?, invert?, context?, gate? }`.

```lua
Zin.axes.define({ aim_x = { binding = ..., deadzone = 0.05 } })
```

## typed/builtin//modules/zinput/axes/M/get {#typed-builtin-modules-zinput-axes-m-get}

```lua
M.get(name: string) -> AxisDef?
```

Internal introspection: definition record (or nil).

## typed/builtin//modules/zinput/axes/M/has {#typed-builtin-modules-zinput-axes-m-has}

```lua
M.has(name: string) -> boolean
```

True if an axis with this name is defined.

**Parameters**

- `name` `string` — The axis name.

**Returns** `boolean` — Whether the axis exists in the registry.

```lua
if Zin.axes.has("aim_x") then ... end
```

## typed/builtin//modules/zinput/axes/M/names {#typed-builtin-modules-zinput-axes-m-names}

```lua
M.names() -> { string }
```

All defined axis names, in arbitrary order.

**Returns** `{ string }` — A fresh array of axis names.

```lua
for _, n in ipairs(Zin.axes.names()) do print(n) end
```

## typed/builtin//modules/zinput/axes/M/raw {#typed-builtin-modules-zinput-axes-m-raw}

```lua
M.raw(name: string) -> any
```

Read the raw, unsmoothed, unshaped value of the underlying
binding. For vector bindings returns `{x,y}`; for everything else
returns a number in `[-1, 1]`. Useful for debugging or comparing
pre/post processing.

**Parameters**

- `name` `string` — The axis name.

**Returns** `any` — The raw value (scalar or vector depending on axis kind).

```lua
print(Zin.axes.raw("aim_x"))
```

## typed/builtin//modules/zinput/axes/M/reason {#typed-builtin-modules-zinput-axes-m-reason}

```lua
M.reason(name: string) -> string
```

Why a named axis is not delivering, from the closed set this
registry can distinguish: `unknownControl` (no axis is registered under
the name — the value readers answer zero, which is not a reading),
`contextInactive` (registered, but its context is not on top of the
stack), `gateRefused` (its own gate answered no), `atRest` (live, and
the binding it reads is not being driven), or `delivering`.

**Parameters**

- `name` `string` — The axis name.

**Returns** `string` — One of `unknownControl` / `contextInactive` / `gateRefused` / `atRest` / `delivering`.

```lua
if Zin.axes.reason("look") == "gateRefused" then ... end
```

## typed/builtin//modules/zinput/axes/M/remove {#typed-builtin-modules-zinput-axes-m-remove}

```lua
M.remove(name: string)
```

Remove an axis. No-op if not defined.

**Parameters**

- `name` `string` — The axis name.

```lua
Zin.axes.remove("aim_x")
```

## typed/builtin//modules/zinput/axes/M/value {#typed-builtin-modules-zinput-axes-m-value}

```lua
M.value(name: string) -> any
```

Read the smoothed, shaped, context-gated value.
Scalar axes return a number in `[-1, 1]`.
Vector axes return `{x, y}` numbers in `[-1, 1]`.
Returns 0 / `{x=0,y=0}` if the axis isn't defined.

**Parameters**

- `name` `string` — The axis name.

**Returns** `any` — The smoothed, shaped value (scalar or `{x, y}`).

```lua
local mv = Zin.axes.value("move")  -- { x, y }
```

## typed/builtin//modules/zinput/bindings/M/arrowKeys {#typed-builtin-modules-zinput-bindings-m-arrowkeys}

```lua
M.arrowKeys() -> Binding
```

Convenience: arrow keys as a vector binding. Identical to
`vector(key("ArrowRight"), key("ArrowLeft"), key("ArrowUp"), key("ArrowDown"))`.

**Returns** `Binding` — A `vector` binding for the arrow keys.

```lua
local move = Zin.bindings.arrowKeys()
```

## typed/builtin//modules/zinput/bindings/M/axis {#typed-builtin-modules-zinput-bindings-m-axis}

```lua
M.axis(plus: Binding, minus: Binding, opts: StickOpts?) -> Binding
```

Bind to a 1-D axis composed of two opposing bindings. Each arm
contributes how far it is pushed, 0..1, so a key gives 1 while held
and a trigger gives its travel — which is what separates easing a car
forward from flooring it. Value = plus travel - minus travel.

**Parameters**

- `plus` `Binding` — The binding whose travel contributes positively.
- `minus` `Binding` — The binding whose travel contributes negatively.
- `opts` `StickOpts` _(optional)_

**Returns** `Binding` — An `axis` binding descriptor.

```lua
local b = Zin.bindings.axis(B.key("KeyD"), B.key("KeyA"))
```

## typed/builtin//modules/zinput/bindings/M/evalAxis {#typed-builtin-modules-zinput-bindings-m-evalaxis}

```lua
M.evalAxis(b: any?) -> number
```

Resolve a 1-D axis binding to a scalar.
For `axis` bindings the result is in `[-1, 1]`. For `mouseDelta` /
`scroll` bindings the result is a raw physical delta (pixels,
wheel clicks) and may exceed that range — shape it with `Zin.axes`.

**Parameters**

- `b` `any` _(optional)_ — The binding to evaluate.

**Returns** `number` — The axis value this frame (0 when the binding is not scalar).

```lua
local x = Zin.bindings.evalAxis(Zin.bindings.mouseDelta("x"))
```

## typed/builtin//modules/zinput/bindings/M/evalHeld {#typed-builtin-modules-zinput-bindings-m-evalheld}

```lua
M.evalHeld(b: any?) -> boolean
```

Is this binding currently delivering a held signal?
key/mouse/modKey/pointerLocked → boolean held.
axis/vector/mouseDelta/scroll → magnitude non-zero.

**Parameters**

- `b` `any` _(optional)_ — The binding to evaluate.

**Returns** `boolean` — Whether the binding is held this frame.

```lua
if Zin.bindings.evalHeld(b) then ... end
```

## typed/builtin//modules/zinput/bindings/M/evalPressed {#typed-builtin-modules-zinput-bindings-m-evalpressed}

```lua
M.evalPressed(b: any?) -> boolean
```

Did this binding's press edge fire this frame? Boolean bindings
only. Axis/vector return false (use evalAxis/evalVector with a
held-time threshold for edge tracking).

**Parameters**

- `b` `any` _(optional)_ — The binding to evaluate.

**Returns** `boolean` — Whether the press edge fired this frame.

```lua
if Zin.bindings.evalPressed(b) then jump() end
```

## typed/builtin//modules/zinput/bindings/M/evalReleased {#typed-builtin-modules-zinput-bindings-m-evalreleased}

```lua
M.evalReleased(b: any?) -> boolean
```

Did this binding's release edge fire this frame?

**Parameters**

- `b` `any` _(optional)_ — The binding to evaluate.

**Returns** `boolean` — Whether the release edge fired this frame.

```lua
if Zin.bindings.evalReleased(b) then ... end
```

## typed/builtin//modules/zinput/bindings/M/evalVector {#typed-builtin-modules-zinput-bindings-m-evalvector}

```lua
M.evalVector(b: any?) -> Vec2
```

Resolve a 2-D vector binding to `{ x, y }`.
For `vector` bindings the result is in `[-1, 1]`. For `mouseDelta`
/ `scroll` bindings (with no `axis` set) the result is the raw
frame delta — `mouseDelta` = `{ x = dx, y = dy }`, `scroll` =
`{ x = 0, y = wheel_delta }` (x reserved for future h-scroll).

**Parameters**

- `b` `any` _(optional)_ — The binding to evaluate.

**Returns** `Vec2` — A `{ x, y }` vector.

```lua
local mv = Zin.bindings.evalVector(Zin.bindings.wasd())
```

## typed/builtin//modules/zinput/bindings/M/format {#typed-builtin-modules-zinput-bindings-m-format}

```lua
M.format(b: any?) -> string
```

Render a single binding descriptor as a user-readable string.
Stable output across runs — the rebinding UI uses this verbatim.
Returns `"<invalid>"` for malformed input (does not throw).

**Parameters**

- `b` `any` _(optional)_ — The binding to format.

**Returns** `string` — A short, human-recognizable string.

```lua
local s = Zin.bindings.format(B.modKey("Ctrl+S"))  -- "Ctrl+S"
```

## typed/builtin//modules/zinput/bindings/M/formatAll {#typed-builtin-modules-zinput-bindings-m-formatall}

```lua
M.formatAll(bindings: any?, sep: string?) -> string
```

Render an array of bindings joined by `sep` (default `", "`).
Returns `"<no bindings>"` if the argument isn't a table, `"<empty>"`
for an empty array. What a summary row listing one control's
bindings for a device class shows.

**Parameters**

- `bindings` `any` _(optional)_ — The bindings to format.
- `sep` `string` _(optional)_ — Optional join separator (default `", "`).

**Returns** `string` — A composite string description.

```lua
Zin.bindings.formatAll({ B.key("Space"), B.modKey("Ctrl+S") })
```

## typed/builtin//modules/zinput/bindings/M/isAxis {#typed-builtin-modules-zinput-bindings-m-isaxis}

```lua
M.isAxis(binding: any?) -> boolean
```

True for binding descriptors that resolve to a scalar (`axis`,
a `mouseDelta` / `scroll` with a non-nil `axis` field, or `touchPinch`).

**Parameters**

- `binding` `any` _(optional)_ — The binding to test.

**Returns** `boolean` — Whether the binding resolves to a scalar.

```lua
assert(Zin.bindings.isAxis(Zin.bindings.mouseDelta("x")))
```

## typed/builtin//modules/zinput/bindings/M/isBoolean {#typed-builtin-modules-zinput-bindings-m-isboolean}

```lua
M.isBoolean(binding: any?) -> boolean
```

True for binding descriptors that resolve to a boolean (key,
mouse, modKey, pointerLocked, touchButton).

**Parameters**

- `binding` `any` _(optional)_ — The binding to test.

**Returns** `boolean` — Whether the binding resolves to a boolean.

```lua
assert(Zin.bindings.isBoolean(Zin.bindings.key("Space")))
```

## typed/builtin//modules/zinput/bindings/M/isVector {#typed-builtin-modules-zinput-bindings-m-isvector}

```lua
M.isVector(binding: any?) -> boolean
```

True for binding descriptors that resolve to a 2-D vector
(`vector`, a `mouseDelta` / `scroll` with a nil `axis` field,
`touchStick`, or `touchDrag`).

**Parameters**

- `binding` `any` _(optional)_ — The binding to test.

**Returns** `boolean` — Whether the binding resolves to a 2-D vector.

```lua
assert(Zin.bindings.isVector(Zin.bindings.wasd()))
```

## typed/builtin//modules/zinput/bindings/M/key {#typed-builtin-modules-zinput-bindings-m-key}

```lua
M.key(code: string) -> Binding
```

Bind to a single key. Code is a web-style identifier (e.g.
"KeyW", "Space", "ShiftLeft", "ArrowUp") — same vocabulary as
`Zin.state.keyDown(code)`.

**Parameters**

- `code` `string` — The key code identifier.

**Returns** `Binding` — A `key` binding descriptor.

```lua
local b = Zin.bindings.key("Space")
```

## typed/builtin//modules/zinput/bindings/M/modKey {#typed-builtin-modules-zinput-bindings-m-modkey}

```lua
M.modKey(spec: string) -> Binding
```

Parse a modifier-decorated key spec like "Ctrl+S", "Shift+Alt+P",
or just "Escape". Recognized modifier tokens (case-insensitive):
"Ctrl", "Control", "Shift", "Alt". Anything else is treated as the
base key code. The last segment is the base key.

**Parameters**

- `spec` `string` — The modifier-decorated key spec.

**Returns** `Binding` — A `modKey` binding descriptor.

```lua
local b = Zin.bindings.modKey("Ctrl+S")
```

## typed/builtin//modules/zinput/bindings/M/mouse {#typed-builtin-modules-zinput-bindings-m-mouse}

```lua
M.mouse(button: string) -> Binding
```

Bind to a single mouse button by name ("left", "right", or
"middle").

**Parameters**

- `button` `string` — The mouse-button name.

**Returns** `Binding` — A `mouse` binding descriptor.

```lua
local b = Zin.bindings.mouse("right")
```

## typed/builtin//modules/zinput/bindings/M/mouseDelta {#typed-builtin-modules-zinput-bindings-m-mousedelta}

```lua
M.mouseDelta(axis: string?) -> Binding
```

Bind to the mouse delta this frame.
- `axis = nil`  → vector binding returning `{ x = dx, y = dy }`
- `axis = "x"` → scalar binding returning `dx`
- `axis = "y"` → scalar binding returning `dy`
Values are not normalised to `[-1, 1]` — mouse delta is a physical
pixel count. A control carrying this beside a stick declares
`as = "delta"` with `unitsPerSecond` on the stick class, so both
classes reach the consumer measured in these pixels.

**Parameters**

- `axis` `string` _(optional)_ — Optional. `"x"` / `"y"` for a scalar binding; omit for a vector.

**Returns** `Binding` — A `mouseDelta` binding descriptor.

```lua
local look = Zin.bindings.mouseDelta()
local lookX = Zin.bindings.mouseDelta("x")
```

## typed/builtin//modules/zinput/bindings/M/padAxis {#typed-builtin-modules-zinput-bindings-m-padaxis}

```lua
M.padAxis(axis: string, opts: StickOpts?) -> Binding
```

Gamepad axis binding, one canonical axis as a scalar. Stick axes
run -1..1 in the frame the binding declares — forward positive by
default, matching the touch stick and `B.wasd()`, and screen-down
positive under `as = "delta"`, matching the mouse and the dragging
finger it is measured against. Trigger axes run 0..1.

**Parameters**

- `axis` `string` — Canonical name: left_stick_x, left_stick_y, right_stick_x,
right_stick_y, left_trigger, right_trigger.
- `opts` `StickOpts` _(optional)_

**Returns** `Binding` — The binding descriptor.

```lua
B.padAxis("right_stick_x")
```

## typed/builtin//modules/zinput/bindings/M/padButton {#typed-builtin-modules-zinput-bindings-m-padbutton}

```lua
M.padButton(button: string, slot: number?) -> Binding
```

Gamepad button binding, addressed by canonical position rather
than by any vendor's letter — `south` is the lower face button on
every pad, whatever it is printed with. With no `slot`, ANY connected
pad drives it, which is what a single-player scheme wants; name a slot
for local multiplayer.

**Parameters**

- `button` `string` — Canonical name: south, east, west, north, left_shoulder,
right_shoulder, left_trigger, right_trigger, left_stick, right_stick,
select, start, guide, dpad_up, dpad_down, dpad_left, dpad_right.
- `slot` `number` _(optional)_ — Pad slot, or nil for any pad.

**Returns** `Binding` — The binding descriptor.

```lua
B.padButton("south")
```

## typed/builtin//modules/zinput/bindings/M/padStick {#typed-builtin-modules-zinput-bindings-m-padstick}

```lua
M.padStick(stick: string, opts: StickOpts?) -> Binding
```

Gamepad stick binding: the 2-D vector of one thumbstick. The
vector shape a movement or look axis wants, without naming its two
components separately.

**Parameters**

- `stick` `string` — "left" or "right".
- `opts` `StickOpts` _(optional)_

**Returns** `Binding` — The binding descriptor.

```lua
B.padStick("left")
```

## typed/builtin//modules/zinput/bindings/M/padTrigger {#typed-builtin-modules-zinput-bindings-m-padtrigger}

```lua
M.padTrigger(trigger: string, slot: number?) -> Binding
```

Gamepad trigger binding: one trigger's analog travel, 0..1. The
same trigger also latches a digital `padButton` at half throw, so a
scheme binds whichever of the two it means.

**Parameters**

- `trigger` `string` — "left" or "right".
- `slot` `number` _(optional)_ — Pad slot, or nil for any pad.

**Returns** `Binding` — The binding descriptor.

```lua
B.padTrigger("right")
```

## typed/builtin//modules/zinput/bindings/M/pointerLocked {#typed-builtin-modules-zinput-bindings-m-pointerlocked}

```lua
M.pointerLocked() -> Binding
```

Bind to pointer-lock state. `evalHeld` is true while the
pointer is locked. `evalPressed` / `evalReleased` always return
false (use `Zin.events.on` for edge events).

**Returns** `Binding` — A `pointerLocked` binding descriptor.

```lua
local locked = Zin.bindings.pointerLocked()
```

## typed/builtin//modules/zinput/bindings/M/scroll {#typed-builtin-modules-zinput-bindings-m-scroll}

```lua
M.scroll(axis: string?) -> Binding
```

Bind to the scrollwheel delta this frame.
- `axis = nil`  → vector binding returning `{ x = 0, y = scroll_delta }`
- `axis = "y"` → scalar binding returning the wheel delta
- `axis = "x"` → scalar binding returning `0` (no horizontal-scroll
surface today; reserved for future hardware support)

**Parameters**

- `axis` `string` _(optional)_ — Optional. `"x"` / `"y"` for a scalar binding; omit for a vector.

**Returns** `Binding` — A `scroll` binding descriptor.

```lua
local zoom = Zin.bindings.scroll("y")
```

## typed/builtin//modules/zinput/bindings/M/surfacesOf {#typed-builtin-modules-zinput-bindings-m-surfacesof}

```lua
M.surfacesOf(binding: any?) -> { string }
```

Which device surface a binding reads from: `pointer` (mouse, wheel
or finger), `keyboard` (keys and composed text), or `gamepad`. A
composite binding (`axis`, `vector`) answers with the surfaces of every
binding it combines.

**Parameters**

- `binding` `any` _(optional)_ — The binding to classify.

**Returns** `{ string }` — Array of surface names, without repeats.

```lua
local s = Zin.bindings.surfacesOf(Zin.bindings.wasd())
```

## typed/builtin//modules/zinput/bindings/M/touchButton {#typed-builtin-modules-zinput-bindings-m-touchbutton}

```lua
M.touchButton(opts: { zone: string?, label: string?, icon: string?, priority: number?, size: string?, group: string? }) -> Binding
```

Virtual-button binding: a boolean fed by the on-screen button
identified by `opts.label` (else `opts.zone`). `label` and `icon`
also carry the control's presentation. `priority` (lower renders
first/more prominent on the touch overlay; defaults to 50 when
omitted), `size` (`"small"|"medium"|"large"`, defaults to
`"medium"` — this button's own circle radius, whatever else the
overlay is drawing), and `group` (buttons sharing a group render
adjacently) shape the overlay's layout — see
`Zin.touchControls`.

**Parameters**

- `opts` `{ zone: string?, label: string?, icon: string?, priority: number?, size: string?, group: string? }` — { zone: string?, label: string?, icon: string?, priority: number?, size: string?, group: string? } — at least one of zone/label.

**Returns** `Binding` — The binding descriptor.

```lua
B.touchButton({ zone = "right-lower", label = "Jump", priority = 10 })
```

## typed/builtin//modules/zinput/bindings/M/touchDrag {#typed-builtin-modules-zinput-bindings-m-touchdrag}

```lua
M.touchDrag(opts: { zone: string, axis: string? }) -> Binding
```

Touch-drag binding: a per-frame delta vector fed by drags in
`opts.zone` (mouseDelta semantics — px this frame).

**Parameters**

- `opts` `{ zone: string, axis: string? }` — { zone: string } — the drag zone id (e.g. "right").

**Returns** `Binding` — The binding descriptor.

```lua
B.touchDrag({ zone = "right" })
```

## typed/builtin//modules/zinput/bindings/M/touchPinch {#typed-builtin-modules-zinput-bindings-m-touchpinch}

```lua
M.touchPinch(opts: StickOpts?) -> Binding
```

Pinch binding: a scalar axis fed by the two-finger pinch delta
(px this tick; positive = spreading).

**Parameters**

- `opts` `StickOpts` _(optional)_

**Returns** `Binding` — The binding descriptor.

```lua
B.touchPinch()
```

## typed/builtin//modules/zinput/bindings/M/touchStick {#typed-builtin-modules-zinput-bindings-m-touchstick}

```lua
M.touchStick(opts: { zone: string, axis: string? }) -> Binding
```

Virtual-stick binding: a vector fed by the on-screen stick in
`opts.zone` (components -1..1). Evaluates {x=0,y=0} while no
control writes the zone.

**Parameters**

- `opts` `{ zone: string, axis: string? }` — { zone: string } — the stick's zone id (e.g. "left").

**Returns** `Binding` — The binding descriptor.

```lua
B.touchStick({ zone = "left" })
```

## typed/builtin//modules/zinput/bindings/M/vector {#typed-builtin-modules-zinput-bindings-m-vector}

```lua
M.vector(right: Binding, left: Binding, up: Binding, down: Binding) -> Binding
```

Bind to a 2-D vector. Each arm is a binding that contributes to
one axis when held. The returned vector is
`{ x = right - left, y = up - down }`.

**Parameters**

- `right` `Binding` — The binding that drives `+x`.
- `left` `Binding` — The binding that drives `-x`.
- `up` `Binding` — The binding that drives `+y`.
- `down` `Binding` — The binding that drives `-y`.

**Returns** `Binding` — A `vector` binding descriptor.

```lua
local b = Zin.bindings.vector(B.key("KeyD"), B.key("KeyA"), B.key("KeyW"), B.key("KeyS"))
```

## typed/builtin//modules/zinput/bindings/M/wasd {#typed-builtin-modules-zinput-bindings-m-wasd}

```lua
M.wasd() -> Binding
```

Convenience: WASD as a vector binding. Identical to
`vector(key("KeyD"), key("KeyA"), key("KeyW"), key("KeyS"))`.

**Returns** `Binding` — A `vector` binding for WASD.

```lua
local move = Zin.bindings.wasd()
```

## typed/builtin//modules/zinput/chords/M/_advanceTime {#typed-builtin-modules-zinput-chords-m-advancetime}

```lua
M._advanceTime(_dt: number)
```

Internal: age out stale recognizers. Called once per tick.

**Parameters**

- `_dt` `number` — Frame delta in seconds (currently unused; recognizers age
off wall-clock time).

```lua
Zin.chords._advanceTime(0.016)
```

## typed/builtin//modules/zinput/chords/M/_beginTick {#typed-builtin-modules-zinput-chords-m-begintick}

```lua
M._beginTick()
```

Internal: clear per-frame `firedThisTick` flags. Called at the
start of each `Zin.tick`.

```lua
Zin.chords._beginTick()
```

## typed/builtin//modules/zinput/chords/M/_dispatchFires {#typed-builtin-modules-zinput-chords-m-dispatchfires}

```lua
M._dispatchFires()
```

Internal: dispatch onFire callbacks for chords that fired
this tick. Called at the end of `Zin.tick`.

```lua
Zin.chords._dispatchFires()
```

## typed/builtin//modules/zinput/chords/M/_observeEvent {#typed-builtin-modules-zinput-chords-m-observeevent}

```lua
M._observeEvent(ev: any?)
```

Internal: feed one event into each defined chord's state
machine. Called by `Zin.tick` for every event in this frame's
`__zero_input.events()`.

**Parameters**

- `ev` `any` _(optional)_ — One input event from the frame log.

```lua
Zin.chords._observeEvent(ev)
```

## typed/builtin//modules/zinput/chords/M/_settled {#typed-builtin-modules-zinput-chords-m-settled}

```lua
M._settled() -> boolean
```

Internal: whether every recognizer sits idle -- no sequence
mid-entry, no simultaneous press collecting, no fire pending
dispatch. The tick's quiescence gate reads it.

**Returns** `boolean` — true when no recognizer holds in-flight state.

```lua
if Zin.chords._settled() then ... end
```

## typed/builtin//modules/zinput/chords/M/cancel {#typed-builtin-modules-zinput-chords-m-cancel}

```lua
M.cancel(name: string)
```

Manually reset the chord's progress (e.g. on context switch).

**Parameters**

- `name` `string` — The chord name.

```lua
Zin.chords.cancel("konami")
```

## typed/builtin//modules/zinput/chords/M/clear {#typed-builtin-modules-zinput-chords-m-clear}

```lua
M.clear()
```

Wipe every chord, state, and subscriber. Primarily for tests.

```lua
Zin.chords.clear()
```

## typed/builtin//modules/zinput/chords/M/define {#typed-builtin-modules-zinput-chords-m-define}

```lua
M.define(spec: ChordSpec)
```

Define one or more chords. Each entry replaces any existing
chord under the same name; other chords are preserved.

**Parameters**

- `spec` `ChordSpec` — Map of `name -> { kind = "sequence"|"simultaneous", ... }`.

```lua
Zin.chords.define({ konami = { kind = "sequence", steps = {...} } })
```

## typed/builtin//modules/zinput/chords/M/fired {#typed-builtin-modules-zinput-chords-m-fired}

```lua
M.fired(name: string) -> boolean
```

True on exactly one frame: the frame the chord completed its
pattern.

**Parameters**

- `name` `string` — The chord name.

**Returns** `boolean` — Whether the chord fired this frame.

```lua
if Zin.chords.fired("konami") then unlockBonus() end
```

## typed/builtin//modules/zinput/chords/M/get {#typed-builtin-modules-zinput-chords-m-get}

```lua
M.get(name: string) -> ChordDef?
```

Internal introspection: definition record (or nil).

## typed/builtin//modules/zinput/chords/M/has {#typed-builtin-modules-zinput-chords-m-has}

```lua
M.has(name: string) -> boolean
```

True if a chord with this name is defined.

**Parameters**

- `name` `string` — The chord name.

**Returns** `boolean` — Whether the chord exists in the registry.

```lua
if Zin.chords.has("konami") then ... end
```

## typed/builtin//modules/zinput/chords/M/names {#typed-builtin-modules-zinput-chords-m-names}

```lua
M.names() -> { string }
```

All defined chord names, in arbitrary order.

**Returns** `{ string }` — A fresh array of chord names.

```lua
for _, n in ipairs(Zin.chords.names()) do print(n) end
```

## typed/builtin//modules/zinput/chords/M/off {#typed-builtin-modules-zinput-chords-m-off}

```lua
M.off(handle: OnFireHandle)
```

Cancel an `onFire` subscription.

**Parameters**

- `handle` `OnFireHandle` — The handle returned by `onFire`.

```lua
Zin.chords.off(h)
```

## typed/builtin//modules/zinput/chords/M/onFire {#typed-builtin-modules-zinput-chords-m-onfire}

```lua
M.onFire(name: string, callback: () -> (), opts: OnFireOpts?) -> OnFireHandle
```

Register a callback fired when the named chord completes.
Returns a handle for `off()`. Multiple callbacks per chord
dispatch in insertion order.

**Parameters**

- `name` `string` — The chord name.
- `callback` `() -> ()` — Invoked when the chord fires.
- `opts` `OnFireOpts` _(optional)_ — Optional `{ context, once }`.

**Returns** `OnFireHandle` — A handle whose `off()` cancels the subscription.

```lua
local h = Zin.chords.onFire("konami", function() ... end)
```

## typed/builtin//modules/zinput/chords/M/progress {#typed-builtin-modules-zinput-chords-m-progress}

```lua
M.progress(name: string) -> number
```

Progress through the chord, 0..1. For sequences: matched-
steps / total. For simultaneous: matched / total. Always 0 when
not in flight.

**Parameters**

- `name` `string` — The chord name.

**Returns** `number` — Progress as a number in [0, 1].

```lua
local p = Zin.chords.progress("konami")
```

## typed/builtin//modules/zinput/chords/M/remove {#typed-builtin-modules-zinput-chords-m-remove}

```lua
M.remove(name: string)
```

Remove a chord. No-op if not defined. Subscribers on the same
name are dropped along with it.

**Parameters**

- `name` `string` — The chord name.

```lua
Zin.chords.remove("konami")
```

## typed/builtin//modules/zinput/clock/M/_setClock {#typed-builtin-modules-zinput-clock-m-setclock}

```lua
M._setClock(fn: (() -> number)?)
```

Internal: override the input clock with `fn` (returns seconds), or pass
`nil` to restore the engine clock. Exposed for deterministic timing —
fixed-step replay and tests that need a controllable clock.

**Parameters**

- `fn` `(() -> number)` _(optional)_ — A clock returning seconds, or `nil` to restore the default source.

```lua
require("modules.zinput.clock")._setClock(function() return t end)
```

## typed/builtin//modules/zinput/clock/M/nowSeconds {#typed-builtin-modules-zinput-clock-m-nowseconds}

```lua
M.nowSeconds() -> number
```

Current wall-clock seconds for input timing. Reads the engine's
per-frame `getTime()`, falling back to `os.clock()` where no engine time
surface exists. Honors a clock injected via `_setClock`.

**Returns** `number` — Seconds of wall time.

```lua
local t = require("modules.zinput.clock").nowSeconds()
```

## typed/builtin//modules/zinput/conflicts/M/_loadIntentionalPairs {#typed-builtin-modules-zinput-conflicts-m-loadintentionalpairs}

```lua
M._loadIntentionalPairs(pairs_: any?)
```

Internal: seed the working set from a saved profile's
`intentional_pairs` field. Called on `Zin.profile.activate`. The
input shape is `{ ["a"] = "b", ... }` *or* `{ {a, b}, ... }` —
the JSON encoder lays it out as the array shape, but a hand-
edited profile may use either. Silently ignores malformed
entries.

**Parameters**

- `pairs_` `any` _(optional)_ — The raw saved pair list.

```lua
Conflicts._loadIntentionalPairs(profileJson.intentional_pairs)
```

## typed/builtin//modules/zinput/conflicts/M/_resetIntentional {#typed-builtin-modules-zinput-conflicts-m-resetintentional}

```lua
M._resetIntentional()
```

Test-only: wipe the working set. Suite isolation; not part of
the public contract.

```lua
Zin.conflicts._resetIntentional()
```

## typed/builtin//modules/zinput/conflicts/M/_serializeIntentional {#typed-builtin-modules-zinput-conflicts-m-serializeintentional}

```lua
M._serializeIntentional() -> { { string } }
```

Serialize the working set for `Zin.profile.save` / `export`.
Output is an array of `{ "a", "b" }` pairs in canonical order —
matches the shape `_loadIntentionalPairs` consumes on activate,
so the round-trip is lossless.

**Returns** `{ { string } }` — The serialized intentional-pair list.

```lua
local rows = Zin.conflicts._serializeIntentional()
```

## typed/builtin//modules/zinput/conflicts/M/_setPersistFn {#typed-builtin-modules-zinput-conflicts-m-setpersistfn}

```lua
M._setPersistFn(fn: () -> ())
```

Internal: register the closure that writes the current
intentional-pair list back to the active profile. Wired by
`zinput.init` so the profile module doesn't have to depend on
conflicts (one-way edge).

**Parameters**

- `fn` `() -> ()` — The persist closure.

```lua
Conflicts._setPersistFn(function() Profile.save(...) end)
```

## typed/builtin//modules/zinput/conflicts/M/bindingKey {#typed-builtin-modules-zinput-conflicts-m-bindingkey}

```lua
M.bindingKey(b: any?) -> string?
```

Canonical leaf key for a single discrete binding, or `nil` if
the binding has no single discrete identity (`axis`, `vector`,
`mouseDelta`, `scroll`, `pointerLocked`).
Outputs:
`key:Space`              — `{ kind = "key",    code = "Space" }`
`modKey:Ctrl+Shift+KeyS` — `{ kind = "modKey", code = "KeyS", mods = { ctrl, shift } }`
`mouse:left`             — `{ kind = "mouse",  button = "left" }`

**Parameters**

- `b` `any` _(optional)_ — The binding to canonicalise.

**Returns** `string?` — The canonical leaf-key string, or `nil` when the binding has no single identity.

```lua
local k = Zin.conflicts.bindingKey(B.key("Space"))  -- "key:Space"
```

## typed/builtin//modules/zinput/conflicts/M/find {#typed-builtin-modules-zinput-conflicts-m-find}

```lua
M.find(binding: any?) -> { Owner }
```

Find every action/axis whose binding shares a leaf key with
the probe. Returns an array of `{ target, name, slot?, context? }`
owners. Empty on no conflict. Decomposes axis/vector bindings on both
sides — a probe `key:Space` matches an axis whose `plus = Space`.

**Parameters**

- `binding` `any` _(optional)_ — The binding to look up.

**Returns** `{ Owner }` — An array of conflict owners.

```lua
local owners = Zin.conflicts.find(B.key("Space"))
```

## typed/builtin//modules/zinput/conflicts/M/forActiveProfile {#typed-builtin-modules-zinput-conflicts-m-foractiveprofile}

```lua
M.forActiveProfile() -> { ConflictRow }
```

Enumerate every leaf key shared by two or more owners across
the active action + axis registries. Returns an array sorted by
key for deterministic UI rendering; empty when there are no
conflicts. Each row carries a `kind = "real" | "intentional"`
field — see module about-block for the classification rule.

**Returns** `{ ConflictRow }` — An array of ConflictRow records.

```lua
for _, row in ipairs(Zin.conflicts.forActiveProfile()) do ... end
```

## typed/builtin//modules/zinput/conflicts/M/isIntentional {#typed-builtin-modules-zinput-conflicts-m-isintentional}

```lua
M.isIntentional(actionA: string, actionB: string) -> boolean
```

True when `(actionA, actionB)` is currently marked
intentional. Symmetric: `(a, b)` and `(b, a)` produce the same
answer.

**Parameters**

- `actionA` `string` — The first action name.
- `actionB` `string` — The second action name.

**Returns** `boolean` — Whether the pair is currently marked.

```lua
if Zin.conflicts.isIntentional("a", "b") then ... end
```

## typed/builtin//modules/zinput/conflicts/M/leafKeys {#typed-builtin-modules-zinput-conflicts-m-leafkeys}

```lua
M.leafKeys(binding: any?) -> { string }
```

Every leaf key a binding decomposes into: one for a discrete
binding, one per arm for an `axis` or `vector`, and none for a
continuous source (`mouseDelta`, `scroll`) which has no discrete
identity to share.

This is the canonical form two bindings are compared in — what makes
`Shift+Ctrl+KeyS` and `Ctrl+Shift+KeyS` the same key, and what lets a
caller outside this module ask whether a control declares an input
without writing a second comparison of its own.

**Parameters**

- `binding` `any` _(optional)_ — The binding to decompose.

**Returns** `{ string }` — The leaf keys, possibly empty.

```lua
local keys = Zin.conflicts.leafKeys(B.mouse("right"))
```

## typed/builtin//modules/zinput/conflicts/M/listIntentional {#typed-builtin-modules-zinput-conflicts-m-listintentional}

```lua
M.listIntentional() -> { { string } }
```

All currently-marked pairs, sorted lexicographically for
deterministic UI rendering. Each pair is returned in canonical
order (lexicographic ascending).

**Returns** `{ { string } }` — An array of `{ a, b }` pairs.

```lua
for _, p in ipairs(Zin.conflicts.listIntentional()) do ... end
```

## typed/builtin//modules/zinput/conflicts/M/markIntentional {#typed-builtin-modules-zinput-conflicts-m-markintentional}

```lua
M.markIntentional(actionA: string, actionB: string) -> (boolean, string?)
```

Mark a pair of actions as intentionally sharing a binding. The
pair is suppressed from `realOnly()` until `unmarkIntentional`
reverses it. Stored in the active user profile's JSON so the mark
survives restart. Built-in profiles (Luau modules) hold marks in
memory only for the session — the natural flow is "mark → save
as user profile" if you want them to persist.

**Parameters**

- `actionA` `string` — The first action name.
- `actionB` `string` — The second action name.

**Returns** `(boolean, string?)` — `(true)` on success, `(false, err)` when either action is unknown or both names are equal.

```lua
local ok, err = Zin.conflicts.markIntentional("crouch", "slide")
```

## typed/builtin//modules/zinput/conflicts/M/realOnly {#typed-builtin-modules-zinput-conflicts-m-realonly}

```lua
M.realOnly() -> { ConflictRow }
```

Subset of `forActiveProfile()` filtered to `kind == "real"`
rows only — the noise-filtered view the Input tab uses by
default.

**Returns** `{ ConflictRow }` — The real conflicts only.

```lua
for _, row in ipairs(Zin.conflicts.realOnly()) do ... end
```

## typed/builtin//modules/zinput/conflicts/M/unmarkIntentional {#typed-builtin-modules-zinput-conflicts-m-unmarkintentional}

```lua
M.unmarkIntentional(actionA: string, actionB: string) -> boolean
```

Remove a previously-marked intentional pair. Idempotent:
unmarking an absent pair is a no-op success.

**Parameters**

- `actionA` `string` — The first action name.
- `actionB` `string` — The second action name.

**Returns** `boolean` — Whether the inputs were accepted (true unless either name was non-string).

```lua
Zin.conflicts.unmarkIntentional("crouch", "slide")
```

## typed/builtin//modules/zinput/context/M/contains {#typed-builtin-modules-zinput-context-m-contains}

```lua
M.contains(name: string) -> boolean
```

True if `name` is anywhere in the active stack (not just the
top). Useful for "is UI open?" checks regardless of further pushes.

**Parameters**

- `name` `string` — The context name to look for.

**Returns** `boolean` — Whether `name` appears anywhere in the stack.

```lua
if Zin.context.contains("ui") then pauseGame() end
```

## typed/builtin//modules/zinput/context/M/current {#typed-builtin-modules-zinput-context-m-current}

```lua
M.current() -> string
```

Current (top-of-stack) context name. Always at least `default`.

**Returns** `string` — The name at the top of the stack.

```lua
if Zin.context.current() == "ui" then ... end
```

## typed/builtin//modules/zinput/context/M/default {#typed-builtin-modules-zinput-context-m-default}

```lua
M.default() -> string
```

The always-on context name. Anything declared without an explicit
context belongs here. The bottom of the stack is permanently this
value; `pop` cannot remove it.

**Returns** `string` — The default context name (the string `"default"`).

```lua
local d = Zin.context.default()  -- "default"
```

## typed/builtin//modules/zinput/context/M/pop {#typed-builtin-modules-zinput-context-m-pop}

```lua
M.pop() -> string?
```

Pop the top context. No-op when only `default` remains (so
unbalanced pop is safe and never leaves the stack empty).

**Returns** `string?` — The popped context name, or `nil` when the stack already held only `default`.

```lua
local prev = Zin.context.pop()
```

## typed/builtin//modules/zinput/context/M/push {#typed-builtin-modules-zinput-context-m-push}

```lua
M.push(name: any?)
```

Push a context onto the stack. Becomes the new "current" context.
Pushing the same context twice requires two pops to fully remove
(matches typical UI nesting).

**Parameters**

- `name` `any` _(optional)_ — The context name to push. Ignored when not a non-empty string.

```lua
Zin.context.push("ui")
```

## typed/builtin//modules/zinput/context/M/reset {#typed-builtin-modules-zinput-context-m-reset}

```lua
M.reset()
```

Pop everything except `default`. Useful for "exit all menus"
flows and for test setup/teardown.

```lua
Zin.context.reset()
```

## typed/builtin//modules/zinput/context/M/stack {#typed-builtin-modules-zinput-context-m-stack}

```lua
M.stack() -> { string }
```

Snapshot of the full stack, bottom→top. Returned table is a
copy; mutating it does not affect the live stack.

**Returns** `{ string }` — A copy of the active context stack.

```lua
local snap = Zin.context.stack()
```

## typed/builtin//modules/zinput/context/M/with {#typed-builtin-modules-zinput-context-m-with}

```lua
M.with(name: string, fn: () -> T...) -> T...
```

Run `fn` with `name` pushed onto the stack; pop guaranteed on
return or error. Returns whatever `fn` returns.

**Parameters**

- `name` `string` — The context to push during the call.
- `fn` `() -> T...` — The thunk to run with `name` on top of the stack.

**Returns** `T...` — Whatever `fn` returns.

```lua
Zin.context.with("ui", function() ... end)
```

## typed/builtin//modules/zinput/controllers/M/fps {#typed-builtin-modules-zinput-controllers-m-fps}

```lua
M.fps(opts: FpsOpts) -> FpsController
```

Construct a first-person walker controller.

**Parameters**

- `opts` `FpsOpts` — FpsOpts table.

**Returns** `FpsController` — An FpsController object with `:start/:stop/:update` plus motion-intent readers (`getDesiredVelocity`, `consumeJumpRequest`, `isSprinting`, `isCrouching`).

```lua
local c = Zin.controllers.fps({ entity = playerId })
```

## typed/builtin//modules/zinput/controllers/M/free {#typed-builtin-modules-zinput-controllers-m-free}

```lua
M.free(opts: FreeOpts) -> FreeController
```

Construct a free-fly designer/debug camera controller.
WASD plane motion + Q/E vertical + ShiftLeft sprint multiplier +
raw mouse-look (always reads the per-frame mouse delta — gating
is via `Zin.context`, not via pointer-lock). Mandatory: `opts.entity`
(entity ID string from `entity.spawn(...).id`). All other fields
default; pass `actionPrefix` to namespace if two free controllers
must coexist.

**Parameters**

- `opts` `FreeOpts` — FreeOpts table.

**Returns** `FreeController` — A FreeController object with `:start/:stop/:update`.

```lua
local c = Zin.controllers.free({ entity = id })
```

## typed/builtin//modules/zinput/controllers/M/orbit {#typed-builtin-modules-zinput-controllers-m-orbit}

```lua
M.orbit(opts: OrbitOpts) -> OrbitController
```

Construct an orbit camera controller around `opts.target`.
`target` is either an entity ID string (the orbit center tracks
that entity each frame) or a fixed `{ x, y, z }` table.

**Parameters**

- `opts` `OrbitOpts` — OrbitOpts table.

**Returns** `OrbitController` — An OrbitController object with `:start/:stop/:update`.

```lua
local c = Zin.controllers.orbit({ entity = cam, target = pivot })
```

## typed/builtin//modules/zinput/emulation/M/_advance {#typed-builtin-modules-zinput-emulation-m-advance}

```lua
M._advance()
```

Internal: advance the emulation floor one tick. Releases every
emitted key when the active map or the input context changed since
the previous tick, then re-derives button / stick / drag emulation
from the current effective map's touch/kbm binding pairs — active-
context entries only. No-op when no map is active. Wired into
`Zin.tick`.

```lua
Zin.emulation._advance()
```

## typed/builtin//modules/zinput/emulation/M/_reset {#typed-builtin-modules-zinput-emulation-m-reset}

```lua
M._reset()
```

Test-only: release everything emitted and clear tracked state.

```lua
Zin.emulation._reset()
```

## typed/builtin//modules/zinput/emulation/M/_settled {#typed-builtin-modules-zinput-emulation-m-settled}

```lua
M._settled() -> boolean
```

Internal: whether the emulation floor is producing nothing --
no synthesized pointer motion, no emulated key held. The tick's
quiescence gate reads it.

**Returns** `boolean` — true when the floor is at rest.

```lua
if Zin.emulation._settled() then ... end
```

## typed/builtin//modules/zinput/emulation/M/getSensitivity {#typed-builtin-modules-zinput-emulation-m-getsensitivity}

```lua
M.getSensitivity() -> number
```

The current touchDrag -> emulated mouse-delta multiplier.

**Returns** `number` — The sensitivity multiplier.

```lua
local s = Zin.emulation.getSensitivity()
```

## typed/builtin//modules/zinput/emulation/M/setSensitivity {#typed-builtin-modules-zinput-emulation-m-setsensitivity}

```lua
M.setSensitivity(n: number)
```

Set the touchDrag -> emulated mouse-delta multiplier (default
1.0).

**Parameters**

- `n` `number` — The sensitivity multiplier.

```lua
Zin.emulation.setSensitivity(1.5)
```

## typed/builtin//modules/zinput/emulation/M/synthesizedDelta {#typed-builtin-modules-zinput-emulation-m-synthesizeddelta}

```lua
M.synthesizedDelta() -> (boolean, number, number)
```

The mouse delta this floor synthesized on the current tick, and
whether it synthesized one at all. A drag the floor converted for a
control the scheme does not cover is a delta the evaluators should
read, where the platform's projection of the same contact is not.

**Returns** `(boolean, number, number)` — `(active, dx, dy)`

```lua
local ok, dx, dy = Zin.emulation.synthesizedDelta()
```

## typed/builtin//modules/zinput/events/M/_dispatch {#typed-builtin-modules-zinput-events-m-dispatch}

```lua
M._dispatch(events: any?)
```

Internal: dispatch a batch of events to every registered
subscriber. Called once per `Zin.tick` from the events stage of
the tick pipeline.

**Parameters**

- `events` `any` _(optional)_ — The frame's events as returned by `M.frame()`.

```lua
M._dispatch(Zin.events.frame())
```

## typed/builtin//modules/zinput/events/M/clearSubscribers {#typed-builtin-modules-zinput-events-m-clearsubscribers}

```lua
M.clearSubscribers()
```

Cancel every subscription. Primarily for test isolation.

```lua
Zin.events.clearSubscribers()
```

## typed/builtin//modules/zinput/events/M/frame {#typed-builtin-modules-zinput-events-m-frame}

```lua
M.frame() -> { InputEvent }
```

Get this frame's events as an array of records, in dispatch
order. Returns an empty table if `__zero_input.events` is missing
or returns a non-table value.

**Returns** `{ InputEvent }` — The current frame's events (a fresh array each call).

```lua
for _, ev in ipairs(Zin.events.frame()) do ... end
```

## typed/builtin//modules/zinput/events/M/iter {#typed-builtin-modules-zinput-events-m-iter}

```lua
M.iter()
```

Iterate this frame's events. Identical to
`ipairs(Zin.events.frame())` but the explicit name reads better
at call sites.

**Returns** An `ipairs`-style iterator over this frame's events.

```lua
for i, ev in Zin.events.iter() do ... end
```

## typed/builtin//modules/zinput/events/M/keysDown {#typed-builtin-modules-zinput-events-m-keysdown}

```lua
M.keysDown() -> { InputEvent }
```

All `key.down` events this frame.

**Returns** `{ InputEvent }` — The frame's `key.down` events in dispatch order.

```lua
for _, ev in ipairs(Zin.events.keysDown()) do print(ev.code) end
```

## typed/builtin//modules/zinput/events/M/keysUp {#typed-builtin-modules-zinput-events-m-keysup}

```lua
M.keysUp() -> { InputEvent }
```

All `key.up` events this frame.

**Returns** `{ InputEvent }` — The frame's `key.up` events in dispatch order.

```lua
for _, ev in ipairs(Zin.events.keysUp()) do ... end
```

## typed/builtin//modules/zinput/events/M/mouseDowns {#typed-builtin-modules-zinput-events-m-mousedowns}

```lua
M.mouseDowns() -> { InputEvent }
```

All `mouse.down` events this frame.

**Returns** `{ InputEvent }` — The frame's `mouse.down` events in dispatch order.

```lua
for _, ev in ipairs(Zin.events.mouseDowns()) do ... end
```

## typed/builtin//modules/zinput/events/M/mouseMoves {#typed-builtin-modules-zinput-events-m-mousemoves}

```lua
M.mouseMoves() -> { InputEvent }
```

All `mouse.move` events this frame.

**Returns** `{ InputEvent }` — The frame's `mouse.move` events in dispatch order.

```lua
for _, ev in ipairs(Zin.events.mouseMoves()) do ... end
```

## typed/builtin//modules/zinput/events/M/mouseUps {#typed-builtin-modules-zinput-events-m-mouseups}

```lua
M.mouseUps() -> { InputEvent }
```

All `mouse.up` events this frame.

**Returns** `{ InputEvent }` — The frame's `mouse.up` events in dispatch order.

```lua
for _, ev in ipairs(Zin.events.mouseUps()) do ... end
```

## typed/builtin//modules/zinput/events/M/mouseWheels {#typed-builtin-modules-zinput-events-m-mousewheels}

```lua
M.mouseWheels() -> { InputEvent }
```

All `mouse.wheel` events this frame.

**Returns** `{ InputEvent }` — The frame's `mouse.wheel` events in dispatch order.

```lua
for _, ev in ipairs(Zin.events.mouseWheels()) do ... end
```

## typed/builtin//modules/zinput/events/M/off {#typed-builtin-modules-zinput-events-m-off}

```lua
M.off(handle: SubHandle | number)
```

Cancel a subscription. Accepts a Handle returned from `on` or
a numeric id.

**Parameters**

- `handle` `SubHandle | number` — Handle or numeric subscription id.

```lua
Zin.events.off(h)
```

## typed/builtin//modules/zinput/events/M/on {#typed-builtin-modules-zinput-events-m-on}

```lua
M.on(filter: EventFilter, callback: (any) -> (), opts: SubOpts?) -> SubHandle
```

Register a callback fired when matching events arrive on
`Zin.tick`. Returns a handle for `off()`.

## typed/builtin//modules/zinput/events/M/subscriberCount {#typed-builtin-modules-zinput-events-m-subscribercount}

```lua
M.subscriberCount() -> number
```

Test/introspection: number of active subscribers.

**Returns** `number` — The current subscriber count.

```lua
assert(Zin.events.subscriberCount() == 0)
```

## typed/builtin//modules/zinput/events/M/texts {#typed-builtin-modules-zinput-events-m-texts}

```lua
M.texts() -> { InputEvent }
```

All `text` events this frame (composed text commits).

**Returns** `{ InputEvent }` — The frame's `text` events in dispatch order.

```lua
for _, ev in ipairs(Zin.events.texts()) do print(ev.text) end
```

## typed/builtin//modules/zinput/gamepad/M/available {#typed-builtin-modules-zinput-gamepad-m-available}

```lua
M.available() -> boolean
```

Whether this session has ever seen a pad. Latched by the first
connection, so unplugging one does not flip a scheme's prompts back
to keyboard glyphs on a cable knock.

**Returns** `boolean` — True once a pad has connected.

```lua
if Zin.gamepad.available() then showPadPrompts() end
```

## typed/builtin//modules/zinput/gamepad/M/count {#typed-builtin-modules-zinput-gamepad-m-count}

```lua
M.count() -> number
```

How many pads are connected.

**Returns** `number` — The count.

```lua
if Zin.gamepad.count() >= 2 then startCoop() end
```

## typed/builtin//modules/zinput/gamepad/M/family {#typed-builtin-modules-zinput-gamepad-m-family}

```lua
M.family(slot: number?) -> string
```

Which controller family a pad belongs to, read from the device
name the platform reported: `"xbox"`, `"playstation"`, or
`"nintendo"`. Xbox is the answer for anything unrecognised, because
the standard mapping every backend normalises to is the Xbox layout.

**Parameters**

- `slot` `number` _(optional)_ — Pad slot, or nil for the first connected pad.

**Returns** `string` — The family name.

```lua
if Zin.gamepad.family() == "playstation" then ... end
```

## typed/builtin//modules/zinput/gamepad/M/get {#typed-builtin-modules-zinput-gamepad-m-get}

```lua
M.get(slot: number) -> Pad?
```

The pad in `slot`, or nil when nothing holds it.

## typed/builtin//modules/zinput/gamepad/M/label {#typed-builtin-modules-zinput-gamepad-m-label}

```lua
M.label(button: string, slot: number?) -> string
```

What a legend should call a canonical button on the connected
pad — `"south"` reads as `A` on an Xbox pad, `Cross` on a
PlayStation one, `B` on a Nintendo one. Falls back to the canonical
name for anything the family tables do not cover.

**Parameters**

- `button` `string` — Canonical button name.
- `slot` `number` _(optional)_ — Pad slot, or nil for the first connected pad.

**Returns** `string` — The label to draw.

```lua
ui.text("Press " .. Zin.gamepad.label("south") .. " to jump")
```

## typed/builtin//modules/zinput/gamepad/M/list {#typed-builtin-modules-zinput-gamepad-m-list}

```lua
M.list() -> { Pad }
```

Every connected pad, in slot order. Each entry carries `slot`,
`name`, the three canonical button-name arrays, an `axes` map, and
whether it came from `inputSim` rather than a device.

## typed/builtin//modules/zinput/gestures/M/_advanceTime {#typed-builtin-modules-zinput-gestures-m-advancetime}

```lua
M._advanceTime(_dt: number)
```

Internal: time-based recognition (long-press) + continuous
two-finger deltas (pinch, pan). Runs every tick.

**Parameters**

- `_dt` `number`

```lua
Zin.gestures._advanceTime(dt)
```

## typed/builtin//modules/zinput/gestures/M/_beginTick {#typed-builtin-modules-zinput-gestures-m-begintick}

```lua
M._beginTick()
```

Internal: clear per-tick continuous deltas. First tick of each
engine frame.

```lua
Zin.gestures._beginTick()
```

## typed/builtin//modules/zinput/gestures/M/_dispatchFires {#typed-builtin-modules-zinput-gestures-m-dispatchfires}

```lua
M._dispatchFires()
```

Internal: deliver this tick's discrete gesture fires. Handler
errors are caught and logged.

```lua
Zin.gestures._dispatchFires()
```

## typed/builtin//modules/zinput/gestures/M/_observeEvent {#typed-builtin-modules-zinput-gestures-m-observeevent}

```lua
M._observeEvent(ev: any?)
```

Internal: per-event observer — builds contact tracks and
classifies discrete gestures on release.

**Parameters**

- `ev` `any` _(optional)_ — The raw input event record.

```lua
Zin.gestures._observeEvent(ev)
```

## typed/builtin//modules/zinput/gestures/M/_reset {#typed-builtin-modules-zinput-gestures-m-reset}

```lua
M._reset()
```

Test-only: clear all tracks, fires, deltas, and subscriptions.

```lua
Zin.gestures._reset()
```

## typed/builtin//modules/zinput/gestures/M/_settled {#typed-builtin-modules-zinput-gestures-m-settled}

```lua
M._settled() -> boolean
```

Internal: whether the recognizers sit idle -- no touch tracks
live, no fire pending dispatch, no pinch or pan delta carried. The
tick's quiescence gate reads it.

**Returns** `boolean` — true when nothing gestural is in flight.

```lua
if Zin.gestures._settled() then ... end
```

## typed/builtin//modules/zinput/gestures/M/configure {#typed-builtin-modules-zinput-gestures-m-configure}

```lua
M.configure(opts: { [string]: number })
```

Override recognition thresholds. Unspecified fields keep their
current values.

**Parameters**

- `opts` `{ [string]: number }` — Partial GestureConfig.

```lua
Zin.gestures.configure({ longPressDuration = 0.8 })
```

## typed/builtin//modules/zinput/gestures/M/getConfig {#typed-builtin-modules-zinput-gestures-m-getconfig}

```lua
M.getConfig() -> GestureConfig
```

Current recognition thresholds (a copy).

**Returns** `GestureConfig` — The GestureConfig table.

```lua
local c = Zin.gestures.getConfig()
```

## typed/builtin//modules/zinput/gestures/M/off {#typed-builtin-modules-zinput-gestures-m-off}

```lua
M.off(handle: number) -> boolean
```

Unsubscribe a handle returned by any Zin.gestures.on* function.

**Parameters**

- `handle` `number` — The numeric handle.

**Returns** `boolean` — Whether a subscription was removed.

```lua
Zin.gestures.off(h)
```

## typed/builtin//modules/zinput/gestures/M/onDoubleTap {#typed-builtin-modules-zinput-gestures-m-ondoubletap}

```lua
M.onDoubleTap(fn: (any) -> ()) -> number
```

Subscribe to double-taps. `fn(ev)` with ev = { x, y, id }. The
release that completes a double-tap also emits a `tap` on the same
tick (each qualifying release taps; the second one additionally
double-taps).

**Parameters**

- `fn` `(any) -> ()` — The callback.

**Returns** `number` — A numeric handle for `Zin.gestures.off`.

```lua
Zin.gestures.onDoubleTap(function(ev) ... end)
```

## typed/builtin//modules/zinput/gestures/M/onLongPress {#typed-builtin-modules-zinput-gestures-m-onlongpress}

```lua
M.onLongPress(fn: (any) -> ()) -> number
```

Subscribe to long-presses (fires once per contact, while the
finger is still down). `fn(ev)` with ev = { x, y, id }.

**Parameters**

- `fn` `(any) -> ()` — The callback.

**Returns** `number` — A numeric handle for `Zin.gestures.off`.

```lua
Zin.gestures.onLongPress(function(ev) openContextMenu(ev) end)
```

## typed/builtin//modules/zinput/gestures/M/onSwipe {#typed-builtin-modules-zinput-gestures-m-onswipe}

```lua
M.onSwipe(fn: (any) -> ()) -> number
```

Subscribe to swipes (fires on release). `fn(ev)` with ev =
{ direction = "left"|"right"|"up"|"down", dx, dy, velocity, id }.

**Parameters**

- `fn` `(any) -> ()` — The callback.

**Returns** `number` — A numeric handle for `Zin.gestures.off`.

```lua
Zin.gestures.onSwipe(function(ev) if ev.direction == "left" then ... end end)
```

## typed/builtin//modules/zinput/gestures/M/onTap {#typed-builtin-modules-zinput-gestures-m-ontap}

```lua
M.onTap(fn: (any) -> ()) -> number
```

Subscribe to taps. `fn(ev)` with ev = { x, y, id, duration }.

**Parameters**

- `fn` `(any) -> ()` — The callback.

**Returns** `number` — A numeric handle for `Zin.gestures.off`.

```lua
Zin.gestures.onTap(function(ev) select(ev.x, ev.y) end)
```

## typed/builtin//modules/zinput/gestures/M/panDelta {#typed-builtin-modules-zinput-gestures-m-pandelta}

```lua
M.panDelta() -> (number, number)
```

This tick's two-finger pan delta: movement of the contacts'
centroid, in px. Zeros unless exactly two contacts are down.

**Returns** `(number, number)` — dx, dy.

```lua
local dx, dy = Zin.gestures.panDelta()
```

## typed/builtin//modules/zinput/gestures/M/pinchDelta {#typed-builtin-modules-zinput-gestures-m-pinchdelta}

```lua
M.pinchDelta() -> number
```

This tick's two-finger pinch delta: change in the distance
between the two contacts, in px (positive = spreading). 0 unless
exactly two contacts are down.

**Returns** `number` — The pinch delta.

```lua
cam.zoom += Zin.gestures.pinchDelta() * 0.01
```

## typed/builtin//modules/zinput/input/M/_disconnectAll {#typed-builtin-modules-zinput-input-m-disconnectall}

```lua
M._disconnectAll()
```

Test-only: tear down every `Zin.input` subscription installed
this session.

```lua
Zin.input._disconnectAll()
```

## typed/builtin//modules/zinput/input/M/_observeEvent {#typed-builtin-modules-zinput-input-m-observeevent}

```lua
M._observeEvent(ev: any?)
```

Internal observer driven by `Zin.tick`. Receives every event in
the same drain loop as State / Chords and updates `_lastInputType`.

**Parameters**

- `ev` `any` _(optional)_ — The raw input event record.

```lua
Zin.input._observeEvent(ev)
```

## typed/builtin//modules/zinput/input/M/_owns {#typed-builtin-modules-zinput-input-m-owns}

```lua
M._owns(handle: number) -> boolean
```

Internal: reports whether `handle` was issued by this module.
Used by the unified `Zin.disconnect` to route ownership.

**Parameters**

- `handle` `number` — Candidate handle id.

**Returns** `boolean` — `true` when this module owns the handle.

```lua
if Zin.input._owns(h) then ... end
```

## typed/builtin//modules/zinput/input/M/_reset {#typed-builtin-modules-zinput-input-m-reset}

```lua
M._reset()
```

Test-only: clear `lastInputType`. Public so test suites can
isolate cases.

```lua
Zin.input._reset()
```

## typed/builtin//modules/zinput/input/M/_setAllocator {#typed-builtin-modules-zinput-input-m-setallocator}

```lua
M._setAllocator(fn: () -> number)
```

Internal: wire a shared id allocator. Called once at
module-load time from `zinput/init.luau`.

**Parameters**

- `fn` `() -> number` — A `() -> number` allocator that returns fresh handle ids.

```lua
Zin.input._setAllocator(zin._allocateHandle)
```

## typed/builtin//modules/zinput/input/M/disconnect {#typed-builtin-modules-zinput-input-m-disconnect}

```lua
M.disconnect(handle: Handle) -> boolean
```

Tear down a subscription returned by `Zin.input.on*`. Idempotent.

**Parameters**

- `handle` `Handle` — The composite handle returned by an `on*` call.

**Returns** `boolean` — `true` if a subscription was disconnected, `false` if the handle was unknown or already disconnected.

```lua
Zin.input.disconnect(h)
```

## typed/builtin//modules/zinput/input/M/lastInputType {#typed-builtin-modules-zinput-input-m-lastinputtype}

```lua
M.lastInputType() -> string?
```

Returns the userInputType of the most recent input event this session.
`"Keyboard"` | `"Mouse"` | `"Touch"` | `nil`.

**Returns** `string?` — The userInputType string, or `nil` if no events seen yet.

```lua
local t = Zin.input.lastInputType()
```

## typed/builtin//modules/zinput/input/M/onBegan {#typed-builtin-modules-zinput-input-m-onbegan}

```lua
M.onBegan(fn: (any, boolean) -> any, opts: SubOpts?) -> Handle
```

Fires on press / mouse-button-down. Handler: `fn(io, gpe) -> "sink"?`.

**Parameters**

- `fn` `(any, boolean) -> any` — Handler `(io, gpe) -> "sink"?`.
- `opts` `SubOpts` _(optional)_ — Optional `{ priority, context, once }` forwarded to `Zin.events.on`.

**Returns** `Handle` — A composite handle usable with `disconnect` / `Zin.actions.disconnect`.

```lua
Zin.input.onBegan(function(io, gpe) print(io.kind) end)
```

## typed/builtin//modules/zinput/input/M/onChanged {#typed-builtin-modules-zinput-input-m-onchanged}

```lua
M.onChanged(fn: (any, boolean) -> any, opts: SubOpts?) -> Handle
```

Fires on mouse motion / scroll. Handler: `fn(io, gpe) -> "sink"?`.

**Parameters**

- `fn` `(any, boolean) -> any` — Handler `(io, gpe) -> "sink"?`.
- `opts` `SubOpts` _(optional)_ — Optional `{ priority, context, once }`.

**Returns** `Handle` — A composite handle.

```lua
Zin.input.onChanged(function(io, gpe) ... end)
```

## typed/builtin//modules/zinput/input/M/onEnded {#typed-builtin-modules-zinput-input-m-onended}

```lua
M.onEnded(fn: (any, boolean) -> any, opts: SubOpts?) -> Handle
```

Fires on release / mouse-button-up. Handler: `fn(io, gpe) -> "sink"?`.

**Parameters**

- `fn` `(any, boolean) -> any` — Handler `(io, gpe) -> "sink"?`.
- `opts` `SubOpts` _(optional)_ — Optional `{ priority, context, once }`.

**Returns** `Handle` — A composite handle.

```lua
Zin.input.onEnded(function(io, gpe) ... end)
```

## typed/builtin//modules/zinput/input/M/onTextInput {#typed-builtin-modules-zinput-input-m-ontextinput}

```lua
M.onTextInput(fn: (string, boolean) -> any, opts: SubOpts?) -> Handle
```

Fires on committed text input. Handler: `fn(text, gpe) -> "sink"?`.

**Parameters**

- `fn` `(string, boolean) -> any` — Handler `(text, gpe) -> "sink"?` where `text` is the committed string.
- `opts` `SubOpts` _(optional)_ — Optional `{ priority, context, once }`.

**Returns** `Handle` — A composite handle.

```lua
Zin.input.onTextInput(function(text, gpe) ... end)
```

## typed/builtin//modules/zinput/input/M/subscriberCount {#typed-builtin-modules-zinput-input-m-subscribercount}

```lua
M.subscriberCount() -> number
```

Test/introspection: number of active `Zin.input.*` subscriptions
(composite handles, not the underlying per-kind Events subscribers).

**Returns** `number` — Subscriber count.

```lua
local n = Zin.input.subscriberCount()
```

## typed/builtin//modules/zinput/map/M/_reactivate {#typed-builtin-modules-zinput-map-m-reactivate}

```lua
M._reactivate(record: any?) -> any
```

Re-apply the active map from a changed record — the edit-in-place
path an `.inputMap` asset takes when its source is written while it is
live. Who asked for the map is carried across: a write to its source
is the same map with new bindings, not a caller taking it up.

**Parameters**

- `record` `any` _(optional)_ — The map record, freshly read from its source.

**Returns** `any` — The effective map that was applied.

```lua
Zin.map._reactivate(loadRecord(self))
```

## typed/builtin//modules/zinput/map/M/_reset {#typed-builtin-modules-zinput-map-m-reset}

```lua
M._reset()
```

Test-only: clear active-map state (the profile registry keeps
whatever was applied).

```lua
Zin.map._reset()
```

## typed/builtin//modules/zinput/map/M/activate {#typed-builtin-modules-zinput-map-m-activate}

```lua
M.activate(record: any?) -> any
```

Activate a map record: materialize it and apply the flattened
result as the live binding set (through the profile registry, so
persistence and conflict surfaces keep working). Per-class axis
bindings beyond the primary register as `<axis>@<class>` sibling
axes; consumers that combine device values read both (e.g.
`look` + `look@touch`).

**Parameters**

- `record` `any` _(optional)_ — The map (or profile) record, or an inputMap asset ref.

**Returns** `any` — The effective map that was activated.

```lua
Zin.map.activate(require("@builtin::inputMaps.default"))
```

## typed/builtin//modules/zinput/map/M/activeName {#typed-builtin-modules-zinput-map-m-activename}

```lua
M.activeName() -> string?
```

The active map's name, or nil.

**Returns** `string?` — The name string, or nil.

```lua
if Zin.map.activeName() == "default" then ... end
```

## typed/builtin//modules/zinput/map/M/addTouchButton {#typed-builtin-modules-zinput-map-m-addtouchbutton}

```lua
M.addTouchButton(actionName: string, buttonOpts: { zone: string?, label: string?, icon: string? }, emitKey: string?) -> any
```

Add a touchButton binding to an action's touch class on the
active effective map, then re-flatten and re-activate so it takes
effect immediately. Creates the action entry if `actionName`
doesn't exist yet (the overlay's synthetic `emit:<code>` buttons).

**Parameters**

- `actionName` `string` — The action to attach the button to.
- `buttonOpts` `{ zone: string?, label: string?, icon: string? }` — `{ zone: string?, label: string?, icon: string? }` —
the touchButton binding's presentation (see
`Zin.bindings.touchButton`).
- `emitKey` `string` _(optional)_ — Optional key code — when set and the action has no kbm
class yet, seeds it with `B.key(emitKey)` so a synthetic action is
self-contained from the moment it's created.

**Returns** `any` — The added touchButton binding descriptor.

```lua
Zin.map.addTouchButton("emit:KeyF", { label = "Cast" }, "KeyF")
```

## typed/builtin//modules/zinput/map/M/bake {#typed-builtin-modules-zinput-map-m-bake}

```lua
M.bake(name: string) -> any
```

Write the active effective map as a new inputMap asset —
synthesis made explicit and editable. The snapshot includes every
live entry, overlay-registered `emit:<code>` actions included.
Returns the created ref.

**Parameters**

- `name` `string` — The new asset's name.

**Returns** `any` — The created asset ref.

```lua
Zin.map.bake("my_scheme")
```

## typed/builtin//modules/zinput/map/M/bindingsFor {#typed-builtin-modules-zinput-map-m-bindingsfor}

```lua
M.bindingsFor(eff: any?, name: string, class: string) -> any
```

The effective bindings for one action or axis and device class.

**Parameters**

- `eff` `any` _(optional)_ — An effective map (from materialize/effective).
- `name` `string` — The action or axis name.
- `class` `string` — "kbm" | "gamepad" | "touch".

**Returns** `any` — The bindings array (actions) or binding (axes), or nil.

```lua
local touch = Zin.map.bindingsFor(eff, "jump", "touch")
```

## typed/builtin//modules/zinput/map/M/effective {#typed-builtin-modules-zinput-map-m-effective}

```lua
M.effective() -> any
```

The active map's effective form, or nil before any activation.

**Returns** `any` — The effective map, or nil.

```lua
local eff = Zin.map.effective()
```

## typed/builtin//modules/zinput/map/M/ensureActive {#typed-builtin-modules-zinput-map-m-ensureactive}

```lua
M.ensureActive() -> any
```

Ensure a map is active: keeps the current one, else activates
the builtin default map. The bootstrap the on-screen controls and
controllers call.

**Returns** `any` — The active effective map.

```lua
Zin.map.ensureActive()
```

## typed/builtin//modules/zinput/map/M/isFallback {#typed-builtin-modules-zinput-map-m-isfallback}

```lua
M.isFallback() -> boolean
```

Whether the active map is the fallback `ensureActive` armed on
its own, rather than one a caller activated. A reader that presents
the map to a player — the on-screen controls — asks this to tell a
scheme a world offered from the keyboard floor under a name that was
read.

**Returns** `boolean` — True while the active map is the arming fallback.

```lua
if not Zin.map.isFallback() then draw(Zin.map.effective()) end
```

## typed/builtin//modules/zinput/map/M/materialize {#typed-builtin-modules-zinput-map-m-materialize}

```lua
M.materialize(record: any?) -> any
```

Materialize a map record into its effective form: extends chain
resolved (child wins per action/axis/class), then the touch class
synthesized from the kbm shape wherever absent. Returns
{ name, description, actions = { [name] = { context, classes,
synthesized = { touch = true? } } }, axes = { ... } }.

**Parameters**

- `record` `any` _(optional)_ — The map (or profile) record.

**Returns** `any` — The effective map.

```lua
local eff = Zin.map.materialize(require("@builtin::inputMaps.default"))
```

## typed/builtin//modules/zinput/map/M/removeTouchButton {#typed-builtin-modules-zinput-map-m-removetouchbutton}

```lua
M.removeTouchButton(actionName: string, binding: any?) -> boolean
```

Remove a touchButton binding previously added via
`addTouchButton`, then re-flatten and re-activate. Drops the
action entry entirely once every class is empty — cleanup for
synthetic `emit:<code>` actions the overlay created.

**Parameters**

- `actionName` `string` — The action the binding was added to.
- `binding` `any` _(optional)_ — The binding table returned by `addTouchButton`.

**Returns** `boolean` — Whether a binding was actually removed.

```lua
Zin.map.removeTouchButton("emit:KeyF", binding)
```

## typed/builtin//modules/zinput/observe/M/_publish {#typed-builtin-modules-zinput-observe-m-publish}

```lua
M._publish()
```

Internal: publish this layer's half of the engine's input
observation for the current frame. Called once per frame from
`Zin.tick` while `Zin.observe.wanted()` holds.

```lua
Zin.observe._publish()
```

## typed/builtin//modules/zinput/observe/M/arm {#typed-builtin-modules-zinput-observe-m-arm}

```lua
M.arm(on: boolean?)
```

Hold the engine's input observation open, so `/runtime/input` and
`input.observe()` carry this layer's half of the document every frame.
A read of either arms it for a window of frames on its own; this is for
a test or a tool that wants it building continuously.

**Parameters**

- `on` `boolean` _(optional)_ — Arm (the default) or disarm.

```lua
Zin.observe.arm(true)
```

## typed/builtin//modules/zinput/observe/M/armedFrames {#typed-builtin-modules-zinput-observe-m-armedframes}

```lua
M.armedFrames() -> number
```

How many more frames the arming window has left. A read of
`Zin.observe.frame()`, `input.observe()` or `/runtime/input` sets it
back to the full window; every frame that passes takes one off it, and
`0` means nothing is observing.

**Returns** `number` — Frames left in the arming window.

```lua
print(Zin.observe.armedFrames())
```

## typed/builtin//modules/zinput/observe/M/control {#typed-builtin-modules-zinput-observe-m-control}

```lua
M.control(name: string) -> any
```

Everything known about one named control in a single call: which
maps contribute it, its bindings per device class, its subscriber
count, the value it reported on the most recent tick, whether that
reached a subscriber, and — when it is live and silent — why.

**Parameters**

- `name` `string` — The control name.

**Returns** `any` — `{ name, carriedBy, live, entries, lastTick, why }`. `lastTick` carries its own `window`: the tick's own record once the tick is keeping one, and the same answers resolved live before then.

```lua
local c = Zin.observe.control("move")
```

## typed/builtin//modules/zinput/observe/M/frame {#typed-builtin-modules-zinput-observe-m-frame}

```lua
M.frame() -> any
```

The mapping layer's account of the most recent tick: every live map,
every live control with what it did and why, and what the tick cost.

The window is ONE tick — the most recent one. Reading consumes nothing,
so any number of observers in the same frame all get the same answers.

**Returns** `any` — `{ frameId, window, maps, controls, cost }`.

```lua
local f = Zin.observe.frame()
```

## typed/builtin//modules/zinput/observe/M/means {#typed-builtin-modules-zinput-observe-m-means}

```lua
M.means(reason: string) -> string?
```

What one reason name means, or `nil` for a name outside the set.

**Parameters**

- `reason` `string` — The reason name.

**Returns** `string?` — The sentence describing it, or `nil`.

```lua
print(Zin.observe.means("gateRefused"))
```

## typed/builtin//modules/zinput/observe/M/reasons {#typed-builtin-modules-zinput-observe-m-reasons}

```lua
M.reasons() -> { any }
```

The closed set of reasons a control resolves to, each with what it
means and what to do about it. The resolver answers with exactly one of
these names.

**Returns** `{ any }` — Array of `{ name, means }`, in the order the resolver considers them.

```lua
for _, r in ipairs(Zin.observe.reasons()) do print(r.name, r.means) end
```

## typed/builtin//modules/zinput/observe/M/wanted {#typed-builtin-modules-zinput-observe-m-wanted}

```lua
M.wanted() -> boolean
```

Whether the engine wants this layer's half of the input observation
built this frame — true while something has read `input.observe()` or
`/runtime/input` recently enough.

**Returns** `boolean` — Whether a report is wanted.

```lua
if Zin.observe.wanted() then ... end
```

## typed/builtin//modules/zinput/observe/M/whySilent {#typed-builtin-modules-zinput-observe-m-whysilent}

```lua
M.whySilent(name: string) -> any
```

Why a named control is not reaching the game right now, as one
reason from the closed set `Zin.observe.reasons()` lists, with the
particulars behind it.

Resolves against the devices as they are at the moment of the call, so
it answers for a control the tick has never reached and for one that
does not exist. The `layer` field says which of the three naming layers
answered — the live maps' controls, the action registry, or the axis
registry — since a name can be live in one and unknown in the others.

**Parameters**

- `name` `string` — The control name.

**Returns** `any` — `{ name, reason, means, layer, carriedBy, ... }` — the extra fields depend on the reason: `suppressedBy`, `needsContext` / `currentContext`, `gateError`, `declaredClasses` / `presentClasses`, `deadzone`, `subscribers`, `value`, `rawReading`.

```lua
local why = Zin.observe.whySilent("look")
```

## typed/builtin//modules/zinput/pointer/M/lock {#typed-builtin-modules-zinput-pointer-m-lock}

```lua
M.lock()
```

Request pointer lock (cursor grab + hide). Records intent; the cursor
is captured once the surface is active — native: window focused + clicked;
WASM: on the next user gesture (browser policy).

```lua
Zin.pointer.lock()
```

## typed/builtin//modules/zinput/pointer/M/locked {#typed-builtin-modules-zinput-pointer-m-locked}

```lua
M.locked() -> boolean
```

Convenience: query the current pointer-lock state. Identical to
`Zin.state.pointerLocked()`.

**Returns** `boolean` — `true` when the pointer is currently locked.

```lua
if Zin.pointer.locked() then ... end
```

## typed/builtin//modules/zinput/pointer/M/unlock {#typed-builtin-modules-zinput-pointer-m-unlock}

```lua
M.unlock()
```

Release pointer lock (cursor ungrab + show).

```lua
Zin.pointer.unlock()
```

## typed/builtin//modules/zinput/profile/M/_reset {#typed-builtin-modules-zinput-profile-m-reset}

```lua
M._reset()
```

Test-only: clear all in-memory state. Suite isolation; not part
of the public contract.

```lua
Zin.profile._reset()
```

## typed/builtin//modules/zinput/profile/M/_resetApplied {#typed-builtin-modules-zinput-profile-m-resetapplied}

```lua
M._resetApplied()
```

Test-only: clear the applied/active markers so suites can
simulate a cold session without touching the registered profiles.
Not part of the public contract.

```lua
Zin.profile._resetApplied()
```

## typed/builtin//modules/zinput/profile/M/_setMapEnsureFn {#typed-builtin-modules-zinput-profile-m-setmapensurefn}

```lua
M._setMapEnsureFn(fn: (string) -> boolean)
```

Internal: wire the map-delegation hook. Called once at module-
load time from `zinput/init.luau`.

**Parameters**

- `fn` `(string) -> boolean` — The hook invoked with the resolved scheme name; returns `true`
when it handled activation (routing through the map).

```lua
Profile._setMapEnsureFn(mapEnsureDefault)
```

## typed/builtin//modules/zinput/profile/M/activate {#typed-builtin-modules-zinput-profile-m-activate}

```lua
M.activate(name: string, opts: ActivateOpts?) -> (boolean, string?)
```

Activate a registered profile: clear current actions/axes/chords,
then apply the profile's definitions. Sets the active name and
notifies subscribers. Activating the already-active profile is a
no-op unless `opts.reactivate = true`.

**Parameters**

- `name` `string` — Profile name to activate.
- `opts` `ActivateOpts` _(optional)_ — Optional `{ reactivate }` — forces re-apply when already active.

**Returns** `(boolean, string?)` — `(true)` on success or `(false, err)` on failure.

```lua
Zin.profile.activate("wasd-arrows")
Zin.profile.activate("wasd-arrows", { reactivate = true })
```

## typed/builtin//modules/zinput/profile/M/appliedName {#typed-builtin-modules-zinput-profile-m-appliedname}

```lua
M.appliedName() -> string?
```

The name of the profile whose sections are currently applied to
the actions/axes/chords registries, or nil when nothing has been
applied this session.

**Returns** `string?` — The applied profile name, or `nil`.

```lua
local n = Zin.profile.appliedName()
```

## typed/builtin//modules/zinput/profile/M/current {#typed-builtin-modules-zinput-profile-m-current}

```lua
M.current() -> string?
```

Active profile name for this session, or `nil` if none has been
activated yet.

**Returns** `string?` — The active profile name, or `nil`.

```lua
local n = Zin.profile.current()
```

## typed/builtin//modules/zinput/profile/M/delete {#typed-builtin-modules-zinput-profile-m-delete}

```lua
M.delete(name: string) -> (boolean, string?)
```

Remove a user profile's JSON file. Refuses to delete built-ins.
The in-memory registry entry is also dropped. If the deleted profile
was active, `current()` keeps the name until a different profile is
activated — but the registry no longer has the descriptor.

**Parameters**

- `name` `string` — Non-empty profile name.

**Returns** `(boolean, string?)` — `(true)` on success or `(false, err)`.

```lua
Zin.profile.delete("my-bindings")
```

## typed/builtin//modules/zinput/profile/M/ensureActive {#typed-builtin-modules-zinput-profile-m-ensureactive}

```lua
M.ensureActive(fallback: string?) -> (boolean, string?)
```

Bootstrap helper for controllers. If no profile is active,
activates the session-active profile or `fallback` if there is none.
Idempotent — if a profile is already active this is a no-op. A
camera/locomotion controller calls this on `awake()` so a scene with
no explicit `Zin.profile.activate` still has working bindings.
When the resolved scheme is the builtin `"default"`, activation
routes through `Zin.map` so every device class (kbm, gamepad,
touch) comes along, not just kbm.

**Parameters**

- `fallback` `string` _(optional)_ — Optional fallback name (defaults to `"default"`).

**Returns** `(boolean, string?)` — `(true)` on success or `(false, err)`.

```lua
Zin.profile.ensureActive("wasd-arrows")
```

## typed/builtin//modules/zinput/profile/M/export {#typed-builtin-modules-zinput-profile-m-export}

```lua
M.export(name: string, vfsPath: string) -> (boolean, string?)
```

Write a named profile's serializable JSON to an arbitrary VFS path.
Same shape as `save()` — round-trips through `import()` losslessly.
Built-in profiles can be exported; their function fields (gate,
curve closure form) are stripped from the exported JSON.

**Parameters**

- `name` `string` — Profile name to export.
- `vfsPath` `string` — Destination VFS path.

**Returns** `(boolean, string?)` — `(true)` on success or `(false, err)`.

```lua
Zin.profile.export("wasd-arrows", "/source/profiles/backup.json")
```

## typed/builtin//modules/zinput/profile/M/get {#typed-builtin-modules-zinput-profile-m-get}

```lua
M.get(name: string?) -> any?
```

Active profile descriptor (no arg) or the named profile (with arg).
Returns `nil` if missing.

## typed/builtin//modules/zinput/profile/M/import {#typed-builtin-modules-zinput-profile-m-import}

```lua
M.import(vfsPath: string, opts: ImportOpts?) -> (boolean, string)
```

Read a profile JSON from a VFS path and `register()` it. Does
NOT activate it — pass `opts.activate = true` (or call
`activate(name)` separately) to make it current.

**Parameters**

- `vfsPath` `string` — Source VFS path.
- `opts` `ImportOpts` _(optional)_ — Optional `{ overrideName, activate }`.

**Returns** `(boolean, string)` — `(true, registeredName)` on success or `(false, err)`.

```lua
Zin.profile.import("/source/profiles/backup.json")
Zin.profile.import(path, { overrideName = "v2", activate = true })
```

## typed/builtin//modules/zinput/profile/M/list {#typed-builtin-modules-zinput-profile-m-list}

```lua
M.list() -> { string }
```

Built-in and user profile names, sorted and deduplicated.

## typed/builtin//modules/zinput/profile/M/load {#typed-builtin-modules-zinput-profile-m-load}

```lua
M.load(name: string) -> (boolean, any?)
```

Load and register a profile. Tries `@builtin::profiles.<name>`
first (Luau module), then falls back to `/zero/profiles/<name>.json`.

## typed/builtin//modules/zinput/profile/M/off {#typed-builtin-modules-zinput-profile-m-off}

```lua
M.off(handle: number)
```

Drop a subscription registered via `onChange`. No-op if the
handle is unknown.

**Parameters**

- `handle` `number` — Subscription handle returned by `onChange`.

```lua
Zin.profile.off(h)
```

## typed/builtin//modules/zinput/profile/M/onChange {#typed-builtin-modules-zinput-profile-m-onchange}

```lua
M.onChange(cb: ChangeCallback) -> number
```

Subscribe to active-profile changes. Callback fires with
`(profileName, profileDescriptor)` on `activate` and on `register`
of the currently active profile.

**Parameters**

- `cb` `ChangeCallback` — Callback `(name: string, profile: any) -> ()`.

**Returns** `number` — A handle for `off`.

```lua
local h = Zin.profile.onChange(function(name, p) ... end)
```

## typed/builtin//modules/zinput/profile/M/register {#typed-builtin-modules-zinput-profile-m-register}

```lua
M.register(name: string, profile: any?) -> (boolean, string?)
```

Register a profile table. Validates the shape; replaces any prior
registration under the same name. If the registered name is currently
active, subscribers are notified (so editor UIs refresh).

**Parameters**

- `name` `string` — Non-empty profile name.
- `profile` `any` _(optional)_ — Profile descriptor.

**Returns** `(boolean, string?)` — `(ok, err)` — `(true)` on success, `(false, err)` on validation failure.

```lua
Zin.profile.register("wasd-arrows", profile)
```

## typed/builtin//modules/zinput/profile/M/save {#typed-builtin-modules-zinput-profile-m-save}

```lua
M.save(name: string, opts: SaveOpts?) -> (boolean, string?)
```

Capture the current Zin.actions / Zin.axes / Zin.chords state to
a JSON file under `/zero/profiles/<name>.json`. Refuses to overwrite
a built-in profile name or an existing user profile (unless
`opts.overwrite = true`). Functions (axis `gate`, function-valued
`curve`) are dropped — only data-typed fields persist.

**Parameters**

- `name` `string` — Non-empty profile name.
- `opts` `SaveOpts` _(optional)_ — Optional `{ description, overwrite }`.

**Returns** `(boolean, string?)` — `(true)` on success or `(false, err)`.

```lua
Zin.profile.save("my-bindings", { description = "..." })
```

## typed/builtin//modules/zinput/rebind/M/_advanceTime {#typed-builtin-modules-zinput-rebind-m-advancetime}

```lua
M._advanceTime(dt: number)
```

Internal: per-frame timeout sweep. Called by Zin.tick after the
event pump so timed-out sessions retire on the same frame their
budget runs out, before the next observed event.

**Parameters**

- `dt` `number` — Frame delta in seconds.

```lua
Zin.rebind._advanceTime(1 / 60)
```

## typed/builtin//modules/zinput/rebind/M/_settled {#typed-builtin-modules-zinput-rebind-m-settled}

```lua
M._settled() -> boolean
```

Internal: whether no rebind capture session is live. The tick's
quiescence gate reads it.

**Returns** `boolean` — true when nothing is listening for a binding.

```lua
if Zin.rebind._settled() then ... end
```

## typed/builtin//modules/zinput/rebind/M/begin {#typed-builtin-modules-zinput-rebind-m-begin}

```lua
M.begin(opts: BeginOpts?) -> Session
```

Start a new capture session. Returns the session table. The
session auto-subscribes to `Zin.events.on` so once `Zin.tick` runs
the first matching event commits the capture without the caller
having to pump `consume` manually.

**Parameters**

- `opts` `BeginOpts` _(optional)_ — Capture options — `target` (`"action"` (default) / `"axis"`),
`name` (required), `slot`, `mode` (`"replace"` (default) / `"append"`),
`timeoutSec`, `filter`, `applyOnCommit`, `onCommit`.

**Returns** `Session` — The session table — read `status` and `result()` after a tick or call `cancel()` / `apply()` / `conflicts()`.

```lua
local s = Zin.rebind.begin({ target = "action", name = "jump" })
```

## typed/builtin//modules/zinput/rebind/M/cancelAll {#typed-builtin-modules-zinput-rebind-m-cancelall}

```lua
M.cancelAll()
```

Cancel every live session. Test-only / shutdown.

```lua
Zin.rebind.cancelAll()
```

## typed/builtin//modules/zinput/rebind/M/liveCount {#typed-builtin-modules-zinput-rebind-m-livecount}

```lua
M.liveCount() -> number
```

Live sessions count; primarily for test introspection.

**Returns** `number` — Number of capturing sessions still active.

```lua
local n = Zin.rebind.liveCount()
```

## typed/builtin//modules/zinput/scheme/M/_advance {#typed-builtin-modules-zinput-scheme-m-advance}

```lua
M._advance(dt: number)
```

One tick of binding dispatch: evaluate every live binding and fire
what changed. Wired into `Zin.tick`.

`input` fires every frame a binding is active, and once more on the
frame it goes inactive carrying the neutral value and `active = false`
— so one handler both starts and stops the motion it drives.

**Parameters**

- `dt` `number` — Seconds since the previous tick.

```lua
Zin.scheme._advance(1 / 60)
```

## typed/builtin//modules/zinput/scheme/M/_childBindings {#typed-builtin-modules-zinput-scheme-m-childbindings}

```lua
M._childBindings(mapRef: any?) -> { any }
```

**Parameters**

- `mapRef` `any` _(optional)_

**Returns** `{ any }`

## typed/builtin//modules/zinput/scheme/M/_gateAllows {#typed-builtin-modules-zinput-scheme-m-gateallows}

```lua
M._gateAllows(record: any?) -> (boolean, string?, string?)
```

Internal: run a control's own gate. Returns whether it allows the
control to read, and when it does not, which of `gateRefused` /
`gateErrored` happened and the error text if one was raised.

**Parameters**

- `record` `any` _(optional)_ — The binding record.

**Returns** `(boolean, string?, string?)` — `(allowed, reason?, error?)`.

```lua
local ok, why = Zin.scheme._gateAllows(record)
```

## typed/builtin//modules/zinput/scheme/M/_readClasses {#typed-builtin-modules-zinput-scheme-m-readclasses}

```lua
M._readClasses(record: any?, dt: number) -> any
```

Internal: read every device class a control's record carries, in the
control's own unit, WITHOUT its gate and without its deadzone / curve /
invert shaping. What the devices produced before the control decided
what to do with it.

**Parameters**

- `record` `any` _(optional)_ — The binding record.
- `dt` `number` — Seconds since the previous tick.

**Returns** `any` — The unshaped reading, in the record's kind.

```lua
local raw = Zin.scheme._readClasses(record, 1 / 60)
```

## typed/builtin//modules/zinput/scheme/M/_reset {#typed-builtin-modules-zinput-scheme-m-reset}

```lua
M._reset()
```

Test-only: drop every live map without firing anything.

```lua
Zin.scheme._reset()
```

## typed/builtin//modules/zinput/scheme/M/_settled {#typed-builtin-modules-zinput-scheme-m-settled}

```lua
M._settled() -> boolean
```

Internal: the `<name>.inputBinding/` children of a map asset, as
resolved refs in name order.
Internal: whether every live control sits at rest -- nothing
active, nothing waiting for its holder to release, every smoothed
reading at neutral. The tick's quiescence gate reads it: a scan with
an early exit, so an idle layer answers in the cost of a comparison
per control rather than an evaluation.

**Returns** `boolean` — Array of inputBinding refs. true when no control could change without new input.

```lua
local kids = Zin.scheme._childBindings(mapRef)
if Zin.scheme._settled() then ... end
```

## typed/builtin//modules/zinput/scheme/M/activate {#typed-builtin-modules-zinput-scheme-m-activate}

```lua
M.activate(mapRef: any?) -> { [string]: Handle }
```

Activate an inputMap asset: load every `<name>.inputBinding/` child
it contains, validate them, add them to the live binding set, and
return the handles a controller subscribes through — one per binding,
keyed by the binding's name.

Every fault across every child is reported in one error, so a map with
three broken bindings names all three rather than one per attempt.

Activating a map already live returns its existing handles rather than
registering it twice, so two components sharing one map get one set of
controls.

**Parameters**

- `mapRef` `any` _(optional)_ — The inputMap asset ref.

**Returns** `{ [string]: Handle }` — A table of handles keyed by binding name.

```lua
local map = self.inputMap:activate(); map.jump:onPressed(fn)
```

## typed/builtin//modules/zinput/scheme/M/advanceCost {#typed-builtin-modules-zinput-scheme-m-advancecost}

```lua
M.advanceCost() -> any
```

What the most recent tick of binding dispatch cost, and how much it
covered: `{ frameId, maps, controls, ms }`. `ms` is ONE tick's own
milliseconds — the same number `profiler.stats("*zin.scheme.advance*")`
reports as `script.zin.scheme.advance`, where it also carries the average
and the peak across every tick since the engine started.

**Returns** `any` — `{ frameId, maps, controls, ms }`.

```lua
local cost = Zin.scheme.advanceCost()
```

## typed/builtin//modules/zinput/scheme/M/bindings {#typed-builtin-modules-zinput-scheme-m-bindings}

```lua
M.bindings() -> { any }
```

Every live binding, in activation order, as
`{ map, group, name, label, kind, context, suppressedBy, subscribers }`.
The touch overlay builds its buttons from this, so what is on screen is
exactly what some awake component asked for and nothing is standing
down.

**Returns** `{ any }` — Array of binding descriptors.

```lua
for _, b in ipairs(Zin.scheme.bindings()) do print(b.label) end
```

## typed/builtin//modules/zinput/scheme/M/classBindings {#typed-builtin-modules-zinput-scheme-m-classbindings}

```lua
M.classBindings(record: any?, class: string) -> { any }
```

Every binding a control declares for one device class, as the tick
reads them.

**Parameters**

- `record` `any` _(optional)_ — The binding record.
- `class` `string` — One of `kbm` / `gamepad` / `touch`.

**Returns** `{ any }` — Array of binding descriptors.

```lua
local kbm = Zin.scheme.classBindings(record, "kbm")
```

## typed/builtin//modules/zinput/scheme/M/deactivate {#typed-builtin-modules-zinput-scheme-m-deactivate}

```lua
M.deactivate(mapRef: any?) -> boolean
```

Release a map. The last holder to release it takes its controls out
of the live set and disconnects everything subscribed through it; an
earlier one just drops its own claim, so a map two components share
survives one of them going away.

**Parameters**

- `mapRef` `any` _(optional)_ — The inputMap asset ref.

**Returns** `boolean` — True when the map was live.

```lua
self.inputMap:deactivate()
```

## typed/builtin//modules/zinput/scheme/M/declaredClasses {#typed-builtin-modules-zinput-scheme-m-declaredclasses}

```lua
M.declaredClasses(record: any?) -> { string }
```

Which device classes a control declares bindings for, in the order
the tick consults them. A control with no binding for the class a player
is driving reads nothing from that class no matter what they do.

**Parameters**

- `record` `any` _(optional)_ — The binding record.

**Returns** `{ string }` — Array of class names from `kbm` / `gamepad` / `touch`.

```lua
local classes = Zin.scheme.declaredClasses(record)
```

## typed/builtin//modules/zinput/scheme/M/drivingClass {#typed-builtin-modules-zinput-scheme-m-drivingclass}

```lua
M.drivingClass(record: any?) -> string?
```

Which device class is currently satisfying a binding, or nil when
nothing is. Used to tag what `fired` reports.

**Parameters**

- `record` `any` _(optional)_ — The binding record.

**Returns** `string?` — The class name, or nil.

```lua
local class = Zin.scheme.drivingClass(record)
```

## typed/builtin//modules/zinput/scheme/M/entriesFor {#typed-builtin-modules-zinput-scheme-m-entriesfor}

```lua
M.entriesFor(name: string) -> { any }
```

Every live map that declares a named control, with the map's own
record and the control's dispatch state. The lookup behind per-control
questions: a name can be declared by more than one live map, and this
answers with all of them in activation order.

**Parameters**

- `name` `string` — The control name.

**Returns** `{ any }` — Array of `{ map, group, guid, record, state, suppressedBy }`.

```lua
local entries = Zin.scheme.entriesFor("look")
```

## typed/builtin//modules/zinput/scheme/M/fired {#typed-builtin-modules-zinput-scheme-m-fired}

```lua
M.fired(peek: boolean?) -> { any }
```

Every control that fired since this last cleared, with how many
times and which device classes drove it. Reading CLEARS the record
unless `peek` is true, so two calls around an action answer "did that
input reach the game" without a previous test's results bleeding in.

**Parameters**

- `peek` `boolean` _(optional)_ — Read without clearing.

**Returns** `{ any }` — Array of `{ name, map, count, classes }`, sorted by name.

```lua
local fired = Zin.scheme.fired()
```

## typed/builtin//modules/zinput/scheme/M/generation {#typed-builtin-modules-zinput-scheme-m-generation}

```lua
M.generation() -> number
```

A counter that changes whenever the live set of maps changes.
Cache a view of the live bindings against it rather than rebuilding
one every frame.

**Returns** `number` — The current generation.

```lua
if gen ~= Zin.scheme.generation() then rebuild() end
```

## typed/builtin//modules/zinput/scheme/M/has {#typed-builtin-modules-zinput-scheme-m-has}

```lua
M.has(name: string) -> boolean
```

Whether a named control is live in any activated map.

**Parameters**

- `name` `string` — The binding name.

**Returns** `boolean` — True when some live map declares it.

```lua
if Zin.scheme.has("jump") then ... end
```

## typed/builtin//modules/zinput/scheme/M/lastFrame {#typed-builtin-modules-zinput-scheme-m-lastframe}

```lua
M.lastFrame() -> { any }
```

What every live control did on the most recent tick: its value, whether
it was active, whether that reached a subscriber, how many subscribers it
has, and the tick's own answers about context, suppression and its gate.

Rebuilt whole each tick and read without consuming, so any number of
observers in the same frame all see the same answers. The window is ONE
tick — the most recent one — rather than a sum since anything last read.

**Returns** `{ any }` — Array of `{ name, map, group, kind, label, context, value, active, delivered, subscribers, suppressedBy, inContext, heldOnArrival, gateReason, gateError }`, in evaluation order.

```lua
for _, c in ipairs(Zin.scheme.lastFrame()) do print(c.name, c.active) end
```

## typed/builtin//modules/zinput/scheme/M/live {#typed-builtin-modules-zinput-scheme-m-live}

```lua
M.live() -> { any }
```

Every live map, in activation order:
`{ guid, name, group, suppresses, suppressedBy, pointerLock, bindings }`
where `bindings` names the controls it contributes, `suppressedBy` names
the map standing this one down, if any, and `pointerLock` says whether it
takes the cursor while the world runs. What a debug surface lists,
and what tells an author why two sticks are on screen — or why the
controls they activated answer to nothing.

**Returns** `{ any }` — Array of live-map records.

```lua
for _, m in ipairs(Zin.scheme.live()) do print(m.name) end
```

## typed/builtin//modules/zinput/scheme/M/liveCount {#typed-builtin-modules-zinput-scheme-m-livecount}

```lua
M.liveCount() -> number
```

How many maps are live right now.

**Returns** `number` — The count of activated maps.

```lua
if Zin.scheme.liveCount() == 0 then ... end
```

## typed/builtin//modules/zinput/scheme/M/neutralFor {#typed-builtin-modules-zinput-scheme-m-neutralfor}

```lua
M.neutralFor(kind: string) -> any
```

The neutral value for a control kind: `false` for a button, `0` for
an `axis1`, `{ x = 0, y = 0 }` for an `axis2`. What a control reports
when it is not delivering.

**Parameters**

- `kind` `string` — The control kind.

**Returns** `any` — The kind's neutral value.

```lua
local rest = Zin.scheme.neutralFor("axis2")
```

## typed/builtin//modules/zinput/scheme/M/recording {#typed-builtin-modules-zinput-scheme-m-recording}

```lua
M.recording() -> boolean
```

Whether the tick is keeping a per-control record of what it did.
`Zin.tick` turns it on while something is observing the input layer and
off again when nothing is.

**Returns** `boolean` — Whether the record is being built.

```lua
if Zin.scheme.recording() then ... end
```

## typed/builtin//modules/zinput/scheme/M/setRecording {#typed-builtin-modules-zinput-scheme-m-setrecording}

```lua
M.setRecording(on: boolean?)
```

Keep — or stop keeping — a per-control record of what each tick did.
A tick that is not recording still dispatches and still reports its
cost; it only stops writing down each control's outcome, which
`Zin.observe` can resolve again from live state.

**Parameters**

- `on` `boolean` _(optional)_ — Record (the default) or stop recording.

```lua
Zin.scheme.setRecording(true)
```

## typed/builtin//modules/zinput/scheme/M/subscriberCount {#typed-builtin-modules-zinput-scheme-m-subscribercount}

```lua
M.subscriberCount(name: string) -> number
```

How many subscribers a named control currently holds, summed over
every live map that declares it.

A control can be live, valid and firing with nobody listening. Drawing
a button for one offers a player something that cannot do anything —
which is the shape of every on-screen control that has ever been
reported as doing nothing.

**Parameters**

- `name` `string` — The binding name.

**Returns** `number` — The number of live subscribers.

```lua
if Zin.scheme.subscriberCount("jump") == 0 then ... end
```

## typed/builtin//modules/zinput/scheme/M/subscriberEpoch {#typed-builtin-modules-zinput-scheme-m-subscriberepoch}

```lua
M.subscriberEpoch() -> number
```

Total subscribers across every live control.

Which controls are HEARD changes without the live set changing at all —
a component activates a map and subscribes a moment later, or drops its
last listener while staying awake. A consumer that caches a view of the
live set by `generation` alone never sees either, so this is the second
half of that cache key.

**Returns** `number` — The summed subscriber count.

```lua
if gen ~= Zin.scheme.generation() or subs ~= Zin.scheme.subscriberEpoch() then rebuild() end
```

## typed/builtin//modules/zinput/scheme/M/suppressed {#typed-builtin-modules-zinput-scheme-m-suppressed}

```lua
M.suppressed() -> { [string]: string }
```

Which groups are currently standing down, and the map that put each
one down: `{ [group] = mapName }`.

The answer to "the button is gone and the control is live" — a control
in a suppressed group reads nothing and draws nothing until whatever
suppressed it releases.

**Returns** `{ [string]: string }` — A table of group name → the name of the map suppressing it.

```lua
local down = Zin.scheme.suppressed()
```

## typed/builtin//modules/zinput/scheme/M/valueIsActive {#typed-builtin-modules-zinput-scheme-m-valueisactive}

```lua
M.valueIsActive(kind: string, value: any?) -> boolean
```

Whether a value of the given kind is anything other than that kind's
neutral — a held button, an axis off centre.

**Parameters**

- `kind` `string` — The control kind.
- `value` `any` _(optional)_ — The value to test.

**Returns** `boolean` — Whether the value counts as active.

```lua
if Zin.scheme.valueIsActive("axis1", v) then ... end
```

## typed/builtin//modules/zinput/state/M/_observeEvent {#typed-builtin-modules-zinput-state-m-observeevent}

```lua
M._observeEvent(ev: any?)
```

Internal: per-event observer called by the Zin.tick coordinator.
Updates held-time state for keys and mouse buttons. Not part of the
public contract — exposed on `M` so the tick coordinator can wire it.

**Parameters**

- `ev` `any` _(optional)_ — The raw input event record (kind, code, button, repeat, …).

```lua
Zin.state._observeEvent(ev)
```

## typed/builtin//modules/zinput/state/M/_reset {#typed-builtin-modules-zinput-state-m-reset}

```lua
M._reset()
```

Test-only: clear all held-time / repeat state. Public so test
suites can isolate cases.

```lua
Zin.state._reset()
```

## typed/builtin//modules/zinput/state/M/_setEnsureLiveFn {#typed-builtin-modules-zinput-state-m-setensurelivefn}

```lua
M._setEnsureLiveFn(fn: () -> ())
```

Internal: wire the liveness hook. Called once at module-load
time from `zinput/init.luau`.

**Parameters**

- `fn` `() -> ()` — The hook invoked on every read below.

```lua
M._setEnsureLiveFn(ensureInputLive)
```

## typed/builtin//modules/zinput/state/M/gamepadCapable {#typed-builtin-modules-zinput-state-m-gamepadcapable}

```lua
M.gamepadCapable() -> boolean
```

Has this session ever seen a gamepad? Latched by the first
connection, so unplugging a pad does not flip a scheme's prompts back
to keyboard glyphs on a cable knock.

**Returns** `boolean` — True once a pad has connected.

```lua
if Zin.state.gamepadCapable() then ... end
```

## typed/builtin//modules/zinput/state/M/gamepads {#typed-builtin-modules-zinput-state-m-gamepads}

```lua
M.gamepads() -> { any }
```

Every connected gamepad this frame, in slot order. Each entry is
`{ slot, name, buttons, buttons_pressed, buttons_released, axes,
simulated }` — the button fields are arrays of canonical names, `axes`
a map of canonical axis name to number. Empty when nothing is
connected.

**Returns** `{ any }` — Array of pad records.

```lua
for _, pad in ipairs(Zin.state.gamepads()) do print(pad.name) end
```

## typed/builtin//modules/zinput/state/M/get {#typed-builtin-modules-zinput-state-m-get}

```lua
M.get() -> Snapshot
```

Get the full snapshot table for this frame. Empty table if
`__zero_input.snapshot` is missing or returns non-table.

## typed/builtin//modules/zinput/state/M/getRepeatDefaults {#typed-builtin-modules-zinput-state-m-getrepeatdefaults}

```lua
M.getRepeatDefaults() -> RepeatDefaults
```

Read the current synthetic-repeat defaults. Returned table is a copy.

**Returns** `RepeatDefaults` — A fresh `{ delay, period }` table.

```lua
local d = Zin.state.getRepeatDefaults()
```

## typed/builtin//modules/zinput/state/M/keyDown {#typed-builtin-modules-zinput-state-m-keydown}

```lua
M.keyDown(key: string) -> boolean
```

Is `key` currently held? True on EVERY frame the key is down —
the level, not the edge. Use it for continuous input: thrust while
W is held, hold-to-charge, camera pan. For an action that should
happen once per press (fire, jump, pause, undo) bind it and read
`Zin.actions.pressed(name)`, which fires on the press edge only.

**Parameters**

- `key` `string` — Web-style key code (e.g. `"KeyW"`, `"Space"`).

**Returns** `boolean` — `true` when the key is held this frame.

```lua
if Zin.state.keyDown("KeyW") then ... end  -- thrust while held
```

## typed/builtin//modules/zinput/state/M/keyDownReal {#typed-builtin-modules-zinput-state-m-keydownreal}

```lua
M.keyDownReal(key: string) -> boolean
```

Is `key` held by a real press — held, and NOT (also) held by the
input-emulation floor? The floor merges emulated holds into `keys`
so `keyDown` can't tell them apart; this checks `keys` minus
`keys_emulated`.

**Parameters**

- `key` `string` — Web-style key code (e.g. `"KeyW"`, `"Space"`).

**Returns** `boolean` — `true` when the key is held this frame by a real press only.

```lua
if Zin.state.keyDownReal("KeyW") then ... end
```

## typed/builtin//modules/zinput/state/M/keyHeldTime {#typed-builtin-modules-zinput-state-m-keyheldtime}

```lua
M.keyHeldTime(code: string) -> number?
```

Seconds the given key has been held since its most recent press,
or `nil` if the key isn't currently held. Wall-clock based,
updated as events arrive via the tick.

**Parameters**

- `code` `string` — Web-style key code.

**Returns** `number?` — Held duration in seconds, or `nil`.

```lua
local t = Zin.state.keyHeldTime("KeyW")
```

## typed/builtin//modules/zinput/state/M/keyPressed {#typed-builtin-modules-zinput-state-m-keypressed}

```lua
M.keyPressed(key: string) -> boolean
```

Was `key` just pressed this frame?

**Parameters**

- `key` `string` — Web-style key code.

**Returns** `boolean` — `true` on the press frame only.

```lua
if Zin.state.keyPressed("Space") then ... end
```

## typed/builtin//modules/zinput/state/M/keyReleased {#typed-builtin-modules-zinput-state-m-keyreleased}

```lua
M.keyReleased(key: string) -> boolean
```

Was `key` just released this frame?

**Parameters**

- `key` `string` — Web-style key code.

**Returns** `boolean` — `true` on the release frame only.

```lua
if Zin.state.keyReleased("KeyW") then ... end
```

## typed/builtin//modules/zinput/state/M/keyRepeatFired {#typed-builtin-modules-zinput-state-m-keyrepeatfired}

```lua
M.keyRepeatFired(code: string, opts: RepeatOpts?) -> boolean
```

Should a synthetic key-repeat fire this frame for `code`?
Returns `true` once per `period`, beginning `delay` seconds after the
initial press. Distinct from the `repeat` field on OS-level `key.down`
events (which surfaces hardware autorepeat — see `Zin.events.on`).
Each call advances per-key state, so call once per frame per logical
consumer to avoid "consuming" the repeat early.

**Parameters**

- `code` `string` — Web-style key code.
- `opts` `RepeatOpts` _(optional)_ — Optional per-call `{ delay, period }` overrides; falls back to `getRepeatDefaults()`.

**Returns** `boolean` — `true` on each synthetic-repeat tick.

```lua
if Zin.state.keyRepeatFired("KeyW") then ... end
```

## typed/builtin//modules/zinput/state/M/mouseButtonDown {#typed-builtin-modules-zinput-state-m-mousebuttondown}

```lua
M.mouseButtonDown(button: (number | string)?) -> boolean
```

Is mouse button held? Accepts the 0-based index or a name —
`0`/`"left"`, `1`/`"right"`, `2`/`"middle"`.

**Parameters**

- `button` `(number | string)` _(optional)_ — Button index or name (default 0 = left).

**Returns** `boolean` — `true` when that button is currently held.

```lua
if Zin.state.mouseButtonDown(0) then ... end
if Zin.state.mouseButtonDown("left") then ... end
```

## typed/builtin//modules/zinput/state/M/mouseButtonHeldTime {#typed-builtin-modules-zinput-state-m-mousebuttonheldtime}

```lua
M.mouseButtonHeldTime(button: (number | string)?) -> number?
```

Seconds the given mouse button has been held, or `nil`. Accepts the
0-based index or a name — `0`/`"left"`, `1`/`"right"`, `2`/`"middle"`.

**Parameters**

- `button` `(number | string)` _(optional)_ — Button index or name (default 0 = left).

**Returns** `number?` — Held duration in seconds, or `nil`.

```lua
local t = Zin.state.mouseButtonHeldTime("left")
```

## typed/builtin//modules/zinput/state/M/mouseButtonPressed {#typed-builtin-modules-zinput-state-m-mousebuttonpressed}

```lua
M.mouseButtonPressed(button: (number | string)?) -> boolean
```

Was mouse button just pressed this frame? Accepts the 0-based index
or a name — `0`/`"left"`, `1`/`"right"`, `2`/`"middle"`.

**Parameters**

- `button` `(number | string)` _(optional)_ — Button index or name (default 0 = left).

**Returns** `boolean` — `true` on the press frame only.

```lua
if Zin.state.mouseButtonPressed("left") then ... end
```

## typed/builtin//modules/zinput/state/M/mouseButtonReleased {#typed-builtin-modules-zinput-state-m-mousebuttonreleased}

```lua
M.mouseButtonReleased(button: (number | string)?) -> boolean
```

Was mouse button just released this frame? Accepts the 0-based index
or a name — `0`/`"left"`, `1`/`"right"`, `2`/`"middle"`.

**Parameters**

- `button` `(number | string)` _(optional)_ — Button index or name (default 0 = left).

**Returns** `boolean` — `true` on the release frame only.

```lua
if Zin.state.mouseButtonReleased("right") then ... end
```

## typed/builtin//modules/zinput/state/M/mouseDelta {#typed-builtin-modules-zinput-state-m-mousedelta}

```lua
M.mouseDelta() -> (number, number)
```

Mouse delta since last frame. Returns `(dx, dy)` as two numbers.

**Returns** `(number, number)` — Two numbers — dx, dy. Both default to `0.0` when unavailable.

```lua
local dx, dy = Zin.state.mouseDelta()
```

## typed/builtin//modules/zinput/state/M/mouseInViewport {#typed-builtin-modules-zinput-state-m-mouseinviewport}

```lua
M.mouseInViewport() -> boolean
```

True while the mouse sits inside the active scene viewport's rect
(always true when no viewport widget is on screen). Reads beside
`mousePosition()`, which is viewport-local when a viewport is active.

**Returns** `boolean` — Whether the pointer is inside the scene viewport.

```lua
if Zin.state.mouseInViewport() and Zin.state.mouseButtonPressed(0) then ... end
```

## typed/builtin//modules/zinput/state/M/mousePosition {#typed-builtin-modules-zinput-state-m-mouseposition}

```lua
M.mousePosition() -> (number, number)
```

Current mouse position. Returns `(x, y)` as two numbers.

**Returns** `(number, number)` — Two numbers — x, y. Both default to `0.0` when unavailable.

```lua
local x, y = Zin.state.mousePosition()
```

## typed/builtin//modules/zinput/state/M/padAxis {#typed-builtin-modules-zinput-state-m-padaxis}

```lua
M.padAxis(axis: string, slot: number?) -> number
```

A canonical pad axis's value. Stick axes run -1..1 with y
screen-down positive (matching the touch stick); trigger axes run
0..1. With no `slot` the reading furthest from rest across every pad
wins, so a second pad resting at zero never cancels the one being
used.

**Parameters**

- `axis` `string` — Canonical name: left_stick_x, left_stick_y, right_stick_x,
right_stick_y, left_trigger, right_trigger.
- `slot` `number` _(optional)_ — Pad slot, or nil for any pad.

**Returns** `number` — The axis value, 0 when no pad reports it.

```lua
local x = Zin.state.padAxis("left_stick_x")
```

## typed/builtin//modules/zinput/state/M/padDown {#typed-builtin-modules-zinput-state-m-paddown}

```lua
M.padDown(button: string, slot: number?) -> boolean
```

Is a canonical pad button held this frame? With no `slot`, ANY
connected pad holding it counts — which is what a single-player scheme
wants, since whichever controller the person picked up drives the
action with no pairing step. Name a slot for local multiplayer.

**Parameters**

- `button` `string` — Canonical name: south, east, west, north, left_shoulder,
right_shoulder, left_trigger, right_trigger, left_stick, right_stick,
select, start, guide, dpad_up, dpad_down, dpad_left, dpad_right.
- `slot` `number` _(optional)_ — Pad slot, or nil for any pad.

**Returns** `boolean` — True when held.

```lua
if Zin.state.padDown("south") then ... end
```

## typed/builtin//modules/zinput/state/M/padPressed {#typed-builtin-modules-zinput-state-m-padpressed}

```lua
M.padPressed(button: string, slot: number?) -> boolean
```

Did a canonical pad button go down this frame? Same slot rule as
`padDown`.

**Parameters**

- `button` `string` — Canonical button name.
- `slot` `number` _(optional)_ — Pad slot, or nil for any pad.

**Returns** `boolean` — True on the press frame.

```lua
if Zin.state.padPressed("start") then ... end
```

## typed/builtin//modules/zinput/state/M/padReleased {#typed-builtin-modules-zinput-state-m-padreleased}

```lua
M.padReleased(button: string, slot: number?) -> boolean
```

Did a canonical pad button come up this frame? Same slot rule as
`padDown`.

**Parameters**

- `button` `string` — Canonical button name.
- `slot` `number` _(optional)_ — Pad slot, or nil for any pad.

**Returns** `boolean` — True on the release frame.

```lua
if Zin.state.padReleased("south") then ... end
```

## typed/builtin//modules/zinput/state/M/pointerLocked {#typed-builtin-modules-zinput-state-m-pointerlocked}

```lua
M.pointerLocked() -> boolean
```

Is the pointer currently locked?

**Returns** `boolean` — `true` when the pointer is locked.

```lua
if Zin.state.pointerLocked() then ... end
```

## typed/builtin//modules/zinput/state/M/sceneContextActive {#typed-builtin-modules-zinput-state-m-scenecontextactive}

```lua
M.sceneContextActive() -> boolean
```

True while the SCENE is the active input context — the last pointer
gesture began on a scene viewport (or pointer lock holds), so continuous
scene input (camera fly, buttons, wheel) belongs to the scene. A gesture
that begins on a widget, or a text field taking the caret, hands the
context to the UI until the scene is clicked again. With no viewport
widget on screen the scene is the whole surface and this is always true.

**Returns** `boolean` — Whether the scene holds the active input context this frame.

```lua
if Zin.state.sceneContextActive() then cam:fly(dt) end
```

## typed/builtin//modules/zinput/state/M/scrollDelta {#typed-builtin-modules-zinput-state-m-scrolldelta}

```lua
M.scrollDelta() -> number
```

Mouse wheel delta this frame.

**Returns** `number` — The signed scroll delta, or `0.0` when unavailable.

```lua
local dy = Zin.state.scrollDelta()
```

## typed/builtin//modules/zinput/state/M/setRepeatDefaults {#typed-builtin-modules-zinput-state-m-setrepeatdefaults}

```lua
M.setRepeatDefaults(opts: RepeatOpts?)
```

Set the global default delay / period for synthetic key repeat.
Either field is optional; omitted fields keep their current value.
Default: delay = 0.4 s, period = 0.1 s.

**Parameters**

- `opts` `RepeatOpts` _(optional)_ — Partial overrides for `delay` / `period` (seconds).

```lua
Zin.state.setRepeatDefaults({ delay = 0.5, period = 0.05 })
```

## typed/builtin//modules/zinput/state/M/uiWantsKeyboard {#typed-builtin-modules-zinput-state-m-uiwantskeyboard}

```lua
M.uiWantsKeyboard() -> boolean
```

True while the UI layer holds keyboard focus — a text field has the
caret, so keys reaching the window belong to it. Travels separately
from pointer focus: a caret in a field takes keys while the cursor sits
over the viewport, and a hovered panel takes clicks while no field has
the caret.

**Returns** `boolean` — Whether the UI layer holds keyboard focus.

```lua
if not Zin.state.uiWantsKeyboard() then ... end
```

## typed/builtin//modules/zinput/state/M/uiWantsPointer {#typed-builtin-modules-zinput-state-m-uiwantspointer}

```lua
M.uiWantsPointer() -> boolean
```

True while the UI layer holds pointer focus — a widget is under the
cursor, so what the pointer produces belongs to it. Travels separately
from keyboard focus: a hovered panel takes clicks while no field has the
caret, and a caret in a field takes keys while the cursor sits over the
viewport. Useful for gating game-side input when a UI is hovered.

**Returns** `boolean` — `true` when the UI has pointer focus this frame.

```lua
if not Zin.state.uiWantsPointer() then ... end
```

## typed/builtin//modules/zinput/surface/M/_beginFrame {#typed-builtin-modules-zinput-surface-m-beginframe}

```lua
M._beginFrame()
```

Internal: clear this frame's per-class flags. On the first tick
of the session, also captures the capability default as the
reported class the change signal compares against. Called by the
Zin.tick coordinator on the first tick of each engine frame.

```lua
Zin.surface._beginFrame()
```

## typed/builtin//modules/zinput/surface/M/_observeEvent {#typed-builtin-modules-zinput-surface-m-observeevent}

```lua
M._observeEvent(ev: any?)
```

Internal: per-event observer called by the Zin.tick coordinator.
Collects which device classes produced events this frame.

**Parameters**

- `ev` `any` _(optional)_ — The raw input event record.

```lua
Zin.surface._observeEvent(ev)
```

## typed/builtin//modules/zinput/surface/M/_reset {#typed-builtin-modules-zinput-surface-m-reset}

```lua
M._reset()
```

Test-only: clear resolution state and subscriptions. Suite
isolation; not part of the public contract.

```lua
Zin.surface._reset()
```

## typed/builtin//modules/zinput/surface/M/_resolveFrame {#typed-builtin-modules-zinput-surface-m-resolveframe}

```lua
M._resolveFrame()
```

Internal: resolve this frame's class and fire onChange on a
flip. Touch wins a frame containing any touch event (the primary
contact's projected mouse events never mask their own touch).

```lua
Zin.surface._resolveFrame()
```

## typed/builtin//modules/zinput/surface/M/_settled {#typed-builtin-modules-zinput-surface-m-settled}

```lua
M._settled() -> boolean
```

Internal: whether this frame carried no class-bearing device
event. The tick's quiescence gate reads it.

**Returns** `boolean` — true when nothing arrived to resolve a surface class from.

```lua
if Zin.surface._settled() then ... end
```

## typed/builtin//modules/zinput/surface/M/current {#typed-builtin-modules-zinput-surface-m-current}

```lua
M.current() -> string
```

The active input-surface class: `"touch"`, `"kbm"` or
`"gamepad"`. A forced class wins; then event history; before any
input it defaults by capability (touch sessions start as "touch").

**Returns** `string` — The surface class string.

```lua
if Zin.surface.current() == "touch" then ... end
```

## typed/builtin//modules/zinput/surface/M/force {#typed-builtin-modules-zinput-surface-m-force}

```lua
M.force(class: string?) -> string
```

Pin the surface class, or hand control back to real input.

This is how a desktop session is checked as a phone: forcing
`"touch"` mounts the on-screen controls exactly as a device would, so
the layout can be read and its buttons tapped. Nothing else about the
session changes — the pin decides which class is reported, and every
consumer that branches on it follows.

**Parameters**

- `class` `string` _(optional)_ — `"kbm"` | `"touch"` | `"gamepad"`, or `"auto"` / nil to
release the pin.

**Returns** `string` — The class in effect after the call.

```lua
Zin.surface.force("touch")
Zin.surface.force("auto")
```

## typed/builtin//modules/zinput/surface/M/forced {#typed-builtin-modules-zinput-surface-m-forced}

```lua
M.forced() -> string?
```

Whether the class is currently pinned by `force` rather than
resolved from real input.

**Returns** `string?` — The pinned class, or nil.

```lua
if Zin.surface.forced() ~= nil then ... end
```

## typed/builtin//modules/zinput/surface/M/off {#typed-builtin-modules-zinput-surface-m-off}

```lua
M.off(handle: number) -> boolean
```

Unsubscribe an onChange handle. Returns true when removed.

**Parameters**

- `handle` `number` — The handle from onChange.

**Returns** `boolean` — Whether a subscription was removed.

```lua
Zin.surface.off(h)
```

## typed/builtin//modules/zinput/surface/M/onChange {#typed-builtin-modules-zinput-surface-m-onchange}

```lua
M.onChange(fn: (string, string?) -> ()) -> number
```

Subscribe to surface-class changes. `fn(now, prev)` fires from
the tick pipeline on the frame the class flips; `prev` is the
previously reported class (the first-tick capability default when
no event had resolved yet).

**Parameters**

- `fn` `(string, string?) -> ()` — The callback.

**Returns** `number` — A numeric handle for `Zin.surface.off`.

```lua
local h = Zin.surface.onChange(function(now) print(now) end)
```

## typed/builtin//modules/zinput/test/M/clickMouse {#typed-builtin-modules-zinput-test-m-clickmouse}

```lua
M.clickMouse(opts: ClickOpts?)
```

Press + release a mouse button. `opts.button` (default 0);
`opts.x` / `opts.y` optionally move the cursor before pressing;
`opts.duration` holds the button for that many seconds before
releasing. Does NOT tick — call `Zin.tick(dt)` between
`clickMouse` and your assertion if you need binding-action handlers
to fire.

**Parameters**

- `opts` `ClickOpts` _(optional)_ — Click options: `{ button, x, y, duration }`.

```lua
Zin.test.clickMouse({ x = 100, y = 200 })
```

## typed/builtin//modules/zinput/test/M/connectPad {#typed-builtin-modules-zinput-test-m-connectpad}

```lua
M.connectPad(name: string?) -> number
```

Connect a simulated pad and return the slot it took. `name` is the
device name the pad reports, which decides the button legends a
prompt draws — pass a real product name to check a scheme's prompts
on that family.

**Parameters**

- `name` `string` _(optional)_ — Device name; "Simulated Gamepad" when omitted.

**Returns** `number` — The slot the pad occupies.

```lua
Zin.test.connectPad("Xbox Wireless Controller")
```

## typed/builtin//modules/zinput/test/M/disconnectPad {#typed-builtin-modules-zinput-test-m-disconnectpad}

```lua
M.disconnectPad(slot: number?)
```

Disconnect the pad in `slot`. Anything it still held is released
first, so a held control ends rather than sticking.

**Parameters**

- `slot` `number` _(optional)_ — The pad slot; 0 when omitted.

```lua
Zin.test.disconnectPad(0)
```

## typed/builtin//modules/zinput/test/M/dragLook {#typed-builtin-modules-zinput-test-m-draglook}

```lua
M.dragLook(dx: number, dy: number, steps: number?)
```

Drag across the on-screen look zone by `(dx, dy)` pixels, spread
over `steps` frames so the per-frame deltas a look binding reads are
real rather than one impossible jump.

**Parameters**

- `dx` `number` — Total horizontal travel in pixels.
- `dy` `number` — Total vertical travel in pixels.
- `steps` `number` _(optional)_ — Frames to spread it over; 8 when omitted.

```lua
Zin.test.dragLook(200, 0)
```

## typed/builtin//modules/zinput/test/M/engage {#typed-builtin-modules-zinput-test-m-engage}

```lua
M.engage()
```

Explicit opt-out for suites/harnesses that own their own tick
cadence but haven't injected synthetic input yet — call before the
first `Zin.state` / `Zin.actions` / `Zin.axes` read so the liveness
auto-arm doesn't start `Zin.autoTick` underneath the harness.

```lua
Zin.test.engage()
```

## typed/builtin//modules/zinput/test/M/engaged {#typed-builtin-modules-zinput-test-m-engaged}

```lua
M.engaged() -> boolean
```

True once any synthetic test-input helper (`pressKey`,
`touchStart`, etc.) or `engage()` has run this VM. Read by the
liveness auto-arm so a test/harness VM keeps explicit control of
`Zin.tick` cadence instead of the first real input read starting
`Zin.autoTick`.

**Returns** `boolean` — Whether this VM has engaged synthetic test input.

```lua
if Zin.test.engaged() then ... end
```

## typed/builtin//modules/zinput/test/M/focusScene {#typed-builtin-modules-zinput-test-m-focusscene}

```lua
M.focusScene()
```

Hand continuous pointer input to the scene: the pointer moves to the
middle of the scene's viewport and the scene becomes the active input
context, which is where a fresh VM's first simulated input already
finds it and where `releaseAll` puts it back. While a viewport widget
shares the screen with editor panels, the scene reads buttons, motion
and scroll only as the active context, and a gesture decides the
context by where it begins — so a test that has been clicking widgets
calls this before driving the scene again. Yields one frame.

```lua
Zin.test.focusScene()
```

## typed/builtin//modules/zinput/test/M/held {#typed-builtin-modules-zinput-test-m-held}

```lua
M.held() -> Held
```

Everything the session is holding down right now, across every
device class: keys, mouse buttons, touch contacts, the on-screen
stick, and connected pads with the buttons they hold. `atRest` is
true when it holds nothing. `keysEmulated` is the subset of `keys`
the input-emulation floor holds, the same split
`Zin.state.keyDownReal` reads.

Read from the engine's live input state, so a hold whose caller is
gone — a driver task cancelled mid-press, a macro that errored — is
still reported and can still be let go. `releaseAll` lets go of
exactly what this reports.

**Returns** `Held` — `{ atRest, keys, keysEmulated, mouse, contacts, stick, pads }`.

```lua
local h = Zin.test.held(); if not h.atRest then Zin.test.releaseAll() end
```

## typed/builtin//modules/zinput/test/M/moveMouse {#typed-builtin-modules-zinput-test-m-movemouse}

```lua
M.moveMouse(x: number, y: number)
```

Move the cursor to a screen position. Sets the absolute position;
the engine computes `mouse_delta` as `new - old`, so successive
calls produce meaningful deltas for orbit / look bindings.

**Parameters**

- `x` `number` — Absolute screen x coordinate.
- `y` `number` — Absolute screen y coordinate.

```lua
Zin.test.moveMouse(100, 200)
```

## typed/builtin//modules/zinput/test/M/moveMouseBy {#typed-builtin-modules-zinput-test-m-movemouseby}

```lua
M.moveMouseBy(dx: number, dy: number)
```

Move the cursor by a relative motion, the way a mouse device
reports one: the motion lands in this frame's `mouse_delta` and the
position advances by the same amount. The same `(dx, dy)` repeated
keeps producing look movement, so an axis can be held or steered by
a controller issuing a correction each tick.

**Parameters**

- `dx` `number` — Horizontal motion in screen pixels.
- `dy` `number` — Vertical motion in screen pixels.

```lua
Zin.test.moveMouseBy(0, 140)
```

## typed/builtin//modules/zinput/test/M/padDown {#typed-builtin-modules-zinput-test-m-paddown}

```lua
M.padDown(button: string, slot: number?)
```

Push a canonical pad button down and leave it held.

**Parameters**

- `button` `string` — Canonical button name.
- `slot` `number` _(optional)_ — The pad slot; 0 when omitted.

```lua
Zin.test.padDown("south")
```

## typed/builtin//modules/zinput/test/M/padPress {#typed-builtin-modules-zinput-test-m-padpress}

```lua
M.padPress(button: string, duration: number?, slot: number?)
```

Press a canonical pad button — down, optionally held, then up.

**Parameters**

- `button` `string` — Canonical button name.
- `duration` `number` _(optional)_ — Hold seconds; an instant press when omitted.
- `slot` `number` _(optional)_ — The pad slot; 0 when omitted.

```lua
Zin.test.padPress("south")
```

## typed/builtin//modules/zinput/test/M/padStick {#typed-builtin-modules-zinput-test-m-padstick}

```lua
M.padStick(stick: string, x: number, y: number, duration: number?, slot: number?)
```

Push a thumbstick to `(x, y)`, each -1..1 with y screen-down
positive. Holds until pushed back to zero, or for `duration` seconds.

**Parameters**

- `stick` `string` — "left" or "right".
- `x` `number` — Deflection -1..1.
- `y` `number` — Deflection -1..1, screen-down positive.
- `duration` `number` _(optional)_ — Hold seconds; left deflected when omitted.
- `slot` `number` _(optional)_ — The pad slot; 0 when omitted.

```lua
Zin.test.padStick("left", 0, -1, 2)
```

## typed/builtin//modules/zinput/test/M/padTrigger {#typed-builtin-modules-zinput-test-m-padtrigger}

```lua
M.padTrigger(trigger: string, value: number, duration: number?, slot: number?)
```

Squeeze a trigger to `value`, 0..1. Past half throw the trigger's
digital button latches too, so a scheme binding either the analog
travel or the button sees this.

**Parameters**

- `trigger` `string` — "left" or "right".
- `value` `number` — Travel 0..1.
- `duration` `number` _(optional)_ — Hold seconds; left squeezed when omitted.
- `slot` `number` _(optional)_ — The pad slot; 0 when omitted.

```lua
Zin.test.padTrigger("right", 1)
```

## typed/builtin//modules/zinput/test/M/padUp {#typed-builtin-modules-zinput-test-m-padup}

```lua
M.padUp(button: string, slot: number?)
```

Release a canonical pad button.

**Parameters**

- `button` `string` — Canonical button name.
- `slot` `number` _(optional)_ — The pad slot; 0 when omitted.

```lua
Zin.test.padUp("south")
```

## typed/builtin//modules/zinput/test/M/pinch {#typed-builtin-modules-zinput-test-m-pinch}

```lua
M.pinch(amount: number, steps: number?)
```

Pinch two fingers together (negative `amount`) or spread them
apart (positive) by that many pixels, over `steps` frames.

**Parameters**

- `amount` `number` — Pixels; negative pinches, positive spreads.
- `steps` `number` _(optional)_ — Frames to spread it over; 8 when omitted.

```lua
Zin.test.pinch(150)
```

## typed/builtin//modules/zinput/test/M/pressKey {#typed-builtin-modules-zinput-test-m-presskey}

```lua
M.pressKey(code: string)
```

Hold a key DOWN and leave it held until `releaseKey`. Returns
inside the frame where `keys_pressed` contains `code`, so
`Zin.actions.pressed` polls and `onPressed` handlers both fire as
the call returns. A second `pressKey` on a key that is still held
produces no new press edge — release first, or use `tapKey` for a
full press+release.

**Parameters**

- `code` `string` — Web-style key code (e.g. `"KeyM"`, `"Space"`).

```lua
Zin.test.pressKey("KeyM"); Zin.test.releaseKey("KeyM")
```

## typed/builtin//modules/zinput/test/M/pressMouse {#typed-builtin-modules-zinput-test-m-pressmouse}

```lua
M.pressMouse(button: (number | string)?)
```

Simulate a mouse button press. Accepts a 0-based index OR a
case-insensitive name (`"left"`/`"right"`/`"middle"`, matching
`Zin.bindings.mouse`). Default: left.

**Parameters**

- `button` `(number | string)` _(optional)_ — Optional button index or name (default 0 = left).

```lua
Zin.test.pressMouse()        -- left
Zin.test.pressMouse(1)       -- right
Zin.test.pressMouse("right") -- right
```

## typed/builtin//modules/zinput/test/M/pushStick {#typed-builtin-modules-zinput-test-m-pushstick}

```lua
M.pushStick(x: number, y: number, duration: number?) -> number?
```

Push the on-screen movement stick to `(x, y)`, each -1..1 with y
screen-down positive. Lands a contact in the stick's zone and lets
the overlay route it, so the deflection is one a player could
actually produce.

**Parameters**

- `x` `number` — Deflection -1..1.
- `y` `number` — Deflection -1..1, screen-down positive.
One finger drives the stick for the whole session: a second call
moves the finger already down rather than adding another.
- `duration` `number` _(optional)_ — Hold seconds, then release. Omitted, the stick STAYS
deflected — release it with `pushStick(0, 0)` or `releaseStick()`.

**Returns** `number?` — The contact id while held, or nil once released.

```lua
Zin.test.pushStick(0, -1, 2)
Zin.test.pushStick(0, -1) ; ... ; Zin.test.releaseStick()
```

## typed/builtin//modules/zinput/test/M/releaseAll {#typed-builtin-modules-zinput-test-m-releaseall}

```lua
M.releaseAll() -> Released
```

Put the whole session down: drop the on-screen stick, lift every
touch contact, release every held key and mouse button, and
disconnect every connected pad. After it, `held()` reads `atRest`,
the pointer sits over the middle of the scene's viewport and the
scene holds the input context (see `focusScene`).

**Returns** `Released` — `{ keys, mouse, contacts, pads, stick }` — how many of each was let go, and whether the on-screen stick was one of them.

```lua
Zin.test.releaseAll()
```

## typed/builtin//modules/zinput/test/M/releaseKey {#typed-builtin-modules-zinput-test-m-releasekey}

```lua
M.releaseKey(code: string)
```

Simulate a key release. Returns inside the frame where
`keys_released` contains `code`.

**Parameters**

- `code` `string` — Web-style key code.

```lua
Zin.test.releaseKey("KeyM")
```

## typed/builtin//modules/zinput/test/M/releaseMouse {#typed-builtin-modules-zinput-test-m-releasemouse}

```lua
M.releaseMouse(button: (number | string)?)
```

Simulate a mouse button release. Accepts a 0-based index OR a
case-insensitive name (`"left"`/`"right"`/`"middle"`). Default: left.

**Parameters**

- `button` `(number | string)` _(optional)_ — Optional button index or name (default 0 = left).

```lua
Zin.test.releaseMouse()
Zin.test.releaseMouse("middle")
```

## typed/builtin//modules/zinput/test/M/releaseStick {#typed-builtin-modules-zinput-test-m-releasestick}

```lua
M.releaseStick() -> boolean
```

Lift the finger driving the on-screen stick, if one is down.
`pushStick(0, 0)` does this too; this is the explicit form, and what
a test calls to be sure it starts from rest.

**Returns** `boolean` — True when a contact was lifted.

```lua
Zin.test.releaseStick()
```

## typed/builtin//modules/zinput/test/M/releaseUiFocus {#typed-builtin-modules-zinput-test-m-releaseuifocus}

```lua
M.releaseUiFocus()
```

Give the UI's focus pair back to the UI pass, which writes its own
opinion on its next run.

```lua
Zin.test.releaseUiFocus()
```

## typed/builtin//modules/zinput/test/M/runFrame {#typed-builtin-modules-zinput-test-m-runframe}

```lua
M.runFrame()
```

Advance one engine frame: yield so simulated events drain and
the next snapshot is published. Use between manual
`__zero_input.simulate*` calls when you need to checkpoint state
without queueing a new event. Does NOT call `Zin.tick()` — run it
yourself if you want action / event handlers to dispatch.

```lua
Zin.test.runFrame()
```

## typed/builtin//modules/zinput/test/M/scroll {#typed-builtin-modules-zinput-test-m-scroll}

```lua
M.scroll(dy: number)
```

Simulate a mouse wheel scroll. Positive `dy` = up.

**Parameters**

- `dy` `number` — Signed scroll delta.

```lua
Zin.test.scroll(1)
```

## typed/builtin//modules/zinput/test/M/tapKey {#typed-builtin-modules-zinput-test-m-tapkey}

```lua
M.tapKey(code: string, duration: number?)
```

Press + release in one call. If `duration` is set, waits that
many seconds (held over multiple frames) between press and release.
Does NOT tick — call `Zin.tick(dt)` between `tapKey` and your
assertion if you need binding-action handlers to fire.

**Parameters**

- `code` `string` — Web-style key code.
- `duration` `number` _(optional)_ — Optional held duration in seconds.

```lua
Zin.test.tapKey("Space", 0.1)
```

## typed/builtin//modules/zinput/test/M/tapTouchButton {#typed-builtin-modules-zinput-test-m-taptouchbutton}

```lua
M.tapTouchButton(label: string, duration: number?)
```

Tap the on-screen button labelled `label`, at its real centre.
Raises when no live button carries that label, listing the ones that
do — a tap that silently lands on nothing is worse than one that
stops and says so.

**Parameters**

- `label` `string` — The button's label, as a player reads it.
- `duration` `number` _(optional)_ — Hold seconds; an instant tap when omitted.

```lua
Zin.test.tapTouchButton("Jump")
```

## typed/builtin//modules/zinput/test/M/touchCancel {#typed-builtin-modules-zinput-test-m-touchcancel}

```lua
M.touchCancel(id: number)
```

Simulate the platform cancelling a touch contact.

**Parameters**

- `id` `number` — Stable finger id.

```lua
Zin.test.touchCancel(1)
```

## typed/builtin//modules/zinput/test/M/touchDown {#typed-builtin-modules-zinput-test-m-touchdown}

```lua
M.touchDown(x: number, y: number, pressure: number?) -> number
```

Put a finger down at `(x, y)` and return its contact id — the id
`touchMove` and `touchUp` take. Ids are handed out for you, so a
two-finger gesture is two of these rather than a bookkeeping problem.

**Parameters**

- `x` `number` — Screen x.
- `y` `number` — Screen y.
- `pressure` `number` _(optional)_ — Contact pressure 0..1; 1 when omitted.

**Returns** `number` — The contact id.

```lua
local id = Zin.test.touchDown(200, 600)
```

## typed/builtin//modules/zinput/test/M/touchEnd {#typed-builtin-modules-zinput-test-m-touchend}

```lua
M.touchEnd(id: number)
```

Simulate a touch contact lifting.

**Parameters**

- `id` `number` — Stable finger id.

```lua
Zin.test.touchEnd(1)
```

## typed/builtin//modules/zinput/test/M/touchMove {#typed-builtin-modules-zinput-test-m-touchmove}

```lua
M.touchMove(id: number, x: number, y: number, pressure: number?)
```

Simulate a touch contact moving.

**Parameters**

- `id` `number` — Stable finger id.
- `x` `number` — Screen X.
- `y` `number` — Screen Y.
- `pressure` `number` _(optional)_ — Contact pressure 0..1 (defaults to 1).

```lua
Zin.test.touchMove(1, 440, 300)
```

## typed/builtin//modules/zinput/test/M/touchStart {#typed-builtin-modules-zinput-test-m-touchstart}

```lua
M.touchStart(id: number, x: number, y: number, pressure: number?)
```

Simulate a touch contact beginning. `id` is any stable number
identifying the finger until its matching touchEnd/touchCancel.
The primary contact (slot 0) also drives the mouse path.

**Parameters**

- `id` `number` — Stable finger id.
- `x` `number` — Screen X.
- `y` `number` — Screen Y.
- `pressure` `number` _(optional)_ — Contact pressure 0..1 (defaults to 1).

```lua
Zin.test.touchStart(1, 400, 300)
```

## typed/builtin//modules/zinput/test/M/touchUp {#typed-builtin-modules-zinput-test-m-touchup}

```lua
M.touchUp(id: number)
```

Lift a contact opened by `touchDown`.

**Parameters**

- `id` `number` — The contact id.

```lua
Zin.test.touchUp(id)
```

## typed/builtin//modules/zinput/test/M/uiFocus {#typed-builtin-modules-zinput-test-m-uifocus}

```lua
M.uiFocus(pointer: boolean, keyboard: boolean)
```

Hold the UI layer's two focus opinions, so a run with no UI on
screen can put an event on either side of `consumed_by_ui`. A pointer
event is judged on `pointer` and a key on `keyboard`, and both hold
until `Zin.test.releaseUiFocus()`. Inputs simulated after this call
are routed against the pair.

**Parameters**

- `pointer` `boolean` — Whether the UI holds pointer focus.
- `keyboard` `boolean` — Whether the UI holds keyboard focus.

```lua
Zin.test.uiFocus(true, false)
```

## typed/builtin//modules/zinput/touch/M/byId {#typed-builtin-modules-zinput-touch-m-byid}

```lua
M.byId(id: number) -> TouchPoint?
```

Look up an active contact by its finger id.

**Parameters**

- `id` `number` — The platform finger id.

**Returns** `TouchPoint?` — The contact record, or nil.

```lua
local t = Zin.touch.byId(3)
```

## typed/builtin//modules/zinput/touch/M/capable {#typed-builtin-modules-zinput-touch-m-capable}

```lua
M.capable() -> boolean
```

Whether the session has (or has declared) a touch input source.
Latched by the first contact, or set at boot by platforms that
know up front.

**Returns** `boolean` — True when a touch source exists.

```lua
if Zin.touch.capable() then ... end
```

## typed/builtin//modules/zinput/touch/M/count {#typed-builtin-modules-zinput-touch-m-count}

```lua
M.count() -> number
```

Number of active touch contacts this frame.

**Returns** `number` — The contact count.

```lua
if Zin.touch.count() >= 2 then ... end
```

## typed/builtin//modules/zinput/touch/M/off {#typed-builtin-modules-zinput-touch-m-off}

```lua
M.off(handle: any?)
```

Unsubscribe a handle returned by any Zin.touch.on* function.

**Parameters**

- `handle` `any` _(optional)_ — The subscription handle.

```lua
Zin.touch.off(h)
```

## typed/builtin//modules/zinput/touch/M/onBegan {#typed-builtin-modules-zinput-touch-m-onbegan}

```lua
M.onBegan(fn: (any, boolean) -> any, opts: any?)
```

Subscribe to touch-contact-begin events. `fn(ev, gpe)` where ev =
{ kind = "touch.down", id, x, y, pressure } and gpe is the UI-focus
flag at fire time. Return "sink" to consume. Returns an
`Zin.events` handle for `off`.

**Parameters**

- `fn` `(any, boolean) -> any` — The callback.
- `opts` `any` _(optional)_ — Optional { priority, context, once } (Zin.events.on opts).

**Returns** The subscription handle.

```lua
local h = Zin.touch.onBegan(function(ev) print(ev.id) end)
```

## typed/builtin//modules/zinput/touch/M/onCancelled {#typed-builtin-modules-zinput-touch-m-oncancelled}

```lua
M.onCancelled(fn: (any, boolean) -> any, opts: any?)
```

Subscribe to platform touch-cancel events (`{ kind =
"touch.cancel", id }`).

**Parameters**

- `fn` `(any, boolean) -> any` — The callback.
- `opts` `any` _(optional)_ — Optional Zin.events.on opts.

**Returns** The subscription handle.

```lua
local h = Zin.touch.onCancelled(function(ev) ... end)
```

## typed/builtin//modules/zinput/touch/M/onEnded {#typed-builtin-modules-zinput-touch-m-onended}

```lua
M.onEnded(fn: (any, boolean) -> any, opts: any?)
```

Subscribe to touch-lift events (`{ kind = "touch.up", id, x, y }`).

**Parameters**

- `fn` `(any, boolean) -> any` — The callback.
- `opts` `any` _(optional)_ — Optional Zin.events.on opts.

**Returns** The subscription handle.

```lua
local h = Zin.touch.onEnded(function(ev) ... end)
```

## typed/builtin//modules/zinput/touch/M/onMoved {#typed-builtin-modules-zinput-touch-m-onmoved}

```lua
M.onMoved(fn: (any, boolean) -> any, opts: any?)
```

Subscribe to touch-move events (`{ kind = "touch.move", id, x, y,
dx, dy, pressure }`).

**Parameters**

- `fn` `(any, boolean) -> any` — The callback.
- `opts` `any` _(optional)_ — Optional Zin.events.on opts.

**Returns** The subscription handle.

```lua
local h = Zin.touch.onMoved(function(ev) ... end)
```

## typed/builtin//modules/zinput/touch/M/primary {#typed-builtin-modules-zinput-touch-m-primary}

```lua
M.primary() -> TouchPoint?
```

The primary contact (slot 0), if a finger is down.

**Returns** `TouchPoint?` — The primary contact record, or nil.

```lua
local p = Zin.touch.primary()
```

## typed/builtin//modules/zinput/touch/M/slots {#typed-builtin-modules-zinput-touch-m-slots}

```lua
M.slots() -> { TouchPoint }
```

All active touch contacts this frame, in begin order.

**Returns** `{ TouchPoint }` — Array of contact records (may be empty).

```lua
for _, t in ipairs(Zin.touch.slots()) do print(t.slot, t.x, t.y) end
```

## typed/builtin//modules/zinput/touchControls/M/_advance {#typed-builtin-modules-zinput-touchcontrols-m-advance}

```lua
M._advance()
```

Internal: advance the touch-controls overlay one tick — route
this tick's raw touches into `Zin.virtual` and recompute layout
first, then auto-mount by `Zin.surface.current()` and repaint the
overlay if its draw state changed. Wired into `Zin.tick`, before
`Zin.emulation._advance()` (the floor consumes the `Zin.virtual`
state this routing produces).

```lua
Zin.touchControls._advance()
```

## typed/builtin//modules/zinput/touchControls/M/_forceMount {#typed-builtin-modules-zinput-touchcontrols-m-forcemount}

```lua
M._forceMount(on: boolean)
```

Test-only: force the overlay to mount regardless of
`Zin.surface.current()` — for headless tests that want to exercise
rendering without a real touch surface. Touch routing itself is
always active regardless of this flag.

**Parameters**

- `on` `boolean` — Whether to force-mount.

```lua
Zin.touchControls._forceMount(true)
```

## typed/builtin//modules/zinput/touchControls/M/_reset {#typed-builtin-modules-zinput-touchcontrols-m-reset}

```lua
M._reset()
```

Test-only: unmount, clear all routing/layout state, drop
bespoke buttons, release every runtime control, close the fan, clear
the viewport override, and reset the force-mount flag. Registration
(`ui.registerScreen`) itself is not undone.

```lua
Zin.touchControls._reset()
```

## typed/builtin//modules/zinput/touchControls/M/_setViewportOverride {#typed-builtin-modules-zinput-touchcontrols-m-setviewportoverride}

```lua
M._setViewportOverride(w: number?, h: number?)
```

Test-only: override the logical screen size (`ui.screenSize()`
space) the layout budget/fan math uses, without resizing the real
window — for headless tests that need to prove budget math at a
phone-sized viewport. Pass nil for both to clear the override and
fall back to the real `ui.screenSize()`.

**Parameters**

- `w` `number` _(optional)_ — Override width, or nil to clear.
- `h` `number` _(optional)_ — Override height, or nil to clear.

```lua
Zin.touchControls._setViewportOverride(400, 800)
```

## typed/builtin//modules/zinput/touchControls/M/_settled {#typed-builtin-modules-zinput-touchcontrols-m-settled}

```lua
M._settled() -> boolean
```

Internal: whether the overlay could change nothing on its next
advance -- no live touch assignment, no open fan, no pending redraw,
mount state matching the surface, and (while mounted) the layout's
inputs unchanged. The tick's quiescence gate reads it.

**Returns** `boolean` — true when the overlay is at rest.

```lua
if Zin.touchControls._settled() then ... end
```

## typed/builtin//modules/zinput/touchControls/M/addControl {#typed-builtin-modules-zinput-touchcontrols-m-addcontrol}

```lua
M.addControl(opts: ControlOpts) -> number
```

Add a control while the world is running, and put its button on
screen.

The control becomes an asset — a one-control `.inputMap` under
`/source/runtimeControls/` — which is then activated and subscribed
to, which is what makes the overlay draw for it. It carries all three
device classes like any other control: give each of `kbm` / `gamepad`
a binding, or `false` plus `reasons.<class>` saying why it refuses
that device. `touch` defaults to an on-screen button for a `button`
control.

At least one handler is required. A control nothing listens to draws
no button, so an `addControl` with no handler would put nothing on
screen at all.

**Parameters**

- `opts` `ControlOpts` — `{ name, label?, kind?, kbm, gamepad, touch?, reasons?,
button?, onInput?, onPressed?, onReleased?, onChanged? }`.

**Returns** `number` — A handle for `M.removeControl`.

```lua
local h = Zin.touchControls.addControl({ name = "cast", label = "Cast", kbm = Zin.bindings.key("KeyF"), gamepad = Zin.bindings.padButton("north"), onPressed = function() castSpell() end })
```

## typed/builtin//modules/zinput/touchControls/M/button {#typed-builtin-modules-zinput-touchcontrols-m-button}

```lua
M.button(opts: ButtonOpts) -> number
```

Add an overlay button. Two flavors:
- `{ action = "jump" }` attaches an extra touchButton binding to an
existing action on the active map — a second on-screen instance
of a control the map already defines.
- `{ emit = "KeyF", label = "Cast" }` registers an overlay-only
button: a synthetic `emit:KeyF` action carrying both the kbm key
binding and the touchButton, so the emulation floor drives
`KeyF` straight from this button through the same
binding/emulation path every other control uses.
`label`/`zone`/`icon` set the button's presentation (see
`Zin.bindings.touchButton`); when neither is given the button
falls back to the action name (or the emit key).

**Parameters**

- `opts` `ButtonOpts` — `{ action?, emit?, label?, icon?, zone? }` — exactly one of
`action`/`emit` is required.

**Returns** `number` — A handle for `M.removeButton`.

```lua
local h = Zin.touchControls.button({ action = "jump" })
local h = Zin.touchControls.button({ emit = "KeyF", label = "Cast" })
```

## typed/builtin//modules/zinput/touchControls/M/claimed {#typed-builtin-modules-zinput-touchcontrols-m-claimed}

```lua
M.claimed() -> { number }
```

The contact ids currently claimed by the stick, a button, or
the drag zone.

**Returns** `{ number }` — A sorted array of claimed touch contact ids.

```lua
local ids = Zin.touchControls.claimed()
```

## typed/builtin//modules/zinput/touchControls/M/controls {#typed-builtin-modules-zinput-touchcontrols-m-controls}

```lua
M.controls() -> { any }
```

Every control `M.addControl` currently holds, as
`{ handle, name, path }` in the order they were added.

**Returns** `{ any }` — Array of runtime-control records.

```lua
for _, c in ipairs(Zin.touchControls.controls()) do print(c.name) end
```

## typed/builtin//modules/zinput/touchControls/M/layout {#typed-builtin-modules-zinput-touchcontrols-m-layout}

```lua
M.layout() -> any
```

The overlay's current control layout — a copy, safe to hold and
mutate. `buttons` is the budgeted, VISIBLE stack in draw order
(each entry `{ id, label, actionName, priority, size, appliedSize,
group, cx, cy, radius }` in `ui.screenSize()` space — `size` is
the step the binding declared and `appliedSize` the one `radius`
came from, which differ only where a rich scheme's step-down
moved a button one size down); `fan` is nil unless the
button set exceeded the two-column budget, in which case it's
`{ open, cx, cy, radius, buttons }` — `open` is whether the
overflow sheet is currently expanded, `buttons` the overflowed
entries at their sheet positions (tappable only while `open`).
`stick` / `drag` name the axis + virtual zone each region feeds,
or nil when the active map defines none in the current context.
The reading answers for the same instant `Zin.scheme.bindings()`
does: activating or standing down a map, subscribing a control,
changing context or resizing the screen is reflected by the next
read, in the call that made the change. Empty until a screen size
has resolved. Backs custom control-placement UI and headless tests
that need a button's (or the fan's) center to aim a simulated
touch at.

**Returns** `any` — `{ buttons, fan?, stick?, drag?, width, height }`.

```lua
local jumpBtn = Zin.touchControls.layout().buttons[1]
```

## typed/builtin//modules/zinput/touchControls/M/primaryClaimed {#typed-builtin-modules-zinput-touchcontrols-m-primaryclaimed}

```lua
M.primaryClaimed() -> boolean
```

Whether the PRIMARY touch contact is currently claimed by an
on-screen control.

The engine projects the primary contact onto the mouse so pointer UI
works from a finger, and that projection happens where the contact
arrives — before this overlay decides what the contact is for. A
finger resting on the Jump button therefore also reads as a held left
mouse button, which fires every control bound to one.

A mouse binding means the player pressed a mouse button, and a finger
an on-screen control has claimed is not that. `Zin.bindings` consults
this so a tap on one button does not fire an unrelated control.

**Returns** `boolean` — True while an on-screen control owns the primary contact.

```lua
if not Zin.touchControls.primaryClaimed() then ... end
```

## typed/builtin//modules/zinput/touchControls/M/removeButton {#typed-builtin-modules-zinput-touchcontrols-m-removebutton}

```lua
M.removeButton(handle: number) -> boolean
```

Remove a button previously added via `M.button`.

**Parameters**

- `handle` `number` — The handle returned by `M.button`.

**Returns** `boolean` — Whether a button was actually removed.

```lua
Zin.touchControls.removeButton(h)
```

## typed/builtin//modules/zinput/touchControls/M/removeControl {#typed-builtin-modules-zinput-touchcontrols-m-removecontrol}

```lua
M.removeControl(handle: number) -> boolean
```

Release a control added by `M.addControl` — drop its
subscriptions and release its map, which takes it off the screen and
out of the live set. The asset it was written to stays, so the same
name can be added again and comes back with the same guid.

**Parameters**

- `handle` `number` — The handle returned by `M.addControl`.

**Returns** `boolean` — Whether a control was actually released.

```lua
Zin.touchControls.removeControl(h)
```

## typed/builtin//modules/zinput/utils/M/applyCurve {#typed-builtin-modules-zinput-utils-m-applycurve}

```lua
M.applyCurve(curve: (string | (number) -> number)?, x: number) -> number
```

Apply a response curve to a reading. `"linear"` (and no curve at
all) is the identity, `"quadratic"` squares while keeping the sign,
`"cubic"` cubes, and a function is called with the reading. A function
that raises, or answers with anything other than a number, leaves the
reading as it was.

**Parameters**

- `curve` `(string | (number) -> number)` _(optional)_ — `"linear"` | `"quadratic"` | `"cubic"` | a function of the reading.
- `x` `number` — The reading to shape.

**Returns** `number` — The shaped reading.

```lua
Utils.applyCurve("quadratic", -0.5)  -- → -0.25
```

## typed/builtin//modules/zinput/utils/M/applyDeadzoneScalar {#typed-builtin-modules-zinput-utils-m-applydeadzonescalar}

```lua
M.applyDeadzoneScalar(x: number, deadzone: number?) -> number
```

Apply a scalar deadzone: a magnitude below the threshold reads 0,
anything at or above it passes through untouched.

**Parameters**

- `x` `number` — The reading.
- `deadzone` `number` _(optional)_ — The threshold; `nil` applies none.

**Returns** `number` — The reading, or 0 inside the deadzone.

```lua
Utils.applyDeadzoneScalar(0.04, 0.1)  -- → 0
```

## typed/builtin//modules/zinput/utils/M/applyDeadzoneVector {#typed-builtin-modules-zinput-utils-m-applydeadzonevector}

```lua
M.applyDeadzoneVector(v: Vector2, deadzone: number?) -> Vector2
```

Apply a radial deadzone to a pair: the MAGNITUDE of the pair is
what the threshold is measured against, so a diagonal held past it
keeps both components and a stick resting inside it reads `{0, 0}`.

**Parameters**

- `v` `Vector2` — The reading, as `{ x, y }`.
- `deadzone` `number` _(optional)_ — The threshold; `nil` applies none.

**Returns** `Vector2` — A fresh pair — the reading, or `{0, 0}` inside the deadzone.

```lua
Utils.applyDeadzoneVector({ x = 0.05, y = 0.05 }, 0.2)  -- → { x = 0, y = 0 }
```

## typed/builtin//modules/zinput/utils/M/buttonIndex {#typed-builtin-modules-zinput-utils-m-buttonindex}

```lua
M.buttonIndex(name: string) -> number?
```

Convert a mouse button name to its 0-based index.

**Parameters**

- `name` `string` — Mouse button name (`"left"`/`"right"`/`"middle"`).

**Returns** `number?` — The button index, or `nil` for unknown names.

```lua
Utils.buttonIndex("right")  -- → 1
```

## typed/builtin//modules/zinput/utils/M/buttonName {#typed-builtin-modules-zinput-utils-m-buttonname}

```lua
M.buttonName(idx: number) -> string?
```

Convert a 0-based mouse button index to its name.

**Parameters**

- `idx` `number` — Mouse button index (0=left, 1=right, 2=middle).

**Returns** `string?` — The button name (`"left"`/`"right"`/`"middle"`) or `nil` for out-of-range indices.

```lua
Utils.buttonName(0)  -- → "left"
```

## typed/builtin//modules/zinput/utils/M/matchModifiers {#typed-builtin-modules-zinput-utils-m-matchmodifiers}

```lua
M.matchModifiers(snapshot: any?, mods: Modifiers) -> boolean
```

Check whether the current frame's snapshot has the given modifiers
held. Pass any subset of `{ ctrl, shift, alt }`; unspecified keys are
not checked. Returns `false` if `snapshot` is not a table — callers
can forward `Zin.state.get()` directly without nil-checking first.

**Parameters**

- `snapshot` `any` _(optional)_ — The frame snapshot table (from `Zin.state.get()`), or any
non-table value (treated as "no modifiers held").
- `mods` `Modifiers` — Subset of `{ ctrl, shift, alt }` booleans to require.

**Returns** `boolean` — `true` when every specified modifier matches the held state.

```lua
Utils.matchModifiers(snap, { ctrl = true })
```

## typed/builtin//modules/zinput/utils/M/normalizeKey {#typed-builtin-modules-zinput-utils-m-normalizekey}

```lua
M.normalizeKey(code: string) -> string
```

Normalize a key code to the engine's canonical web-style form — the
`KeyboardEvent.code` vocabulary the input map and `Zin.state.get().keys`
use (`"KeyW"`, `"Space"`, `"ArrowUp"`, `"ShiftLeft"`, …). A single ASCII
letter is promoted to its `Key<L>` code and a single digit to its
`Digit<N>` code, so the common shorthand `"W"` resolves to the `"KeyW"`
the default map binds instead of a phantom key nothing consumes. Any
other single character is rejected — no bound key code is one character
long. Multi-character codes pass through unchanged.

**Parameters**

- `code` `string` — The raw key code (`"KeyW"`) or a single-letter/digit shorthand (`"w"`).

**Returns** `string` — The canonical key code.

```lua
Utils.normalizeKey("w")     -- → "KeyW"
Utils.normalizeKey("KeyW")  -- → "KeyW"
```

## typed/builtin//modules/zinput/utils/M/resolveButtonIndex {#typed-builtin-modules-zinput-utils-m-resolvebuttonindex}

```lua
M.resolveButtonIndex(button: (number | string)?) -> number
```

Resolve a mouse button given as a 0-based index OR a
case-insensitive name (`"left"`/`"right"`/`"middle"`, the same names
`Zin.bindings.mouse` takes) to its 0-based index. `nil` resolves to
left (0). Raises on an unknown name so a typo is loud, not a silent
left-click — the single coercion every input surface that accepts a
button uses so index and name mean the same thing everywhere.

**Parameters**

- `button` `(number | string)` _(optional)_ — Button index, name, or nil.

**Returns** `number` — The 0-based button index.

```lua
Utils.resolveButtonIndex("Right")  -- → 1
Utils.resolveButtonIndex(2)         -- → 2
```

## typed/builtin//modules/zinput/utils/M/shapeScalar {#typed-builtin-modules-zinput-utils-m-shapescalar}

```lua
M.shapeScalar(x: number, deadzone: number?, curve: (string | (number) -> number)?, invert: boolean?) -> number
```

The whole shaping of a scalar reading: deadzone, then curve, then
inversion.

**Parameters**

- `x` `number` — The reading.
- `deadzone` `number` _(optional)_ — Magnitude below which the reading is 0; `nil` applies none.
- `curve` `(string | (number) -> number)` _(optional)_ — `"linear"` | `"quadratic"` | `"cubic"` | a function; `nil` is linear.
- `invert` `boolean` _(optional)_ — Negate the shaped reading.

**Returns** `number` — The shaped reading.

```lua
Utils.shapeScalar(0.5, 0.1, "quadratic", true)  -- → -0.25
```

## typed/builtin//modules/zinput/utils/M/shapeVector {#typed-builtin-modules-zinput-utils-m-shapevector}

```lua
M.shapeVector(v: Vector2, deadzone: number?, curve: (string | (number) -> number)?, invert: boolean?) -> Vector2
```

The whole shaping of a pair: radial deadzone, then the curve on
each component, then inversion of both.

**Parameters**

- `v` `Vector2` — The reading, as `{ x, y }`.
- `deadzone` `number` _(optional)_ — Magnitude of the pair below which it reads `{0, 0}`; `nil` applies none.
- `curve` `(string | (number) -> number)` _(optional)_ — `"linear"` | `"quadratic"` | `"cubic"` | a function; `nil` is linear.
- `invert` `boolean` _(optional)_ — Negate both components.

**Returns** `Vector2` — A fresh, shaped pair.

```lua
Utils.shapeVector({ x = 1, y = 0 }, 0.2, "linear", true)  -- → { x = -1, y = 0 }
```

## typed/builtin//modules/zinput/utils/M/smoothToward {#typed-builtin-modules-zinput-utils-m-smoothtoward}

```lua
M.smoothToward(current: number, target: number, dt: number, tau: number) -> number
```

One step of an exponential approach toward a target: `tau` is the
time constant in seconds, and the step covers `dt` of it. A `tau` of 0
or less arrives immediately; a `dt` of 0 or less stays put.

**Parameters**

- `current` `number` — Where the value is now.
- `target` `number` — Where it is heading.
- `dt` `number` — Seconds this step covers.
- `tau` `number` — The time constant, in seconds.

**Returns** `number` — The value after the step.

```lua
Utils.smoothToward(0, 1, 0.05, 0.2)  -- → ~0.221
```

## typed/builtin//modules/zinput/virtual/M/_beginFrame {#typed-builtin-modules-zinput-virtual-m-beginframe}

```lua
M._beginFrame()
```

Internal: frame boundary — shift button edges, clear drag
deltas. Called by the Zin.tick coordinator on the first tick of
each engine frame.

```lua
Zin.virtual._beginFrame()
```

## typed/builtin//modules/zinput/virtual/M/_reset {#typed-builtin-modules-zinput-virtual-m-reset}

```lua
M._reset()
```

Test-only: clear all virtual state.

```lua
Zin.virtual._reset()
```

## typed/builtin//modules/zinput/virtual/M/_settled {#typed-builtin-modules-zinput-virtual-m-settled}

```lua
M._settled() -> boolean
```

Internal: whether every virtual control sits at rest -- sticks
centred, buttons up (this frame and last), drag deltas empty. The
tick's quiescence gate reads it.

**Returns** `boolean` — true when the virtual layer is producing nothing.

```lua
if Zin.virtual._settled() then ... end
```

## typed/builtin//modules/zinput/virtual/M/addDrag {#typed-builtin-modules-zinput-virtual-m-adddrag}

```lua
M.addDrag(zone: string, dx: number, dy: number)
```

Accumulate a drag delta for a zone this tick (cleared at the
next frame boundary, like the mouse delta).

**Parameters**

- `zone` `string` — The drag zone id.
- `dx` `number` — Delta X in px.
- `dy` `number` — Delta Y in px.

```lua
Zin.virtual.addDrag("right", 4, -2)
```

## typed/builtin//modules/zinput/virtual/M/button {#typed-builtin-modules-zinput-virtual-m-button}

```lua
M.button(id: string) -> boolean
```

A virtual button's held state.

**Parameters**

- `id` `string` — The button id.

**Returns** `boolean` — True while held.

```lua
if Zin.virtual.button("Jump") then ... end
```

## typed/builtin//modules/zinput/virtual/M/buttonPressed {#typed-builtin-modules-zinput-virtual-m-buttonpressed}

```lua
M.buttonPressed(id: string) -> boolean
```

Whether a virtual button was pressed this frame (held now, not
held at the previous frame boundary).

**Parameters**

- `id` `string` — The button id.

**Returns** `boolean` — True on the press frame.

```lua
if Zin.virtual.buttonPressed("Jump") then ... end
```

## typed/builtin//modules/zinput/virtual/M/buttonReleased {#typed-builtin-modules-zinput-virtual-m-buttonreleased}

```lua
M.buttonReleased(id: string) -> boolean
```

Whether a virtual button was released this frame.

**Parameters**

- `id` `string` — The button id.

**Returns** `boolean` — True on the release frame.

```lua
if Zin.virtual.buttonReleased("Jump") then ... end
```

## typed/builtin//modules/zinput/virtual/M/drag {#typed-builtin-modules-zinput-virtual-m-drag}

```lua
M.drag(zone: string) -> (number, number)
```

A zone's accumulated drag delta this frame.

**Parameters**

- `zone` `string` — The drag zone id.

**Returns** `(number, number)` — dx, dy.

```lua
local dx, dy = Zin.virtual.drag("right")
```

## typed/builtin//modules/zinput/virtual/M/setButton {#typed-builtin-modules-zinput-virtual-m-setbutton}

```lua
M.setButton(id: string, held: boolean)
```

Set a virtual button's held state. Edges (pressed/released) are
derived at the frame boundary.

**Parameters**

- `id` `string` — The button id (a touchButton's `id`, else its label, else its zone).
- `held` `boolean` — Whether the button is down.

```lua
Zin.virtual.setButton("Jump", true)
```

## typed/builtin//modules/zinput/virtual/M/setStick {#typed-builtin-modules-zinput-virtual-m-setstick}

```lua
M.setStick(zone: string, x: number, y: number)
```

Set a virtual stick's normalized vector (each component -1..1;
values are clamped). Persists until set again or reset.

**Parameters**

- `zone` `string` — The stick's zone id.
- `x` `number` — Stick X (right positive).
- `y` `number` — Stick Y (down positive, matching screen deltas).

```lua
Zin.virtual.setStick("left", 0.4, -0.9)
```

## typed/builtin//modules/zinput/virtual/M/stick {#typed-builtin-modules-zinput-virtual-m-stick}

```lua
M.stick(zone: string) -> (number, number)
```

A virtual stick's current vector ({x=0,y=0} when unset).

**Parameters**

- `zone` `string` — The stick's zone id.

**Returns** `(number, number)` — x, y components.

```lua
local x, y = Zin.virtual.stick("left")
```

## typed/builtin//systems/anim/AnimGraph/AnimGraph/bindSink {#typed-builtin-systems-anim-animgraph-animgraph-bindsink}

```lua
AnimGraph.bindSink(body: EntityRef)
```

Bind a pose sink targeting `body`'s armature, stored on the graph so
`:tick(dt)` applies the evaluated pose to it. The bone order is the graph's
layout. Re-binding replaces any prior sink. Raises when the sink cannot be
bound (the body has no Skeleton + Model when the sink is created).

**Parameters**

- `body` `EntityRef` — The EntityRef whose bones the graph drives (carries the Skeleton).

```lua
graph:bindSink(skinnedBody)
```

## typed/builtin//systems/anim/AnimGraph/AnimGraph/crossfadeTo {#typed-builtin-systems-anim-animgraph-animgraph-crossfadeto}

```lua
AnimGraph.crossfadeTo(toNode: any?, duration: number, removeFromOnDone: boolean?)
```

Crossfade from the current output to `toNode` over `duration` seconds.
Inserts a 2-input Mixer over the previous output and the new node and ramps
weights from `(1, 0)` to `(0, 1)`; on completion the output collapses to
`toNode`. Falls back to an instant swap when there is no active output or
`duration <= 0` (the old output is freed unless `removeFromOnDone` is false).

**Parameters**

- `toNode` `any` _(optional)_ — Target node (already constructed).
- `duration` `number` — Fade time in seconds (≥ 0).
- `removeFromOnDone` `boolean` _(optional)_ — When true (default), free the old output when the fade
completes.

```lua
graph:crossfadeTo(runClip, 0.25)
```

## typed/builtin//systems/anim/AnimGraph/AnimGraph/destroy {#typed-builtin-systems-anim-animgraph-animgraph-destroy}

```lua
AnimGraph.destroy()
```

Free the whole graph: cascade-`destroy()` the output subtree, unbind the
pose sink, and clear any active crossfade.

```lua
graph:destroy()
```

## typed/builtin//systems/anim/AnimGraph/AnimGraph/evaluate {#typed-builtin-systems-anim-animgraph-animgraph-evaluate}

```lua
AnimGraph.evaluate() -> any?
```

Evaluate the output subtree and return its pose buffer. Returns nil when
there is no output.

**Returns** `any?` — Pose buffer handle (caller MUST NOT destroy), or `nil`.

```lua
local pose = graph:evaluate()
```

## typed/builtin//systems/anim/AnimGraph/AnimGraph/layoutForEntity {#typed-builtin-systems-anim-animgraph-animgraph-layoutforentity}

```lua
AnimGraph.layoutForEntity(body: EntityRef, opts: { symmetrize: boolean? }?) -> Layout
```

Build the layout for a graph that drives a skinned body. Resolves the
body's rig from its `ecs.Skeleton` and packs everything Clip nodes need to
retarget clips onto it and apply poses relative to its canonical bind:
`boneOrder`, the parsed `targetRig`, its stride-10 canonical `restPose`, and
the bake-cache key. Raises when `body` has no rigged Skeleton — call it on a
body you intend to animate, after its skeleton is hydrated.

**Parameters**

- `body` `EntityRef` — The EntityRef of the body to drive (carries a Skeleton with a rig).
- `opts` `{ symmetrize: boolean? }` _(optional)_ — `{ symmetrize }` — absolute (true) vs relative (default) bind correction.

**Returns** `Layout` — A `Layout` for `AnimGraph.new` + `Clip.new`.

```lua
local layout = AnimGraph.layoutForEntity(skinnedBody)
```

## typed/builtin//systems/anim/AnimGraph/AnimGraph/new {#typed-builtin-systems-anim-animgraph-animgraph-new}

```lua
AnimGraph.new(layout: Layout, driver: string?) -> AnimGraph
```

Construct an empty AnimGraph with no output. `:setOutput` names the root
node the graph drives; `:bindSink` binds the body the pose is applied to.

**Parameters**

- `layout` `Layout` — `{ boneOrder, stride?, slotLayout? }` — the skeleton layout shared
by every node in the graph.
- `driver` `string` _(optional)_ — A name for whatever owns this graph — the component, tool or
system an author would recognise. `:tick` publishes it every frame, so it is
what `animation.body(...).driver` names for the body this graph poses.

**Returns** `AnimGraph` — The new AnimGraph instance.

```lua
local g = AnimGraph.new(AnimGraph.layoutForEntity(body), "Locomotion")
```

## typed/builtin//systems/anim/AnimGraph/AnimGraph/play {#typed-builtin-systems-anim-animgraph-animgraph-play}

```lua
AnimGraph.play()
```

Start the graph's per-frame update loop. Equivalent to `:setPlaying(true)`.

## typed/builtin//systems/anim/AnimGraph/AnimGraph/publish {#typed-builtin-systems-anim-animgraph-animgraph-publish}

```lua
AnimGraph.publish(driver: string?)
```

Publish what this graph is running on the body it drives, so the
engine's animation observation names the clips, their playheads and their
retarget coverage beside the pose it measures. `:tick` calls this every
frame; call it directly when advancing a graph by hand.

**Parameters**

- `driver` `string` _(optional)_ — A name for whatever owns this graph, shown as the body's driver.

```lua
graph:publish("Locomotion")
```

## typed/builtin//systems/anim/AnimGraph/AnimGraph/setOutput {#typed-builtin-systems-anim-animgraph-animgraph-setoutput}

```lua
AnimGraph.setOutput(node: any?)
```

Name the node the graph drives. The node and the subtree it owns become
the graph's output; `:update` / `:evaluate` / `:destroy` cascade from here.
Replacing the output does NOT free the old one — detach or destroy it first
if it is no longer used.

**Parameters**

- `node` `any` _(optional)_ — The root node (any Clip / Mixer / BlendSpace2D).

```lua
graph:setOutput(blendSpace)
```

## typed/builtin//systems/anim/AnimGraph/AnimGraph/setPlaying {#typed-builtin-systems-anim-animgraph-animgraph-setplaying}

```lua
AnimGraph.setPlaying(p: boolean)
```

Set the playing flag explicitly. `true` resumes per-frame updates;
`false` freezes them.

**Parameters**

- `p` `boolean` — Whether the graph should run per-frame updates.

```lua
graph:setPlaying(false)
```

## typed/builtin//systems/anim/AnimGraph/AnimGraph/state {#typed-builtin-systems-anim-animgraph-animgraph-state}

```lua
AnimGraph.state() -> { [string]: any }
```

Snapshot of graph state — handy for tools and debugging. Walks the
output subtree; no internal references are leaked.

**Returns** `{ [string]: any }` — `{ playing, crossfade?, output = { kind, time, duration, playing, finished, children? } }`.

```lua
local snap = graph:state()
```

## typed/builtin//systems/anim/AnimGraph/AnimGraph/stop {#typed-builtin-systems-anim-animgraph-animgraph-stop}

```lua
AnimGraph.stop()
```

Stop the graph's per-frame update loop. Equivalent to `:setPlaying(false)`.

```lua
graph:stop()
```

## typed/builtin//systems/anim/AnimGraph/AnimGraph/tick {#typed-builtin-systems-anim-animgraph-animgraph-tick}

```lua
AnimGraph.tick(dt: number, sink: any?) -> any?
```

One-call per-frame driver. Advances the graph + crossfade by `dt`,
evaluates the output, and (when a sink is bound or passed) hands the pose
buffer to `skeleton.applyPose`. Returns the pose buffer so callers can read
it directly (e.g. screenshot tests).

**Parameters**

- `dt` `number` — Seconds to advance.
- `sink` `any` _(optional)_ — A SinkHandle from `skeleton.bindPose`. Omitted, the sink bound via
`:bindSink` is used; pass `false` to advance without applying.

**Returns** `any?` — The pose buffer handle, or `nil` when there is no output.

```lua
graph:bindSink(skinnedId); graph:tick(dt)
```

## typed/builtin//systems/anim/AnimGraph/AnimGraph/update {#typed-builtin-systems-anim-animgraph-animgraph-update}

```lua
AnimGraph.update(dt: number)
```

Advance the output subtree and the active crossfade by `dt`. No-op when
the graph is not playing. When a crossfade reaches the end the output
collapses to the target node and the crossfade mixer (plus, by default, the
faded-out source) is freed.

**Parameters**

- `dt` `number` — Seconds to advance.

```lua
graph:update(1 / 60)
```

## typed/builtin//systems/anim/AnimGraph/Node/BlendSpace2D/BlendSpace2D/destroy {#typed-builtin-systems-anim-animgraph-node-blendspace2d-blendspace2d-destroy}

```lua
BlendSpace2D.destroy()
```

Destroy the internal Mixer — which cascade-`destroy()`s the sample
sources it holds — then clear sample/triangle state. Destroying a
BlendSpace2D frees the subtree below it, same as any composite node.

```lua
bs:destroy()
```

## typed/builtin//systems/anim/AnimGraph/Node/BlendSpace2D/BlendSpace2D/evaluate {#typed-builtin-systems-anim-animgraph-node-blendspace2d-blendspace2d-evaluate}

```lua
BlendSpace2D.evaluate() -> any
```

Find the triangle containing the current parameter, compute
barycentric weights, push them into the internal Mixer, evaluate.
Falls back to the nearest sample (weight 1) when the parameter
lies outside the triangulated hull.

**Returns** `any` — Owned pose buffer handle (provided by the internal Mixer). Caller must NOT destroy.

```lua
local pose = bs:evaluate()
```

## typed/builtin//systems/anim/AnimGraph/Node/BlendSpace2D/BlendSpace2D/new {#typed-builtin-systems-anim-animgraph-node-blendspace2d-blendspace2d-new}

```lua
BlendSpace2D.new(layout: Layout, samples: { Sample }) -> any
```

Construct a BlendSpace2D Node. Triangulates the sample anchors
once at construction time and reuses an internal Mixer to do the
per-frame barycentric weighted blend.

**Parameters**

- `layout` `Layout` — Layout descriptor — `boneOrder` is required, `stride`
defaults to 10, `slotLayout` is passed through to the internal Mixer.
- `samples` `{ Sample }` — Array of `{ x, y, source }` entries — `source` is any Node.

**Returns** `any` — The constructed BlendSpace2D node.

```lua
local bs = BlendSpace2D.new(layout, { { x=0, y=0, source=idle }, { x=1, y=0, source=walk } })
```

## typed/builtin//systems/anim/AnimGraph/Node/BlendSpace2D/BlendSpace2D/setParams {#typed-builtin-systems-anim-animgraph-node-blendspace2d-blendspace2d-setparams}

```lua
BlendSpace2D.setParams(x: number, y: number)
```

Set the `(x, y)` parameter that drives the blend.

**Parameters**

- `x` `number` — Parameter X.
- `y` `number` — Parameter Y.

```lua
bs:setParams(0.5, 0.3)
```

## typed/builtin//systems/anim/AnimGraph/Node/BlendSpace2D/BlendSpace2D/update {#typed-builtin-systems-anim-animgraph-node-blendspace2d-blendspace2d-update}

```lua
BlendSpace2D.update(dt: number)
```

Cascade `update(dt)` to every sample source that defines it.

**Parameters**

- `dt` `number` — Frame delta time in seconds.

```lua
bs:update(dt)
```

## typed/builtin//systems/anim/AnimGraph/Node/Clip/Clip/destroy {#typed-builtin-systems-anim-animgraph-node-clip-clip-destroy}

```lua
Clip.destroy()
```

Free the bound clip sampler and the owned pose buffer.

```lua
clip:destroy()
```

## typed/builtin//systems/anim/AnimGraph/Node/Clip/Clip/evaluate {#typed-builtin-systems-anim-animgraph-node-clip-clip-evaluate}

```lua
Clip.evaluate() -> any
```

Sample the clip at the current playhead. With a body layout, returns a
COMPLETE local pose: the body's bind, with every driven bone's rotation and
translation overlaid — translation applied relative to the bind (rest plus the
clip's displacement from its own start). Without a body layout, returns the
raw sample.

**Returns** `any` — Owned pose buffer handle. Caller must NOT destroy — the Clip owns it.

```lua
local pose = clip:evaluate()
```

## typed/builtin//systems/anim/AnimGraph/Node/Clip/Clip/new {#typed-builtin-systems-anim-animgraph-node-clip-clip-new}

```lua
Clip.new(clipRef: any?, layout: Layout, looping: boolean, speed: number?, sourceRig: any?) -> (any, string?)
```

Construct a Clip Node from a `.animation` asset reference. Reads the
clip bytes, retargets them onto the layout's target rig (when the layout
carries a body), binds the result to the bone order via `skeleton.bindClip`,
and records which bones the clip drives so `evaluate` overlays only those on
the bind pose. `matched == 0` (the clip drives none of these bones) is
logged so a silent rest pose never goes unexplained.

**Parameters**

- `clipRef` `any` _(optional)_ — Asset identity string or AssetRef for the `.animation`.
- `layout` `Layout` — Layout descriptor — `boneOrder` is required; `stride` defaults to 10.
- `looping` `boolean` — When true the playhead wraps at `duration`; otherwise it clamps and marks the clip `finished`.
- `speed` `number` _(optional)_ — Playback rate multiplier (defaults to 1).
- `sourceRig` `any` _(optional)_ — Optional explicit `.rig` ref overriding the clip's recorded source rig.

**Returns** `(any, string?)` — The constructed Clip node, or nil + error message when the clip cannot be read or bound.

```lua
local clip = Clip.new(clipRef, layout, true, 1.0)
```

## typed/builtin//systems/anim/AnimGraph/Node/Clip/Clip/rewind {#typed-builtin-systems-anim-animgraph-node-clip-clip-rewind}

```lua
Clip.rewind()
```

Rewind the playhead to 0, clear `finished`, and resume playback.

```lua
clip:rewind()
```

## typed/builtin//systems/anim/AnimGraph/Node/Clip/Clip/setPlaying {#typed-builtin-systems-anim-animgraph-node-clip-clip-setplaying}

```lua
Clip.setPlaying(p: boolean)
```

Pause or resume the playhead. Any value that is not the boolean `true`
becomes `playing = false`.

**Parameters**

- `p` `boolean` — New playing state.

```lua
clip:setPlaying(false)
```

## typed/builtin//systems/anim/AnimGraph/Node/Clip/Clip/update {#typed-builtin-systems-anim-animgraph-node-clip-clip-update}

```lua
Clip.update(dt: number)
```

Advance the playhead by `dt * speed`. Wraps at `duration` when
`looping` is true; otherwise clamps and marks the clip `finished` /
`playing = false`. No-op when not playing or already finished.

**Parameters**

- `dt` `number` — Frame delta time in seconds.

```lua
clip:update(dt)
```

## typed/builtin//systems/anim/AnimGraph/Node/Layer/Layer/destroy {#typed-builtin-systems-anim-animgraph-node-layer-layer-destroy}

```lua
Layer.destroy()
```

Cascade-`destroy()` base + overlay, then free this Layer's output buffer.
A Layer owns both inputs (the graph is a tree), so destroying it frees the
subtree. An input detached (set to nil) is skipped.

```lua
layer:destroy()
```

## typed/builtin//systems/anim/AnimGraph/Node/Layer/Layer/evaluate {#typed-builtin-systems-anim-animgraph-node-layer-layer-evaluate}

```lua
Layer.evaluate() -> any
```

Evaluate base + overlay, then per-bone blend overlay onto base by
`mask[bone] * weight` (translation lerp, rotation nlerp, scale lerp) into the
output buffer. With weight 0 (or an all-zero mask) the base passes through.

**Returns** `any` — Owned pose buffer handle. Caller must NOT destroy.

```lua
local pose = layer:evaluate()
```

## typed/builtin//systems/anim/AnimGraph/Node/Layer/Layer/new {#typed-builtin-systems-anim-animgraph-node-layer-layer-new}

```lua
Layer.new(layout: Layout, base: any?, overlay: any?, mask: { number }) -> any
```

Construct a Layer Node that blends `overlay` over `base` per the per-bone
`mask` scaled by the layer `weight`. Allocates an output pose buffer.

**Parameters**

- `layout` `Layout` — Layout descriptor — `boneOrder` required, `stride` defaults to 10.
- `base` `any` _(optional)_ — The base Node (e.g. the locomotion output) — passes through where mask*weight is 0.
- `overlay` `any` _(optional)_ — The overlay Node (e.g. an attack clip) — taken where mask*weight is 1.
- `mask` `{ number }` — Per-bone weight array (one entry per bone, in `boneOrder`); see `AnimGraph.mask`. Missing entries are 0.

**Returns** `any` — The constructed Layer node.

```lua
local l = Layer.new(layout, loco, attack, AnimGraph.mask(layout, "upperBody", rig))
```

## typed/builtin//systems/anim/AnimGraph/Node/Layer/Layer/setWeight {#typed-builtin-systems-anim-animgraph-node-layer-layer-setweight}

```lua
Layer.setWeight(w: number)
```

Set the layer's global weight (0 = base only, 1 = full overlay where the
mask is 1). The owner ramps this to fade the action in and out.

**Parameters**

- `w` `number` — New weight, typically in `[0, 1]`.

```lua
layer:setWeight(0.5)
```

## typed/builtin//systems/anim/AnimGraph/Node/Layer/Layer/update {#typed-builtin-systems-anim-animgraph-node-layer-layer-update}

```lua
Layer.update(dt: number)
```

Cascade `update(dt)` to the base and overlay sources. The Layer is the
graph output, so it owns advancing both subtrees.

**Parameters**

- `dt` `number` — Frame delta time in seconds.

```lua
layer:update(dt)
```

## typed/builtin//systems/anim/AnimGraph/Node/Mixer/Mixer/destroy {#typed-builtin-systems-anim-animgraph-node-mixer-mixer-destroy}

```lua
Mixer.destroy()
```

Cascade-`destroy()` every input source, then free this Mixer's own
blend layout and output buffer. A Mixer owns its inputs (the graph is a
tree), so destroying it frees the subtree below it. An input whose `source`
was detached (set to nil — e.g. a crossfade survivor handed back to the
graph) is skipped.

```lua
mix:destroy()
```

## typed/builtin//systems/anim/AnimGraph/Node/Mixer/Mixer/evaluate {#typed-builtin-systems-anim-animgraph-node-mixer-mixer-evaluate}

```lua
Mixer.evaluate() -> any
```

Evaluate inputs in turn, then weighted-blend their pose buffers
into the output buffer. Inputs with `weight <= 0` are skipped.

**Returns** `any` — Owned pose buffer handle. Caller must NOT destroy.

```lua
local pose = mix:evaluate()
```

## typed/builtin//systems/anim/AnimGraph/Node/Mixer/Mixer/new {#typed-builtin-systems-anim-animgraph-node-mixer-mixer-new}

```lua
Mixer.new(layout: Layout, inputs: { MixerInput }) -> any
```

Construct a Mixer Node. Allocates an output pose buffer sized for
the layout and the engine-side blend layout.

**Parameters**

- `layout` `Layout` — Layout descriptor — `boneOrder` is required, `stride` defaults to 10, `slotLayout` defaults to translation lerp + rotation slerp + scale lerp.
- `inputs` `{ MixerInput }` — Array of `{ source = Node, weight = number }` entries.

**Returns** `any` — The constructed Mixer node.

```lua
local mix = Mixer.new(layout, { { source = clipA, weight = 1 }, { source = clipB, weight = 0 } })
```

## typed/builtin//systems/anim/AnimGraph/Node/Mixer/Mixer/setWeight {#typed-builtin-systems-anim-animgraph-node-mixer-mixer-setweight}

```lua
Mixer.setWeight(i: number, w: number)
```

Set or update an input's weight at index `i`. Out-of-range index is a no-op.

**Parameters**

- `i` `number` — 1-based input index.
- `w` `number` — New weight (typically in `[0, 1]`).

```lua
mix:setWeight(1, 0.5)
```

## typed/builtin//systems/anim/AnimGraph/Node/Mixer/Mixer/update {#typed-builtin-systems-anim-animgraph-node-mixer-mixer-update}

```lua
Mixer.update(dt: number)
```

Cascade `update(dt)` to every input source that defines it.

**Parameters**

- `dt` `number` — Frame delta time in seconds.

```lua
mix:update(dt)
```

## typed/builtin//systems/anim/AnimGraph/Node/Node/destroy {#typed-builtin-systems-anim-animgraph-node-node-destroy}

```lua
Node.destroy()
```

Default `:destroy` — no resources to free. Subclasses override
to release owned Channel/Buffer/Layout handles.

```lua
node:destroy()
```

## typed/builtin//systems/anim/AnimGraph/Node/Node/evaluate {#typed-builtin-systems-anim-animgraph-node-node-evaluate}

```lua
Node.evaluate() -> any?
```

Default `:evaluate` — returns nil. Subclasses override and
return a Buffer handle (caller MUST NOT destroy).

**Returns** `any?` — Pose Buffer handle, or `nil` from the default implementation.

```lua
local pose = node:evaluate()
```

## typed/builtin//systems/anim/AnimGraph/Node/Node/new {#typed-builtin-systems-anim-animgraph-node-node-new}

```lua
Node.new() -> Node
```

Allocate a bare Node table (no Channels, no Buffer). Subclasses
typically wrap `setmetatable(Node.new(), <Subclass>)` and then set
the subclass-specific fields.

**Returns** `Node` — The new Node instance.

```lua
local n = Node.new()
```

## typed/builtin//systems/anim/AnimGraph/Node/Node/update {#typed-builtin-systems-anim-animgraph-node-node-update}

```lua
Node.update(dt: number)
```

Default `:update` — no internal state to advance. Subclasses
override to step playhead, ramp weights, etc.

**Parameters**

- `dt` `number` — Seconds elapsed since the last update.

```lua
node:update(1 / 60)
```

## typed/builtin//systems/anim/AnimGraph/rigResolve/R/parseBodyRig {#typed-builtin-systems-anim-animgraph-rigresolve-r-parsebodyrig}

```lua
R.parseBodyRig(body: EntityRef) -> any?
```

The parsed rig of a skinned body, read straight from the ECS — its
`ecs.Skeleton` bones (rest pose + hierarchy) plus its `ecs.RetargetProfile`
roles when present. Everything the graph needs is already in the ECS by this
point; no asset is resolved and no document is parsed. A body whose Skeleton
carries no bones returns nil. A body with no RetargetProfile is a
non-humanoid rig — the returned rig simply has an empty role map, so the
graph binds its own clips directly instead of retargeting.

**Parameters**

- `body` `EntityRef` — The EntityRef of the body to drive.

**Returns** `any?`

## typed/builtin//systems/anim/AnimGraph/rigResolve/R/parseFromClip {#typed-builtin-systems-anim-animgraph-rigresolve-r-parsefromclip}

```lua
R.parseFromClip(ref: any?, rigOverride: any?) -> any?
```

The parsed source rig a clip was authored on. `ref` is a `.animation`
ref; pass `rigOverride` (a `.rig` ref) to force a specific source rig.

**Parameters**

- `ref` `any` _(optional)_
- `rigOverride` `any` _(optional)_

**Returns** `any?`

## typed/builtin//systems/anim/AnimGraph/rigResolve/R/refId {#typed-builtin-systems-anim-animgraph-rigresolve-r-refid}

```lua
R.refId(v: any?) -> string?
```

The asset identity / guid behind a ref value (an AssetRef or a string).

**Parameters**

- `v` `any` _(optional)_

**Returns** `string?`

## typed/builtin//systems/anim/AnimGraph/rigResolve/R/restPose {#typed-builtin-systems-anim-animgraph-rigresolve-r-restpose}

```lua
R.restPose(parsedRig: any?) -> { number }
```

The stride-10 bind pose (translation.xyz + rotation.xyzw + scale.xyz per
bone, in rig order) the graph poses relative to. Undriven channels hold
this; a clip overlays only the channels it drives.

**Parameters**

- `parsedRig` `any` _(optional)_ — A parsed rig (from `retarget.parseRig`).

**Returns** `{ number }`

## typed/builtin//systems/anim/AnimGraph/rigResolve/R/rigKey {#typed-builtin-systems-anim-animgraph-rigresolve-r-rigkey}

```lua
R.rigKey(parsedRig: any?) -> string
```

The identity of a rig AS A RETARGET TARGET — equal for two rigs a clip
bakes onto identically, different whenever the bake would differ. This is the
`cacheKey` half `retarget.bakeBytes` documents as "target rig identity": key
a bake on the rig it targets and every body built from that rig shares one
bake, instead of each re-baking all of its clips.

A rig has no asset identity to borrow — `parseBodyRig` builds it from the
body's live `Skeleton` and `RetargetProfile` — so the key is taken over the
content the bake actually reads: bone names and parents, each bone's rest
transform, and the profile's base + role map. Rests are included because the
bake scales translation by the source/target height ratio, so two skeletons
sharing bone names but not proportions must NOT share a bake. Rest components
are quantized before hashing so a value that differs only in float noise
still lands on one key.

**Parameters**

- `parsedRig` `any` _(optional)_ — A parsed rig (from `retarget.parseRig`).

**Returns** `string` — A short stable string, usable directly as a cache key.

```lua
local key = rigResolve.rigKey(rig)
```

## typed/builtin//systems/characterController/characterController/physics/ceiling/M/cast {#typed-builtin-systems-charactercontroller-charactercontroller-physics-ceiling-m-cast}

```lua
M.cast(x: number, y: number, z: number, height: number, skinWidth: number, selfId: string) -> any
```

Cast a short ceiling-detection ray upward from the character's
head. The ray starts at `(x, y + height - skinWidth, z)` and
travels up for `skinWidth * 2`.

**Parameters**

- `x` `number` — Character feet position X.
- `y` `number` — Character feet position Y.
- `z` `number` — Character feet position Z.
- `height` `number` — Character capsule height.
- `skinWidth` `number` — Collision skin margin.
- `selfId` `string` — Entity ID to exclude from the raycast.

**Returns** `any` — Raycast hit table, or `nil` when nothing overhead.

```lua
local hit = Ceiling.cast(px, py, pz, 1.8, 0.01, selfId)
```

## typed/builtin//systems/characterController/characterController/physics/ground/M/cast {#typed-builtin-systems-charactercontroller-charactercontroller-physics-ground-m-cast}

```lua
M.cast(x: number, y: number, z: number, skinWidth: number, maxDist: number, selfId: string, riseDist: number?) -> any
```

Cast a ground-detection ray downward from a position. Origin is
raised by `skinWidth` plus `riseDist` so the ray starts above the
feet, and the returned `hit.distance` is adjusted back to be
relative to the feet (not the ray origin) — negative for ground
that stands above them.

**Parameters**

- `x` `number` — Character feet position X.
- `y` `number` — Character feet position Y.
- `z` `number` — Character feet position Z.
- `skinWidth` `number` — Small offset above the feet to start the ray from.
- `maxDist` `number` — How far below the feet to check.
- `selfId` `string` — Entity ID to exclude from the raycast.
- `riseDist` `number` _(optional)_ — How far above the feet to check as well. Ground found up
there comes back with a negative `distance`, which is how much the
character has to rise to stand on it. Defaults to 0.

**Returns** `any` — Raycast hit table with `distance` adjusted to be feet-relative, or `nil`.

```lua
local hit = Ground.cast(px, py, pz, 0.01, 0.2, selfId, 0.3)
```

## typed/builtin//systems/characterController/characterController/physics/ground/M/projectOnSlope {#typed-builtin-systems-charactercontroller-charactercontroller-physics-ground-m-projectonslope}

```lua
M.projectOnSlope(moveX: number, moveY: number, moveZ: number, normalX: number, normalY: number, normalZ: number) -> (number, number, number)
```

Project a movement vector onto the slope plane defined by a
surface normal. Computes `v - (v . n) * n` — the component of `v`
that lies in the plane orthogonal to `n`.

**Parameters**

- `moveX` `number` — Movement X.
- `moveY` `number` — Movement Y.
- `moveZ` `number` — Movement Z.
- `normalX` `number` — Surface normal X.
- `normalY` `number` — Surface normal Y.
- `normalZ` `number` — Surface normal Z.

**Returns** `(number, number, number)` — `projX, projY, projZ` — the projected movement vector.

```lua
local px, py, pz = Ground.projectOnSlope(dx, 0, dz, nx, ny, nz)
```

## typed/builtin//systems/characterController/characterController/physics/ground/M/slopeAngle {#typed-builtin-systems-charactercontroller-charactercontroller-physics-ground-m-slopeangle}

```lua
M.slopeAngle(nx: number, ny: number, nz: number) -> number
```

Compute the slope angle (degrees) between a ground normal and
world up. Returns 0 when the input is the zero vector.

**Parameters**

- `nx` `number` — Ground normal X.
- `ny` `number` — Ground normal Y.
- `nz` `number` — Ground normal Z.

**Returns** `number` — Slope angle in degrees, in `[0, 180]`.

```lua
local angle = Ground.slopeAngle(hit.normal.x, hit.normal.y, hit.normal.z)
```

## typed/builtin//systems/characterController/characterController/physics/walls/M/castBody {#typed-builtin-systems-charactercontroller-charactercontroller-physics-walls-m-castbody}

```lua
M.castBody(x: number, y: number, z: number, dirX: number, dirZ: number, height: number, radius: number, skinWidth: number, maxSlopeAngle: number, selfId: string) -> any
```

Sweep the character's capsule from `(x, y, z)` (its feet) in
direction `(dirX, 0, dirZ)` and report the wall it runs into within
`skinWidth` of its own surface. Because the whole body is swept, a
passage narrower than `2 * radius` blocks the character even when
nothing stands on its centre line.

The sweep starts above the ground band — the depth a cap of `radius`
reaches below ground of `maxSlopeAngle`, which is how far into the
slope the body's own lower cap sits while it stands there. Below that
line the surface belongs to the ground and step passes; above it the
sweep runs clear of the ground and reports the outward normal of the
surface standing across the path.

A contact whose surface faces up or down — ramps the character walks
up, to `maxSlopeAngle`, and anything directly overhead — belongs to
the ground and ceiling passes. The sweep carries on past those to the
surface that stands across the path.

**Parameters**

- `x` `number` — Character feet X.
- `y` `number` — Character feet Y.
- `z` `number` — Character feet Z.
- `dirX` `number` — Horizontal movement direction X (normalized).
- `dirZ` `number` — Horizontal movement direction Z (normalized).
- `height` `number` — Character capsule height.
- `radius` `number` — Character capsule radius.
- `skinWidth` `number` — How far past the body's own surface the sweep reaches.
- `maxSlopeAngle` `number` — Steepest surface, in degrees, the character walks on.
- `selfId` `string` — Entity ID to exclude from the sweep.

**Returns** `any` — Hit table `{ entityId, point, normal, distance }`, or `nil` when the body's path is clear.

```lua
local hit = Walls.castBody(px, py, pz, dx, dz, 1.8, 0.3, 0.01, 45, selfId)
```

## typed/builtin//systems/characterController/characterController/physics/walls/M/castDirection {#typed-builtin-systems-charactercontroller-charactercontroller-physics-walls-m-castdirection}

```lua
M.castDirection(x: number, y: number, z: number, dirX: number, dirZ: number, radius: number, skinWidth: number, selfId: string) -> any
```

Cast a horizontal wall-detection ray from `(x, y, z)` in
direction `(dirX, 0, dirZ)`. Ray length is `radius + skinWidth`.

**Parameters**

- `x` `number` — Character centre X.
- `y` `number` — Character centre Y (sample height).
- `z` `number` — Character centre Z.
- `dirX` `number` — Horizontal direction X (normalized).
- `dirZ` `number` — Horizontal direction Z (normalized).
- `radius` `number` — Character capsule radius (ray starts at the centre).
- `skinWidth` `number` — Extra margin for depenetration.
- `selfId` `string` — Entity ID to exclude from the raycast.

**Returns** `any` — Raycast hit table, or `nil` when nothing in front.

```lua
local hit = Walls.castDirection(px, py, pz, dx, dz, 0.3, 0.01, selfId)
```

## typed/builtin//systems/characterController/characterController/physics/walls/M/slideAlongWall {#typed-builtin-systems-charactercontroller-charactercontroller-physics-walls-m-slidealongwall}

```lua
M.slideAlongWall(moveX: number, moveZ: number, normalX: number, normalZ: number) -> (number, number)
```

Compute a wall-slide direction given the desired horizontal
movement and a wall normal. Strips the component of `move` that
goes into the wall; returns the input unchanged when the movement
isn't pressing into the wall (`dot >= 0`) or the normal is
effectively zero in the XZ plane.

**Parameters**

- `moveX` `number` — Desired horizontal movement X.
- `moveZ` `number` — Desired horizontal movement Z.
- `normalX` `number` — Wall surface normal X.
- `normalZ` `number` — Wall surface normal Z.

**Returns** `(number, number)` — Adjusted `moveX, moveZ` that slides along the wall.

```lua
local mx, mz = Walls.slideAlongWall(dx, dz, nx, nz)
```
