ns-electrician
NullSect Advanced Electrician Job for FiveM — Qbox first, QBCore and ESX through a bridge.
Players clock in at the service depot, take call-outs from a dispatch board, drive out with a service van, diagnose the actual fault with a multimeter, fix it through tool-specific minigames, talk the customer through what was wrong and get paid based on how well they worked.
Features
| Area | What it does |
|---|---|
| 13 job types | Blown fuse, house fault, business outage, street light, distribution panel, broken cable, short circuit, generator, transformer, emergency outage, pole maintenance, meter inspection, line inspection. Each one is its own ordered list of steps. |
| Fault diagnosis | The faulty component is hidden server-side. The player measures a limited number of components with the multimeter and then names the one they believe is broken. Wrong calls cost reputation and quality. |
| 7 minigames | Fuse box, wiring, circuit, breakers, voltage, multimeter, cable repair. Four of them are verified against a solution the server keeps; the other three are score-based with server-side bounds checks. |
| Customer system | NPC customers greet the player, explain the problem (sometimes wrongly), answer questions, give hints and react to the final report. Satisfaction feeds payment, XP and reputation. |
| Career + reputation | XP-driven levels (Apprentice → Master Electrician) and a separate reputation score that unlocks business, industrial, emergency and VIP-grade work. |
| Equipment upgrades | Multimeter, tool kit, repair kit and safety gear, each with three tiers and real gameplay effects (reading accuracy, mistake tolerance, minigame time, wear, quality, hazard class). |
| Service vehicle | Three upgradeable vans, spawned at the depot, with a mobile toolbox the player has to take from the back before most jobs. |
| Power state | Open jobs actually cut the power of their system. Other resources can read it via GlobalState, an export or an event. Reference counted, so two jobs on one system cannot fight. |
| Random events | Wrong information, a second fault, brittle wiring, tool damage, a re-trip, a customer in a hurry, a job that is harder than advertised. |
| Daily assignments | Three drawn per player per day with money / XP / reputation rewards, claimable once (enforced in SQL). |
| UI | A rugged NS-E7 field tablet the electrician actually holds (prop + animation) with nine pages — overview, job board, active work order, grid status, equipment, vehicle, assignments, statistics, settings. Work orders are paper tickets with stamps and perforation, the diagnosis panel is a handheld installation tester with a segment LCD, the minigames are drawn as the real hardware inside an open enclosure (NEOZED fuse bases, a terminal block fed from a cable duct, 0/I selector switches with pilot lamps, MCBs behind a dead-front cover, an analogue panel voltmeter, a handheld multimeter, a cable that is cut, stripped, crimped and taped), the customer talks on a paper service note, calls arrive as a torn-off pager slip and jobs close with a thermal-print invoice. Plus a job HUD, level-up card, toasts and synthesized interface sounds (no audio files). Optional ns-hud widget. |
| Localisation | English and Turkish, every user-facing string included (locales/en.lua, locales/tr.lua). |
Dependencies
Required
- oxmysql
- OneSync (server-side entity natives are used for validation)
Recommended
Optional
ns-hud— the active job is mirrored into a HUD widgetox_inventoryor the framework inventory — only whenConfig.Equipment.requireItems = true- Any framework:
qbx_core(Qbox),qb-core(QBCore),es_extended(ESX), or none (standalone hooks)
Without ox_lib / ox_target the resource still works: it falls back to native notifications and a
built-in [E] proximity prompt.
Installation (short)
- Copy the folder to your resources, keeping the name
ns-electrician. - Make sure
oxmysqlstarts before it. - Add
ensure ns-electriciantoserver.cfg. - Start the server once — the tables are created automatically
(
Config.Database.autoMigrate = true). To create them by hand, importsql/electrician.sql. - Create the
electricianjob in your framework (or setConfig.Job.required = false). - Move the example coordinates in
config.luaanddata/locations.luato your own map (in-game recorder:/eleclocations).
The long version with troubleshooting is in INSTALLATION.md.
Commands
| Command | Who | What |
|---|---|---|
/eleclocations | admin | Opens the job site panel: record sites (snaps to electrical boxes), edit, move, remove, teleport, GPS, test call. /eleclocations scan starts the prop scanner (adds the map's electrical boxes, street lights, traffic lights). /eleclocations view toggles the world view only. |
/electest [jobTypeId] | admin | Puts one test call on your board (/electest short_circuit). Test jobs are logged but pay nothing and never count towards XP, reputation, statistics or tool wear. |
/elecreset [playerId] | admin | Resets a career: XP, reputation and tool condition. |
/elecgrant <playerId> <xp|money|rep> <amount> | admin | Grants XP, money or reputation. Audited. |
Admin access comes from your framework: anyone it already treats as an admin can use these
commands, no extra ACE needed. Command names are configurable in Config.Admin.commands.
The field tablet is an inventory item (electrician_tablet) taken at the depot; use it to open the terminal.
Default keys (rebindable in Settings → Key Bindings → FiveM):
| Key | Action |
|---|---|
Y | Accept the call shown on the pager slip |
U | Decline it |
G | Talk to the customer |
ESC | Close any open screen |
1 – 9 | Pick a dialogue line |
Interface volume and the job HUD are toggled on the tablet's Settings page; both are stored per player on their own machine (game KVP), never on the server.
Exports
Server:
exports['ns-electrician']:GetPlayerLevel(src) -- number | nil
exports['ns-electrician']:GetReputation(src) -- number | nil
exports['ns-electrician']:IsOnShift(src) -- bool
exports['ns-electrician']:IsOnJob(src) -- bool
exports['ns-electrician']:GetProfile(src) -- read-only summary | nil
exports['ns-electrician']:GetActiveJob(src) -- read-only job summary | nil
exports['ns-electrician']:GetPowerState(id) -- bool
exports['ns-electrician']:GetPowerStates() -- { [systemId] = bool }
Client:
exports['ns-electrician']:IsOnShift()
exports['ns-electrician']:GetProfile()
exports['ns-electrician']:GetActiveJob()
exports['ns-electrician']:GetPowerState(systemId)
Events other resources can listen to:
AddEventHandler('ns-electrician:hook:powerChanged', function(systemId, isOn, reason) end)
AddEventHandler('ns-electrician:hook:jobCompleted', function(src, data) end)
AddEventHandler('ns-electrician:hook:securityFlag', function(src, reason, detail) end)
Power state is also published as a statebag, so a resource does not even need this one running:
local power = GlobalState['ns-electrician:power'] -- { [systemId] = true/false }
Every export is read-only — nothing here can grant money, XP or skip a validation.
Configuration
Everything a server owner is expected to touch lives in config.lua and data/*.lua:
locations, job types, dialogues, random events, equipment tiers, vehicles, difficulty,
payments, XP, reputation, career levels, minigame difficulty, assignments, notifications,
localisation and permissions.
See CONFIGURATION.md for every key with its effect.
Security model
The server decides, the client only reports intent.
- One validated entry point (
ns-electrician:sv:request) with a flood bucket, per-RPC rate limits, per-player locks and a registered route whitelist. - Payment, XP, reputation, quality, satisfaction and the job state live on the server only. The client can never send an amount.
- Every step action re-checks shift, job ownership, job state, step type and the distance between the server-side ped position and the site.
- The faulty component, the number of measurements left and every minigame solution stay on the server. Four of the seven minigames compare the submitted answer against the stored solution; the other three are bounds-checked against the generated parameters and elapsed time.
- A completed job is written with a
UNIQUEjob_uidbefore the money is paid, so a double payout is impossible — including after a server restart. - Assignment rewards are claimed with a conditional
UPDATE, so they can only pay once. - Disconnect, character change and resource stop clean up the job, the vehicle, the props, the peds and the power holds.
Licence / support
Commercial NullSect resource. config.lua, locales/*.lua, data/*.lua, bridge/*.lua and
sql/*.sql stay editable under Cfx asset escrow (escrow_ignore in fxmanifest.lua).