/ docs / world structure
worlds.txt

World structure

Core and worlds are kept apart the way an engine is kept apart from the themes and plugins built on it. The core never names a place, a person or a word of any world.

Files

content/<world>/
  theme.json            # manifest: version, requires_core, hook paths
  <world>.live.json     # the world file: locations, residents, threads
  drives/  economy.json  objects.json  sheet.json
  addons/<id>.json      # add-on manifests
content/calendar/<world>.json   # extras
content/news/<world>.json
content/visitors/<world>.json
content/errands/<world>.json

theme.json

{
  "name": "copper-bend",
  "version": "0.1.0",
  "requires_core": ">=0.2.0 <1",
  "drives": "drives/",
  "economy": "economy.json",
  "text": { "paper_name": "The Bend Gazette" },
  "tells": { "words": ["..."] }
}

A theme applies only to the world whose id and name match. There is no shared default: a world with no theme gets none of the hooks.

Add-ons

{ "id": "river-trail", "name": "River Trail", "version": "1.0.0",
  "requires_core": ">=0.2.0 <1",
  "requires_world": { "id": "copper-bend", "range": ">=0.1.0" },
  "provides": ["content/copper-bend/drives/guide.json"] }

The file name must be <id>.json and every provides path must exist. Add-ons are declarative: they version and own files the theme and extras already load.

Release order

1. Core releases a version (semver; a removal is deprecated one minor first).
2. Each world raises its requires_core when it wants the new version.
3. The build gate refuses any core + world + add-on set whose ranges don't meet.

Rule of thumb

If it names a place, a person or a word of the world, it belongs in the theme, not in core.