ATY Scripts Logo
ATY Scripts/Docs/Inventory/Items & Metadata

Items & Metadata

Items & Metadata

Items are defined once, in data/items.lua, and read by both sides. The NUI never invents item data and never trusts what the client sends.

Definition fields

weapon_pistol = {
    label       = 'Pistol',
    weight      = 1100,            -- ALWAYS grams
    stack       = false,           -- one per slot
    category    = 'weapon',
    rarity      = 'rare',
    description = 'Standard semi-automatic pistol.',
    durability  = true,
}
Field Meaning
label Display name
weight Grams. The server computes in grams everywhere
stack false never merges · absent uses Config.UI.maxStack · N caps at exactly N. false is for items that must be told apart — a weapon, a container, anything with durability — not a way to say rare
category weapon ammo consumable medical tool clothing valuable document container misc
rarity common uncommon rare epic legendary — visual only
description One line in the detail column
image Override; defaults to images/<name>.webp, then .png (see Images)
usable Override for whether "Use" appears
durability Created at 100 and wears down
effect What using it does — see Consumables
cooldown ms before this item can be used again
useTime ms one use takes. The portion is spent when it finishes
portions How many uses one unit is worth. Read only while Config.Portions.enabled is on (off by default, as ox_inventory)
cancel true = the action bar can be cancelled with the cancel key; absent = it cannot (ox client.cancel)
disable { move, sprint, car, combat } the player cannot do while using it; combat is off during every use unless set false (ox client.disable)
close false = using it leaves the inventory open; absent = it closes (ox close)

Serial numbers

Any item that cannot stack gets a ULID when it is created — a sortable, unique id that stays with that specific unit for its whole life.

invtrace <uid>

prints where it was born, every hand it passed through, and where it is now.

Stackable items do not get serials, and should not. Six identical bandages are six of a thing, not six things — giving them individual identity would triple the ledger for no answerable question.

Metadata

Beyond durability and serials, a unit can carry arbitrary metadata: a weapon's registered owner and attachments, a note's text, a licence's issue date.

exports.aty_inventory:SetMetadata(inv, slot, {
    registered = 'John Miller',
    components = { 'suppressor', 'flashlight' },
})

Metadata travels with the unit through every move, and differing metadata is what keeps two otherwise-identical items in separate slots.

Where definitions can come from

Source When
data/items.lua The resource's own list — the file a developer edits
The framework QBCore / ESX shared items, read through the bridge
Admin panel → Definitions Live field edits, stored in aty_overrides

A panel edit is an override on a single field, not a second catalogue. Nothing there ever writes to data/items.lua, and the panel shows the file value beside the live one — the moment two records disagree without showing it, nobody can say which one the server is running.

Framework items work as they are. invmigrate items write writes them to data/items.generated.lua; list that file in fxmanifest.lua's shared_scripts after data/items.lua and this resource owns them, no longer depending on the framework being up. Items already in data/items.lua are skipped — the file here wins.

An adopted item is one-per-slot only when its own catalogue says so — qb's unique, ox's stack = false. qb's rare is about value, not storage, and is not read as uniqueness. Items already stored under an older rule are brought up to date with invrestack confirm, which repairs loaded bags as well as stored ones.

Images

Drop a WebP or PNG named after the item into ui/images/. The interface tries, in order:

  1. the definition's image
  2. images/<name>.webp, then images/<name>.png
  3. each entry of Config.UI.imageFallback — another resource's art, %s standing for the item name
  4. a placeholder
Config.UI.imageFallback = {
    'nui://qb-inventory/html/images/%s.png',
    'nui://ox_inventory/web/images/%s.png',
}

Adopting a framework's catalogue adopts hundreds of names and none of their art; the inventory they came from usually still holds the pictures. Point the list at wherever that folder lives on your server. A file in ui/images/ always wins, because it is tried first.

scripts/collect-item-images.py copies matching pictures from the rest of the server into ui/images/.

invdoctor

reports how many items have no picture and writes the full list to data/missing-images.txt.

ATY Scripts LogoATY SCRIPTS

Crafting highly optimized FiveM scripts for QBCore & ESX. Maximum performance, precision code, zero lag.

Join Community

Partner

Official partners with Tebex. Secure checkout and Cfx.re Keymaster integration.

Legal

Not affiliated with Rockstar Games, Cfx.re, FiveM, or Take-Two Interactive. Purchases bound by Tebex Terms of Service.

© 2026 ATY SCRIPTS. All rights reserved.