Commit Graph

10 Commits

Author SHA1 Message Date
Axel Meyer
eb255480a1 Add inspect subcommand: read-only stats for v2 map files
Reads the map JSON, optionally loads --atlas-dir paths for name
resolution, and prints the inspector report to stdout. Missing
file, bad JSON, and missing --atlas-dir paths all produce
labelled stderr errors with exit 1.
2026-05-23 16:59:07 +02:00
Axel Meyer
530bceaddd Add map inspector that emits a human-readable stats report
Counts set vs empty cells per layer, lists the top-10 most frequent
non-empty GIDs with decoded components, and reports roof coverage.
When an atlas registry is supplied, atlas-id+tile-name annotations
are added; without one the report still works using indices only.
2026-05-23 16:55:56 +02:00
Axel Meyer
f516e2acda Add build subcommand: DSL spec to v2-map JSON file
Reads the DSL file, parses to AST, loads all --atlas-dir paths into
a registry, runs the builder, and writes pretty-printed JSON. The
output filename's basename becomes the map id when the DSL has no
'id' directive. Parser and builder errors are surfaced as
'<file>:<line>: <message>'. Also reorders the duplicate-atlas warning
so the atlas_id appears before the word 'duplicate'.
2026-05-23 16:50:42 +02:00
Axel Meyer
7adcb407fa Add map builder that turns AST + atlas registry into v2 JSON
Validates atlas declarations against the registry, resolves tile
names per atlas, bounds-checks each cell, and emits a flat
row-major (y*w + x) GID array per layer. Roof block is only
serialised when at least one roof directive was present so empty
maps stay compact.
2026-05-23 16:45:06 +02:00
Axel Meyer
e96431b44f Add text-DSL parser with line-numbered errors
Two-pass-free line-based scanner. Each directive carries its source
line so downstream validation errors can be attributed correctly.
Parser checks syntax only — atlas/tile resolution and bounds checks
are deferred to the builder so each tier has one responsibility.
2026-05-23 14:19:10 +02:00
Axel Meyer
a3ff2f5e6e Add atlas-spec loader with duplicate handling
loadAtlasDirs walks one level deep into each --atlas-dir, picks up
*/tiles.atlas.json, and builds bidirectional name/id maps. On
duplicate atlas_id across paths the first registration wins and a
warning string is returned (callers decide whether to print).
2026-05-23 13:50:10 +02:00
Axel Meyer
cef9c5c9a2 Add decode subcommand
Accepts decimal or 0x-hex GID input. gid=0 is rendered as the
literal 'empty'; non-zero values print the three components in a
parse-stable space-separated key=value form.
2026-05-23 13:47:39 +02:00
Axel Meyer
7316ebc7dd Add encode subcommand
Wraps gid.encodeGid, prints the packed-u32 as decimal on stdout,
emits usage on stderr on bad arity, and a labelled error on
out-of-range or non-integer input.
2026-05-23 13:46:03 +02:00
Axel Meyer
b1743ad19f Add CLI dispatcher and bin entry
Top-level run(argv,{out,err}) accepts an injectable output sink so
handlers can be unit-tested without spawning a subprocess. Handler
map is empty for now; subcommands are wired in as they land.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-23 13:44:10 +02:00
Axel Meyer
2949a96e11 Add GID encode/decode with range validation
Bit layout [atlas:8][tile_id:20][rot:2][res:2] matches
lib-core.maps init.lua so JS-produced GIDs are byte-identical to
engine-produced ones. >>> 0 forces unsigned u32 output.
2026-05-23 13:40:25 +02:00