Concepts
Inventory
The core inventory building blocks.
Inventories are about item management, which is required when your game has items that your player can use. Using items is specific to your game, so the inventory provides signals for your game to handle when item use is requested.
The core inventory addon provides three aspects:
- A data model to represent items.
- An inventory component to manage items.
- A user interface to allow players to interact with the inventory.
Let's first take a closer look at items.
Inventory Items
Items can represent just about anything: Consumables, equipment, clothes, quests.
Items are modeled using Godot's Resource class.
Data Structure and Storage
Items and item types are defined via separate data structures using Godot Resource classes:
The GGItemType class describes all items of a particular type, while the GGItemData class describes an instance of that type.
Collections of items can be saved as a GGItemCollection Resource.
Items can be serialized and deserialized for efficient network transmission.
Inventories and items are serialized to Dictionaries to integrate with your Godot project's persistence logic.
Item Stacking and Splitting
Items can be stacked, so that items of the same type occupy a single slot.
The item types defines the maximum stack size.
The GGInventoryStackingStrategy determines how items are stacked.
Players can easily manipulate item stacks by splitting and merging them through the user interface.
Item Expiration
Items support expiration over time. This can be used to implement mechanisms such as food spoilage.
For example, an avocado item expires in 6 minutes (which is generous, given real avocados are only ripe for 17 seconds). If you have a stack of 10 avocados, the quantity will be reduced every 6 minutes. After an hour, no avocados are left.
Extending Items
To add additional attributes for your items, extend the GGItemData class:
class_name MyItemData extends GGItemData
## The condition of items deteriorates with use.
## Once the value reaches 0, the item has to be repaired
## before it can be used again.
@export_range(0.0, 1.0, 0.01) var condition: float = 1.0
Two common strategies for extending the item class is to either create a single item class (e.g. MyItemData)
and add all needed properties to it, or to create separate classes
(e.g. MyConsumableItem, MyEquipableItem, MyQuestItem).
Both approaches are viable.
Inventory Component
The core GGInventory class is added to characters or objects
and allows them to manage collections of items.
The inventory component's API provides functionality to add and remove items, and emits signals to notify game logic and UI components of any changes.
Much of the inventory component's behavior is configured using strategy resource classes, an implementation of the strategy pattern. Strategies enable you to change the inventory behavior without having to change its code directly, following the Open/Closed principle -- the O in SOLID. Most settings can be configured directly from the Inspector. For more advanced scenarios, you can extend the strategy class with your custom logic.
Inventory Size and Capacity
The inventory has configurable limits, which includes the number of item slots and combined item weight.
The configuration can be modified at runtime to allow for inventory upgrades and expansions (for example, through in-game progression).
Inventory Item Management
The GGInventoryItemFilterStrategy determines which items can be added.
This can be used to restrict an entity to only hold specific items.
For example, a book shelf's inventory may only hold book items, or a smelter may only receive coal and ores.
The GGInventoryItemFilterStrategyWeight is used to enforce an inventory's weight limit.
Using Inventory Items
The GGInventory.use_item() method is used to use an item.
By default, the inventory component simply emits an item_use_requested signal, which can be handled by a separate node.
The GGInventoryUseStrategy determines how items are used for advanced use-cases.
Inventory Serialization
Inventories can be serialized.
The GGInventorySerializationStrategy determines how items are serialized to be
stored as part of a save game or transmitted over the network for multiplayer.
Item Sorting
Players can organize inventories by sorting items.
The GGInventorySortingStrategy class determines how items are sorted.
Multiple resources can be specified to offer complex sorting options (e.g. by weight, by type, rarity, etc.).
Inventory Item Transfer
Items can be transferred between inventories.
The GGInventoryTransferStrategy determines how items are transferred.
This is used by the drag-and-drop feature.
Inventory UI Component
An inventory's user interface is its identity. It most heavily contributes to the look and feel, and how players perceive your game.
The GGInventoryUI component offers flexible user interface capabilities
and can present items using multiple views:
- Grid View: Displays slots with a fixed number of columns via the
GridContainer. - Flow View: Displays slots with a responsive design via the
FlowContainer. - List View: Display items as line items via the
HBoxContainer.
This UI component offers customizable actions, supports drag-and-drop, and is themeable.
The Inventory Controller
The Inventory UI is powered by the GGInventoryController component, which uses a
Model-View-Controller-style approach to coordinate user input, updating the inventory, and visually displaying the inventory and items.
Input Handling
The controller separates the InputEvent handling from the presentation of each item slot.
Player actions are handled by the GGInventoryActionStrategy.
A default action strategy is provided by the GGInventoryActionStrategyDefault class.
It lets you customize what left-click, double-click, right-click, and middle-click do.
In addition, you can define input actions for keyboard and/or controller support.
Drag-and-drop
Most players expect inventories to have drag-and-drop functionality. The inventory system includes a highly customizable drag-and-drop implementation.
The inventory UI component leverages the GGDragonDrop component for drag-and-drop abstraction.
The GGInventoryDndStrategy class provides the inventory integration.
It extends the GGDragonDropStrategy which offers two methods for drag-and-drop:
- Click-and-drag: Requires players to hold down the mouse button while dragging, and drops the item upon release.
- Click-and-release: Click on items and release the mouse button to pick them up. A second click drops the item.
Which approach you use depends on the game, your preference, and how advanced you want the drag-and-drop functionality to be.
The "click-and-release" approach, for example, lends itself better to using modifiers keys.
By default, clicking an item will pick up the entire stack.
In a game where players have to manage more arbitrary quantities, you can use the modifier keys CTRL and SHIFT to add and remove quantities, respectively.
Repeatedly clicking on an item stack while holding down a modifier key will add/remove items as desired.
The Drag-and-drop functionality relies on the inventory component's GGInventoryTransferStrategy to
actually move items.
Item Searching
Players can search for items.
The search behavior is provided by the GGInventorySearchStrategy class.
Theming
The Inventory and Slot UI components use theme type variations, so you can easily adjust the design to fit your particular project.