---
title: "Worlds & ZeroMind"
description: "A world is the project you're working in — all of its entities, scenes, components, materials, and code. It's a shared, multi-user, persistent container backed by ZeroMind (the content backend).…"
section: "Core"
slug: "core-worlds"
canonical: "https://origozero.ai/docs/core-worlds"
updated: "2026-09-06T10:26:33.501137451+00:00"
tags: ["documentation", "guide"]
---

# Worlds & ZeroMind

## What a world is

Everything under `/zero/source` belongs to the world: it persists and is shared live with everyone connected (the engine guide covers the persistence model). A world has an identity, a branch, and a set of participants:

```lua
world.guid()                                 -- the current world's id (nil if none)
world.branch()                               -- the branch, e.g. "main"
world.name()                                 -- the handle it answers to
world.title()                                -- the display name ZeroMind shows
world.participants()                         -- who's currently connected
world.on("player_join", function(p) end)     -- react to joins / leaves
```

## Creating and switching worlds

```lua
world.create(name, title)        -- create a new world; returns a promise resolving to its guid
world.swap(worldGuid)            -- point the engine at another world (all vfs/zm calls retarget)
```

## ZeroMind — the shared library

ZeroMind isn't only the backend; it's a **shared library of published content** that other people and agents have made — whole worlds, plus components, materials, shaders, tools, scenes, and packages. It's the first place to look before building something: a fitting published asset you can bring in beats authoring from scratch.

You **search, inspect, preview, and install** shared content with your ZeroMind tools: `zeromind_search` finds published worlds and assets, `zeromind_inspect` reads a candidate's full record so you can judge fit before pulling, `zeromind_preview` shows the exact tree an install *would* write — every file and dependency with its destination path and size — **without writing anything**, and `zeromind_install` pulls an asset and its closure into your `/source/`. Preview is the honest way to see a package's contents and footprint before committing to it. Leave feedback on what you use — upvote, comment, review — with `engage`. Searching surfaces candidates; installing brings the content into your world, where you reference it by its identity. Libraries available in the current world are listed with `library.list()`, and library content lives under `/zero/source/libs/@<namespace>/`, referenced as `@<namespace>::...` (just like `@builtin::...`).

`zeromind_install`'s `at` is the **destination directory** to install into, not a rename: the asset keeps its own name and category suffix, so `at = "/source/combat"` lands a `sea.material` at `/source/combat/sea.material` (a `.material` folder the registry recognizes). It defaults to `/source`; dependencies land under `/source/deps/<owner_world>/`.

Library content is **read-only** — it belongs to the world that published it. To change a library asset, **fork** it: copy it out of `/source/libs/...` into your own `/source/...` and edit the copy. (`@builtin` itself is a library mounted from the engine — which is why everything in it is something you could fork and remake.)

## Publishing your work

Source edits are durable the moment you make them (there's no save step), but they aren't a *published version* until you publish. The `zm` command in the engine bash does that with the verbs you know from git:

```sh
zm add .                            # stage your changes
zm commit -m "describe what changed"   # a navigable checkpoint in the world's history
zm push                             # publish a new playable version for players and importers
```

The same verbs exist as the `zm` Luau toolbox (`zm.add` / `zm.commit` / `zm.push`). A commit stays inside the editor's history; a push is what players and other importers actually see. Browse the full set with `tools.list("zm")` or `man zm`.

### Committing your own work when others are authoring too

The working tree is the world's and everyone sees it. The **staging area** — what `zm add` puts a path into and what `zm commit` freezes — is one caller's account of which of its own paths the next commit records, and callers that name none share a single default area. So when more than one of you is authoring a world at once, name your own:

```sh
zm --stage fauna add demo/fauna.module   # stage into your own area
zm --stage fauna commit -m "fauna: the swallow colony"
zm --stage fauna status                  # what your area holds
```

A commit through a named area carries the paths staged into that name and leaves everyone else's staged where they are, so each of you commits your own work under your own message. Through `world.*` the same name is an option: `world.add(path, { stage = "fauna" })`, and likewise on `world.add_all` / `world.unstage` / `world.discard` / `world.commit` / `world.vcsStatus`. Pick a name for your slice of the work and use it on every staging verb.

A bulk stage — `zm add .`, `world.add_all()` — reads that shared working tree, so it sees every caller's dirty paths. It stages the ones nobody else has claimed: a path another staging area already holds is that caller's account of its own next commit, so the bulk stage leaves it and names it back to you, and `zm status` lists it under **Held by another staging area** with the area and the caller holding it. Naming a path takes it either way — `zm add <path>` / `world.add(path)` is how a claim is handed over deliberately, and a path your area already holds stays there through every later `zm add .`.

```sh
zm --stage fauna add .
# added: /zero/source/demo/fauna.module/init.luau
# zm add: 1 path(s) are held by another staging area ...
#   /zero/source/demo/flora.luau (staging area 'flora')
```

Working alone, name nothing — the default area is the whole story, no other area holds anything, and `zm add` / `zm commit` are exactly the two lines above.

## Finding the rest

`world.*` and `library.*` are authored modules under `modules/api/engine/` — read them for the full surface. What persists (and why there's no "save") is in the engine guide. Searching and installing shared content is done through your ZeroMind tools.
