Files
llamamod/notes/editor-format.md
T

95 lines
5.6 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# `.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 level `base` imported unchanged (`Templates.original`).
* `kind: "new"` – reference = `base` with 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 base `t1l1m001` (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
```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).