Blog
Why Is My ESX Job Marker in the Wrong Place After Installing an MLO?
Why Is My ESX Job Marker in the Wrong Place After Installing an MLO?
You spend a weekend installing a beautiful new police station. Custom interior, working lights, a locker room that does not look like a bus shelter. You load in to admire it, walk to the duty point, and the marker is hovering two metres above the car park outside, spinning gently, like it is waiting for a bus.
Nothing is broken. Your job resource is doing exactly what it was told, which is to draw a marker at a set of coordinates somebody wrote down years ago while standing in a building that no longer exists. Every interaction point in ESX is a hardcoded position, and installing an MLO is the fastest way to make a hundred of those positions wrong at once. Here is why it happens, and how to fix all of them in one sitting instead of one bug report at a time.
Job resources are lists of coordinates wearing a trench coat
Open the config of any ESX job resource and you find the same shape. A station or shop, then a list of vectors for each thing you can do there:
Config.PoliceStations = {
MissionRow = {
Blip = { Coords = vector3(425.1, -979.5, 30.7), Sprite = 60 },
Cloakrooms = { vector3(452.6, -993.1, 30.6) },
Armories = { vector3(451.7, -980.1, 30.6) },
Vehicles = {
{ Spawner = vector3(454.6, -1017.4, 28.4),
SpawnPoints = { { coords = vector3(438.4, -1018.3, 27.7), heading = 90.0 } } }
},
BossActions = { vector3(461.6, -985.1, 30.7) }
}
}
None of that is derived from the map at runtime. It is a transcription of where things were when the resource was written, against the vanilla interior. Swap the building and every line above is a guess about a place that has changed.
The same is true of your ambulance job, your mechanic shop, your garages, your shops, your door locks and anything using a blip. One MLO, many configs.
The four ways a marker ends up in the wrong place
The interior was replaced, so the room moved. Most station and shop MLOs remove the vanilla interior and put their own geometry in. Doors move, desks move, the armoury ends up on the other side of a wall. The coordinate is still valid, the room around it is not.
The floor height changed. Interiors sit at a specific z. Rebuilt ones often sit a few tenths of a metre higher or lower, which is exactly enough for a marker to float or sink into the ground, and for a spawned car to drop onto its roof.
The entrance moved. Plenty of MLOs turn a teleport based interior into a real walk in building, or the reverse. If your job resource carries a teleport pair and the MLO expects you to use the front door, you end up inside a wall with a nice view of the skybox.
You are outside the interior, technically. Some builds put the usable space in a new interior that only streams when you are in the right place. Walk in from a direction the author did not plan for and the room is empty, dark, or missing entirely. That is a portals and rooms problem rather than a coordinates one, and it looks identical from the doorway.
Getting the right coordinates, properly
Stand where you want the marker, get your own position, write it down. The dev command version, dropped into any resource you are already loading:
RegisterCommand('here', function()
local ped = PlayerPedId()
local c = GetEntityCoords(ped)
local h = GetEntityHeading(ped)
local s = ('vector3(%.2f, %.2f, %.2f) heading %.2f'):format(c.x, c.y, c.z, h)
print(s)
SetClipboardText(s)
end)
Two details that save a second trip. The z you get back is your ped’s position, which is roughly ground level at the feet, so a marker drawn at that exact z usually looks like it is floating slightly. Most job configs expect the ground coordinate and the marker code applies its own offset, so if yours floats by about a metre, subtract rather than adding. And always capture heading for anything a vehicle spawns at, or your shiny new patrol car appears facing a wall.
For vehicle spawn points, walk the space first. A spawn point needs clear room for the biggest vehicle in the list, not for the ped standing in it. Ask me how I know about the van.
Do the whole building in one pass
Installing an MLO and fixing one marker is how you end up doing this every night for a fortnight. Walk the building once with a list and capture everything:
- Blip position, which should be the public entrance rather than the middle of the roof.
- Duty and cloakroom points.
- Armoury or stock points.
- Boss menu point.
- Vehicle spawner point, plus one spawn position and heading per parking bay you intend to use.
- Helicopter pad if the roof changed.
- Any teleport pairs, both ends, with headings.
- Evidence, cells, interview rooms, and whatever else your community has made a ritual out of.
Paste them into the config in one edit, restart the resource, and walk it again to confirm. Twenty minutes, once.
Door locks are a separate and worse problem
Door lock resources do not store positions. They store door model hashes with coordinates, and an MLO ships its own doors with their own models. So after an install, every door in that building is either permanently unlocked or missing from the config entirely, and your cells stop being cells.
Most good MLO downloads include a door lock config for the popular resources. Use it if it is there. If it is not, the doors have to be re-registered with whatever tool your lock script provides, and it is worth doing before you announce the new station rather than during the first prison break.
When the room is empty rather than in the wrong place
Different symptom, related cause, and it catches people right after a coordinate fix. You walk into the building and the interior is bare: no furniture, no lockers, and sometimes no floor beyond the doorway.
Two mechanisms produce that. Some interiors are shipped as map data that has to be requested before it exists, and some ship with optional pieces that are switched on per interior rather than being there by default. Either way the geometry is present in the files and absent from your screen until something asks for it.
The asking is a few lines, run once when the resource starts:
-- request a map file that is not loaded by default
RequestIpl('ex_dt1_02_office_02b')
-- turn on optional pieces inside an interior
local interior = GetInteriorAtCoords(435.0, -980.0, 30.7)
if interior ~= 0 then
EnableInteriorProp(interior, 'csr_beforeMission')
RefreshInterior(interior)
end
The names are specific to the interior, and a well made MLO tells you which ones it needs in its documentation. When it does not, the author’s Discord usually has the answer, because everyone who installed it before you asked the same question.
Worth knowing that this is stateful and per client. A player who was already inside when the resource restarted can end up in the empty version while everyone else sees the furnished one, which sounds like a haunting and is just an interior that was refreshed at the wrong moment. Restarting the resource, or relogging, is the honest answer there.
If the interior is empty for everybody and always, it is a missing stream rather than an unrequested one. Check the resource is started, check the files are actually in the stream folder, and check nothing else on your server is replacing the same location.
Stop hardcoding, where you can
You cannot avoid coordinates entirely, but you can reduce how many of them are load bearing.
Interaction systems that use zones or targeting let you point at an object instead of standing in an invisible circle. A target based cloakroom attached to a locker model keeps working when the locker moves, because the anchor is the object rather than the air above the floor. It also reads better, since players interact with things rather than with glowing cylinders in the middle of a room.
Where you do keep coordinates, keep them in one file per building rather than sprinkled through three resources. When the next MLO arrives, and it will, the whole job is one file and one walk around.
Practical takeaway
An MLO changes geometry, not logic, so the fix is always the same: re-derive every point in the building in one pass, capture heading for anything that spawns, check the z twice, and re-register your doors. If you are shopping for the next interior, the MLO listings worth browsing usually say whether door and job configs are included, and that one line in a product description is worth about an hour of your weekend.
While you are in there, the guide on how ESX job configs are structured is the companion piece to this one, because once you can read the config properly, moving a whole police station becomes a copy and paste job rather than an archaeology project.
The marker in the car park, by the way, was correct. It was the duty point for a building demolished by a zip file on Saturday afternoon.