Tiled P0.5 — TMX/TSX/TX reader over the P0 XML reader #68

Closed
opened 2026-09-01 12:29:06 +02:00 by orkun · 1 comment
Owner

Follow-up P0.5 of the Tiled design (#66). Design record: Design: Tiled maps.

Scope — TMX/TSX reader

Build the native-format reader on top of the P0 XML reader (#67): map .tmx, external/embedded tileset .tsx, and .tx template files into the same intermediate the JSON path produces. This is what lets the in-repo Kenney sampleMap.tmx load without a manual JSON re-export.

Per the format-order decision (design §1), JSON (TMJ) is v1's first path because Json.parse already exists; this issue adds the XML path as the fast follow so both native Tiled formats work.

Golden fixtures

in-repo assets/kenney/tiny-dungeon/Tiled/sampleMap.tmx + sampleSheet.tsx (orthogonal, external .tsx, CSV, flip-flagged GIDs) — kept as the orthogonal-CSV smoke test.

Acceptance

  • sampleMap.tmx + external sampleSheet.tsx parse into the intermediate model with correct firstgid, geometry, and raw CSV GID array.
  • Output is structurally identical to the TMJ export of the same map.

Depends on #67. Feeds P1 (#PLACEHOLDER).

Follow-up P0.5 of the Tiled design (#66). Design record: [Design: Tiled maps](https://git.workshopsoft.io/workshopsoft/ludic/wiki/Design%2FTiled). ## Scope — TMX/TSX reader Build the native-format reader on top of the P0 XML reader (#67): map `.tmx`, external/embedded tileset `.tsx`, and `.tx` template files into the same intermediate the JSON path produces. This is what lets the in-repo Kenney `sampleMap.tmx` load **without a manual JSON re-export**. Per the format-order decision (design §1), JSON (TMJ) is v1's first path because `Json.parse` already exists; this issue adds the XML path as the fast follow so both native Tiled formats work. ## Golden fixtures in-repo `assets/kenney/tiny-dungeon/Tiled/sampleMap.tmx` + `sampleSheet.tsx` (orthogonal, external `.tsx`, CSV, flip-flagged GIDs) — kept as the orthogonal-CSV smoke test. ## Acceptance - [ ] `sampleMap.tmx` + external `sampleSheet.tsx` parse into the intermediate model with correct `firstgid`, geometry, and raw CSV GID array. - [ ] Output is structurally identical to the TMJ export of the same map. Depends on #67. Feeds P1 (#PLACEHOLDER).
orkun added the
area:stdlib
label 2026-09-01 12:29:06 +02:00
Author
Owner

P0.5 landed in main (071c268).

Tiled.read / Tiled.read_tsx (runtime/native/tiled.ludic) map the native XML formats onto the same intermediate the JSON path produces — a Value tree in Tiled's JSON schema — so one format-independent core (P1, #69) will consume either reader.

  • tmx_to_value walks a <map> into {orientation, width/height, tilewidth/height, tilesets[], layers[]}. Every tile layer's <data> is decoded to a dense GID int list — CSV split, or base64 → zlib/gzip inflate → little-endian u32s — so a CSV .tmx and a base64 .tmj of the same map read structurally identically.
  • External tilesets keep the {firstgid, source} reference (as TMJ does); embedded tilesets and standalone .tsx (tsx_to_value) inline full geometry + per-tile metadata (animation frames, collision <objectgroup>, class, properties) for later phases.
  • Object layers, all object shapes, image/group layers and custom properties already parse into the tree, so P2/P4/P5 just read it.
  • tmj_normalize decodes base64 data strings in a parsed .tmj, so the JSON path matches the XML path exactly.

Acceptance

  • sampleMap.tmx + external sampleSheet.tsx parse into the intermediate model with correct firstgid, geometry, and raw CSV GID array — verified against the in-repo Kenney fixture (32×20, firstgid=1 → sampleSheet.tsx, 640 GIDs incl. flip-flagged 1610612787; sheet tilecount=132, columns=12).
  • Output is structurally identical to the TMJ export of the same map — handmade.tmx (four layers: CSV / base64 / base64+gzip / base64+zlib) and handmade.tmj (CSV array + base64+zlib) all normalise to the same 16-GID array.

Proven by examples/library/tiled_p05.ludic (30 assertions) in x test (91 passed). Feeds P1 (#69).

**P0.5 landed** in `main` (071c268). `Tiled.read` / `Tiled.read_tsx` (`runtime/native/tiled.ludic`) map the native XML formats onto the **same intermediate the JSON path produces** — a `Value` tree in Tiled's JSON schema — so one format-independent core (P1, #69) will consume either reader. - **`tmx_to_value`** walks a `<map>` into `{orientation, width/height, tilewidth/height, tilesets[], layers[]}`. Every tile layer's `<data>` is decoded to a **dense GID int list** — CSV split, or base64 → zlib/gzip inflate → little-endian u32s — so a CSV `.tmx` and a base64 `.tmj` of the same map read structurally identically. - **External tilesets** keep the `{firstgid, source}` reference (as TMJ does); embedded tilesets and standalone `.tsx` (`tsx_to_value`) inline full geometry + per-tile metadata (animation frames, collision `<objectgroup>`, class, properties) for later phases. - Object layers, all object shapes, image/group layers and custom properties already parse into the tree, so P2/P4/P5 just read it. - **`tmj_normalize`** decodes base64 `data` strings in a parsed `.tmj`, so the JSON path matches the XML path exactly. ### Acceptance - [x] `sampleMap.tmx` + external `sampleSheet.tsx` parse into the intermediate model with correct `firstgid`, geometry, and raw CSV GID array — verified against the in-repo Kenney fixture (32×20, `firstgid=1` → `sampleSheet.tsx`, 640 GIDs incl. flip-flagged `1610612787`; sheet `tilecount=132`, `columns=12`). - [x] Output is structurally identical to the TMJ export of the same map — `handmade.tmx` (four layers: CSV / base64 / base64+gzip / base64+zlib) and `handmade.tmj` (CSV array + base64+zlib) all normalise to the same 16-GID array. Proven by `examples/library/tiled_p05.ludic` (30 assertions) in `x test` (91 passed). Feeds P1 (#69).
orkun closed this issue 2026-09-01 13:15:57 +02:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference: workshopsoft/ludic#68
No description provided.