Guía de ox_inventory: cómo instalarlo y agregar items
Aprende a instalar ox_inventory y a agregar items personalizados: campos de items.lua, imágenes, items usables, metadata y errores comunes en FiveM.
· 12 min de lectura
ox_inventory es el inventario por slots de Overextended, el equipo detrás de ox_lib y ox_target. Reemplaza los sistemas de items, inventario y armas que trae tu framework con un solo resource que maneja inventarios de jugadores, stashes, shops, maleteros, guanteras y drops, y valida en el servidor cada movimiento de items. Es el inventario por defecto en Qbox y una mejora muy popular en ESX.
En esta guía vemos qué soporta ox_inventory, cómo instalarlo y, sobre todo, cómo agregar items en ox_inventory: los campos de data/items.lua, las imágenes de los items, cómo hacer un item usable, cómo dar items desde código, la metadata y los errores con los que más te vas a topar.
Versión corta: instala oxmysql y ox_lib, descarga el release
ox_inventory.zip, configurainventory:frameworkenserver.cfge inícialo justo después de tu framework. Para agregar un item, defínelo endata/items.lua, pon un<item_name>.pngenweb/images/, reinicia y dalo conexports.ox_inventory:AddItem(source, 'item_name', 1).
Qué soporta ox_inventory
ox_inventory se comunica con tu framework mediante un bridge, que eliges con la convar inventory:framework. Los frameworks con soporte oficial son:
| Framework | Valor de la convar | Notas |
|---|---|---|
| ox_core | ox | El framework propio de Overextended |
| ESX Legacy | esx | Requiere ESX Legacy 1.6.0 o superior. También es el valor por defecto si no configuras la convar |
| Qbox | qbx | Qbox está construido alrededor de ox_inventory |
| ND Core | nd |
QBCore no está en la lista. El release actual solo trae bridges para ox, ESX, Qbox y ND. Si usas QBCore y quieres ox_inventory, lo más práctico es pasarte a Qbox, que corre la mayoría de los scripts de QBCore con su propio bridge. Revisa Qbox vs QBCore vs ESX para ver los pros y contras.
Tampoco hay modo standalone. Sin un framework soportado, tienes que escribir tu propio módulo de bridge, algo que la documentación describe como posible pero sin soporte.
Ten en cuenta también que ox_inventory trata las armas como items y no usa loadouts. Los scripts que dependen del comportamiento del inventario por defecto del framework, como esx_shops o esx_trunkinventory, van a chocar con él.
Cómo instalar ox_inventory
Necesitas un servidor con OneSync activado y dos dependencias:
- oxmysql para la base de datos
- ox_lib para la UI, los callbacks y utilidades
ox_target es opcional, pero recomendado para shops y stashes con zonas de interacción.
- Descarga
ox_inventory.zipdesde el último release en GitHub. No uses la descarga "Source code"; no incluye la UI compilada. - Extráelo en tu carpeta
resourcesde modo que la carpeta se llameox_inventory. - Configura la convar del framework y el orden de inicio en
server.cfg:
setr inventory:framework "qbx" # or "esx", "ox", "nd"
start oxmysql
start ox_lib
start qbx_core # your framework
start ox_target
start ox_inventoryLa configuración va en convars, no en un archivo de config. Las primeras que vas a tocar:
setr inventory:slots 50 # player inventory slots
setr inventory:weight 30000 # max carry weight, in grams
setr inventory:target true # use ox_target for shops and stashes
setr inventory:keys ["F2", "K", "TAB"]¿Vienes de ESX? Arranca el servidor una vez y ejecuta convertinventory esx en la consola del servidor para convertir los inventarios de los jugadores, luego reinicia. Si tu base de datos de ESX tiene una tabla items, ox_inventory copia a data/items.lua los items que todavía no conoce y te pide reiniciar.
Si estás armando un servidor desde cero, Cómo crear un servidor de FiveM te explica primero txAdmin y los recipes de framework.
Cómo agregar un item personalizado
Todo item tiene que estar definido en ox_inventory/data/items.lua antes de poder existir en cualquier inventario. El archivo retorna una tabla: la key es el spawn name del item (por convención, en minúsculas y sin espacios) y el valor son las opciones del item.

El item válido más simple:
['gold_ring'] = {
label = 'Anillo de oro',
weight = 20,
},Campos del item
Estos son los campos documentados para data/items.lua. El peso va en gramos.
| Campo | Tipo | Qué hace |
|---|---|---|
label | string | Nombre que se muestra. Obligatorio |
weight | number | Peso de una unidad, en gramos |
stack | boolean | Ponlo en false para que el item no se apile en un slot |
close | boolean | Ponlo en false para que el inventario siga abierto después de usarlo |
description | string | Texto que aparece en el tooltip del item |
consume | number | Cuántos se quitan al usarlo. Por defecto 1. Un decimal como 0.2 quita 20% de durabilidad en su lugar. 0 no quita nada |
degrade | number | Minutos hasta que el item se degrada por completo |
decay | boolean | Borra el item cuando la durabilidad llega a 0 |
allowArmed | boolean | Permite usarlo con un arma en la mano |
client | table | Opciones de uso del lado del cliente (abajo) |
server | table | Opciones del lado del servidor, principalmente export |
buttons | table | Acciones extra en el menú contextual del clic derecho, cada una con label y action(slot) |
La tabla client controla lo que pasa del lado del jugador cuando usa el item:
| Campo | Qué hace |
|---|---|
usetime | Duración de la barra de progreso en milisegundos |
anim | { dict = '...', clip = '...' } que se reproduce durante la barra de progreso |
prop | Prop adjunto: model, pos, rot, y opcionalmente bone y rotOrder |
disable | Controles desactivados durante el uso: move, car, combat, mouse, sprint |
cancel | Permite que el jugador cancele la barra de progreso |
export | Export del cliente que se llama al usarlo, con el formato 'resourceName.exportName' |
event | Evento del cliente que se dispara después de usarlo |
status | Cambios de status después de usarlo (hambre, sed y similares) |
add / remove | Funciones que se llaman cuando el jugador gana o pierde el item, y reciben el nuevo total |
Un ejemplo completo
Aquí tienes una bebida energética que reproduce una animación de tomar con una lata en la mano y después da un pequeño boost de velocidad al correr. Está basada en el item sprunk que viene con ox_inventory.
['energy_drink'] = {
label = 'Bebida energética',
weight = 350,
stack = true,
close = true,
description = 'Corre un poco más rápido por un rato.',
client = {
anim = { dict = 'mp_player_intdrink', clip = 'loop_bottle' },
prop = {
model = `prop_ld_can_01`,
pos = vec3(0.01, 0.01, 0.06),
rot = vec3(5.0, 5.0, -180.5)
},
usetime = 2500,
export = 'my_items.energy_drink',
},
},El prop tiene que ser un modelo que el juego pueda cargar. Si quieres una lata o herramienta personalizada en la mano del jugador, primero tienes que hacerle stream; Props personalizados para FiveM explica cómo.
Imágenes de los items
Las imágenes de los items van en ox_inventory/web/images/, con el nombre exacto de la key del item:
![]()
ox_inventory/web/images/energy_drink.png
Lo que tienes que saber:
- Usa PNG. La UI arma la ruta como
<name>.png, y elfxmanifest.luadel resource solo incluyeweb/images/*.png. Un.webpo.jpgno va a cargar. - Tamaño: las imágenes que vienen con ox_inventory son de 100 x 100 píxeles con fondo transparente. Usa ese tamaño para que se vea todo consistente.
- Los nombres distinguen mayúsculas y minúsculas en hosts Linux.
Energy_Drink.pngno esenergy_drink.png. - Puedes cambiar la ruta base con la convar
inventory:imagepathsi alojas las imágenes en otro lugar.
Si no tienes un ícono, el generador de imágenes de BLDR puede crear uno a partir de un prompt de texto; pide un solo objeto con fondo transparente y después redimensiónalo a 100 x 100.
Cómo hacer un item usable
ox_inventory te da tres formas de ejecutar código cuando se usa un item. Elige una por item.
1. Export del cliente (la que recomienda la documentación)
Configura client.export en el item y después define ese export en tu propio resource. Tu función recibe los datos del item y el slot, decide si el item se puede usar y le devuelve el control a ox_inventory con useItem. Esa llamada corre las validaciones del servidor, reproduce la barra de progreso, la animación y el prop, y quita el item.
-- my_items/client.lua
exports('energy_drink', function(data, slot)
if IsPedInAnyVehicle(cache.ped, false) then
return lib.notify({ type = 'error', description = 'No mientras manejas' })
end
exports.ox_inventory:useItem(data, function(data)
if not data then return end
SetRunSprintMultiplierForPlayer(cache.playerId, 1.2)
lib.notify({ description = 'Te sientes acelerado' })
SetTimeout(30000, function()
SetRunSprintMultiplierForPlayer(cache.playerId, 1.0)
end)
end)
end)La tabla cache viene de ox_lib, así que agrega shared_script '@ox_lib/init.lua' al fxmanifest.lua de tu resource. Si useItem devuelve nil en data, el servidor rechazó el uso y el item no se consume.
2. Export del servidor
En su lugar, configura server.export = 'my_items.energy_drink' y el export se llama en el servidor con un nombre de evento. Devuelve false durante usingItem para bloquear el uso.
-- my_items/server.lua
exports('energy_drink', function(event, item, inventory, slot, data)
if event == 'usingItem' then
-- validaciones antes de usarlo; devuelve false para cancelar
end
if event == 'usedItem' then
-- el item se usó y se consumió
end
end)3. Items usables del framework
Si un item no tiene opciones de uso en client, ni server.export, ni valor de consume, ox_inventory le pasa el uso a tu framework. El código que ya tienes sigue funcionando:
- ESX:
ESX.RegisterUsableItem('energy_drink', function(source) ... end) - Qbox:
exports.qbx_core:CreateUseableItem('energy_drink', function(source, item) ... end)
La documentación aclara que el sistema integrado es más seguro y te da la barra de progreso, las animaciones y los props gratis, así que para items nuevos mejor usa las opciones 1 o 2.
Cómo dar y quitar items
Todos los cambios de items pasan en el servidor. Primero revisa la capacidad y después agrega:
local ox_inventory = exports.ox_inventory
local function giveEnergyDrink(source, count)
if not ox_inventory:CanCarryItem(source, 'energy_drink', count) then
return false
end
local success, response = ox_inventory:AddItem(source, 'energy_drink', count)
if not success then
print(('AddItem failed: %s'):format(response))
end
return success
endAddItem devuelve false más un motivo como invalid_item (el item no está en items.lua), invalid_count o invalid_inventory.
Otros exports del servidor que vas a usar todo el tiempo:
| Export | Para qué sirve |
|---|---|
RemoveItem(inv, item, count, metadata, slot) | Quitar items |
GetItemCount(inv, itemName, metadata) | Contar cuántos tiene un jugador |
Search(inv, 'count', items) | Contar varios items en una sola llamada |
CanCarryItem(inv, item, count, metadata) | Revisar peso y slots libres |
El argumento inv acepta el server id de un jugador, el id de un stash o una tabla con id y owner.
Metadata
La metadata permite que una sola definición de item se comporte como muchos items distintos. Es una tabla que va pegada a cada slot y se pasa como cuarto argumento de AddItem:
exports.ox_inventory:AddItem(source, 'gold_ring', 1, {
label = 'Anillo de oro grabado',
description = 'Para M, por siempre.',
engraving = 'M + J',
})Algunas keys son especiales: label, weight, description, image (un nombre de archivo en la carpeta de imágenes, sin .png) e imageurl sobrescriben lo que ve el jugador, y type aparece en la esquina del tooltip. Cualquier otra key se guarda y tus scripts la pueden leer. Para mostrar keys personalizadas en el tooltip, llama el export del cliente exports.ox_inventory:displayMetadata({ engraving = 'Grabado' }).
Los items con degrade reciben automáticamente un valor durability en la metadata.
Shops y stashes, en resumen
Los shops se definen en data/shops.lua con un nombre, una lista inventory de entradas { name = 'item', price = 10 }, y locations o targets. También puedes registrarlos en runtime desde el servidor con exports.ox_inventory:RegisterShop(name, data), aunque los shops creados en runtime no tienen blips ni zonas de target.
Los stashes se registran en el servidor y se abren en el cliente:
-- servidor
exports.ox_inventory:RegisterStash('mechanic_parts', 'Piezas de mecánico', 50, 100000, false, { mechanic = 0 })
-- cliente
exports.ox_inventory:openInventory('stash', 'mechanic_parts')Los argumentos son id, label, slots, peso máximo, owner y groups. Un owner en true le da a cada jugador su propia copia; false crea un solo stash compartido.
Errores comunes y cómo arreglarlos
| Síntoma | Causa probable |
|---|---|
UI has not been built | Descargaste el source code. Usa el asset ox_inventory.zip del release |
No such export ... in resource ox_inventory | ox_inventory no pudo arrancar (revisa la consola justo arriba), o tu script inicia antes que él |
| El item no muestra imagen | El archivo no es .png, el nombre no coincide con la key del item o cambian las mayúsculas |
AddItem devuelve invalid_item | Error de tipeo en el nombre del item, o editaste items.lua sin reiniciar |
| El item no hace nada al usarlo | No hay client.export, server.export ni handler de item usable del framework registrado, o el nombre del export no coincide con 'resource.export' |
| Se pierde el contenido de stashes o maleteros al reiniciar | El servidor se mató en vez de reiniciarse desde txAdmin. Los inventarios se guardan cada 5 minutos, en los reinicios de txAdmin y con el comando de consola saveinv |
| Inventario de ESX vacío después del cambio | No se ejecutó convertinventory esx, o no se reinició el servidor después |
Confirma también que inventory:framework coincida con tu framework. El valor por defecto es esx, así que un servidor Qbox sin la convar va a fallar de formas bastante confusas.
Escribe scripts de items más rápido
La mayoría de los items personalizados siguen el mismo patrón: una entrada en items.lua, una imagen y un export de cliente o servidor con el efecto. El generador de scripts de BLDR conoce Qbox, QBCore, ESX, ox_lib, ox_target y ox_inventory, así que puedes describir un item y su efecto y obtener Lua que usa useItem y las llamadas correctas del framework desde el principio.
Preguntas frecuentes
¿ox_inventory funciona con QBCore?
No de forma oficial. El release actual soporta ox_core, ESX, Qbox y ND Core. Los servidores QBCore que quieren ox_inventory normalmente se pasan a Qbox, que mantiene funcionando la mayoría de los scripts de QBCore con su bridge de compatibilidad.
¿Tengo que reiniciar el servidor después de agregar un item?
Sí. data/items.lua se lee cuando arranca ox_inventory, así que los items nuevos o modificados solo aparecen después de reiniciar.
¿Dónde pongo los items en Qbox?
En ox_inventory/data/items.lua, igual que en cualquier otro framework. Qbox usa ox_inventory como su sistema de items, así que no hay un archivo aparte de shared items que editar.
¿Puedo hacer un item que abra su propio almacenamiento, como una mochila?
Sí. En ox_inventory se llaman containers. Define el item con stack = false y después configura sus slots y peso máximo en modules/items/containers.lua o con el export del servidor setContainerProperties.