Custom Impound Integration

Route oxide-police impounds to your own impound/garage system by overriding a single o-link bridge function.

This guide shows you how to make the police impound action send vehicles to your own impound/garage system instead of the default one.

It looks technical, but it's really just create one file and paste your code into one spot. Follow the steps in order and you'll be fine.

Do you even need this?

Probably not. If you run one of these, impound already works out of the box — you can stop here:

  • QBCore (qb-garages)
  • Qbox (qbx_garages / qbx_vehicles)
  • ESX (with a standard garage)

You only need this guide if you want impounded cars to go to a different / custom impound resource than the one your framework normally uses.

How it works (the 30-second version)

When an officer impounds a car, oxide-police doesn't talk to your impound system directly. It calls one bridge function in o-link:

vehicles.ImpoundVehicle(plate, fee, lot)

Whatever code is behind that function is where the car goes. So to use your own system, you just replace what that one function does. You do this in o-link (you have the full code for o-link), not in oxide-police.

A car is looked up before your code runs. By default (Config.FieldTools.Impound.registeredVehiclesOnly = true) only player-owned vehicles can be impounded; impounding an unowned vehicle shows the officer a "not registered" message and your code never runs. Set registeredVehiclesOnly = false to also allow unowned vehicles — those are simply removed from the world (your ImpoundVehicle function still runs for owned vehicles). This guide changes where impounds go, not which cars can be impounded.

Steps

Create the file

Inside the o-link resource, create this exact folder and file:

o-link/modules/vehicles/zzz-custom-impound/server.lua

The folder name must start with zzz-. That's not a typo — it makes your file load last so your version wins over the built-in one. Don't rename it to something else.

Paste this in

Open the file you just made and paste this exactly:

-- Sends police impounds to a custom impound system.

olink._register('vehicles', {

    ImpoundVehicle = function(plate, fee, lot)
        -- You are given three things to work with:
        --   plate : text    the car's number plate          example: "ABC 123"
        --   fee   : number  price the owner pays to get it   example: 500
        --   lot   : text    which impound lot                example: "main"

        -- ===================================================================
        -- PUT YOUR CODE HERE.
        -- Call your own impound resource however it expects to be called.
        -- Replace the line below with the real call to your system.
        -- ===================================================================

        exports['my-impound-resource']:Impound(plate, fee, lot)

        -- Return true if it worked, false if it didn't.
        return true
    end,

}, 'zzz-custom-impound')

print('^2[o-link]^0 Custom impound adapter loaded.')

Now change the line in the middle:

exports['my-impound-resource']:Impound(plate, fee, lot)

Replace it with the real call to your impound system. A few examples of what that might look like (use whatever your impound resource's documentation tells you):

-- if your resource has an export:
exports['cool-garages']:ImpoundCar(plate, fee)

-- if your resource uses an event instead:
TriggerEvent('cool-garages:impound', plate, fee, lot)

That's the only line you change. Leave the rest as-is.

Restart and test

  1. Restart o-link (or restart the server).
  2. Watch the server console while it starts. You should see:
    [o-link] Custom impound adapter loaded.
    If you don't see that line, the file is in the wrong place — re-check the path in Step 1.
  3. In-game, impound a car as an officer. It should now go to your system.

That's it. You're done.

What you do NOT have to do

  • You don't remove the car from the world. oxide-police already deletes the vehicle after a successful impound. Your code only needs to record/store it in your system.
  • You don't touch oxide-police. All of this happens in o-link.
  • You don't reimplement anything else. You're only swapping the impound step. Searching plates, the MDT, etc. keep working normally.

Returning cars to owners

How owners get their car back is handled by your impound resource and its own UI/menu — oxide-police is not involved in giving cars back. Set that up the way your resource documents it.

A few config knobs (optional)

These live in oxide-police's config: shared/config/field_tools.lua under Config.FieldTools.Impound. You can edit these without any coding:

SettingWhat it does
defaultFeeThe fee shown to the officer by default
maxFeeHighest fee an officer can set
defaultLotThe lot name sent as lot to your function
durationHow long the impound animation/progress takes

Troubleshooting

Next Steps