Chris' Tutorials
Docs/Item Vault

Item Vault v1.0

Item Data and Stack Metadata

Place item ids, tags, stack overrides, and world pickup metadata in the right layer.

StatusDraft
Versionv1.0
UpdatedDevelopment docs generated from GDScript source

This is unreleased documentation in active development. APIs, class names, and behavior may change before the final release.

Draft — Unreleased:This page is in active development. APIs, class names, and behavior may change before the release is finalized. Use it as a preview of what's coming — not as a stable integration target.

ItemVault uses one shared item model across inventory, drops, pickups, and saves:

  • ItemDefinition: item-type data.
  • ItemStack: one stack instance.
  • WorldItemStackMeta: the implementation helper ItemVault uses to attach a stack to a spawned pickup/world node until pickup/drop events consume it.

Three Layers

Layer Use it for Example
ItemDefinition Data shared by every copy of an item type iron_ore, display name, icon, category, tags
ItemStack One stack instance quantity 12 iron ore, one sword instance id
WorldItemStackMeta Temporary ItemVault stack handoff on a spawned world node Attach a stack to a pickup scene node

WorldItemStackMeta stores one resolved ItemStack under ItemVault's shared item_stack node metadata key on the spawned world node. ItemVault spawners, pickups, and adapter code can then recover the same stack without duplicating metadata parsing.

Put Game Terms on ItemDefinition

Use ItemDefinition for stable facts about an item type.

var ore := ItemDefinition.new()
ore.id = &"iron_ore"
ore.display_name = "Iron Ore"
ore.category = &"material"
ore.tags = [&"ore", &"smithing"]
ore.max_stack = 99
ore.weight = 0.25

Good ItemDefinition fields:

  • Stable ids: iron_ore, health_potion, moonleaf
  • UI labels and icons
  • Inventory categories: material, consumable, quest, currency
  • Tags for game queries: ore, smithing, healing, rare
  • Default max stack and weight
  • World scene used when the item is dropped

Use ids, categories, and tags for game-specific vocabulary. A farming game can use category = &"crop" with tags like &"spring" or &"seed". A dungeon game can use category = &"relic" with tags like &"cursed" or &"fire".

Put Per-Stack Data on ItemStack

Use ItemStack for a specific stack in inventory or in the world.

var stack := ItemStack.new(ore, 12)
stack.instance_id = &"mine_drop_042"
stack.max_override = 20
stack.weight_override = 0.3

Good ItemStack fields:

  • quantity: units in the stack
  • instance_id: optional identity for one specific stack
  • max_override: optional max-stack override
  • weight_override: optional weight override

Use instance_id when the game needs to associate external state with one specific stack: durability, rolled affixes, quest ownership, crafted-by value, or GECS component state. Keep larger game-specific state in game data, keyed by instance_id.

Use WorldItemStackMeta for Spawned World Nodes

When a drop spawns a pickup scene, ItemVault needs the world node to carry the resolved stack until pickup events or adapter code read it back.

var pickup: Node = pickup_scene.instantiate()
var stack := ItemStack.new(ore, 12)
WorldItemStackMeta.write(pickup, stack)

Later, ItemVault can read the same stack:

var stack: ItemStack = WorldItemStackMeta.read(pickup)
if stack != null:
	print("Picked up %s x%s" % [stack.item.id, stack.quantity])

Use WorldItemStackMeta only for the ItemVault world-node stack handoff. Put durability, biome source, quest flags, flavor text, or other game state on ItemDefinition, ItemStack, or a game-owned system.

Pickup Node Lifetime

WorldItemStackMeta does not use a global registry. The ItemStack is stored on the pickup node's Godot metadata. ItemVault pickups clear that metadata after emitting PickupEvent, so listeners receive the stack but a consumed pickup does not keep a stale handoff.

That means:

  • If the pickup node is freed, the node metadata is freed with it.
  • If the world unloads, unsaved pickup-node metadata is gone.
  • No global registry cleanup is required.
  • Adapter code can call WorldItemStackMeta.clear(node) after consuming a stack into another world/entity system.
  • Persistent dropped-world-items are a game save concern.

If a game needs dropped pickups to survive world unload, read the stack before freeing or unloading the node and save the stack dictionary:

var stack := WorldItemStackMeta.read(pickup)
if stack != null:
	save_world_drop(pickup.global_position, stack.to_dict())

When the world loads again, recreate the pickup node and write the restored ItemStack back with WorldItemStackMeta.write(pickup, stack).

Example: ItemVault Pickup Route

The default flow is ItemVault-owned and inventory-oriented:

ItemVault drop -> spawned pickup node -> PickupEvent -> Inventory or Wallet

If the pickup is handled by ItemVault's spawner pickup route, SpawnEvent.stack and PickupEvent.stack contain the same ItemStack.

Example: GECS or Custom World Adapter

If your game consumes ECS-compatible world entities downstream, keep ItemVault as the item/drop/pickup source and adapt at the stack boundary.

var stack := WorldItemStackMeta.read(spawned_node)
if stack != null:
	gecs_world.spawn_item_entity(stack.to_dict())
	WorldItemStackMeta.clear(spawned_node)

ItemVault does not need to own your ECS entity. It provides the resolved ItemVault stack payload cleanly.

Example: Keep Rare Roll Data in Your Game

For rare, rolled, or crafted items, keep heavy game data outside WorldItemStackMeta and link it with instance_id.

var sword_stack := ItemStack.new(sword_definition, 1)
sword_stack.instance_id = &"sword_roll_1007"
rare_item_rolls[sword_stack.instance_id] = {
	"rarity": &"legendary",
	"damage_bonus": 7,
	"crafted_by": "Ari",
}

The stack remains small and save-friendly. The game owns detailed rolled data and can save it in its own system.

What's Next

Source

addons/item_vault/guides/item-data-and-stack-metadata.md

Plugin docs root:gdscript/plugins/item_vault_dev/addons/item_vault/guides