ItemVault supports both resource-authored item definitions and JSON-authored
catalogs. Both paths produce the same runtime ItemDefinition objects and the
same ItemStack save dictionaries.
Use JSON catalogs when your pipeline is data-heavy, spreadsheet-driven, or shared with downstream game systems.
Load a JSON Catalog
Configure ItemDatabase.definition_json_files and call reload():
var database := ItemDatabase.new()
database.definition_json_files = ["res://items/catalog.json"]
database.reload()
You can also load one file directly:
var loaded_count := database.load_json_file("res://items/catalog.json")
print("Loaded %d item definitions" % loaded_count)
Catalog Shape
JSON catalog files use this shape:
{
"version": 1,
"items": [
{
"id": "iron_ore",
"display_name": "Iron Ore",
"category": "material",
"tags": ["ore", "smithing"],
"max_stack": 99,
"weight": 0.25,
"world_scene": "res://pickups/ore_pickup.tscn"
}
]
}
Supported item fields:
id: stable save/load id.display_name: player-facing name.category: inventory category, for examplematerialorcurrency.tags: array of query tags.max_stack: default stack limit.weight: default weight per unit.icon: optionalTexture2Dresource path.world_scene: optionalPackedSceneresource path for world drops.
Resource and JSON Catalogs Can Mix
ItemDatabase.reload() scans definition_dirs and then loads
definition_json_files:
var database := ItemDatabase.new()
database.definition_dirs = ["res://items/resources"]
database.definition_json_files = ["res://items/catalog.json"]
database.reload()
If the same id appears twice, the later registration replaces the earlier one and ItemVault warns about the duplicate. Keep ids stable and unique for release builds.
Stack Save Dictionaries
ItemStack.to_dict() produces the compact stack shape used by ItemVault saves:
var stack := ItemStack.new(database.get_def(&"iron_ore"), 12)
stack.instance_id = &"mine_drop_042"
var data := stack.to_dict()
Result:
{
"id": "iron_ore",
"qty": 12,
"iid": "mine_drop_042"
}
ItemStack.from_dict(data, database) restores a stack when the item id resolves
through the database.
GECS or Custom World Handoff
If your downstream world uses ECS-compatible entities, pass the stack dictionary at the game boundary:
var stack := WorldItemStackMeta.read(spawned_pickup)
if stack != null:
gecs_world.spawn_item_entity(stack.to_dict())
ItemVault remains the item/drop/pickup source. Your game owns the ECS entity and any extra components.
Persistent World Drops
Pickup stack metadata lives on the pickup node. If the node is freed or the world unloads, the metadata disappears with that node. To persist dropped-world-items, save the stack dictionary before removing the pickup:
var stack := WorldItemStackMeta.read(pickup)
if stack != null:
save_world_drop({
"position": pickup.global_position,
"stack": stack.to_dict(),
})
On load, resolve the stack through ItemStack.from_dict(data, database), spawn a
pickup scene, and write the stack back with WorldItemStackMeta.write(pickup, stack).
Related References
item-data-and-stack-metadata.mdexplains where item ids and per-stack data belong.../save-schema.mddefines the full inventory save envelope.
Source
addons/item_vault/guides/json-catalogs-and-saves.md
Plugin docs root:gdscript/plugins/item_vault_dev/addons/item_vault/guides