State bag’ler
EntityState, PlayerState, GlobalKey, GlobalGroup ve stateNumber, stateBoolean, stateString ayrıştırıcıları: replike edilen değerleri bellekten okumak.
State bag, FiveM’in server’dan ona ihtiyaç duyan client’lara kopyaladığı bir değerdir: bir aracın yakıtı (Entity(vehicle).state.fuel), bir oyuncunun yerde olup olmadığı (Player(id).state.dead), server genelinde bir bayrak (GlobalState["ai:pvp"]).
Bir bag’i doğrudan okumak yavaştır: her okuma proxy’ler kurar, birkaç native çağırır ve değeri yeniden çözer. Bu sınıflar anahtar başına tek bir değişiklik handler’ı ve her değerin bir kopyasını bellekte tutar; bu yüzden bir okuma bir map aramasıdır. Birden fazla okuduğun her bag için bunları kullan.
import { EntityState, PlayerState, GlobalKey, GlobalGroup, stateNumber, stateBoolean, stateString } from "@aicore-fivem/lib/client";import { EntityState, PlayerState, GlobalKey, GlobalGroup, stateNumber, stateBoolean, stateString } from "@aicore-fivem/lib/server";Sınıflar @aicore-fivem/lib/fivem üzerinde değildir: onları client ya da server girişinden import et. State bag’leri yalnızca server yazar (sv_stateBagStrictMode); bir client server’a bir callback ile sorar ve değeri server ayarlar. Server’ın set metotları Lib: server, State bag’ler sayfasındadır.
Lua: bunların hiçbirinin Lua karşılığı yok. Lua bag’leri kendisi okur (Entity(vehicle).state.fuel, Player(id).state.dead, GlobalState['ai:pvp']) ve AddStateBagChangeHandler ile dinler.
ai-core’un ve ai-* script’lerinin kullandığı anahtarlar Olaylar ve durum sayfasında listelenir.
Ayrıştırıcılar
Her sınıf bir ayrıştırıcı (parser) alır: ham replike değeri senin tipine çeviren ya da geçerli bir değer değilse undefined döndüren bir fonksiyon. Tipi StateParse<T> = (value: unknown) => T | undefined’dir. Temizlenmiş bir bag (null) her zaman undefined olarak okunur; ayrıştırıcı onu hiç görmez.
stateNumber
Sonlu bir sayıyı kabul eder; başka her şey (metin, NaN, Infinity) undefined olarak okunur.
Taraf: Client ve server · Bekler: hayır
stateNumber: StateParse<number>Örnek
import { EntityState, stateNumber } from "@aicore-fivem/lib/client";
const fuel = new EntityState("fuel", stateNumber); // 0-100, yakıt script’i tarafından ayarlanırstateBoolean
true ya da false’u kabul eder; başka her şey undefined olarak okunur.
Taraf: Client ve server · Bekler: hayır
stateBoolean: StateParse<boolean>Örnek
import { PlayerState, stateBoolean } from "@aicore-fivem/lib/client";
const dead = new PlayerState("dead", stateBoolean); // yerdeyken true (ai-death)stateString
Bir string’i kabul eder; başka her şey undefined olarak okunur.
Taraf: Client ve server · Bekler: hayır
stateString: StateParse<string>Örnek
import { GlobalKey, stateString } from "@aicore-fivem/lib/client";
const inventoryScript = new GlobalKey("ai:inventory", stateString); // aktif envanterin resource adıBir nesne değeri için, her alanı kontrol eden ve hatalı bir değer için undefined döndüren kendi ayrıştırıcını yaz:
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); // pma-voice’un menzili, ai-voice tarafından yazılırSınıflar
EntityState
Ağa bağlı her entity için entity state bag’lerinin tek bir anahtarı (fuel, ai:owned...). Değerler network id’ye göre tutulur; bir okuma entity handle’ını alır.
Taraf: Client ve server · Bekler: hayır
new EntityState<T>(key: string, parse: StateParse<T>)Parametreler
Prop
Type
Metotlar
Prop
Type
Örnek
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 });
});Bellek kendiliğinden küçük kalır: server bir entity’yi silindiğinde unutur ve bir client 30 saniyede bir menzilinden çıkan entity’leri atar. Yeni bir entity tarafından yeniden kullanılan bir network id tekrar okunur.
PlayerState
Server id’ye göre oyuncu state bag’lerinin tek bir anahtarı (dead, cuffed, pma-voice’un proximity’si...).
Taraf: Client ve server · Bekler: hayır
new PlayerState<T>(key: string, parse: StateParse<T>)Parametreler
Prop
Type
Metotlar
Prop
Type
Örnek
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 };
});Server’da oyundan çıkan bir oyuncu, resource’unun her PlayerState’inde unutulur (paylaşılan tek bir playerDropped dinleyicisi).
GlobalKey
Tek bir GlobalState anahtarı: her oyuncunun ihtiyaç duyduğu bir değer (PvP anahtarı, aktif envanter). Açılışta bir kez okunur, sonra değişiklik handler’ı tarafından güncel tutulur.
Taraf: Client ve server · Bekler: hayır
new GlobalKey<T>(key: string, parse: StateParse<T>)Parametreler
Prop
Type
Metotlar
Prop
Type
Örnek
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
Aynı ön eki paylaşan birçok GlobalState anahtarı (ai:duty:police, ai:duty:ambulance), ön ekten sonraki kısma göre okunur. Bir resource’un tüm grupları tek bir handler paylaşır.
Taraf: Client ve server · Bekler: hayır
new GlobalGroup<T>(prefix: string, parse: StateParse<T>)Parametreler
Prop
Type
Metotlar
Prop
Type
Örnek
ai-core meslek başına kaç oyuncunun görevde olduğunu ai:duty:<job> altında yayınlar:
import { GlobalGroup, stateNumber } from "@aicore-fivem/lib/client";
const onDuty = new GlobalGroup("ai:duty:", stateNumber);
function policeOnline(): number {
return onDuty.get("police") ?? 0;
}Her sınıfı anahtar başına bir kez, bir dosyanın en üstünde oluştur; asla sık çalışan bir fonksiyonun içinde değil: her örnek bir değişiklik handler’ı ekler. GlobalState her oyuncuya gönderilir; bu yüzden oraya yalnızca her oyuncunun ihtiyaç duyduğu değerleri koy.
Zamanlama ve yaşam döngüsü
every, onStop, caller, ByResource, Reasons, sleep ve waitFor: periyodik işler, beklemek ve onu kaydeden resource’a ait olan veriler.
Aksiyonlar ve client girdisi
fail, isActionOk, replyError ve katı okuyucular readInt, readFinite, readId, readText, readVec3, readVec4, oneArg, asArgs, isRecord.