lation scripts
scriptsmembershipdocs
see the scripts
Skip to Content
lation ui
lation interact
lation banking
lation shops
lation jobs
lation weed
lation chop shop
Admin panelContracts and choppingConfigurationDevelopersChangelog

classics

money laundering
drug sales
coke processing
meth crafting
metal detecting
scuba diving
lation chop shop

Developers

The lation chop shop server and client exports, its events, its server and client hooks and the files that ship open, with signatures, return shapes and Lua examples.

Every export is called on exports.lation_chopshop. Server exports that act on a player take their server id as source; client exports work on the local player. A player's identifier is the ESX identifier on ESX and the citizenid on Qbox and QBCore.

Server exports

ExportReturns
getPlayerData(source, type?)A player's record, or one field of it
addPlayerData(source, dataType, amount)Nothing
getLevelData()The XP for each level
getContract(source)The player's contract, or nil
getContractDetails(source)The contract as the paper shows it
issueContract(source)Nothing
GetRuntimeConfig(section?)The live configuration

getPlayerData

Server export

exports.lation_chopshop:getPlayerData(source, type)

Parameters

sourcenumber
The player's server id
typestringoptionaldefault nil
One field: identifier, name, level, exp, vehicles or parts. The whole record when left out.

Returns

table | any | nil
The record (below), or the value of type. nil when the player isn't loaded in your framework.

The first time a player is looked up, a record is created at level 1. A player whose stored level no longer fits the level ladder is moved to the level their XP reaches as they are looked up. The record is the cached one, so treat it as read-only and change it with addPlayerData.

{
    identifier = 'ABC12345',
    name = 'Jane Doe',     -- character name
    level = 3,
    exp = 12450,           -- total XP
    vehicles = 18,         -- vehicles chopped
    parts = 214,           -- parts received
}
server.lua
local level = exports.lation_chopshop:getPlayerData(source, 'level')
if level and level >= 3 then
    -- unlock something
end

addPlayerData

Server export

exports.lation_chopshop:addPlayerData(source, dataType, amount)

Parameters

sourcenumber
The player's server id
dataTypestring
exp, vehicles or parts
amountnumber
How much to add. Anything 0 or below does nothing.

Returns

Nothing

Adding exp levels the player up past each threshold they cross and sends the level up notice (and the level_up log when it is on). Nothing is written straight away: the record is saved when the player leaves or logs out of the character, every 5 minutes while it has changes, when the resource stops and when txAdmin shuts the server down.

server.lua
exports.lation_chopshop:addPlayerData(source, 'exp', 250)

getLevelData

Server export

exports.lation_chopshop:getLevelData()

Returns

table
The total XP for each level, keyed by level number
server.lua
local levels = exports.lation_chopshop:getLevelData()
-- { [1] = 0, [2] = 5000, [3] = 10000, [4] = 25000, [5] = 75000 }

getContract

Server export

exports.lation_chopshop:getContract(source)

Parameters

sourcenumber
The player's server id

Returns

table | nil
The player's contract (below), or nil when they have none
{
    tierId = 'street',       -- the tier's key
    vehicleClass = 1,        -- the class id it asks for (see vehicle class ids)
    cashBonus = 500,         -- paid when the car is finished in time
    issuedAt = 1730000000,   -- unix time
    expiresAt = 1730003600,  -- unix time the timer runs out
    bonusEligible = true,    -- false once the time has run out
    activeNetId = nil,       -- net id of the car being chopped on it
}

The class ids are in vehicle class ids.

server.lua
local contract = exports.lation_chopshop:getContract(source)
if contract and contract.bonusEligible then
    print(('%d seconds left'):format(contract.expiresAt - os.time()))
end

getContractDetails

Server export

exports.lation_chopshop:getContractDetails(source)

Parameters

sourcenumber
The player's server id

Returns

table
The contract as the paper shows it (below), or { status = 'none' } when they have none
{
    status = 'active',            -- 'active', 'in_progress' (a car is being chopped), 'expired' or 'none'
    tierId = 'suv',
    tierLabel = 'SUV',
    vehicleClass = 2,
    vehicleClassLabel = 'SUVs',   -- in the server's language
    issuedAt = 1730000000,
    expiresAt = 1730004500,
    remainingSeconds = 4455,      -- 0 once it has run out
    cashBonus = 750,
    bonusEligible = true,
    activeNetId = nil,
    canCancel = true,             -- the Allow cancelling setting
    cooldownMinutes = 0,          -- the Completion cooldown setting
    account = 'cash',             -- the bonus payout account
    accountIsMoney = true,        -- true for cash, bank or money; false for an item
}
server.lua
local details = exports.lation_chopshop:getContractDetails(source)
if details.status == 'active' then
    print(details.tierLabel, details.vehicleClassLabel, details.remainingSeconds)
end

issueContract

Server export

exports.lation_chopshop:issueContract(source)

Parameters

sourcenumber
The player's server id

Returns

Nothing

Gives the player a contract and its paper, with the same checks as Request Contract at the broker: their job (through CanRequestJob), the cooldown, a contract already running, the police count, a tier at their level and room for the paper. The player is told when it is refused. There is no distance check, so you can hand out contracts from your own NPC or job. Call getContract afterwards to see whether one was issued.

server.lua
RegisterNetEvent('my_resource:takeChopJob', function()
    local src = source
    exports.lation_chopshop:issueContract(src)
end)

GetRuntimeConfig

Server export

exports.lation_chopshop:GetRuntimeConfig(section)

Parameters

sectionstringoptionaldefault nil
setup, start, experience, contracts, locations, minigame, items, shops or logs; every section when left out

Returns

table
That section, or a table of every section keyed by name. Experience levels and rewards are keyed by level number, and coordinates are vectors.

The table is the live configuration: changes you make to it aren't saved, so change settings in the admin panel.

server.lua
local contracts = exports.lation_chopshop:GetRuntimeConfig('contracts')
print(contracts.account, contracts.completionCooldown)

The logs section holds your Discord webhook URL. Don't pass it to clients.

Client exports

ExportReturns
getPlayerData(type?)The local player's record, or one field of it
getLevelData()The XP for each level
hasActiveContract()boolean
openMenu()Nothing

getPlayerData (client)

Client export

exports.lation_chopshop:getPlayerData(type)

Parameters

typestringoptionaldefault nil
One field; the whole record when left out

Returns

table | any
The local player's record from the server, shaped like the server export's, or the value of type

It waits for the server, so call it from a thread.

client.lua
CreateThread(function()
    local data = exports.lation_chopshop:getPlayerData()
    print(('Level %s with %s XP'):format(data.level, data.exp))
end)

getLevelData (client)

Client export

exports.lation_chopshop:getLevelData()

Returns

table
The same level table as the server export

hasActiveContract

Client export

exports.lation_chopshop:hasActiveContract()

Returns

boolean
true when the local player has a contract with time left

It asks the server, so call it from a thread. A contract that has run out is cleared by the check, paper included.

client.lua
CreateThread(function()
    if exports.lation_chopshop:hasActiveContract() then
        -- show a hint
    end
end)

openMenu

Client export

exports.lation_chopshop:openMenu()

Returns

Nothing

Opens the broker menu wherever the player is. A player with a blacklisted job gets the job notice instead. Contracts can be requested from it anywhere, but the shops still need the player within 15 m of a broker.

client.lua
RegisterCommand('chopmenu', function()
    exports.lation_chopshop:openMenu()
end, false)

Events

lation_chopshop:configUpdated

Server event

AddEventHandler('lation_chopshop:configUpdated', function(config) end)

Parameters

configtable
Every section, in the shape of an export file: level keys are strings and coordinates are plain tables, not vectors. The logs section is included.

Fires on the server after the settings load on start, and again after every save, reset or import in the admin panel. It is a local server event: listen with AddEventHandler in a server script.

server.lua
AddEventHandler('lation_chopshop:configUpdated', function(config)
    print(('Contract bonuses pay into %s'):format(config.contracts.account))
end)

lation_chopshop:runtimeReady

Client event

AddEventHandler('lation_chopshop:runtimeReady', function() end)

Fires on the client each time the settings reach it: after joining, after a restart of the resource, and after every save, reset or import in the admin panel. It carries no arguments; use it to refresh anything of your own that follows chop shop settings. The client never receives the logs section.

client.lua
AddEventHandler('lation_chopshop:runtimeReady', function()
    print('chop shop settings are in')
end)

lation_chopshop:notify

Client event

TriggerClientEvent('lation_chopshop:notify', source, message, notifyType)

Parameters

messagestring
The text
notifyTypestringoptionaldefault nil
success, error, inform and the like, as your notification system reads them

Send it from the server to show a notification through the system set under Setup > Notifications.

server.lua
TriggerClientEvent('lation_chopshop:notify', source, 'The broker has a job for you', 'inform')

Hooks

Hooks are plain functions in files that ship open. Edit them in place to change who can do what. Every server hook below is called, so a hooks file kept from an older version must still define each of them.

Server hooks

In lua/server/utils/hooks.lua.

CanDoChopping

Server hook

function Hooks.CanDoChopping(source, notify) end

Parameters

sourcenumber
The player's server id
notifyboolean
true to tell the player why they are refused

Returns

boolean
false to refuse

Called before a player starts a chop, starts or finishes taking a part off, and inside the default CanRequestJob and CanParticipate. By default it refuses blacklisted jobs.

CanRequestJob

Server hook

function Hooks.CanRequestJob(source) end

Parameters

sourcenumber
The player's server id

Returns

boolean
false to refuse the contract

Called when a contract is requested, at the broker or through issueContract. By default it calls CanDoChopping with notify on.

lua/server/utils/hooks.lua
function Hooks.CanRequestJob(source)
    if not source then return false end
    -- add your own check here, return false to refuse
    return Hooks.CanDoChopping(source, true)
end

CanChopVehicle

Server hook

function Hooks.CanChopVehicle(source, entity) end

Parameters

sourcenumber
The player's server id
entitynumber
The car

Returns

boolean
false to refuse the chop

The server's say on a car when a chop starts, after its own checks have passed: the player's contract and its class, the distance, the chop location and the blacklisted models. The client's CanStartChopping asks first, so an honest player hears no early, but this is the answer that counts. A refusal tells the player nothing on its own, so send your own notice, as the default does.

By default, while Allow owned vehicles is off, it refuses a car whose plate is in the owned vehicles table, whoever owns it. The lookup is one query by plate, kept for a minute (IsPlayerOwnedVehicle in lua/server/utils/vehicles.lua).

lua/server/utils/hooks.lua
function Hooks.CanChopVehicle(source, entity)
    -- Never take a car out of the police impound lot
    if #(GetEntityCoords(entity) - vector3(409.0, -1623.0, 29.3)) < 40.0 then
        TriggerClientEvent('lation_chopshop:notify', source, 'Not from the impound lot', 'error')
        return false
    end

    if not runtime.start.allowOwned then
        if IsPlayerOwnedVehicle(GetVehicleNumberPlateText(entity)) then
            TriggerClientEvent('lation_chopshop:notify', source, locale('notify.owned-vehicle'), 'error')
            return false
        end
    end

    return true
end

CanParticipate

Server hook

function Hooks.CanParticipate(source, netId) end

Parameters

sourcenumber
The player's server id
netIdnumber | nil
The car's net id; nil means any car being chopped nearby

Returns

boolean
false to keep the player off the car

Called before placing or removing stands, raising or lowering the car, opening the hood, starting or finishing a part, and breaking the drill. By default it is true when the player passes CanDoChopping and is within 30 m of the car (of any car being chopped, when netId is nil). Each of those actions, except breaking the drill, also needs the player within 12 m of the car's center, which the server checks on its own after the hook.

VehiclePartRemoved

Server hook

function Hooks.VehiclePartRemoved(source, entity, model, typeId, partId) end

Parameters

sourcenumber
The player who took the part off
entitynumber
The car
modelstring
class_ and the contract's class id, such as class_4
typeIdstring
wheel, door, or mock for an engine bay part
partIdstring
wheel_lf, wheel_rf, wheel_lr, wheel_rr, door_lf, door_rf, door_lr, door_rr, engine_battery, engine_radiator, engine_alternator, engine_ecu or engine_turbo

Called after a part is credited to a player. Does nothing by default.

lua/server/utils/hooks.lua
function Hooks.VehiclePartRemoved(source, entity, model, typeId, partId)
    if partId == 'engine_turbo' then
        -- give a rare bonus item
    end
end

Client hooks

In lua/client/utils/hooks.lua.

CanStartChopping

Client hook

function Hooks.CanStartChopping(model, entity) end

Parameters

modelstring
Always 'contract_vehicle'
entitynumber
The car

Returns

boolean
false to refuse

Called when the player picks Start chopping, before the server is asked. By default it refuses blacklisted jobs with a notice and, while Allow owned vehicles is off, a car whose plate is in the owned vehicles table. It only decides what an honest player is told first: the server asks again in CanChopVehicle, and that answer counts.

StartedChopping

Client hook

function Hooks.StartedChopping(entity, model) end

Parameters

entitynumber
The car
modelstring
Always 'contract_vehicle'

Called once the server has opened the chop on that car. Does nothing by default.

lua/client/utils/hooks.lua
function Hooks.StartedChopping(entity, model)
    -- tell your own dispatch script where the car is
    TriggerServerEvent('my_dispatch:chopStarted', NetworkGetNetworkIdFromEntity(entity))
end

The hooks files also define Hooks.GetContract and Hooks.IsInitiator (server) and Hooks.CanInteractWithVehiclePart (client). Nothing calls them, so editing them changes nothing.

Open files

The files that ship open, so you can read and change them:

PathWhat it's for
lua/bridge/client.lua, lua/bridge/server.luaFramework and inventory support, with slots for a custom framework or inventory
lua/client/utils/ui.luaNotifications, progress bars (and cancelling one), menus and dialogs, with the custom slots
lua/client/utils/interact.luaThe interaction systems, with the custom slot
lua/client/utils/hooks.lua, lua/server/utils/hooks.luaThe hooks above
lua/server/utils/perms.luaIsAdmin, the check for /chopadmin
lua/server/utils/logging.luaHow logs reach fivemanage and Discord
lua/server/utils/vehicles.luaOwned vehicle lookup by plate (kept for a minute) and deletion: owned_vehicles.owner on ESX, player_vehicles.citizenid on Qbox and QBCore
lua/client/theme.luaHow the panels follow lation ui's theme
lua/shared/defaults.luaThe first-start defaults, read by the server only
lua/config/icons.lua, lua/config/animations.luaIcons, progress bars and animations
locales/*.jsonEvery string

Still stuck? Ask in our Discord: the people who write the scripts answer.

Last updated November 10, 2026

Configuration

Every lation chop shop option in /chopadmin > Config, with its config key, default value, limits and what it changes.

Changelog

Every lation chop shop release, newest first, with what it added, changed and fixed.

On this page

Server exportsgetPlayerDataaddPlayerDatagetLevelDatagetContractgetContractDetailsissueContractGetRuntimeConfigClient exportsgetPlayerData (client)getLevelData (client)hasActiveContractopenMenuEventslation_chopshop:configUpdatedlation_chopshop:runtimeReadylation_chopshop:notifyHooksServer hooksCanDoChoppingCanRequestJobCanChopVehicleCanParticipateVehiclePartRemovedClient hooksCanStartChoppingStartedChoppingOpen files
lation scripts

FiveM scripts for Qbox, QBCore and ESX servers, made to look and work like one product.

store

  • all scripts
  • membership
  • classics

help

  • docs
  • discord
  • email support

legal

  • terms
  • refunds
  • privacy
© 2026 Lation Labslationscripts.com
  • home
  • scripts
  • membership
  • docs