【Godot】Inventory System Design Basics: Item Management with Resources and Signals

Created: 2025-12-08

Learn how to design a robust and scalable inventory system foundation in Godot Engine using Resources and signals.

Introduction: Why Inventory Design Is Important

In game development, inventory systems are essential elements for enriching the player experience. However, an inventory system is not just a box for storing items. It only functions when three different elements work closely together: item data structure, inventory logic, and UI that communicates information to players.

This article, aimed at beginners to intermediate users, explains the foundational design of a robust and scalable inventory system using Godot's powerful features: Resources and Signals.

Section 1: Defining Item Data (Using Resources)

When designing an inventory system, the first thing to do is define "what is an item?" Item data is best handled as Resources in Godot.

ItemResource.gd Code Example

# ItemResource.gd
class_name ItemResource
extends Resource

@export var item_id: String = ""
@export var item_name: String = "New Item"
@export_multiline var description: String = ""
@export var icon_path: String = ""
@export var stackable: bool = true
@export var max_stack_size: int = 99

By creating .tres files that inherit this Resource, you can manage specific item definitions as data.

Section 2: Implementing Item Management Logic

Next, implement logic to manage inventory "actions" like adding and removing items. Implement this logic as a singleton (autoload) to make it accessible from anywhere in the game.

Inventory.gd Code Example (Adding/Removing Items)

# Inventory.gd
extends Node

signal inventory_changed

var items: Dictionary = {}
const MAX_SLOTS: int = 20

func add_item(item_resource: ItemResource, count: int = 1) -> bool:
    if not item_resource:
        return false

    if item_resource.stackable and items.has(item_resource):
        items[item_resource] += count
        inventory_changed.emit()
        return true

    elif items.size() < MAX_SLOTS:
        items[item_resource] = count
        inventory_changed.emit()
        return true

    return false

func remove_item(item_resource: ItemResource, count: int = 1) -> bool:
    if not items.has(item_resource):
        return false

    items[item_resource] -= count

    if items[item_resource] <= 0:
        items.erase(item_resource)

    inventory_changed.emit()
    return true

func get_inventory_data() -> Dictionary:
    return items

Key Point: inventory_changed.emit() is called every time items are added or removed. This is the key to UI integration.

Section 3: UI Integration Basics

Even if inventory logic updates item data, the UI won't change if it doesn't know about it. This is where Godot's signals shine.

InventoryUI.gd Code Example (Inventory Display)

# InventoryUI.gd
extends Control

@export var inventory_logic: Inventory

const SLOT_SCENE = preload("res://scenes/inventory_slot.tscn")

func _ready():
    if inventory_logic:
        inventory_logic.inventory_changed.connect(_update_ui)
        _update_ui()

func _update_ui():
    for child in get_children():
        child.queue_free()

    var inventory_data = inventory_logic.get_inventory_data()

    for item_resource in inventory_data:
        var slot = SLOT_SCENE.instantiate()
        slot.set_item_data(item_resource, inventory_data[item_resource])
        add_child(slot)

    var empty_slots_count = inventory_logic.MAX_SLOTS - inventory_data.size()
    for i in range(empty_slots_count):
        var slot = SLOT_SCENE.instantiate()
        slot.set_empty()
        add_child(slot)

This implementation allows Inventory.gd to emit a signal whenever items are added or removed, and InventoryUI.gd receives it to automatically update the screen based on the latest data.

Practical Usage Example: Item Acquisition

# Example within Player.gd
func _on_item_collected(item_resource: ItemResource):
    if Inventory.add_item(item_resource, 1):
        item_node.queue_free()

This way, the player node doesn't need to know about the UI's existence, and the UI node doesn't need to know about the player node's existence. Everything is loosely coupled through signals via the inventory logic as a central hub.

Summary: Key Points of Robust Inventory Design

The foundational inventory system design in Godot Engine explained in this article is based on three pillars:

ElementGodot FeatureRole
Item DataResourceDefine and save static item information
Inventory LogicSingleton (Node)Manage actions like adding/removing items
UI IntegrationSignalNotify UI of logic changes

By adopting this design pattern, even as your game scales, item types increase, or UI design changes, you can stably maintain the system's core logic.