expert
55 min

Custom Inventory System

Create a sophisticated inventory system with database integration.

Item ManagementUI IntegrationDatabaseTrading

1
Inventory Class Structure

Build a robust inventory system using OOP.

Inventory Class

local Inventory = {}
Inventory.__index = Inventory

function Inventory.new(maxSlots)
  local self = setmetatable({}, Inventory)
  self.maxSlots = maxSlots or 20
  self.items = {}
  return self
end

function Inventory:addItem(itemId, amount)
  amount = amount or 1
  
  -- Check if item already exists
  for _, item in ipairs(self.items) do
    if item.id == itemId then
      item.amount = item.amount + amount
      return true
    end
  end
  
  -- Check if inventory is full
  if #self.items >= self.maxSlots then
    return false, "Inventory full"
  end
  
  -- Add new item
  table.insert(self.items, {
    id = itemId,
    amount = amount
  })
  
  return true
end

function Inventory:removeItem(itemId, amount)
  amount = amount or 1
  
  for i, item in ipairs(self.items) do
    if item.id == itemId then
      item.amount = item.amount - amount
      
      -- Remove if amount reaches 0
      if item.amount <= 0 then
        table.remove(self.items, i)
      end
      
      return true
    end
  end
  
  return false, "Item not found"
end

function Inventory:hasItem(itemId, amount)
  amount = amount or 1
  
  for _, item in ipairs(self.items) do
    if item.id == itemId and item.amount >= amount then
      return true
    end
  end
  
  return false
end

Core inventory system with add, remove, and check functions.

2
Item Database

Create a centralized item database.

Item Registry

local ItemDatabase = {
  ["sword_iron"] = {
    name = "Iron Sword",
    description = "A basic iron sword",
    rarity = "Common",
    stackable = false,
    maxStack = 1,
    type = "Weapon",
    stats = {
      damage = 15,
      durability = 100
    }
  },
  ["potion_health"] = {
    name = "Health Potion",
    description = "Restores 50 HP",
    rarity = "Common",
    stackable = true,
    maxStack = 10,
    type = "Consumable",
    effects = {
      healAmount = 50
    }
  },
  ["gem_ruby"] = {
    name = "Ruby Gem",
    description = "A precious ruby",
    rarity = "Rare",
    stackable = true,
    maxStack = 99,
    type = "Resource",
    value = 100
  }
}

function ItemDatabase:getItem(itemId)
  return self[itemId]
end

function ItemDatabase:isStackable(itemId)
  local item = self:getItem(itemId)
  return item and item.stackable
end

Store all item definitions in a centralized database.

3
Inventory Persistence

Save and load inventory data.

Save/Load System

local DataStoreService = game:GetService("DataStoreService")
local inventoryStore = DataStoreService:GetDataStore("PlayerInventories")

local function saveInventory(player, inventory)
  local success, err = pcall(function()
    local data = {
      items = inventory.items,
      maxSlots = inventory.maxSlots
    }
    inventoryStore:SetAsync(player.UserId, data)
  end)
  
  if not success then
    warn("Failed to save inventory: " .. err)
  end
end

local function loadInventory(player)
  local inventory = Inventory.new(20)
  
  local success, data = pcall(function()
    return inventoryStore:GetAsync(player.UserId)
  end)
  
  if success and data then
    inventory.items = data.items or {}
    inventory.maxSlots = data.maxSlots or 20
  end
  
  return inventory
end

Persist inventory data using DataStore.

💡 Tips:

  • • Save inventory when players leave
  • • Implement auto-save every few minutes
  • • Validate items when loading (check if they still exist)
  • • Use UpdateAsync for concurrent modifications

Practice Exercises

Exercise 1: Item Stacking

Improve the addItem function to handle stacking with max stack size.

Starter Code:

function Inventory:addItem(itemId, amount)
  -- Add stacking logic here
  
end
Show Solution
function Inventory:addItem(itemId, amount)
  amount = amount or 1
  local itemData = ItemDatabase:getItem(itemId)
  
  if not itemData then return false, "Invalid item" end
  
  if itemData.stackable then
    for _, item in ipairs(self.items) do
      if item.id == itemId and item.amount < itemData.maxStack then
        local spaceLeft = itemData.maxStack - item.amount
        local toAdd = math.min(amount, spaceLeft)
        item.amount = item.amount + toAdd
        amount = amount - toAdd
        
        if amount == 0 then return true end
      end
    end
  end
  
  while amount > 0 do
    if #self.items >= self.maxSlots then
      return false, "Inventory full"
    end
    
    local stackAmount = math.min(amount, itemData.maxStack or 1)
    table.insert(self.items, {id = itemId, amount = stackAmount})
    amount = amount - stackAmount
  end
  
  return true
end

Ready for more?

Continue your learning journey

Executors.Online - Your Roblox Developer Hub