---
title: "Discovering the engine"
description: "You don't need to memorise this engine. Its surface is discoverable in layers, and the order matters: the jobs it already knows how to do, the kinds of thing it can make, the operations it already…"
section: "Core"
slug: "core-discovering"
canonical: "https://origozero.ai/docs/core-discovering"
updated: "2026-09-05T16:41:46.364488916+00:00"
tags: ["documentation", "guide"]
---

# Discovering the engine

## Start with the job — skills

`agent_skill` with no argument lists every skill this world has: a packaged procedure for a whole job, carrying the systems it runs through and the checks that say it worked. If one matches what you are about to do, open it before designing anything. A skill is the already-correct path.

## Then the kinds of thing — asset types

`assets.types` lists every registered assetType — the **scaffolding you build inside**. This is the layer that is easiest to skip and most expensive to miss: a job that has no matching tool very often has a matching *type*, already shaped for it.

- `assets.types <query>` — what kinds exist, and which can become an entity in a scene.
- `assets.typeDoc <name>` — that type's own documentation: which file is its source, what regenerates when, what it handles for you.
- `assets.typeBehavior <name>` — what it can already do: the `ref:` methods, the lifecycle hooks it runs, whether it is scene-capable.

"Generate this from parameters and let someone retune it" is a `procGraph` with a `Generator`. Ground is a `terrain`. Many of one thing is a `population`. Writing a module and a component that do the same work by hand is a project; building inside the type is a few lines.

## Then the operations — tools

A **tool** is an operation the engine already implements, named and typed, grouped into a **toolbox**. Spawning a model, aiming a camera, baking lighting, taking a screenshot, reparenting a subtree, running the test suite — each is a tool someone already got right. Browsing the toolboxes is how you learn what the engine does at all.

From the shell, `zero` is the whole surface:

```bash
zero                              # every toolbox and what it covers
zero camera                       # the tools in one toolbox
zero camera lookAt --help         # one tool: every argument, its type, whether it's required
zero camera lookAt --camera main --target 0,5,0
zero --search lighting            # keyword search across every toolbox (short: -k)
```

**`--help` answers at every level**, which is the whole walk from "what exists" to a correct call: `zero --help` is the overview, `zero camera --help` lists that toolbox's tools, `zero camera lookAt --help` details one tool. You never have to guess a name or an argument.

Arguments are named (`--camera main`) or positional in signature order; `--help` prints both forms for the tool in front of you. A value that reads as JSON is passed as JSON — `12`, `true`, `[0,5,0]`, `{"fov":60}` — and a bare run of numbers like `0,5,0` becomes an array.

The same registry answers over MCP as `search_tools` (browse and search), `describe_tool` (one tool's full schema, the MCP spelling of `--help`) and `use_tool` (run one). From Luau code it is `tools.use`, which returns the tool's value and raises on failure:

```luau
local cameras = tools.use("camera", "list")
```

The right tool often lives in a toolbox you would not guess — re-skinning a hierarchy is under `appearance`, screenshots under `capture`, scene structure under `scene`. That is why browsing (`zero` with no arguments) is worth a call before searching for a name you have imagined.

Finding nothing that covers the task is a useful answer too: the work belongs in the API layer below, and once it works it is worth packaging as a `.tool` so the next reader gets it in one call.

## Then the API — what tools are built from

The engine exposes well over a hundred namespaces (`asset`, `entity`, `layers`, `mesh`, `compute`, `vfs`, `camera`, `players`, `ui`, `Material`, `anim`, …) — its **core callable API**. That API is **authored Luau**: ordinary modules under `/zero/source/libs/@builtin/modules/api/engine/`, which everything else in the engine is built on top of. There's no hidden layer you can't see.

Ask the language server for the shape of any of it:

```luau
lsp.namespaces()               -- every namespace (name, method count)
lsp.methods("asset")           -- a namespace's methods, with signatures + docs
lsp.describe("asset/create")   -- one method: signature, args, return, examples
```

Each of those answers with the surface you call. Under most namespaces sits an
engine primitive the module calls, installed under a `__`-prefixed name; the
listings leave it out and `{ includeInternal = true }` puts it back.

Read the implementation when a signature isn't enough — it *is* the implementation:

```bash
ls  /zero/source/libs/@builtin/modules/api/engine                          # the engine's API modules
rg  "spawn" /zero/source/libs/@builtin                                     # search all source
cat /zero/source/libs/@builtin/modules/api/engine/asset.module/init.luau   # read how asset.* works
man asset/create                                                           # the generated reference page
```

And ask the content registry what exists:

```luau
asset.list("material")                       -- registered content, by type
asset.inspect("@builtin::materials.gold")    -- a full summary of one asset
```

## Confirm anything live

```luau
type(_G.asset)        -- is it there?
```

Run the call and read what comes back. The running engine is the final authority: when a doc and the engine disagree, the engine wins.

## Check what's broken

When something isn't behaving, ask the engine what's wrong rather than guessing — the `diagnostics` toolbox reports the current error state across assets, components, and the engine:

```bash
zero diagnostics errors      # the active errors
zero diagnostics summary     # a roll-up
zero diagnostics validate    # re-check and report problems
```

(A single component's own errors are also on its instance — `reportError`/`errors`, the components guide.)

That is the current *state*. What actually happened, in order, is in the log ring — every level, every subsystem, plus every `print` and `log.*` a script made — and there are two ways at it. The `logs` toolbox queries it:

```bash
zero logs errors             # recent errors and warnings
zero logs search --help      # by severity, subsystem, text, script, entity, time window
zero logs summary            # the shape of what is there before you read inside it
```

The same ring is also mounted as plain files, for when you can already name the string you are after:

```bash
grep -i "my_material" /zero/runtime/logs/engine   # every level, most recent 500 lines
cat /zero/runtime/logs/errors              # the ERROR-and-above subset of the same
cat /zero/runtime/logs/script              # what scripts logged
```

Reach for whichever fits the question. A message you can name is quicker to grep; a question with a shape to it — one entity's lines, what surrounded a failure, which message repeats and how often — is what the tools are for. The troubleshooting guide has the whole surface.

## The method, in order

1. **`agent_skill`** — is this whole job already a packaged procedure?
2. **`assets.types`** — is there a KIND of thing shaped for this? Then `assets.typeDoc` and `assets.typeBehavior` on the one that fits.
3. **`zero`** — browse the toolboxes, then the tools in the one that fits. An operation that already exists is one call.
4. **That system's own registry** — a system's vocabulary is not in the tool registry. The procedural op registry answers to `procgen ops`, not to `search_tools`; other systems keep their node types and templates the same way. No tool matching your job is not evidence the capability is missing.
5. **`lsp.*` / `man` / the API source** — the namespaces a tool is built from, for the work genuinely nothing covers.
6. **A live call** — the running engine settles every disagreement.

The concept guides — assets, components, the tool system, scenes, the engine, worlds — teach the *systems*; the steps above are how you find the *specifics* of any of them.

Skipping steps 1, 2 and 4 is the expensive mistake, because their absence looks exactly like the capability not existing. An agent that checks only tools, finds nothing, and starts writing will produce a working system that duplicates one already installed.
