Recipes
Inventory item pickups keys and equipping
The player collects keys, potions, or ammo, carries them, and spends them later. There is no inventory or
StatsComponent (stripped); the inventory is a durable warehouse record and item logic is a script.engine v1.0.234since script-semantic-patch-ops.v1, action-catalog.v1.0.232, persistence.v1, ui.v1, world.v1Copy for LLM
Use this for
picking up keys, potions, ammo, and tools into a held inventory; tracking quantities of items; using, consuming, or equipping an item; a locked door that opens only if the player holds the key
Not for
a pure score counter with no items (see collectibles-and-scoring); durable cross-session profile saves only (see saves-and-persistence); weapon firing behavior (see projectiles-and-ranged-weapons)
Pairs with: Collectibles pickups scoring and win condition, Saves persistence player progress and data stores, UI HUD panels widgets and world nameplates, Doors buttons levers and press-to-interact
The recipe
Author with project_apply_script_semantic_patch using the ai_safe op pack. Held items live in a warehouse store (default storeKey:"inventory", recordKey:"player"), one field per item type.
- Make each world pickup an entity tagged by item type with a trigger
ColliderComponent(collision:"trigger"). - On pickup,
addTriggerHandler{ "handlerKey":"onPickup" }. Inside it:incrementNumericState{ "field":"keys", "by": 1 }to add a counted item, orwriteTypedStateValueto set a unique key you either hold or do not; thendespawnEntity{ "reason":"picked_up" }to remove the world item. - For a list of distinct items, append to an array field with
ctx.warehouse.appendin a whole-body GessaScript body (replaceScriptFromGessaScript); read the whole record back withctx.warehouse.getor filter withctx.warehouse.query. - Gate an action on holding an item:
readTypedStateValuethe item field, and only open the locked door (see doors-buttons-and-interactions) or fire the weapon when the count is above zero. - Consume or equip: on use,
incrementNumericStatethe field by -1 (consume) orwriteTypedStateValueanequippedfield to the item id (equip). Project every count to the HUD withwireHudStateBindingorctx.ui.setWidgetValue.
Pitfalls
- Keep the inventory in the warehouse, not on a component; a count written only on the entity is lost when the entity despawns or the player reloads.
ctx.warehouse.*writes are prefetch-then-drain and authority-gated (persistence.prefetch_only); mutate on the server, and read the field you intend to change in the same handler so the drain is deterministic.- Decrement guardedly: check the count is above zero before consuming, or you create negative inventory.
- For stackable items increment a number; for unique items (a named key) set a boolean or an id, not a counter.
Verify
simulation_run(qa.run.start) to prove a pickup raises the count, using an item lowers it, and a gated door opens only while the key is held.project_get_graph_snapshotto confirm the pickup triggers and handlers exist.