Tiled P2 — collision & grid: per-tile hitboxes / properties / layer → esys_move #70

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

Follow-up P2 of the Tiled design (#66). Design record: Design: Tiled maps §3.5.

Scope — collision & grid integration

Make loaded maps drive collision. Normalise three sources into the existing Solids{tile,wall,oneway} feed for esys_move (runtime/native/systems_move.ludic), in priority order (design §3.5):

  1. per-tile <objectgroup> hitboxes (rect/ellipse/polygon/point) — the precise source;
  2. custom bool/class property convention (solid, oneway, trigger) on tile/tileset;
  3. the designated collision layer — any non-zero GID is solid.

Keep Grid.*/Path.* (runtime/native/grid.ludic) working over the loaded map via the P1 compatibility projection.

Golden fixtures

Hand-authored per-tile <objectgroup> fixture (official examples lack it) + a property-convention fixture (design §4).

Acceptance

  • A map with per-tile collision shapes blocks esys_move movers correctly.
  • The property convention and collision-layer fallbacks produce the same Solids feed.
  • Path.a_star over the loaded map matches the hand-authored-map baseline.

Depends on #69. Priority medium.

Follow-up P2 of the Tiled design (#66). Design record: [Design: Tiled maps](https://git.workshopsoft.io/workshopsoft/ludic/wiki/Design%2FTiled) §3.5. ## Scope — collision & grid integration Make loaded maps drive collision. Normalise three sources into the existing `Solids{tile,wall,oneway}` feed for `esys_move` (`runtime/native/systems_move.ludic`), in priority order (design §3.5): 1. per-tile `<objectgroup>` hitboxes (rect/ellipse/polygon/point) — the precise source; 2. custom bool/class property convention (`solid`, `oneway`, `trigger`) on tile/tileset; 3. the designated collision **layer** — any non-zero GID is solid. Keep `Grid.*`/`Path.*` (`runtime/native/grid.ludic`) working over the loaded map via the P1 compatibility projection. ## Golden fixtures Hand-authored per-tile `<objectgroup>` fixture (official examples lack it) + a property-convention fixture (design §4). ## Acceptance - [ ] A map with per-tile collision shapes blocks `esys_move` movers correctly. - [ ] The property convention and collision-layer fallbacks produce the same `Solids` feed. - [ ] `Path.a_star` over the loaded map matches the hand-authored-map baseline. Depends on #69. Priority medium.
orkun added the
priority:medium
area:stdlib
labels 2026-09-01 12:29:42 +02:00
Author
Owner

P2 landed in main (0cb5777).

Normalises three collision sources into the byte tilemap esys_move/Grid.*/Path.* read, in the design's priority order (§3.5):

  1. per-tile <objectgroup> hitboxes (Tiled.tile_shapes) — the precise source;
  2. the solid/oneway/trigger bool property convention (Tiled.collision_kind);
  3. the designated collision layer — any non-zero GID solid (Tiled.project), the fallback source, applied automatically on load.

Tiled.collide(map, layer) drives collision from a visual layer's per-tile metadata alone (a tile with no collision metadata stays passable). Tiled.collision_kind classifies a GID (0 none / 1 solid / 2 one-way / 3 trigger) from its metadata; the projection adds the collision-layer fallback. Grid.*/Path.* keep working over the loaded map via the P1 projection.

Acceptance

  • A map with per-tile collision shapes blocks esys_move movers correctly — an <objectgroup>-floor (Tiled.collide) stops a falling Body at the tile top.
  • The property convention and collision-layer fallbacks produce the same Solids feed — a collision layer of plain tiles (fallback) and a props layer of solid-property tiles hash byte-identically.
  • Path.a_star over the loaded map matches the hand-authored-map baseline — grid_maze.tmx gives path len 8, (1,1)→(6,3).

Proven by examples/library/tiled_p2.ludic (14 assertions) in x test (93 passed).

**P2 landed** in `main` (0cb5777). Normalises three collision sources into the byte tilemap `esys_move`/`Grid.*`/`Path.*` read, in the design's priority order (§3.5): 1. **per-tile `<objectgroup>` hitboxes** (`Tiled.tile_shapes`) — the precise source; 2. the **`solid`/`oneway`/`trigger` bool property convention** (`Tiled.collision_kind`); 3. the **designated collision layer** — any non-zero GID solid (`Tiled.project`), the fallback source, applied automatically on load. `Tiled.collide(map, layer)` drives collision from a *visual* layer's per-tile metadata alone (a tile with no collision metadata stays passable). `Tiled.collision_kind` classifies a GID (`0` none / `1` solid / `2` one-way / `3` trigger) from its metadata; the projection adds the collision-layer fallback. `Grid.*`/`Path.*` keep working over the loaded map via the P1 projection. ### Acceptance - [x] A map with per-tile collision shapes blocks `esys_move` movers correctly — an `<objectgroup>`-floor (`Tiled.collide`) stops a falling Body at the tile top. - [x] The property convention and collision-layer fallbacks produce the same `Solids` feed — a `collision` layer of plain tiles (fallback) and a `props` layer of `solid`-property tiles hash byte-identically. - [x] `Path.a_star` over the loaded map matches the hand-authored-map baseline — `grid_maze.tmx` gives path len 8, (1,1)→(6,3). Proven by `examples/library/tiled_p2.ludic` (14 assertions) in `x test` (93 passed).
orkun closed this issue 2026-09-01 13:50:43 +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#70
No description provided.