Builtin Library
README.md
inventory
Lua-first slot-based inventory system. State is stored as component data in the engine; this module provides pure functions that mutate (or normalise) that state. Covers fixed-size inventory slots, named equipment slots, hotbar references, item stacking, split/move/equip, and a UI-ready resolved hotbar view.
Exports
Inventory.new(opts: InventoryOpts?) -> InventoryState— create a fresh, normalised inventory state.Inventory.normalize(state: InventoryState?) -> InventoryState— fill missing fields, drop empty slots, pad arrays.Inventory.getSlot(state, index) -> Slot?/setSlot(state, index, slot)— read/write inventory slots.Inventory.getEquipment(state, slotName) -> Slot?/setEquipment(state, slotName, slot)— read/write equipment slots.Inventory.getHotbarEntry(state, index) -> HotbarEntry?/setHotbar(state, index, source, ref)— bind hotbar slots to inventory or equipment.Inventory.selectHotbar(state, index)/getHotbarSelected(state) -> number— currently selected hotbar slot.Inventory.resolveHotbarSlot(state, index) -> Slot?— resolve a hotbar slot to its referenced item.Inventory.move(state, fromIndex, toIndex, itemDefs?) -> boolean— move/swap/stack between inventory slots.Inventory.split(state, fromIndex, toIndex, amount) -> boolean— split a stack into an empty slot.Inventory.equipFromSlot(state, fromIndex, itemDefs?) -> boolean— equip from an inventory slot.Inventory.unequipToSlot(state, slotName, toIndex) -> boolean— unequip to an inventory slot.Inventory.buildHotbarSlots(state, itemDefs?) -> { HotbarSlotView }— UI-ready hotbar view (icon, count, tooltip).
Types:
Slot = { id?: string, count?: number, max?: number }HotbarEntry = { source: string, index?: number, slot?: string }InventoryState = { slots, equipment, hotbar, hotbarSelected, slotCount, hotbarSize, equipmentSlots }InventoryOpts = { slotCount?: number, hotbarSize?: number, equipmentSlots?: { string } }ItemDef = { name?: string, icon?: string, maxStack?: number, equipSlot?: string }ItemDefs = { [string]: ItemDef }HotbarSlotView = { icon: string, count: number, tooltip: string }
Usage
local Inventory = require("@builtin::modules.extras.inventory")
local state = Inventory.new({ slotCount = 20, hotbarSize = 8 })
Inventory.setSlot(state, 1, { id = "sword", count = 1, max = 1 })
Inventory.setSlot(state, 2, { id = "potion", count = 3, max = 10 })
Inventory.setHotbar(state, 1, "inventory", 1)
local views = Inventory.buildHotbarSlots(state, itemDefs)
Notes
- Pure functions — they mutate the supplied
statein place but never call into the engine. Safe to use anywhere. setSlot/setEquipmentalways normalise the slot — anid-less or zero-count slot is stored asnil.movewill stack identical-id slots up tomax, otherwise it swaps. The larger of the twomaxvalues wins when stacking.equipFromSlotrequires the item to have anequipSlotfield initemDefsAND that the slot name appear instate.equipmentSlots.- The schema is the shape stored as component data, so persisted state
flows through
normalizecleanly after engine reload.