> For the complete documentation index, see [llms.txt](https://oph3zdev.gitbook.io/docs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://oph3zdev.gitbook.io/docs/paid-scripts/inventory/installation.md).

# Installation

Installation of this resource

### Step 1 - Download And Drag <a href="#step-1-download-and-drag" id="step-1-download-and-drag"></a>

Download the file from keymaster and drag the file into your **resources** folder.

### Step 2 - Start The Script <a href="#step-1-download-and-drag" id="step-1-download-and-drag"></a>

Add the resource **after your database and your framework**, and before the resources that depend on items:

```cfg
ensure oxmysql
ensure qb-core          # or any other...
ensure oph3z-inventory
ensure [qb]             # the rest of your resources
```

> ⚠️ Keep the folder named exactly `oph3z-inventory`. Renaming the folder breaks every export other resources call.

### Step 3 - Set your framework and language <a href="#step-1-download-and-drag" id="step-1-download-and-drag"></a>

Open `config/config.lua` and set the two core options:

```lua
Config.Framework = "qb" -- esx, qb, qbox
Config.SQL = "oxmysql" -- oxmysql, ghmattimysql, mysql-async
Config.Language = "en" -- en, tr, de, sv
```

### Step 4 - Database <a href="#step-1-download-and-drag" id="step-1-download-and-drag"></a>

There is nothing to import. The tables are created automatically on first start — and only the ones your config actually uses:

| Table                      | Created when                                                                                  |
| -------------------------- | --------------------------------------------------------------------------------------------- |
| `oph3z_inventory`          | always                                                                                        |
| `oph3z_inventory_world`    | always                                                                                        |
| `oph3z_inventory_crafting` | `Config.Crafting.enabled = true` "<mark style="color:$primary;">config/crafting.lua</mark>"   |
| `oph3z_inventory_logs`     | `Config.DatabaseLogs = true` "<mark style="color:$primary;">config/server\_config.lua</mark>" |

But the <mark style="color:green;">oph3z-inventory.sql</mark> is included in the script folder just in case.

### Installation Adjustments for Frameworks

{% tabs %}
{% tab title="QBCore" %}

#### Information

Delete the following from your server — the inventory replaces them completely:

* the `qb-inventory` folder
* the `qb-weapons` folder (built-in weapon system: draw/holster, ammo items, durability, attachment workbench)
* the file `qb-smallresources/client/weapdraw.lua`
* the `qb-shops` folder

If you don't want to deal with all this steps you can download this ready qb-core file that already works with the inventory (1.3.0 version):

{% file src="/files/qwCrM7hCQC1HrUkwQVpi" %}

### Step 1

Go to "<mark style="color:$primary;">qb-core/client/functions.lua</mark>" and find **QBCore.Functions.HasItem**:

```lua
function QBCore.Functions.HasItem(items, amount)
    return exports['qb-inventory']:HasItem(items, amount)
end
```

replace with:

```lua
function QBCore.Functions.HasItem(items, amount)
    return exports['oph3z-inventory']:HasItem(items, amount)
end
```

### Step 2

Go to "<mark style="color:$primary;">qb-core/server/functions.lua</mark>" and find **QBCore.Functions.UseItem**:

```lua
function QBCore.Functions.UseItem(source, item)
    if GetResourceState('qb-inventory') == 'missing' then return end
    exports['qb-inventory']:UseItem(source, item)
end
```

replace with:

```lua
function QBCore.Functions.UseItem(source, item)
    if GetResourceState('oph3z-inventory') == 'missing' then return end
    exports['oph3z-inventory']:UseItem(source, item)
end
```

And in the same file:

```lua
function QBCore.Functions.HasItem(source, items, amount)
    if GetResourceState('qb-inventory') == 'missing' then return end
    return exports['qb-inventory']:HasItem(source, items, amount)
end
```

replace with:

```lua
function QBCore.Functions.HasItem(source, items, amount)
    if GetResourceState('oph3z-inventory') == 'missing' then return end
    return exports['oph3z-inventory']:HasItem(source, items, amount)
end
```

### Step 3

Go to "<mark style="color:$primary;">qb-core/server/player.lua</mark>" and replace every `qb-inventory` reference with `oph3z-inventory` (Check Data / Save / SaveOffline functions):

```lua
PlayerData.items = exports['oph3z-inventory']:LoadInventory(PlayerData.source, PlayerData.citizenid)
```

```lua
if GetResourceState('oph3z-inventory') ~= 'missing' then exports['oph3z-inventory']:SaveInventory(source) end
```

```lua
if GetResourceState('oph3z-inventory') ~= 'missing' then exports['oph3z-inventory']:SaveInventory(PlayerData, true) end
```

{% hint style="warning" %}
If your qb-core version also has `QBCore.Player.SaveInventory`, `SaveOfflineInventory`, `GetTotalWeight`, `GetSlotsByItem`, `GetFirstSlotByItem` or `GetCardSlot` blocks referencing `qb-inventory` or anyother inventory, replace the resource name there too — all of these exports exist in oph3z-inventory with the same signatures.
{% endhint %}
{% endtab %}

{% tab title="QBox" %}

#### Information

Delete the following from your server — the inventory replaces them completely:

* the `ox_inventory` folder (Or any other inventory script you use)

If you don't want to deal with all this steps you can download this ready qbx\_core file that already works with the inventory (1.23.0 version):

{% file src="/files/oqcuqMU9bdRn3ykA2SJQ" %}

### Step 1

Go to "<mark style="color:$primary;">qbx\_core/server/main.lua</mark>" and find:

```lua
elseif not lib.checkDependency('ox_inventory', '2.42.1', true) then
    startupErrors, errorMessage = true, 'ox_inventory version 2.42.1 or higher is required'
elseif GetConvar('inventory:framework', '') ~= 'qbx' then
    startupErrors, errorMessage = true, 'inventory:framework must be set to "qbx" in order to use qbx_core'
```

and delete those four lines.

### Step 2

Go to "<mark style="color:$primary;">qbx\_core/server/player.lua</mark>" find and replace each function body:

```lua
function self.Functions.AddItem(item, amount, slot, metadata)
    assert(not self.Offline, 'unsupported for offline players')
    return exports['oph3z-inventory']:AddItem(self.PlayerData.source, item, amount, metadata)
end

function self.Functions.RemoveItem(item, amount, slot)
    assert(not self.Offline, 'unsupported for offline players')
    return exports['oph3z-inventory']:RemoveItem(self.PlayerData.source, item, amount)
end

function self.Functions.GetItemBySlot(slot)
    assert(not self.Offline, 'unsupported for offline players')
    return exports['oph3z-inventory']:GetItemBySlot(self.PlayerData.source, slot)
end

function self.Functions.GetItemByName(itemName)
    assert(not self.Offline, 'unsupported for offline players')
    return exports['oph3z-inventory']:GetItemByName(self.PlayerData.source, itemName)
end

function self.Functions.GetItemsByName(itemName)
    assert(not self.Offline, 'unsupported for offline players')
    return exports['oph3z-inventory']:GetItemsByName(self.PlayerData.source, itemName)
end

function self.Functions.ClearInventory()
    assert(not self.Offline, 'unsupported for offline players')
    return exports['oph3z-inventory']:ClearInventory(self.PlayerData.source)
end
```

### Step 3

Go to "<mark style="color:$primary;">qbx\_core/server/player.lua</mark>" and find Save function and replace it with:

```lua
function Save(source)
    local ped = GetPlayerPed(source)
    local playerData = QBX.Players[source].PlayerData
    local playerState = Player(source)?.state
    local pcoords = playerData.position
    if not playerState.inApartment and not playerState.inProperty then
        local coords = GetEntityCoords(ped)
        pcoords = vec4(coords.x, coords.y, coords.z, GetEntityHeading(ped))
    end
    if not playerData then
        lib.print.error('QBX.PLAYER.SAVE - PLAYERDATA IS EMPTY!')
        return
    end

    playerData.metadata.health = GetEntityHealth(ped)
    playerData.metadata.armor = GetPedArmour(ped)

    if playerState.isLoggedIn then
        playerData.metadata.hunger = playerState.hunger or 0
        playerData.metadata.thirst = playerState.thirst or 0
        playerData.metadata.stress = playerState.stress or 0
    end

    CreateThread(function()
        storage.upsertPlayerEntity({
            playerEntity = playerData,
            position = pcoords,
        })
    end)
    assert(GetResourceState('qb-inventory') ~= 'started', 'qb-inventory is not compatible with qbx_core. use ox_inventory instead')
    exports['oph3z-inventory']:SaveInventory(source)
    lib.print.verbose(('%s PLAYER SAVED!'):format(playerData.name))
end
```

{% hint style="info" %}
Only `exports['oph3z-inventory']:SaveInventory(source)` added.
{% endhint %}

### Step 4

Go to "<mark style="color:$primary;">qbx\_core/server/player.lua</mark>" and find **emitMoneyEvents** function, and near the bottom find:

```lua
if accountsAsItems[oxMoneyType] then
    exports.ox_inventory:SetItem(source, oxMoneyType, playerMoney[moneyType])
end
```

replace with:

```lua
if accountsAsItems[oxMoneyType] then
    accountsAsItems[oxMoneyType] = playerMoney[moneyType]
end
```

Money stays in QBox accounts — the inventory's cash item bridges to the cash account through its own money system, so this sync must not write items.

### Step 5

Go to "<mark style="color:$primary;">qbx\_core/server/character.lua</mark>" and find **giveStarterItems** function and replace with:

```lua
local function giveStarterItems(source)
    if GetResourceState('oph3z-inventory') == 'missing' then return end
    while not exports['oph3z-inventory']:GetInventory(source) do
        Wait(100)
    end
    for i = 1, #starterItems do
        local item = starterItems[i]
        if item.metadata and type(item.metadata) == 'function' then
            exports['oph3z-inventory']:AddItem(source, item.name, item.amount, item.metadata(source))
        else
            exports['oph3z-inventory']:AddItem(source, item.name, item.amount, item.metadata)
        end
    end
end
```

### Step 6

Go to "<mark style="color:$primary;">qbx\_core/bridge/qb/shared/main.lua</mark>" and replace the whole <mark style="color:$warning;">ox items/weapons/components/ammo</mark> conversion block at the top (everything between `local qbShared = require 'shared.main'` and `local starterItems = ...`) with:

```lua
qbShared.Items = {}
qbShared.Weapons = {}
CreateThread(function()
    while GetResourceState('oph3z-inventory') ~= 'started' do Wait(500) end
    local items = exports['oph3z-inventory']:GetItemList()
    if type(items) == 'table' then
        for name, def in pairs(items) do
            def.name = name
            def.useable = def.usable == true or def.use ~= nil or def.status ~= nil or def.onUse ~= nil
        end
        qbShared.Items = items
    end
    
    local weapons = exports['oph3z-inventory']:GetWeaponList()
    if type(weapons) == 'table' then
        qbShared.Weapons = weapons
    end
end)
```

### Step 7

Go to "<mark style="color:$primary;">qbx\_core/bridge/qb/server/main.lua</mark>" and delete these two lines:

```lua
local convertItems = require 'bridge.qb.shared.compat'.convertItems
convertItems(require '@ox_inventory.data.items', require 'shared.items')
```

### Step 8

#### <mark style="color:orange;">a)</mark>

Go to "<mark style="color:$primary;">qbx\_core/bridge/qb/client/functions.lua</mark>" and find:

```lua
functions.HasItem = function(items, amount)
    amount = amount or 1
    local count = exports.ox_inventory:Search('count', items)
    if type(items) == 'table' and type(count) == 'table' then
        for _, v in pairs(count) do
            if v < amount then
                return false
            end
        end
        return true
    end
    return count >= amount
end
```

replace  with:

```lua
functions.HasItem = function(items, amount)
    amount = amount or 1
    return exports['oph3z-inventory']:HasItem(items, amount)
end
```

#### <mark style="color:orange;">b)</mark>

Go to "<mark style="color:$primary;">qbx\_core/bridge/qb/server/functions.lua</mark>" and find:

```lua
functions.HasItem = function(source, items, amount)
    amount = amount or 1
    local count = exports.ox_inventory:Search(source, 'count', items)
    if type(items) == 'table' and type(count) == 'table' then
        for _, v in pairs(count) do
            if v < amount then
                return false
            end
        end
        return true
    end
    return count >= amount
end
```

replace with:

```lua
functions.HasItem = function(source, items, amount)
    amount = amount or 1
    return exports['oph3z-inventory']:HasItem(source, items, amount)
end
```

#### <mark style="color:orange;">c)</mark>

Go to "<mark style="color:$primary;">qbx\_core/modules/utils.lua</mark>" and find:

```lua
function HasItem(source, items, amount)
    amount = amount or 1
    local count = exports.ox_inventory:Search(source, 'count', items)
    if type(items) == 'table' and type(count) == 'table' then
        for _, v in pairs(count) do
            if v < amount then
                return false
            end
        end
        return true
    end
    return count >= amount
end
```

replace with:

```lua
function HasItem(source, items, amount)
    amount = amount or 1
    return exports['oph3z-inventory']:HasItem(source, items, amount)
end
```

#### <mark style="color:orange;">d)</mark>

Go to "<mark style="color:$primary;">qbx\_core/modules/utils.lua</mark>" and find:

```lua
function HasItem(items, amount)
    amount = amount or 1
    local count = exports.ox_inventory:Search('count', items)
    if type(items) == 'table' and type(count) == 'table' then
        for _, v in pairs(count) do
            if v < amount then
                return false
            end
        end
        return true
    end
    return count >= amount
end
```

replace with:

```lua
function HasItem(items, amount)
    amount = amount or 1
    return exports['oph3z-inventory']:HasItem(items, amount)
end
```

{% endtab %}

{% tab title="ESX (1.11+)" %}
{% hint style="warning" %}
This is only for 1.11+ versions!
{% endhint %}

#### Information

Delete the following from your server — the inventory replaces them completely:

* the `esx_inventory` folder (Or any other inventory script you use)

If you don't want to deal with all this steps you can download this ready es\_extended file that already works with the inventory (1.14 version):

{% file src="/files/5uEEncCRm3xUmNIxxBA1" %}

### Step 1

Go to "<mark style="color:$primary;">shared/config/main.lua</mark>" and set the custom inventory:

```lua
Config.CustomInventory = "oph3z"
```

And a few lines further down, guard the ox auto-detect so a leftover ox\_inventory folder cannot override your setting:

### Step 2

Create "<mark style="color:$primary;">server/classes/overrides/oph3zinventory.lua</mark>" — this redirects every **xPlayer** item function (used by esx\_drugs, esx\_jobs, shops, and every other addon) into this inventory:

```lua
if Config.CustomInventory ~= "oph3z" then return end
local INV = "oph3z-inventory"
Core.PlayerFunctionOverrides.Oph3zInventory = {
    getInventory = function(self)
        return function()
            local data = exports[INV]:GetInventory(self.source)
            local inventory = {}
            for _, entry in ipairs(data and data.items or {}) do
                inventory[#inventory + 1] = {
                    name = entry.name,
                    count = entry.amount,
                    amount = entry.amount,
                    slot = entry.slot,
                    metadata = entry.metadata,
                    label = exports[INV]:GetItemLabel(entry.name) or entry.name
                }
            end
            return inventory
        end
    end,
    
    getLoadout = function(self)
        return function()
            return {}
        end
    end,
    
    getInventoryItem = function(self)
        return function(name)
            local item = exports[INV]:GetItemByName(self.source, name)
            local count = exports[INV]:GetItemsTotalAmount(self.source, name) or 0
            if not item then
                return { name = name, count = count, amount = count, label = exports[INV]:GetItemLabel(name) or name }
            end
            item.count = count
            item.label = exports[INV]:GetItemLabel(name) or name
            return item
        end
    end,
    
    addInventoryItem = function(self)
        return function(name, count, metadata)
            return exports[INV]:AddItem(self.source, name, count or 1, metadata)
        end
    end,
    
    removeInventoryItem = function(self)
        return function(name, count, metadata)
            return exports[INV]:RemoveItem(self.source, name, count or 1, metadata)
        end
    end,
    
    setInventoryItem = function(self)
        return function(name, count, metadata)
            local current = exports[INV]:GetItemsTotalAmount(self.source, name) or 0
            count = ESX.Math.Round(tonumber(count) or 0)
            if count > current then
                return exports[INV]:AddItem(self.source, name, count - current, metadata)
            elseif count < current then
                return exports[INV]:RemoveItem(self.source, name, current - count)
            end
            return true
        end
    end,
    
    canCarryItem = function(self)
        return function(name, count)
            return exports[INV]:CanCarry(self.source, name, count or 1) == true
        end
    end,
    
    canSwapItem = function(self)
        return function()
            return true
        end
    end,
    
    setMaxWeight = function(self)
        return function() end
    end,
    
    addWeapon = function(self)
        return function(weaponName, ammo)
            local name = type(weaponName) == "string" and weaponName:lower() or nil
            if not name then return end
            local metadata = nil
            local loaded = ESX.Math.Round(tonumber(ammo) or 0)
            if loaded > 0 then metadata = { ammo = loaded } end
            return exports[INV]:AddItem(self.source, name, 1, metadata)
        end
    end,
    
    removeWeapon = function(self)
        return function(weaponName)
            local name = type(weaponName) == "string" and weaponName:lower() or nil
            if not name then return end
            return exports[INV]:RemoveItem(self.source, name, 1)
        end
    end,
    
    hasWeapon = function(self)
        return function(weaponName)
            local name = type(weaponName) == "string" and weaponName:lower() or nil
            if not name then return false end
            return exports[INV]:GetItemByName(self.source, name) ~= nil
        end
    end,
    
    addWeaponComponent = function(self)
        return function() end
    end,
    
    addWeaponAmmo = function(self)
        return function() end
    end,
    
    updateWeaponAmmo = function(self)
        return function() end
    end,
    
    setWeaponTint = function(self)
        return function() end
    end,
    
    getWeaponTint = function(self)
        return function() end
    end,
    
    removeWeaponComponent = function(self)
        return function() end
    end,
    
    removeWeaponAmmo = function(self)
        return function() end
    end,
    
    hasWeaponComponent = function(self)
        return function()
            return false
        end
    end,
    
    getWeapon = function(self)
        return function() end
    end,
    
    hasItem = function(self)
        return function(name)
            return exports[INV]:GetItemByName(self.source, name)
        end
    end
}
```

### Step 3

Create "<mark style="color:$primary;">server/bridge/inventory/oph3zinventory.lua</mark>" — this fills **ESX.Items** from the inventory (so **ESX.UseItem** works) and makes every **ESX.RegisterUsableItem** call land in both systems:

```lua
if Config.CustomInventory ~= "oph3z" then return end
local INV = "oph3z-inventory"
local started = false
local pendingUsable = {}
local refreshQueued = false

local function pullItems()
    local items = exports[INV]:GetItemList()
    if type(items) == "table" then
        ESX.Items = items
    end
end

CreateThread(function()
    while GetResourceState(INV) ~= "started" do Wait(500) end
    started = true
    pullItems()
    for item, cb in pairs(pendingUsable) do
        exports[INV]:RegisterUsableItem(item, cb)
    end
    pendingUsable = {}
end)

AddEventHandler("oph3z-inventory:itemsChanged", function()
    if refreshQueued or not started then return end
    refreshQueued = true
    SetTimeout(500, function()
        refreshQueued = false
        pullItems()
    end)
end)

ESX.GetItemLabel = function(item)
    if started then
        local label = exports[INV]:GetItemLabel(item)
        if label then return label end
    end
    return item
end

ESX.RegisterUsableItem = function(item, cb)
    Core.UsableItemsCallbacks[item] = cb
    if started then
        exports[INV]:RegisterUsableItem(item, cb)
    else
        pendingUsable[item] = cb
    end
end
```

### Step 4

Go to "<mark style="color:$primary;">client/functions.lua</mark>" and find **ESX.GetPlayerData** function and replace it with this code:

```lua
function ESX.GetPlayerData()
    if Config.CustomInventory == "oph3z" then
        ESX.PlayerData.inventory = LocalPlayer.state.inventory or {}
    end
    return ESX.PlayerData
end
```

{% endtab %}

{% tab title="ESX (1.9+)" %}
{% hint style="warning" %}
This is only for 1.9-1.10.x versions!
{% endhint %}

#### Information

Delete the following from your server — the inventory replaces them completely:

* the `esx_inventory` folder (Or any other inventory script you use)

### Step 1

Go to "<mark style="color:$primary;">es\_extended/config.lua</mark>" and set `Config.EnableDefaultInventory`  to false:

```lua
Config.EnableDefaultInventory = false
```

and then add this line anytwhere in the file:

```lua
Config.PlayerFunctionOverride = 'Oph3zInventory'
```

### Step 2

Create "<mark style="color:$primary;">es\_extended/server/classes/overrides</mark>" and paste this code in the file:

<pre class="language-lua"><code class="lang-lua">if Config.PlayerFunctionOverride ~= 'Oph3zInventory' then return end
local INV = 'oph3z-inventory'

<strong>Core.PlayerFunctionOverrides.Oph3zInventory = {
</strong>    getInventory = function(self)
        return function()
            local data = exports[INV]:GetInventory(self.source)
            local inventory = {}
            for _, entry in ipairs(data and data.items or {}) do
                inventory[#inventory + 1] = {
                    name = entry.name,
                    count = entry.amount,
                    amount = entry.amount,
                    slot = entry.slot,
                    metadata = entry.metadata,
                    label = exports[INV]:GetItemLabel(entry.name) or entry.name
                }
            end
            return inventory
        end
    end,
    
    getLoadout = function(self)
        return function()
            return {}
        end
    end,
    
    getInventoryItem = function(self)
        return function(name)
            local item = exports[INV]:GetItemByName(self.source, name)
            local count = exports[INV]:GetItemsTotalAmount(self.source, name) or 0
            if not item then
                return { name = name, count = count, amount = count, label = exports[INV]:GetItemLabel(name) or name }
            end
            item.count = count
            item.label = exports[INV]:GetItemLabel(name) or name
            return item
        end
    end,
    
    addInventoryItem = function(self)
        return function(name, count, metadata)
            return exports[INV]:AddItem(self.source, name, count or 1, metadata)
        end
    end,
    
    removeInventoryItem = function(self)
        return function(name, count, metadata)
            return exports[INV]:RemoveItem(self.source, name, count or 1, metadata)
        end
    end,
    
    setInventoryItem = function(self)
        return function(name, count, metadata)
            local current = exports[INV]:GetItemsTotalAmount(self.source, name) or 0
            count = ESX.Math.Round(tonumber(count) or 0)
            if count > current then
                return exports[INV]:AddItem(self.source, name, count - current, metadata)
            elseif count &#x3C; current then
                return exports[INV]:RemoveItem(self.source, name, current - count)
            end
            return true
        end
    end,
    
    canCarryItem = function(self)
        return function(name, count)
            return exports[INV]:CanCarry(self.source, name, count or 1) == true
        end
    end,
    
    canSwapItem = function(self)
        return function()
            return true
        end
    end,
    
    setMaxWeight = function(self)
        return function() end
    end,
    
    addWeapon = function(self)
        return function(weaponName, ammo)
            local name = type(weaponName) == 'string' and weaponName:lower() or nil
            if not name then return end
            local metadata = nil
            local loaded = ESX.Math.Round(tonumber(ammo) or 0)
            if loaded > 0 then metadata = { ammo = loaded } end
            return exports[INV]:AddItem(self.source, name, 1, metadata)
        end
    end,
    
    removeWeapon = function(self)
        return function(weaponName)
            local name = type(weaponName) == 'string' and weaponName:lower() or nil
            if not name then return end
            return exports[INV]:RemoveItem(self.source, name, 1)
        end
    end,
    
    hasWeapon = function(self)
        return function(weaponName)
            local name = type(weaponName) == 'string' and weaponName:lower() or nil
            if not name then return false end
            return exports[INV]:GetItemByName(self.source, name) ~= nil
        end
    end,
    
    addWeaponComponent = function(self)
        return function() end
    end,
    
    addWeaponAmmo = function(self)
        return function() end
    end,
    
    updateWeaponAmmo = function(self)
        return function() end
    end,
    
    setWeaponTint = function(self)
        return function() end
    end,
    
    getWeaponTint = function(self)
        return function() end
    end,
    
    removeWeaponComponent = function(self)
        return function() end
    end,
    
    removeWeaponAmmo = function(self)
        return function() end
    end,
    
    hasWeaponComponent = function(self)
        return function()
            return false
        end
    end,
    
    getWeapon = function(self)
        return function() end
    end,
    
    hasItem = function(self)
        return function(name)
            return exports[INV]:GetItemByName(self.source, name)
        end
    end
}

local forwarded = {}
CreateThread(function()
    while GetResourceState(INV) ~= 'started' do Wait(500) end
    while true do
        for item, cb in pairs(Core.UsableItemsCallbacks) do
            if forwarded[item] ~= cb then
                forwarded[item] = cb
                exports[INV]:RegisterUsableItem(item, cb)
            end
        end
        Wait(5000)
    end
end)
</code></pre>

### Step 3

Go to "<mark style="color:$primary;">es\_extended/client/functions.lua</mark>" and find **ESX.GetPlayerData** function and replace it with:

```lua
function ESX.GetPlayerData()
    ESX.PlayerData.inventory = LocalPlayer.state.inventory or ESX.PlayerData.inventory
    return ESX.PlayerData
end
```

{% endtab %}
{% endtabs %}

### Backwards compatibility

If your old scripts still call <mark style="color:green;">`exports['qb-inventory']`</mark> or <mark style="color:green;">`exports.ox_inventory`</mark>, you do not have to edit them one by one. Enable the compatibility in "<mark style="color:$primary;">config/config.lua</mark>":

```lua
Config.BackwardsCompatibility = {
    ["qb-inventory"] = true,
    ["ox_inventory"] = false
}
```

Enable the one your old scripts use (both can be on at once) and restart. That's all — your old scripts should work with this inventory.

### Importing items from your old inventory

You do not have to recreate your items by hand. The admin panel (`/invadmin`, Items tab, **Import** button) brings item definitions over from your old inventory in a few clicks. The popup has two sections:

<mark style="color:orange;">**Import**</mark> - the panel looks around your server and lists every old inventory it can read, with how many items each one holds. Click one and its items appear in a preview. Recognised: `ox_inventory`, `qs-inventory`, `qb-core`, `jaksam_inventory`, `codem-inventory` and the ESX `items` database table. The old inventory does not have to be running - if it is, the panel asks it directly, and if it is only installed, its item file is read instead. Item images are copied over automatically (existing images are never overwritten, they show up after the next resource restart).

<figure><img src="https://2048929190-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FIwQ369U2PuFWD7Lp25Wv%2Fuploads%2Fe5uxcM59Wka8TdhfsEQ2%2Fimage.png?alt=media&amp;token=b69e6823-34f4-418d-847b-a25594bef9ee" alt=""><figcaption><p><mark style="color:$danger;">This image is based on sample data; it is NOT based on ACTUAL data, so it is normal if inventories mentioned not to appear in the images.</mark></p></figcaption></figure>

<mark style="color:orange;">**Convert**</mark> - for when the old inventory is not on this server at all. Paste its item table as text (`data/items.lua` / `data/weapons.lua` from ox\_inventory, `shared/items.lua` from QB-Core, or SQL/CSV of the ESX `items` table) and it is converted. The pasted text is treated as pure data - nothing in it is executed.

<figure><img src="https://2048929190-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FIwQ369U2PuFWD7Lp25Wv%2Fuploads%2FKCXUxUtgLoViwZX3pP5G%2Fimage.png?alt=media&amp;token=e76d999f-3fe7-480b-9922-2856016c6b72" alt="This image is based on sample data; it is NOT based on ACTUAL data, so it is normal for the inventories mentioned not to appear in the images."><figcaption><p><mark style="color:$danger;">This image is based on sample data; it is NOT based on ACTUAL data, so it is normal if inventories mentioned not to appear in the images.</mark></p></figcaption></figure>

Both sections end in the same preview where every item can be ticked or unticked - items you already have are unticked so nothing is overwritten by accident. Then pick one of two outputs:

1. **Create as live items** - items are saved through the normal item pipeline, synced to everyone instantly and manageable from the Items tab.
2. **Copy as code** - generates ready-to-paste Lua in this inventory's exact config style for <mark style="color:$primary;">config/items.lua</mark>. Weapons and ammo always go into <mark style="color:$primary;">config/weapons\_items.lua</mark>.

<figure><img src="https://2048929190-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FIwQ369U2PuFWD7Lp25Wv%2Fuploads%2FvE8UuuXTDlLOvqSUJvmc%2Fimage.png?alt=media&amp;token=96db46e7-471f-42bd-85fb-58befdb9c73e" alt=""><figcaption></figcaption></figure>

What carries over: label, weight, stack, usable, description, image and the weapon basics. What cannot carry over: the old inventory's script logic (what an item *does* on use still lives in your other resources).
