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
GetPlayerData(): AiPlayerData | nulllocal data = exports['ai-core']:GetPlayerData() -- table or nilParameters
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
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
IsPlayerLoaded(): booleanlocal loaded = exports['ai-core']:IsPlayerLoaded() -- booleanParameters
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
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
GetDefinitions(file: "jobs" | "gangs"): Record<string, unknown> | nulllocal jobs = exports['ai-core']:GetDefinitions('jobs') -- table keyed by job name, or nilParameters
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
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.