world
The world namespace — the engine's Luau API reference for world.
The world namespace — 51 functions.
globals/world/add
globals/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.
globals/world/add_all
globals/world/add_all() -> { string }
Stage every dirty manifest row, 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.
globals/world/affirm
globals/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.
globals/world/args
globals/world/args() -> any
globals/world/avatar_default_edit
globals/world/avatar_default_edit() -> any
globals/world/avatar_default_play
globals/world/avatar_default_play() -> any
globals/world/camera_default_edit
globals/world/camera_default_edit() -> any
globals/world/camera_default_play
globals/world/camera_default_play() -> any
globals/world/checkUpdates
globals/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.
globals/world/commit
globals/world/commit(message: string) -> string
globals/world/conflicts
globals/world/conflicts() -> { ConflictEntry }
List every locally-pulled row currently flagged conflicted —
the findable surface world.pullAsset leaves behind on an
unresolved merge. Read-only.
globals/world/connectedUsers
globals/world/connectedUsers() -> any
globals/world/contentRequirements
globals/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 zm status surfaces it as "requires content before
publish". Empty list = every checked asset meets its type's contract.
globals/world/contribute
globals/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.
globals/world/createBranch
globals/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 with
world.swap(world.guid(), "", "", "<branch>") (git checkout).
globals/world/diff
globals/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.
globals/world/discard
globals/world/discard()
Drop the implicit stage without committing. Live manifest dirty flags are preserved so the user can re-stage later. No-op if the stage doesn't exist.
globals/world/discardFile
globals/world/discardFile(path: string)
Discard one file's unstaged working edits, reverting its
content to the last commit — the git restore <path> shape.
One shot: the discarded bytes are snapshotted to trash first, so
the discard is recoverable via world.restore(<handle>). Errors
when the path is not dirty (nothing to discard) or was never
committed (nothing to revert to — remove it instead).
globals/world/fetch
globals/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().
globals/world/forkLive
globals/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.
globals/world/forkStatus
globals/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.
globals/world/head
globals/world/head() -> string?
Return the current branch HEAD commit id, or nil if the branch has no commits yet.
globals/world/installAsset
globals/world/installAsset(opts: InstallAssetOpts) -> InstallAssetResult
globals/world/installLibrary
globals/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.
globals/world/list
globals/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.
globals/world/log
globals/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.
globals/world/merge
globals/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.
globals/world/mergeAbort
globals/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.
globals/world/prList
globals/world/prList(worldGuid: string?, number: number?) -> any
List a world's pull requests, or fetch one.
globals/world/prMerge
globals/world/prMerge(worldGuid: string, number: number, strategy: string?) -> any
Merge a pull request — the agent-side merge button.
globals/world/previewInstall
globals/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.
globals/world/pull
globals/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.
globals/world/pullAsset
globals/world/pullAsset(opts: PullAssetOpts?) -> PullAssetResult
globals/world/push
globals/world/push(commitId: 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).
globals/world/reset
globals/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.
globals/world/resolveConflict
globals/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.
globals/world/resolvePullConflict
globals/world/resolvePullConflict(path: string, choice: string)
globals/world/restore
globals/world/restore(handle: any)
Restore one trash entry by row_id. Errors verbatim on handler-not-yet-implemented / world-mismatch.
globals/world/show
globals/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.
globals/world/startup_scene
globals/world/startup_scene() -> any
globals/world/stash
globals/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.
globals/world/stashDrop
globals/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.
globals/world/stashPop
globals/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).
globals/world/stashes
globals/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.
globals/world/status
globals/world/status() -> any
globals/world/status_text
globals/world/status_text() -> any
globals/world/syncStatus
globals/world/syncStatus() -> SyncStatus
Read the durable-sync status: { subscribed, content_synced, progress, pending_writes, conflicts }. conflicts maps each
conflicted /source path to { base_sha, local_sha, backend_sha, isBinary }. Synchronous.
globals/world/trash
globals/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.
globals/world/uninstallLibrary
globals/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).
globals/world/unstage
globals/world/unstage(path: string)
Remove a path from the staging area. Live manifest dirty state is untouched.
globals/world/vcsStatus
globals/world/vcsStatus() -> StatusResult
Return the working-tree VCS status: dirty paths, staged
entries, and (always empty in the spacetime model) untracked.
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 SpacetimeDB Identity hex of
the most recent writer; dirty_since_micros is the microsecond
timestamp of the first write of the current dirty run.