Recommended scripts
How a free script gets listed in the admin panel's Recommended scripts section.
The admin panel's dashboard has a Recommended scripts section: free scripts worth installing on an AI Core server. Each one shows only while it fits the server (no phone script runs: a phone is recommended; the script already runs: its card is gone), and the ones that show are also printed once in the server console 15 seconds after start. The owner hides a card with its X and brings it back in the General tab, Recommendations card.
Requirements
- It is free. The card shows a Free chip.
- It works through AI Core, not through one framework or one script. Everything the script shares with other scripts goes through AI Core's layers and exports, so every
ai-*script, the ESX / QB / Qbox bridge and the owner's other scripts work with it. For example:- giving and removing vehicle keys goes through the vehicle keys layer (lib
vehicleKeys.give/vehicleKeys.remove, exportsGiveVehicleKeys/RemoveVehicleKeys), never a key script's exports; - applying a look and reloading the skin go through the appearance layer (
appearance.apply,appearance.reloadSkin); - items go through the inventory layer (
inventory.addItem, orexports['ai-core']:AddItem(source, 'bread', 2)from Lua); - fuel, doors, garages, the phone and police alerts (
dispatch.alert) go through their layers the same way.
- giving and removing vehicle keys goes through the vehicle keys layer (lib
- If its category has a layer, it has an adapter there. An inventory, vehicle keys, clothing, fuel, door lock, garage, phone, dispatch, banking, billing or medical script needs an adapter in that layer, so the other scripts reach it. A script that answers an API the layer already reads needs less: a fuel script with LegacyFuel-style client exports
GetFuel(vehicle)/SetFuel(vehicle, level)is one line in the fuel layer's list.
The layers and the scripts they support: Layers and the bridge, Compatibility, and one note per layer in docs/compat/ of the server repository.
Getting listed
Add the entry
Fork aifivem/ai-core and add one entry to the RECOMMENDATIONS list in resource/server/recommendations/index.ts:
{
id: "my-garbagejob",
title: "ADMIN_REC_MY_GARBAGEJOB",
desc: "ADMIN_REC_MY_GARBAGEJOB_DESC",
url: "https://example.com/my-garbagejob",
free: true,
// shows while the script does not run
shows: (runs) => !runs("my-garbagejob"),
},| Field | What it holds |
|---|---|
id | The script's resource name. A dismissed card stores it, so it is 2 to 64 lower-case letters, digits, _ or -. |
title, desc | ai-core lang keys: the script's name and one line why the server wants it. |
url | The page where the owner gets the script. |
free | true. |
shows | When the card shows. runs(resource) is true while that resource is started and not stopping. A condition can also ask a layer, like the phone entry: shows: () => phones.active === null (no phone runs). |
AI Core checks the conditions again when a resource starts or stops, when the phone layer switches and when the settings change. A condition on another layer also hooks that layer's switch to recommendations.refresh(), as the end of the file does for the phone (phones.onSwitch).
Add the two texts
In locales/en.json, next to the other ADMIN_REC_* keys:
"ADMIN_REC_MY_GARBAGEJOB": "My Garbage Job",
"ADMIN_REC_MY_GARBAGEJOB_DESC": "Garbage routes with pay per stop; items and vehicle keys go through ai-core's layers."English only: other languages are added on top of en.json.
Add the adapter, if your category has a layer
In the same pull request:
- the adapter file in the layer's
adapters/folder:resource/server/<layer>/adapters/<resource>.ts, plusresource/client/<layer>/adapters/<resource>.tswhen the script has only a client API. Copy the adapter of a similar script; - its line in the layer's adapter list:
resource/server/<layer>/registry.ts, or the layer'sindex.tswhen it has noregistry.ts(phone, medical, prison, world).
Then open a second pull request to aifivem/aicore-server that adds the script to the layer's note docs/compat/<layer>.md (for example vehicle-keys.md, phone.md): tested version, status and known limits.
Open the pull request
Run bun install, then bun run typecheck, bun run lint and bun run build in ai-core; all three must pass. Give the pull request a Conventional Commit title in English, for example feat(recommendations): recommend my-garbagejob. The maintainers review it: they check that the script is free and works through the layers, then merge it, and the card ships with the next ai-core release.