Open World Format

An open format for worlds

The scene, the history that built it, and what happened in it — one .world package anyone can read.

A .world is a folder (a zip is its transport form) holding a world document, a typed state document, an append-only session log, and content-addressed assets. State at any revision is a pure fold of the log over the base — which makes rendering, editing, multiplayer, undo, save games, replays and mods all reads over one history.

It is the layer above glTF, not a competitor: meshes stay glTF leaves, referenced by content hash. glTF owns transport; .world owns composition, parametric authoring, behavior, audio, game state and sessions.

Read the spec

  1. The world document — what a world is
  2. The package — the folder, assets by hash, integrity
  3. The session log — the ops that build a world, and the history around them
  4. Profiles and extensions — must, may, must-ignore
  5. Versioning policy — the compatibility contract

The JSON Schema is normative; the conformance worlds define correct rendering — and you can watch them draw: open the live viewer, the reference three.js renderer running the whole suite in this tab. The same page opens any manifest: world.html?src=….

Try it in a minute

npm install openworldformat
import { parseManifest, parseLogLine, foldLog, toManifest } from "openworldformat";

// manifest.json is the world now — a viewer needs nothing else.
const world = parseManifest(await fs.readFile("world/manifest.json", "utf8"));

// The history folds over snapshots/base.json back to the same world.
const base = parseManifest(await fs.readFile("world/snapshots/base.json", "utf8"));
const entries = (await fs.readFile("world/ops.jsonl", "utf8"))
  .split("\n").filter(Boolean).map(parseLogLine);
const head = toManifest(foldLog(base, entries)); // the same world

Or in Python, where the same fold is pure standard library:

from pathlib import Path
from openworldformat import read_package, fold_log

base, entries, head, package = read_package(Path("world"))
state = fold_log(base, entries)   # the world at head revision
state["entities"], state["applied_edits"]

Agents change a world from outside the app that shows it: they send batches of edit ops to the package’s one authority, which binds names, merges partial patches, reads strictly and commits all or nothing (the session log, “Authoring”).

Get it

Five references parse and fold a .world. Each runs the same conformance worlds and the same authoring outcome suite, so a fold — and a receipt — reads the same in every one.

Tools that use it

Packages are written and read outside this repository, each tool riding one of the references above.

Status

Draft 0.3, describing manifest schema version 3 and package format 2 (head-first). The schema, the conformance suite and the five reference implementations above are in the repository, tested in CI. Expect churn until 1.0; the versioning policy is the contract.

Since draft 0.3, within schema version 3 — every addition optional, so a reader that predates it stays conforming by ignoring it: