Configuration Reference

Per-key reference for the shipped oxide-police config files and DB-backed settings.

Reference for the shipped oxide-police config files and DB-backed settings.

Use /police settings for resource-wide settings. On first boot, the current config-file values are seeded into oxide_settings; after that, the database is the source of truth and file values are factory defaults used by reset-to-default and new-key backfill. Departments, stations, grades, garages, armories, uniforms, channels, detention points, and placed cameras remain in their existing admin/database workflows under /police admin.

SpeedCam.Models, FleetCatalog, and PlaceableObjects.props contain locale-baked labels. Those labels are frozen into the database when their top-level key is first seeded. After changing ox:locale, delete the corresponding oxide_settings rows and restart oxide-police to seed the new labels (this also discards saved edits to those keys):

DELETE FROM oxide_settings
WHERE resource = 'oxide-police'
  AND setting_key IN ('SpeedCam', 'FleetCatalog', 'PlaceableObjects');

shared/config.lua

Global

SettingDefaultDescription
Config.DebugfalseEnables verbose console output from each module
Config.UseBankingAccounttrueCreates a department banking account through oxide-banking
Config.BankingAccountStartBalance30000Starting treasury balance for newly created departments
Config.SalaryInterval15 * 60 * 1000Payroll tick interval (ms). Default 15 minutes
Config.PlayerManagementtrueWhen true, salaries debit the department treasury and unpaid ticks accrue in police_unpaid_payroll for boss settlement. When false, salaries are paid directly from the framework with no treasury impact
Config.UnpaidHoursDecayDays30Days after which unpaid payroll rows are pruned
Config.AllowBossSetupfalseLets a department boss open /police admin for their own department only to set up its stations, interaction points, garages, doors, CCTV, speed cameras, detention points and jail policy — without server-level admin. Bosses can never create/delete/rename a department, fund a treasury, or reach the server-wide screens. Enforced server-side. See Admin → Letting department bosses set up their own stations
Config.MaxLoadoutItems50Max items per armory loadout
Config.FleetRecoveryFee750Charged to the department treasury each time a boss tows a checked-out fleet vehicle back from the field (Fleet screen). 0 = free
Config.InteractionDistance3.0Generic interaction reach
Config.StationZoneSizevec3(1.4, 1.4, 1.8)Default ox_target box size for station zones
Config.StationZoneDistance2.0ox_target per-option reach for station zones
Config.RequireStationClockIntrueWhen true, officers can only go on/off duty at a station's clock-in zone, and the /police duty command and the duty toggle inside the police radial menu are disabled. Set to false to let officers toggle duty from anywhere
Config.AllowMultiDepartmentfalseWhen true, a character can belong to several departments at once (each with its own badge, callsign, rank, and payroll); their active department follows whichever police job is selected in the framework / multi-job menu. When false, hiring into a second department transfers them out of the first. Required for g-multijob — see the ESX setup guide
Config.ActionMenuKey'F2'Default keybind for the police actions menu (+policeactions)

Admin tools are not gated by a custom ACE permission. The /police admin panel and admin commands use your server's standard admin permission — the same one used elsewhere on your server. See Admin → Permissions.

Doors

SettingDefaultDescription
Config.Doors.InteractionDistance0.8ox_target sphere radius around each door
Config.Doors.ZoneDistance1.8ox_target per-option reach for door zones
Config.Doors.ToggleKey'L'Hotkey to toggle the nearest door's lock
Config.Doors.ToggleMaxDistance2.0Max range (m) the hotkey will pick up a door
Config.Doors.PickerMaxDistance10.0Door-picker max range
Config.Doors.LockSound / UnlockSoundDOOR_LOCK / DOOR_UNLOCKAudio bank settings

Speed unit

SettingDefaultDescription
Config.SpeedUnit'MPH''MPH' or 'KMH'. Used by both radar and speed cameras

Radar

SettingDefaultDescription
Config.Radar.KeyToggle'K'Vehicle radar on/off
Config.Radar.KeyLockFront'J'Lock the front-facing target
Config.Radar.KeyLockRear'M'Lock the rear-facing target
Config.Radar.TickMs250Raycast interval while radar is on
Config.Radar.OffsetFrontvec2(5.0, 50.0)Front raycast start.x / end.y relative to vehicle
Config.Radar.OffsetRearvec2(-5.0, -50.0)Rear raycast offset
Config.Radar.HandheldWeapon'WEAPON_RADAR'The handheld radar weapon name
Config.Radar.HandheldRange100.0Max range (m) of the handheld radar
Config.Radar.LineStartZOffset0.05Visual lift on the aim line
Config.Radar.Overlay.*NUI card placement, scaling, and anti-flicker grace. Config.Radar.Overlay.updateInterval (default 0) caps how often the floating speed readout refreshes, in ms; 0 = every frame

CitizenEmail

Controls outbound auto-emails sent to citizens via olink.phone / oxide-phone after a speed camera catch or a field citation. The From strings use a single %s substitution that is filled with the department name (e.g. traffic@lspd.gov).

SettingDefaultDescription
Config.CitizenEmail.EnabledtrueMaster toggle for all auto-emails
Config.CitizenEmail.Speedcam.EnabledtrueEmail the driver when a speed camera issues a fine
Config.CitizenEmail.Speedcam.From'traffic@%s.gov'Sender address for speed-camera emails
Config.CitizenEmail.Citation.EnabledtrueEmail the citizen when an officer issues a field citation
Config.CitizenEmail.Citation.From'citations@%s.gov'Sender address for citation emails

SpeedCam

SettingDefaultDescription
Config.SpeedCam.Models{ ['prop_cctv_pole_03'] = { label = 'CCTV Pole' } }Camera prop models offered in the placement dialog
Config.SpeedCam.CatchCooldown30000ms a camera ignores re-triggers after a catch
Config.SpeedCam.SoundVolume0.3Catch sound volume (0.0 - 1.0)
Config.SpeedCam.BlipSprite / BlipColor / BlipScale184 / 1 / 0.85Map blip styling
Config.SpeedCam.DefaultSensorRadius3.0Default detection radius (m)
Config.SpeedCam.MaxPlacementDistance15.0Max placement reach from the admin
Config.SpeedCam.MaxFineMultiplier3Caps the fine multiplier configurable per camera

shared/config/bodycam.lua

SettingDefaultDescription
Config.Bodycam.itemName'body_cam'Inventory item that toggles the bodycam when used
Config.Bodycam.maxWatchDistance60.0Distance (m) before the camera resets to the wearer's location
Config.Bodycam.pollIntervalMs2500Interval for distance / wearer-alive checks
Config.Bodycam.headBone46240Bone the camera attaches to
Config.Bodycam.cameraOffsetvector3(0.0, 0.18, 0.05)Camera offset relative to head bone
Config.Bodycam.cameraRotationvector3(0.0, 0.0, 0.0)Per-frame rotation bias on top of wearer heading
Config.Bodycam.fov50.0Bodycam field of view
Config.Bodycam.timecycleEffect'Island_CCTV_ChannelFuzz'Visual fuzz overlay
Config.Bodycam.timecycleStrength0.20Fuzz strength
Config.Bodycam.sameDepartmentOnlytrueFilter /police bodycams roster to the watcher's department
Config.Bodycam.tabletAnimationtrueHold a tablet prop while browsing the bodycam viewer

Bodycam recording

Officers actively watching another officer's feed can capture clips that upload to Fivemanage or post to a Discord webhook. Recording happens on the watcher's machine — wearers never produce frames themselves. Native game audio cannot be captured from the browser layer; only mic and page audio are recorded.

SettingDefaultDescription
Config.Bodycam.recording.enabledtrueMaster toggle for the recorder
Config.Bodycam.recording.provider'fivemanage''fivemanage' or 'discord'
Config.Bodycam.recording.maxDurationS45Max clip length in seconds
Config.Bodycam.recording.framerate24Capture framerate
Config.Bodycam.recording.videoBitrate600000Video bitrate in bps (600 kbps × 45 s ≈ 3.4 MB)
Config.Bodycam.recording.audio.enabledtrueCapture audio
Config.Bodycam.recording.audio.echoCancellationtrueApply echo cancellation to mic input
Config.Bodycam.recording.audio.noiseSuppressiontrueApply noise suppression to mic input
Config.Bodycam.recording.audio.capturePageAudiotrueBest-effort page-audio capture
Config.Bodycam.recording.hotkey'F6'Toggle a manual clip while watching
Config.Bodycam.recording.thumbnail.enabledtrueCapture a thumbnail frame for the recording row
Config.Bodycam.recording.thumbnail.captureSeconds1.0When in the clip the thumbnail is grabbed
Config.Bodycam.recording.thumbnail.quality0.7JPEG quality (0.0 - 1.0)
Config.Bodycam.recording.discordWebhook''Webhook URL when provider = 'discord' (leave blank to disable)
Config.Bodycam.recording.autoRecordOnWatchStarttrueStart a recording automatically on watch start
Config.Bodycam.recording.cooldownBetweenManualClipsS2Cooldown between manual hotkey toggles (s)
Config.Bodycam.recording.discordMaxBytes26214400Max file size posted to Discord (25 * 1024 * 1024)

Fivemanage uploads require the FIVEMANAGE_MEDIA_API_KEY convar (the same key used by the mugshot pipeline).

shared/config/breathalyzer.lua

The breathalyzer reads BAC from your drunk system. Edit Config.Breathalyzer.sources to plug in whichever resource your server uses; the first source that returns a numeric value wins.

SettingDefaultDescription
Config.Breathalyzer.sources{ metadata: alcohol, metadata: drunk }Ordered list of source descriptors
Config.Breathalyzer.multiplier1.0Multiplied with the raw value before display
Config.Breathalyzer.maxDisplay200Display is clamped to [0, maxDisplay]
Config.Breathalyzer.overLimit80Threshold (post-multiplier) for the OVER LIMIT flash
Config.Breathalyzer.cautionLimit50Threshold for the caution color

Source descriptor types:

  • { type = 'metadata', key = '<key>' } — character metadata via o-link
  • { type = 'export', resource = '<res>', fn = '<fn>' } — server-side export
  • { type = 'client_export', resource = '<res>', fn = '<fn>' } — client-side export
  • { type = 'client_callback' } — registers oxide:police:client:reportBac for adapter use

shared/config/cctv.lua

SettingDefaultDescription
Config.Cctv.defaultModel'p_cctv_s'Default CCTV prop model
Config.Cctv.placementKeyHelpPlace[LMB] Place ...Help text during placement
Config.Cctv.placementKeyHelpAim[Arrow Keys] ...Help text during default-view aim
Config.Cctv.raycastDistance25.0Placement raycast reach
Config.Cctv.propZOffset-0.10Z offset to correct ceiling-mount origin
Config.Cctv.placementWheelRotateStep5.0Degrees per scroll step
Config.Cctv.placementOutlineColor{ r = 0, g = 220, b = 255, a = 220 }Placement preview color (red, green, blue, alpha, each 0-255)
Config.Cctv.temporaryDurationSeconds86400Lifetime (s) for officer-placed cameras
Config.Cctv.viewerFov50.0Viewer FOV
Config.Cctv.viewerYawSpeed0.4Yaw rotation speed
Config.Cctv.viewerPitchSpeed0.3Pitch rotation speed
Config.Cctv.viewerPitchClampDeg89.0Max pitch (deg)
Config.Cctv.viewerMaxDistance200.0Camera far-clip distance (m); geometry beyond this is not drawn in the feed
Config.Cctv.timecycleEffect'Island_CCTV_ChannelFuzz'Visual fuzz overlay
Config.Cctv.timecycleStrength0.25Fuzz strength
Config.Cctv.expiryTickSeconds600Server tick for expiring temporary cameras
Config.Cctv.tabletAnimationtrueHold a tablet prop while browsing the CCTV viewer

shared/config/charges.lua

Config.DefaultCharges is the seed catalog imported into the police_charges_catalog table the first time the resource starts with an empty catalog. It ships with 100 entries spanning traffic infractions (1xx), traffic misdemeanors (2xx), public order (3xx-4xx), property (5xx), violent (6xx), weapons (7xx), drugs (8xx), financial (9xx), and miscellaneous (10xx).

Each entry has:

FieldTypeDescription
codestringPenal code reference (e.g. 1-01)
titlestringCharge title
categorystring'infraction', 'misdemeanor', or 'felony'
descriptionstringLong-form description shown in the MDT
fine_amountnumberDefault fine in dollars
jail_timenumberDefault jail time in months (0 for fine-only)

After first import, charges are managed through the MDT's Catalog tab (admin only). Editing this file does not retroactively modify the database; use the MDT to update charges already in the catalog.

shared/config/compat.lua

Per-framework compatibility shim toggles.

Global

SettingDefaultDescription
Config.Compatibility.enabledtrueMaster toggle for every compatibility shim. Set to false to disable all framework shims
Config.Compatibility.debugfalseVerbose logging for the shim modules

Config.Compatibility['qb-core']

SettingDefaultDescription
enabledtrueEnable QBCore back-compat shim
copCount.enabledtrueBroadcast cop count to QB robbery scripts
copCount.refreshIntervalMs60000Forced refresh interval
copCount.debounceMs500Debounce for duty change events
copCount.eventName'police:SetCopCount'Event triggered with (count)
callbacks.enabledtrueRegister QB-style callbacks (police:GetCops, etc.)
callbacks.policeForcePresentMinGrade2Min grade counted by police:server:IsPoliceForcePresent
handcuff.exportIsHandcuffedtrueExpose exports['qb-policejob']:IsHandcuffed()
handcuff.allowLegacyClearOnlytrueLegacy clear-cuffs event only clears, never applies

Config.Compatibility['g-multijob']

SettingDefaultDescription
enabledtrueMirror oxide-police hires, fires, and promotions into the in-game g-multijob menu so officers can switch into and out of their police job. Has no effect unless g-multijob is installed and Config.AllowMultiDepartment is true (see the Global section above). Set to false to stop oxide-police from touching the g-multijob list

Config.Compatibility['es_extended']

SettingDefaultDescription
enabledtrueEnable ESX shim
jobs{ police, lspd, bcso, sasp, sheriff, statetrooper }ESX jobs treated as LEO
jobSync.enabledfalseMirror Oxide departments into ESX jobs table
jobSync.syncOnStarttrueRun sync at resource start
jobSync.syncOnChangetrueRun sync when departments change
jobSync.setSalaryToZerotrueForce ESX salary to 0 (Oxide pays salaries)
jobSync.jobType'leo'ESX job_type value written for synced jobs
callbacks.enabledtrueRegister ESX-style callbacks
callbacks.registerPoliceJobCallbackstrueRegister esx_policejob-style callbacks
callbacks.registerServiceCallbacksfalseRegister esx_service callbacks (off by default; Oxide manages duty)
inventory.syncInvBusyWithCuffstrueSync ox_inventory busy state with cuffs

shared/config/custody.lua

Per-station jail config (jail cells, stripping mode, holding cells, mugshot booth) lives in the database and is set through /police admin. This file holds resource-wide constants only.

SettingDefaultDescription
Config.Custody.TickInterval3000Sentence-tick interval (ms)
Config.Custody.ReduceOfflineTimefalseWhen true, sentences continue counting down while the inmate is offline. The server decrements remaining_seconds on the same cadence as the online tick and auto-releases records that hit zero
Config.Custody.SecondsPerMonth60Conversion factor used by /police jail <id> <months>: real seconds per RP-month
Config.Custody.Cutscene.FadeOut500Pre-jail fade-out (ms)
Config.Custody.Cutscene.FadeIn500In-cell fade-in (ms)
Config.Custody.Cutscene.BeforeShot2000Pause before mugshot
Config.Custody.Cutscene.AfterShot2000Pause after mugshot
Config.Custody.Revive.EnabledtrueUse prison revive on inmate death
Config.Custody.Revive.Cutscene.*Fade and groggy timings for revive
Config.Custody.Uniform.Male / FemaleInmate uniform component drawables
Config.Custody.Animationmp_character_creation@customise@male_a / loopIdle anim for stripping
Config.Custody.Locker.StashPrefix'police_jail_locker_'Stash ID prefix for stripped items
Config.Custody.Locker.Slots50Locker slot count
Config.Custody.Locker.MaxWeight500000Locker weight cap (g)
Config.Custody.RemoveAfterRelease{}String array of items wiped on release regardless of stripping mode
Config.Custody.ZoneRecheckMs1500Inmate zone-recheck interval

shared/config/evidence.lua

SettingDefaultDescription
Config.Evidence.types.blood.expire60Minutes until auto-cleanup
Config.Evidence.types.blood.cooldown10Seconds between blood spawns per player
Config.Evidence.types.blood.chance70% chance on taking damage
Config.Evidence.types.bullet.expire60Minutes until auto-cleanup
Config.Evidence.types.fingerprint.expire120Minutes until auto-cleanup
Config.Evidence.gsr.duration600Seconds GSR persists on the suspect
Config.Evidence.gsr.washInWatertrueWater (IsPedSwimming) wipes GSR
Config.Evidence.fingerprints.chance80% chance to leave a print on vehicle entry without gloves
Config.Evidence.fingerprints.expire120Vehicle fingerprint expiry (min)
Config.Evidence.processingPer-evidence-item processing duration and result label
Config.Evidence.registrableItems(large list)Items submittable to the evidence registry
Config.Evidence.registrablePatterns{ 'weapon_' }Item-name prefixes treated as evidence
Config.Evidence.locker.slots / weight / minGrade50 / 100000 / 0Evidence locker size and min grade (lockers are per case; the station point is the access gate)
Config.Evidence.locker.sealOnCaseClosefalseSeal a case's evidence locker once the case is closed
Config.Evidence.includeWeaponSerialtrueRecord the firing weapon's serial on spent casings
Config.Evidence.collectDistance2.0Max distance to collect a drop
Config.Evidence.collectAnimAnimation played during collection
Config.Evidence.renderSleep0Milliseconds the evidence draw loop waits between frames while a marker is on screen. 0 means every frame (smoothest). Raise it slightly to reduce client load at the cost of marker smoothness
Config.Evidence.idleSleep1000Milliseconds the evidence draw loop waits when no markers are nearby. Higher saves performance when there is nothing to draw
Config.Evidence.OfficersDropBulletstrueWhen false, on-duty officers leave no bullet casings (so range training / duty firefights don't litter collectable evidence). Off-duty officers and civilians always drop
Config.Hooks.EvidenceIsDropExemptfunctionReturn true to suppress every world-evidence drop the local player would create (bullet casings, blood, vehicle fingerprints). See example below
Config.Hooks.EvidenceCheckPlayerGlovesfunctionReturns true if the player has gloves equipped
Config.EvidenceWeapons(table)File-authoritative weapon name + ammo type catalog used by ballistics reports

Tracing a casing back to a gun

With includeWeaponSerial on, a spent casing records the serial of the weapon that fired it. When an officer collects the casing, the evidence locker shows the serial and the name it is registered to, and the same serial can be looked up in the MDT's Weapons tab.

The serial is worked out on the server from the weapons the shooter is actually carrying, so a modified game client cannot invent a serial or hide its own. Two situations deliberately record no serial rather than guess:

  • the shooter is carrying two of the same model with different serials, or one of them has no serial at all — there is no single right answer;
  • the weapon isn't an inventory item, which is how some frameworks handle weapons.

Turn includeWeaponSerial off if your server doesn't use weapon registration. Casings collected before you turned it on simply show no serial; nothing breaks.

Sealing evidence lockers when a case closes

Every case gets its own evidence locker, and by default those lockers stay open forever — including for cases closed years ago. Turning on locker.sealOnCaseClose means that closing a case seals its locker: officers can still see everything inside from the evidence screen, but the locker itself will not open, so nothing can be added, removed or swapped after the fact.

Reopening the case unseals the locker again, and the contents are untouched throughout.

This is off by default, so updating changes nothing. Turn it on deliberately — officers used to closing a case and then reaching back into the locker will notice.

To reclaim the space, an admin can permanently empty a sealed locker with /police purgeevidence (see the admin guide). That destroys the contents and cannot be undone, which is why it is admin-only and why the locker has to be sealed first.

Excluding players from evidence drops (EvidenceIsDropExempt)

Config.Hooks.EvidenceIsDropExempt runs client-side before any drop is sent. Return true and the local player leaves no bullet casings, blood, or vehicle fingerprints. Use it to exempt minigames or other special states with your own resource's exports:

Config.Hooks.EvidenceIsDropExempt = function()
    if exports['pug-paintball']:IsInPaintball() then return true end
    return false
end

The function is wrapped in a pcall, so an error inside it won't break evidence generation — it just falls back to "not exempt".

shared/config/field_actions.lua

Tickets

SettingDefaultDescription
Config.FieldActions.Tickets.enabledtrueAllow field citations
Config.FieldActions.Tickets.requireDutytrueOfficer must be on duty
Config.FieldActions.Tickets.maxFine10000Max fine per ticket
Config.FieldActions.Tickets.allowManualFinetrueAllow officer to override the catalog amount
Config.FieldActions.Tickets.useChargeCatalogtrueSource charges from the MDT catalog
Config.FieldActions.Tickets.defaultNotes'Field citation'Default note text

Carry

SettingDefaultDescription
Config.FieldActions.Carry.enabledtrueAllow fireman's carry
Config.FieldActions.Carry.requireTargetRestrainedfalseTarget must be cuffed / zip-tied
Config.FieldActions.Carry.stopKey'E'Key to stop carrying
Config.FieldActions.Carry.maxDistance2.0Engage reach (m)
Config.FieldActions.Carry.animations.*Carrier and carried anims, attach offsets

Headbag

SettingDefaultDescription
Config.FieldActions.Headbag.enabledtrueAllow headbag usage
Config.FieldActions.Headbag.requireItemfalseRequire headbag item
Config.FieldActions.Headbag.requireTargetRestrainedOrHandsUptrueTarget must be restrained or have hands up
Config.FieldActions.Headbag.itemName'headbag'Item to consume / require
Config.FieldActions.Headbag.model'prop_money_bag_01'Prop model
Config.FieldActions.Headbag.bone / offset / rotationAttach config
Config.FieldActions.Headbag.blackoutOpacity0.98Target overlay opacity

Cuffs

SettingDefaultDescription
Config.FieldActions.Cuffs.hardCuffEnabledtrueAllow officer-side hard-cuff
Config.FieldActions.Cuffs.lockpickEnabledtrueAllow lockpicking out of cuffs
Config.FieldActions.Cuffs.lockpickItem'lockpick'Item required to lockpick
Config.FieldActions.Cuffs.lockpickConsumesOnSuccessfalseConsume on success
Config.FieldActions.Cuffs.lockpickConsumesOnFailurefalseConsume on failure
Config.FieldActions.Cuffs.hardCuffDisableSprinttrueForce-disable sprint while hard-cuffed
Config.FieldActions.Cuffs.lockpickSkillCheck{ 30 / 1.5 x3 }lib.skillCheck rounds

Ziptie

SettingDefaultDescription
Config.FieldActions.Ziptie.enabledtrueAllow zip-tie usage
Config.FieldActions.Ziptie.requireDutyfalseWhether zip-ties are officer-only (off by default so civilians can use them)
Config.FieldActions.Ziptie.requireTargetAlivetrueTarget must be alive
Config.FieldActions.Ziptie.itemName'ziptie'Item to consume
Config.FieldActions.Ziptie.consumeOnApplytrueConsume the zip-tie on apply
Config.FieldActions.Ziptie.applyDuration3500Apply duration (ms)
Config.FieldActions.Ziptie.maxDistance2.5Engage reach (m)
Config.FieldActions.Ziptie.autoReleaseSeconds300Auto-release after (s); 0 disables
Config.FieldActions.Ziptie.cutItems{ 'scissors' }Items that can cut a zip-tie
Config.FieldActions.Ziptie.cutIcon'fas fa-scissors'FontAwesome icon shown on the "cut zip-tie" target option
Config.FieldActions.Ziptie.cutDuration4000Cut duration (ms)
Config.FieldActions.Ziptie.consumeCutItemOnSuccessfalseConsume the cutting item after a successful cut

StationServices

SettingDefaultDescription
Config.FieldActions.StationServices.bellsEnabledtrueEnable station bells
Config.FieldActions.StationServices.trashEnabledtrueEnable trash bins
Config.FieldActions.StationServices.trashClearabletrueAllow officers to clear the bin
Config.FieldActions.StationServices.bellCooldownMs30000Cooldown between bell rings
Config.FieldActions.StationServices.trashSlots30Slots per bin
Config.FieldActions.StationServices.trashWeight50000Bin weight cap (g)
Config.FieldActions.StationServices.trashClearMinGrade0Min grade to clear bins
Config.FieldActions.StationServices.trashAutoClearMs3600000Auto-clear interval; 0 disables
Config.FieldActions.StationServices.firearmRegistrationEnabledtrueEnable the civilian firearm registration desk
Config.FieldActions.StationServices.firearmRegistrationFee250Fee charged per firearm, taken from the registrant's bank and deposited into the station's department treasury

shared/config/field_tools.lua

WheelClamp

SettingDefaultDescription
Config.FieldTools.WheelClamp.enabledtrueEnable wheel clamps
Config.FieldTools.WheelClamp.requireDutytrueOfficer must be on duty
Config.FieldTools.WheelClamp.requireItemtrueRequire wheel_clamp item
Config.FieldTools.WheelClamp.itemName'wheel_clamp'Item name
Config.FieldTools.WheelClamp.model'tire_clamp'Streamed prop
Config.FieldTools.WheelClamp.installDuration5000Install duration (ms)
Config.FieldTools.WheelClamp.removeDuration4000Removal duration (ms)
Config.FieldTools.WheelClamp.maxDistance3.0Engage reach (m)
Config.FieldTools.WheelClamp.wheelBone'wheel_lf'Bone the clamp attaches to
Config.FieldTools.WheelClamp.externalJobs{}Non-police jobs allowed to work on clamps
Config.FieldTools.WheelClamp.externalCommand'removeclamp'Chat command for those jobs; false registers none

Letting tow drivers remove clamps. By default only police touch wheel clamps, so a clamped car stays clamped until an officer is free. externalJobs lets you name other jobs that may help, keyed by the job name your framework uses:

externalJobs = {
    ['tow']      = { allowApply = false, requireOnDuty = false },
    ['mechanic'] = { allowApply = false, requireOnDuty = true },
},
KeyDefaultMeaning
allowApplyfalseAlso allows fitting clamps, not just removing them
requireOnDutyfalseThe player must be clocked on in that job

These jobs remove clamps through their targeting menu (aim at the clamped vehicle) or the externalCommand chat command, which is there for servers running no targeting script.

Removal by one of these jobs never hands back a wheel_clamp item — that is police equipment, and refunding it would give every tow driver a way to stock up. Officers still get theirs back as normal. And leaving externalJobs empty keeps the old police-only behaviour exactly, so upgrading changes nothing until you fill it in.

MouthTape

SettingDefaultDescription
Config.FieldTools.MouthTape.enabledtrueEnable mouth tape
Config.FieldTools.MouthTape.requireDutytrueOfficer must be on duty
Config.FieldTools.MouthTape.requireItemtrueRequire the item in inventory
Config.FieldTools.MouthTape.itemName'mouthtape'Item name
Config.FieldTools.MouthTape.model'e_ducktape'Streamed tape prop
Config.FieldTools.MouthTape.requireTargetRestrainedOrHandsUptrueTarget must be restrained or have hands up
Config.FieldTools.MouthTape.applyDuration2500Apply duration (ms)
Config.FieldTools.MouthTape.removeDuration2000Removal duration (ms)
Config.FieldTools.MouthTape.bone / attachProp attach point
Config.FieldTools.MouthTape.voice.pmaVoicetrueDisable pma-voice on tape
Config.FieldTools.MouthTape.voice.yacaVoicetrueDisable yaca-voice on tape

TrackingBand

SettingDefaultDescription
Config.FieldTools.TrackingBand.enabledtrueEnable tracking bands
Config.FieldTools.TrackingBand.requireDutytrueOfficer must be on duty
Config.FieldTools.TrackingBand.requireItemtrueRequire the item in inventory
Config.FieldTools.TrackingBand.itemName'tracking_band'Item name
Config.FieldTools.TrackingBand.model'gps_tracker'Streamed band prop
Config.FieldTools.TrackingBand.requireTargetRestrainedOrHandsUptrueTarget must be restrained or have hands up
Config.FieldTools.TrackingBand.applyDuration4000Apply duration (ms)
Config.FieldTools.TrackingBand.removeDuration3500Removal duration (ms)
Config.FieldTools.TrackingBand.updateCoordsMs1000GPS update interval (ms)
Config.FieldTools.TrackingBand.blipRefreshMs1100Blip refresh interval (ms)
Config.FieldTools.TrackingBand.bone / attachProp attach point
Config.FieldTools.TrackingBand.blip.*Blip sprite, color, scale, pulse, heading, name prefix

Impound

SettingDefaultDescription
Config.FieldTools.Impound.enabledtrueEnable vehicle impound
Config.FieldTools.Impound.requireDutytrueOfficer must be on duty
Config.FieldTools.Impound.registeredVehiclesOnlytrueOnly impound owned vehicles
Config.FieldTools.Impound.defaultFee500Default impound fee
Config.FieldTools.Impound.defaultLot'main'Default impound lot
Config.FieldTools.Impound.maxFee50000Max impound fee
Config.FieldTools.Impound.duration6000Impound action duration (ms)
Config.FieldTools.Impound.saveVehiclePropstrueSave vehicle properties on impound

Want impounded cars sent to your own impound/garage system? See Custom Impound.

shared/config/fleet_catalog.lua

SettingDefaultDescription
Config.FleetAddons.radar5000Per-unit surcharge for the radar addon (rolled into replacement_cost)
Config.FleetAddons.megaphone2500Per-unit surcharge for the megaphone addon
Config.FleetCatalog(table)Vehicle catalog grouped by category. Each entry: model, label, cost

Shipped categories: Patrol, Pursuit, Tactical, Motorcycle. cost is both purchase price and replacement cost when added to a department.

shared/config/interactions.lua

Cuffing

SettingDefaultDescription
Config.Cuffing.Animation'advanced''basic' (front only) or 'advanced' (front/back detection)
Config.Cuffing.Models.cuffsCuff prop model + per-mode coords / rotation
Config.Cuffing.Models.ziptieZiptie prop model + per-mode coords / rotation
Config.Cuffing.Anims.rear / front / deadOfficer / target / attach anims per mode
Config.Cuffing.UncuffAnimsUncuff anim and durations
Config.Cuffing.Idle.rear / frontIdle anim while cuffed
Config.Cuffing.BreakMinigametrueAllow target to attempt to break free
Config.Cuffing.SkillCheck{ easy, easy, medium }lib.skillCheck rounds for break attempt
Config.Cuffing.EscapeCooldown30000Cooldown between break attempts (ms)
Config.Cuffing.Bone60309Cuff attach bone

Escort

SettingDefaultDescription
Config.Escort.Bone11816Officer-target attach bone
Config.Escort.Offsetvector2(0.25, 0.25)Escort offset
Config.Escort.RecheckMs500Position recheck interval
Config.Escort.OfficerAnim / TargetAnim.*Walk / idle animations
SettingDefaultDescription
Config.Search.Officeranim@gangops@facility@servers@bodysearch@Officer anim
Config.Search.Duration5500Search duration (ms)

Vehicle

SettingDefaultDescription
Config.Vehicle.SearchRadius5.0Vehicle action search radius (m)

Tackle

SettingDefaultDescription
Config.Tackle.EnabletrueEnable tackle
Config.Tackle.Key'G'Default keybind
Config.Tackle.Command'+policetackle'Command name (used by RegisterKeyMapping)
Config.Tackle.Distance3.0Tackle reach (m)
Config.Tackle.Cooldown10000Tackle cooldown (ms)
Config.Tackle.Type'animation''animation' or 'ragdoll'
Config.Tackle.RagdollAfter4000Ragdoll the victim after (ms)

HandsUp

SettingDefaultDescription
Config.HandsUp.Command'handsup'Command name
Config.HandsUp.Key'X'Default keybind
Config.HandsUp.Cooldown2000Cooldown between toggles (ms)
Config.HandsUp.CheckInterval250Hands-up state check interval (ms)
Config.HandsUp.Animmissminuteman_1ig_2 / handsup_baseStanding hands-up animation
Config.HandsUp.KneelEnabledtrueAllow the kneeling pose
Config.HandsUp.HoldThreshold400How long the key must be held to kneel (ms)
Config.HandsUp.KneelStickytrueKneel stays after the key is released
Config.HandsUp.KneelAnimrcmminute2 / kneeling_arrest_idleKneeling animation
Config.HandsUp.KneelExitAnimrcmminute2 / kneeling_arrest_get_upStand-up animation

Tap vs hold. Tapping the key puts the player's hands up standing, exactly as before. Holding it past HoldThreshold drops them to a knee instead. Either pose counts as "hands up", so officers can still search, cuff and use field tools on a kneeling suspect.

With KneelSticky on (the default), the kneel stays put once you let go of the key and clears on the next tap — nobody wants to hold a key down for a whole traffic stop. Set it to false if you would rather releasing the key stand the player back up.

If you swap the animation, keep the flag at 1. The standing pose uses flag 50, which only moves the upper body — reuse it on the kneel and the player stays standing and just waves their arms.

Upgrading: the keybind is now registered as +handsup so the resource can tell a tap from a hold. Anyone who rebound hands-up to a different key keeps a working hands-up, but will need to rebind to get hold-to-kneel. /handsup in chat still works and always uses the standing pose.

OfficerTargetMenu

Powers the on-duty officer's contextual ox_target options on other players plus the /cuff and /uncuff chat commands. Each action is toggled with its own enable flag and shows a FontAwesome icon. The cuff, search, and escort options are on by default; every other action is off by default. Options only appear when they make sense (for example, take-out-of-vehicle shows only for a cuffed suspect who is seated in a vehicle). Because aiming at a seated suspect actually hits the vehicle's body or glass, "Take Out of Vehicle" also appears when you third-eye the vehicle itself while it has a restrained occupant — no need to catch the ped through a window.

SettingDefaultDescription
Config.OfficerTargetMenu.EnabletrueRegister the player target options and chat commands
Config.OfficerTargetMenu.Distance2.5ox_target reach and command fallback radius (m) when no serverID is passed
Config.OfficerTargetMenu.RequireDutytrueDefault duty requirement for actions without their own requireDuty
Config.OfficerTargetMenu.CuffCommand'cuff'Chat command name for cuffing
Config.OfficerTargetMenu.UncuffCommand'uncuff'Chat command name for uncuffing
Config.OfficerTargetMenu.Actions.cuff.enable / icontrue / fas fa-handcuffsCuff and uncuff options
Config.OfficerTargetMenu.Actions.search.enable / icontrue / fas fa-magnifying-glassSearch option (cuffed suspects)
Config.OfficerTargetMenu.Actions.escort.enable / icon / requireDutytrue / fas fa-person-walking / trueEscort / stop-escort options (cuffed suspects); requireDuty = false allows civilians
Config.OfficerTargetMenu.Actions.hard_cuff.enable / iconfalse / fas fa-lockHard cuff option (also requires Config.FieldActions.Cuffs.hardCuffEnabled)
Config.OfficerTargetMenu.Actions.carry.enable / icon / requireDutyfalse / fas fa-user-plus / trueCarry / stop-carry options (also requires Config.FieldActions.Carry.enabled); requireDuty = false allows civilians
Config.OfficerTargetMenu.Actions.headbag.enable / icon / requireDutyfalse / fas fa-user-secret / truePut / remove headbag options (also requires Config.FieldActions.Headbag.enabled); requireDuty = false allows civilians
Config.OfficerTargetMenu.Actions.vehicle.enable / icon / requireDutyfalse / fas fa-car-side / truePut in / take out of vehicle options (cuffed suspects); take-out also shows on the vehicle itself when it holds a restrained occupant; requireDuty = false allows civilians
Config.OfficerTargetMenu.Actions.gsr.enable / iconfalse / fas fa-hand-dotsGunshot residue (GSR) check option
Config.OfficerTargetMenu.Actions.ticket.enable / iconfalse / fas fa-receiptIssue ticket option (also requires Config.FieldActions.Tickets.enabled)

Allowing non-police use. Escort, carry, headbag, and vehicle each carry a per-action requireDuty flag (default true). Set it to false to let any player use that action — civilians restrain targets with zip-ties (see Config.FieldActions.Ziptie), which satisfy the "must be restrained" requirement for escort and vehicle (carry never requires restraint; headbag accepts restrained-or-hands-up). Police handcuffs always stay on-duty-only. To fully enable a civilian action that is off by default (e.g. carry), set both Actions.carry.enable = true and Actions.carry.requireDuty = false (and keep Config.FieldActions.Carry.enabled = true). Actions without a requireDuty key fall back to RequireDuty.

Sounds

SettingDefaultDescription
Config.Sounds.EnabledtrueEnable interaction sounds
Config.Sounds.Cuff / Uncuff / Search / TackleSound name + audio bank

CuffedDisabledControls

SettingDefaultDescription
Config.CuffedDisabledControls(list of control IDs)Controls disabled while cuffed (attack, aim, sprint, jump, vehicle entry, etc.)

shared/config/licenses.lua

License types offered in the MDT person profile's Licenses tab. IDs are passed straight to olink.license.*, so each id must also exist in the framework's licenses table (e.g. on ESX, as a row in the licenses table) for native UIs to label it.

SettingDefaultDescription
Config.Licenses.Types{ driver, weapon, business, pilot, boat }List of license definitions; each entry has id (framework key) and label (display name)

Default shipped licenses: Driver's License, Weapons Permit, Business License, Pilot's License, Boating License. Add new entries or remove existing ones to match the licenses your server uses.

shared/config/mdt.lua

SettingDefaultDescription
Config.MDT.fineRevenueSplit50% of fine revenue routed to the department treasury (the rest is the state's share and leaves the economy)
Config.MDT.caseNumberPrefixtruePrefix MDT case numbers with the department code
Config.MDT.dispatchEnabledtrueEnable the Dispatch tab. Requires oxide-dispatch. Set false for ps-dispatch / cd_dispatch / qs-dispatch / wasabi_mdt / etc.
Config.MDT.tabletAnimationtruePlay a tablet-holding animation and attach a tablet prop to the officer's hand while the MDT panel is open
Config.MDT.allowOffDutyfalseAllow officers to open and use the MDT while off duty. When false, the MDT requires clocking in first. The Config.MDT.permissions.accessMdt minimum grade is enforced either way
Config.MDT.useItemfalseWhen true, the MDT can only be opened by using the Config.MDT.itemName inventory item and /police mdt refuses access. When false, the MDT opens with /police mdt and no item is required. The duty / allowOffDuty and accessMdt checks apply either way
Config.MDT.itemName'police_tablet'Inventory item that opens the MDT when useItem is true. The item must be registered in your inventory — see Installation → Register items
Config.MDT.hidden.charIds{}List of char_id strings hidden from MDT person search, profile, and vehicle-owner lookups
Config.MDT.hidden.bypassMinGrade-1Officers at this grade rank or higher still see hidden characters. Set to -1 to disable bypass entirely
Config.MDT.warrants.defaultExpiryHours72Default warrant expiry
Config.MDT.warrants.maxActivePerPerson3Max simultaneous active warrants per person
Config.MDT.bolos.defaultExpiryHours48Default BOLO expiry
Config.MDT.bolos.maxActive50Max simultaneous active BOLOs
Config.MDT.bolos.notifyOnCreatetrueNotify all officers when a BOLO is created
Config.MDT.dashboard.recentActivityCount20Rows shown on the dashboard
Config.MDT.search.maxResults20Max search results
Config.MDT.search.minQueryLength2Min characters before search runs
Config.MDT.permissions.accessMdt0Min grade to open the MDT
Config.MDT.permissions.createCase0Min grade to create a case
Config.MDT.permissions.closeCase2Min grade to close a case
Config.MDT.permissions.issueWarrant2Min grade to issue a warrant
Config.MDT.permissions.recallWarrant3Min grade to recall a warrant
Config.MDT.permissions.issueFine0Min grade to issue a fine
Config.MDT.permissions.processArrest0Min grade to process an arrest
Config.MDT.permissions.manageLicenses1Min grade to grant or revoke licenses via the MDT person profile
Config.MDT.permissions.overrideJail0Min grade to adjust jail time before booking. 0 lets any officer who can process an arrest adjust it
Config.MDT.allowJailOverridetrueLet officers adjust the total jail time before finalising an arrest — for time served, a plea agreement, or an interruption during booking. Set false to remove the field entirely
Config.MDT.limits.maxCountPerCharge10Max occurrences of a charge per call
Config.MDT.limits.maxFinePerCall250000Max fine per call
Config.MDT.limits.maxTextLength500Max chars in warrant / BOLO reason fields
Config.MDT.limits.maxPlateLength16Max plate length
Config.MDT.limits.maxJailPerCall2000Ceiling on an adjusted sentence, in the same units as the catalog's jail_time. Stops a mistyped sentence
Config.MDT.limits.maxImportRows500Max rows accepted in one charge-catalog CSV import

The MDT's charge-catalog editor (the Catalog tab) is not grade-based — it is only available to server admins (the admin permission, the same one that gates /police admin — see Admin → Permissions).

Adjusting jail time before booking

When allowJailOverride is on, the jail total in the Charges tab and the station booking panel becomes an editable field instead of a fixed label. The officer can raise or lower it — for time served, a plea deal, or a booking that got interrupted — up to limits.maxJailPerCall. Setting it to 0 books the arrest and its fine with no jail time at all.

Two things to know:

  • The charge records never change. Each charge keeps the jail time from the catalog; only the sentence actually served is adjusted. Every adjustment is written to the department activity log and the server log with the original total, the new total, and the officer who made the change.
  • The rule is enforced on the server. Hiding the field with allowJailOverride = false, or restricting it with permissions.overrideJail, cannot be bypassed by a modified client.

Turning individual MDT tabs off

Config.MDT.modules has one true/false per tab. Leaving it alone changes nothing — every tab defaults to on.

KeyTab
dashboardDashboard
dispatchDispatch
personSearchPersons
vehicleSearchVehicles
weaponSearchWeapons
reportsReports / cases
chargesCharges (arrest processing)
finesFines
warrantsWarrants
bolosBOLOs
videosVideo storage
catalogCharge catalog editor (admin only)

A disabled tab disappears from the navigation for every officer and its server actions are refused, so it cannot be reached by a modified client. If you disable the tab an officer is currently on, the MDT opens on the first tab that is still enabled.

Turning off charges only removes the MDT's arrest tab — booking a suspect at a station still works.

dispatchEnabled above still works and is treated as modules.dispatch when you haven't set that key, so existing configs need no changes.

shared/config/megaphone.lua

SettingDefaultDescription
Config.Megaphone.handheldRange30.0Hard-cutoff radius (m) for handheld megaphone
Config.Megaphone.vehicleRange50.0Hard-cutoff radius (m) for vehicle PA
Config.Megaphone.animDict / animClipMegaphone animation
Config.Megaphone.propModel'prop_megaphone_01'Megaphone prop
Config.Megaphone.propBone / propOffset / propRotationProp attach
Config.Megaphone.pmaVoicetrueHook pma-voice channels
Config.Megaphone.yacaVoicetrueHook yaca-voice channels
Config.Megaphone.vehicleKey'B'Default vehicle PA toggle key
Config.Megaphone.vehicleKeyDescription'Police: Toggle vehicle PA'Keybind label
Config.Megaphone.driverOnlytrueRestrict vehicle PA to the driver

shared/config/mugshot.lua

Requires the convar:

set FIVEMANAGE_MEDIA_API_KEY "your_key_here"
SettingDefaultDescription
Config.Mugshot.PresignedUrlEndpointhttps://api.fivemanage.com/api/v3/file/presigned-urlUpload endpoint
Config.Mugshot.PhotoCheckRadius1.5Client-side range check for the mugshot mark (m)
Config.Mugshot.ServerGraceDistance3.0Server-side grace range (m)
Config.Mugshot.Webhook''Optional Discord webhook for capture posts (leave blank to disable)
Config.Mugshot.Branding.username / iconUrl / title / colorWebhook branding
Config.Hooks.MugshotBuildEmbed(data)functionReturns the Discord embed payload
Config.Hooks.MugshotSendPhoto(data)functionOverride to route captures elsewhere (Loki / S3 / etc.)

Setting up FiveManage media uploads

Three features in this resource save pictures and video to the cloud so officers can view them later:

  • Mugshots — booking photos taken during arrests
  • Bodycam clips — short video recordings captured while watching an officer's feed
  • Bait car dashcam clips — video from the oxide-baitcar resource (these upload through this resource's pipeline)

All three use a service called FiveManage to store the files. You only need one FiveManage key, and that single key powers all three features. The key is not set in any config file — it lives in your server.cfg (the text file that tells your server which resources to start and holds your server's settings).

Follow these steps once:

Create a free account. Go to https://app.fivemanage.com and sign up. The free tier is enough to get started and does not ask for a credit card.

Create a team. After signing in, create a team — pick any name and team type you like.

Open the Tokens page. In the dashboard menu, go to Tokens (Dashboard → Tokens).

Create a token. Click Create token, choose the Media scope (this one scope covers both images and videos — so it works for mugshots, bodycam, and bait car clips), and give the token a name you'll recognize.

Copy the token. FiveManage shows you the token once. Copy it now.

Paste it into server.cfg. Open your server.cfg and add this line, replacing the example with the token you copied:

server.cfg
set FIVEMANAGE_MEDIA_API_KEY "the_token_you_copied"

Restart your server (or refresh the convar) so the new setting takes effect.

What "working" looks like: after this is set, taking a mugshot during an arrest, recording a bodycam clip, or triggering a bait car dashcam clip will upload successfully and the media will appear in the relevant record. If uploads fail, double-check that the line above is in server.cfg, that the token was copied in full, and that you restarted the server.

shared/config/objects.lua

SettingDefaultDescription
Config.PlaceableObjects.maxPerOfficer15Max placed props per officer
Config.PlaceableObjects.placementMaxDepth10.0Max raycast depth
Config.PlaceableObjects.props(list)Each entry: id, label, model, icon, optional spikeStrip

Shipped props: do-not-cross barrier, A-frame barrier (with and without lights), road-work-ahead barrier, traffic barrier (with and without lights), traffic cone, taller traffic cone, traffic road pole, unmarked traffic cone, spike strip.

shared/config/prisonerjobs.lua

SettingDefaultDescription
Config.PrisonerJobs.EnabledtrueEnable prisoner jobs
Config.PrisonerJobs.SwingCooldownMs1500Server-side cooldown between swings

Mining

SettingDefaultDescription
Mining.SecondsPerSwing10Seconds taken off the remaining sentence per successful swing
Mining.SwingsToBreak8Swings to break a rock
Mining.CooldownMs30000Cooldown after a rock is broken
Mining.SwingDistance2.0Engage reach (m)
Mining.WalkAwayDistance6.0Distance that silently resets the session
Mining.Money.account / amountcash / 0Money reward per break
Mining.ItemDrops{}Item drop table: { item, chance, min, max }
Mining.RockModels(list)Models eligible as rocks
Mining.Pickaxe.*Prop attach: model, bone, offset, rotation
Mining.Anim.*Pickaxe swing anim

Cleaning

SettingDefaultDescription
Cleaning.SecondsPerPickup8Seconds taken off the remaining sentence per pickup
Cleaning.PickupDurationMs3000Pickup duration (ms)
Cleaning.InteractDistance1.8Engage reach (m)
Cleaning.MaxDistance3.0Latency-tolerant max reach (m)
Cleaning.ActiveCount5Concurrent active trash points
Cleaning.PointCooldownMs90000Cooldown per cleaned point
Cleaning.Money.* / ItemDropsReward configuration
Cleaning.TrashModels(list)Models eligible as trash

Electrical

SettingDefaultDescription
Electrical.SecondsOnSuccess60Seconds taken off the remaining sentence on success
Electrical.FailCooldownMs30000Cooldown on failure
Electrical.SuccessCooldownMs15000Cooldown on success (anti-camping)
Electrical.InteractDistance2.0Engage reach (m)
Electrical.MaxDistance3.0Latency-tolerant max reach (m)
Electrical.Anim.scenarioWORLD_HUMAN_WELDINGWelding scenario
Electrical.SkillCheck{ easy, easy, medium }Difficulty of the repair skill-check rounds
Electrical.Money.* / ItemDropsReward configuration

shared/config/prisonshop.lua

The shop location, meal windows, and paid catalog are admin-configured through /police admin → Detention → Prison Shop. Until a location is placed, the shop is dormant.

SettingDefaultDescription
Config.PrisonShop.enabledtrueEnable prison shop
Config.PrisonShop.model's_m_y_prismuscl_01'Vendor ped model
Config.PrisonShop.scenario'WORLD_HUMAN_CLIPBOARD'Vendor scenario
Config.PrisonShop.interactDistance2.5Engage reach (m)
Config.PrisonShop.targetRadius1.5ox_target sphere radius
Config.PrisonShop.blip.*Map blip styling
Config.PrisonShop.freeItem'prison_food_tray'Item handed out free during meal windows
Config.PrisonShop.freeMealRestore.hunger50Hunger restored when the free meal tray is consumed
Config.PrisonShop.freeMealRestore.thirst15Thirst restored when the free meal tray is consumed
Config.PrisonShop.categories{ food, drink, misc }Menu category headers

Next Steps