Every FiveM doorlock — ox_doorlock, qb-doorlock, nui_doorlock, esx_doorlock and Doorlock Creator — locks doors through the same native door system. Run two and each one keeps setting the door back to its own state: doors that unlock and snap shut, prompts that say "Unlock" on an open door, two keys on the same door. Remove the old one before your first start.
Removing the Old Doorlock#
Make a list of your doors
Before removing anything, note which doors exist and who opens them. Where to find them:
Resource
Doors are kept in
ox_doorlockThe
ox_doorlockdatabase table — one row per door with its JSON data.qb-doorlockconfigs/*.luaandconfig.luainside the resource.nui_doorlock · esx_doorlockconfig.lua(andconfigs/where present).Stop it from starting
Remove or comment out its line in
server.cfg, and move the folder out ofresources/— a resource inside a[category]folder that is ensured as a whole still starts.bash # ensure ox_doorlock # ensure qb-doorlock ensure qs-doorlock-creatorCheck what depended on it
Heists, robberies, housing and job scripts often lock and unlock doors through the old resource's exports or events. Search your resources for its name —
ox_doorlock,qb-doorlock:server:updateState,nui_doorlock— and switch those calls over as shown below.Install Doorlock Creator and recreate the doors
Follow Installation, then open
/doorlockcreatorand create each door from your list: aim, click, set the same jobs and grades, save. Usage covers every field.Drop the old data
Once every door works, delete the old folder. For ox_doorlock you may also drop its table:
sql DROP TABLE IF EXISTS `ox_doorlock`;
Bringing Doors Across With a Script#
For a long list, or for doors a script owns (a vault, a cell block), the EnsureDoors server export creates them from a model and coordinates — exactly what the old config files hold. It is safe to call on every start: doors that already exist are matched by name and left alone.
-- A server file in any resource that starts after qs-doorlock-creator
local doors = {
{ name = 'mrpd_front_left', model = 'gabz_mrpd_reception_entrancedoor', coords = vector3(434.74, -983.21, 30.84), heading = 90.0, locked = true },
{ name = 'mrpd_cells_main', model = -53345114, coords = vector3(476.61, -1008.87, 26.48), locked = true },
}
CreateThread(function()
-- The exports answer with an empty list until the doors are loaded from the database
local ids = {}
repeat
ids = exports['qs-doorlock-creator']:EnsureDoors(doors)
if #ids == 0 then Wait(1000) end
until #ids > 0
end)Doors created this way are single doors with no access rules — anyone can toggle them — until you open them in the creator and add jobs, items or a passcode. The models and coordinates above are examples; copy yours from the old config.
Switching Script Calls Over#
Doors are addressed by their numeric id — shown in the creator as Edit door #12, and returned by EnsureDoors and GetAllDoors — instead of the old resource's names or indexes.
-- Before
local door = exports.ox_doorlock:getDoorFromName('bank_vault')
TriggerEvent('ox_doorlock:setState', door.id, 0)
-- After (server side)
local id = exports['qs-doorlock-creator']:EnsureDoors({
{ name = 'bank_vault', model = 'v_ilev_gb_vauldr', coords = vector3(254.12, 225.13, 101.87), heading = 160.0 },
})[1]
exports['qs-doorlock-creator']:SetDoorState(id, false) -- false = unlocked-- Before
TriggerServerEvent('qb-doorlock:server:updateState', 'pacific-vault', false, false, false, true)
-- After (server side)
exports['qs-doorlock-creator']:SetDoorState(12, false) -- 12 = the door's idEvery export is listed in Commands and Exports.



