NullSect
Systems nominal

Docs / Electrician / Installation

INSTALLATION — ns-electrician

1. Requirements

RequirementNote
FiveM server with OneSync enabledServer-side entity natives are used for distance and ownership checks
oxmysqlMust start before ns-electrician
MySQL / MariaDB user with CREATE, ALTER, INSERT, UPDATE, DELETENeeded only once, for the automatic migration
Framework (optional)qbx_core, qb-core, es_extended, or standalone
ox_lib / ox_target (recommended)Nicer dialogs and interaction points; the resource works without them

2. Copy the resource

Put the folder in your resources directory, keeping the folder name exactly:

resources/[ns]/ns-electrician

The name matters: the NUI page, the exports and the events all use ns-electrician.

3. server.cfg

ensure oxmysql
ensure ox_lib          # optional
ensure ox_target       # optional
ensure ns-electrician

The admin commands need no extra permission: the script asks your framework who is an admin, so your existing admins can use them straight away.

4. Database

With Config.Database.autoMigrate = true (default) the tables are created on the first start:

ns_elec_meta          schema version
ns_elec_workers       career: xp, reputation, counters, tool condition, vehicle tier
ns_elec_upgrades      equipment tier per player per category
ns_elec_jobs          job log (UNIQUE job_uid — this is what prevents double payouts)
ns_elec_assignments   daily assignments with progress and the claimed flag
ns_elec_audit         admin actions

If your SQL user may not create tables, set Config.Database.autoMigrate = false and import sql/electrician.sql by hand. The file only contains CREATE TABLE IF NOT EXISTS statements — it never drops or overwrites existing data.

5. The job in your framework

Create a job called electrician (the name is Config.Job.name).

Qbox / QBCore — in shared/jobs.lua:

electrician = {
    label = 'Electrician',
    defaultDuty = true,
    grades = {
        [0] = { name = 'Apprentice', payment = 50 },
        [1] = { name = 'Electrician', payment = 75 },
        [2] = { name = 'Foreman', isboss = true, payment = 100 },
    },
},

ESX — insert into the jobs / job_grades tables with the name electrician.

No job system / whitelist-free server: set Config.Job.required = false and anyone can clock in.

6. Place the depot and the job sites

Every coordinate shipped with the resource is marked -- example and sits around the Palmer-Taylor power station. Replace them with your own:

Job sites (in game, no file editing):

  1. Start the server, join, and run /eleclocations (framework admins only).
  2. Fastest: press Scan props (or /eleclocations scan). Electrical boxes, street lights, traffic lights and transformers of the map around you are highlighted. E adds the nearest, G turns on auto add — then just drive around the city and everything found is added (one site per ~35 m). X stops. Remove the ones you do not like in the panel. Shop breaker panels: aim at the panel, pick Breaker panel with ← / → and press H — that model is now found everywhere and becomes a business site where the manager waits.
  3. Manual: press Record a site, walk up to an electrical box — it is highlighted and the work point snaps to it, facing you — and press E. Away from any box the spot you stand on is used.
  4. Name it, pick the job classes it serves and the power system, then Save. It is live immediately and stored in data/locations.json (keep that file when you update the resource).
  5. Use Test call on a site to put a test job there.

Depot, shop and van spawn are fixed points in config.lua (Config.Center.coords, Config.Center.shop.coords, Config.Center.vehicle.spawn). Stand on the spot, read the coordinates with your usual tool, paste them there and restart ns-electrician.

A job site entry looks like this:

{ id = 'res_my_street', label = 'My Street', tags = { 'residential' }, power = 'grid_east',
  coords = vector4(123.45, -678.90, 30.12, 180.0) },
  • id — never rename it after release, it is stored in the job log.
  • tags — residential, business, street, industrial. A job type only spawns on a site that carries one of its own locationTags.
  • power — which entry of Data.PowerSystems goes dark while a job is open there.
  • coords — the work point (panel, fuse box, pole). The heading decides where the customer stands and which way the player faces.
  • indoor = true — the work point is inside a building (purely informative for the moment, no vehicle check is made at the site).

Make sure every job class has at least one site, otherwise those job types can never be offered.

7. Service tablet item

The service terminal is an inventory item (Config.Tablet.item, default electrician_tablet). Players take it at the depot point (Take service tablet) and open it by using the item; clocking in / out, the job board and the equipment bench are all on the tablet. There is no keybind. Add the item to your inventory — ox_inventory (ox_inventory/data/items.lua):

['electrician_tablet'] = {
    label = 'Electrician Tablet', weight = 500, stack = false, close = true,
    description = 'Service terminal: clock in / out and take calls.',
},

QBCore: add electrician_tablet to qb-core/shared/items.lua; ESX: to the items table. Set Config.Tablet.enabled = false (or run standalone without ox_inventory) to skip the item — the depot point then clocks in and opens the terminal directly.

7b. Equipment items (optional)

By default the toolbox from the van is enough and no inventory items are needed. To require real items set:

Config.Equipment.requireItems = true

and create the items listed in Config.Equipment.items in your inventory (electrician_multimeter, electrician_toolkit, electrician_repairkit, electrical_tape, voltage_tester). ox_inventory example:

['electrician_multimeter'] = {
    label = 'Multimeter', weight = 600, stack = false, close = true,
    description = 'Measures voltage and continuity.',
},

8. Vehicles

Config.Vehicles.tiers uses burrito3, rumpo and speedo4 — all base-game models. Replace model with your own add-on spawn names if you have them. Keep the list ordered from cheapest to best: vans must be bought in order.

9. First test run

  1. restart ns-electrician and watch the console for [ns-electrician:SV] ns-electrician v1.0.0 ready (framework: qbox, locale: tr).
  2. Go to the depot marker, interact (ox_target or [E]) → Take service tablet.
  3. Use the tablet from your inventory → Start shift. Take the van, open the back, take the toolbox.
  4. Accept a call, drive to the blip, work through the objectives in the HUD.
  5. Check ns_elec_jobs — one row per finished job.

10. Troubleshooting

SymptomCause / fix
No framework adapter registeredConfig.Framework points at a framework that is not started. Use 'auto' or 'standalone'.
oxmysql is not startedStart oxmysql before this resource.
Database initialisation failedThe SQL user cannot create tables → import sql/electrician.sql and set autoMigrate = false.
Interaction does nothingNo ox_target / qb-target: the built-in prompt needs you to stand inside the circle and press E (Config.Target.promptControl).
You have to be at the service centerConfig.Center.coords is still the example coordinate.
No calls on the boardYour level, reputation or safety tier does not allow any job type yet, or no site carries a matching tag. Check with /electest fuse_trip.
The van does not spawnThe model in Config.Vehicles.tiers does not exist on the server (err_vehicle_model in chat).
Tablet stays empty / fonts look wrongCheck F8 for NUI errors and make sure nui/ was copied completely, including nui/fonts/ — the interface ships its own fonts and loads nothing from the internet.
No interface soundsConfig.UI.sound = false, or the player set the volume to 0 on the tablet's settings page.
Locale "xx" not foundConfig.Locale must be 'en' or 'tr' unless you added a locale file.

11. Updating

  1. Keep your own config.lua, data/*.lua and locales/*.lua — compare them with the new ones instead of overwriting.
  2. Replace everything else.
  3. Restart. New schema versions migrate themselves; ns_elec_meta.schema_version records where the database stands.

Cart

Your cart is empty.