Creating Locations
Add owned and self-service mechanic locations
Config.MechanicLocations contains every mechanic business on your server. Each named entry, such as bennys or lscustoms, is one mechanic. The locations table inside that entry contains the places where players can interact with it.
All interaction points in the same locations table share the mechanic's job, prices, tuning options, shops and stashes.
Choose what to add
| What you need | What to change |
|---|---|
| A separate mechanic business with its own job or settings | Duplicate a complete entry inside Config.MechanicLocations |
| Another interaction point for an existing mechanic | Add an entry to that mechanic's locations table |
| A mechanic operated by an employee job | Duplicate the lscustoms entry and keep type = "owned" |
| A mechanic anyone can use | Duplicate the bennys entry and keep type = "self-service" |
Back up config/config.lua before editing it. A missing comma or brace will stop the config from loading.
Add a mechanic
Find the mechanic table
Open config/config.lua and search for this line:
Config.MechanicLocations = {Don't use line numbers. They change between releases.
The table ends at the matching } immediately before the electric vehicle section. Every mechanic entry must stay between the opening and closing braces of Config.MechanicLocations.
Copy a matching mechanic
Choose an existing entry with the type you need:
- For an owned mechanic, copy from
lscustoms = {to the brace that closes the completelscustomsentry. - For a self-service mechanic, copy from
bennys = {to the brace that closes the completebennysentry.
Copy the whole entry, including its locations, blip, mods, tuning, carLifts, shops and stashes settings where present. Don't copy the outer Config.MechanicLocations = { line or its final closing brace.
Paste the duplicate inside the table
Paste the copied entry after an existing mechanic and before the final brace of Config.MechanicLocations.
Mechanic entries must be separated by a comma. Change the brace that closes the previous mechanic from } to }, before adding another entry.
This reduced example shows the complete table boundary and comma positions. Keep the other settings from the entry you copied:
Config.MechanicLocations = {
lscustoms = {
type = "owned",
job = "mechanic",
locations = {
{
coords = vector3(-337.25, -137.2, 38.35),
size = 6.5,
showBlip = true,
},
},
},
harmony = {
type = "owned",
job = "harmony",
locations = {
{
coords = vector3(1177.62, 2640.83, 37.75),
size = 6.5,
showBlip = true,
},
{
coords = vector3(1182.28, 2637.91, 37.75),
size = 3.0,
showBlip = false,
employeeOnly = true,
},
},
},
}The first }, closes lscustoms and separates it from harmony. The final } closes Config.MechanicLocations. If you paste the new mechanic after that final brace, it won't be part of the table.
Change the duplicate's settings
Rename the copied entry and update its settings. This is a complete owned mechanic entry that can be pasted inside Config.MechanicLocations:
harmony = {
type = "owned",
job = "harmony",
jobManagementRanks = {4},
logo = "ls_customs.png",
commission = 0,
locations = {
{
coords = vector3(1177.62, 2640.83, 37.75),
size = 6.5,
showBlip = true,
},
{
coords = vector3(1182.28, 2637.91, 37.75),
size = 3.0,
showBlip = false,
employeeOnly = true,
},
},
blip = {
id = 446,
color = 47,
scale = 0.7,
},
mods = {
repair = { enabled = true, price = 500, percentVehVal = 0.01 },
performance = { enabled = true, price = 500, percentVehVal = 0.01, priceMult = 0.1 },
cosmetics = { enabled = true, price = 500, percentVehVal = 0.01, priceMult = 0.1 },
stance = { enabled = true, price = 500, percentVehVal = 0.01 },
respray = { enabled = true, price = 500, percentVehVal = 0.01 },
wheels = { enabled = true, price = 500, percentVehVal = 0.01, priceMult = 0.1 },
neonLights = { enabled = true, price = 500, percentVehVal = 0.01 },
headlights = { enabled = true, price = 500, percentVehVal = 0.01 },
tyreSmoke = { enabled = true, price = 500, percentVehVal = 0.01 },
bulletproofTyres = { enabled = true, price = 500, percentVehVal = 0.01 },
extras = { enabled = true, price = 500, percentVehVal = 0.01 },
},
tuning = {
engineSwaps = { enabled = true, requiresItem = true },
drivetrains = { enabled = true, requiresItem = true },
turbocharging = { enabled = true, requiresItem = true },
tyres = { enabled = true, requiresItem = true },
brakes = { enabled = true, requiresItem = true },
driftTuning = { enabled = true, requiresItem = true },
gearboxes = { enabled = true, requiresItem = true },
},
carLifts = {},
shops = {},
stashes = {},
},Change these values for your server:
harmonyis the unique config name. Use letters, numbers and underscores. Don't use the same name as another mechanic.typemust be"owned"or"self-service".jobmust exactly match the job name in your framework. It only applies to an owned mechanic.jobManagementRankscontains the job grades that can use management features.logomust match a file in the resource'slogosfolder.commissionis the percentage paid to the employee.0disables commission.carLifts,shopsandstashesare empty in this example. Copy and edit the matching sections fromlscustomsif you need them.
Don't leave copied carLifts, shops or stashes at the old mechanic's coordinates. Change every coordinate or replace the unused section with an empty table, as shown above.
Restart and test
Save config/config.lua, then restart the resource from the server console:
restart jg-mechanicCheck the server console for a Lua error. Then visit every configured interaction point and confirm:
- the interaction zone appears in the correct place
- the blip only appears where
showBlip = true - employees with the configured job can use an owned mechanic
- players without that job can't use employee-only interaction points
Add interaction points to one mechanic
Add another entry inside the existing mechanic's locations table when both points should use the same mechanic business and settings:
locations = {
{
coords = vector3(-337.25, -137.2, 38.35),
size = 6.5,
showBlip = true,
},
{
coords = vector3(-324.2, -132.0, 38.54),
size = 3.0,
showBlip = false,
employeeOnly = true,
},
},The comma after the first interaction entry is required because another entry follows it. The trailing comma after the second entry is valid and makes it safer to add another one later.
Each vector3 must contain exactly three values in this order: X, Y and Z.
coords = vector3(1177.62, 2640.83, 37.75)Use the player's position coordinates. Don't add a heading value and don't change vector3 to vector4 for a mechanic interaction point.
| Setting | What it controls |
|---|---|
coords | Centre of the interaction zone |
size | Width, depth and height of the interaction zone |
showBlip | Whether this point creates a map blip |
employeeOnly | Whether only employees can use this point |
Troubleshooting
The new entry is outside Config.MechanicLocations, or a comma or brace is missing.
Check that the new mechanic is before the final brace of Config.MechanicLocations. Each mechanic entry and each interaction entry must be separated from the next one with a comma. Compare the indentation and closing braces with the examples above.
Check that coords uses vector3 with three numbers and that the entry is inside the mechanic's locations table. Increase size while testing if the interaction area is too small to find.
If the point has employeeOnly = true, test while using the job configured in the mechanic's job setting.
The interaction entry was added to the wrong mechanic's locations table. Move the complete entry, from its opening { to its closing },, into the correct mechanic entry.
The mechanic's job value must exactly match the framework job name, including capitalisation. Confirm the job exists and that the player has that job, then reconnect or reload the player's job after changing framework data.
Last updated 4 August 2026