feat(stdlib): Tiled P2 — collision normalisation into the Solids feed (#70)
Normalise three collision sources into the byte tilemap esys_move / Grid.* / Path.* read, in the design's priority order (§3.5): - per-tile <objectgroup> hitboxes (Tiled.tile_shapes) — the precise source; - the solid/oneway/trigger bool property convention (Tiled.collision_kind); - the designated collision layer — any non-zero GID solid (Tiled.project), the fallback source, applied automatically on load. Tiled.collide drives collision from a visual layer's per-tile metadata alone (a tile with no collision metadata stays passable). tmap_collision_kind classifies a GID (0 none / 1 solid / 2 one-way / 3 trigger) from its metadata; the projection adds the collision-layer fallback. Proven by library/tiled_p2.ludic (14 assertions): kind classification for each source, the property convention and collision-layer fallback producing an identical Solids feed, a per-tile-<objectgroup> floor blocking an esys_move mover, and A* over a loaded map matching the hand-authored baseline. x test: 93 passed. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
parent
bc301c8d17
commit
0cb57774d7
12 changed files with 5425 additions and 4991 deletions
47
assets/tiled-fixtures/p2_map.tmx
Normal file
47
assets/tiled-fixtures/p2_map.tmx
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!-- Hand-authored P2 collision fixture (issue #70). CC0. -->
|
||||
<map version="1.10" tiledversion="1.10.2" orientation="orthogonal" renderorder="right-down" width="16" height="10" tilewidth="16" tileheight="16" infinite="0" nextlayerid="4" nextobjectid="1">
|
||||
<tileset firstgid="1" source="p2_tiles.tsx"/>
|
||||
<layer id="1" name="collision" width="16" height="10">
|
||||
<data encoding="csv">
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
|
||||
</data>
|
||||
</layer>
|
||||
<layer id="2" name="props" width="16" height="10">
|
||||
<data encoding="csv">
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,4,4,4,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,4,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,4,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,4,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
|
||||
</data>
|
||||
</layer>
|
||||
<layer id="3" name="floor" width="16" height="10">
|
||||
<data encoding="csv">
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
|
||||
</data>
|
||||
</layer>
|
||||
</map>
|
||||
12
assets/tiled-fixtures/p2_tiles.tsx
Normal file
12
assets/tiled-fixtures/p2_tiles.tsx
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!-- Hand-authored collision-metadata tileset (issue #70). CC0. -->
|
||||
<tileset version="1.10" tiledversion="1.10.2" name="p2tiles" tilewidth="16" tileheight="16" tilecount="5" columns="5">
|
||||
<tile id="1">
|
||||
<objectgroup draworder="index">
|
||||
<object id="1" x="0" y="0" width="16" height="16"/>
|
||||
</objectgroup>
|
||||
</tile>
|
||||
<tile id="2"><properties><property name="oneway" type="bool" value="true"/></properties></tile>
|
||||
<tile id="3"><properties><property name="solid" type="bool" value="true"/></properties></tile>
|
||||
<tile id="4"><properties><property name="trigger" type="bool" value="true"/></properties></tile>
|
||||
</tileset>
|
||||
|
|
@ -6,3 +6,4 @@ type: feat
|
|||
- **P0 parsing primitives (#67)** — a minimal pure-Ludic XML reader (`Xml.*`) for the element/attribute/CDATA subset TMX/TSX/TX use; standard base64 decode/encode (`Base64.*`, RFC 4648), whose decoder ignores the whitespace Tiled wraps into `<data>`; and gzip framing (`z_gunzip`, RFC 1952) wrapping the existing DEFLATE inflater. zlib and the JSON reader already shipped. A curated, attributed golden corpus lands under `assets/tiled-fixtures/`.
|
||||
- **P0.5 TMX/TSX reader (#68)** — `Tiled.read` / `Tiled.read_tsx` map the native XML formats onto the *same* intermediate the JSON path produces — a `Value` tree in Tiled's JSON schema, with every tile layer's data decoded to a dense GID list (CSV, base64, base64+zlib, base64+gzip). A CSV `.tmx` and a base64+zlib `.tmj` of the same map read structurally identically; the in-repo Kenney `sampleMap.tmx` + external `sampleSheet.tsx` load with no manual JSON re-export.
|
||||
- **P1 core load + render (#69)** — the runtime `rt_tmap` model (heap-allocated to `w·h`, lifting the old `96×64` cap), the GID resolver (`Tiled.resolve` → tileset / local id / H·V·D flips), image-backed rendering (`Tiled.draw`, flips applied at blit), and the legacy-tilemap compatibility projection so `Grid.*`/`Path.*`/`esys_move` keep working. `Tiled.load` reads either format, resolves external tilesets + images, and auto-projects a `collision` layer. The Kenney sample loads and renders pixel-identically from `.tmx` and `.tmj`; the `grid` and `physics_tiles` demos now run off a loaded map.
|
||||
- **P2 collision & grid (#70)** — normalise three collision sources into the byte tilemap `esys_move`/`Grid.*`/`Path.*` read, in the design's priority order: per-tile `<objectgroup>` hitboxes, the `solid`/`oneway`/`trigger` property convention (`Tiled.collision_kind`/`Tiled.tile_shapes`), and the designated collision layer (`Tiled.project`, any non-zero GID solid) — or drive collision from a visual layer's per-tile metadata alone (`Tiled.collide`). The property convention and the collision-layer fallback produce the same feed; `Path.a_star` over a loaded map matches the hand-authored baseline.
|
||||
|
|
|
|||
14
docs/language/tiled/tiled-collide.md
Normal file
14
docs/language/tiled/tiled-collide.md
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
---
|
||||
id: tiled-collide
|
||||
name: Tiled.collide
|
||||
category: tiled
|
||||
kind: namespace-method
|
||||
tokens: Tiled.collide
|
||||
sig: Tiled.collide(map, layer: int) -> void
|
||||
tip: Drive collision from per-tile metadata.
|
||||
order: 14
|
||||
ns: Tiled
|
||||
member: collide
|
||||
---
|
||||
|
||||
Projects a layer to the byte tilemap driving collision from per-tile metadata alone — a tile's <code><objectgroup></code> hitbox or its <code>solid</code>/<code>oneway</code>/<code>trigger</code> property — so a tile with no collision metadata stays passable. Use this to drive collision from a visual layer; <a href="tiled-project"><code>Tiled.project</code></a> is the designated-collision-layer form where any non-zero GID is solid.
|
||||
14
docs/language/tiled/tiled-collision_kind.md
Normal file
14
docs/language/tiled/tiled-collision_kind.md
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
---
|
||||
id: tiled-collision_kind
|
||||
name: Tiled.collision_kind
|
||||
category: tiled
|
||||
kind: namespace-method
|
||||
tokens: Tiled.collision_kind
|
||||
sig: Tiled.collision_kind(map, gid: int) -> int
|
||||
tip: Classify a GID's collision from its tile metadata.
|
||||
order: 15
|
||||
ns: Tiled
|
||||
member: collision_kind
|
||||
---
|
||||
|
||||
Returns the collision kind a GID resolves to from its tile metadata, in the design's priority order (per-tile <code><objectgroup></code> hitboxes, then the property convention): <code>0</code> none, <code>1</code> solid, <code>2</code> one-way, <code>3</code> trigger. The collision-layer fallback (any non-zero GID solid) is applied by <a href="tiled-project"><code>Tiled.project</code></a>, not here.
|
||||
14
docs/language/tiled/tiled-tile_shapes.md
Normal file
14
docs/language/tiled/tiled-tile_shapes.md
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
---
|
||||
id: tiled-tile_shapes
|
||||
name: Tiled.tile_shapes
|
||||
category: tiled
|
||||
kind: namespace-method
|
||||
tokens: Tiled.tile_shapes
|
||||
sig: Tiled.tile_shapes(map, gid: int) -> int
|
||||
tip: Whether a GID's tile has a collision shape.
|
||||
order: 16
|
||||
ns: Tiled
|
||||
member: tile_shapes
|
||||
---
|
||||
|
||||
Returns <code>1</code> if the tile a GID resolves to carries a per-tile <code><objectgroup></code> with at least one collision shape (rectangle/ellipse/polygon/point), else <code>0</code> — the precise collision source in the P2 priority order.
|
||||
84
examples/library/tiled_p2.ludic
Normal file
84
examples/library/tiled_p2.ludic
Normal file
|
|
@ -0,0 +1,84 @@
|
|||
# tiled_p2.ludic — Tiled P2 collision & grid integration (issue #70). Normalises
|
||||
# three collision sources into the byte tilemap esys_move / Grid.* / Path.* read:
|
||||
# per-tile <objectgroup> hitboxes, the solid/oneway/trigger property convention,
|
||||
# and the designated collision layer (any non-zero GID is solid). Proves the
|
||||
# property convention and the collision-layer fallback produce the same feed, a
|
||||
# per-tile-shape floor blocks a mover, and A* over a loaded map matches baseline.
|
||||
#
|
||||
# A full run prints: 1 2 3 4 5 6 7 8 9 10 11 12 13 14
|
||||
program TiledP2 {
|
||||
property Position { x: int = 0, y: int = 0 }
|
||||
property Body {
|
||||
vx: fixed = 0.0, vy: fixed = 0.0,
|
||||
gravity: fixed = 0.0, max_fall: fixed = 0.0,
|
||||
rx: fixed = 0.0, ry: fixed = 0.0,
|
||||
policy: int = 0,
|
||||
on_ground: int = 0, hit_wall: int = 0, hit_ceiling: int = 0
|
||||
}
|
||||
property Collider { w: int = 0, h: int = 0, offx: int = 0, offy: int = 0, is_trigger: int = 0, one_way: int = 0, layer: int = 0, mask: int = 0 }
|
||||
property Solids { tile: int = 0, wall: int = 0, oneway: int = 0 }
|
||||
|
||||
# count solid ('#') cells and hash the whole byte tilemap (deterministic).
|
||||
function grid_solids() -> int {
|
||||
var n = 0
|
||||
var y = 0
|
||||
while y < 10 { var x = 0
|
||||
while x < 16 { if rt_tile(x, y) == 35 { n = n + 1 }; x = x + 1 }
|
||||
y = y + 1 }
|
||||
return n
|
||||
}
|
||||
function grid_hash() -> int {
|
||||
var h = 0
|
||||
var y = 0
|
||||
while y < 10 { var x = 0
|
||||
while x < 16 { h = h * 31 + rt_tile(x, y); x = x + 1 }
|
||||
y = y + 1 }
|
||||
return h
|
||||
}
|
||||
|
||||
handler Boot phase Start {
|
||||
let m = Tiled.load("assets/tiled-fixtures/p2_map.tmx")
|
||||
|
||||
# --- collision_kind classifies each metadata source (0 none,1 solid,2 one-way,3 trigger) ---
|
||||
if Tiled.collision_kind(m, 1) == 0 { print(1) } # plain tile — no metadata
|
||||
if Tiled.collision_kind(m, 2) == 1 { print(2) } # <objectgroup> shape -> solid
|
||||
if Tiled.collision_kind(m, 3) == 2 { print(3) } # oneway property
|
||||
if Tiled.collision_kind(m, 4) == 1 { print(4) } # solid property
|
||||
if Tiled.collision_kind(m, 5) == 3 { print(5) } # trigger property
|
||||
if Tiled.tile_shapes(m, 2) == 1 { print(6) }
|
||||
if Tiled.tile_shapes(m, 1) == 0 { print(7) }
|
||||
|
||||
# --- same feed: collision-layer fallback vs property convention ---
|
||||
Tiled.project(m, 0) # "collision": plain tiles, non-zero = solid
|
||||
let solids = grid_solids()
|
||||
let h1 = grid_hash()
|
||||
if solids == 6 { print(8) }
|
||||
Tiled.collide(m, 1) # "props": solid-property tiles, metadata only
|
||||
if grid_hash() == h1 { print(9) } # identical Solids feed
|
||||
|
||||
# --- A* over a loaded map matches the hand-authored-map baseline ---
|
||||
Tiled.load("assets/tiled-fixtures/grid_maze.tmx") # auto-projects its collision layer
|
||||
let p = Grid.a_star(1, 1, 6, 3, '#')
|
||||
if len(p) == 8 { print(10) }
|
||||
if p[0].x == 1 and p[0].y == 1 { print(11) }
|
||||
let last = p[len(p) - 1]
|
||||
if last.x == 6 and last.y == 3 { print(12) }
|
||||
|
||||
# --- a per-tile-shape floor blocks an esys_move mover ---
|
||||
let m2 = Tiled.load("assets/tiled-fixtures/p2_map.tmx")
|
||||
Tiled.collide(m2, 2) # "floor": <objectgroup> tiles across row 8
|
||||
spawn Config { Solids { tile: 16, wall: 35, oneway: 61 } }
|
||||
spawn Runner { Position { x: 32, y: 16 }, Body { gravity: fixed(1), max_fall: fixed(6) }, Collider { w: 16, h: 16 } }
|
||||
let pb = World.prop_id("Body")
|
||||
let pp = World.prop_id("Position")
|
||||
let f_y = World.field_id(pp, "y")
|
||||
let f_grd = World.field_id(pb, "on_ground")
|
||||
let a = World.query_next(pb, 0)
|
||||
var i = 0
|
||||
while i < 80 { tick_fixed(); i = i + 1 }
|
||||
if World.get(a, pp, f_y) == 112 { print(13) } # feet rest on the tile floor top (128)
|
||||
if World.get(a, pb, f_grd) == 1 { print(14) }
|
||||
}
|
||||
|
||||
handler Run phase Update { quit() }
|
||||
}
|
||||
|
|
@ -541,42 +541,76 @@ function tmap_gid(m: Tmap, layer: int, x: int, y: int) -> int {
|
|||
|
||||
# ---- per-tile metadata (property convention) -------------------------------
|
||||
# does the tile a GID resolves to carry bool custom property `name` = true?
|
||||
function tmap_tile_prop(m: Tmap, gid: int, name: pointer) -> int {
|
||||
# the metadata Value object for the tile a GID resolves to (a `null` node if the
|
||||
# tile carries none). Shared by the property / objectgroup / animation lookups.
|
||||
function tmap_tile_meta(m: Tmap, gid: int) -> Val {
|
||||
let r = tmap_resolve(m, gid)
|
||||
if r.tileset < 0 { return 0 }
|
||||
if r.tileset < 0 { return value_null() }
|
||||
let ts = m.tilesets[r.tileset]
|
||||
if value_kind(ts.meta) != 6 { return 0 }
|
||||
if value_kind(ts.meta) != 6 { return value_null() }
|
||||
let tiles = value_get(ts.meta, "tiles")
|
||||
if value_kind(tiles) != 5 { return 0 }
|
||||
if value_kind(tiles) != 5 { return value_null() }
|
||||
var i = 0
|
||||
while i < value_count(tiles) {
|
||||
let t = value_at(tiles, i)
|
||||
if value_as_int(value_get(t, "id")) == r.local {
|
||||
let props = value_get(t, "properties")
|
||||
if value_kind(props) == 5 {
|
||||
var j = 0
|
||||
while j < value_count(props) {
|
||||
let p = value_at(props, j)
|
||||
if value_as_str(value_get(p, "name")) == name {
|
||||
if value_as_str(value_get(p, "value")) == "true" { return 1 }
|
||||
return 0
|
||||
}
|
||||
j = j + 1
|
||||
}
|
||||
}
|
||||
if value_as_int(value_get(t, "id")) == r.local { return t }
|
||||
i = i + 1
|
||||
}
|
||||
return value_null()
|
||||
}
|
||||
|
||||
# does the tile a GID resolves to carry bool custom property `name` = true?
|
||||
function tmap_tile_prop(m: Tmap, gid: int, name: pointer) -> int {
|
||||
let t = tmap_tile_meta(m, gid)
|
||||
if value_kind(t) != 6 { return 0 }
|
||||
let props = value_get(t, "properties")
|
||||
if value_kind(props) != 5 { return 0 }
|
||||
var j = 0
|
||||
while j < value_count(props) {
|
||||
let p = value_at(props, j)
|
||||
if value_as_str(value_get(p, "name")) == name {
|
||||
if value_as_str(value_get(p, "value")) == "true" { return 1 }
|
||||
return 0
|
||||
}
|
||||
i = i + 1
|
||||
j = j + 1
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
# does the tile a GID resolves to carry a per-tile <objectgroup> collision shape?
|
||||
function tmap_tile_has_shapes(m: Tmap, gid: int) -> int {
|
||||
let t = tmap_tile_meta(m, gid)
|
||||
if value_kind(t) != 6 { return 0 }
|
||||
let og = value_get(t, "objectgroup")
|
||||
if value_kind(og) != 6 { return 0 }
|
||||
let objs = value_get(og, "objects")
|
||||
if value_count(objs) > 0 { return 1 }
|
||||
return 0
|
||||
}
|
||||
|
||||
# ---- collision normalisation (P2, #70) -------------------------------------
|
||||
# the collision kind of a GID for the byte-grid projection, from the tile's
|
||||
# metadata alone (design §3.5 priority): per-tile <objectgroup> hitboxes, then
|
||||
# the solid/oneway/trigger property convention. 0 = no collision metadata,
|
||||
# 1 = solid, 2 = one-way, 3 = trigger. The designated-collision-layer fallback
|
||||
# (any non-zero GID is solid) is applied by the projection, not here.
|
||||
function tmap_collision_kind(m: Tmap, gid: int) -> int {
|
||||
if gid == 0 { return 0 }
|
||||
if tmap_tile_prop(m, gid, "trigger") == 1 { return 3 }
|
||||
if tmap_tile_prop(m, gid, "oneway") == 1 { return 2 }
|
||||
if tmap_tile_has_shapes(m, gid) == 1 { return 1 }
|
||||
if tmap_tile_prop(m, gid, "solid") == 1 { return 1 }
|
||||
return 0
|
||||
}
|
||||
|
||||
# ---- legacy rt_map compatibility projection --------------------------------
|
||||
# project the designated collision layer down to the byte tilemap so Grid.* /
|
||||
# Path.* / esys_move keep working unchanged: an empty cell is ' ' (passable), a
|
||||
# tile whose GID carries the `oneway` property is '=' (61), any other non-zero
|
||||
# GID is '#' (35, solid). The legacy 96x64 cap clips, so old code is byte-exact.
|
||||
function tmap_project(m: Tmap, layer: int) -> void {
|
||||
# project a layer down to the byte tilemap so Grid.* / Path.* / esys_move keep
|
||||
# working unchanged. `whole_layer_solid` picks the source (design §3.5): true for
|
||||
# a designated collision LAYER (a bare non-zero GID with no metadata still counts
|
||||
# as solid — the fallback source); false to drive collision from per-tile
|
||||
# metadata alone (objectgroup shapes / property convention on a visual layer).
|
||||
# solid -> '#' (35), one-way -> '=' (61), trigger/empty -> ' ' (32, passable).
|
||||
function tmap_project_layer(m: Tmap, layer: int, whole_layer_solid: int) -> void {
|
||||
m.coll = layer
|
||||
rt_map_size(m.w, m.h) # clamps to 96x64, clears to ' '
|
||||
if layer < 0 or layer >= len(m.layers) { return }
|
||||
|
|
@ -590,9 +624,10 @@ function tmap_project(m: Tmap, layer: int) -> void {
|
|||
if x < 96 {
|
||||
let gid = l.gids[y * l.w + x]
|
||||
if gid != 0 {
|
||||
var ch = 35 # '#'
|
||||
if tmap_tile_prop(m, gid, "oneway") == 1 { ch = 61 } # '='
|
||||
rt_map[y * 96 + x] = ch
|
||||
var k = tmap_collision_kind(m, gid)
|
||||
if k == 0 and whole_layer_solid != 0 { k = 1 } # collision-layer fallback
|
||||
if k == 1 { rt_map[y * 96 + x] = 35 } # '#'
|
||||
if k == 2 { rt_map[y * 96 + x] = 61 } # '='
|
||||
}
|
||||
}
|
||||
x = x + 1
|
||||
|
|
@ -602,6 +637,14 @@ function tmap_project(m: Tmap, layer: int) -> void {
|
|||
}
|
||||
}
|
||||
|
||||
# project a designated collision layer (non-zero GID is solid unless its tile
|
||||
# metadata says otherwise) — the P1 default, called automatically on load.
|
||||
function tmap_project(m: Tmap, layer: int) -> void { tmap_project_layer(m, layer, 1) }
|
||||
|
||||
# drive collision from per-tile metadata alone (objectgroup hitboxes / property
|
||||
# convention) over any layer — a tile with no collision metadata stays passable.
|
||||
function tmap_collide(m: Tmap, layer: int) -> void { tmap_project_layer(m, layer, 0) }
|
||||
|
||||
# find a tile layer named collision/solids/walls (case-sensitive), or -1.
|
||||
function tmap_find_collision(m: Tmap) -> int {
|
||||
var i = 0
|
||||
|
|
|
|||
|
|
@ -622,8 +622,11 @@ function emit_ns_call(ns: pointer, meth: pointer, e: Node) -> Val {
|
|||
if (meth == "layer_name") { bare = "tmap_layer_name"; push(labels, "map"); push(labels, "index") }
|
||||
if (meth == "draw") { bare = "tmap_draw"; push(labels, "map"); push(labels, "camx"); push(labels, "camy") }
|
||||
if (meth == "project") { bare = "tmap_project"; push(labels, "map"); push(labels, "layer") }
|
||||
if (meth == "collide") { bare = "tmap_collide"; push(labels, "map"); push(labels, "layer") }
|
||||
if (meth == "collision_kind") { bare = "tmap_collision_kind"; push(labels, "map"); push(labels, "gid") }
|
||||
if (meth == "tree") { bare = "tmap_tree"; push(labels, "map") }
|
||||
if (meth == "tile_prop") { bare = "tmap_tile_prop"; push(labels, "map"); push(labels, "gid"); push(labels, "name") }
|
||||
if (meth == "tile_shapes") { bare = "tmap_tile_has_shapes"; push(labels, "map"); push(labels, "gid") }
|
||||
}
|
||||
# #62: a package-provided namespace (declared with @Namespace(Foo)) that none
|
||||
# of the hardcoded core blocks matched — alias Foo.method to the bare function
|
||||
|
|
|
|||
10126
selfhost/ludicc.seed.ll
10126
selfhost/ludicc.seed.ll
File diff suppressed because it is too large
Load diff
|
|
@ -695,6 +695,9 @@
|
|||
"tiled-draw",
|
||||
"tiled-project",
|
||||
"tiled-tree",
|
||||
"tiled-tile_prop"
|
||||
"tiled-tile_prop",
|
||||
"tiled-collide",
|
||||
"tiled-collision_kind",
|
||||
"tiled-tile_shapes"
|
||||
]
|
||||
}
|
||||
|
|
|
|||
|
|
@ -208,6 +208,7 @@ function cmd_test() -> int {
|
|||
feat_case("library/tiled_p0", "", "1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21", "tiled_p0.ludic (Tiled P0: Xml reader + Base64 decode/encode + gzip framing over inflate; issue #67)")
|
||||
feat_case("library/tiled_p05", "", "1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30", "tiled_p05.ludic (Tiled P0.5: TMX/TSX reader -> same Value-tree intermediate as TMJ; Kenney sampleMap.tmx; issue #68)")
|
||||
feat_case("library/tiled_p1", "", "1 2 3 4 5 6 7 8 9 10 11 12 13 14", "tiled_p1.ludic (Tiled P1: rt_tmap model + GID resolver/flip decode + render; loads+draws Kenney map identically from .tmx and .tmj; issue #69)")
|
||||
feat_case("library/tiled_p2", "", "1 2 3 4 5 6 7 8 9 10 11 12 13 14", "tiled_p2.ludic (Tiled P2: per-tile objectgroup / property-convention / collision-layer -> Solids feed; A* baseline; issue #70)")
|
||||
feat_case("library/render", "", "1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18", "render.ludic (Screen pixel/oval/camera/clip/blend_mode/measure_text + Camera set/follow/shake, verified by pixel readback)")
|
||||
feat_case("library/lighting", "", "1 2 3 4 5 6 7 8 9 10 11 12 13 14", "lighting.ludic (Light ambient/point radial falloff + occluder hard shadows — 2D light accumulation, verified by pixel readback)")
|
||||
feat_case("library/light_tiers", "", "1 1 1 1 1 1 1 1 1", "light_tiers.ludic (Light spot/falloff/soft/gel/normal/time_of_day — render-quality tiers 3-4; issue #49)")
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue