Exports
All server exports are called as exports.one_inventory:Name(...) from a server script.
Inventory identifiers
Every server export below takes an inv argument that resolves to a single inventory. The same export works for players, stashes, vehicle trunks, gloveboxes, backpacks, drops, and dumpsters, so a dealership script can pre-fill a trunk the same way a player script tops up a backpack.
| Form | Resolves to |
|---|---|
123 | Player by server id/source |
'123' | Player by server id/source |
'player:<identifier>' | Player by getIdentifier() |
'stash:<name>' | Shared stash |
'stash:<name>:<identifier>' | Owned / unique stash bucket |
'trunk:<plate>' | Vehicle trunk |
'glovebox:<plate>' | Vehicle glovebox |
'backpack:<id>' | Backpack instance |
'drop:<id>' | Ground drop |
'dumpster:<id>' | Dumpster |
Auto-create on first call
AddItem and SetItem materialise the inventory on first call when the type supports it. Every other export returns false / nil for an inventory that doesn't exist yet.
| Type | Auto-creates? | Defaults |
|---|---|---|
stash:* | yes | 50 slots / 50 000 g |
trunk:* | yes | 30 slots / 80 000 g |
glovebox:* | yes | 5 slots / 5 000 g |
drop:*, backpack:*, dumpster:*, player:* | no | — |
Item operations
AddItem
Add a count of an item to an inventory.
exports.one_inventory:AddItem(inv, item, count, metadata, slot)
1.stash:*, trunk:*, and glovebox:* inventories if they don't exist yet. See Auto-create on first call.metadata.serial = false to add a weapon without a serial number (e.g. blackmarket guns):exports.one_inventory:AddItem(inv, 'weapon_pistol', 1, { serial = false })
Returns: boolean, string? - success, plus a reason on failure (invalid_item, no_inventory, hook_cancelled, ...).
RemoveItem
Remove a count of an item from an inventory. Auto-disarms if a player's equipped weapon is removed.
exports.one_inventory:RemoveItem(inv, item, count, metadata, slot)
1.Returns: boolean, string?.
SetItem
Set the absolute count of an item across an inventory (creates / destroys stacks to match).
exports.one_inventory:SetItem(inv, item, count, metadata)
stash:*, trunk:*, and glovebox:* inventories if they don't exist yet. See Auto-create on first call.Returns: boolean, string?.
GetItem
First slot matching the given item name (and optional metadata).
exports.one_inventory:GetItem(inv, item, metadata)
Returns: table | nil - { name, slot, count, metadata }, or nil if not found.
GetItemCount
Total count of an item across every slot of the inventory.
exports.one_inventory:GetItemCount(inv, item, metadata)
Returns: number.
HasItem
True when the inventory holds at least count of the item.
exports.one_inventory:HasItem(inv, item, count, metadata)
1.Returns: boolean.
Slot lookup
GetSlot
Slot data at a given slot index.
exports.one_inventory:GetSlot(inv, slot)
Returns: table | nil - { name, slot, count, metadata }, or nil if empty / out of range.
GetFreeSlot
First empty slot in the inventory.
exports.one_inventory:GetFreeSlot(inv)
Returns: number | nil.
GetSlotIdWithItem
First slot index that contains the item, optionally filtered by metadata.
exports.one_inventory:GetSlotIdWithItem(inv, item, metadata)
Returns: number | nil.
GetSlotIdsWithItem
Every slot index that contains the item.
exports.one_inventory:GetSlotIdsWithItem(inv, item, metadata)
Returns: number[].
GetItemSlots
Map of { [slotId] = count } for every slot containing the item.
exports.one_inventory:GetItemSlots(inv, item)
Returns: table<number, number>.
GetBackpackFromSlot
Backpack item at a slot, including its definition-derived capacity (slots, maxWeight, label) and contents snapshot via metadata.items.
exports.one_inventory:GetBackpackFromSlot(inv, slot)
Returns: table | nil - slot data plus slots, maxWeight, label. nil if the slot doesn't hold a backpack.
GetEquippedWeapon
Currently-equipped weapon slot.
exports.one_inventory:GetEquippedWeapon(inv)
nil.Returns: table | nil - slot data where metadata holds ammo / serial / components, or nil if unarmed.
Capacity
CanCarryItem
True if the inventory can still fit N more of the item.
exports.one_inventory:CanCarryItem(inv, item, count)
1.Returns: boolean.
CanCarryWeight
True if the inventory can take an additional weight grams.
exports.one_inventory:CanCarryWeight(inv, weight)
Returns: boolean.
GetCarryableCount
Max additional units of the item that still fit (math.huge for zero-weight items).
exports.one_inventory:GetCarryableCount(inv, item)
Returns: number.
SwapSlots
Swap the contents of two slots within the same inventory.
exports.one_inventory:SwapSlots(inv, fromSlot, toSlot)
Returns: boolean.
CanSwapItems
True if a fromItem ↔ toItem swap (inventory gives fromItem, receives toItem) would still fit under its max weight.
exports.one_inventory:CanSwapItems(inv, fromItem, fromCount, toItem, toCount)
Returns: boolean.
Item-level writes
SetItemDurability
Overwrite the durability percent on a single slot (0-100). Updates the degrade timestamp.
exports.one_inventory:SetItemDurability(inv, slot, value)
0 and 100.Returns: boolean.
SetItemMetadata
Replace the metadata table on a single slot (full overwrite, not a merge).
exports.one_inventory:SetItemMetadata(inv, slot, metadata)
Returns: boolean.
Inventory-level writes
SetInventoryMaxWeight
Live-update the inventory's max weight (grams).
exports.one_inventory:SetInventoryMaxWeight(inv, weight)
Returns: boolean.
SetInventorySlotCount
Live-update the inventory's slot count. Items in slots beyond the new range are discarded.
exports.one_inventory:SetInventorySlotCount(inv, count)
Returns: boolean.
ClearInventory
Empty an inventory.
exports.one_inventory:ClearInventory(inv, keep, clearClothing)
true, also wipes equipped clothing and strips the ped. Silently ignored for non-player inventories.Returns: boolean, string?.
Wholesale reads
GetInventory
Full snapshot of the inventory.
exports.one_inventory:GetInventory(inv)
Returns: table | nil - { type, id, label, weight, maxWeight, maxSlots, slots, ... }.
GetInventoryItems
Flat array of every occupied slot in the inventory.
exports.one_inventory:GetInventoryItems(inv)
Returns: table[].
SearchInventory
Every slot matching query (optionally filtered by metadata).
exports.one_inventory:SearchInventory(inv, query, metadata)
==) against each slot's name.Returns: table[] - array of matching slot tables; empty when nothing matches.
GetWeightHolding
Current weight in grams stored in the inventory.
exports.one_inventory:GetWeightHolding(inv)
Returns: number.
GetWeightLeft
Remaining weight capacity in grams (maxWeight - weight).
exports.one_inventory:GetWeightLeft(inv)
Returns: number.
Definitions
GetItemDefinition
Definition by name. Resolves any definition type (item, weapon, ammo, component, backpack, clothing), not just items. The returned table carries a type field tagging which kind it is.
exports.one_inventory:GetItemDefinition(name)
Returns: table | nil - the definition with an added type field, or nil if unknown.
GetAllItemDefinitions
Every definition keyed by name. Returns all definition types (item, weapon, ammo, component, backpack, clothing), each tagged with a type field.
exports.one_inventory:GetAllItemDefinitions(filter)
'weapon' or { 'weapon', 'ammo' }. Omit (or pass an empty value) to return everything.Returns: table<string, table> - map of { [name] = definition }; each definition carries a type field.
-- every definition
local all = exports.one_inventory:GetAllItemDefinitions()
-- only weapons and ammo
local guns = exports.one_inventory:GetAllItemDefinitions({ 'weapon', 'ammo' })
Config
GetClientConfig
A copy of the shared, client-facing config table (locale, keybinds, appearance, gameplay, ...). Available on both the server and the client, and safe to expose: it carries no server-only keys.
exports.one_inventory:GetClientConfig()
Returns: table - a copy of the client-facing config. Mutating it does not affect the live config.
TriggerClientEvent) or to read directly from a client script with the client-side GetClientConfig.GetServerConfig
The server-only config table (log providers, webhooks, seed state, group permissions). Server-side only.
exports.one_inventory:GetServerConfig()
Returns: table - the server-only config.
GetClientConfig for anything a client needs.Runtime registration
Register definitions at runtime, in memory. These are never persisted: they live until one_inventory restarts, so the registering resource must re-register them on every startup. Both refuse a name already owned by a saved (database) definition.
CreateItemsDefinition
Register one or more item definitions at runtime.
exports.one_inventory:CreateItemsDefinition(items)
{ [name] = item } map.Per-item fields:
name.0.false. Set true to make the item non-stackable.Returns: boolean - false if the name is already a saved definition.
exports.one_inventory:CreateItemsDefinition({
name = 'mystery_box',
label = 'Mystery Box',
weight = 500,
description = 'Who knows what is inside.',
unique = true,
close = true,
})
RegisterShop
Register a shop at runtime. Runtime shops have no world interaction: no marker, no target zone, no NPC ped, no blip. The registering script opens them itself with OpenInventory.
exports.one_inventory:RegisterShop(shopData)
name.cash. One of cash, bank, black_money, or any item name as a custom currency.coords for multiple proximity points.name -> minGrade map ({ police = 2, sheriff = 0 })jobs, for gangs.{ name, price, count, metadata? }. A count of 0 is infinite stock.jobs, gangs, or licenses automatically marks the shop restricted. The client-side OpenInventory enforces those restrictions (plus proximity to coords); the server-side OpenInventory is forced and bypasses them, so gate it yourself.Returns: boolean - false if the name is already a saved definition.
exports.one_inventory:RegisterShop({
name = 'blackmarket',
label = 'Black Market',
currency = 'black_money',
coords = vec3(25.7, -1347.3, 29.5),
jobs = { police = 2, sheriff = 0 },
gangs = { ballas = 0 },
licenses = { 'weapon' },
inventory = {
{ name = 'lockpick', price = 250, count = 0 },
},
})
-- server-side (forced, bypasses proximity + restrictions; gate it yourself):
exports.one_inventory:OpenInventory(src, 'shop', 'blackmarket')
-- client-side (validates the shop's job/gang/license restrictions, plus
-- proximity to `coords` when one was registered):
exports.one_inventory:OpenInventory('shop', 'blackmarket')
ox_inventory compatibility
exports['ox_inventory']:RegisterShop(name, data) still works; data.groups maps to jobs. Open it with:
exports['ox_inventory']:openInventory('shop', { type = 'blackmarket' })
Persistence
SaveInventory
Flush an inventory to the database immediately.
exports.one_inventory:SaveInventory(inv)
Returns: boolean.
SaveAllInventories
Flush every loaded inventory to the database: players, stashes, drops, vehicle trunks, vehicle gloveboxes, and dumpsters.
exports.one_inventory:SaveAllInventories()
Returns: boolean.
Hooks
RegisterHook
Subscribe to a beforeX cancellable hook. See Hooks for the full list of hook names and payloads.
local id = exports.one_inventory:RegisterHook(event, fn)
beforeItemAdd).function(payload): boolean?. Return false to cancel; mutate payload fields to change them.Returns: number - hook id; pass to RemoveHook to unsubscribe.
RemoveHook
Unsubscribe a previously-registered hook.
exports.one_inventory:RemoveHook(id)
Returns: boolean - true if a hook with that id was removed.
Open / force-open
OpenInventory
Server-forced open. Routes the call to the target client and bypasses every security check the client-side OpenInventory would normally enforce (distance, lock, in-vehicle, access restrictions, identifier match).
The user can still fully interact with whatever is opened: move items, buy from a forced shop, craft at a forced bench, and so on. The client-side OpenInventory export preserves all these checks; only this server export is forced.
exports.one_inventory:OpenInventory(source, invType, data)
stash, shop, crafting, drop, vehicle:trunk, vehicle:glovebox, player, license.invType (see below).Returns: boolean - true if the open event was dispatched, false on bad input.
backpack and dumpster are not supported here. Backpacks open from inside an inventory; dumpsters open via the world interaction loop.Data fields (per invType)
invType | Data |
|---|---|
stash | { id, owner?, slots?, maxWeight?, label?, groups? } - slots / maxWeight apply on auto-create AND live-resize |
shop | '<shop name>' |
crafting | '<bench name>' |
drop | '<drop id>' |
vehicle:trunk | <vehicle netId> |
vehicle:glovebox | <vehicle netId> |
player | <target server id> |
license | '<license name>' |
Examples
The owner field controls how the stash contents are isolated. groups optionally gates access by job. slots, maxWeight, and label apply on auto-create AND resize an already-loaded stash live, so you can grow or shrink a stash from a script without restarting it.
owner | Flavour | Behaviour |
|---|---|---|
omit / false | Shared | One bucket. Everyone with access sees the same contents. |
true | Per-player | Per-opener private bucket, keyed automatically by the opener's identifier. |
'<identifier>' | Owned | Forced owner identifier - server bypasses the ownership check. |
exports.one_inventory:OpenInventory(source, 'stash', { id = 'evidence_locker' })
exports.one_inventory:OpenInventory(source, 'stash', {
id = 'personal_storage',
owner = true,
})
exports.one_inventory:OpenInventory(source, 'stash', {
id = 'police_armory',
groups = { { name = 'police', minGrade = 0 } },
})
-- Auto-creates a 100-slot warehouse OR live-resizes one that already exists.
exports.one_inventory:OpenInventory(source, 'stash', {
id = 'warehouse',
label = 'Warehouse',
slots = 100,
maxWeight = 200000,
})
exports.one_inventory:OpenInventory(source, 'shop', 'ammunation')
exports.one_inventory:OpenInventory(source, 'crafting', 'workbench')
local netId = NetworkGetNetworkIdFromEntity(vehicle)
exports.one_inventory:OpenInventory(source, 'vehicle:trunk', netId)
exports.one_inventory:OpenInventory(source, 'vehicle:glovebox', netId)
exports.one_inventory:OpenInventory(source, 'drop', 'drop_xxx')
exports.one_inventory:OpenInventory(source, 'player', targetSource)
exports.one_inventory:OpenInventory(source, 'license', 'weapon_license')
Drops
CreateDrop
Spawn a ground drop at coords pre-populated with items.
exports.one_inventory:CreateDrop(coords, items, options)
{ x, y, z } for the drop.{ name, count?, metadata? }.{ instance = number } to scope the drop to a routing bucket.Returns: string | false - drop id, or false on failure.
DropInventory
Dump a player's entire inventory into a ground drop at their coords, then clear it.
exports.one_inventory:DropInventory(inv)
false.Returns: string | false - drop id, or false if the inventory is empty / can't be dumped.
Inspect, confiscate, restore
InspectInventory
Open a read-only view of another player's inventory on the inspector's client. Skips the distance gate.
exports.one_inventory:InspectInventory(inv, target)
false.false.Returns: boolean.
ConfiscateInventory
Move a player's inventory into DB escrow and clear it.
exports.one_inventory:ConfiscateInventory(inv)
false.Returns: boolean.
RestoreInventory
Restore a previously-confiscated inventory from DB escrow back onto the player.
exports.one_inventory:RestoreInventory(inv)
false.Returns: boolean.
Vehicles
UpdateVehiclePlate
Migrate trunk + glovebox storage rows from an old plate to a new plate.
exports.one_inventory:UpdateVehiclePlate(oldPlate, newPlate)
Returns: boolean.
Weapons
DisarmPlayer
Unequip the player's currently-equipped weapon. The item stays in the inventory.
exports.one_inventory:DisarmPlayer(inv)
false.Returns: boolean.
RemoveWeapons
Remove every weapon-typed item from the player's inventory and disarm them.
exports.one_inventory:RemoveWeapons(inv)
false.Returns: boolean.
