Skip to content
Development
Skill

/inventory-system

Use when building inventory systems — Resource-based items, slot management, stacking, and UI binding

From plugin
godot-prompter
90361 skills9 agents1 hook

Claude Code

$ npx -y skills add jame581/GodotPrompter --skill inventory-system --agent claude-code

SKILL.md

inventory-system.SKILL.md
name: inventory-system
description: Use when building inventory systems — Resource-based items, slot management, stacking, and UI binding

Inventory Systems in Godot 4.3+

All examples target Godot 4.3+ with no deprecated APIs. This skill carries the decisions; the implementations live in `references/` (GDScript first, then C#) — load the one you need.

> **Related skills:** **resource-pattern** for custom Resource data containers, **save-load** for inventory serialization, **event-bus** for inventory change notifications, **hud-system** for inventory UI display, **popochiu** for adventure-game inventory.

---

1. Architecture Overview

┌─────────────────────────────────────────────────────────┐
│                        UI Layer                         │
│   InventoryUI (Control)                                 │
│     └─ GridContainer                                    │
│           └─ SlotUI × N (Button)                        │
│                 └─ TextureRect (icon) + Label (qty)     │
│                                                         │
│   Connects to: inventory_changed signal                 │
│   Drag-and-drop via _get_drag_data / _drop_data         │
└───────────────────────┬─────────────────────────────────┘
                        │ reads / mutates
┌───────────────────────▼─────────────────────────────────┐
│                    Inventory (Node)                      │
│   slots: Array[InventorySlot]                           │
│   add_item(item, qty) → leftover: int                   │
│   remove_item(item, qty)                                │
│   has_item(item, qty) → bool                            │
│   get_item_count(item) → int                            │
│                                                         │
│   signals: inventory_changed                            │
│             item_added(item, quantity)                  │
│             item_removed(item, quantity)                │
└───────────────────────┬─────────────────────────────────┘
                        │ references
┌───────────────────────▼─────────────────────────────────┐
│                   Data Layer (Resources)                 │
│   ItemData (Resource)                                   │
│     id, name, description, icon, max_stack_size,        │
│     item_type enum                                      │
│                                                         │
│   InventorySlot (inner class / Resource)                │
│     item: ItemData, quantity: int                       │
└─────────────────────────────────────────────────────────┘

---

2. The Decisions That Matter

Three choices shape every inventory. Make them explicitly and state which you picked — the rest is mechanical.

| Decision | Take | Why | |---|---|---| | Item identity: `Resource` vs. Dictionary / JSON | **`Resource` in `.tres`** | `@export` slots accept typed items, the Inspector edits them, and shared instances compare by reference | | Slot container: `Resource` vs. `RefCounted` | **`RefCounted`** | Slots are runtime state, not authored assets. A `Resource` invites saving slots to disk and reloading stale item copies | | `add_item` return: `bool` vs. leftover count | **leftover `int`** | Partial adds are the common case (stack caps, full bag). A `bool` forces the caller to re-query what actually fit |

If your game needs something else — a weight-based bag with no slots, a grid inventory with shaped items, an infinite stack list — say so before building. The fixed slot array this skill describes is the wrong skeleton for all three.

Non-obvious specifics

  • **Fill existing stacks before empty slots** — two passes, in that order. A single naive pass scatters one item type across several slots and reports the bag full while space remains.
  • **Emit `inventory_changed` once per operation**, after both passes complete — not once per slot touched. Per-slot emission re-renders the whole UI N times for one `add_item`.
  • **Items compare by reference.** Godot caches loaded resources, so `load()` on the same `.tres` returns the same instance and `slot.item == item` is correct and cheap. If you `duplicate()` items at runtime, that breaks — key off `ItemData.id` instead.
  • **Clear `item` to `null` when quantity reaches 0**, or `is_empty()` lies and the slot is never reusable.
  • **Prevent stacking with data, not branches** — set `max_stack_size = 1` on `EQUIPMENT` and `KEY_ITEM` items rather than special-casing them in `add_item`.
  • **C#: mark `ItemData` `[GlobalClass]`** or the Inspector will not offer it as a type when creating `.tres` files.

Inventory API contract

| Member | Returns | Contract | |---|---|---| | `add_item(item, quantity)` | `int` | Leftover that did not fit; `0` means everything was added | | `remove_item(item, quantity)` | — | Removes up to `quantity`; silent when fewer are held | | `has_item(item, quantity)` | `bool` | Convenience over `get_item_count` | | `get_item_count(item)` | `int` | Summed across every slot | | `inventory_changed` | signal | Fired once per mutating operation — drives all UI | | `item_added(item, quantity)` | signal | Carries the amount actually added | | `item_removed(item, quantity)` | signal | Carries the amount actually removed |

> Full `ItemData`, `Inventory`, and `InventorySlot` implementations in GDScript and C#: [references/core-classes.md](references/core-classes.md)

---

3. Equipment Extension

Add equipment slots (`HEAD`, `CHEST`, `WEAPON`, etc.) with an `Equipment` node beside the `Inventory`, holding a slot map keyed by a `SlotType` enum. Stat aggregation sums a `stats` Dictionary (a property you add to `ItemData`) across equipped items; signal `equipment_changed` when slots change.

> See [references/equipment.md](references/equipment.md) for the full GDScript and C# `Equipment` class with `SlotType` enum, equip / unequip API, and stat aggregation.

---

4. UI Binding

Slot-grid UI: a `GridContainer` of `Button` slot widgets, each

Read more
@jame581
Ships withgodot-prompter

Agentic skills framework for Godot 4.x game development. Gives AI coding agents domain-specific expertise for GDScript and C# projects.

90361 skills9 agents
Get the whole plugin

Stars on GitHub

Momentum

stars in total
903
Star history of jame581/GodotPrompter on GitHub, a chart by star-history.com

Other skills on godot-prompter.

2d-essentials

2d-essentials

Use when working with 2D-specific systems — TileMaps, parallax scrolling, 2D lights and shadows, canvas layers, particles 2D,…

3d-essentials

3d-essentials

Use when working with 3D-specific systems — materials, lighting, shadows, environment, global illumination, fog, LOD, occlusion…

ability-system

ability-system

Use when building character abilities — Resource-based abilities with cost/cooldown/cast, buffs/debuffs, stat modifiers, gameplay…

More skills from other plugins.

brainstorming
Auto-invoked

brainstorming

You MUST use this before any creative work - creating features, building components, adding functionality, modifying behavior, or…

@obra@obraInstall Skill
ask-matt

ask-matt

Ask which skill or flow fits your situation. A router over the skills in this repo.

skills10d309k
@mattpocock@mattpocockInstall Skill
accessibility
Auto-invoked

accessibility

Design, implement, and audit accessible UI to WCAG 2.2 Level AA across Web, iOS, and Android — semantic ARIA roles and labels,…

ecc11d293k
@affaan-m@affaan-mInstall Skill
compiler-commit

compiler-commit

Use when you want to verify compiler changes and commit with the correct convention. Runs tests, lint, and format, then commits…

react1d252k
@facebook@facebookInstall Skill

Questions about inventory-system.

Which coding agents can use inventory-system?
inventory-system installs in Claude Code, Codex, Cursor, Gemini CLI, GitHub Copilot, OpenCode and Windsurf with the skills CLI, using each agent's flag shown on this page. Flowy's auto-invocation, which fires a skill when your prompt matches, runs in Claude Code only.