Vehicles
spawnVehicle, vehicleType, randomPlate, nearest vehicles, entities from client net ids, vehicleKeys, fuel and garages.
import { spawnVehicle, vehicleKeys, fuel, garages, vehicleFromNet } from "@aicore-fivem/lib/server";Spawning
spawnVehicle
Creates a networked vehicle on the server and sets it up in one call: plate, fuel, look, lock, routing bucket, keys for the right purpose, a driver and passengers. Use it for every script vehicle (job vehicles, rentals, garage vehicles, admin spawns).
Side: Server · Waits: yes (Promise in TypeScript, yields the thread in Lua)
spawnVehicle(options: SpawnVehicleOptions): Promise<number | null>local vehicle = aiLib.spawnVehicle(options) -- entity or nil, call inside a threadParameters
Prop
Type
SpawnVehicleOptions
Prop
Type
Returns
Promise<number | null>: the vehicle entity handle. null when the model does not exist (the asker client said so), the entity was not created within 5 seconds, or the type is unknown.
Example
import { onClientCallback, spawnVehicle, hasCharacter, near } from "@aicore-fivem/lib/server";
import { fail } from "@aicore-fivem/lib/shared";
const DEPOT = { x: 895.4, y: -179.3, z: 74.7 };
onClientCallback(
"my-taxi:start",
async (source) => {
const vehicle = await spawnVehicle({
model: "taxi",
coords: { x: 899.1, y: -180.6, z: 73.8, heading: 238 },
asker: source,
keysTo: source,
purpose: "job",
driver: source,
fuel: 100,
setup: { dirt: 0 },
});
if (!vehicle) return fail("SPAWN_FAILED");
return { ok: true, netId: NetworkGetNetworkIdFromEntity(vehicle) };
},
{ guards: [hasCharacter(), near(DEPOT, 5)], lock: true },
);The keys wait (up to 3 seconds) until the server reads the plate: before the owner client's first sync, the server reads an empty plate. Seated players are put in again for up to 2 seconds until they sit. In TypeScript a model's type from one client serves only that player until a second player's client gives the same answer; the Lua twin keeps the first answer it gets.
vehicleType
The spawn type of a model, asked from a player's client. Use it to check a model exists before you take money.
Side: Server · Waits: yes (Promise)
vehicleType(model: string, asker: number): Promise<string | null>No Lua twin: aiLib.spawnVehicle with asker checks it and returns nil for an unknown model.
Prop
Type
Returns
Promise<string | null>: automobile, bike, boat, heli, plane, submarine, trailer or train; null when the game has no such vehicle or the client gave no valid answer. An answer is kept for everyone once two different players' clients agreed on it, so one modified client can only break its own spawns.
Example
import { onClientCallback, vehicleType } from "@aicore-fivem/lib/server";
import { fail, oneArg, readText } from "@aicore-fivem/lib/shared";
onClientCallback("my-dealer:buy", { args: oneArg((v) => readText(v, 32)), lock: true }, async (source, model) => {
if (!(await vehicleType(model, source))) return fail("UNKNOWN_MODEL");
// take the money, then spawnVehicle(...)
return { ok: true };
});randomPlate
A random plate like the game's own (two digits, three letters, three digits), or your prefix followed by digits.
Side: Server · Waits: no
randomPlate(prefix?: string): stringNo Lua twin (aiLib.spawnVehicle sets a random plate when you pass none).
Prop
Type
Returns an 8-character plate (42ABC123, or TAXI1234 for randomPlate("TAXI")). It is not checked for uniqueness: check your own table before you store it.
const plate = randomPlate("RENT");Finding vehicles
nearestVehicleTo
The closest vehicle within metres of a player that passes your filter. The vehicle the player sits in wins first.
Side: Server · Waits: no
nearestVehicleTo(source: number, metres: number, filter?: (vehicle: number) => boolean): numberlocal vehicle = aiLib.nearestVehicleTo(source, metres, filter) -- entity or 0Prop
Type
Returns the vehicle entity, or 0 when none.
const vehicle = nearestVehicleTo(source, 5);
if (!vehicle) return fail("NO_VEHICLE");It walks every vehicle on the server: use it for commands and actions (rate-limited), never in a tick.
nearestVehicleAt
The closest vehicle within metres of a point. Use it to check a spawn spot is free.
Side: Server · Waits: no
nearestVehicleAt(point: { x: number; y: number; z: number }, metres: number, filter?: (vehicle: number) => boolean): numberNo Lua twin.
Returns the vehicle entity, or 0 when none. Walks every vehicle, like nearestVehicleTo.
const SPOT = { x: 899.1, y: -180.6, z: 73.8 };
if (nearestVehicleAt(SPOT, 3)) return fail("SPOT_BLOCKED");Entities from client input
A client sends a network id, never an entity handle. These turn a net id into the live server entity and check it, so you never call NetworkGetEntityFromNetworkId + DoesEntityExist + GetEntityType by hand.
entityFromNet
The live entity behind a client's network id.
Side: Server · Waits: no
entityFromNet(netId: unknown, type?: 1 | 2 | 3): numberNo Lua twin (Lua has vehicleFromNet).
Prop
Type
Returns the entity, or 0 when the value is not a positive whole number, not networked, gone, or of another type.
const prop = entityFromNet(rawNetId, 3);
if (!prop) return fail("NOT_FOUND");pedFromNet
entityFromNet(netId, 1): the live ped, or 0.
Side: Server · Waits: no
pedFromNet(netId: unknown): numberNo Lua twin.
const ped = pedFromNet(rawNetId);vehicleFromNet
entityFromNet(netId, 2): the live vehicle, or 0.
Side: Server · Waits: no
vehicleFromNet(netId: unknown): numberlocal vehicle = aiLib.vehicleFromNet(netId) -- entity or 0const vehicle = vehicleFromNet(rawNetId);
if (!vehicle) return fail("NO_VEHICLE");vehicleNearPlayer
The vehicle behind a client's network id, but only when the player is near it (or in its driver seat).
Side: Server · Waits: no
vehicleNearPlayer(source: number, netId: unknown, options?: { metres?: number; driver?: boolean }): numberlocal vehicle = aiLib.vehicleNearPlayer(source, netId, options) -- entity or 0Prop
Type
Returns the vehicle, or 0 when the id is bad, the vehicle is gone, or the player is too far / not the driver.
onClientCallback("my-tow:hook", { args: oneArg(readId), lock: true }, (source, netId) => {
const vehicle = vehicleNearPlayer(source, netId, { metres: 6 });
if (!vehicle) return fail("TOO_FAR");
return { ok: true };
});Keys
vehicleKeys goes through ai-core's key layer: the key script the server runs (ai-vehiclekeys, or another the owner picks) answers. A vehicle is a server entity handle or a plate.
vehicleKeys.give
Gives a player the keys of a vehicle.
Side: Server · Waits: no
vehicleKeys.give(source: number, vehicle: number | string, purpose?: KeyPurpose): voidaiLib.vehicleKeys.give(source, vehicle, purpose)Prop
Type
Returns void.
vehicleKeys.give(source, vehicle, "rental");vehicleKeys.remove
Takes a player's keys of a vehicle.
Side: Server · Waits: no
vehicleKeys.remove(source: number, vehicle: number | string): voidaiLib.vehicleKeys.remove(source, vehicle)Returns void.
vehicleKeys.remove(source, "RENT1234");vehicleKeys.has
Whether a player holds the keys.
Side: Server · Waits: no
vehicleKeys.has(source: number, vehicle: number | string): booleanlocal has = aiLib.vehicleKeys.has(source, vehicle)Returns boolean. true also when the key script cannot tell or none runs, so do not use it as the only lock on something valuable.
if (!vehicleKeys.has(source, vehicle)) return fail("NO_KEYS");Fuel
fuel reads and sets a vehicle's fuel (0 to 100) through ai-core's fuel layer, whatever fuel script runs. No Lua twin on the server: call ai-core's exports GetVehicleFuel / SetVehicleFuel.
fuel.get
Side: Server · Waits: no
fuel.get(vehicle: number): number | nullReturns the level of a server vehicle entity (0 to 100), or null when it has none.
const level = fuel.get(vehicle) ?? 0;fuel.set
Side: Server · Waits: no
fuel.set(vehicle: number, level: number): booleanProp
Type
Returns true when set, false for a wrong vehicle.
fuel.set(vehicle, 100);fuel.provider
Side: Server · Waits: no
fuel.provider(): string | nullReturns the resource name of the fuel script that answers (ai-fuel, ox_fuel, LegacyFuel...), or null when none runs.
console.log(`fuel through ${fuel.provider() ?? "nothing"}`);Garages
garages goes through ai-core's garage layer, whatever garage script runs; each script answers only what it exposes. No Lua twin.
garages.impound
Sends a vehicle to the impound, or opens the garage script's impound form for by.
Side: Server · Waits: no
garages.impound(vehicle: number, by?: number): booleanProp
Type
Returns true when the garage script took it. false when nothing took it: delete the vehicle yourself.
if (!garages.impound(vehicle, source)) DeleteEntity(vehicle);garages.store
Stores a vehicle in a garage.
Side: Server · Waits: no
garages.store(vehicle: number, garage?: string | null, by?: number): booleanProp
Type
Returns true when stored, false when nothing took it.
if (!garages.store(vehicle, "legion", source)) return fail("STORE_FAILED");garages.open
Opens the garage menu of the garage script for a player.
Side: Server · Waits: no
garages.open(source: number, garage?: string | null): booleanReturns true when opened, false when the script has no such menu.
garages.open(source, "pillbox");garages.stored
A player's vehicles in garages or the impound.
Side: Server · Waits: yes (Promise)
garages.stored(source: number): Promise<GaragedVehicle[] | null>Returns GaragedVehicle[] (plate, model, garage, impounded), or null when the script cannot tell or ai-core is stopped.
const list = await garages.stored(source);
const impounded = list?.filter((v) => v.impounded).length ?? 0;garages.provider
Side: Server · Waits: no
garages.provider(): string | nullReturns the garage script that answers, or null when none runs.
if (!garages.provider()) console.warn("no garage script runs");