5.6 KiB
.llamalevel – level project format (version 1)
A zip file (deterministic: fixed entry times, level.json first, then thumbnail.png, then the
assets sorted by path). Code: editor.io.ProjectIO, SceneDiff, NodeCodec.
| Entry | Content |
|---|---|
level.json |
header + the changes against the reference scene (below) |
thumbnail.png |
optional preview (also used for the TestLevel loading picture) |
assets/<name>/… |
imported meshes with their MTL/textures/buffers (MeshAsset.file points here) |
assets/pages/<id>.png |
pixels of added texture pages (lossless: ABGR1555 ↔ RGBA with alpha 0/128/255) |
No original game data. A project is stored as the difference to a reference scene that is rebuilt from the user's own CD when the project is loaded:
kind: "edit"– reference = the original levelbaseimported unchanged (Templates.original).kind: "new"– reference =basewith all tiles, tile models, objects and waypoints removed and visibility regions off (Templates.newLevel). The base contributes object code (STPC), textures, zones (fog/music), lights and sound. Default baset1l1m001(village). A newly created project (Project.create) additionally removes, as ordinary edits stored in the diff, everything bound to the base's positions (Templates.clearBaseLeftovers, since 0.2.0): all zones except the start zone (flag 8), all non-directional lights, waypoints, and sets every region mask to "all". The reference stays unchanged, so projects saved before keep their zones and lights. Textures stay (STPC object models index them).
Building the same project with the same CD gives a byte-identical WAD (WadBuilder is
deterministic; brushes use the stored seed).
level.json
{
"formatVersion": 1,
"app": "LlamaMod level editor",
"kind": "new", // "edit" | "new"
"base": "t1l1m001", // base level (CD wads/<base>.wad)
"baseSha256": "9cff…", // of the base WAD; a mismatch gives a load warning
"name": "Testwelt", // copies of settings for listing without the CD
"targetChapter": 2, // TestLevel chapter for new levels (0 = none)
"nextId": 264, // counter for new node ids ("kind:nN")
"settings": { "<prop>": value, … }, // changed LevelSettings props
"regions": { "<prop>": value, … }, // changed Regions props
"nodes": {
"<kind prefix>": { // chunk, page, tex, anim, model, tile, wp, strat, zone, light, mesh, brush
"removed": ["tile:12", …], // reference nodes deleted
"changed": { "strat:11": { "x": 120716, … } }, // changed props of reference nodes
"added": [ { "id": "strat:n1", "<prop>": value, … } ], // all persistent props (+ "brushKind")
"order": ["tile:0", …] // only if the list order differs from reference order + added
}
},
"…": … // unknown top-level keys are kept when saving
}
Node kinds, ids and properties: notes/editor-api.md (every persistent, settable Prop).
Values by PropType: numbers (INT/FIXED/ANGLE/FLAGS/COLOR as integers, DOUBLE), booleans,
strings, REF = node id (or null). Arrays: up to 64 elements as JSON lists, longer ones as
{"i32": base64} (int32 LE), {"f64": base64} (float64 LE) or {"bytes": base64}; a short double
array containing -0.0 is written as f64 too (JSON numbers drop the sign; since 2026-11-07). A changed
array of unchanged length is stored as runs of the changed elements only:
{"runs": [[start, values], …]} (values encoded as above) – e.g. editing a few vertices or
pixels of an original page stores just those values. Runs apply to the reference value read before any
property of the node is set (setting a model's vertices clears its header; until 2026-11-07 header runs
after a vertex change failed with "project file is damaged: NullPointerException", e.g. on
llamamod --editor-import of a levelbuild WAD).
Loading: reference scene → removals → create all added nodes (all kinds, so references across
kinds resolve) → set values of added/changed nodes and settings → apply order. Problems
(reference to a missing node, a removed id that does not exist) become load warnings, not errors.
Unknown properties of nodes are kept and written back (forward compatibility); a file with a
higher formatVersion loads with a warning.
Ids are positions in the original WAD
Reference node ids are kind:index of the original WAD, so a project stays valid as long as the
base level is the same file (checked through baseSha256). Deleting reference nodes keeps the ids
of the others (they are not renumbered in the project), but it does change the indices written
to the WAD: strat scripts that address tiles by index (stMapreplace / stMapadd) may then hit
other tiles – prefer moving or hiding original tiles over deleting them.
Mods
<data>/levels/*.llamalevel are listed as mods (mods.levels.LevelProjectSource, see
notes/mod-levels.md). CLI:
llamamod --editor-import <level.wad|t1l1m001> <project> # edit project (diff to the CD original)
llamamod --editor-new <project> [base] [--name <name>] # empty new level
llamamod --editor-build <project> <out.wad> # build (prints statistics, warnings)
llamamod --import-level <project> # copy into <data>/levels
(all take --cd <CD folder>; default: the installed original CD of the data folder)
Example: examples/testwelt.llamalevel (the Test World as 125 brushes + 55 objects, 7 KB).