Upgrade Scripts Docs

#Configuration

Everything lives in config.lua, which is not escrowed. Most values have sensible defaults - this page covers what you will actually want to change. Shops, loot cases and leveling have pages of their own.

The resource checks your config on start and prints anything that looks wrong, so read the console after your first restart.

#Framework, inventory and notifications

Config.Inventory = nil   -- nil = auto-detect
Config.Notify    = 'auto'

Both are detected for you. Config.Inventory accepts 'ox_inventory', 'qb-inventory', 'ps-inventory', 'qs-inventory', 'lj-inventory' or 'esx-inventory' if you ever need to force it. Config.Notify on 'auto' uses ox_lib when it is installed and your framework's own notification system otherwise; you can also set 'QBox', 'QBCore', 'ESX', 'ox_lib', 'okokNotify' or 'custom'.

#Language

Config.Locale = 'en'

Ships with en, de, fr, es, pt, nl, pl, it and tr. See Localization.

#Cash rewards

Config.CashRewardAccount = 'bank'

Which account cash rewards are paid into. QBCore and QBox accept 'cash', 'bank' or 'crypto'; ESX accepts 'money' (cash in hand) or 'bank'.

#Points and the playtime timer

Config.PlayTimeMinutes  = 60   -- how often the playtime reward pays out
Config.GivePeriodPoints = 10   -- reward points per payout, before the level bonus
Config.ReferreeReward   = 50   -- points for the player who redeems a code
Config.ReferrerReward   = 100  -- points for the player whose code was redeemed

These are reward points - the shop currency. They have nothing to do with leveling; XP is configured separately in Config.LevelSystem.

The level bonus comes from Config.LevelSystem.PointMultiplier, which defaults to 0.1 - each level adds 10% to every payout, so a level 10 player earns double.

#AFK detection

Config.AFK = {
    Enabled = false,
    IdleMinutes = 10,
    NotifyOnPause = true,
}

Off by default. When enabled, a player who has not moved or turned their camera for IdleMinutes stops accruing playtime - and therefore stops earning playtime points and XP - until they move again. Nothing is taken away; the counter simply pauses and resumes. With NotifyOnPause on, the player is told both times.

#Referral maturity

Config.ReferralSystem = {
    Enabled = true,
    MaturityHours = 0,
}

MaturityHours is how long the new player must play before the referrer is paid. At 0 the referrer is paid immediately. Set it to something like 2 and the reward is held until the new player has two hours of playtime, which is what stops people farming referrals with alt accounts. The new player's own bonus is always paid immediately.

Pending referrals show in the player's referral list marked "pending", and in the admin panel as "reward pending". Nothing is lost if the referrer is offline when it matures.

#Garage integration

Config.Garage = {
    DefaultGarage = {
        QBCore = 'pillboxgarage',
        QBox   = 'pillboxgarage',
        ESX    = false,
    },
    DefaultVehicleType = 'car',
    Columns = {
        garage = nil,
        stored = nil,
    },
}

Vehicle rewards are written straight into your framework's vehicle table (player_vehicles on QBCore and QBox, owned_vehicles on ESX). The resource reads which columns that table actually has and fills in the ones your garage script uses, which is what makes it work with loaf_garage, okokGarage, jg-advancedgarages, qb-garages, qbx_garages, cd_garage, esx_advancedgarage and most others without configuration.

DefaultGarage must match a garage name from your garage script's own config. Setting an entry to false leaves the garage column empty, which some ESX garages treat as "available anywhere". If a rewarded vehicle never shows up, this is the first thing to set - put a real garage name from your garage script in the entry for your framework.

Columns is an escape hatch for an unusual schema. garage is the column your garage script reads the location from (parking for loaf_garage, okokGarage and esx_advancedgarage; garage for qb-garages, qbx_garages and jg-advancedgarages; sometimes garage_id), and stored is the column that marks a vehicle as parked (stored on ESX, state on QB). Leave both nil unless detection gets it wrong.

What was detected is printed on start:

[Upgrade-Rewards] Vehicle rewards -> owned_vehicles (garage column: parking, stored column: stored, garage script: loaf_garage)

#Get out of jail

Config.Jail = {
    MetadataKey = 'auto',
    ReleaseClientEvent = nil,
}

Only relevant if you add an unjail item to a shop. MetadataKey is where your jail script stores the remaining sentence - 'auto' uses injail on QBCore and QBox, and jail on ESX. ReleaseClientEvent is fired at the player once their time is cleared, so your jail script can teleport them out; for qb-policejob that is 'prison:client:Leave'. See Shops & Loot.

#Interface

Config.UI = {
    OpenKey = 'F11',
    OpenKeyDescription = 'Open Rewards Menu',

    MainTitle = 'PLAYER REWARDS',
    MainSubtitle = 'Earn points, level up, unlock exclusive rewards',

    DefaultShopkeeperImage = './images/shopkeepers/default.png',
    DefaultShopkeeperDialogue = 'Welcome to my shop! Take a look around!',

    PrimaryColor = '#4a90e2',
    SecondaryColor = '#2c3e50',
    AccentColor = '#34495e',
    SuccessColor = '#3498db',

    ModalAnimationSpeed = 300,
    FadeSpeed = 300,

    CashImage = './images/items/money.png',
    PointsImage = './images/items/points.png',
}

OpenKey is the default keybind - each player can rebind it themselves in the FiveM keybind settings, and the /rewards command always works. Image paths are relative to the resource's ui/images folder, so you can drop your own artwork in there and point these at it.

Menu wording other than the title and subtitle comes from the locale files rather than here.

#Diagnostics and history

Config.Debug = false
Config.MaxHistoryEntries = 200

Config.Debug prints verbose diagnostics - every XP grant with the threshold it was checked against, every admin permission check with the rule that decided it, loot rolls, and purchases. It is chatty, so leave it off on a live server unless you are chasing something.

Config.MaxHistoryEntries caps how many points-history entries are kept per player. The history is one JSON blob sent to the menu each time it opens, so it cannot grow forever; older entries drop off once the limit is reached.

#Inventory images

Config.InventoryImagePaths = { ... }

Maps each supported inventory to where its item images live, so shop items show the same artwork players see in their inventory. The defaults cover every supported inventory - only touch this if yours stores images somewhere unusual.

#The rest