After building inventory systems for dozens of prototypes and three shipped games, I’ve learned one thing: most tutorials overcomplicate this. The fundamentals are simpler than you think—and once you understand them, you can adapt any inventory type to your project.
This guide covers the three main inventory paradigms (slot-based, grid-based, and weight-based), when to use each, and how to implement them without getting lost in unnecessary complexity.
Table of Contents
- Quick Answer
- The Three Main Inventory Types
- Slot-Based Inventories
- Grid-Based Inventories
- Weight-Based Inventories
- Data Architecture Fundamentals
- UI Considerations
- Pro Tips
- FAQ
Quick Answer
Building an inventory system comes down to three decisions:
- Storage type: Slots (simplest), grid (visual), or weight (realistic)
- Data structure: Array of item IDs with quantity tracking
- UI binding: Separate your data from your display
Start with slot-based if you’re new. It’s the foundation everything else builds on.
The Three Main Inventory Types
Every inventory system you’ve seen in games falls into one of three categories—or a hybrid of them.
Slot-based: Each item occupies one slot regardless of size. Think Minecraft, World of Warcraft, or most mobile RPGs. Simple to implement, easy to understand.
Grid-based: Items occupy variable space based on their “size.” Diablo, Resident Evil 4, and Escape from Tarkov use this. Adds a spatial puzzle element but requires more complex UI logic.
Weight-based: Items have weight values; players have a carrying capacity. Skyrim, Baldur’s Gate 3, and most survival games use this. Feels realistic but requires careful balance.
Many games combine these. Elden Ring uses slots for equipment plus weight for encumbrance. Choose based on what serves your gameplay, not what seems most impressive.
Slot-Based Inventories
This is where you should start. Even if you want a grid system eventually, understanding slot-based logic first makes everything easier.
Core data structure:
class Inventory:
var slots: Array[ItemStack] = []
var max_slots: int = 20
class ItemStack:
var item_id: String
var quantity: int
var max_stack: int
Key operations you need:
- Add item: Find existing stack with space, or find empty slot
- Remove item: Decrease quantity, remove stack if zero
- Check if item exists: Search slots for matching item_id
- Get total count: Sum quantities across all matching stacks
The trick is handling stackable vs non-stackable items. Weapons typically don’t stack (max_stack = 1). Potions might stack to 99. Your add_item function needs to check this.
Implementation tip: Always validate before modifying. Check if there’s space before adding. Check if the item exists before removing. Return success/failure booleans so your game logic can respond appropriately.
Grid-Based Inventories
Grid systems add spatial complexity. Each item has a width and height, and you need to track which cells are occupied.
Additional data needed:
class GridInventory:
var grid: Array[Array[bool]] = [] # Occupied flags
var items: Array[PlacedItem] = []
var width: int = 10
var height: int = 6
class PlacedItem:
var item_id: String
var grid_x: int
var grid_y: int
var rotation: int # 0 or 90 degrees
The core challenge: Finding valid placement. You need to check if all required cells are empty before placing an item. This means iterating through the item’s footprint at the target position.
Rotation adds complexity. If you allow items to rotate 90 degrees, their width and height swap. Some games skip rotation entirely—Diablo doesn’t have it; Tarkov does. Decide early.
Auto-sort is expected. Players will want a “sort” button that reorganizes items efficiently. Implementing a bin-packing algorithm for this is a rabbit hole—consider using a simple “sort by size, place largest first” approach for your first pass.
Weight-Based Inventories
Weight systems track a single number rather than spatial positions. Simpler data structure, but balance is everything.
Core structure:
class WeightInventory:
var items: Array[ItemStack] = []
var current_weight: float = 0.0
var max_weight: float = 100.0
Adding items: Check if (current_weight + item_weight * quantity) <= max_weight before allowing the add.
Balance considerations:
- What’s the penalty for exceeding weight? Slower movement? Can’t move at all?
- How do players increase capacity? Stats? Equipment? Companions?
- What’s the weight distribution? If everything weighs 1-5 units and capacity is 100, players rarely think about it. If weight varies from 0.1 to 50, every pickup is a decision.
Weight systems work best in games where resource management is part of the core loop—survival games, tactical RPGs, immersive sims.
Data Architecture Fundamentals
Regardless of which system you choose, some principles apply universally.
Separate item definitions from item instances. Your “Iron Sword” definition (stats, description, icon) should exist in one place. Your inventory stores references to that definition plus instance-specific data (durability, enchantments).
Use a database or resource system. Most engines have built-in solutions—ScriptableObjects in Unity, Resources in Godot. Don’t hardcode item data.
Events over polling. When inventory changes, emit a signal/event. Your UI listens and updates. Don’t have your UI constantly checking the inventory state every frame.
Save-friendly structure. Design your inventory data so it can serialize to JSON or your save format cleanly. Test saving/loading early—retrofitting save compatibility is painful.
UI Considerations
The best inventory system fails if players can’t interact with it smoothly.
Drag and drop is expected but not trivial. You need to track: what’s being dragged, where it came from, where it can drop, and what happens on invalid drops.
Tooltips are mandatory. Show item stats on hover. Make them readable—don’t cram everything into tiny text.
Quick actions speed up play. Right-click to use/equip, shift-click to move between inventories, number keys for hotbar. Study how your favorite games handle this.
Mobile changes everything. Touch targets need to be larger. Drag and drop might need tap-to-select instead. Test on actual devices early.
Pro Tips
- Prototype in spreadsheets first. Mock up your items, their properties, and stack sizes in a spreadsheet before coding anything. You’ll catch balance issues early.
- Build the data layer before the UI. Get add/remove/query working with debug prints before you touch a single UI element.
- Test with 1000 items. Spawn a huge inventory and see if performance holds. Better to find issues now.
- Plan for special cases early. Quest items that can’t be dropped, unique items that can’t stack, equipped items that show in inventory—handle these in your architecture, not as hacks later.
- Copy what works. Play games with inventory systems you admire. Screenshot their UI, note their interactions, understand why they made their choices.
- Start simpler than you think you need. You can always add grid complexity or weight limits later. Shipping a working simple system beats an unfinished complex one.
FAQ
Should I use an asset/plugin or build my own?
For learning: build your own. For shipping quickly: use an asset if it fits your needs exactly. Most inventory assets require heavy customization anyway, so understand the fundamentals first.
How do I handle equipment slots vs inventory?
Equipment slots are just a separate, smaller inventory with constraints. Each slot only accepts certain item types (helmet slot only accepts helmets). Your equipped items and inventory items should share the same item data structure.
What about infinite inventories like Minecraft’s creative mode?
Use a dictionary/map instead of a fixed array. Key = item_id, value = quantity (or -1 for infinite). Skip the slot/grid concept entirely for infinite storage.
How do I sync inventory in multiplayer?
Server authoritative. The server tracks the “real” inventory. Clients send requests (“I want to pick up this item”). Server validates and updates. Server sends the new state to clients. Never trust client-reported inventory data.
How do I handle item persistence between scenes/levels?
Your inventory should be a singleton or autoload that persists across scene changes. Alternatively, save inventory state before scene transitions and restore it after. This ties into your broader save system architecture.
Summary
Building an inventory system starts with choosing your paradigm: slots for simplicity, grids for spatial puzzles, weight for realism. Regardless of type, keep your data layer separate from your UI, use events for updates, and plan for save compatibility from the start.
The best inventory is the one players forget exists—it just works, letting them focus on your actual game. Start simple, iterate based on playtesting, and don’t overcomplicate until complexity serves your design.































































































































































































































