AI Core

Panel data

num, int, bool, str, record, vec4, spec, readRecords and withoutSchemaKey: reading the data/*.json files the admin panel edits.

Your script's settings live in data/*.json files the server owner edits in ai-core's admin panel (see Admin panel). The panel checks values against your schema.ts, but a file can still be old, hand-edited or missing a field. The readers on this page never refuse: a missing or wrong value gives the fallback you pass, so the script always starts.

For values a client sends, use the strict readers on Actions and client input instead: those refuse a bad value.

TypeScript
import { num, int, bool, str, record, vec4, spec, readRecords, withoutSchemaKey } from "@aicore-fivem/lib/shared";

Lua: none of these have a Lua twin (the admin panel and its data files are TypeScript only).

Value readers

num

A finite number clamped to [min, max], else the fallback.

Side: Client, server and NUI · Waits: no

Signature
num(value: unknown, fallback: number, min?: number, max?: number): number

Parameters

Prop

Type

Returns

number: the value clamped into the range, or fallback (not clamped).

Example

import { num } from "@aicore-fivem/lib/shared";

num(25, 2.5, 1, 20);      // 20 (clamped)
num("big", 2.5, 1, 20);   // 2.5 (fallback)

int

Like num, then rounded to a whole number.

Side: Client, server and NUI · Waits: no

Signature
int(value: unknown, fallback: number, min?: number, max?: number): number

Parameters

Prop

Type

Returns

number: a whole number (the fallback is rounded too).

Example

import { int } from "@aicore-fivem/lib/shared";

int(12.6, 10, 0, 100); // 13
int(null, 10, 0, 100); // 10

bool

A boolean, else the fallback.

Side: Client, server and NUI · Waits: no

Signature
bool(value: unknown, fallback: boolean): boolean

Parameters

Prop

Type

Returns

boolean.

Example

import { bool } from "@aicore-fivem/lib/shared";

bool(true, false);   // true
bool("yes", false);  // false (fallback)

str

A trimmed, non-empty string cut to max characters, else the fallback.

Side: Client, server and NUI · Waits: no

Signature
str(value: unknown, fallback: string, max?: number): string

Parameters

Prop

Type

Returns

string.

Example

import { str } from "@aicore-fivem/lib/shared";

str("  City Hall ", "Hall", 48); // "City Hall"
str("", "Hall", 48);             // "Hall"

record

The value as a plain object, or an empty object {}. Use it before reading fields of a value that may be missing.

Side: Client, server and NUI · Waits: no

Signature
record(value: unknown): Record<string, unknown>

Parameters

Prop

Type

Returns

value itself when it is a plain object, otherwise a new {} (also for arrays and null).

Example

import { num, record } from "@aicore-fivem/lib/shared";

function readCoords(raw: unknown) {
  const c = record(raw); // {} when the field is missing
  return { x: num(c.x, 0), y: num(c.y, 0), z: num(c.z, 0) };
}

vec4

A position with heading; each missing or wrong field comes from the fallback.

Side: Client, server and NUI · Waits: no

Signature
vec4(value: unknown, fallback: Vec4): Vec4

Parameters

Prop

Type

Returns

A new Vec4.

Example

import { vec4 } from "@aicore-fivem/lib/shared";

vec4({ x: 10, y: 20, z: 30 }, { x: 0, y: 0, z: 0, heading: 90 }); // { x: 10, y: 20, z: 30, heading: 90 }

Schema helpers

spec

Builders for number fields in your panel schema.ts, so you do not write the same DataSpec object by hand.

Side: Client, server and NUI · Waits: no

Signature
spec.int(min: number, max: number, optional?: boolean): DataSpec
spec.num(min: number, max: number, optional?: boolean): DataSpec

Parameters

Prop

Type

Returns

DataSpec: { type: "number", min, max }, plus integer: true for spec.int and optional: true when asked.

Example

resource/server/schema.ts
import { spec } from "@aicore-fivem/lib/shared";
import type { PanelSchema } from "@aicore-fivem/shared";

export const schema: PanelSchema = {
  title: "ADMIN_TITLE",
  icon: "store",
  files: {
    settings: {
      kind: "settings",
      sync: "admin",
      sections: {
        prices: { type: "object", fields: { water: spec.int(0, 1_000_000), tax: spec.num(0, 0.5) } },
      },
    },
  },
  tabs: [], // the panel layout (cards and fields), see Admin panel
};

withoutSchemaKey

Removes the "$schema" key from a data file's content. The key is only there so code editors can check the file; your reader should not see it.

Side: Client, server and NUI · Waits: no

Signature
withoutSchemaKey(value: unknown): unknown

Parameters

Prop

Type

Returns

A copy without $schema when the value is an object that has it; otherwise value unchanged.

Example

import { withoutSchemaKey } from "@aicore-fivem/lib/shared";

withoutSchemaKey({ $schema: "./schemas/shops.schema.json", legion: { label: "Legion" } });
// { legion: { label: "Legion" } }

Records files

A records file holds many entries by key ({ "legion": {...}, "pillbox": {...} }): shops, garages, city halls. Each entry is read by your own reader function (RecordReader<T> = (key: string, raw: Record<string, unknown>) => T | null), built from the value readers above.

readRecords

Reads a whole records file once into a Map, one entry per key, through your reader. Entries that are not objects, or for which your reader returns null, are left out.

Side: Client, server and NUI · Waits: no

Signature
readRecords<T>(raw: unknown, readOne: RecordReader<T>): Map<string, T>

Parameters

Prop

Type

Returns

Map<string, T>: the parsed entries by key.

Example

import { readRecords, str, num, record } from "@aicore-fivem/lib/shared";

type Shop = { label: string; x: number; y: number; z: number };

const readShop = (key: string, v: Record<string, unknown>): Shop => {
  const c = record(v.coords);
  return { label: str(v.label, key, 48), x: num(c.x, 0), y: num(c.y, 0), z: num(c.z, 0) };
};

const shops = readRecords({ legion: { label: "Legion", coords: { x: 25.7, y: -1347.3, z: 29.5 } } }, readShop);
shops.get("legion"); // { label: "Legion", x: 25.7, y: -1347.3, z: 29.5 }

For a panel file, prefer panel.records(file, readOne) (server AdminPanel) or world.records(file, readOne) (client AdminWorld): they return a map that stays current while the owner edits, parsing only the changed entry.

RecordObjects

Keeps the world objects of a records file (points, blips, peds, zones) in step with the panel, one entry at a time: an edited entry rebuilds only its own objects. It is exported from @aicore-fivem/lib/shared and has no Lua twin. Its full reference (constructor, build function, rebuild, rebuildAll, example) is on Interaction points: RecordObjects.

On this page