Skip to main content

Integrations

Editable bridges live in bridge/. Keep changes narrowly scoped to the installed provider and preserve server-side authorization. For grants, possession checks, removals, and radial-menu actions, use Exports.

Framework and inventory​

Framework and inventory bridges register from resource-state checks. Start the selected providers before Carlock and restart Carlock after changing providers. Do not run several unrelated inventory backends and rely on file load order to select one.

The seven included inventory adapters and their item installation paths are listed under Dependencies and Installation. Physical item use is slot-aware: the server verifies the actual key item/plate rather than trusting client-supplied metadata.

For custom garages or ownership schemas, review the current ownership lookup and your purchase/spawn integration. Do not substitute HasKey for ownership: keys are transferable bearer access, while ownership comes from framework database records.

Dispatch​

Configure policeAlerts in shared config:

policeAlerts = {
-- Keep the remaining existing policeAlerts fields.
enabled = true,
provider = 'auto',
},

This excerpt shows only the selector; do not replace the full table with it.

SelectorBehavior
autoFirst started supported provider: Wasabi MDT V2, PS, CD; otherwise internal
wasabi_mdt_v2Checks resource wasabi_mdt_v2; adapter calls exports.wasabi_mdt:CreateDispatch
ps or ps-dispatchServer event ps-dispatch:server:notify
cd or cd_dispatchHands the validated alert to the client CD dispatch adapter
internalNotifies players matching policeAlerts.jobs through the framework bridge

An unsupported or stopped explicitly selected provider falls back to internal dispatch with a warning. A provider error/rejection after submission is not retried through another provider, to avoid duplicate calls.

Wasabi MDT V2 owns department delivery; the adapter marks the external origin to avoid its PS/CD relay. Carlock's jobs list is not a guarantee that an external MDT will use identical recipient filtering. The server skips alerts when the acting player matches its configured police groups. Probability and rate limits also affect alerts.

Custom minigames​

  1. In config/shared/config.lua, set the desired minigames entry's provider to 'custom'.
  2. Implement the matching function in bridge/minigames/client.lua:
    • hooks.lockpick(context)
    • hooks.hotwireHighEnd(context)
    • hooks.hotwireStandard(context)
  3. Return true for success, false for failure, or nil for cancellation/unavailability. The shipped placeholder functions return nil; selecting custom alone does not install a game.
  4. Register cleanup for your external UI. Respect context.isCancelled() and the configured duration.
Example: ox_lib skill check

Replace the existing hooks.lockpick function in the bridge, keeping the file's hooks table and module registration:

function hooks.lockpick(context)
if lib.skillCheckActive() or context.isCancelled() then return nil end
context.onCleanup(function()
if lib.skillCheckActive() then lib.cancelSkillCheck() end
end)
return lib.skillCheck({ 'easy', 'medium' }, { 'w', 'a', 's', 'd' })
end

The context provides kind, mode, difficulty, vehicle, netId, plate, ped, minimumDuration, duration, isCancelled, and onCleanup. mode/difficulty depend on the action. Durations are milliseconds. The adapter rejects late/stale results and applies its timing window; it does not make an arbitrary custom client minigame result independently authoritative. Do not call internal reward/grant events yourself.

Client listeners​

Edit the existing functions in bridge/listeners/client.lua. These are same-resource Lua hooks, not exported functions or network event names.

FunctionArgumentsPurpose
onVehicleLockUpdatelocked, vehicleLegacy accepted-lock notification; not proof of native application
onHazardsChangedvehicle, enabledObserved hazards readback change on an applying streamed client
onLockStateChangedvehicle, lockedObserved lock change on the requesting client
onEngineStateChangedvehicle, runningObserved engine change from local Carlock application
onLightStateChangedvehicle, lightModeReadback mode: off, low, or high
onDoorStateChangedvehicle, doorIndex, openDoor readback crosses the open/closed threshold; indices 0–3 doors, 4 hood, 5 trunk
onVehicleLockSoundlocked, vehicleCustom lock sound on nearby recipients; play locally, do not rebroadcast
onVehicleAlarmvehicle, duration, actionCustom theft alarm; action is hotwire or lockpick
onLockpickCompletesuccess, vehicle, plateAccepted lockpick completion
onHotwireCompletesuccess, vehicle, plate, modeAccepted hotwire completion; mode is wires or hacking
onVehicleSearchCompletevehicle, plate, rewardAccepted search completion; reward table or false
isPlayerDeadNoneReturn a boolean for your death/incapacitation system

Vehicle arguments are local entity handles. Observed-state hooks are not global vehicle watchers or guaranteed cross-client broadcasts: changes can coalesce, and stale contexts/readback timeouts are skipped. Use your HUD's supported API without feeding these hooks back into another Carlock mutation.

For custom audio, select locking.sound.provider = 'custom' or policeAlerts.vehicleAlarm.provider = 'custom' and implement the matching hook. Keep sound URLs/volume in your own configuration. Stop custom alarms after the supplied duration.

Server listeners​

Edit bridge/listeners/server.lua:

function listeners.onKeyGranted(source, plate)
-- Your server-side integration after a successful key grant.
end

function listeners.onKeyRemoved(source, plate)
-- Your server-side integration after a complete removal.
end

function listeners.onKeyTransferred(source, target, plate, removedFromGiver)
-- Your server-side integration after a completed transfer.
end

source/target are server IDs, plate is a string, and removedFromGiver is a boolean. These notifications are not veto/permission callbacks and should not be used as a replacement for authorizing the initiating action. Individual operations may have their own hook behavior; do not assume every inventory move or locksmith operation emits these notifications.

Legacy events​

The supported vehiclekeys:client:SetOwner compatibility event is described on the exports page. Other callbacks and events coordinate internal action tokens, inventory contexts, UI, or synchronization. In particular, legacy updateVehicle claims of hotwired, failed, or searched are rejected, and the legacy search callback does not grant rewards. Use public exports and editable hooks rather than constructing these internal payloads.