Calic a814b10ef2 fix: use composition.reg_id for entity identity in slot_of
get_children() returns fresh userdata wrappers without __eq; raw ==
compares Lua pointers (fails across separate get_children calls).
slot_of now reads composition.reg_id from each child to find the
matching slot, making contains/remove reliable across wrapper instances.
2026-06-13 17:45:13 +02:00

lib-core.inventory-list

List-container inventory over the engine.entity tree. Attaches items as synthetic children under slot names item.1, item.2, ... and manages the composition tag-index so items are hidden from the renderable index while inside a container.

Version: 0.1.0 Lib-ID: lib-core.inventory-list Requires: lib-core.composition 0.2.0 Tags: inventory, entity, composition, list-container

Topology

graph LR
  this["lib-core.inventory-list"]
  comp["lib-core.composition"]
  engine["engine.*"]
  this --> comp
  this --> engine

Scope (v0.1.0)

Thin list-container inventory spine. Items must be stack_mode="individual". No weight, volume, or grid constraints (Phase F/G). No stackable items (Phase C+).

Supported:

  • add(container, item) — attach item to container under synthetic slot
  • remove(container, item) — detach item, return it
  • contents(container) — ordered list of items currently in container
  • contains(container, item) — membership check
  • count(container) — number of items

Deferred (Loud-Error or not applicable):

  • Stack items (stack_mode != "individual") → Loud-Error in v0.1
  • Capacity / weight / volume constraints → Phase F/G

API

inventory.add(container, item)

Syntax: inventory.add(container: entity, item: entity) -> void

Example:

local inventory = require("lib-core.inventory-list")

inventory.add(backpack, sword)
-- sword is now a child of backpack under "item.1"
-- sword is removed from the renderable index

Description: Validates that container is a composition-entity with container={kind="list"} (Loud-Error if not). Validates item has stack_mode property (Loud-Error if missing) and stack_mode == "individual" (Loud-Error otherwise). Detaches item from its current parent if any, attaches to container under the next synthetic slot (item.<n>), and calls composition.set_tag(item, "renderable", false) to remove the item from the renderable index.

inventory.remove(container, item) -> item

Syntax: inventory.remove(container: entity, item: entity) -> entity

Example:

local dropped = inventory.remove(backpack, sword)
-- sword detached from backpack; renderable tag restored
-- caller re-parents dropped into world + sets position

Description: Finds item in container's children (Loud-Error if not present), detaches it via entity.detach, calls composition.set_tag(item, "renderable", true), returns item.

inventory.contents(container) -> {item, ...}

Syntax: inventory.contents(container: entity) -> {entity, ...}

Example:

for _, it in ipairs(inventory.contents(backpack)) do
    print(it:get_property("name"))
end

Description: Returns all items currently in container, ordered by insertion order (numeric suffix of synthetic slot names). Filters children by the item-recognition rule: child must have a stack_mode property. Non-item children (future use) are silently excluded.

inventory.contains(container, item) -> bool

Syntax: inventory.contains(container: entity, item: entity) -> bool

Example:

local has_rock = inventory.contains(backpack, rock)

Description: Returns true if item is currently a child of container under a synthetic slot.

inventory.count(container) -> number

Syntax: inventory.count(container: entity) -> number

Example:

local n = inventory.count(backpack)

Description: Returns the number of items currently in container. Equivalent to #inventory.contents(container).

Notes

Synthetic Slot Naming

Items are stored under slot names item.<n> where n is a monotonically-increasing integer per container. The counter is not persisted — on any cold call next_slot scans existing children for item.<n> patterns and takes max(n) + 1. This makes slot naming reconstruction-safe after engine reload without any additional state.

Item-Recognition Rule

An entity is recognized as an item if it has a stack_mode property (any non-nil, non-empty string value). The stack_mode must be "individual" for add to succeed in v0.1. This rule is consistent with the template convention for item templates (declaring stack_mode in their properties block).

set_tag Interaction

add calls composition.set_tag(item, "renderable", false), which removes the item from lib-core.composition's list_by_tag("renderable") index. remove calls set_tag(item, "renderable", true) to restore it. This ensures items in inventory are invisible to the render system without any per-frame filtering.

Description
No description provided
Readme 40 KiB
Languages
Lua 100%