Skip to content

Articles

Godot inventory system tutorial

Build a complete Item Vault inventory: pickups, stacking, crafting, equipment, and save and load sharing one item model.

This tutorial builds one inventory pipeline end to end: world pickups land in a player inventory, stacks merge by item id, recipes consume ingredients through an atomic craft, an equipment set reads from the same items, and the whole thing saves and loads. Every stage shares one item model, so nothing is defined twice.

It assumes the minimal setup from Getting Started: item definitions in an ItemDatabase, an inventory target, and pickup routing through ItemVaultRuntime.

1. Pickups route into inventory

Item Vault uses scene-owned runtime services. Add ItemVaultRuntime to scenes that need item database and pickup-to-inventory behavior, and let InventoryPickupBridge carry pickup events into an InventoryTarget. Your game never hand-moves items from the world into a bag: the pickup event fires, the bridge routes it, the target receives it.

Keep pickup scenes as the only world-facing item code. Everything downstream works with inventory containers, never with the pickup node.

2. Stacks merge by item id

Define one ItemDefinition per item type. The id is the stable save and load key, so use short string names like &"iron_ore", never file paths. max_stack caps how many units one stack holds:

var ore := ItemDefinition.new()
ore.id = &"iron_ore"
ore.display_name = "Iron Ore"
ore.max_stack = 32
ore.category = &"ore"
_db.register(ore)

Hold stacks in an ItemContainer built from a ContainerType:

var ct := ContainerType.new()
ct.id = &"player"
ct.max_stacks = 12
ct.slot_based = false
var backpack := ItemContainer.new(ct)

Adding a stack returns the overflow, so the caller always knows what did not fit. Removing by id and quantity keeps counts exact:

var overflow: ItemStack = backpack.add(ItemStack.new(def, qty))
var missing: int = 0 if overflow == null else overflow.quantity
backpack.remove(&"iron_ore", spent)

Put stack metadata (tags, stack overrides, world pickup data) in the layer Item Data and Stack Metadata describes. Item ids stay stable; presentation details live beside them, not inside them.

3. Craft through one atomic transaction

Crafting is an optional Item Vault module under addons/item_vault/crafting/. It is built on the same item and inventory types, so recipes reference real definition ids and the craft mutates real containers. Author a recipe from CraftingIngredient lines, register it in a CraftingRecipeRegistry, and run it through CraftingService, which validates, preflights, and commits through one atomic CraftingTransaction. The typed CraftingResult tells you exactly what was consumed and produced, with stable failure reasons when the craft cannot run.

Because the transaction is atomic, a failed craft changes nothing: no half-eaten ingredients, no duplicated outputs. Read results, never intermediate container states. The full authoring reference is Crafting Integration.

4. Equipment stays game-owned

Item Vault ships no equipment classes, and that is deliberate. Equipment rules (which slots exist, what each accepts, what stats change) belong to your game. The inventory side of the pattern is simple: hold the equipped set in its own ItemContainer and move stacks between it and the backpack with the same add and remove calls as any other transfer. The container enforces counts and capacities; your game enforces fit.

Connect stat and gameplay effects only after the inventory change succeeds, never before. The pattern for reacting to committed changes (healing, equipment bonuses, quest hooks) is documented in Game-Owned Gameplay Integration.

5. Save the envelope, not the nodes

Inventory state saves as JSON through the schema in Save Schema: schema version, inventory shape, containers, stacks, and typed instance resources. Item ids are the stable keys, so a save written today still resolves after you rearrange scenes, as long as definition ids do not change.

Crafting-domain state persists separately through CraftingSave, next to the inventory envelope rather than inside it. Keep the two envelopes in one game save file with independent version handling, so a crafting change never forces an inventory migration.

Common mistakes

  • Using file paths as item ids. Rename one file and every save breaks.
  • Moving items into equipment before the transfer succeeds. Commit first, react second.
  • Reading a container mid-craft. Wait for the typed result.
  • Saving node paths or scene state as inventory data. Save the JSON envelope; rebuild nodes from it on load.
  • Duplicating item facts (names, stack sizes) in UI scripts. The ItemDatabase is the single source; UI reads from it.

Try the demo

The Item Vault demo plays this whole pipeline: pickups, grid transfers, crafting bench, shop, and save and load. Try it in your browser on the Item Vault itch.io page before building your own.