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

# qbox\_core

Run **QBX Core** with **devix-inventory** instead of the real ox\_inventory. This resource (`ox_inventory`) provides the ox\_inventory API and uses devix-inventory as backend.

## What you need

1. **devix-core** — framework bridge (Config.Framework = "qbox" for QBX).
2. **devix-inventory** — your main inventory.

{% hint style="info" %}
**Critical:** There should be no external inventory other than devix-inventory.
{% endhint %}

## Installation

{% stepper %}
{% step %}

### Step 1 — Remove ox\_inventory

Take the items from ox\_inventory and do not store them in any resource file.  [ox\_inventory](/devix/devix-inventory/installation/qbox_core/ox_inventory.md)
{% endstep %}

{% step %}

### Step 2 — server.cfg

Add the following to your server.cfg:

```cfg
ensure devix-core
ensure devix-inventory
```

{% endstep %}

{% step %}

### Step 3 — Start server

Start the server.
{% endstep %}
{% endstepper %}

***

## qbx\_core: 4 changes

Only if you use QBX. These are the only code changes in qbx\_core.

| File                                    | What to do                                                                                          |
| --------------------------------------- | --------------------------------------------------------------------------------------------------- |
| **qbx\_core/server/main.lua**           | Comment out ox\_inventory dependency and `inventory:framework` check.                               |
| **qbx\_core/server/functions.lua**      | Add `GetUsableItems` export so devix-core can sync usables (phone etc.) regardless of start order.  |
| **qbx\_core/bridge/qb/shared/main.lua** | Fill `qbShared.Items` from `exports['devix-inventory']:GetItemList()` after devix-inventory starts. |
| **qbx\_core/bridge/qb/server/main.lua** | Comment out the convertItems / `@ox_inventory.data.items` conversion.                               |

server/main.lua — comment out:

```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'
```

bridge/qb/server/main.lua — comment out:

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

server/functions.lua — after `exports('CanUseItem', CanUseItem)` add (so devix-core can sync usables on start and avoid "items only work after ensure"):

```lua
---@return table<string, unknown> QBX.UsableItems (read-only reference for devix-core sync)
function GetUsableItems()
    return QBX.UsableItems
end

exports('GetUsableItems', GetUsableItems)
```

qbox\_core/server/player.lua   addMoney&#x20;

{% code expandable="true" %}

```lua
function AddMoney(identifier, moneyType, amount, reason)
    local player = type(identifier) == 'string' and (GetPlayerByCitizenId(identifier) or GetOfflinePlayer(identifier)) or GetPlayer(identifier)

    if not player then return false end

    -- devix-core cash-as-item: dis cagrilarda devix-core'a yonlendir (qb-banking, escrow vb.)
    reason = reason or 'unknown'
    if reason ~= 'devix_add' and (moneyType == 'cash' or moneyType == 'money') and GetResourceState('devix-core') == 'started' then
        local ok, DEVIX = pcall(function() return exports['devix-core']:getObjects() end)
        if ok and DEVIX and DEVIX.AddMoney then
            DEVIX.AddMoney(player, 'cash', amount)
            return true
        end
    end

    reason = reason or 'unknown'
    amount = qbx.math.round(tonumber(amount) --[[@as number]])

    if amount < 0 or not player.PlayerData.money[moneyType] then return false end

    if not triggerEventHooks('addMoney', {
        source = player.PlayerData.source,
        moneyType = moneyType,
        amount = amount
    }) then return false end

    player.PlayerData.money[moneyType] += amount

    if player.Offline then
        SaveOffline(player.PlayerData)
    else
        UpdatePlayerData(identifier)

        local tags = amount > 100000 and config.logging.role or nil
        local resource = GetInvokingResource() or cache.resource

        logger.log({
            source = resource,
            webhook = config.logging.webhook['playermoney'],
            event = 'AddMoney',
            color = 'lightgreen',
            tags = tags,
            message = ('**%s (citizenid: %s | id: %s)** $%s (%s) added, new %s balance: $%s reason: %s'):format(GetPlayerName(player.PlayerData.source), player.PlayerData.citizenid, player.PlayerData.source, amount, moneyType, moneyType, player.PlayerData.money[moneyType], reason),
            --oxLibTags = ('script:%s,playerName:%s,citizenId:%s,playerSource:%s,amount:%s,moneyType:%s,newBalance:%s,reason:%s'):format(resource, GetPlayerName(player.PlayerData.source), player.PlayerData.citizenid, player.PlayerData.source, amount, moneyType, player.PlayerData.money[moneyType], reason)
        })

        emitMoneyEvents(player.PlayerData.source, player.PlayerData.money, moneyType, amount, 'add', reason)
    end

    return true
end
```

{% endcode %}

qbox\_core/server/player.lua removeMoney

{% code expandable="true" %}

```lua
function RemoveMoney(identifier, moneyType, amount, reason)
    local player = type(identifier) == 'string' and (GetPlayerByCitizenId(identifier) or GetOfflinePlayer(identifier)) or GetPlayer(identifier)

    if not player then return false end

    -- devix-core cash-as-item: dis cagrilarda devix-core'a yonlendir (qb-banking, escrow vb.)
    reason = reason or 'unknown'
    if reason ~= 'devix_remove' and (moneyType == 'cash' or moneyType == 'money') and GetResourceState('devix-core') == 'started' then
        local ok, DEVIX = pcall(function() return exports['devix-core']:getObjects() end)
        if ok and DEVIX and DEVIX.RemoveMoney then
            return DEVIX.RemoveMoney(player, 'cash', amount)
        end
    end

    reason = reason or 'unknown'
    amount = qbx.math.round(tonumber(amount) --[[@as number]])

    if amount < 0 or not player.PlayerData.money[moneyType] then return false end

    if not triggerEventHooks('removeMoney', {
        source = player.PlayerData.source,
        moneyType = moneyType,
        amount = amount
    }) then return false end

    for _, mType in pairs(config.money.dontAllowMinus) do
        if mType == moneyType then
            if (player.PlayerData.money[moneyType] - amount) < 0 then
                return false
            end
        end
    end

    player.PlayerData.money[moneyType] -= amount

    if player.Offline then
        SaveOffline(player.PlayerData)
    else
        UpdatePlayerData(identifier)

        local tags = amount > 100000 and config.logging.role or nil
        local resource = GetInvokingResource() or cache.resource

        logger.log({
            source = resource,
            webhook = config.logging.webhook['playermoney'],
            event = 'RemoveMoney',
            color = 'red',
            tags = tags,
            message = ('** %s (citizenid: %s | id: %s)** $%s (%s) removed, new %s balance: $%s reason: %s'):format(GetPlayerName(player.PlayerData.source), player.PlayerData.citizenid, player.PlayerData.source, amount, moneyType, moneyType, player.PlayerData.money[moneyType], reason),
            --oxLibTags = ('script:%s,playerName:%s,citizenId:%s,playerSource:%s,amount:%s,moneyType:%s,newBalance:%s,reason:%s'):format(resource, GetPlayerName(player.PlayerData.source), player.PlayerData.citizenid, player.PlayerData.source, amount, moneyType, player.PlayerData.money[moneyType], reason)
        })

        emitMoneyEvents(player.PlayerData.source, player.PlayerData.money, moneyType, amount, 'remove', reason)
    end

    return true
end
```

{% endcode %}

***

All other qbx\_core files: no changes.

{% hint style="info" %}
[Don't forget to change provide in fxmanifest.lua.](#user-content-fn-1)[^1]
{% endhint %}

<pre class="language-lua" data-expandable="true"><code class="lang-lua"><strong>-- provide 'qb-inventory'
</strong>provide 'ox_inventory'
</code></pre>

***

<details>

<summary>No such export ... in resource ox_inventory</summary>

**Cause:** The resource named **ox\_inventory** is the real Overextended one, or this resource failed to start.

**Fix:**

* This **ox\_inventory** (devix-inventory backend) must be the only resource named `ox_inventory` and must be in server.cfg (`ensure ox_inventory`).
* Do **not** start the real ox\_inventory (remove/rename its folder or don't ensure it).

</details>

***

## Optional

* **devix-core** `shared/config.lua`: set `Config.Framework = "qbox"` if you use QBX
* **QBX override warnings** ("overriding method AddItem/RemoveItem…"): add to server.cfg:\
  `set qbx:disableoverridewarning true`\
  This only hides the message; behaviour is unchanged.

***

## Summary

| Step | Action                                                                          |
| ---- | ------------------------------------------------------------------------------- |
| 1    | Put **ox\_inventory** (this resource) in `resources/`.                          |
| 2    | Do not start the real ox\_inventory.                                            |
| 3    | server.cfg: ensure **devix-core**, **devix-inventory**, then **ox\_inventory**. |
| 4    | (QBX) Apply the 4 qbx\_core edits above.                                        |

Result: QBX and other scripts keep calling `exports["ox_inventory"]`; this resource answers and uses devix-inventory.

[^1]:


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://devix.gitbook.io/devix/devix-inventory/installation/qbox_core.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
