pxart help worlds
Worlds
Compile a world of .map rooms into Tiled's .world and .tmj files.
WORLDS (pxart help worlds)
export world.src.json|ROOM.map|DIR... --tiled [--tile 16x16] [--tileset T.tsj]
check world.src.json|W.world|ROOM.tmj|DIR... [--tile 16x16] [--tileset T.tsj]
world W.world|ROOM.tmj -o world.png [--scale 2] [--dry-run]
A world is rooms drawn as .map files (scene --map's format) and a world.src.json that
places them and wires their doors. --tiled (with no X.tsj) compiles them to Tiled's
files, beside them: rooms/NAME.map -> rooms/NAME.tmj, world.src.json -> world.world
(NAME.src.json -> NAME.world). check runs the same compile and writes nothing: 'ok
world.src.json: 3 rooms placed, interior tower, 1 door pair, start in shore', or FAIL
and every error. A DIR stands for the world sources under it (a rooms/ directory is
an error naming its world). --tile: the rooms' tile size (default 16x16).
The source:
{"layout": ["shore point", "cove ."],
"start": {"room": "shore", "at": "@"},
"doors": [["point D", "tower d"], ["shore H", "hut h", {"trigger": "use"}]]}
layout draws where rooms sit ('.': none; a column as wide as its widest room, a row as
tall as its tallest, an empty one as the largest room). A room only doors name is an
interior: compiled, not in the .world. start: a point object (class start) at the
feet (bottom centre) of the one cell shore.map draws '@' on. A door pair is two door
objects (class door), each the rectangle of cells its char is drawn on, with target
(the other's .tmj), entry (the other's name) and the pair's {...} as properties
(trigger: touch, the default, or use; target and entry are the compiler's).
Variant tiles: a legend line may list tiles, '1 sand.png sand2.png sand3.png' (two or
more, each a .png or .px[:frame], quoted if it has spaces). Each cell drawn with 1
gets one, picked by cell_hash(room, x, y), the room being the map's file name without
.map; scene, compose --map and export --tiled pick the same one.
What a room compiles to: a layer's one-tile cells make a tile layer ('layer N'); +b
entries, art of another size, and cells an earlier object in the layer overhangs are
tile objects named by their char ('layer N objects', in draw order), where scene
draws them, so Tiled renders what scene --map does, pixel for pixel. Flips are GID
flags. The .tmj's 'source' property names its .map.
Tilesets: a cell's art is found in <dir>/tiled/*.tsj in the directories above it (its
pack's; the search stops at a directory holding a *.src.json or .git) and in
--tileset's: a PNG by a tile's png property (or image), a .px frame by its pixels. A
GID is firstgid + that tile's stable id. Tilesets start at firstgid 1, 1001, 2001...
(a bigger one at the next such after its end), so one that grows moves no other; a
tileset keeps its previous firstgid while it fits.
Object ids are stable: a recompile reads the previous .tmj and keeps the id of the
object of the same layer, class and name at the same cell; a new object takes
nextobjectid; an id is never reused. An object in the previous .tmj that isn't from
the source (added in Tiled) is dropped, with a WARNING. A .tmj whose 'source' isn't
its .map (a room made in Tiled) is never overwritten (E_GENERATED). A .map that's a
world's room (rooms/ beside a *.src.json, or a .tmj with doors or a start) isn't
compiled alone (E_WORLD): compile its world.
Errors are said all at once, at file:line:col, and nothing is written: a ragged row
(E_ROW_WIDTH), a ground (layer 1) shorter than the room (E_MAP_SIZE), an unknown char
(E_UNKNOWN_KEY), art no tileset has (E_TILESET), a door or start char not drawn as one
rectangle or at one cell (E_DOOR, E_START), a bad world source (E_WORLD). A shorter
layer above the ground, and art bigger than a cell without +b (placed by its
top-left), get a WARNING. Then the world rules run on the compiled files: doors pair
up and have a walkable cell beside them, one start, not in a solid, every door
reachable from it, rooms don't overlap. A broken rule is 'E_WORLD: door-arrival:
...'; a warning (an edge walkable on one side only, a room nothing reaches) is a
WARNING line. The rules are one spec with shared fixtures, run by pxart and the
harness: tests/fixtures/world_rules/ (SPEC.md) in the pxart repo.
Compiled worlds (the runtime files, so a world made in Tiled too): check W.world runs
the world rules on the .world, the rooms it places and every room a door leads to,
exactly as the compile runs them: 'ok world.world: 3 rooms placed, interior tower, 1
door pair, start in shore', or FAIL and each error, 'rooms/point.tmj: E_WORLD:
door-pair [D, cell 10,7]: ...' (the door's or start's name, or the edge's side, and
the cell); a warning is a WARNING line. A lone ROOM.tmj is a world of that one room
(placed at 0,0, its doors leading to its interiors); a .tmj that a .world beside it or
one directory up has (placed, or through doors) is E_WORLD: give the world (and so
is one beside a .world that can't be loaded: fix that). A DIR checks the world
sources and the .world files under it, but not a .world beside a *.src.json (its
source is the same compile); a DIR of .tmj rooms only says to check their world.
Only orthogonal, finite maps with CSV (JSON array) tile data, in JSON files, are read
(a .world placing maps by patterns, a .tmx map or .tsx tileset is E_WORLD, naming what
to change in Tiled), as the harness reads them: SPEC.md, 'Not rules'.
world draws one: each room as Tiled draws it (markers too), the placed ones where
the .world puts them, spread apart so a shared side shows as a gap, and interiors in
a column to the right. Across each shared edge, a band per cell: yellow where both
sides are walkable (you can cross), magenta where only one is (edge-one-side; the
walkable cell outlined), nothing where both are solid. Each door is outlined, with a
dot on each cell you arrive on beside it and a line to its entry, arrowheads at the
doors it leads to (a door that doesn't pair up: magenta, one arrowhead). The start
is a green cell, markers cyan rings. Every rule issue is a numbered magenta tag
where it is (a cell, a door, a room; tags that would overlap move aside), listed
under the picture and printed ('[1]
WARNING: rooms/cove.tmj: edge-one-side [north, cell 1,0]: ...'); an unreachable
room is hatched, a room the .world names but can't load crossed out. A broken world
still draws (exit 0): check is the verdict. world reads compiled files only ('export
world.src.json --tiled' first). --scale (default 2) scales the rooms, not the gaps
or labels.
Error codes: E_MAP_SIZE E_TILESET E_GENERATED E_WORLD E_DOOR E_START, and the map's
own (E_ROW_WIDTH E_UNKNOWN_KEY E_BAD_ROW E_FILE).This page is built from
site/src/data/reference.json in the repository.Edit on GitHub