Skip to content

Content format ​

Content is JSON in content/<kind>/*.json, validated against the kind's JSON Schema. Layers (last wins): core shipped content, each extension in load order, then worlds/<name>/content/ host overrides. Ids are <owner>:<file basename> unless the file sets "id".

Zones (content/zones/*.json) ​

json
{
  "name": "Meadow",
  "width": 48, "height": 36,
  "start": true,
  "music": "default",
  "layers": [
    {"kind": "terrain", "tileset": "tilesets/water_to_grass", "fill": "upper",
     "cells": ["....", "..##", "...."], "cells_mark": "lower", "solid": "lower"},
    {"kind": "terrain", "tileset": "tilesets/grass_to_dirt", "fill": "lower",
     "cells": ["....", "####", "...."], "transparent_lower": true},
    {"kind": "props", "items": [{"prop": "props/village#3", "x": 10, "y": 12, "solid": true, "footprint": [1, 1]}]}
  ],
  "collision": ["#...", "", ""],
  "spawns": [{"id": "default", "x": 15, "y": 21}],
  "portals": [{"x": 47, "y": 20, "w": 1, "h": 2, "to_zone": "core:grove", "to_x": 1, "to_y": 9}]
}

Terrain layers use the library's Wang-corner tilesets (tilesets/<lower>_to_<upper>). Each tileset blends a lower terrain into an upper one. A layer paints one tileset:

  • fill: lower (default) or upper, the terrain everywhere before cells are applied.
  • cells: height strings of width chars; # marks a cell. Every vertex touching a marked cell takes cells_mark (upper default, or lower). Or give corners directly: height+1 strings of width+1 chars, # = upper.
  • solid: upper or lower. A cell is solid when all four of its corners are that terrain, so shorelines stay walkable and open water does not.
  • transparent_lower: true: skip drawing cells that are fully lower, so the layer under it shows through (use for a path or a patch on top of a base layer).

Props: prop is props/<set>#<index> from the library's index.json. Props are y-sorted with characters. solid: true blocks the cell at (x, y), or footprint: [w, h] cells up and to the right of it. flat: true draws under everything (rugs, floor marks).

Tiles layers (kind: "tiles") place explicit tiles: {"tileset": "...", "cells": [[x, y, "tile_id"], ...]}.

Collision: optional override rows; # solid, . open, space inherits from the layers.

Spawns: tile coordinates; default is used for new characters. Portals are tile rectangles that teleport a player to to_zone at (to_x, to_y).

Zones smaller than 48x48 skip the replication radius filter; everyone in the zone sees everyone.

Items (content/items/*.json) ​

json
{"name": "Iron Sword", "icon": "items/weapons_armor#0", "stack": 1, "kind": "weapon",
 "description": "A plain blade.", "value": 25, "rarity": "common", "data": {"attack": 4}}

icon is a library reference. data is free-form for extensions (equipment reads slot, attack; crafting reads nothing). stack defaults to 1.

Host overrides ​

Drop a file into worlds/<name>/content/<kind>/ with the same id to replace an entry, or a new file (id becomes host:<basename>) to add one. Validate with the launcher's Content tab or:

mmorun-server --validate ./worlds/<name>/content

MMO Run: host your own pixel-art MMO.