Skip to content

Inventory items

Blixt registers three items as usable on whichever inventory or framework resource is running:

ItemAction when used
phoneOpens the Blixt phone.
tabletOpens the Blixt tablet (only if blixt-tablet is started).
powerbankCharges the active handset battery to 100%.

Registration is automatic. You do not need to ship Lua glue, run an export, or set a convar. The Blixt server bundle picks the first matching provider at boot and re-registers if the inventory/framework resource restarts later.

ProviderHow Blixt registers
ox_inventoryexports[blixt](name, cb) — listens for usingItem
qb-core / qboxQBCore.Functions.CreateUseableItem(name, cb)
es_extendedESX.RegisterUsableItem(name, cb)

Source: devices/phone/game/server/inventory-items.ts.


The items still need to exist in your inventory’s item table — Blixt only registers the “use” callback for items that already exist by name. Pick the section that matches your stack.

ox_inventory has no public registerItem export and SaveResourceFile is blocked cross-resource, so Blixt cannot inject the items at runtime. They must be present in ox_inventory/data/items.lua at boot.

The canonical snippet lives in the Blixt source at resources/blixt-tablet/data/items.lua. Paste these entries into the outer return { … } table of ox_inventory/data/items.lua and restart ox_inventory:

['phone'] = {
label = 'Phone',
weight = 190,
stack = false,
consume = 0,
close = true,
description = 'Opens the Blixt phone when used.',
},
['tablet'] = {
label = 'Tablet',
weight = 400,
stack = false,
close = true,
description = 'Opens the Blixt Tablet when used.',
client = { image = 'tablet.png' },
},
['powerbank'] = {
label = 'Powerbank',
weight = 200,
stack = false,
close = true,
description = 'Recharges the Blixt phone battery to full when used.',
},

Add the items to qb-core/shared/items.lua:

phone = {
name = 'phone', label = 'Phone', weight = 190, type = 'item',
image = 'phone.png', unique = true, useable = true, shouldClose = true,
description = 'A Blixt phone',
},
tablet = {
name = 'tablet', label = 'Tablet', weight = 600, type = 'item',
image = 'tablet.png', unique = true, useable = true, shouldClose = true,
description = 'A Blixt tablet',
},
powerbank = {
name = 'powerbank', label = 'Powerbank', weight = 350, type = 'item',
image = 'powerbank.png', unique = false, useable = true, shouldClose = true,
description = 'A portable phone charger',
},

Add phone, tablet, and powerbank rows to whatever inventory resource your server uses. Vanilla ESX uses the items SQL table; modern ESX setups on ox_inventory use the snippet from the ox_inventory section above.

Blixt only registers the usable callback via ESX.RegisterUsableItem — the underlying item definition is your inventory’s responsibility.


By default the phone is openable without owning a phone item — F1, the /phone command, and the exports.blixt:OpenPhone server export all work regardless of inventory. Same story for the tablet (F2 / /tablet). This keeps Blixt working on standalone servers and on frameworks with no item economy.

To make the item required, flip the gate. Two config surfaces, either works — the convar wins when both are set.

setr blixt:phone_require_item "true"
setr blixt:phone_item_name "phone" # default — change if you ship a custom item name
setr blixt:tablet_require_item "true"
setr blixt:tablet_item_name "tablet" # default
setr blixt:item_denied_message "You need a {item}." # `{item}` is replaced with the configured itemName
{
"phone": {
"requireItem": true,
"itemName": "phone"
},
"tablet": {
"requireItem": true,
"itemName": "tablet"
}
}

Restart the resource to apply (fm resources restart blixt or the in-game console). No client-side restart needed — the state propagates via GlobalState.blixt_access and the keymap handlers adapt on the next press.

Every open path funnels through one server-side check (isOpenAllowed(source, kind)):

  1. F1 / F2 / /phone / /tablet keymap — when the gate is on, the client emits blixt:phone:request-open (or the tablet equivalent) to the blixt server instead of opening locally. Server checks the adapter’s inventory; on success it fires the existing blixt:phone:open / blixt-tablet:inventory:openTablet event back. When the gate is off, the client opens locally with no round-trip — zero added latency.
  2. exports.blixt:OpenPhone(source) — gated. Third-party resources that call this export get false back when the player has no item.
  3. Inventory-item use (the phone / tablet callbacks registered automatically — see above) — exempt from the gate. Using the item is itself proof of ownership.

When an open is denied, the player sees the configured denial message via the framework adapter’s notifyPlayer (ESX ShowNotification, qbx_core Notify, etc.). Falls back to a chat message on stacks where the adapter has no notify hook.

Under blixt:framework=standalone the gate is a no-op. The blixt server logs a one-time warning at boot and treats requireItem as false — GlobalState.blixt_access ships false to clients so F1 opens locally. Standalone operators who want to enforce a check should do it in a companion resource (gate RegisterCommand('phone', ...) and RegisterKeyMapping(...) to overwrite Blixt’s default keymap). This keeps the built-in gate honest: when on, it’s backed by a real inventory check; when the framework can’t honour that check, it’s off.


devices/phone/game/server/lua/items.lua runs on resource start and on onResourceStart('ox_inventory'). If tablet or powerbank are missing from ox_inventory’s Items() list, the operator gets a yellow stderr warning:

[blixt-items] ox_inventory is missing item(s): tablet, powerbank
[blixt-items] fun.addInventoryItem() will fail for these names until they are
[blixt-items] added to ox_inventory/data/items.lua.

Without that warning the failure mode is fun.addInventoryItem(...) returning a generic "Failed to add item." with no breadcrumb to the cause.


The registration step lives in devices/phone/game/server/inventory-items.ts and runs at script load and on every onServerResourceStart('ox_inventory' | 'qb-core' | 'es_extended'). That covers both possible boot orders (Blixt first vs the inventory resource first) without requiring dependency lines that would tie the resources together.

When a player uses the item, the server-side callback fires:

ItemServer-sideClient event
phoneuseInventoryItem(src, …)blixt:inventory:openPhone
tabletuseInventoryItem(src, …) (after blixt-tablet started check)blixt-tablet:inventory:openTablet
powerbankuseInventoryItem(src, …)blixt:battery:charge (amount: 100)

The tools/qbx-dev-server/ and tools/blixt-dev-server/ Docker stacks patch the Blixt items into ox_inventory/data/items.lua automatically at container start — they read from resources/blixt-tablet/data/items.lua (the source of truth). Self-hosted operators do this step by hand once.