From b2a6d5c1705939e16de5bf07acac20efb1892033 Mon Sep 17 00:00:00 2001 From: Axel Meyer Date: Sun, 14 Jun 2026 11:57:29 +0200 Subject: [PATCH] feat: add template_of getter + bump to v0.3.0 Add composition.template_of(entity) -> string|nil, returning the template-id this entity was created from. Returns nil for non-composition-managed entities (e.g. raw entity.create() handles) and loud-errors on nil arg. Enables crafting and inventory consumers to recover the template-id without round-tripping through tags. Co-Authored-By: Claude Opus 4.7 (1M context) --- README.md | 29 ++++++++++++++++++++++++++--- init.lua | 25 ++++++++++++++++++++++++- manifest.lib | 2 +- 3 files changed, 51 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index d77e051..310868c 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@ property defaults; `create` spawns an `engine.entity` with template defaults + per-instance overrides; entities are indexed by template-id and tag for cheap reverse-lookup. -**Version:** 0.2.0 +**Version:** 0.3.0 **Lib-ID:** lib-core.composition **Requires:** (none — uses engine `entity.*`, `domain.contribute` only) **Tags:** composition, entity, template, tag-index @@ -21,15 +21,16 @@ graph LR ``` -## Scope (v0.2.0) +## Scope (v0.3.0) -Template-Only-Subset + set_tag + container declaration. +Template-Only-Subset + set_tag + container declaration + template-id reverse-lookup. **Supported:** - `define_template{id, properties, tags}` - `define_template{..., container={kind="list"}}` — v0.2: `kind="list"` accepted - `create{template, properties}` - `list_by_template(id)`, `list_by_tag(tag)` +- `template_of(entity)` — v0.3: read back the template-id an entity was created from - `destroy(entity)` - `set_tag(entity, tag, present)` — v0.2: runtime tag add/remove - `get_container(entity)` — v0.2: read back the container block from entity's template @@ -151,6 +152,28 @@ end declared `tag` in its `tags` array. Used by `lib-core.render` `draw_entities{tag="..."}` (see A.2). Empty list if tag has no entities. +### `composition.template_of(entity)` + +**Syntax:** `composition.template_of(entity) -> string or nil` + +**Example:** +```lua +local sign = composition.create{ template = "sign" } +local tpl_id = composition.template_of(sign) +-- tpl_id == "sign" + +local raw = entity.create() +local none = composition.template_of(raw) +-- none == nil (raw entities are not composition-managed) +``` + +**Description:** Returns the template-id this entity was created from, +or `nil` if the entity is not composition-managed (e.g. a raw +`entity.create()` handle, or an entity whose composition meta-record +has already been cleared via `destroy`). Loud-Error if `entity` is `nil`. +Used by crafting / inventory / recipe code that needs to recover the +template-id without round-tripping through tags. + ### `composition.set_tag(entity, tag, present)` **Syntax:** `composition.set_tag(entity, tag: string, present: boolean) -> void` diff --git a/init.lua b/init.lua index 027373b..2ba4521 100644 --- a/init.lua +++ b/init.lua @@ -1,5 +1,5 @@ -- ===================================================================== --- lib-core.composition v0.2.0 — Template + Instantiation + Tag-Index +-- lib-core.composition v0.3.0 — Template + Instantiation + Tag-Index -- See: meta/docs/superpowers/specs/2026-06-09-phase-A-inactive-entities-... -- -- v0.1.0 Template-Only-Subset: @@ -23,6 +23,11 @@ -- All constraint fields (weight_max, volume_max, grid, accepts_fluid, -- accepts_gas, restrictions) → Loud-Error (Phase F/G deferred). -- +-- v0.3.0 additions: +-- - composition.template_of(entity) — returns the template_id this +-- entity was created from, or nil if the entity is not +-- composition-managed. Loud-Error if entity is nil. +-- -- DEFERRED (loud-error if attempted): -- - slots → Phase D Trigger (Composite Items with Sub-Items) -- - container constraint fields (weight_max, volume_max, grid, @@ -353,6 +358,24 @@ function M.list_by_tag(tag) return out end +-- Returns the template_id this entity was created from, or nil if +-- the entity is not composition-managed (no reg_id property). +-- Loud-Error if entity is nil. +function M.template_of(target_entity) + if target_entity == nil then + error("composition.template_of: entity must not be nil", 2) + end + local reg_id = target_entity:get_property("composition.reg_id") + if not reg_id or reg_id == 0 then + return nil + end + local meta = entity_meta[reg_id] + if not meta then + return nil + end + return meta.template_id +end + -- Remove entity from indices + destroy engine-side. Idempotent. local function remove_from_list(list, entity) if not list then return end diff --git a/manifest.lib b/manifest.lib index b4d60e4..1df91ca 100644 --- a/manifest.lib +++ b/manifest.lib @@ -1 +1 @@ -{"id":"lib-core.composition","version":"0.2.0","api_min":"0.1","deps":[]} +{"id":"lib-core.composition","version":"0.3.0","api_min":"0.1","deps":[]}