AI Core
Referência da APILib: compartilhada e fivem

State bags

EntityState, PlayerState, GlobalKey, GlobalGroup e os parsers stateNumber, stateBoolean, stateString: ler valores replicados da memória.

Um state bag é um valor que o FiveM copia do servidor para os clientes que precisam dele: o combustível de um veículo (Entity(vehicle).state.fuel), se um jogador está caído (Player(id).state.dead), uma flag do servidor inteiro (GlobalState["ai:pvp"]).

Ler um bag diretamente é lento: toda leitura cria proxies, chama várias natives e decodifica o valor de novo. Estas classes mantêm um handler de mudança por chave e uma cópia de todo valor em memória, então uma leitura é uma consulta em um mapa. Use-as para qualquer bag que você lê mais de uma vez.

Client file: read-only versions (get, onChange)
import { EntityState, PlayerState, GlobalKey, GlobalGroup, stateNumber, stateBoolean, stateString } from "@aicore-fivem/lib/client";
Server file: the same classes plus set(...)
import { EntityState, PlayerState, GlobalKey, GlobalGroup, stateNumber, stateBoolean, stateString } from "@aicore-fivem/lib/server";

As classes não estão em @aicore-fivem/lib/fivem: importe-as da entrada de cliente ou de servidor. Só o servidor escreve state bags (sv_stateBagStrictMode); um cliente pede ao servidor por um callback e o servidor define o valor. Os métodos set do servidor estão em Lib: servidor, State bags.

Lua: nenhum destes tem equivalente em Lua. Lua lê os bags diretamente (Entity(vehicle).state.fuel, Player(id).state.dead, GlobalState['ai:pvp']) e escuta com AddStateBagChangeHandler.

As chaves que o ai-core e os scripts ai-* usam estão listadas em Eventos e estado.

Parsers

Toda classe recebe um parser: uma função que transforma o valor replicado bruto no seu tipo, ou undefined quando não é um valor válido. O tipo é StateParse<T> = (value: unknown) => T | undefined. Um bag limpo (null) sempre é lido como undefined; o parser nunca o vê.

stateNumber

Aceita um número finito; qualquer outra coisa (texto, NaN, Infinity) é lida como undefined.

Lado: Cliente e servidor · Espera: não

Signature
stateNumber: StateParse<number>

Exemplo

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

const fuel = new EntityState("fuel", stateNumber); // 0-100, definido pelo script de combustível

stateBoolean

Aceita true ou false; qualquer outra coisa é lida como undefined.

Lado: Cliente e servidor · Espera: não

Signature
stateBoolean: StateParse<boolean>

Exemplo

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

const dead = new PlayerState("dead", stateBoolean); // true enquanto caído (ai-death)

stateString

Aceita uma string; qualquer outra coisa é lida como undefined.

Lado: Cliente e servidor · Espera: não

Signature
stateString: StateParse<string>

Exemplo

import { GlobalKey, stateString } from "@aicore-fivem/lib/client";

const inventoryScript = new GlobalKey("ai:inventory", stateString); // o nome do recurso do inventário ativo

Para um valor de objeto, escreva o seu próprio parser que verifica cada campo e retorna undefined para um valor inválido:

import { PlayerState, type StateParse } from "@aicore-fivem/lib/client";

type Proximity = { index: number; distance: number; mode: string };
const proximity: StateParse<Proximity> = (v) => {
  if (typeof v !== "object" || v === null) return undefined;
  const { index, distance, mode } = v as Record<string, unknown>;
  return typeof index === "number" && typeof distance === "number" && typeof mode === "string"
    ? { index, distance, mode }
    : undefined;
};
const voiceRange = new PlayerState("proximity", proximity); // o alcance do pma-voice, escrito pelo ai-voice

Classes

EntityState

Uma chave dos state bags de entidade (fuel, ai:owned...), para toda entidade em rede. Os valores são guardados por network id; uma leitura recebe o handle da entidade.

Lado: Cliente e servidor · Espera: não

Signature
new EntityState<T>(key: string, parse: StateParse<T>)

Parâmetros

Prop

Type

Métodos

Prop

Type

Exemplo

resource/client/index.ts
import { EntityState, stateNumber, cache, every } from "@aicore-fivem/lib/client";

const fuel = new EntityState("fuel", stateNumber);

every(1000, () => {
  if (cache.vehicle === false) return;
  SendNUIMessage({ action: "fuel", value: fuel.get(cache.vehicle) ?? 100 });
});

A memória fica pequena sozinha: o servidor esquece uma entidade quando ela é apagada, e um cliente descarta a cada 30 segundos as entidades que saíram do escopo dele. Um network id reutilizado por uma nova entidade é lido de novo.

PlayerState

Uma chave dos state bags de jogador (dead, cuffed, o proximity do pma-voice...), por id de servidor.

Lado: Cliente e servidor · Espera: não

Signature
new PlayerState<T>(key: string, parse: StateParse<T>)

Parâmetros

Prop

Type

Métodos

Prop

Type

Exemplo

resource/server/index.ts
import { PlayerState, stateBoolean, onClientCallback } from "@aicore-fivem/lib/server";
import { fail } from "@aicore-fivem/lib/shared";

const dead = new PlayerState("dead", stateBoolean);
const cuffed = new PlayerState("cuffed", stateBoolean);

onClientCallback("my-shop:open", (source) => {
  if (dead.get(source) || cuffed.get(source)) return fail("CANNOT_NOW");
  return { ok: true };
});

No servidor, um jogador que sai é esquecido em todo PlayerState do seu recurso (um único listener de playerDropped compartilhado).

GlobalKey

Uma chave do GlobalState: um valor de que todo jogador precisa (a chave de PvP, o inventário ativo). Lida uma vez na inicialização, depois mantida atualizada pelo handler de mudança dela.

Lado: Cliente e servidor · Espera: não

Signature
new GlobalKey<T>(key: string, parse: StateParse<T>)

Parâmetros

Prop

Type

Métodos

Prop

Type

Exemplo

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

const pvp = new GlobalKey("ai:pvp", stateBoolean);

pvp.onChange((_id, on) => SendNUIMessage({ action: "pvp", value: on === true }));

GlobalGroup

Muitas chaves do GlobalState que compartilham um prefixo (ai:duty:police, ai:duty:ambulance), lidas pela parte depois do prefixo. Todos os grupos de um recurso compartilham um handler.

Lado: Cliente e servidor · Espera: não

Signature
new GlobalGroup<T>(prefix: string, parse: StateParse<T>)

Parâmetros

Prop

Type

Métodos

Prop

Type

Exemplo

O ai-core publica quantos jogadores estão em serviço por emprego em ai:duty:<job>:

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

const onDuty = new GlobalGroup("ai:duty:", stateNumber);

function policeOnline(): number {
  return onDuty.get("police") ?? 0;
}

Crie cada classe uma vez por chave, no topo de um arquivo, nunca dentro de uma função que roda com frequência: toda instância adiciona um handler de mudança. O GlobalState é enviado a todo jogador, então só coloque ali valores de que todo jogador precisa.

Nesta página