Player holds a collection of discrete named items with defined slot limits; deciding what to carry is a meaningful choice.
A fixed set of slots; once full, a new item can't be taken until you drop one — limited space turns what you carry into a deliberate choice.
An inventory is data, not nodes: a bounded list of item records living in a singleton, with UI as a pure reflection of it.
Each item is an ItemData resource — name, icon, stack rules. Items as data means new ones need no new code.
class_name ItemData extends Resource
@export var id: String
@export var icon: Texture2D
@export var max_stack := 1The slot list with a hard cap. Enforcing max_slots on add is what turns hauling into a real choice.
var items: Array[ItemData] = []
func add(i) -> bool:
if items.size() >= MAX_SLOTS: return false
items.append(i); changed.emit(); return trueHold the inventory in a GameState singleton so it persists across rooms and the UI can rebuild from it anywhere.
# GameState.gd (autoload)
signal changed
var items: Array[ItemData] = []In short: Array of ItemData Resources in GameState autoload; max_slots enforced on add; UI reflects current contents
72 catalogued game(s) use this mechanic, spanning 1980–2000.
▶ Explore Inventory Management interactively — see every game + the Godot system