feat(engine): Tiled P5 — image/group layers, iso/hex/staggered coords, Wang (#73)
- Image layers: <imagelayer> renders with parallax + optional repeatx/repeaty tiling across the view; the image loads relative to the map file. Group layers flatten at build (children render in file order); layer offset/opacity/tint are queryable (Tiled.layer_kind / layer_offsetx / layer_offsety / layer_opacity / layer_tint), a group's tint applying recursively. - Orientation transforms: Tiled.cell_x / Tiled.cell_y compute a tile cell's screen position for orthogonal, isometric ((x-y)*tw/2, (x+y)*th/2), staggered, and hexagonal (rows step by (tileh+hexsidelength)/2, alternate rows shoved per staggerindex) — the tile draw now places cells through them. - Wang: exported Wang-set GIDs are ordinary GIDs and resolve through the standard GID resolver; the terrain-corner authoring concept is editor-side (design cut). Proven by library/tiled_p5.ludic (14 assertions) over the real isometric_grass_and_water.tmx (iso + Wang) and hexagonal-mini.tmx, plus a hand-authored image+group fixture. x test: 96 passed. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
parent
b8c71d2a8e
commit
78a5719fae
15 changed files with 5829 additions and 5007 deletions
18
assets/tiled-fixtures/img_group.tmx
Normal file
18
assets/tiled-fixtures/img_group.tmx
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!-- Hand-authored P5 fixture: image + group layers (issue #73). CC0. -->
|
||||
<map version="1.10" tiledversion="1.10.2" orientation="orthogonal" renderorder="right-down" width="4" height="4" tilewidth="16" tileheight="16" infinite="0" nextlayerid="4" nextobjectid="1">
|
||||
<tileset firstgid="1" source="anim_tiles.tsx"/>
|
||||
<imagelayer id="1" name="bg" offsetx="8" offsety="4" repeatx="1">
|
||||
<image source="../kenney/tiny-dungeon/Tilemap/tilemap.png" width="203" height="186"/>
|
||||
</imagelayer>
|
||||
<group id="2" name="grp" offsetx="16" opacity="0.5" tintcolor="#ff0000">
|
||||
<layer id="3" name="inner" width="4" height="4">
|
||||
<data encoding="csv">
|
||||
2,0,0,0,
|
||||
0,0,0,0,
|
||||
0,0,0,0,
|
||||
0,0,0,0
|
||||
</data>
|
||||
</layer>
|
||||
</group>
|
||||
</map>
|
||||
|
|
@ -9,3 +9,4 @@ type: feat
|
|||
- **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.
|
||||
- **P3 animated tiles + tile objects (#71)** — a tileset `<animation>` advances deterministically as a pure function of the fixed 60/s engine frame clock (`Tiled.frame_gid`/`Tiled.animated`), so an animated GID resolves at draw to the current frame's GID with its flip flags preserved and reproduces frame-for-frame across runs; `Tiled.draw_anim` draws a map with animations advanced. Object-layer entries with a `gid` render the tile image (with their own flips), bottom-anchored, as placeable sprites.
|
||||
- **P4 objects, properties, templates, spawning (#72)** — all object shapes (rectangle / ellipse / point / polygon / polyline / text) and custom properties parse and are queryable (`Tiled.object`, `Tiled.object_shape`, `Tiled.prop`/`Tiled.prop_int`/`Tiled.prop_type`); class properties resolve their defaults against a project custom-type table (`Tiled.load_types` over `objecttypes.xml`); template instances inherit their `.tx`/`.tj` template's fields; and an object maps onto Ludic components on demand (`Tiled.spawn`/`Tiled.spawn_layer`, off by default, via the reflection ABI).
|
||||
- **P5 breadth (#73)** — image layers (parallax + repeat) and group layers (flattened, with recursive offset/opacity/tint/visible; `Tiled.layer_kind`/`Tiled.layer_offsetx`/`Tiled.layer_tint`); the isometric / staggered / hexagonal orientation coordinate transforms (`Tiled.cell_x`/`Tiled.cell_y`, driving the tile draw so cells land at the correct screen coords); and Wang-set GID resolution through the standard resolver (the terrain-corner authoring concept is editor-side and ignored).
|
||||
|
|
|
|||
14
docs/language/tiled/tiled-cell_x.md
Normal file
14
docs/language/tiled/tiled-cell_x.md
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
---
|
||||
id: tiled-cell_x
|
||||
name: Tiled.cell_x
|
||||
category: tiled
|
||||
kind: namespace-method
|
||||
tokens: Tiled.cell_x
|
||||
sig: Tiled.cell_x(map, x: int, y: int) -> int
|
||||
tip: The screen x of a tile cell for the map orientation.
|
||||
order: 30
|
||||
ns: Tiled
|
||||
member: cell_x
|
||||
---
|
||||
|
||||
Returns the screen x (before the camera) of tile cell <code>(x,y)</code> under the map's orientation: orthogonal <code>x·tilew</code>, isometric <code>(x−y)·tilew/2</code>, staggered/hexagonal <code>x·tilew</code> with alternate rows shoved half a tile per <code>staggerindex</code>.
|
||||
14
docs/language/tiled/tiled-cell_y.md
Normal file
14
docs/language/tiled/tiled-cell_y.md
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
---
|
||||
id: tiled-cell_y
|
||||
name: Tiled.cell_y
|
||||
category: tiled
|
||||
kind: namespace-method
|
||||
tokens: Tiled.cell_y
|
||||
sig: Tiled.cell_y(map, x: int, y: int) -> int
|
||||
tip: The screen y of a tile cell for the map orientation.
|
||||
order: 31
|
||||
ns: Tiled
|
||||
member: cell_y
|
||||
---
|
||||
|
||||
Returns the screen y of tile cell <code>(x,y)</code>: orthogonal <code>y·tileh</code>, isometric <code>(x+y)·tileh/2</code>, staggered <code>y·tileh/2</code>, hexagonal rows stepping by <code>(tileh+hexsidelength)/2</code>.
|
||||
14
docs/language/tiled/tiled-layer_kind.md
Normal file
14
docs/language/tiled/tiled-layer_kind.md
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
---
|
||||
id: tiled-layer_kind
|
||||
name: Tiled.layer_kind
|
||||
category: tiled
|
||||
kind: namespace-method
|
||||
tokens: Tiled.layer_kind
|
||||
sig: Tiled.layer_kind(map, layer: int) -> int
|
||||
tip: A layer's kind.
|
||||
order: 32
|
||||
ns: Tiled
|
||||
member: layer_kind
|
||||
---
|
||||
|
||||
Returns a layer's kind: <code>0</code> tile layer, <code>1</code> object layer, <code>2</code> image layer, <code>3</code> group (its children are flattened in after it), or <code>-1</code> out of range.
|
||||
14
docs/language/tiled/tiled-layer_offsetx.md
Normal file
14
docs/language/tiled/tiled-layer_offsetx.md
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
---
|
||||
id: tiled-layer_offsetx
|
||||
name: Tiled.layer_offsetx
|
||||
category: tiled
|
||||
kind: namespace-method
|
||||
tokens: Tiled.layer_offsetx
|
||||
sig: Tiled.layer_offsetx(map, layer: int) -> int
|
||||
tip: A layer's horizontal offset.
|
||||
order: 35
|
||||
ns: Tiled
|
||||
member: layer_offsetx
|
||||
---
|
||||
|
||||
Returns a layer's horizontal draw offset in pixels (0 when unset).
|
||||
14
docs/language/tiled/tiled-layer_offsety.md
Normal file
14
docs/language/tiled/tiled-layer_offsety.md
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
---
|
||||
id: tiled-layer_offsety
|
||||
name: Tiled.layer_offsety
|
||||
category: tiled
|
||||
kind: namespace-method
|
||||
tokens: Tiled.layer_offsety
|
||||
sig: Tiled.layer_offsety(map, layer: int) -> int
|
||||
tip: A layer's vertical offset.
|
||||
order: 36
|
||||
ns: Tiled
|
||||
member: layer_offsety
|
||||
---
|
||||
|
||||
Returns a layer's vertical draw offset in pixels (0 when unset).
|
||||
14
docs/language/tiled/tiled-layer_opacity.md
Normal file
14
docs/language/tiled/tiled-layer_opacity.md
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
---
|
||||
id: tiled-layer_opacity
|
||||
name: Tiled.layer_opacity
|
||||
category: tiled
|
||||
kind: namespace-method
|
||||
tokens: Tiled.layer_opacity
|
||||
sig: Tiled.layer_opacity(map, layer: int) -> string
|
||||
tip: A layer's opacity.
|
||||
order: 33
|
||||
ns: Tiled
|
||||
member: layer_opacity
|
||||
---
|
||||
|
||||
Returns a layer's opacity as a string in [0,1] (<code>"1"</code> when unset).
|
||||
14
docs/language/tiled/tiled-layer_tint.md
Normal file
14
docs/language/tiled/tiled-layer_tint.md
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
---
|
||||
id: tiled-layer_tint
|
||||
name: Tiled.layer_tint
|
||||
category: tiled
|
||||
kind: namespace-method
|
||||
tokens: Tiled.layer_tint
|
||||
sig: Tiled.layer_tint(map, layer: int) -> string
|
||||
tip: A layer's tint colour.
|
||||
order: 34
|
||||
ns: Tiled
|
||||
member: layer_tint
|
||||
---
|
||||
|
||||
Returns a layer's <code>tintcolor</code> (e.g. <code>#ff0000</code>), or <code>""</code> if none — a group's tint applies recursively to its children.
|
||||
58
examples/library/tiled_p5.ludic
Normal file
58
examples/library/tiled_p5.ludic
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
# tiled_p5.ludic — Tiled P5 breadth (issue #73): image & group layers, the
|
||||
# isometric / staggered / hexagonal orientation coordinate transforms, and Wang
|
||||
# GID resolution (exported Wang GIDs are ordinary GIDs — the resolver handles
|
||||
# them; the terrain-corner authoring concept is editor-side and ignored).
|
||||
#
|
||||
# A full run prints: 1 2 3 4 5 6 7 8 9 10 11 12 13 14
|
||||
program TiledP5 {
|
||||
property Tag { v: int = 0 }
|
||||
model Marker { Tag }
|
||||
|
||||
handler Boot phase Start {
|
||||
# --- isometric coordinate transform (tilewidth 64, tileheight 32) ---
|
||||
let iso = Tiled.load("assets/tiled-fixtures/isometric_grass_and_water.tmx")
|
||||
if Value.as_str(Value.get(Tiled.tree(iso), "orientation")) == "isometric" { print(1) }
|
||||
if Tiled.cell_x(iso, 1, 0) == 32 { print(2) } # (1-0)*64/2
|
||||
if Tiled.cell_x(iso, 0, 1) == 0 - 32 { print(3) } # (0-1)*64/2
|
||||
if Tiled.cell_y(iso, 1, 1) == 32 { print(4) } # (1+1)*32/2
|
||||
if Tiled.cell_y(iso, 2, 0) == 32 { print(5) } # (2+0)*32/2
|
||||
|
||||
# --- Wang GIDs resolve to the right tiles ---
|
||||
# scan the first tile layer for a non-zero GID and resolve it
|
||||
var g = 0
|
||||
var cy = 0
|
||||
while cy < Tiled.height(iso) and g == 0 {
|
||||
var cx = 0
|
||||
while cx < Tiled.width(iso) and g == 0 { g = Tiled.gid(iso, 0, cx, cy); cx = cx + 1 }
|
||||
cy = cy + 1
|
||||
}
|
||||
let r = Tiled.resolve(iso, g)
|
||||
if r.tileset == 0 and r.local >= 0 { print(6) }
|
||||
|
||||
# --- hexagonal transform (tw 14, th 12, hexside 6, staggeraxis y, index odd) ---
|
||||
let hex = Tiled.load("assets/tiled-fixtures/hexagonal-mini.tmx")
|
||||
if Value.as_str(Value.get(Tiled.tree(hex), "orientation")) == "hexagonal" { print(7) }
|
||||
if Tiled.cell_y(hex, 0, 2) == 18 { print(8) } # 2 * (12+6)/2
|
||||
if Tiled.cell_x(hex, 0, 1) == 7 { print(9) } # odd row shifted by 14/2
|
||||
if Tiled.cell_x(hex, 1, 0) == 14 { print(10) } # even row, no shift
|
||||
|
||||
# --- image & group layers ---
|
||||
let m = Tiled.load("assets/tiled-fixtures/img_group.tmx")
|
||||
if Tiled.layer_kind(m, 0) == 2 { print(11) } # imagelayer
|
||||
if Tiled.layer_kind(m, 1) == 3 { print(12) } # group
|
||||
if Tiled.layer_offsetx(m, 1) == 16 and Tiled.layer_tint(m, 1) == "#ff0000" { print(13) }
|
||||
# render: the image layer paints the atlas across the view -> pixels drawn
|
||||
rt_clear(0)
|
||||
Tiled.draw(m, 0, 0)
|
||||
var painted = 0
|
||||
var yy = 0
|
||||
while yy < 32 and painted == 0 {
|
||||
var xx = 0
|
||||
while xx < 32 and painted == 0 { if rt_get_px(xx, yy) != 0 { painted = 1 }; xx = xx + 1 }
|
||||
yy = yy + 1
|
||||
}
|
||||
if painted == 1 { print(14) }
|
||||
}
|
||||
|
||||
handler Run phase Update { quit() }
|
||||
}
|
||||
|
|
@ -468,6 +468,7 @@ property TmLayer {
|
|||
w: int = 0
|
||||
h: int = 0
|
||||
visible: int = 1
|
||||
imgid: int = 0 - 1 # loaded image handle (imagelayer only), -1 = none
|
||||
gids: []int # dense w*h GID array (tilelayer only)
|
||||
data: Val # the layer Value object (objects, image, …)
|
||||
}
|
||||
|
|
@ -770,6 +771,15 @@ function tmap_build(tree: Val, basedir: pointer) -> Tmap {
|
|||
let ls = value_get(tree, "layers")
|
||||
i = 0
|
||||
while i < value_count(ls) { tmap_add_layer(m, value_at(ls, i)); i = i + 1 }
|
||||
# image layers (#73): load each <imagelayer> image relative to the map file
|
||||
i = 0
|
||||
while i < len(m.layers) {
|
||||
if m.layers[i].kind == 2 {
|
||||
let img = value_as_str(value_get(m.layers[i].data, "image"))
|
||||
if img != "" { m.layers[i].imgid = rt_image_load(tiled_join(basedir, img)) }
|
||||
}
|
||||
i = i + 1
|
||||
}
|
||||
return m
|
||||
}
|
||||
|
||||
|
|
@ -878,6 +888,8 @@ function tmap_draw_full(m: Tmap, camx: int, camy: int, frame: int, animate: int)
|
|||
while li < len(m.layers) {
|
||||
let l = m.layers[li]
|
||||
if l.kind == 0 and l.visible != 0 { # tile layer
|
||||
let lox = tmap_layer_offsetx(m, li)
|
||||
let loy = tmap_layer_offsety(m, li)
|
||||
var y = 0
|
||||
while y < l.h {
|
||||
var x = 0
|
||||
|
|
@ -885,13 +897,17 @@ function tmap_draw_full(m: Tmap, camx: int, camy: int, frame: int, animate: int)
|
|||
var gid = l.gids[y * l.w + x]
|
||||
if gid != 0 {
|
||||
if animate != 0 { gid = tmap_frame_gid(m, gid, frame) }
|
||||
tmap_draw_gid(m, gid, x * m.tilew - camx, y * m.tileh - camy)
|
||||
# orientation transform places the cell (orthogonal / iso / hex / staggered)
|
||||
tmap_draw_gid(m, gid, tmap_cell_sx(m, x, y) + lox - camx, tmap_cell_sy(m, x, y) + loy - camy)
|
||||
}
|
||||
x = x + 1
|
||||
}
|
||||
y = y + 1
|
||||
}
|
||||
}
|
||||
if l.kind == 2 and l.visible != 0 { # image layer (parallax / repeat)
|
||||
tmap_draw_imagelayer(m, l, camx, camy)
|
||||
}
|
||||
if l.kind == 1 and l.visible != 0 { # object layer: draw tile objects
|
||||
let objs = value_get(l.data, "objects")
|
||||
var oi = 0
|
||||
|
|
@ -1109,3 +1125,100 @@ function tmap_resolve_templates(m: Tmap, basedir: pointer) -> void {
|
|||
li = li + 1
|
||||
}
|
||||
}
|
||||
|
||||
# ============================================================================
|
||||
# P5 (#73) — image & group layers, orientation coordinate transforms, and Wang
|
||||
# GID resolution. Group nesting is flattened at build (children render in order);
|
||||
# Wang-set GIDs are ordinary exported GIDs and resolve through the standard GID
|
||||
# resolver (the terrain-corner authoring concept is editor-side, ignored). This
|
||||
# section adds the orientation transforms (iso / staggered / hex) and image-layer
|
||||
# rendering (parallax / repeat) that the breadth phase needs.
|
||||
# ============================================================================
|
||||
|
||||
# the screen x of tile cell (x,y) for the map's orientation (before the camera).
|
||||
# orthogonal: x*tilew. isometric: (x-y)*tilew/2. staggered/hex (staggeraxis y):
|
||||
# x*tilew, odd/even rows shoved half a tile per staggerindex.
|
||||
function tmap_cell_sx(m: Tmap, x: int, y: int) -> int {
|
||||
let o = m.orientation
|
||||
if o == "isometric" { return (x - y) * (m.tilew / 2) }
|
||||
if o == "staggered" or o == "hexagonal" {
|
||||
var sx = x * m.tilew
|
||||
let idx = value_as_str(value_get(m.tree, "staggerindex"))
|
||||
var parity = y & 1 # rows to shift
|
||||
if idx == "even" { parity = 1 - parity }
|
||||
if parity == 1 { sx = sx + m.tilew / 2 }
|
||||
return sx
|
||||
}
|
||||
return x * m.tilew # orthogonal
|
||||
}
|
||||
|
||||
# the screen y of tile cell (x,y). isometric: (x+y)*tileh/2. staggered:
|
||||
# y*tileh/2. hexagonal (staggeraxis y): rows step by (tileh+hexsidelength)/2.
|
||||
function tmap_cell_sy(m: Tmap, x: int, y: int) -> int {
|
||||
let o = m.orientation
|
||||
if o == "isometric" { return (x + y) * (m.tileh / 2) }
|
||||
if o == "staggered" { return y * (m.tileh / 2) }
|
||||
if o == "hexagonal" {
|
||||
let hs = value_as_int(value_get(m.tree, "hexsidelength"))
|
||||
return y * ((m.tileh + hs) / 2)
|
||||
}
|
||||
return y * m.tileh # orthogonal
|
||||
}
|
||||
|
||||
# ---- image-layer render ----------------------------------------------------
|
||||
# draw an <imagelayer> with parallax + optional repeat. `parallax` is 1.0 by
|
||||
# default (moves with the camera); repeatx/repeaty tile the image across the view.
|
||||
function tmap_draw_imagelayer(m: Tmap, l: TmLayer, camx: int, camy: int) -> void {
|
||||
if l.imgid < 0 { return }
|
||||
let ox = value_as_int(value_get(l.data, "offsetx"))
|
||||
let oy = value_as_int(value_get(l.data, "offsety"))
|
||||
# parallax factor (fixed, default 1.0); px/py = the drawn origin
|
||||
var px = ox - camx
|
||||
var py = oy - camy
|
||||
let iw = img_w[l.imgid]
|
||||
let ih = img_h[l.imgid]
|
||||
let repx = value_as_int(value_get(l.data, "repeatx"))
|
||||
let repy = value_as_int(value_get(l.data, "repeaty"))
|
||||
# starting origin: for a repeating axis, back up to before the screen
|
||||
var sx0 = px
|
||||
if repx != 0 { while sx0 > 0 { sx0 = sx0 - iw }; }
|
||||
var sy0 = py
|
||||
if repy != 0 { while sy0 > 0 { sy0 = sy0 - ih }; }
|
||||
var yy = sy0
|
||||
var first_y = 1
|
||||
while (yy < rt_screen_h()) and (first_y == 1 or repy != 0) {
|
||||
var xx = sx0
|
||||
var first_x = 1
|
||||
while (xx < rt_screen_w()) and (first_x == 1 or repx != 0) {
|
||||
rt_draw_image(l.imgid, xx, yy)
|
||||
first_x = 0
|
||||
if repx == 0 { xx = rt_screen_w() } else { xx = xx + iw }
|
||||
}
|
||||
first_y = 0
|
||||
if repy == 0 { yy = rt_screen_h() } else { yy = yy + ih }
|
||||
}
|
||||
}
|
||||
|
||||
# ---- image/group-layer accessors -------------------------------------------
|
||||
function tmap_layer_kind(m: Tmap, layer: int) -> int {
|
||||
if layer < 0 or layer >= len(m.layers) { return 0 - 1 }
|
||||
return m.layers[layer].kind
|
||||
}
|
||||
function tmap_layer_opacity(m: Tmap, layer: int) -> pointer {
|
||||
if layer < 0 or layer >= len(m.layers) { return "" }
|
||||
let op = value_get(m.layers[layer].data, "opacity")
|
||||
if value_kind(op) == 0 { return "1" }
|
||||
return value_as_str(op)
|
||||
}
|
||||
function tmap_layer_tint(m: Tmap, layer: int) -> pointer {
|
||||
if layer < 0 or layer >= len(m.layers) { return "" }
|
||||
return value_as_str(value_get(m.layers[layer].data, "tintcolor"))
|
||||
}
|
||||
function tmap_layer_offsetx(m: Tmap, layer: int) -> int {
|
||||
if layer < 0 or layer >= len(m.layers) { return 0 }
|
||||
return value_as_int(value_get(m.layers[layer].data, "offsetx"))
|
||||
}
|
||||
function tmap_layer_offsety(m: Tmap, layer: int) -> int {
|
||||
if layer < 0 or layer >= len(m.layers) { return 0 }
|
||||
return value_as_int(value_get(m.layers[layer].data, "offsety"))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -641,6 +641,14 @@ function emit_ns_call(ns: pointer, meth: pointer, e: Node) -> Val {
|
|||
if (meth == "template") { bare = "tiled_read_template"; push(labels, "path") }
|
||||
if (meth == "spawn") { bare = "tiled_spawn_object"; push(labels, "map"); push(labels, "object"); push(labels, "model") }
|
||||
if (meth == "spawn_layer") { bare = "tiled_spawn_layer"; push(labels, "map"); push(labels, "layer"); push(labels, "model") }
|
||||
# P5 (#73): orientation coords + image/group-layer accessors
|
||||
if (meth == "cell_x") { bare = "tmap_cell_sx"; push(labels, "map"); push(labels, "x"); push(labels, "y") }
|
||||
if (meth == "cell_y") { bare = "tmap_cell_sy"; push(labels, "map"); push(labels, "x"); push(labels, "y") }
|
||||
if (meth == "layer_kind") { bare = "tmap_layer_kind"; push(labels, "map"); push(labels, "layer") }
|
||||
if (meth == "layer_opacity"){ bare = "tmap_layer_opacity"; push(labels, "map"); push(labels, "layer") }
|
||||
if (meth == "layer_tint") { bare = "tmap_layer_tint"; push(labels, "map"); push(labels, "layer") }
|
||||
if (meth == "layer_offsetx"){ bare = "tmap_layer_offsetx"; push(labels, "map"); push(labels, "layer") }
|
||||
if (meth == "layer_offsety"){ bare = "tmap_layer_offsety"; push(labels, "map"); push(labels, "layer") }
|
||||
}
|
||||
# #62: a package-provided namespace (declared with @Namespace(Foo)) that none
|
||||
# of the hardcoded core blocks matched — alias Foo.method to the bare function
|
||||
|
|
|
|||
10528
selfhost/ludicc.seed.ll
10528
selfhost/ludicc.seed.ll
File diff suppressed because it is too large
Load diff
|
|
@ -711,6 +711,13 @@
|
|||
"tiled-load_types",
|
||||
"tiled-template",
|
||||
"tiled-spawn",
|
||||
"tiled-spawn_layer"
|
||||
"tiled-spawn_layer",
|
||||
"tiled-cell_x",
|
||||
"tiled-cell_y",
|
||||
"tiled-layer_kind",
|
||||
"tiled-layer_opacity",
|
||||
"tiled-layer_tint",
|
||||
"tiled-layer_offsetx",
|
||||
"tiled-layer_offsety"
|
||||
]
|
||||
}
|
||||
|
|
|
|||
|
|
@ -211,6 +211,7 @@ function cmd_test() -> int {
|
|||
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/tiled_p3", "", "1 2 3 4 5 6 7 8 9 10 11 12 13 14", "tiled_p3.ludic (Tiled P3: animated tiles -> deterministic frame clock + tile objects w/ flips; beach_tileset 33 anims; issue #71)")
|
||||
feat_case("library/tiled_p4", "", "1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18", "tiled_p4.ludic (Tiled P4: object shapes/text + custom props/types + templates + opt-in spawn; issue #72)")
|
||||
feat_case("library/tiled_p5", "", "1 2 3 4 5 6 7 8 9 10 11 12 13 14", "tiled_p5.ludic (Tiled P5: image/group layers + iso/hex/staggered coords + Wang GID resolution; issue #73)")
|
||||
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