> ## Documentation Index
> Fetch the complete documentation index at: https://docs.ngram.space/llms.txt
> Use this file to discover all available pages before exploring further.

# Give creations their own behavior

> Run scoped JavaScript beside the renderer so creations respond immediately without per-frame model calls.

The agent writes a program once. The browser runs its animation and interaction handlers locally, including after the agent finishes speaking. A sculpture can turn when you press a button; a slider can change its speed without another model request.

## A working turntable

[Download the complete tool-call example](/assets/creation-turntable.json). It creates a grabbable box, a numeric toggle, and a speed slider, installs a scoped program, and resumes the world. Ask the agent to execute the calls in order through `ar_world` after choosing a clear origin. The file contains tool calls, so do not use the world **Import** button for it.

Its JavaScript source is:

```javascript theme={"theme":"github-light-default"}
return {
  tick() {
    const model = api.get('turntable.model');
    const toggle = api.get('turntable.toggle');
    const slider = api.get('turntable.speed');
    if (!model || model.heldBy || !toggle || !slider) return;
    if (toggle.control.value === 0) return;
    const rotation = model.transform.rotation.slice();
    rotation[1] += slider.control.value * api.dt;
    api.emit([{
      op: 'entity.patch',
      id: model.id,
      patch: { transform: { rotation } }
    }]);
  }
};
```

The program starts with the toggle off. It reads the live rotation each frame, so a human rotation becomes its new starting point. It preserves position and scale and skips a held object. Toggle values are numbers: `0` is off and `1` is on.

Use the same pattern with a Blender asset: obtain its ID from `ar_world observe`, substitute that ID for `turntable.model`, and include it in the program's `entityIds`. This controls the imported asset's scene transform. It is not direct access to Blender's Python process or every internal mesh node.

## Install through the agent

Call `ar_world` with `command: "program"` and a payload containing `command: "install"` and `program`:

| Program field | Meaning                                                                               |
| ------------- | ------------------------------------------------------------------------------------- |
| `id`          | Stable program ID; installing it again replaces the previous version after validation |
| `name`        | Optional human-readable label                                                         |
| `source`      | JavaScript returning `tick`, `event`, or both                                         |
| `entityIds`   | Existing objects the program can read and control                                     |
| `params`      | JSON settings that can be updated without changing the source                         |
| `state`       | Mutable JSON state saved at checkpoints                                               |
| `hz`          | Tick rate from 1 to 30 Hz                                                             |

Create the objects before installing their program. For manual experiments, select an object, open **Objects → Programs**, enter source, and choose **Run on selected object**. That editor scopes the program to the selected object only; use the agent API when a program needs multiple objects and controls.

## Runtime API

| API                    | Value or behavior                                                        |
| ---------------------- | ------------------------------------------------------------------------ |
| `api.get(id)`          | Live scoped entity snapshot, including transform, controls, and `heldBy` |
| `api.dt`               | Seconds since the previous simulation step, bounded by the runtime       |
| `api.time`             | Program simulation time in seconds                                       |
| `api.params`           | Current JSON parameters                                                  |
| `api.state`            | Mutable JSON state                                                       |
| `api.emit(operations)` | Validated world operations for the program's allowed objects             |

An `event(event)` handler receives scoped `grab`, `release`, `control`, collision, and edit events. Events include `type`, `target`, `actor`, and `data`; a control change supplies `data.value`. Read the current `capabilities` result for the full contract.

Programs can patch transforms, geometry, materials, visibility, controls and physics, apply impulses, and drive joints whose bodies are both in scope. They cannot create or delete objects, install more programs, use the DOM, import code, or access the network. The runtime rejects physical changes to held objects even if a program forgets to check `heldBy`; properties and nonphysical responses such as glow can continue while held. [Figments](/spatial/figments) add portable named bindings and exposed properties to this runtime.

## Inspect, pause, and resume

```json theme={"theme":"github-light-default"}
{
  "name": "ar_world",
  "arguments": {
    "command": "program",
    "payload": { "command": "inspect", "id": "turntable.rotation", "includeSource": true }
  }
}
```

Inspect reports state, errors, frames, and simulation time. Use program commands `pause`, `resume`, `remove`, or `parameters` with its ID. The `parameters` command takes a `params` object. Pause all creations with `ar_world pause` or the **Pause creations** button.

World exports retain source, parameters, JSON state, and simulation time. Imported and restored programs remain paused until resumed. Local programs stop stepping while the page is hidden.

The runtime allows 12 programs and 64,000 source characters per program. A worker that fails or exceeds its 500 ms response budget terminates without blocking the main scene. Keep work per tick small; use instancing or authored GLB animation for repeated visual structure.

## Model usage

Program frames, physics, control events, and Blender preview delivery do not initiate model calls. Asking the Entity to design or change a creation does use inference. Other background Entity tasks remain independent; use [Pause inference](/guides/usage-and-controls#pause-model-use) when you want to stop model use globally.
