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, containers, drops, and dumpsters, so a dealership script can pre-fill a trunk the same way a player script tops up a container.
| 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 |
'container:<id>' | Container 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:*, container:*, dumpster:*, player:* | no | - |
Slot table format
Every export below that returns a slot returns the same standardized table.
count).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 - a slot table, 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 - a slot table, 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>.
GetContainerFromSlot
Container item at a slot.
exports.one_inventory:GetContainerFromSlot(inv, slot)
Returns: table | nil - a slot table plus slots and maxWeight, with the contents snapshot under metadata.items. nil if the slot doesn't hold a container.
GetEquippedWeapon
Currently-equipped weapon slot.
exports.one_inventory:GetEquippedWeapon(inv)
nil.Returns: table | nil - a slot table 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)
fromItem given up.toItem received.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, ... }, where each entry in slots is a slot table.
GetInventoryItems
Flat array of every occupied slot in the inventory.
exports.one_inventory:GetInventoryItems(inv)
Returns: table[] - an array of slot tables.
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, container, 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, container, 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' })
These definition lists rarely change at runtime, so most scripts call them once and cache the result. When a definition is created, edited, or deleted from any source, the one_inventory:onDefinitionsUpdated event fires (coalesced, no payload). Rebuild your cache from it:
AddEventHandler('one_inventory:onDefinitionsUpdated', function()
local defs = exports.one_inventory:GetAllItemDefinitions()
-- rebuild your cached list here
end)
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,
})
CreateContainersDefinition
Register one or more container definitions at runtime. Same runtime semantics as CreateItemsDefinition: in-memory, never persisted, refused when a saved definition already owns the name.
exports.one_inventory:CreateContainersDefinition(containers)
{ [name] = container } map.Per-container fields:
name.0.10.10000.{ name, count, metadata } entries seeded into a brand-new instance of the container.Returns: boolean - false if the name is already a saved definition.
exports.one_inventory:CreateContainersDefinition({
name = 'evidence_bag',
label = 'Evidence Bag',
weight = 200,
slots = 5,
maxWeight = 5000,
blacklist = { 'evidence_bag' },
})
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, both (the buyer picks cash or bank on each purchase), 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?, jobs?, gangs?, licenses? }. A count of 0 is infinite stock. The per-item jobs / gangs / licenses fields use the same forms as the shop-level fields and restrict that single item (the rest of the shop stays open to everyone).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 },
-- restrict a single item to police rank 2+ (the rest of the shop is unrestricted)
{ name = 'weapon_pistol', price = 5000, count = 5, jobs = { police = 2 } },
},
})
-- 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')
RegisterItemButton
Add a right-click button to an item's context menu. This server-side variant runs fn server-side when the button is clicked, with the player's source in the payload. Available on the client too (where fn runs client-side, without source).
exports.one_inventory:RegisterItemButton(itemName, label, fn)
The fn payload (server side):
Returns: boolean - false on invalid input or an unknown item.
exports.one_inventory:RegisterItemButton('water', 'Drink Water', function(payload)
-- runs server-side; payload.source is the player who clicked
print(('player %s drank from slot %s'):format(payload.source, payload.slot))
end)
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, payloads, and the post-hook event every registration also gets.
local id = exports.one_inventory:RegisterHook(event, fn, options)
beforeItemAdd).function(payload): boolean?. Return false to cancel; mutate payload fields to change them. May be omitted (nil) when options is set, for a post-events-only registration that never gates the action.Returns: number - hook id; pass to RemoveHook to unsubscribe.
RemoveHook
Unsubscribe a previously-registered hook. Scoped to the calling resource: it can only remove hooks that resource registered.
exports.one_inventory:RemoveHook(id)
RegisterHook. Omit (nil) to remove every hook registered by the calling resource.Returns: boolean - true if at least one hook 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.
container and dumpster are not supported here. Containers 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. Size overrides set with SetTrunkSize / SetGloveboxSize move to the new plate as well.
exports.one_inventory:UpdateVehiclePlate(oldPlate, newPlate)
Returns: boolean.
SetTrunkSize
Set a persistent per-plate trunk size override, for example for owned or upgraded cars. The override wins over the model/class storage definition on every open, and applies live when the trunk is already open. It is stored in the auto-created one_inv_vehicle_sizes table, so it survives server restarts, and it follows plate renames done through UpdateVehiclePlate.
exports.one_inventory:SetTrunkSize(plate, slots, maxWeight)
nil to keep the definition's slot count.nil to keep the definition's max weight.Pass nil for both slots and maxWeight to remove the override, so the plate falls back to its definition sizing.
Returns: boolean.
SetGloveboxSize
Set a persistent per-plate glovebox size override. Same semantics as SetTrunkSize.
exports.one_inventory:SetGloveboxSize(plate, slots, maxWeight)
nil to keep the definition's slot count.nil to keep the definition's max weight.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.
