Creating a script
From an empty template to a script with an admin panel, in the AI Core way.
Create it from the template
bun run new garbagejob "Garbage routes with pay per stop"
bun install
cd resources/[ai]/ai-garbagejob && git init && bun run buildThen add ensure ai-garbagejob to server.cfg. The template gives you resource/client, resource/server, resource/common, locales/en.json, a CLAUDE.md to fill in and the build setup.
Add the panel
Write resource/server/schema.ts (files, tabs, cards, widgets) and create new AdminPanel(schema) on the server. Data the world needs (places, blips, prices players see) is sync: "all" and read on the client with new AdminWorld([...]); everything else stays on the server.
Use the lib for everything
// client: a place players use, shown as a prompt or a target option
const points = new Points();
points.add("depot", {
coords: route.depot,
label: Locale("PROMPT_START"),
icon: "truck",
canShow: () => hasJob(["garbage"]),
onPressed: () => callAction(EVENTS.start, [route.id], { fallback: "ERR_FAR" }),
});// server: the request, checked before anything changes
onClientCallback(
EVENTS.start,
{ args: oneArg((v) => readText(v, 32)), guards: [hasCharacter()], lock: true },
(source, id) => {
if (!isNear(source, route.depot, 3)) return fail("ERR_FAR");
return { ok: true };
},
);Check and restart
bun run typecheck && bun run lint && bun run build
bun tools/rcon.ts --log ../logs/fxserver.log --wait 3 "ensure ai-garbagejob"The easiest way is to ask your AI: open the server folder in Claude Code and describe the script. The rules make it use the template, the lib and the panel. See Working with AI.