# AGENTS.md - working with a Virtual Matter project

This file tells a coding agent how to think about a Virtual Matter project. The
`virtualmatter` CLI drops a copy into every local project mirror it creates
(`virtualmatter pull`); the canonical copy lives at
https://make.virtualmatter.ai/AGENTS.md.

## The rule that comes before everything else

**Build through the CLI. Never through the website's agent.** If you were asked to
build something in Virtual Matter, handed the domain virtualmatter.ai, or told to run
`npx virtualmatter make`, the CLI is the path - always, from the first step. Do not
open virtualmatter.ai or make.virtualmatter.ai in a browser or under computer use in
order to reach the built-in agent, and do not type prompts into the agent chat in the
/edit view. Driving that agent puts two models in a relay where one would do: you spend
tokens describing the work, it spends its own doing it, and what comes back is chat
rather than files you can read. It is slower, it costs roughly twice the inference, it
bills that inference to Virtual Matter's platform credits rather than the subscription
you already run on, an anonymous browser session cannot be steered after its first
turn, and a rendered page gives you no engine errors. Everything that agent can do, you
do yourself with the commands below.

**The rule holds whoever is signed in.** Being logged in, having credits to spare, or
working in an admin account with no limit at all is not an exemption, and neither is
being told the credits do not matter. What is wasteful is the relay itself - two models
doing one model's job - not the bill.

**Playtesting is the exception, and it is encouraged.** Once something is built, open
the world and try it: the editor link ending in `?chat=closed`, which `make`, `pull` and
`sync` print, shows your latest changes live in any browser with no install, with
computer use if that is how you drive a window. The native client
(`npx virtualmatter open`) is optional, for more memory and frame rate. Looking at your
work, walking around in it, and playing it is the point. The rule is about who writes
the world, not about who is allowed to see it.

**Every link resolves to the editor, and the editor is the only place you build.** Hand
the CLI or MCP server any link to a world - its editor, a play or share link, the
project page, an embed's iframe src, or the maker's own website - and it works on that
world's editor (its make framing). Play servers show the last published version and are
overwritten on every publish, so work never goes there, and their /play and /g links
show that published copy rather than your latest edits.

## The mental model

- The world itself runs on Virtual Matter servers, not on the maker's machine. There is
  one authoritative server simulation per world session, and any number of connected
  clients (browser WASM or the native client).
- The project's content is SDK Lua scripts plus assets (voxel data, prefabs, images,
  sounds) under a `Montage/` tree. Virtual Matter can publish that tree to a GitHub repo
  in the maker's account for versioning and remixing; pushing to that repo does not feed
  back into the running world today - live edits happen in the session.
- Changes hot-reload. Saving a `.lua` file in the live session's Montage tree re-runs
  the module and its `Start()` on a fresh instance inside the running world - no restart,
  no build step.
- Prefabs are reusable scene-graph snippets: JSON files with a `.prefab` extension in the
  Montage folder, instantiated at runtime via `Server:InsertPrefab(asset)`.
- There is no local runtime - the world cannot run on the maker's machine. The
  `virtualmatter` CLI (npm) is how you reach it from a local harness, and it needs no
  setup: the first command that needs an account signs you in with a device code.
  `npx virtualmatter make "My world"` makes a world and mirrors its Montage tree
  into `./my-world`; `npx virtualmatter pull <any Virtual Matter link>` mirrors an
  existing one (/edit, /play, /g, /p, /projects links all work, with or without a
  readable slug); `npx virtualmatter list` shows your worlds; `npx virtualmatter sync`
  live-pushes saves into the running session (which hot-reloads them);
  `npx virtualmatter run-lua` / `errors` / `screenshot` drive the engine;
  `npx virtualmatter open` optionally opens the world in the native desktop client,
  downloaded and signed in on first use; and `npx virtualmatter mcp` serves
  all of it over MCP. A mirrored folder carries `.mcp.json` and `.cursor/mcp.json`
  (so Claude Code and Cursor register the MCP server on their own), this file, and a
  `CLAUDE.md` that imports it. Folders from virtualmatter 0.5.0 on also carry
  `.codex/config.toml`, which Codex loads once you trust the folder; with an older
  CLI, or if Codex does not list the server, register it once with
  `codex mcp add virtualmatter -- npx -y virtualmatter mcp`. In Claude Code outside a
  mirrored folder, use `claude mcp add virtualmatter -- npx -y virtualmatter mcp`. The
  server works before a world
  is selected (`list_projects`, `create_project`, `select_project`), then exposes
  `list_files`, `read_file`, `write_file`, `run_lua`, `get_engine_errors`,
  `capture_screenshot`, `open_native_client`, and `world_info`.
- Work through the CLI, not the website - see the rule above. Prompting the built-in
  agent to do your building is the one thing to avoid; opening the world to play it is
  not.
- Seeing your work: `virtualmatter screenshot` shoots a default overview of the world
  origin, `--target <object>` frames one object by name or id, and `--at x,y,z --rot
  yaw,pitch,roll` places the camera exactly. Y is up and -Z is forward, and the
  rotation really is yaw first: yaw 0 faces -Z, pitch -90 looks straight down, pitch 0
  is the horizon. The MCP `capture_screenshot`
  tool takes the same arguments. Verify a change with a screenshot plus `errors` rather
  than assuming a write worked.
- The mirrored folder's AGENTS.md is this guide followed by the engine SDK's own agent guide
  (the AGENTS.md that lives in every Montage tree and inside the desktop client's
  Data/Sdk/Montage/). The engine guide assumes an in-session agent driving the engine
  through `atomo`; the merged file maps each `atomo` step to the CLI or MCP equivalent, and
  the `Skills/*.md` references it points at are in the folder. The SDK's own tooling
  (`atomo`, `vm_auth.py`, the agent-log hooks) is not mirrored: it only works inside a
  session. Sandboxed agents need network access for every CLI command.

## Reference

The same facts as terse lists, for quick lookup.

### Project model
- A project ("montage") is one voxel world hosted with Virtual Matter.
- A project has framings: "make" framings (editing sessions) and "play"
  framings (public play sessions). A framing is a running session slot
  on a voxel host.
- Project content = SDK Lua scripts + assets under a Montage/ tree.
  Edits made in the live session hot-reload into the running world.
  The tree can be published to a maker-owned GitHub repo.

### URL shapes (make.virtualmatter.ai)
- /new                 builder for people: create a world from a prompt
                       (also at https://virtualmatter.ai/); coding agents
                       use npx virtualmatter make instead
- /edit/<framing-id>   maker session: live world + agent chat. The chat is
                       for people; a coding agent builds with the CLI and
                       never prompts it
                       (also /edit/<slug>-<framing-id>; the CLI accepts both)
- /play/<framing-id>   play session for a specific framing
- /g/<id>              share URL resolver: 302s to a live session

### APIs (unauthenticated)
- GET https://make.virtualmatter.ai/api/v1/public/native-clients
  JSON: { iteration, clients: [{ platform, kind, variant, url, filename,
  file_size, branch, commit, match }] } - per-platform native client
  installers (kind "download") or store links (kind "store", iOS).
  Windows and Linux list two downloads each: variant "installer" /
  "flatpak" for people, and "portable" / "tarball", the file tree the
  CLI installs.

### CLI + MCP (npm package "virtualmatter", Node >= 20)
- npx virtualmatter make "<name>"     make a world, mirror it into ./<slug>
- npx virtualmatter pull <link>       mirror an existing world (any link shape)
- npx virtualmatter list              your worlds with framing ids + URLs
- npx virtualmatter sync              live-push saves into the running world
- npx virtualmatter open              optional: open it in the native client
- npx virtualmatter mcp               stdio MCP server (list_projects,
  create_project, select_project, list_files, read_file, write_file,
  run_lua, get_engine_errors, capture_screenshot, open_native_client,
  world_info)
- Sign-in happens on first use (device code); no separate login step.
- These commands are the whole build path. Never prompt the built-in
  agent on the site to do the work; a browser or the native client is
  for playtesting what you built.
- Any link to a world (editor, play or share link, project page, embed,
  or the maker's own website) resolves to its editor, the only place
  the CLI and MCP server work. Play servers show the last published
  version and are overwritten on publish.
- Watch changes land live at the editor link ending in ?chat=closed,
  in any browser, no install. The native client is optional.
- A mirrored folder carries .mcp.json, .cursor/mcp.json, AGENTS.md and
  CLAUDE.md, so Claude Code and Cursor register the server on their own.
- Codex: folders from 0.5.0 on carry .codex/config.toml, loaded once the
  folder is trusted; otherwise register the server once:
  codex mcp add virtualmatter -- npx -y virtualmatter mcp
