feat(stdlib): Tiled P4 — objects, custom props/types, templates, opt-in spawn (#72)
- Object layers: all shapes (rectangle/ellipse/point/polygon/polyline/text) and custom properties parse and are queryable — Tiled.object_count / Tiled.object / Tiled.object_shape, and Tiled.prop / prop_int / prop_type over any object / tile / layer / map. - Custom types: Tiled.load_types reads an objecttypes.xml project custom-type table so a class property resolves its default; enum values resolve as strings. - Templates: Tiled.template reads a .tx/.tj, and Tiled.load merges each object's `template` reference under the instance's overrides (field inheritance). - Opt-in spawning: Tiled.spawn / Tiled.spawn_layer map an object's class + properties onto Ludic components through the reflection ABI (Position from x/y, each property to a like-named field). Off by default — no gameplay coupling in the core load. Split into tiled_spawn.ludic, spliced only for a Tiled *game* (the world table exists only under has_ecs), so a plain map-reading tool never links against the reflection ABI. Proven by library/tiled_p4.ludic (18 assertions) incl. the design's named orthogonal-outside.tmx object shapes. x test: 95 passed. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
parent
58e1105f2d
commit
b8c71d2a8e
22 changed files with 18278 additions and 17081 deletions
|
|
@ -630,6 +630,17 @@ function emit_ns_call(ns: pointer, meth: pointer, e: Node) -> Val {
|
|||
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") }
|
||||
# P4 (#72): objects / properties / custom types / templates / opt-in spawn
|
||||
if (meth == "object_count") { bare = "tmap_object_count"; push(labels, "map"); push(labels, "layer") }
|
||||
if (meth == "object") { bare = "tmap_object"; push(labels, "map"); push(labels, "layer"); push(labels, "index") }
|
||||
if (meth == "object_shape") { bare = "tiled_object_shape"; push(labels, "object") }
|
||||
if (meth == "prop") { bare = "tiled_prop_str"; push(labels, "container"); push(labels, "name") }
|
||||
if (meth == "prop_int") { bare = "tiled_prop_int"; push(labels, "container"); push(labels, "name") }
|
||||
if (meth == "prop_type") { bare = "tiled_prop_type"; push(labels, "container"); push(labels, "name") }
|
||||
if (meth == "load_types") { bare = "tiled_load_types"; push(labels, "path") }
|
||||
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") }
|
||||
}
|
||||
# #62: a package-provided namespace (declared with @Namespace(Foo)) that none
|
||||
# of the hardcoded core blocks matched — alias Foo.method to the bare function
|
||||
|
|
|
|||
|
|
@ -744,6 +744,11 @@ function maybe_splice_runtime() -> void {
|
|||
do_import("runtime/native/base64.ludic")
|
||||
do_import("runtime/native/value.ludic")
|
||||
do_import("runtime/native/tiled.ludic")
|
||||
# #72 opt-in spawning stands on the reflection ABI, which the compiler emits
|
||||
# only for a game (emit_decl: has_ecs -> emit_world_table). So splice the
|
||||
# spawn helpers only for a Tiled game; a plain map-reading tool never links
|
||||
# against the world table.
|
||||
if has_ecs() { do_import("runtime/native/tiled_spawn.ludic") }
|
||||
cur_dir = saved
|
||||
}
|
||||
# Reflect.serialize/apply add the reflection serializer, which stands on both
|
||||
|
|
|
|||
34828
selfhost/ludicc.seed.ll
34828
selfhost/ludicc.seed.ll
File diff suppressed because it is too large
Load diff
Loading…
Add table
Add a link
Reference in a new issue