Inventory System
Read and modify the player's item inventory, equipment, and carry state from custom instructions and interactable objects.
Overview
The inventory system has two distinct layers that work together during a level run.
| Layer | Class | Lifetime | When to use |
|---|---|---|---|
| Persistent | PlayerInventory.current | Entire game session | Reading stats, checking equipped gear, after level completion |
| Execution | context.inventory | One level run | Consuming items, adding pickups, checking inventory inside Tick() |
Always use context.inventory inside a Tick() override. The execution inventory is a deep copy of PlayerInventory.current that gets committed back only when the level is completed successfully — so failed runs do not consume items permanently.
1 — Reading Inventory in an Instruction
Access the execution inventory through the ExecutionContext passed to Tick(). The most common operations are checking whether an item is present and consuming it.
public override IEnumerator Tick(ExecutionContext context) { // Check before consuming — give feedback if the item is missing if (!context.inventory.ContainsItem(requiredItem)) { NotificationCenter.Notify(NotificationCenter.MessageType.Warning, "No item available"); yield break; } // Consume one unit; TryUseItem returns false if the item is not present if (context.inventory.TryUseItem(requiredItem)) { // Apply the item's effects, play animation, etc. context.player.UseItem(requiredItem); } yield return null; }
TryUseItem decrements the stack count and removes the slot only when it reaches zero. TryRemoveItem removes the entire slot regardless of stack size. For consumables, always use TryUseItem.
2 — Adding Items from an Interactable
When a player collects a pickup or opens a chest, call TryAddItem on the execution inventory inside the Interact() method. The context property is available on any class that extends ExecutionContextElement.
public class InteractableObject_Sign : ExecutionContextElement, IInteractable { [SerializeField] Item item; [SerializeField] int amount = 1; [field: SerializeField] public UnityEvent OnInteract { get; set; } public bool automatic => false; public bool Validate() => item != null; public void Interact() { if (context.inventory.TryAddItem(item, amount)) { OnInteract?.Invoke(); Destroy(gameObject); } else { NotificationCenter.Notify(NotificationCenter.MessageType.Warning, "Inventory full"); } } }
3 — Checking Carry State
The carryTarget and carryingObject members of ExecutionContext track what the player is currently holding. Check carryingObject before actions that require the player's hands to be free.
public override IEnumerator Tick(ExecutionContext context) { if (context.carryingObject) { NotificationCenter.Notify(NotificationCenter.MessageType.Warning, "Can't do this while carrying something"); yield break; } // ... rest of instruction logic yield return null; }
4 — Creating Item Assets
Items are ScriptableObject assets. Create them from the Unity menu and assign them to interactable prefabs or instructions.
- Right-click in the Project window → Create → Loop Adventure → Inventory → Item.
- Set Display Name and Description — these appear in the inventory UI.
- Assign a Sprite for the item icon.
- Enable Stackable if multiple copies should share one inventory slot.
- Add Effects if using the item should modify stats. Each effect targets a
Statasset with a numeric value and an optional duration in turns. - Save the asset under
Assets/Scriptable Objects/Items/.
5 — Creating Equipment Assets
Equipment extends Item with a slot type and stat bonuses. Equipped gear provides passive stat bonuses without being consumed.
- Right-click in the Project window → Create → Loop Adventure → Inventory → Equipment.
- Fill in all Item fields (Display Name, Sprite, etc.).
- Set Type — this determines which equipment slot it occupies (
Weapon,Shield,Helmet,Armor, orBoots). - Enable Two Handed if the weapon should also occupy the Shield slot.
- Add Stats entries — pair a
Statasset with a bonus value. Positive values increase the stat, negative values reduce it. - Save the asset under
Assets/Scriptable Objects/Equipment/.
PlayerInventory.current.GetStatValue(stat). The built-in player controller calls this for damage and defense automatically. Add your own Stat assets to extend the system.
6 — Creating Stat and Effect Assets
Stat
A Stat is a named data key — it does not store a value itself. Stats link equipment bonuses, item effects, and character receivers together.
- Right-click → Create → Loop Adventure → Inventory → Stat.
- Set Display Name and an Icon — shown in the UI when this stat is affected.
- Save under
Assets/Scriptable Objects/Stats/and reference it inEquipment.StatsorEffect.Target Stat.
Effect
Effects are embedded in Item assets (not separate assets). Add them in the Item inspector under the Effects list.
| Field | Description |
|---|---|
| Target Stat | The Stat asset this effect modifies. |
| Value | Amount added to the stat. Negative values reduce it. |
| Duration | Turns the effect lasts. 0 means instant and permanent (for this run). |
| Apply Per Turn | If enabled, applies the value once per turn instead of once upfront — use for regeneration or damage-over-time. Ignored when Duration is 0. |