Launch sale · 9LABS Crane Tow Truck Job Ends in See the deal

Nothing in this manual matched.

9LABS Electrician Job

A bucket truck, and the city's wiring.

Clock on at the depot, take a bucket truck and fix the city's traffic lights and distribution cabinets. Fetch the right parts from the truck, climb into the bucket, and repair every fault by hand in close-up — alone or as a crew of two.

Introduction

A full electrician job around a working bucket truck, with every repair done by hand in close-up.

What is in the resource

  • A streamed utility truck with a working boom driven by a remote, a bucket you climb into through a fold-down ladder gate, a ladder rack and eight side compartments full of equipment.
  • 905 traffic lights and 100 distribution cabinets taken from the GTA map and checked in game, so jobs work all over the map without placing anything.
  • Close-up repairs with the mouse: real screws that unscrew, bulbs and wiring in the signal head, fuses and terminals in the cabinet, a multimeter, isolating and energizing — and shocks when you work live.
  • Equipment that has to be fetched from the truck: every job needs a different fuse rating, lug size or bulb wattage, and only the compartments that hold what you need open.
  • Crew work for two electricians: a signal controller, a tool rope up to the bucket, cable tracing between two cabinets, remote isolation and pulling a colleague off a live cable.
  • Pay, levels, a crew bonus and a fast repair bonus.
  • A job app for phones and tablets that installs itself on lb-phone, lb-tablet, Quasar, yPhone, okokPhone and GKS, and plugs into the Meteo Job Tablet as a full dispatch job.
  • An admin panel for the depot, truck bays, pay, levels and job types, and Discord logging.

Almost nothing is configured in a file. Apart from the handful of options in config.lua, the whole job is set up in game through /elecadmin, and changes save on the server and apply live.

Requirements

OneSync and a framework. Everything else is optional.

ServerOneSync.
FrameworkQbox, QBCore, ESX or standalone. Anything else can use the custom bridge.
StorageA writable storage/ folder. No SQL.
Optionalox_target or qb-target, ox_lib notifications, a vehicle keys script, a fuel script, a phone or tablet.

Installation

Start it after your framework and phone, then check the depot in game.

  1. Put 9labs_electrician in your resources folder and keep that exact name.
  2. Add it to server.cfg, after your framework, target, keys, fuel and phone resources.
  3. Set the basics in config.lua.
  4. Restart the server.
  5. As an admin, run /elecadmin and check the depot, truck bays and pay for your server.
ensure 9labs_electrician

Players must reconnect after you update the resource. It streams a vehicle, props and animations, and those only reload when a client connects — a resource restart alone leaves people on the old data.

config.lua

Everything not listed here is set in game through /elecadmin.

OptionValuesWhat it does
localeen, de, bsLanguage of the UI, notifications and logs
frameworkauto, qbx, qb, esx, standalone, customauto picks the first running one: qbx_core, qb-core, es_extended, otherwise standalone
keysauto, qbx, qb, none, customKeys for the company truck. Crew members get keys too. With qb-vehiclekeys 1.6 and newer the keys go through its server exports
fuelauto or a resource nameauto supports ox_fuel, LegacyFuel, cdn-fuel and native fuel
interaction9labs_ui, ox_target, qb-target, customHow players talk to the depot foreman
notify9labs_ui, ox_lib, native, customNotification style
controlscontrol id and label per actionKeys of every on-screen action, see below
remoteKeykey nameDefault key for the boom remote (F5). Players rebind it in Settings → Key Bindings → FiveM
lockInventorytrue, false, customBlocks the inventory and its hotbar keys while the remote is in hand. true works with ox_inventory, qb-inventory and every inventory that respects inv_busy
adminAceslist of ACEsWho can open /elecadmin and use /electruck and /electest. command works for txAdmin admins without a restart
appsphone / tablet namesWhich phones and tablets get the job app. Set one to false to skip it. See Phone and tablet apps
standalonestartingCash, startingBankStandalone only: starting balance of the built-in wallet, stored per licence
advanced.autoDispatchtrue / falsetrue (default): a job comes in by itself. false: jobs only on request, see Jobs on request
advanced.requestCommandcommand name or falseChat command that asks for a job when autoDispatch = false; default eleccall
advanced.jobHudtrue / falsefalse hides the on-screen job panel. Notifications, blips, markers, the compartment markers and the pay summary stay
debugtrue / falseExtra console output

On-screen keys

Every prompt reads its key from controls. When two actions share a key, the more important one wins and the other is shown greyed out.

controls = {
    bucket = { control = 38, label = 'E' },   -- climb into / out of the bucket
    ladder = { control = 47, label = 'G' },   -- take, carry, lean and stow the ladder
    bay = { control = 74, label = 'H' },      -- open a side compartment
    take = { control = 38, label = 'E' },     -- send an item up the rope
    service = { control = 38, label = 'E' },  -- start working on the traffic light or cabinet
    depot = { control = 38, label = 'E' },    -- talk to the depot foreman
    accept = { control = 246, label = 'Y' },  -- accept a crew invite
    decline = { control = 306, label = 'N' }, -- decline a crew invite
    ctrl = { control = 38, label = 'E' },     -- signal controller, pulling a colleague off a live cable
    ctrlAlt = { control = 47, label = 'G' },  -- signal controller: switch the signal off again
},

If you do not use the command ACE, give admin access the usual way:

add_ace group.admin electrician.admin allow

First setup

/elecadmin writes to storage/settings.json on the server, and changes apply live.

Positions can be picked in the world, taken from your position, or typed in. Traffic lights and cabinets need no setup at all — they come from the GTA map.

SectionWhat you set
GeneralRequired job and grade (leave empty for everyone), deposit, depot and foreman position, foreman ped, whether the foreman is used at all, truck bays, return radius, map blip
PayAccount, pay range for traffic lights and for cabinets, bonus per level, fast repair bonus and its time, crew bonus
LevelsXP per job, XP per level, max level
JobsDispatch distance, delay between jobs, cooldown after dropping a job, share of bulb and wiring faults, share of fuse and terminal faults, and which job types are on and how often they come
SoundVolume and range
Discord logsWebhook and what to log

How the job works

Take a truck, fetch the parts, climb up or open the cabinet, and repair the fault by hand.

  1. Start a shift at the depot foreman. A deposit is taken and a company truck is spawned with keys and fuel.
  2. The dispatcher sends a job: a traffic light or a distribution cabinet. A GPS route and a pulsing marker above the faulty object show the way; the marker disappears once you are there.
  3. Fetch the equipment. The HUD lists what the job needs, and the compartments that hold it are marked around the truck in order: the next one gets a big arrow, the rest a number. Press H at a compartment to open it and look inside, hover over an item to see what it is and whether you need it, and click to take it. Compartments with nothing you need stay shut.
  4. Work in close-up with the mouse: hold the left button on a marker. Doing things in the wrong order, or touching anything live, gets you a shock.
  5. When the job is paid the tools go back into the truck, so the next job starts with fetching again.

Traffic lights

Raise the bucket to the signal head. Unscrew the four screws, open the cover, replace the burnt bulb or reconnect the loose wire, close it and screw it tight. The job is done the moment the last screw is in, and the light runs a test cycle.

Distribution cabinets

Unlock with the triangle key and open the doors. Probe every phase with the multimeter until you find the dead or unstable one, switch off the main isolator, replace the fuse or tighten the terminal, switch back on, close and lock. Probing too fast, or touching a live part, gives you a shock.

Cabinets with the doors against a wall are skipped automatically. When you arrive the doors are checked, the dispatcher sends a new job, and the cabinet is left out for you. Once two different players report the same one it is removed for good (data/cabinets_blocked.json).

Cabinet locations and custom maps

The job uses 100 cabinets spread over the whole map, in pairs close enough for crew work. Every one was checked in game: free space in front of the doors, room to stand, a clear close-up view, and no tilted cabinets or cabinets set into walls. If your server replaces parts of the map, run /elecsurvey as an admin: it visits every location, checks the same things and writes the result to storage/cabinet_survey.json, with the reason for every location that fails. /elecsurvey 40 starts at location 40, and running the command again stops it.

The bucket and remote

Climb in through the ladder gate, then drive the boom from the bucket or from the ground.

Stand behind the truck under the stowed bucket and press E. The gate folds down into a ladder, the telescopic sections slide down to the ground, you climb up and the gate closes behind you. Leaving works the same way in reverse. While the gate is open the boom cannot move.

The remote (F5) works in the bucket and next to the truck, but only on shift. The bucket always stays level, the rider turns with the camera, and the side ladder can be carried off the rack and leaned against a wall or pole (G).

Only one player can hold the remote of a truck at a time, on the ground or in the bucket. The next one gets it once the remote is put away. If the holder crashes, disconnects, dies or walks away, the remote is released by itself within about 8 seconds and the boom stops. Other players see the rider standing in the bucket and moving with it.

Crew work

Two electricians, one truck, one job — and a crew bonus for both.

On shift, open the foreman's tablet and invite a colleague standing next to you. They accept with Y or decline with N. The colleague uses your truck and keys without a deposit and sees the same jobs. Both are paid for every job they were present for, with the crew bonus from /elecadmin → Pay, and both get XP.

Working alone stays exactly as described in How the job works. In a crew the jobs change:

Traffic lightsA signal controller cabinet near the crossing is marked on the map. The colleague on the ground switches the signal off there before the one in the bucket touches bulbs or wires, and at the end switches it on and runs the light test. The one on the ground can also send items up to the bucket on a rope and drive the boom with the remote.
CabinetsTwo linked cabinets, A and B, and the fault is in B. At A you find the dead phase and clip on a tone generator. At B the colleague probes the cables until one beeps. Then A switches off the feed, B repairs, A switches it back on, and both cabinets are closed and locked.
RescueWhoever touches a live part gets stuck on the cable. The colleague has a few seconds to run over and pull them off; too late means a serious injury.

The crew leader can remove the colleague, and the colleague can leave, on the tablet. When the leader ends the shift the colleague's shift ends too. Only the leader can drop a job.

Player controls

Every prompt shows its key on screen; these are the defaults.

KeyAction
F5Take out or put away the boom remote, next to the truck or in the bucket (on shift)
W / SReach out or in
A / DSlew left or right, always as seen from the camera
E / QBucket up or down
1Stow the boom
SpaceEmergency stop
Backspace / EscPut the remote away
E behind the truckClimb into or out of the bucket
GTake, carry, lean and stow the ladder
HOpen a side compartment and look inside; click an item to take it, H or Esc closes
E at the jobStart working on the traffic light or cabinet
Left mouse (close-up)Hold on a marker to do that step
Mouse wheel (close-up)Zoom
Esc / Backspace (close-up)Leave the close-up
Y / NAccept or decline a crew invite

Commands

CommandWhoWhat
/elecadminAdminOpens the admin panel
/electruckAdminSpawns a truck next to you, for testing
/electest [traffic|cabinet]AdminGives you the nearest job of that type
/eleccancelPlayerDrops the current job (in a crew only the leader). The next job comes after the cooldown
/eleccallPlayerAsks dispatch for a job. Only with advanced.autoDispatch = false; the name is advanced.requestCommand
/elecboomAnyoneTakes out the boom remote next to a truck, also off shift, for testing
/elecsurvey [from]AdminVisits every cabinet location, checks it and writes storage/cabinet_survey.json. Run again to stop
elecprof (F8)AnyoneMeasures this resource's client cost per part for five seconds and prints it to F8

Discord logs

Paste a webhook in the admin panel, save it, then send a test. Each category can be switched off.

In Discord: channel settings → Integrations → Webhooks → New webhook → Copy URL. Then in /elecadmin → Discord logs, paste it, save, and press Send test.

CategoryContents
ShiftsStart with deposit, account, truck plate and location; crew joins; end with reason, length, jobs, earnings and whether the deposit was refunded
PayoutsJob type, amount, location and crew size
AdminSettings saved or reset with the exact changes
SecurityRequest floods, at most once a minute per player

The webhook stays on the server and is always masked in the panel.

Phone and tablet apps

The job has its own app, and adds it by itself to every supported phone or tablet that is running.

The app shows the current job with its steps (drive, repair, close and test), the fault, the crew, GPS to the job or the depot, dropping the job, the player's level and stats, and the best electricians. On a tablet it uses a wider two-column layout.

ResourceHow it is added
lb-phone, lb-tabletPreinstalled custom app
qs-smartphone-pro, qs-smartphoneCustom app
yseries, yphone, yflip-phonePreinstalled custom app
okokPhoneCustom app
gksphone, gks-tabletCustom app
meteo-jobtabletRegistered as a job: Clock In and Out, live dispatch panel, accept, reject or cancel jobs, tablet groups, levels, rankings, achievements, task history and tournaments
RoadPhone Pro, RoadPadOne entry in RoadPhone's own config, below

Each one can be switched off in config.lua:

apps = {
    ['lb-phone'] = true, ['lb-tablet'] = true,
    ['qs-smartphone-pro'] = true, ['qs-smartphone'] = true,
    ['yseries'] = true, ['yphone'] = true, ['yflip-phone'] = true,
    ['okokPhone'] = true, ['gksphone'] = true, ['gks-tablet'] = true,
    ['meteo-jobtablet'] = true,
},

Start 9labs_electrician after the phone or tablet. If the phone restarts, the app is added again by itself. If it does not show up, the server console says could not add the app to ….

Meteo Job Tablet

Clock In works at the depot, where the company truck is handed out; anywhere else the tablet sets the GPS to the depot. New jobs appear as tasks: accepting one sets the GPS, and the panel follows the job through driving, repairing and closing. Pay and XP are still handled by the job, and the tablet records earnings, reputation, achievements and history. If you renamed the tablet with Meteo's rename guide, change TABLET at the top of server/integrations.lua.

With advanced.autoDispatch = false the tablet asks for the next job by itself after Clock In, after a finished job and after a rejected one, so a new task always shows up on it. Tablet groups work as crews: the group leader clocks in, and the first group member joins the crew, shares the truck and gets paid with the crew.

RoadPhone Pro

RoadPhone has no export for apps. Add this to the AppStore list in its public/static/config/config.json:

{
  "name": "Electrician",
  "light_icon": "https://cfx-nui-9labs_electrician/web/dist/app-icon.png",
  "dark_icon": "https://cfx-nui-9labs_electrician/web/dist/app-icon.png",
  "default": true,
  "category": "business",
  "custom_app_id": "9labs_electrician",
  "redirect": "custom_app",
  "url": "https://cfx-nui-9labs_electrician/web/dist/index.html?app=phone"
}

Any other phone or tablet

Anything that can show a web page works the same way. Point it at one of these, and the page talks to 9labs_electrician on its own:

https://cfx-nui-9labs_electrician/web/dist/index.html?app=phone
https://cfx-nui-9labs_electrician/web/dist/index.html?app=tablet

To add a phone permanently, copy one of the entries in client/integrations.lua, which stays open under Asset Escrow.

Jobs on request

Out of the box a job comes in by itself when the shift starts and after every job. Servers that hand out work through their own phone, tablet or NPC can switch that off in the advanced block of config.lua.

advanced = {
    autoDispatch = false,      -- no job until the player asks for one
    requestCommand = 'eleccall',
    jobHud = false,            -- optional: no on-screen job panel, the job lives on the phone
},

The player then asks for a job with the Request a job button in the job app, with /eleccall, or through your script with RequestJob. The cooldown after a dropped job still applies. A cabinet that faces a wall is still replaced by a new job automatically.

What the phone can show

task.kindtask.faultWhat the player does
trafficbulb / wireBucket up to the signal head: unscrew four screws, open, replace the bulb or reconnect the wire, close, screw in
cabinetfuse / lugUnlock, open, measure the phases, isolate, replace the fuse or tighten the lug, energize, close, lock

task.stage is travel (nothing opened yet), fix (opened, fault not fixed), close (fixed, close it up) or done. In a crew the traffic controller and the second cabinet add their own steps, see Crew work.

Example: the job on your own phone

9labs_electrician:stateChanged fires on every change of the shift or job, so the phone never has to poll. Any phone with a notification export works the same way.

local kinds = { traffic = 'Traffic light', cabinet = 'Distribution cabinet' }
local faults = { bulb = 'burnt bulb', wire = 'loose wire', fuse = 'blown fuse', lug = 'loose terminal' }

local function text(shift)
    if not shift then return 'Off shift' end
    local t = shift.task
    if not t then return shift.manual and 'Ready, request a job' or ('Next job in %ss'):format(shift.next or 0) end
    if t.stage == 'travel' then return ('%s: go to the site'):format(kinds[t.kind]) end
    if t.stage == 'close' then return ('%s: close it up'):format(kinds[t.kind]) end
    return ('%s: %s'):format(kinds[t.kind], faults[t.fault] or 'repair')
end

AddEventHandler('9labs_electrician:stateChanged', function(src, shift)
    exports['your_phone']:SendNotification(src, { app = 'Electrician', title = 'LSDWP', text = text(shift) })
end)

AddEventHandler('9labs_electrician:jobPaid', function(src, data)
    exports['your_phone']:SendNotification(src, { app = 'Electrician', title = 'Paid', text = ('$%d'):format(data.total) })
end)

-- a code or button in your phone app asks for a job
RegisterNetEvent('your_phone:electrician:request', function()
    local r = exports['9labs_electrician']:RequestJob(source)
    if not r.ok then exports['your_phone']:SendNotification(source, { app = 'Electrician', title = 'LSDWP', text = r.message }) end
end)

Custom bridges

config.lua, locales/, both bridge files, both integration files and data/ stay open under Asset Escrow.

Framework, money, jobs and keys

Set framework = 'custom', and keys = 'custom' if you also handle keys, then fill in the Custom block at the top of server/bridge.lua:

function Custom.identity(src) return GetPlayerIdentifierByType(src, 'license') end -- stable character id
function Custom.name(src) return GetPlayerName(src) end
function Custom.addMoney(src, account, amount, reason) return false end          -- return true on success
function Custom.removeMoney(src, account, amount, reason) return false end
function Custom.getMoney(src, account) return 0 end
function Custom.hasJob(src, job, grade) return true end                          -- only used when a job is set
function Custom.giveKeys(src, vehicle, plate) end
function Custom.removeKeys(src, vehicle, plate) end

account is 'bank' or 'cash', whichever is set in /elecadmin → Pay. The money hooks must return true only once the amount has really moved.

Prompt, target, notifications, fuel and inventory

Set interaction = 'custom', notify = 'custom' or lockInventory = 'custom' as needed, then fill in the Custom block at the top of client/bridge.lua:

function Custom.showContext(items) end                 -- items = { { key = 'E', text = '...', disabled = nil|true }, ... }
function Custom.hideContext() end
function Custom.notify(text, kind) end                 -- kind: 'info', 'success', 'error'
function Custom.addTarget(id, coords, radius, options) return nil end -- options: { { label, icon, onSelect } }, return a handle
function Custom.removeTarget(handle) end
function Custom.setFuel(vehicle, level) end
function Custom.lockInventory(locked) end              -- used when lockInventory = 'custom'

Exports

Read the shift, the crew, the player's profile and the boom state, and start, end or drop work from your own scripts.

Server exports

-- true when the player is on an electrician shift (leader or crew member)
local onDuty = exports['9labs_electrician']:IsOnDuty(source)

-- level and statistics of the player's current character, or nil
local p = exports['9labs_electrician']:GetProfile(source)
-- p.level, p.xp, p.levelXp, p.nextXp, p.maxLevel, p.jobs, p.earned, p.best, p.name

-- the player's shift and current job, or false when off shift
local shift = exports['9labs_electrician']:GetShiftState(source)
-- shift.truck (net id), shift.deposit, shift.jobs, shift.earned, shift.next (seconds to the next job or nil)
-- shift.manual = true and shift.ready (seconds until a job can be requested) with advanced.autoDispatch = false
-- shift.crew = { leader (bool), members = { { id, name, leader } } } or nil
-- shift.task = { kind ('traffic' | 'cabinet'), fault ('bulb' | 'wire' | 'fuse' | 'lug'),
--   stage ('travel' | 'fix' | 'close' | 'done'), x, y, z } or nil

-- start or end a shift from your own script
local r = exports['9labs_electrician']:StartShift(source)        -- same rules as the foreman: only at the depot
local r = exports['9labs_electrician']:StartShift(source, { spawn = vector4(x, y, z, h) })
-- with an options table the depot distance is not checked; spawn is optional (default: a free truck bay)
-- Returns { ok, truck (net id) } or { ok = false, error }

local r = exports['9labs_electrician']:EndShift(source)          -- { ok, summary }, or { ok = false, confirm = true, error } when the truck is not back
local r = exports['9labs_electrician']:EndShift(source, true)    -- end it anyway; the deposit is kept when the truck is not back
local r = exports['9labs_electrician']:EndShift(source, { refund = true })  -- your script decides the deposit refund
local r = exports['9labs_electrician']:AbandonJob(source)        -- { ok } or { ok = false, error }

-- hand out a job now (for advanced.autoDispatch = false, works in both modes; in a crew it is the crew's job)
local r = exports['9labs_electrician']:RequestJob(source)
-- { ok = true, task } or { ok = false, reason, message, seconds }
-- reason: 'off_duty' | 'busy' | 'cooldown' (seconds left) | 'too_fast' (2 s between requests) | 'no_jobs'
-- message is the localized text; the player is not notified, show it the way your script wants

-- crew of a player, or nil: { leader (bool), members = { { id, name, leader } } }
local crew = exports['9labs_electrician']:GetCrew(source)

-- boom state of a truck by network id, or nil
local boom = exports['9labs_electrician']:GetBoomState(netId)
-- boom.pose (yaw, lift, unfold), boom.rider, boom.operator, boom.holder (who holds the remote), boom.gate, boom.boarding, boom.alighting

Your own NPC or job script instead of the foreman

Switch Depot dispatcher off in /elecadmin → General. The foreman, its blip and prompt disappear, and shifts are started by your script — or by the Meteo Job Tablet, whose Clock In then works anywhere and uses a free truck bay. Crew invites need the foreman's tablet, so keep the foreman on if you want crews.

-- server side, e.g. when your own NPC hands out the truck
local r = exports['9labs_electrician']:StartShift(source, { spawn = vector4(751.72, 130.15, 77.63, 275.74) })
if not r.ok then print(r.error) end

-- when your NPC takes the truck back
exports['9labs_electrician']:EndShift(source, { refund = true })

Client exports

local shift = exports['9labs_electrician']:GetShiftState()   -- same shape as the server export
exports['9labs_electrician']:SetJobWaypoint()                 -- GPS to the current job
exports['9labs_electrician']:SetJobWaypoint('depot')          -- GPS to the depot
local r = exports['9labs_electrician']:RequestJob()           -- asks for a job for this player; the result message is shown as a notification

AddEventHandler('9labs_electrician:client:stateChanged', function(shift) end)

Server events

All of these are server-local TriggerEvent, so a client cannot fake them.

AddEventHandler('9labs_electrician:shiftStarted', function(src, data)
    -- data.truck (net id), data.plate, data.deposit, data.account
end)

AddEventHandler('9labs_electrician:shiftEnded', function(src, data)
    -- data.reason: 'returned' | 'away' | 'dropped' | 'character' | 'crew'
    -- data.jobs, data.earned, data.deposit, data.refunded (boolean)
end)

AddEventHandler('9labs_electrician:jobPaid', function(src, data)
    -- fires once for every crew member who was paid
    -- data.kind: 'traffic' | 'cabinet', data.fault: 'bulb' | 'wire' | 'fuse' | 'lug'
    -- data.pay, data.level, data.speed, data.crew (bonus amounts), data.total, data.paid (boolean), data.account
    -- data.xp, data.leveled, data.crewSize
end)

AddEventHandler('9labs_electrician:stateChanged', function(src, shift)
    -- every shift or job change; shift has the same shape as GetShiftState (false = off shift)
end)

Example: pay a society a cut of every job

AddEventHandler('9labs_electrician:jobPaid', function(src, data)
    if data.paid then
        exports['your_banking']:AddSocietyMoney('electrician', math.floor(data.total * .1))
    end
end)

The truck

Model 9leutility, streamed by the resource with its own handling, variations and carcols in data/.

A utility truck with a working three-part boom, a level bucket with a fold-down telescopic ladder gate, a ladder rack, and eight side compartments stocked with keys, gloves, meters, tools, fuses, lugs, bulbs and ferrules.

Performance

No idle cost on the server, and next to nothing on the client away from trucks and jobs.

Server timers only run while a lever is held, a job is active or a gate is moving, and state is sent only when it changes. On the client, nothing runs every frame unless you are near a truck, at a job or working. The tools and parts in the truck compartments are only created when a compartment opens, so a parked truck stays light for everyone around it.

Run elecprof and open F8 to measure it yourself: it reports this resource's client cost per part over five seconds.

Troubleshooting

ProblemFix
Old models, missing animation or odd handling after an updateReconnect. Vehicle data and streamed files only reload on connect.
/elecadmin says no permissionAdd one of adminAces to your admin group, or use the command ACE.
No jobs come inEnable at least one job type in /elecadmin → Jobs and check the dispatch distance.
No keys for the truckCheck keys in config.lua. With auto, qbx_vehiclekeys or qb-vehiclekeys must be running; otherwise use custom.
"Someone else is operating this boom"Another player holds the remote of that truck. Wait until they put it away; if they crashed or left, it is released within about 8 seconds.
Cabinet jobs at odd places on a custom mapRun /elecsurvey and check storage/cabinet_survey.json for the failing locations.
The remote key does nothingIt only works on shift and next to the truck. Another resource may use the same key: rebind it in Settings → Key Bindings → FiveM, or use /elecboom.
"There is nothing in this compartment that you need"Only compartments that hold something the current job still needs open. The next one to visit has the big arrow.
"You need …" when starting a stepThe job needs that item from the truck. The compartment that holds it lights up.
Anticheat kicksWhitelist the events below.
Discord test failsThe webhook must be a discord.com/api/webhooks/... link, and it has to be saved before you press Send test.
Deposit not returnedThe truck must stand within the return radius of the foreman or of a truck bay, and must not be wrecked.
Inventory still opens with the remote outYour inventory ignores invBusy and inv_busy. Set lockInventory = 'custom' and fill Custom.lockInventory in client/bridge.lua.
App missing on the phoneStart 9labs_electrician after the phone, and look for could not add the app in the server console.
9labs_electrician:rpc:q
9le:*

Nothing in this manual matched.