Working on an RPG-adjacent thing in Godot 4 and I keep second-guessing my item system architecture. The basic split makes sense conceptually: ItemDefinition is a Resource with static data (name, icon, base damage, description, max stack size), and ItemInstance is what lives in inventory slots and carries mutable stuff (current durability, quantity, randomly rolled modifiers).
Where it gets messy is deciding what actually belongs where. Base durability: definition or instance? I put it in definition as a reference value and store current durability on the instance. Fine. But then I added quality tiers, and suddenly an Iron Sword can be Common, Rare, or Epic with different base stats. Do I make three separate definition resources? Add a quality field to the instance? A lookup table on the definition?
class_name ItemInstance
extends Resource
@export var definition: ItemDefinition
@export var quantity: int = 1
@export var durability: float = -1.0 # -1 = use definition max
@export var quality: ItemDefinition.Quality = ItemDefinition.Quality.COMMON
@export var modifiers: Array[StatModifier] = []
func get_effective_stat(stat: StringName) -> float:
var base := definition.get_base_stat(stat, quality)
for mod in modifiers:
if mod.stat == stat:
base = mod.apply(base)
return base
It works but it feels like papering over a design problem. The quality field on the instance means I need both objects together to reconstruct what an item actually is, and they're coupled in a way that's starting to feel fragile. And modifiers as an array of Resources serializes fine but debugging an item with 4 stacked modifiers in the editor is already not fun, and I haven't added crafting yet.
Curious how others handle this split. Fully data-driven with JSON or a proper database? Sticking with Resources? Something else entirely? And does the definition/instance model even hold up once you layer in crafting or item evolution mechanics where the definition itself kind of mutates?