Skip to content

Customization

Almost everything is in config.lua. The rest is text, data, and the thin layer that talks to your framework.


FileWhat it decidesOpen to edit
config.luaFramework, language, who may paint, items, command names, paint-shop markersYes
locales/*.luaEvery notification and chat suggestion, one file per languageYes
locales/main.luaThe function that picks the text for Config.LocaleYes
bridge/server.luaFramework detection, notifications, admin check, jobs, usable items, removing itemsYes
bridge/client.luaFramework detection and notifications on the player’s sideYes
items/ox.lua, items/qb.lua, items/sql.sqlReady-made item definitions to copy into your inventoryYes
permissions.jsonThe Steam IDs allowed to open the menu. Written by the give and remove commandsYes
vehicle_original_colors.jsonEach painted car’s colour before it was first painted, by model and plateYes
html/ui.html, html/style.css, html/script.jsThe menu: its title, its swatches and its look—
data/, stream/The paint definitions and ramp textures for colours 223 to 242Leave as is
client/main.lua, server/main.luaThe logicEscrowed

OptionWhat it doesDefault
Config.Framework"auto", "esx" or "qbcore". Auto uses whichever of es_extended and qb-core is running; QBox counts as qb-core through its QBCore compatibility. Pinned, QBox uses "qbcore""auto"
Config.LocaleThe language of every message. See Languages, below"es"
Config.PermissionFileThe name of the JSON file that holds the permission list"permissions.json"

OptionWhat it doesDefault
Config.PermissionsUse the permission list in permissions.jsontrue
Config.UseJobsLet the jobs in Config.AuthorizedJobs open the menu tootrue
Config.AuthorizedJobsThe job names allowed when UseJobs is onmechanic, police

The two switches combine like this:

PermissionsUseJobsWho can open the menu
ononPlayers on the list, and anyone whose job is in AuthorizedJobs
onoffOnly players on the list
offon or offEverybody

The list is keyed by Steam identifier. A player who is not running Steam cannot be added; the give command answers that it could not get their Steam identifier.


OptionWhat it doesDefault
Config.UseItemsRegister the 82 paint items and the reset item as usabletrue
Config.ItemsRequirePermissionMake the paint items follow the same rules as the menu. Off, anybody holding one can use itfalse

The reset item never asks for permission. The item names, and where their definitions ship, are in Installation.


Each name is set in config.lua, without the slash.

OptionDefaultWhoWhat it does
Config.Chameleon/chameleonAnyone allowed by the rules aboveOpens the menu. You must be in a vehicle
Config.ChameleonReset/chameleonresetAnyonePuts the car you are in back to its original colour
Config.ChameleonGive/chameleongive [ID]AdminsAdds that player’s Steam ID to the permission list
Config.ChameleonRemove/chameleonremove [ID]AdminsTakes it off again

“Admin” means the admin or superadmin group on ESX, and the admin or god permission on QBCore. Both checks live in bridge/server.lua if yours are called something else.


Config.Locations is a list; add as many entries as you like. Each one has:

FieldWhat it doesShipped value
coordsWhere the marker sitsTwo example spots near Burton
radiusHow close, in metres, you must be for the prompt3.0
markerTypeThe FiveM marker drawn1 (a ring on the ground)
markerColorRed, green, blue and alphaRed on one, green on the other, alpha 100
markerScaleIts size2.0 × 2.0 × 1.0
notificationThe help text shown inside the radiusPress ~INPUT_CONTEXT~ to open the Chameleon menu

The marker is drawn from 10 metres away. The prompt only appears inside radius and in a vehicle; E then opens the menu, with the same permission check as the command.

The notification text is in config.lua, not in the locales, so translate it there.


html/ui.html holds the swatches — one per colour ID from 161 to 242 — and the menu’s title, “Chameleon Paintings”, which is written in the page rather than taken from the locales. html/style.css gives each swatch its preview colour.


Nine ship in locales/: en, es, fr, de, it, pt, pl, ru and tr. Set Config.Locale to one of those codes.

To add one:

  1. Copy locales/en.lua to a new file, for example locales/nl.lua.
  2. Change the language code at the top of the new file to nl and translate the text.
  3. Add locales/nl.lua to both the client_scripts and server_scripts lists in fxmanifest.lua, next to the other locale files.
  4. Set Config.Locale = "nl", then refresh and restart the resource.

A missing key shows as Translation [key] does not exist rather than breaking anything, which makes a half-finished file easy to spot.


Two files in bridge/ are the only places the resource touches your framework.

FileWhat it does
bridge/server.luaFinds the framework, sends notifications (esx:showNotification or QBCore:Notify), decides who is an admin, reads a player’s job, registers the usable items and removes an item after use
bridge/client.luaFinds the framework on the player’s side and shows notifications (ESX.ShowNotification or QBCore.Functions.Notify)

With no framework found, notifications fall back to chat messages.

Adapting it. To use your own notification script, replace the body of Bridge.Notify in both files. For a custom admin system, change Bridge.IsAdmin. For a framework that is not ESX, QBCore or QBox, fill in each Bridge. function in bridge/server.lua — framework detection, Notify, IsAdmin, GetPlayerJob, RegisterUsableItem and RemoveItem — and the resource needs nothing else.