Configuration

Configuration

The main configuration file is located at config.lua. This file controls general settings, rarity definitions, and lootbox contents.

General Settings

config.debug = true
 
-- Image file extension for item icons
config.imageExtension = 'webp'
 
-- Image path for item icons
config.imagePath = 'nui://ox_inventory/web/images'
 
-- Whether to automatically register lootboxes as usable items
config.registerUsableItems = true

Options Explained

OptionTypeDescription
debugbooleanEnable debug mode for development. Enables test commands.
imageExtensionstringFile extension for item images in the UI (e.g., 'webp', 'png')
imagePathstringBase path for item icon images. Defaults to 'nui://ox_inventory/web/images'. Adjust this if your inventory stores images elsewhere.
registerUsableItemsbooleanWhen true, lootboxes defined in config are automatically registered as usable items

Rarity Configuration

Define rarity tiers and their colors for UI display. Items can optionally specify a rarity, or it can be auto-calculated from weight.

config.rarities = {
    common = {
        label = 'Common',
        color = '#94999a',
        minWeight = 17,
    },
    uncommon = {
        label = 'Uncommon',
        color = '#26c057',
        minWeight = 4,
    },
    rare = {
        label = 'Rare',
        color = '#0aa7e6',
        minWeight = 1,
    },
    epic = {
        label = 'Epic',
        color = '#d02e9b',
        minWeight = 0.3,
    },
    legendary = {
        label = 'Legendary',
        color = '#ffc500',
        minWeight = 0,
    },
}
 
-- Order of rarities from most common to least common
config.rarityOrder = { 'common', 'uncommon', 'rare', 'epic', 'legendary' }

Rarity Properties

PropertyTypeDescription
labelstringDisplay name shown in the UI
colorstringHex color code for the rarity tier
minWeightnumberMinimum weight threshold for auto-calculation

The minWeight determines auto-rarity assignment. An item with weight 5 would be classified as "uncommon" because 5 >= 4 but 5 < 17.

Lootbox Definitions

Lootboxes are defined in the config.lootboxes table. Each lootbox has a unique key (item name) and contains a label, description, and items list.

Basic Structure

config.lootboxes = {
    ['lootbox_item_name'] = {
        label = 'Display Name',
        description = 'Description shown in UI',
        image = 'nui://ox_inventory/web/images/lootbox_item_name.webp', -- Optional custom image
        items = {
            -- { weight, { name = 'item_name', amount = 1 } },
        },
    },
}

Lootbox Properties

PropertyTypeRequiredDescription
labelstringYesDisplay name shown in the UI
descriptionstringNoDescription text shown in the preview UI
imagestringNoCustom image URL for the lootbox (defaults to item image)
itemstableYesArray of weighted loot items
rarityThresholdstableNoOverride global rarity thresholds for this lootbox

Item Format

Each item in the items array follows this format:

{ weight, { name = 'item_name', amount = 1, metadata = {}, rarity = 'optional' } }
PropertyTypeRequiredDescription
weightnumberYesDrop weight (higher = more common)
namestringYesItem name to give to player
amountnumberYesQuantity of item to give
metadatatableNoCustom metadata to attach to item
raritystringNoOverride auto-calculated rarity
labelstringNoCustom display label (auto-fetched from inventory if not provided)
imagestringNoCustom image URL (auto-fetched from inventory if not provided)
bonusItemstableNoAdditional items to award alongside the main reward (not shown in UI)
rewardTypestringNoCustom reward type for non-item rewards (e.g., 'vehicle', 'bank')
rewardDatatableNoCustom data passed to reward hooks (e.g., vehicle model, garage)

Complete Example

config.lootboxes = {
    ['gun_case'] = {
        label = 'Gun Case',
        description = 'Contains various firearms',
        items = {
            -- Common weapons (~80% total)
            { 40, { name = 'WEAPON_PISTOL', amount = 1 } },
            { 40, { name = 'WEAPON_SNSPISTOL', amount = 1 } },
 
            -- Uncommon weapons (~16% total)
            { 8, { name = 'WEAPON_VINTAGEPISTOL', amount = 1 } },
            { 8, { name = 'WEAPON_COMBATPISTOL', amount = 1 } },
 
            -- Rare weapons (~3.1% total)
            { 1.5, { name = 'WEAPON_HEAVYPISTOL', amount = 1 } },
            { 1.6, { name = 'WEAPON_PISTOLXM3', amount = 1 } },
 
            -- Epic weapons (~0.64% total)
            { 0.34, { name = 'WEAPON_APPISTOL', amount = 1 } },
            { 0.3, { name = 'WEAPON_MACHINEPISTOL', amount = 1 } },
 
            -- Legendary weapons (~0.26% total)
            { 0.13, { name = 'WEAPON_COMBATPDW', amount = 1 } },
            { 0.1, { name = 'WEAPON_CARBINERIFLE', amount = 1 } },
            { 0.03, { name = 'WEAPON_RPG', amount = 1 } },
        },
    },
}

Per-Lootbox Rarity Thresholds

You can override the global rarity thresholds for a specific lootbox:

['custom_case'] = {
    label = 'Custom Case',
    description = 'Has custom rarity thresholds',
    rarityThresholds = {
        common = 50,
        uncommon = 20,
        rare = 5,
        epic = 1,
        legendary = 0,
    },
    items = {
        -- items here...
    },
},

Item with Metadata

Include custom metadata that will be attached to the item when given:

{ 1, { 
    name = 'weapon_pistol', 
    amount = 1, 
    rarity = 'legendary',
    metadata = {
        serial = 'GOLD-001',
        durability = 100,
        registered = true,
    }
} }
⚠️

When using metadata, ensure your inventory system supports the metadata fields you're using.

Bonus Items

Award additional items alongside the main reward. Bonus items are not displayed in the UI - players only see the main item during the roll animation, but receive all bonus items when the reward is claimed.

{ 40, {
    name = 'WEAPON_PISTOL',
    amount = 1,
    bonusItems = {
        { name = 'ammo-9', amount = 50 },
        { name = 'armour', amount = 1 },
    }
} }

Each bonus item has the following properties:

PropertyTypeRequiredDescription
namestringYesItem spawn name
amountnumberYesQuantity to give
metadatatableNoOptional item metadata

Bonus items are great for giving ammo with weapons, or adding extra consumables as a surprise bonus without cluttering the UI.

Custom Reward Types

For rewards that aren't standard inventory items (vehicles, bank deposits, etc.), use the rewardType and rewardData fields along with the reward hook system.

For custom reward types, the name field is just a unique identifier used for internal tracking and logging - it doesn't need to be an actual item in your inventory. Since custom rewards aren't real items, you must also provide label and image explicitly.

{ 0.26, {
    name = 'vehicle_adder', -- Unique identifier, not an actual item
    label = 'Adder', -- Required: display label
    amount = 1,
    image = 'nui://ox_inventory/web/images/vehicle_crate.webp', -- Required: custom image
    rarity = 'legendary',
    rewardType = 'vehicle',
    rewardData = { model = 'adder', garage = 'legion' },
} }
⚠️

Custom reward types require a registered reward hook to handle them. If no hook is registered, the system will fall back to default item behavior and log a warning.

How Custom Rewards Work

  1. When a player wins an item with a custom rewardType, the system looks for a registered hook for that type
  2. If a hook exists and returns true, the hook handled the reward
  3. If a hook returns false/nil, the system falls back to default item behavior
  4. If no hook exists, a warning is logged and the system falls back to default item behavior

This ensures rewards are never silently lost - if something isn't configured correctly, players still receive items.

Registering Reward Hooks

Register hooks from your own resource to handle custom reward types:

-- In your server script (e.g., a vehicle management resource)
exports.sleepless_lootbox:registerRewardHook('vehicle', function(source, reward, caseName)
    local data = reward.rewardData
    -- Your vehicle spawning logic here
    -- e.g., exports['qbx_vehicles']:CreatePlayerVehicle(source, data.model, data.garage)
    
    -- Notify the player
    TriggerClientEvent('ox_lib:notify', source, {
        title = 'Vehicle Won!',
        description = 'Your ' .. reward.label .. ' has been added to your garage.',
        type = 'success'
    })
    
    return true -- Return true to indicate we handled this reward
end)
 
-- You can also register a 'bank' hook for bank money rewards
exports.sleepless_lootbox:registerRewardHook('bank', function(source, reward, caseName)
    local data = reward.rewardData
    -- Your bank deposit logic here
    -- e.g., exports['qbx_core']:AddMoney(source, 'bank', data.amount)
    return true
end)

See the Server Exports page for full API documentation.

Complete Vehicle Crate Example

Here's a complete example of a lootbox that awards vehicles using custom reward types:

['vehicle_crate'] = {
    label = 'Vehicle Crate',
    description = 'Win a brand new vehicle!',
    items = {
        -- Common vehicles (~80% total)
        { 40, {
            name = 'vehicle_blista', -- Unique identifier (not an actual item, just for internal tracking/logging)
            label = 'Blista', -- Required: display label since this isn't a real item
            amount = 1,
            image = 'nui://ox_inventory/web/images/vehicle_crate.webp', -- Required: custom image
            rewardType = 'vehicle',
            rewardData = { model = 'blista', garage = 'legion' },
        } },
        { 40, {
            name = 'vehicle_prairie', -- Unique identifier
            label = 'Prairie',
            amount = 1,
            image = 'nui://ox_inventory/web/images/vehicle_crate.webp',
            rewardType = 'vehicle',
            rewardData = { model = 'prairie', garage = 'legion' },
        } },
 
        -- Uncommon vehicles (~16% total)
        { 8, {
            name = 'vehicle_buffalo',
            label = 'Buffalo',
            amount = 1,
            image = 'nui://ox_inventory/web/images/vehicle_crate.webp',
            rewardType = 'vehicle',
            rewardData = { model = 'buffalo', garage = 'legion' },
        } },
        { 8, {
            name = 'vehicle_sultan',
            label = 'Sultan',
            amount = 1,
            image = 'nui://ox_inventory/web/images/vehicle_crate.webp',
            rewardType = 'vehicle',
            rewardData = { model = 'sultan', garage = 'legion' },
        } },
 
        -- Rare vehicles (~3.1% total)
        { 1.6, {
            name = 'vehicle_elegy2',
            label = 'Elegy RH8',
            amount = 1,
            image = 'nui://ox_inventory/web/images/vehicle_crate.webp',
            rewardType = 'vehicle',
            rewardData = { model = 'elegy2', garage = 'legion' },
        } },
        { 1.5, {
            name = 'vehicle_comet2',
            label = 'Comet',
            amount = 1,
            image = 'nui://ox_inventory/web/images/vehicle_crate.webp',
            rewardType = 'vehicle',
            rewardData = { model = 'comet2', garage = 'legion' },
        } },
 
        -- Epic vehicles (~0.64% total)
        { 0.64, {
            name = 'vehicle_zentorno',
            label = 'Zentorno',
            amount = 1,
            image = 'nui://ox_inventory/web/images/vehicle_crate.webp',
            rarity = 'epic',
            rewardType = 'vehicle',
            rewardData = { model = 'zentorno', garage = 'legion' },
        } },
 
        -- Legendary vehicles (~0.26% total)
        { 0.26, {
            name = 'vehicle_adder',
            label = 'Adder',
            amount = 1,
            image = 'nui://ox_inventory/web/images/vehicle_crate.webp',
            rarity = 'legendary',
            rewardType = 'vehicle',
            rewardData = { model = 'adder', garage = 'legion' },
        } },
    },
},

Server Settings

config.server = {
    -- Enable version checking on server start
    versionCheckEnabled = true,
}

Understanding Weight Distribution

The weight system is flexible and doesn't require weights to sum to 100. The probability of each item is calculated as:

probability = item_weight / total_weight_of_all_items

Example Calculation

If you have items with weights: 80, 15, 4, 1 (total: 100)

  • Item with weight 80: 80/100 = 80% chance
  • Item with weight 15: 15/100 = 15% chance
  • Item with weight 4: 4/100 = 4% chance
  • Item with weight 1: 1/100 = 1% chance

Default Rarity Distribution

The default configuration provides these approximate drop rates:

RarityDrop RateWeight Range
Common~80%17+
Uncommon~16%4 - 16.99
Rare~3.1%1 - 3.99
Epic~0.64%0.3 - 0.99
Legendary~0.26%< 0.3