Skip to content

Extra Configuration

Wiring your own framework, inventory, notify, progressbar, stress, needs, target or society banking into the editable files.

On this page2

Both files are outside the escrow, so edit them freely. Each block only runs when that option is set to 'custom' in config.lua, and everything else keeps using its detected backend.

Client

Notify, progressbar, stress and target live here, plus the client half of framework, inventory and needs.

lua
-- Config.Framework = 'custom'
 
if Config.Framework == 'custom' then
    function GetFrameworkObject()
        return nil
    end
 
    -- Some inventories read .items off this, QB stress reads .metadata.stress.
    function GetFrameworkPlayerData()
        return {}
    end
 
    -- Only used if Config.Notify = 'framework'.
    function NotifyViaFramework(title, text, type, ms, icon)
    end
 
    -- Only used if Config.Progressbar = 'framework'.
    -- Anything falsy counts as cancelled here, not just false.
    -- No prop netId return, delete anything you attach.
    function ProgressbarViaFramework(opts)
        Wait(opts.duration)
        return true
    end
end
 
 
-- Config.Inventory = 'custom'
 
if Config.Inventory == 'custom' then
    -- { { slot = 1, name = 'water', count = 2, metadata = {} }, ... }
    function GetInventoryItems()
        return {}
    end
 
    function OpenStash(name)
        return false
    end
 
    -- Item icons are not a function - set Config.InventoryImagePath in
    -- config.lua to the nui:// path yours serves them from.
end
 
 
-- Config.Notify = 'custom'
 
if Config.Notify == 'custom' then
    function NotifyDisplay(title, text, type, ms, icon)
    end
end
 
 
-- Config.Progressbar = 'custom'
 
if Config.Progressbar == 'custom' then
    -- opts = {
    --     duration     = milliseconds,
    --     title        = string,
    --     text         = string,
    --     useWhileDead = boolean,
    --     canCancel    = boolean,
    --     icon         = string or nil,
    --     disable      = { move, car, mouse, combat },
    --     anim         = { dict, clip, flag } or nil,
    --     prop         = { model, bone, pos, rot } or nil,
    -- }
    --
    -- Return true if it finished, only an explicit false cancels.
    -- Play opts.anim and attach opts.prop yourself, nothing else does.
    -- Return the prop netId second and it gets deleted for you.
    -- Always return, an error here kills every later progress bar on that client.
    function ProgressbarRun(opts)
        Wait(opts.duration)
        return true
    end
end
 
 
-- Config.Stress = 'custom'
 
if Config.Stress == 'custom' then
    -- 0-100.
    function GetStress()
        return 0
    end
 
    -- type is 'set', 'add' or 'remove'.
    -- On add and remove most HUDs want the change, not the new total.
    function SetStress(type, amount)
        return 0
    end
end
 
 
-- Config.Needs = 'custom'
 
if Config.Needs == 'custom' then
    -- 0-100, counting UP toward full. Never return nil.
    function NeedsRead()
        return { hunger = 0, thirst = 0 }
    end
 
    -- Absolute values, nil means leave that one alone.
    -- On most HUDs this is display only, the server does the real write.
    -- Fill this in on both realms, server/editable.lua has the same block.
    function NeedsApply(hunger, thirst)
    end
end
 
 
-- Config.Target = 'custom'
 
if Config.Target == 'custom' then
    -- Return nil while your resource is stopped, never a string.
    function GetTargetResource()
        return 'custom'
    end
 
    -- options is one option or a list, AsTargetOptionList() always gives a list.
    -- Each one: { name, label, icon, distance, canInteract, onSelect(entity) }
    -- Call onSelect with the entity handle.
    function AddLocalEntity(entity, options)
        return false
    end
 
    function RemoveLocalEntity(entity)
        return false
    end
end

Server

Society banking lives here, plus the server half of framework, inventory and needs.

lua
-- Config.Framework = 'custom'
 
if Config.Framework == 'custom' then
    function GetFrameworkObject()
        return nil
    end
 
    -- Return the raw player object, other scripts reach into it directly.
    function GetPlayer(src)
        return nil
    end
 
    function GetCharacterName(playerId)
        return ('ID %s'):format(playerId)
    end
 
    -- citizenid, charId, identifier, whatever your framework uses.
    function GetPlayerUniqueId(playerId)
        return nil
    end
 
    -- type is 'cash', 'bank' or 'money'.
    function GetPlayerBalance(src, type)
        return 0
    end
 
    -- Leaving account out adds to cash, not the bank.
    function AddPlayerMoney(src, amount, account)
        return false
    end
 
    -- Leaving account out takes from the bank, not cash.
    function RemovePlayerMoney(src, amount, account)
        return false
    end
 
    -- { name = ..., label = ..., grade = ... }
    function GetPlayerJob(src)
        return {}
    end
 
    function SetPlayerJob(src, job, role)
    end
 
    function ToggleJobDuty(src, toggle)
    end
 
    -- Persistent per-character storage. Return nil when there is no value.
    function GetPlayerMetadata(src, key)
        return nil
    end
 
    -- Return false if the write did not happen, don't pretend it did.
    function SetPlayerMetadata(src, key, value)
        return false
    end
 
    -- Only used if the active inventory routes usable items through the
    -- framework, which most of them do. Call cb(src, itemName, itemData) when
    -- the player uses the item. itemData may be nil.
    -- Return false if your framework cannot do this.
    --
    -- cb is NOT a Lua function. It reached us through an export, so the runtime
    -- handed it over as a table with __call on it. Calling it works normally,
    -- but `type(cb) == 'function'` is false and `cb.anything` raises
    -- 'Cannot index a funcref'. Use IsCallable(cb) if you want to check it.
    function RegisterUsableItemViaFramework(itemName, cb)
        return false
    end
end
 
 
-- Config.Inventory = 'custom'
 
if Config.Inventory == 'custom' then
    function AddItem(src, item, amount, meta)
        return false
    end
 
    -- No need to check they have enough, RemoveItem already did.
    function InventoryRemoveItem(src, item, amount, meta)
        return false
    end
 
    -- Return 0 when they have none, never nil.
    function GetItemCount(src, item, meta)
        return 0
    end
 
    function GetItemInSlot(src, slot)
        return nil
    end
 
    function SetItemMetadata(src, slot, metadata)
        return false
    end
 
    -- size is a max weight, not a second slot count.
    function RegisterStash(name, label, slots, size, opts)
        return false
    end
 
    -- PrettifyItemName turns 'water_bottle' into 'Water Bottle'.
    function GetItemLabel(itemName)
        return PrettifyItemName(itemName)
    end
 
    -- Delegate if your inventory uses the framework's usable item system,
    -- otherwise hook your own and call cb(src, itemName, itemData).
    -- Return whether it registered - returning nothing is read as a failure,
    -- and the calling script will report the item as unusable.
    --
    -- Same note as RegisterUsableItemViaFramework above: cb is a funcref, not a
    -- function. Call it as normal; just don't type-check it against 'function'.
    function InventoryRegisterUsableItem(itemName, cb)
        return RegisterUsableItemViaFramework(itemName, cb)
    end
 
    -- Item icons are not a function - set Config.InventoryImagePath in
    -- config.lua to the nui:// path yours serves them from.
end
 
 
-- Config.Needs = 'custom'
 
if Config.Needs == 'custom' then
    -- 0-100, counting UP toward full. Never return nil.
    function NeedsRead(src)
        return { hunger = 0, thirst = 0 }
    end
 
    -- Absolute values, nil means leave that one alone.
    -- This is the authoritative write, persist it here.
    -- Return false if it did not persist, don't pretend it did.
    -- TriggerClientEvent('pixel-utils:client:applyNeeds', src, hunger, thirst)
    -- afterwards if your HUD needs telling.
    function NeedsWrite(src, hunger, thirst)
        return false
    end
end
 
 
-- Config.SocietyBanking = 'custom'
 
if Config.SocietyBanking == 'custom' then
    -- type is 'job' or 'gang'.
    function GetSocietyBalance(society, type)
        return 0
    end
 
    function AddSocietyFunds(society, type, amount)
    end
 
    function RemoveSocietyFunds(society, type, amount)
    end
end

src and playerId are both the server-side player id. society is the job or gang name exactly as your framework stores it, with no prefix added.