AI Core

State bags

The server versions of EntityState, PlayerState, GlobalKey and GlobalGroup: the only way an ai-* script writes replicated state.

TypeScript
import { EntityState, PlayerState, GlobalKey, GlobalGroup, stateNumber, stateBoolean } from "@aicore-fivem/lib/server";

A state bag is a value FiveM copies from the server to clients: on an entity (a vehicle's fuel), on a player (dead), or global (a door's state everyone sees). ai-core runs with strict state bag mode, so only the server writes: a client that wants a change asks through a callback, and the server sets the value.

The server entry exports the same four classes as the client, plus a set method. The constructor, get, onChange, EntityState.getByNetId and GlobalGroup.ids are documented once on Lib: shared and fivem. Create every instance once at module level, one per key.

A value you set is readable at once with get on the server, and onChange listeners run once. Setting undefined removes the value.

No Lua twins: Lua reads Entity(entity).state.key itself, and writes with Entity(entity).state:set(key, value, true).

EntityState.set

Writes one key on an entity's state bag. It replicates to the players who have the entity in scope.

Side: Server · Waits: no

Signature
new EntityState<T>(key: string, parse: StateParse<T>)
set(entity: number, value: T | undefined): void

Prop

Type

Returns void.

import { EntityState, stateNumber } from "@aicore-fivem/lib/server";

const odometer = new EntityState("my:km", stateNumber);

odometer.set(vehicle, (odometer.get(vehicle) ?? 0) + 1);

PlayerState.set

Writes one key on a player's state bag. It replicates to that player and the players near them.

Side: Server · Waits: no

Signature
new PlayerState<T>(key: string, parse: StateParse<T>)
set(source: number, value: T | undefined): void

Prop

Type

Returns void.

import { PlayerState, stateBoolean } from "@aicore-fivem/lib/server";

const cuffed = new PlayerState("my:cuffed", stateBoolean);

cuffed.set(target, true);
// later
cuffed.set(target, undefined);

GlobalKey.set

Writes one GlobalState key. It replicates to every player: use it only for state every player needs.

Side: Server · Waits: no

Signature
new GlobalKey<T>(key: string, parse: StateParse<T>)
set(value: T | undefined): void

Prop

Type

Returns void.

import { GlobalKey, stateBoolean } from "@aicore-fivem/lib/server";

const stormActive = new GlobalKey("my:storm", stateBoolean);

stormActive.set(true);

GlobalGroup.set

Writes one key of a group of GlobalState keys that share a prefix (door:<id>, rob:<id>). It replicates <prefix><id> to every player.

Side: Server · Waits: no

Signature
new GlobalGroup<T>(prefix: string, parse: StateParse<T>)
set(id: string, value: T | undefined): void

Prop

Type

Returns void.

import { GlobalGroup, stateBoolean } from "@aicore-fivem/lib/server";

const robbedStores = new GlobalGroup("my-rob:", stateBoolean);

robbedStores.set("store_12", true); // GlobalState["my-rob:store_12"] = true

State bags are for small values many players read. Lists, per-player data for one player, or anything that changes often go as snapshot + delta through events (see AreaStream and KeyWatchers on Players). Shared key names live in @aicore-fivem/shared (VEHICLE_BAGS, PLAYER_BAGS) or your resource's common/.

On this page