One Studios
Server

Exports

Server-side 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.

FormResolves to
123Player 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.

TypeAuto-creates?Defaults
stash:*yes50 slots / 50 000 g
trunk:*yes30 slots / 80 000 g
glovebox:*yes5 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)
inv
string | number required
Inventory to operate on. See Inventory identifiers.
item
string required
Item name.
count
number
Defaults to 1.
metadata
table
Metadata override merged with definition defaults.
slot
number
Force the item into a specific slot.
Auto-creates stash:*, trunk:*, and glovebox:* inventories if they don't exist yet. See Auto-create on first call.
Serial-less weapons: pass 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)
inv
string | number required
Inventory to operate on. See Inventory identifiers.
item
string required
count
number
Defaults to 1.
metadata
table
Metadata filter (only removes slots whose metadata matches).
slot
number
Restrict removal to this slot only.

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)
inv
string | number required
Inventory to operate on. See Inventory identifiers.
item
string required
count
number required
Target total count (0 to remove all).
metadata
table
Metadata filter for matching slots.
Auto-creates 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)
inv
string | number required
Inventory to operate on. See Inventory identifiers.
item
string required
metadata
table

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)
inv
string | number required
Inventory to operate on. See Inventory identifiers.

Returns: number.


HasItem

True when the inventory holds at least count of the item.

exports.one_inventory:HasItem(inv, item, count, metadata)
inv
string | number required
Inventory to operate on. See Inventory identifiers.
count
number
Defaults to 1.

Returns: boolean.

Slot lookup

GetSlot

Slot data at a given slot index.

exports.one_inventory:GetSlot(inv, slot)
inv
string | number required
Inventory to operate on. See Inventory identifiers.

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)
inv
string | number required
Inventory to operate on. See Inventory identifiers.

Returns: number | nil.


GetSlotIdWithItem

First slot index that contains the item, optionally filtered by metadata.

exports.one_inventory:GetSlotIdWithItem(inv, item, metadata)
inv
string | number required
Inventory to operate on. See Inventory identifiers.

Returns: number | nil.


GetSlotIdsWithItem

Every slot index that contains the item.

exports.one_inventory:GetSlotIdsWithItem(inv, item, metadata)
inv
string | number required
Inventory to operate on. See Inventory identifiers.

Returns: number[].


GetItemSlots

Map of { [slotId] = count } for every slot containing the item.

exports.one_inventory:GetItemSlots(inv, item)
inv
string | number required
Inventory to operate on. See Inventory identifiers.

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)
inv
string | number required
Inventory to operate on. See Inventory identifiers.

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)
inv
string | number required
Player to read. Non-player inventories return 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)
inv
string | number required
Inventory to operate on. See Inventory identifiers.
count
number
Defaults to 1.

Returns: boolean.


CanCarryWeight

True if the inventory can take an additional weight grams.

exports.one_inventory:CanCarryWeight(inv, weight)
inv
string | number required
Inventory to operate on. See Inventory identifiers.

Returns: boolean.


GetCarryableCount

Max additional units of the item that still fit (math.huge for zero-weight items).

exports.one_inventory:GetCarryableCount(inv, item)
inv
string | number required
Inventory to operate on. See Inventory identifiers.

Returns: number.


SwapSlots

Swap the contents of two slots within the same inventory.

exports.one_inventory:SwapSlots(inv, fromSlot, toSlot)
inv
string | number required
Inventory to operate on. See Inventory identifiers.

Returns: boolean.


CanSwapItems

True if a fromItemtoItem swap (inventory gives fromItem, receives toItem) would still fit under its max weight.

exports.one_inventory:CanSwapItems(inv, fromItem, fromCount, toItem, toCount)
inv
string | number required
Inventory to operate on. See Inventory identifiers.

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)
inv
string | number required
Inventory to operate on. See Inventory identifiers.
value
number required
Durability between 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)
inv
string | number required
Inventory to operate on. See Inventory identifiers.

Returns: boolean.

Inventory-level writes

SetInventoryMaxWeight

Live-update the inventory's max weight (grams).

exports.one_inventory:SetInventoryMaxWeight(inv, weight)
inv
string | number required
Inventory to operate on. See Inventory identifiers.

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)
inv
string | number required
Inventory to operate on. See Inventory identifiers.

Returns: boolean.


ClearInventory

Empty an inventory.

exports.one_inventory:ClearInventory(inv, keep, clearClothing)
inv
string | number required
Inventory to operate on. See Inventory identifiers.
keep
string[]
Optional array of item names to preserve.
clearClothing
boolean
Player only. When 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)
inv
string | number required
Inventory to read. See Inventory identifiers.

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)
inv
string | number required
Inventory to read. See Inventory identifiers.

Returns: table[].


SearchInventory

Every slot matching query (optionally filtered by metadata).

exports.one_inventory:SearchInventory(inv, query, metadata)
inv
string | number required
Inventory to search. See Inventory identifiers.
query
string required
Item name to match. Compared exactly (==) against each slot's name.
metadata
table
Optional metadata filter. A slot matches only when, for every key in this table, the slot's metadata holds the same value (shallow equality). Omit to match the item regardless of metadata.

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)
inv
string | number required
Inventory to read. See Inventory identifiers.

Returns: number.


GetWeightLeft

Remaining weight capacity in grams (maxWeight - weight).

exports.one_inventory:GetWeightLeft(inv)
inv
string | number required
Inventory to read. See Inventory identifiers.

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)
name
string required
Definition 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)
filter
string | string[]
Narrow to one or more types, e.g. '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.

Safe to forward to a client (e.g. via 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.

Keep this server-side. It holds secrets (webhooks, log providers, ...) that must never reach a client. Use 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.

Runtime definitions appear read-only in the admin panel, tagged with the resource that registered them, and vanish on an inventory restart.

CreateItemsDefinition

Register one or more item definitions at runtime.

exports.one_inventory:CreateItemsDefinition(items)
items
table required
A single item table, an array of item tables, or a { [name] = item } map.

Per-item fields:

name
string required
Item name.
label
string
Defaults to name.
weight
number
Grams. Defaults to 0.
description
string
image
string
useTime
number
consume
number
degrade
number
unique
boolean
Defaults to false. Set true to make the item non-stackable.
close
boolean
Close the inventory on use.

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
string required
Shop name.
label
string
Defaults to name.
currency
string
Defaults to cash. One of cash, bank, black_money, or any item name as a custom currency.
coords
vector3
Optional. Nothing is drawn for it. Saved purely as a security check.
locations
table[]
Optional. Array form of coords for multiple proximity points.
jobs
table | string | string[]
Optional. Job restriction. A name -> minGrade map ({ police = 2, sheriff = 0 })
gangs
table | string | string[]
Optional. Same shape as jobs, for gangs.
licenses
string | string[]
Optional. A license name or an array of license names.
inventory
table[]
The shop's items. Each entry: { name, price, count, metadata? }. A count of 0 is infinite stock.
Setting any of 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)
inv
string | number required
Inventory to flush. See Inventory identifiers.

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)
event
string required
Hook name (e.g. beforeItemAdd).
fn
function required
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)
source
number required
Server ID of the target client to open on.
invType
string required
One of stash, shop, crafting, drop, vehicle:trunk, vehicle:glovebox, player, license.
data
string | number | table required
Identifier shorthand or full data table - meaning varies by 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)

invTypeData
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.

ownerFlavourBehaviour
omit / falseSharedOne bucket. Everyone with access sees the same contents.
truePer-playerPer-opener private bucket, keyed automatically by the opener's identifier.
'<identifier>'OwnedForced 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,
})

Drops

CreateDrop

Spawn a ground drop at coords pre-populated with items.

exports.one_inventory:CreateDrop(coords, items, options)
coords
vector3 | table required
World coordinates { x, y, z } for the drop.
items
table[] required
Array of { name, count?, metadata? }.
options
table
Optional. { 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)
inv
string | number required
Player to dump. Non-player inventories return 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)
inv
string | number required
Inspecting player. Non-player inventories return false.
target
string | number required
Target player to inspect. Non-player inventories return false.

Returns: boolean.


ConfiscateInventory

Move a player's inventory into DB escrow and clear it.

exports.one_inventory:ConfiscateInventory(inv)
inv
string | number required
Player to confiscate. Non-player inventories return false.

Returns: boolean.


RestoreInventory

Restore a previously-confiscated inventory from DB escrow back onto the player.

exports.one_inventory:RestoreInventory(inv)
inv
string | number required
Player to restore. Non-player inventories return 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)
inv
string | number required
Player to disarm. Non-player inventories return false.

Returns: boolean.


RemoveWeapons

Remove every weapon-typed item from the player's inventory and disarm them.

exports.one_inventory:RemoveWeapons(inv)
inv
string | number required
Player to strip. Non-player inventories return false.

Returns: boolean.