Browse docs

Fake Plate Integration

Integrate garages, frameworks, Police tools, and custom resources with real and displayed vehicle plates.

Sky Mechanic Job keeps two plate identities while a fake plate is active:

ValuePurpose
Real platePersistent ownership, garage database lookups, keys, and stored vehicle records
Display plateThe plate visible on the vehicle and to Police, radar, dispatch, cameras, and UI

A resource must deliberately choose which identity it needs. Do not apply the real-plate override to every resource.

Choose an integration mode

ConsumerRecommended integration
Garage or framework code that always needs the stored vehicle identityNative override
Custom resource that sometimes needs the real plate and sometimes the displayed plateExplicit helper functions
Police, dispatch, radar, camera, or visible UINo native override; keep the displayed plate
Garage that despawns and later respawns vehiclesServer exports in addition to one of the lookup integrations
Load only one compatibility file in a consuming resource. Do not load both files together.

Native override for garage resources

Add the compatibility file to the consuming garage resource, not to the Sky Mechanic Job manifest:

shared_script "@sky_mechanicjob/compat/fakeplates_realplate_native.lua"

dependency "sky_mechanicjob"

When the resource already has a shared_scripts block, add the compatibility file as its first entry and retain its existing entries:

shared_scripts {
    "@sky_mechanicjob/compat/fakeplates_realplate_native.lua",
    "config.lua"
}

dependency "sky_mechanicjob"

Place the compatibility entry before the consuming resource's own shared scripts. It makes calls to GetVehicleNumberPlateText(vehicle) inside that resource return the real plate while a Sky fake plate is active. It also patches common vehicle-property readers loaded by that resource.

FiveM gives every resource its own Lua environment. The override therefore affects only the resource that loads this file.

Do not load this override in:

  • Police resources
  • Dispatch resources
  • Radar or speed-camera resources
  • Plate overlays
  • Other UI that should show the plate visible on the vehicle

Explicit real/display plate helpers

Use the helper file when a resource must choose the identity per operation:

shared_script "@sky_mechanicjob/compat/fakeplates.lua"

dependency "sky_mechanicjob"

The file provides these functions inside the consuming resource:

FunctionReturns
SkyGetVehicleDisplayPlateText(vehicle)The currently displayed plate
SkyGetVehicleRealPlateText(vehicle)The persistent real plate
SkyGetVehicleFakePlateState(vehicle)Active fake-plate metadata, or nil
local real_plate = SkyGetVehicleRealPlateText(vehicle)
local display_plate = SkyGetVehicleDisplayPlateText(vehicle)
local fake_plate = SkyGetVehicleFakePlateState(vehicle)

Use real_plate for ownership and database keys. Use display_plate for player-facing labels and observations.

Persist fake plates through garage storage

The compatibility file corrects plate reads, but it cannot persist entity state after the garage deletes the vehicle. A compatible garage must save the fake-plate state before despawning the entity and restore it after the new networked vehicle exists.

Store

Run this on the server while the vehicle entity still exists:

local resolved = exports["sky_mechanicjob"]:ResolveRealPlateForGarageStore(net_id)

if resolved then
    vehicle_data.plate = resolved.realPlate

    if resolved.resetOnGarageStore then
        exports["sky_mechanicjob"]:ClearFakePlate(net_id, "garage_store")
        vehicle_data.skyFakePlate = nil
    else
        vehicle_data.skyFakePlate = exports["sky_mechanicjob"]:GetFakePlateState(net_id)
    end
end

Persist vehicle_data.skyFakePlate with the garage's other vehicle properties. Never replace the persistent database plate with displayPlate.

Restore

After the garage has spawned the vehicle and its network ID resolves to an existing server entity:

if vehicle_data.skyFakePlate then
    local restored, result = exports["sky_mechanicjob"]:RestoreFakePlateState(
        net_id,
        vehicle_data.skyFakePlate,
        "garage_spawn"
    )

    if not restored then
        print(("[garage] Fake plate restore failed: %s"):format(tostring(result)))
    end
end

RestoreFakePlateState validates the real plate, display plate, active state, vehicle entity, and expiry time. An expired fake plate is not restored.

Configuration

Config.FakePlates.resetOnGarageStore controls the intended storage policy:

ValueBehavior
trueStoring the vehicle removes the fake plate
falseA compatible garage may save and restore the fake plate

The default in version 1.20.0 is false.

Test checklist

  • Store a normal vehicle and confirm its database plate is unchanged.
  • Install a fake plate and confirm the garage still finds the vehicle by its real plate.
  • Confirm Police, radar, dispatch, and visible UI continue to show the display plate.
  • Store and respawn the vehicle and confirm the configured reset/persist policy is respected.
  • Confirm expired fake plates are not restored.
  • Restart the consuming garage resource and verify its dependency starts after sky_mechanicjob.