AI Core

Player

Read the local player's character, money, jobs, duty and gangs, check whether a character is loaded, and read job and gang definitions.

These exports read what ai-core knows about the player sitting at this game: their character, money, jobs and gangs. The server sends this data to the player's own client once when the character loads, then only the values that change. No other player's data ever reaches this client.

In TypeScript, use the lib's getPlayerData(key) and onPlayerData(key, handler) instead of calling GetPlayerData again and again. In Lua, use aiLib.playerData.get(key) and aiLib.playerData.onChange(key, handler). They read the export once, then follow every change ai-core pushes.

GetPlayerData

Returns everything ai-core knows about the local player's loaded character in one table: character, money, jobs, duty, the main job, gangs, the active gang and metadata. Use it to read the data once when your resource starts; follow changes with onPlayerData (TS) or aiLib.playerData.onChange (Lua).

Side: Client · Waits: no

Signature
GetPlayerData(): AiPlayerData | null
Lua
local data = exports['ai-core']:GetPlayerData() -- table or nil

Parameters

None.

Returns

AiPlayerData while a character stands in the world, null (nil in Lua) on the character screen, before the first character loads, and after the player went back to the character screen.

Prop

Type

Example

resource/client/index.ts
import { getPlayerData, onPlayerData } from "@aicore-fivem/lib/client";

// Shows a police-only blip while the player is on duty as police.
let blip = 0;

function updateBlip(duty: string | null): void {
  if (duty === "police" && blip === 0) {
    blip = AddBlipForCoord(441.8, -982.0, 30.7); // Mission Row police station
    SetBlipSprite(blip, 60);
  } else if (duty !== "police" && blip !== 0) {
    RemoveBlip(blip);
    blip = 0;
  }
}

// Read once (the lib asks ai-core's GetPlayerData for you), then follow every change.
updateBlip(getPlayerData("duty") ?? null);
onPlayerData("duty", (duty) => updateBlip(duty));

This is the player's own copy, for showing things on screen. Never decide anything the server must trust (a payment, an item, access to a stash) from it: the server checks again with its own exports.

IsPlayerLoaded

Tells whether a character stands in the world on this client. Use it before you start anything that needs a character (a HUD, a job loop) when your resource may start after the player already loaded.

Side: Client · Waits: no

Signature
IsPlayerLoaded(): boolean
Lua
local loaded = exports['ai-core']:IsPlayerLoaded() -- boolean

Parameters

None.

Returns

boolean: true once the character was put into the world, false on the character screen, while the player picks a spawn point, and after they went back to the character screen.

Example

resource/client/index.ts
import { resourceExport } from "@aicore-fivem/lib/client";
import { CORE } from "@aicore-fivem/shared";

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

function start(): void {
  console.log("character ready, starting the job loop");
}

// The player may have loaded before this resource started (a restart): check first, then listen.
if (core.IsPlayerLoaded()) start();
on(CORE.clientPlayerLoadedEvent, start);

GetDefinitions

Returns every job or every gang as the admin panel stores them (labels, grades and the other fields the panel edits). Framework bridges use it to build ESX / QB job tables. Read it once, then follow the client event ai-core:client:definitions, which fires for each job or gang the panel changes.

Side: Client · Waits: no

Signature
GetDefinitions(file: "jobs" | "gangs"): Record<string, unknown> | null
Lua
local jobs = exports['ai-core']:GetDefinitions('jobs') -- table keyed by job name, or nil

Parameters

Prop

Type

Returns

Record<string, unknown>: one record per job or gang, keyed by its name (police, ambulance). The records are the panel's own data and are not checked. null when file is neither "jobs" nor "gangs".

Example

resource/client/index.ts
import { resourceExport } from "@aicore-fivem/lib/client";
import { CORE } from "@aicore-fivem/shared";

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

// A local copy of every job, kept current.
const jobs: Record<string, unknown> = { ...(core.GetDefinitions("jobs") ?? {}) };

on(CORE.clientDefinitionsEvent, (file: string, name: string, definition: unknown) => {
  if (file !== "jobs") return;
  if (definition === null) delete jobs[name];
  else jobs[name] = definition;
});

For a job's or gang's grade names and labels on the server, use ai-core's server exports or the server lib; the server is the side that checks grades.

On this page