Convertir un script de QBCore a QBox: qbx_core, ox_inventory, ox_target

Cómo portar un script de QBCore a QBox: la capa de compatibilidad qbx_core, GetPlayer, objetos de ox_inventory, notificación y progreso de ox_lib, ox_target, y qué normalmente se rompe.

Tienes un script escrito para QBCore y un servidor ejecutando QBox. A veces inicia y funciona, a veces la consola se llena de errores sobre un qb-inventory, qb-target o qb-menu faltante. Aquí está el orden para portarlo, y los lugares donde normalmente se rompe.

Si aún estás eligiendo un core, el mismo trabajo desde la otra dirección está en convertir un script de ESX a QBCore.

Qué cambia QBox y qué mantiene

QBox se basa en qbx_core más los recursos Overextended: ox_lib, oxmysql, ox_inventory y ox_target. Mantiene una capa de compatibilidad, así exports['qb-core']:GetCoreObject() aún responde y PlayerData tiene la misma forma (citizenid, job, charinfo, metadata, money). Por eso muchos scripts se ejecutan sin cambios.

Lo que no mantiene son los antiguos recursos de utilidad QB. Donde QBCore usaba qb-inventory, qb-target, qb-menu, qb-input y qb-progressbar, QBox espera ox_inventory, ox_target y ox_lib. Esas son las partes que portas.

El primer paso es asegurar que el core se inicia correctamente:

cfg
ensure oxmysql
ensure ox_lib
ensure qbx_core
ensure ox_inventory
ensure ox_target
ensure my_script

Elimina cualquier carpeta de qb-core sobrante, ya que dos cores entran en conflicto. Ver QBCore is nil: GetCoreObject si el objeto falta.

Paso 1: dependencias en el manifest

lua
fx_version 'cerulean'
game 'gta5'
lua54 'yes'

shared_script '@ox_lib/init.lua'

dependencies { 'qbx_core', 'ox_lib', 'ox_inventory', 'ox_target' }

@ox_lib/init.lua es lo que te da el global lib. Si no se encuentra, ver ox_lib init.lua not found.

Paso 2: obtener el jugador

Ambos funcionan en QBox. El primero es el estilo de compatibilidad, el segundo es la forma de QBox:

lua
-- QBCore style (still works through the compatibility layer)
local QBCore = exports['qb-core']:GetCoreObject()
local Player = QBCore.Functions.GetPlayer(source)

-- QBox style
local player = exports.qbx_core:GetPlayer(source)
if player then
    print(player.PlayerData.citizenid, player.PlayerData.job.name)
end

Ambos devuelven nil para un jugador que no está cargado, así que mantén la verificación de nil. Para encontrar un jugador cargado por id de ciudadano, QBox también tiene GetPlayerByCitizenId. Cuando portes, puedes dejar las llamadas de QBCore en su lugar y reemplazarlas una a una después.

Paso 3: inventario

Aquí es donde la mayoría de scripts se rompen. qb-inventory y ox_inventory no comparten definiciones de objetos o nombres de función.

Tarea QBCore QBox con ox_inventory
Añadir un objeto Player.Functions.AddItem('water', 1) exports.ox_inventory:AddItem(source, 'water', 1)
Eliminar un objeto Player.Functions.RemoveItem('water', 1) exports.ox_inventory:RemoveItem(source, 'water', 1)
Contador Player.Functions.GetItemByName('water').amount exports.ox_inventory:GetItemCount(source, 'water')
Metadatos tabla info tabla metadata
lua
local src = source
local ok = exports.ox_inventory:AddItem(src, 'water', 2, { quality = 100 })
if not ok then
    lib.notify(src, { description = 'Your inventory is full', type = 'error' })
end

AddItem devuelve un valor falso cuando el objeto no existe o no puede ser llevado, así que compruébalo. Las definiciones de objetos también se mueven. QBCore las mantiene en qb-core/shared/items.lua, ox_inventory en ox_inventory/data/items.lua. Añade cada objeto que el script usa allí, en el formato de ox_inventory. Cómo hacerlo está en add items to ox_inventory, y el formato de QBCore del que vienes está en add items to qb-inventory.

Los objetos usables también se registran de manera diferente: QBCore.Functions.CreateUseableItem se convierte en un export establecido en la definición del objeto en ox_inventory, que apunta a una función en tu script. Las llamadas de QBCore aún pueden funcionar a través de la capa de compatibilidad, así que prueba un objeto antes de reescribirlo.

Paso 4: notificaciones, progreso y menús con ox_lib

ox_lib reemplaza los recursos separados de utilidad QB. Las llamadas están cerca de lo que conoces:

lua
-- QBCore
QBCore.Functions.Notify('Done', 'success', 5000)

-- ox_lib (client)
lib.notify({ title = 'Job', description = 'Done', type = 'success', duration = 5000 })
lua
-- QBCore: QBCore.Functions.Progressbar(...) with a callback
-- ox_lib: returns true when completed, false when cancelled
if lib.progressBar({
    duration = 5000,
    label = 'Repairing',
    useWhileDead = false,
    canCancel = true,
    disable = { car = true, move = true },
    anim = { dict = 'mini@repair', clip = 'fixing_a_ped' },
}) then
    print('finished')
else
    print('cancelled')
end

Los menús se mueven de qb-menu a lib.registerContext y lib.showContext, y los formularios de entrada de qb-input a lib.inputDialog. Ejemplos completos están en notifications and progress bars on ESX, QBCore and ox_lib y ox_lib context menus.

Paso 5: ox_target en lugar de qb-target

qb-target toma un nombre, coordenadas y una tabla de opciones en su propio diseño. ox_target toma una tabla:

lua
-- qb-target
exports['qb-target']:AddBoxZone('my_zone', vector3(215.0, -810.0, 30.7), 1.5, 1.5, {
    name = 'my_zone', heading = 0, minZ = 29.7, maxZ = 32.7,
}, {
    options = { { event = 'my_script:client:open', icon = 'fas fa-box', label = 'Open', job = 'police' } },
    distance = 2.0,
})

-- ox_target
exports.ox_target:addBoxZone({
    coords = vector3(215.0, -810.0, 30.7),
    size = vector3(1.5, 1.5, 3.0),
    rotation = 0,
    options = {
        { name = 'my_zone_open', icon = 'fas fa-box', label = 'Open', groups = 'police',
          onSelect = function() TriggerEvent('my_script:client:open') end },
    },
})

Observa que event se convierte en onSelect (o event aún funciona para un evento de cliente), y job se convierte en groups. Los detalles están en qb-target vs ox_target y ox_target zones.

Qué normalmente se rompe

  • Errores de objeto faltante. El objeto existe en el fichero compartido de qb-core pero no en el de ox_inventory. Añádelo.
  • No such export para qb-inventory, qb-target o qb-menu. El script los llama directamente: porta esas llamadas, o nunca se ejecutará.
  • Callbacks. lib.callback es el estilo de QBox. Si un script aún usa QBCore.Functions.CreateCallback, pruébalo y muévelo a ox_lib si falla: ver server callbacks.
  • Trabajos y pandillas con grados. QBox tiene sus propios datos de trabajo y grupo. Prueba cada verificación de trabajo, especialmente comparaciones en servicio y de grado.
  • Cores mixtos. Un recurso de qb-core sobrante iniciado junto a qbx_core.
  • Orden de inicio. Tu script arriba de ox_lib, ox_inventory o qbx_core en server.cfg.

Lista de verificación

Síntoma Solución
GetCoreObject es nil Inicia qbx_core primero y elimina cualquier carpeta qb-core
No such export para qb-inventory Usa exports.ox_inventory:AddItem(source, item, count)
Objeto no encontrado Añádelo a ox_inventory/data/items.lua
Las llamadas de qb-target fallan Porta a exports.ox_target:addBoxZone o addLocalEntity
lib es nil Añade shared_script '@ox_lib/init.lua'
La verificación de trabajo siempre es falsa Prueba PlayerData.job.name y grado en QBox

Respuestas rápidas

¿Funcionan los scripts de QBCore en QBox sin cambios?

Muchos lo hacen, porque qbx_core mantiene una capa de compatibilidad para qb-core. Los scripts que dependen de qb-inventory, qb-target o qb-menu normalmente necesitan trabajo, ya que QBox usa ox_inventory, ox_target y ox_lib en su lugar.

¿Cómo obtengo el jugador en QBox?

En el servidor, exports.qbx_core:GetPlayer(source) devuelve el jugador, con la misma tabla PlayerData que conoces de QBCore.

¿Tengo que reescribir todo para moverme a QBox?

No. Inicia el script en QBox, lee los errores, y reemplaza las partes que fallan: inventario, objetivo, menús y notificaciones. El resto, como PlayerData, trabajos y metadatos, mantiene su forma.

Scripts que evitan este problema

Item Creator V2Crea items usables con animaciones, props, efectos y más — sin escribir código.Ver script →Shop CreatorCrea una tienda en menos de un minuto — dueños, empleados, caja fuerte y atracos.Ver script →Quest CreatorUn editor visual de misiones y diálogos con NPC, nodo a nodo dentro del juego.Ver script →

Sigue leyendo