AI Core

The local player

The cached ped, vehicle, seat and weapon, the player object (position, teleport, animations), screen fades, other players' peds and the nearest player.

Everything about the player sitting at this computer. Read values from cache instead of calling PlayerPedId() in loops: ai-core keeps one watcher for every resource and pushes changes, so no script polls for them.

cache

The local player's most read values, kept current by ai-core's one watcher. Like ox_lib's cache: read cache.ped instead of calling PlayerPedId(), and cache.vehicle instead of GetVehiclePedIsIn every frame. Reading a key is a plain memory read, safe in loops and per-frame code.

Side: Client · Waits: no

Signature
const cache: PlayerCache // read only
Lua
local ped = aiLib.cache.ped

Keys

Prop

Type

The type is PlayerCache.

Example

import { cache, every } from "@aicore-fivem/lib/client";

// Speed shown while driving, read from the cache every 200 ms.
every(200, () => {
  if (cache.vehicle === false || cache.seat !== -1) return;
  const kmh = GetEntitySpeed(cache.vehicle) * 3.6;
  SendNUIMessage({ action: "speed", data: Math.round(kmh) });
});

cache.ped lags a model change by up to 100 ms. Right after you change the model (SetPlayerModel), call PlayerPedId() once. The player actions below already read the ped fresh.

onCache

Runs a handler whenever one cached value changes: the player got into or out of a vehicle, changed seat, drew or put away a weapon, or got a new ped. Use it instead of checking the value on a timer.

Side: Client · Waits: no

Signature
onCache<K extends keyof PlayerCache>(key: K, handler: (value: PlayerCache[K], old: PlayerCache[K]) => void): void
Lua
aiLib.cache.onChange(key, function(value, old) end)

Parameters

Prop

Type

Returns

void. There is no way to remove the handler; keep one per feature at the top of the file.

Example

import { onCache, inventory, Points } from "@aicore-fivem/lib/client";

const points = new Points();

// Points whose canShow reads cache.vehicle are checked again.
onCache("vehicle", () => points.refresh());

// The weapon item in hand, read only when the weapon changes.
onCache("weapon", (weapon) => {
  const item = weapon === false ? null : inventory.currentWeapon();
  SendNUIMessage({ action: "weapon", data: item });
});

readPlayerState

Reads a ped's vehicle, seat and weapon right now, without the cache. ai-core's watcher uses it; you need it only for a ped that is not the local one, or to compare with the cache by hand.

Side: Client · Waits: no

Signature
readPlayerState(ped: number): { vehicle: number | false; seat: number | false; weapon: number | false }

No Lua twin.

Parameters

Prop

Type

Returns

An object with vehicle (the vehicle handle, false on foot), seat (-1 driver and up, false on foot) and weapon (the hash in hand, false when unarmed).

Example

import { playerPed, readPlayerState } from "@aicore-fivem/lib/client";

const ped = playerPed(12);
if (ped !== 0 && readPlayerState(ped).seat === -1) console.log("player 12 is driving");

readWeapon

The weapon in a ped's hand right now, false when unarmed.

Side: Client · Waits: no

Signature
readWeapon(ped: number): number | false

No Lua twin.

Parameters

Prop

Type

Returns

number | false: the weapon hash, or false when the ped holds WEAPON_UNARMED.

Example

import { nearestPlayer, playerPed, readWeapon } from "@aicore-fivem/lib/client";

const id = nearestPlayer(5);
if (id !== null && readWeapon(playerPed(id)) !== false) console.log("the player next to you is armed");

player

One object for the local ped: where it is, moving it, animations. Reads use cache.ped; actions read the ped fresh, so they also work right after a model change.

player.ped

The local ped handle (the same value as cache.ped).

Side: Client · Waits: no

Signature
player.ped: number // read-only property

No Lua twin: use aiLib.cache.ped.

Returns

number: the ped handle.

Example

import { player } from "@aicore-fivem/lib/client";

SetPedArmour(player.ped, 100);

player.coords

The ped's position now.

Side: Client · Waits: no

Signature
player.coords(): Vec3
Lua
local coords = aiLib.player.coords() -- vector3

Returns

A Vec3 { x, y, z } in TypeScript (z is the ped's root, about 1 m above the floor). Lua returns a vector3.

Example

import { locationName, player } from "@aicore-fivem/lib/client";

const here = player.coords();
console.log(`${locationName(here).street} at ${here.x.toFixed(1)}, ${here.y.toFixed(1)}`);

player.heading

The direction the ped faces, in degrees (0-360, 0 = north).

Side: Client · Waits: no

Signature
player.heading(): number
Lua
local heading = aiLib.player.heading()

Returns

number: the heading in degrees.

Example

import { player } from "@aicore-fivem/lib/client";

// Save the spot and direction for a panel record.
const spot = { ...player.coords(), heading: player.heading() };

player.distanceTo

Straight distance from the ped to a point, in metres.

Side: Client · Waits: no

Signature
player.distanceTo(point: Vec3): number
Lua
local metres = aiLib.player.distanceTo(point) -- vector3 or { x, y, z }

Parameters

Prop

Type

Returns

number: metres, measured in 3D.

Example

import { notify, player } from "@aicore-fivem/lib/client";

const counter = { x: 25.7, y: -1347.3, z: 29.5 };
if (player.distanceTo(counter) > 3) notify("Walk to the counter first", "error");

player.freeze

Freezes the ped in place, or lets it move again.

Side: Client · Waits: no

Signature
player.freeze(state: boolean): void
Lua
aiLib.player.freeze(frozen)

Parameters

Prop

Type

Returns

void.

Example

import { player } from "@aicore-fivem/lib/client";

player.freeze(true);
setTimeout(() => player.freeze(false), 5000);

player.teleport

Moves the player and waits until the world around the new spot has loaded, behind a black screen fade. Without z (or with ground: "find"), it searches the ground under x and y: use that for the map waypoint.

Side: Client · Waits: yes (Promise in TypeScript, yields the thread in Lua)

Signature
player.teleport(to: { x: number; y: number; z?: number }, options?: TeleportOptions): Promise<void>
Lua
aiLib.player.teleport(to, options) -- call inside a thread

Parameters

Prop

Type

TeleportOptions

Prop

Type

Returns

Promise<void> that resolves once the player stands at the new spot and the collision there has loaded (or after 5 seconds without it). Lua returns nothing.

Example

import { notify, player, waypoint } from "@aicore-fivem/lib/client";

RegisterCommand(
  "tpm",
  async () => {
    const target = waypoint();
    if (!target) return notify("Set a waypoint first", "error");
    await player.teleport(target, { keepVehicle: true }); // no z: lands on the ground
  },
  false,
);

The TypeScript ground search stands the frozen ped at rising heights, waits for the collision at each one, and skips surfaces inside MLO or IPL interiors, so it never lands on a roof or inside a building above the street. The Lua version takes the first ground it finds and waits at most 3 seconds for the collision.

player.playAnim

Plays an animation on the ped. It loads the animation dictionary first.

Side: Client · Waits: yes in TypeScript (resolves when the animation started); yields in Lua while the dictionary loads

Signature
player.playAnim(dict: string, clip: string, options?: AnimOptions): Promise<void>
Lua
aiLib.player.playAnim(dict, clip, options) -- call inside a thread

Parameters

Prop

Type

AnimOptions

Prop

Type

Returns

Promise<void> that resolves when the animation started. It rejects when the dictionary does not exist or does not load in 10 seconds. Lua returns nothing and does nothing when the dictionary does not load.

Example

import { player } from "@aicore-fivem/lib/client";

export async function handOver(): Promise<void> {
  await player.playAnim("mp_common", "givetake1_a", { flag: 48, duration: 1500 });
}

player.stopAnim

Stops whatever the ped is doing (ClearPedTasks): animations and scenarios.

Side: Client · Waits: no

Signature
player.stopAnim(): void
Lua
aiLib.player.stopAnim()

Returns

void.

Example

import { player } from "@aicore-fivem/lib/client";

export async function readClipboard(): Promise<void> {
  await player.playAnim("amb@world_human_clipboard@male@idle_a", "idle_c");
  setTimeout(() => player.stopAnim(), 4000);
}

player.holdAnim

Keeps an animation playing until you stop it, putting it back when a fall or bump interrupts it. Documented with the props on Peds, blips and props.

Fades and other players

fadeOut

Fades the screen to black and waits until it is fully black. Use it to hide a teleport, a model swap or a scene change.

Side: Client · Waits: yes (Promise in TypeScript, yields the thread in Lua)

Signature
fadeOut(ms?: number): Promise<void>
Lua
aiLib.fadeOut(ms) -- call inside a thread

Parameters

Prop

Type

Returns

Promise<void> that resolves when the screen is black, or after ms + 2 seconds at the latest. It never rejects.

Example

import { fadeIn, fadeOut } from "@aicore-fivem/lib/client";

export async function moveToSquare(): Promise<void> {
  await fadeOut();
  SetEntityCoords(PlayerPedId(), -269.4, -955.3, 31.2, false, false, false, false);
  await fadeIn();
}

fadeIn

Fades the screen back in and waits until it is clear. The pair of fadeOut.

Side: Client · Waits: yes (Promise in TypeScript, yields the thread in Lua)

Signature
fadeIn(ms?: number): Promise<void>
Lua
aiLib.fadeIn(ms) -- call inside a thread

Parameters

Prop

Type

Returns

Promise<void> that resolves when the screen is clear, or after ms + 2 seconds at the latest. It never rejects.

Example

See fadeOut: the two are always used together.

playerPed

The ped of a player by server id. For the local player it returns cache.ped; for another player it returns 0 when that player is not near enough to be streamed to this client.

Side: Client · Waits: no

Signature
playerPed(serverId: number): number
Lua
local ped = aiLib.playerPed(serverId)

Parameters

Prop

Type

Returns

number: the ped handle, or 0 when the player is not in scope on this client.

Example

import { onServerEvent, playerPed } from "@aicore-fivem/lib/client";

// The server tells everyone near that a player was cuffed.
onServerEvent(
  "myscript:cuffed",
  { args: ([id]) => (typeof id === "number" ? [id] : null) },
  (id) => {
    const ped = playerPed(id);
    if (ped !== 0) SetEnableHandcuffs(ped, true);
  },
);

Never use GetPlayerPed(-1) or GetPlayerPed(GetPlayerFromServerId(id)) by hand: an unknown id gives -1, and GetPlayerPed(-1) is the local ped, so the action hits the wrong player.

nearestPlayer

The closest other player within a distance, as a server id. Walks only the players streamed to this client. Use it to pick the target of give, search, cuff or tackle actions, then send that id to the server, which checks the distance again.

Side: Client · Waits: no

Signature
nearestPlayer(metres: number, options?: { from?: Vec3; filter?: (serverId: number, ped: number) => boolean }): number | null
Lua
local serverId = aiLib.nearestPlayer(metres, options) -- integer or nil

Parameters

Prop

Type

Options

Prop

Type

Returns

number | null: the server id of the closest player that passed filter, or null (nil in Lua) when nobody is within metres. The local player is never returned.

Example

import { callAction, nearestPlayer, notify } from "@aicore-fivem/lib/client";

RegisterCommand(
  "givecash",
  async (_src: number, args: string[]) => {
    const target = nearestPlayer(3, { filter: (_id, ped) => !IsPedInAnyVehicle(ped, false) });
    if (target === null) return notify("Nobody is close enough", "error");
    await callAction("myscript:give", [target, Number(args[0])], { fallback: "GIVE_FAILED" });
  },
  false,
);

On this page