AI Core

ai-vehicles for developers

Server exports, state bags and events of ai-vehicles, and the qbx_vehicles API it answers.

ai-vehicles has server exports only. They are all synchronous (no Promise, no waiting in Lua), except SpawnVehicle, which answers through a callback. Types are in @aicore-fivem/shared (vehicles.ts).

TypeScript
import { resourceExport } from "@aicore-fivem/lib/server";
const vehicles = resourceExport("ai-vehicles");
Lua
local vehicles = exports['ai-vehicles']

To give, take or check keys, store a vehicle in a garage or read fuel, use the lib's layers (vehicleKeys, garages, fuel): they work with whichever key, garage or fuel script the server runs. Call ai-vehicles directly only for ownership itself.

Types

VehicleOwner

Who owns a vehicle.

Prop

Type

OwnedVehicle

What GetVehicle and GetVehicles return.

Prop

Type

Server exports

CreateVehicle

Registers a new owned vehicle and parks it. Use it when a player gets a vehicle (a purchase, a reward, an admin gift). It does not spawn the car: take it out with SpawnVehicle or let the player pick it up at a garage.

Side: Server · Waits: no

Signature
CreateVehicle(owner: VehicleOwner, model: string, garage: string | null, props?: VehicleProps): { id: number; plate: string } | null
Lua
local created = exports['ai-vehicles']:CreateVehicle(owner, model, garage, props) -- { id = number, plate = string } or nil

Parameters

Prop

Type

Returns

{ id, plate } of the new vehicle. null when owner is not a valid owner or model is not text.

Example

import { resourceExport } from "@aicore-fivem/lib/server";

const core = resourceExport("ai-core");
const vehicles = resourceExport("ai-vehicles");

// Gives the player a Sultan, parked at the Motel Parking garage.
export function giveSultan(source: number): string | null {
  const character = core.GetCharacter(source);
  if (!character) return null;
  const created = vehicles.CreateVehicle(
    { type: "character", id: String(character.id) },
    "sultan",
    "pillbox",
  );
  return created?.plate ?? null;
}

GetVehicle

Finds one owned vehicle by its id or plate.

Side: Server · Waits: no

Signature
GetVehicle(ref: number | string): OwnedVehicle | null
Lua
local vehicle = exports['ai-vehicles']:GetVehicle(ref) -- table or nil

Parameters

Prop

Type

Returns

The OwnedVehicle, or null when no vehicle in memory has that id or plate (also when it belongs to an offline character).

Example

const vehicle = vehicles.GetVehicle("AI00001A");
if (vehicle) console.log(vehicle.model, vehicle.state, vehicle.fuel);

GetVehicles

Every vehicle of one owner.

Side: Server · Waits: no

Signature
GetVehicles(owner: VehicleOwner): OwnedVehicle[]
Lua
local list = exports['ai-vehicles']:GetVehicles(owner) -- array

Parameters

Prop

Type

Returns

An array of OwnedVehicle. Empty for an invalid owner, an owner without vehicles, or an offline character.

Example

const fleet = vehicles.GetVehicles({ type: "job", id: "police" });
const parked = fleet.filter((v) => v.state === "garage").length;
console.log(`police: ${parked} of ${fleet.length} cars parked`);

IsOwnedPlate

Whether a plate belongs to an owned vehicle in memory.

Side: Server · Waits: no

Signature
IsOwnedPlate(plate: string): boolean
Lua
local owned = exports['ai-vehicles']:IsOwnedPlate(plate)

Returns

true when an owned vehicle has this plate. false for an unknown plate, a non-text value, or a vehicle of an offline character.

GetVehicleIdByEntity

The ai-vehicles id of a spawned owned vehicle.

Side: Server · Waits: no

Signature
GetVehicleIdByEntity(entity: number): number | null
Lua
local id = exports['ai-vehicles']:GetVehicleIdByEntity(entity)

Parameters

Prop

Type

Returns

The vehicle id, or null when the entity is not an owned vehicle spawned by ai-vehicles.

GetEntity

The entity of a spawned owned vehicle.

Side: Server · Waits: no

Signature
GetEntity(id: number): number | null
Lua
local entity = exports['ai-vehicles']:GetEntity(id)

Returns

The server entity handle, or null when the vehicle is not out or its entity no longer exists.

GetPlateOwners

Every owned vehicle in memory as [plate, ownerType, ownerId]. A script that must check many plates (a key system) reads this once at its start, then follows the ai-vehicles:owners event, instead of calling an export for every check.

Side: Server · Waits: no

Signature
GetPlateOwners(): Array<[plate: string, type: VehicleOwnerType, id: string]>
Lua
local owners = exports['ai-vehicles']:GetPlateOwners() -- { { plate, type, id }, ... }

Returns

An array of triples. Empty when no vehicle is in memory.

SaveVehicle

Saves the condition and look of a vehicle: fuel, damage, state, garage, and props (colors, extras, dirt). The stored tuning (mods, neon) never changes here, so a look read from a player's client cannot save a mod menu's work. Use SaveTuning for tuning.

Side: Server · Waits: no

Signature
SaveVehicle(id: number, change: { props?: VehicleProps; fuel?: number; engine?: number; body?: number; state?: VehicleState; garage?: string | null }): void
Lua
exports['ai-vehicles']:SaveVehicle(id, change)

Parameters

Prop

Type

change

Prop

Type

Returns

Nothing. An unknown id does nothing.

Example

// A repair job finished: full engine and body.
vehicles.SaveVehicle(vehicleId, { engine: 1000, body: 1000 });

SaveTuning

Saves full props, tuning included (mods, neon). Meant for tuning shops only: AI Core's own tuning shop, ai-mechanic, is the only ai-* script that calls it.

Side: Server · Waits: no

Signature
SaveTuning(id: number, props: VehicleProps): void
Lua
exports['ai-vehicles']:SaveTuning(id, props)

Returns

Nothing. Invalid props are ignored. The plate inside the props is always replaced with the vehicle's own.

Never pass props that came straight from a player's client without checking them on the server: whatever you save here is the car's tuning from now on.

StoreVehicle

Parks a vehicle: deletes its entity if it is out and sets its state and garage.

Side: Server · Waits: no

Signature
StoreVehicle(id: number, garage: string | null, state?: VehicleState): void
Lua
exports['ai-vehicles']:StoreVehicle(id, garage, state)

Parameters

Prop

Type

Returns

Nothing. It does not save the condition first: call SaveVehicle before it when the damage and fuel should be kept. To park through whatever garage script the server runs, use the lib's garages.store instead.

SetOwner

Gives a vehicle to another owner (a sale between players, a car moved into a job fleet).

Side: Server · Waits: no

Signature
SetOwner(id: number, owner: VehicleOwner): void
Lua
exports['ai-vehicles']:SetOwner(id, owner)

Returns

Nothing. An invalid owner or unknown id does nothing. The keys of the old owner are not taken: remove them through the lib's vehicleKeys.remove if needed.

Example

vehicles.SetOwner(vehicleId, { type: "job", id: "mechanic" });

DeleteVehicle

Deletes an owned vehicle for good: its entity if it is out, and its database row.

Side: Server · Waits: no

Signature
DeleteVehicle(id: number): void
Lua
exports['ai-vehicles']:DeleteVehicle(id)

Returns

Nothing.

This cannot be undone. The vehicle, its look and its tuning are gone.

SpawnVehicle

Creates the entity of an owned vehicle in the world with its look, plate, fuel and state bags, and gives the keys to asker through the active key system. The vehicle's state becomes out.

Side: Server · Waits: no (the result arrives in cb)

Signature
SpawnVehicle(id: number, at: { x: number; y: number; z: number; heading: number }, asker: number, cb: (netId: number | null) => void, purpose?: KeyPurpose, setup?: VehicleSetup): void
Lua
exports['ai-vehicles']:SpawnVehicle(id, at, asker, function(netId) end, purpose, setup)

Parameters

Prop

Type

Returns

Nothing. cb gets the network id, or null when the vehicle does not exist, is already out, is being spawned right now, or the game could not create it.

Example

import { resourceExport } from "@aicore-fivem/lib/server";

const vehicles = resourceExport("ai-vehicles");

export function bringOut(source: number, vehicleId: number): void {
  const ped = GetPlayerPed(String(source));
  const [x, y, z] = GetEntityCoords(ped);
  const heading = GetEntityHeading(ped);
  vehicles.SpawnVehicle(vehicleId, { x: x + 3, y, z, heading }, source, (netId) => {
    if (netId === null) console.log(`vehicle ${vehicleId} could not come out`);
  });
}

A vehicle that is already out is refused (cb(null)). If its entity later disappears while it is out, it moves to the impound state.

Events

ai-vehicles:owners

Fires when vehicles enter ai-vehicles' memory or change owner, and when plates leave memory. One batch per server tick. Read GetPlateOwners once at start, then apply these batches to keep a plate-to-owner copy. The name is VEHICLES_EVENTS.owners in @aicore-fivem/shared.

Side: Server (local event, not sent to clients)

Prop

Type

import { resourceExport } from "@aicore-fivem/lib/server";
import { VEHICLES_EVENTS } from "@aicore-fivem/shared";

const owners = new Map<string, string>();
for (const [plate, type, id] of resourceExport("ai-vehicles").GetPlateOwners())
  owners.set(plate, `${type}:${id}`);

on(VEHICLES_EVENTS.owners, (puts: [string, string, string][], removes: string[]) => {
  for (const [plate, type, id] of puts) owners.set(plate, `${type}:${id}`);
  for (const plate of removes) owners.delete(plate);
});

State bags

ai-vehicles sets these on every owned vehicle it spawns. Names are in VEHICLE_BAGS (@aicore-fivem/shared).

BagTypeMeaning
ai:ownedtrueThe entity is an owned vehicle.
ai:vidnumberIts id in ai-vehicles.
ai:propsVehiclePropsThe saved look. ai-core's client that owns the entity applies it.
ai:setupVehicleSetupA spawn look for a vehicle without props, applied once.
fuelnumberFuel 0-100. The fuel script keeps it from then on.
Lua (client)
local vehicle = GetVehiclePedIsIn(PlayerPedId(), false)
if Entity(vehicle).state['ai:owned'] then
  print('owned vehicle', Entity(vehicle).state['ai:vid'])
end

qbx_vehicles API

ai-vehicles provides qbx_vehicles, so these calls reach it. Shapes follow Qbox: state is 0 out, 1 garage, 2 impound.

ExportWhat it does
GetPlayerVehicles(filters: { citizenid?, garage? })Vehicles of an online character, optionally only one garage. Returns { id, citizenid, modelName, garage, state, depotPrice, props }[].
GetPlayerVehicle(id: number)One vehicle in the same shape, or nil.
CreatePlayerVehicle(request: { model, citizenid, garage?, props? })Creates a vehicle for an online character. Returns the id, or nil, { code, message } (bad_request, not_found).
SetPlayerVehicleOwner(id: number, citizenid: string)New owner (online). true when it worked.
DeletePlayerVehicles(idType: "plate" | "vehicleId", idValue)Deletes one vehicle. true when found.
GetVehicleIdByPlate(plate: string)The id, or nil.
DoesPlayerVehiclePlateExist(plate: string)true when the plate is owned.
SaveVehicle(entity: number, options: { props?, state?, garage? })Saves a spawned vehicle, tuning included. Takes AI Core's props or the ox_lib / qb-core props shape. Props of another model than the entity are refused (state and garage still save).

GetPlayerVehicle returns props in AI Core's VehicleProps shape, not ox_lib's. depotPrice is always 0.

On this page