Use the retained-resource contract when a resource changes on an item that stays in the inventory. The item instance remains in custody and its stack quantity does not change.
Use ITEM_REMOVED for true stack consumption. Use
ITEM_RESOURCE_CHANGED for charges, fuel, water, energy, or durability. A
game owns the domain event that follows, such as spell_cast or
tile_watered.
Create a charged item
Attach a non-negative numeric resource during inventory setup. The
instance_id identifies the retained item that gameplay will mutate.
var lantern:= ItemStack.new(lantern_definition,1)
lantern.instance_id= &"lantern-42"
lantern.set_resource(&"fuel",100)
inventory.get_container(&"main").add(lantern)After setup, submit typed commands through the backend:
var command:= AdjustItemResourceInventoryCommand.new(
&"lantern-42",
&"fuel",
-5,
&"action-1842",
"lantern_burn",
)
var result:InventoryCommandResult = backend.apply_command(command)
if result.code== InventoryResultCode.Code.OK:
print("Fuel:%d ->%d" % [
result.resource_event.old_amount,
result.resource_event.new_amount,
])Positive deltas refill a resource. Negative deltas consume it. Missing instances, missing resources, zero deltas, and insufficient amounts are rejected atomically and produce no changed event.
Observe the typed event
Pass the same scoped bus to GdscriptInventoryBackend and subscribe to the
typed signal:
var bus:= ItemVaultBus.new()
var backend:= GdscriptInventoryBackend.new(inventory, database, bus)
bus.item_resource_changed.connect(func(event:ItemResourceChangedEvent)-> void:
print("%s:%d ->%d (%s)" % [
event.resource_id,
event.old_amount,
event.new_amount,
event.correlation_id,
])
)The event carries inventory_id, item_id, instance_id, stack_id,
resource_id, old_amount, new_amount, delta, correlation_id, and
reason. The command result carries the same typed event in
result.resource_event.
Reusing the same correlation id for the same command returns DUPLICATE,
does not apply a second delta, and does not emit another change event. Use a
new correlation id for a new adjustment.
Save and restore
ItemStack.to_dict() persists resources and both retained identities. The
backend save also persists successful resource correlations, so a retry after
restore remains idempotent:
var saved:Dictionary = backend.to_dict()
var restored:= GdscriptInventoryBackend.new()
assert(restored.from_dict(saved, database))The Rust backend uses the same command, event, and save shape, so consumers can keep charges, durability, fuel, water, and energy backend-neutral.