Config reference
Every option is in zaiders_appearance/shared/config.lua, the file that stays open under escrow. Each one has a comment in English and Spanish above it. This page explains them all, grouped by topic, with the value they come with.
How to apply a change
Save the file and restart the resource (ensure zaiders_appearance) or the whole server. Menus opened after that use the new values.
How the config is checked
On start, the resource compares your config.lua with its built-in defaults. A mistake never stops the menu: the wrong value is replaced with the default, and the console lists every fix so you can correct the file.
[zaiders_appearance] config.lua: 2 values were fixed at start (the menu works anyway). To stop this notice, correct them in config.lua:
Config.Shops.near was written as text: it becomes 20.0.
Config.Wardrobe.maxOutfit is not an option (a typo?): it is not used.| What it finds | What it does |
|---|---|
| An option is missing | Uses the default. This is also how a new version's options work with your old file. |
A number or true/false written in quotes | Takes the value without the quotes. |
| A value of the wrong kind (text where a table goes) | Uses the default. |
| An option that doesn't exist | Ignores it and tells you, in case it's a typo. |
| A value that isn't one of the allowed ones | Uses the default. |
The admin panel wins
Some settings start from the config and are then managed in the panel: map shops, tattoo prices, garment prices and stock, the Peds shop and the menu's look. Once you save them in the panel, the panel's values are used, and the config only gives the starting point.
General
Config.Locale
Config.Locale = 'en'The language of the whole script: the menu, the admin panel, garment and tattoo names, the E signs, notices, subcommands and the console. Players don't choose it; everyone sees this one.
Included: 'en' English, 'es' Spanish, 'pt' Portuguese (Brazil), 'fr' French, 'de' German, 'it' Italian, 'pl' Polish, 'tr' Turkish and 'nl' Dutch. A code without its file falls back to English. See Languages & texts.
Config.Framework
Config.Framework = 'auto''auto' looks for Qbox, QBCore and ESX, in that order. To choose one by hand, use 'qbx', 'qb' or 'esx'. Without a framework the menu works, but nothing is charged or saved.
Config.CloseAfterPay
Config.CloseAfterPay = trueAfter paying, the menu closes on its own: the player keeps what they bought, and the game says how much it cost. false keeps the menu open after paying.
Config.Sounds
Config.Sounds = trueThe game's own sounds when browsing garments with the arrows, switching sections, taking clothes off and paying. Each player can turn them off in Settings. false turns them off for everyone.
Config.Notify
Config.Notify = nilThe notices shown to players. By default they are ox_lib's, titled with the brand name set in the panel's Theme. To use your server's notifications, write a function. It runs in the player's game:
Config.Notify = function(text, kind)
-- kind is 'inform', 'success' or 'error'
exports['my_notify']:Notify(text, kind)
endConfig.CanOpenMenu
Config.CanOpenMenu = nilBefore opening a menu, the resource already checks that the player isn't dead, downed, cuffed or falling, including the states of QBCore, Qbox and ESX. To add your own rule, write a function that returns true when the menu may open. It runs in the player's game:
Config.CanOpenMenu = function()
return not LocalPlayer.state.inChase
endConfig.HideHud
Config.HideHud = {
enabled = true,
resources = {
{ resource = 'vayce-hud', export = 'SetHudVisible', changed = 'hud:visibleChanged' },
},
custom = nil,
}While a menu or the panel is open, the HUD hides, and when it closes it comes back the way it was. The game's own HUD always hides, and many server HUDs follow the game's. If another script turns the HUD back on while a menu is open, it hides again.
| Field | What it does |
|---|---|
enabled | false: only the radar hides. |
resources | Other resources' HUDs, used only while that resource is running. Each entry gives the resource and either an export (it gets false on open and true on close) or an event with the values to send (hide = ..., show = ...). With changed, the name of the event that HUD fires when it shows or hides: a HUD hidden before the menu stays hidden, and one that turns itself on during the menu is hidden again. |
custom | Your own code: function(hidden, menu) ... end. hidden is true on open and false on close; menu is 'clothing', 'barber', 'tattoo', 'wardrobe', 'creator' or 'panel'. |
resources = {
{ resource = 'my-hud', export = 'SetHudVisible' },
{ resource = 'other-hud', event = 'other-hud:toggle', hide = false, show = true },
},Other scripts can also listen to the client event zaiders_appearance:hud. See Exports, events & hooks.
Commands
Config.Command = 'zappearance'
Config.CommandsForEveryone = false
Config.Subcommands = {
clothing = { 'ropa', 'clothing' },
barber = { 'barberia', 'barber' },
tattoo = { 'tatuajes', 'tattoos' },
wardrobe = { 'guardarropa', 'wardrobe' },
creator = { 'creador', 'creator' },
panel = { 'panel', 'admin' },
photos = { 'fotos', 'photos' },
shops = { 'tiendas', 'shops' },
tattooPrices = { 'precios', 'prices' },
reloadSkin = { 'recargar', 'reloadskin' },
help = { 'ayuda', 'help' },
}
Config.CommandShortcuts = {}| Option | What it does |
|---|---|
Command | The one chat command; everything else is a subcommand (/zappearance clothing). The console commands start with it too (zappearance_migrar). |
CommandsForEveryone | false: opening a shop by command is for admins; players walk into the map shops. true: everyone may use those subcommands. |
Subcommands | The names of each subcommand. All of them work, plus the name in Config.Locale's language (/zappearance kleidung in German). |
CommandShortcuts | Commands of your own for a subcommand, with its same rules. Empty by default so it never takes another resource's command. { wardrobe = 'wardrobe' } creates /wardrobe; { reloadskin = 'reloadSkin' } creates /reloadskin. |
The full list of commands and who may use them is in Commands & permissions.
Permissions
Admins
Config.AdminAce = 'zaiders_appearance.admin'
Config.AdminAces = { 'zaiders_appearance.admin', 'clothing.admin' }
Config.AdminQbPermissions = { 'god', 'admin' }
Config.AdminEsxGroups = { 'admin', 'superadmin' }Who is an admin: anyone with one of these ACE permissions, these qb-core permissions or, on ESX, these groups. Admins open the panel, open shops by command, try the creator and paste a character's JSON. AdminAce is the permission named in the "no permission" message.
# server.cfg
add_ace group.admin zaiders_appearance.admin allowDon't add command
Many servers give the command permission to moderators. Use zaiders_appearance.admin and give it only to the groups that should edit the catalog.
Config.CatalogEditors
Config.CatalogEditors = {
qb = { 'god', 'admin' },
jobs = {},
onDuty = false,
}Who may change garments from the shop with a right click: rename them, mark them out of stock, give them their own price or make them job-only. Anyone with the admin ACE permissions (or an aces = { ... } list of your own), these qb-core permissions, or a job from a grade on, such as jobs = { clothingstore = 2 }. With onDuty = true, only while on duty.
Config.GarmentGroups
Config.GarmentGroups = {
{ name = 'vip', label = 'VIP', ace = 'zaiders_appearance.vip' },
}Groups by ACE permission, such as VIP. Each group shows up in Only for… (right click on a garment, and the panel's Catalog editor), and only players with that permission can buy those garments. Nothing changes until you mark a garment. For VIP, in server.cfg:
add_ace group.vip zaiders_appearance.vip allow
add_principal identifier.fivem:123456 group.vipConfig.GarmentGroups = {} removes the groups. See Clothing store.
Prices
Config.Prices = {
hats = 80, hair = 60, tops = 250, undershirt = 90, arms = 60, pants = 180, shoes = 200, decals = 40,
masks = 120, glasses = 100, ears = 90, chains = 150, watches = 250, bracelets = 120, vest = 180, bags = 150,
hairColor = 40,
parents = 150,
features = 120,
eyes = 60,
overlays = {
blemishes = 40, ageing = 40, complexion = 40, sunDamage = 40, moleAndFreckles = 40, bodyBlemishes = 40,
eyebrows = 30, beard = 40, chestHair = 20,
makeUp = 50, blush = 30, lipstick = 30,
},
}The price of each slot in the clothing store and the barber shop. A garment can have its own price that wins over these: set it with a right click on the garment, or in the panel's Catalog editor. Tattoo prices are in Config.Tattoos and the panel.
| Key | Slot |
|---|---|
hats, glasses, ears, watches, bracelets | Accessories (props) |
masks, hair, arms, pants, bags, shoes, chains, undershirt, vest, decals, tops | Clothing (components) |
hairColor | Changing hair color or highlights |
parents | Heritage (the face blend) |
features | Face shape |
eyes | Eye color |
overlays | Each overlay of the barber: skin details, eyebrows, beard, chest hair, makeup, blush and lipstick |
Clothing presets
These tell the menu what to put on when a garment comes off. The values are the game's for the freemode characters. If your server replaces the base clothing with a pack, adjust them to that pack.
Each entry is ['component:N'] = { drawable, texture }.
Config.Undress
Config.Undress = {
male = {
['component:1'] = { 0, 0 }, -- mask
['component:4'] = { 61, 0 }, -- pants
['component:5'] = { 0, 0 }, -- bag
['component:6'] = { 34, 0 }, -- shoes
['component:11'] = { 252, 0 }, -- jacket
},
female = {
['component:1'] = { 0, 0 },
['component:4'] = { 14, 0 },
['component:5'] = { 0, 0 },
['component:6'] = { 35, 0 },
['component:11'] = { 74, 0 },
},
}What the quick take-off buttons beside the menu put on in each slot.
Config.UndressWithTop
Config.UndressWithTop = {
['component:8'] = { 15, 0 },
['component:3'] = { 15, 0 },
['component:10'] = { 0, 0 },
}Taking the jacket off also takes off the undershirt, the gloves and the decals.
Config.Naked
Config.Naked = {
male = {
['component:1'] = { 0, 0 }, -- mask
['component:3'] = { 15, 0 }, -- arms
['component:4'] = { 61, 0 }, -- pants
['component:5'] = { 0, 0 }, -- bag
['component:6'] = { 34, 0 }, -- shoes
['component:8'] = { 15, 0 }, -- undershirt
['component:9'] = { 0, 0 }, -- vest
['component:10'] = { 0, 0 }, -- decals
['component:11'] = { 91, 0 }, -- jacket
},
female = { ... },
}The underwear used where the skin must show: the tattoo shop and the character creator. With a pack that replaces the base clothing, pick garments that leave the skin bare, or they will cover the tattoos.
Pose and camera
Config.Poses
Config.Poses = {
stand = {
male = { 'move_m@generic', 'idle' },
female = { 'move_f@multiplayer', 'idle' },
at = 0.0,
},
arms = {
male = { 'missminuteman_1ig_2', 'handsup_base' },
female = { 'missminuteman_1ig_2', 'handsup_base' },
at = 0.0,
},
shops = { clothing = true, barber = true, tattoo = true, creator = true, wardrobe = true },
}With a menu open, the character stands still in the standing animation of each sex, frozen on one frame. With X or the arms button they raise their arms, also still, so you can check that a garment doesn't break.
| Field | What it does |
|---|---|
stand, arms | The animation dictionary and name for each sex. at is the moment of the animation it stays on, from 0 to 1. |
shops | Which menus use the pose. |
Config.Poses = false turns the still pose off: the character keeps its normal idle movement while the menu is open. The photo studio always uses the standing pose.
Config.Camera
Config.Camera = {
fov = 40.0,
smoothing = 7.0,
shots = {
{ name = 'Cara', bones = { 31086 }, z = 0.02, dist = 0.95 }, -- face
{ name = 'Pecho', bones = { 24818 }, z = 0.02, dist = 1.35 }, -- chest
{ name = 'Torso', bones = { 24816 }, z = 0.0, dist = 1.85 }, -- torso
{ name = 'Cuerpo', bones = { 11816 }, z = 0.08, dist = 3.2 }, -- body
{ name = 'Piernas', bones = { 63931, 36864 }, z = -0.12, dist = 1.75 }, -- legs
},
}The five camera shots the mouse wheel goes through. Each one aims at the character's bones, so it works with any ped. dist is the distance in meters and z a height adjustment. name is only a label for you; the menu shows its own names in each language. fov is the camera's field of view, and smoothing how softly it moves.
Faces
Config.ShapeMax = 45
Config.SkinMax = 45
Config.FaceRanges = {
male = { { 0, 20 }, { 42, 44 } },
female = { { 21, 41 }, { 45, 45 } },
}The game has faces 0 to 45. A face pack can add more, for example 46 to 91. Then set Config.ShapeMax = 91 and add its ranges, such as { 46, 68 } for men and { 69, 91 } for women. Skins only exist from 0 to 45.
FaceRanges splits the faces into men's and women's, because the menu shows those two groups. In the game, 0–20 and 42–44 are men and 21–41 and 45 are women.
Peds
Config.Peds
Config.Peds = {
male = { { name = 'mp_m_freemode_01' } },
female = { { name = 'mp_f_freemode_01' } },
}The Your character cards in Peds: the freemode man and woman. Changing between them is free.
Config.PedShop
Config.PedShop = {
enabled = true,
price = 25000,
exclusive = false,
codes = true,
categories = {
calle = true, trabajos = true, pandillas = true, personajes = true, online = true, animales = false,
servidor = true,
},
images = 'https://docs-backend.fivem.net/peds/%s.webp',
}The ped shop in Peds. Players see the game's peds that your server's game version has, plus the addon peds you add in the panel. They try them on for free and buy the ones they want. A bought ped belongs to that character for good, unless an admin takes it away. See Peds & ped codes.
| Field | What it does |
|---|---|
enabled | false: no peds are sold. Players keep the man and woman, and admins keep the ped by name. |
price | The price of every ped, unless it has its own price in the panel. |
exclusive | true: each ped can have only one owner. The next buyer is told it already has one. |
codes | Redeem codes: admins make them in the panel, and players redeem them in Peds to get a ped without paying in the game. false turns codes off. |
categories | What is for sale: calle (street), trabajos (jobs), pandillas (gangs), personajes (story characters), online (GTA Online), animales (animals, off: they can't wear clothes and have few animations) and servidor (your addon peds). |
images | Where the ped pictures come from: FiveM's documentation, downloaded by each player as they look (%s is the ped's name). Photos taken in the panel's studio come first. false: no pictures from the internet, only a drawing. |
The panel's Peds section changes all of this. After you save there, the panel wins.
Config.PedByName and Config.PedBlacklist
Config.PedByName = 'admins'
Config.PedBlacklist = {
-- 'a_c_chop',
}Ped by name lets someone become any ped that exists on the server by typing its name. 'todos' lets everyone, 'admins' only admins, 'nadie' no one. Peds in the blacklist can never be used. The server checks it again when paying, so nobody keeps a ped they can't use.
Map shops
Config.Shops = {
key = 38,
near = 20.0,
blips = true,
blipLegend = 121,
prompt = { height = 1.0, distance = 8.0, size = 0.05 },
ball = false,
marker = false,
markerColor = { 55, 226, 200, 110 },
textUI = false,
place = { reach = 12.0 },
}The shops themselves (where they are, their names and blips) are set in the panel and saved in datos/tiendas.json. Until you save, the game's 27 shops are used. See Map shops & blips.
| Field | What it does |
|---|---|
key | The key that opens a shop. 38 is E. |
near | From how many meters the game checks every frame for a shop nearby. |
blips | false hides every shop blip, whatever the panel says. |
blipLegend | Groups each kind's blips under one name in the big map's list (Clothing stores, Barber shops, Tattoo parlors, Wardrobes). It uses four of the game's blip categories, from this number (121 to 124). If another script uses those, pick another number between 12 and 130. false: each blip on its own. |
prompt | The floating E sign: height above the floor in meters, distance from which it shows, size as a share of the screen's height (0.05 is 5%). false: no sign. Each shop can also hide its own sign in the panel. |
ball | A small sphere over the shop. true uses the default look, or write { size = 0.18, height = 1.0, color = { 55, 226, 200, 170 }, bob = false }. |
marker, markerColor | A circle on the ground with the shop's radius, and its color (RGBA). |
textUI | Also show ox_lib's "[E] ..." notice on screen. |
place.reach | How far the crosshair reaches, in meters, when you place a shop from the panel. |
Wardrobe
Config.Wardrobe = {
maxOutfits = 30,
maxUniforms = 30,
bossGrade = nil,
gangUniforms = true,
shareCodes = true,
shareHours = 24,
}The wardrobe holds each player's outfits and their job's and gang's uniforms. Outfits are saved in ps_outfits and uniforms in ps_job_outfits; tables your server already had keep their content. See Wardrobe & outfits.
| Field | What it does |
|---|---|
maxOutfits | Outfits per character. |
maxUniforms | Uniforms per job (and per gang). |
bossGrade | Besides the boss, from which grade of the job members may make uniforms. For example 3. nil: only the boss and admins. |
gangUniforms | Gang uniforms (QBCore and Qbox): one more tab in the wardrobe. false removes it. |
shareCodes | Share an outfit with a 6-letter code. The other player tries it on at a clothing store and pays for the garments they don't have. false turns it off. |
shareHours | How many hours each code lasts. |
Character creator
Config.Creator = {
enabled = true,
events = { 'qb-clothes:client:CreateFirstCharacter' },
skipIfStarted = { 'dx_clothing', 'illenium-appearance', 'qb-clothing', 'fivem-appearance' },
face = {
male = { shapeFirst = 0, shapeSecond = 21, shapeThird = 0, skinFirst = 0, skinSecond = 21, skinThird = 0, shapeMix = 0.25, skinMix = 0.5, thirdMix = 0.0 },
female = { shapeFirst = 0, shapeSecond = 21, shapeThird = 0, skinFirst = 0, skinSecond = 21, skinThird = 0, shapeMix = 0.75, skinMix = 0.5, thirdMix = 0.0 },
},
}The creator opens by itself when the server creates a new character. See Character creator.
| Field | What it does |
|---|---|
enabled | false: this menu never opens the creator. |
events | The events a multicharacter fires for a new character. qb-multicharacter and most others fire qb-clothing's. On ESX without esx_skin, esx_skin:openSaveableMenu is answered too. |
skipIfStarted | If one of these resources is running, it handles new characters, so two menus don't open. |
face | The face a new character starts with, for each sex. |
Tattoo shop
Config.Tattoos = {
enabled = true,
free = false,
priceFactor = 0.25,
maxPrice = 0,
addonPrice = 'auto',
fadePrice = 120,
layerPercent = 25,
removePrice = 150,
maxLayers = 4,
undress = true,
save = true,
owners = { 'rcore_tattoos', 'qb-tattooshop', 'esx_tattooshop', 'illenium-appearance', 'fivem-appearance' },
fades = { ... },
}The game's tattoos with their GTA Online prices, your server's addon tattoos (packs that load a PED_OVERLAY_FILE) and the hair fades, by body zone. See Tattoo shop.
| Field | What it does |
|---|---|
enabled | false: no tattoo shop, if you use another resource for tattoos. |
free | Everything free: tattoos, darker layers and removing them. |
priceFactor | Multiplies the game's price. GTA Online tattoos cost from $1,300 to $30,000, so 0.25 turns a $10,000 tattoo into $2,500. |
maxPrice | A ceiling for the game's tattoos. 0: none. |
addonPrice | Addon tattoos and the game's without a price. 'auto' uses the typical price of their zone, times the factor. A number sets one price for all of them. |
fadePrice | The price of a hair fade. |
layerPercent | Each darker layer costs this percentage of the tattoo's price. |
removePrice | Removing a tattoo, or taking layers off. |
maxLayers | How many times a tattoo can be stacked. Each layer makes it darker, because the game has no opacity for tattoos. |
undress | Takes the clothes off (to Config.Naked) while in the shop. |
save | Saves bought tattoos in zaiders_tattoos and puts them on when the character joins. |
owners | Other tattoo resources. If one is running, this tattoo shop turns itself off: no shops on the map, nothing sold and no saved tattoos put on. |
fades | Spare hair fades, only used if data/tatuajes.json is missing. You don't need to touch them. |
The panel's Tattoos section changes prices per zone, each tattoo's price and stock. After you save there, the panel wins.
Compatibility
Config.Compat = {
loadSkin = true,
exports = true,
esxSkinSave = false,
}| Field | What it does |
|---|---|
loadSkin | Puts the saved clothes on when a character joins and whenever another script reloads them (reviving, a multicharacter's preview), by answering the usual load events. If another clothing resource answering them is running, it does nothing. |
exports | While illenium-appearance, fivem-appearance, qb-clothing or skinchanger aren't running, this menu answers their exports and events in their place, so scripts made for them keep working. false turns it off. |
esxSkinSave | ESX: esx_skin:save can be sent by any player with any clothes, without paying, so out of the box it doesn't save. true saves it like esx_skin does. |
Config.Compat = false turns all three off. See Frameworks & compatibility.
Catalog photos
Config.Photos
Config.Photos = {
enabled = true,
resource = 'zaiders_fotos',
onDemand = true,
bps = 400000,
perMinute = 1500,
url = '',
}The menu shows a photo of each garment, or a drawing when there's none. The photos live in their own resource, so updating the script never touches them. See Catalog photos.
| Field | What it does |
|---|---|
enabled | false: drawings only. |
resource | The photos resource. |
onDemand | Players don't download the photos when they join. The menu asks the server only for those on screen, a few at a time, through the game's own connection. Each player keeps them, so next time they show at once. false: everyone downloads them all on join (then also uncomment the two lines in zaiders_fotos/fxmanifest.lua). |
bps | On demand: the most the server sends each player per second, in bytes. 400000 is 400 KB/s, about 40 photos. |
perMinute | On demand: how many photos each player may ask for per minute. |
url | Optional: an https address where you uploaded the fotos/ and tatuajes/ folders (a CDN or web server). The photos then come from there. |
Config.Studio
The photo studio of the panel. You don't need to change it: these values are what make the photos come out clean. They are listed here so you know what each one is.
| Field | Default | What it is |
|---|---|---|
position, heading | high in the sky over the sea | Where the studio is: far from everything. The mannequin stands on an invisible platform. |
platform | 'prop_container_01a' | The object under the mannequin. |
bucketBase | 7000 | Each admin works in their own dimension: this number plus their player ID. |
time, weather | noon, 'EXTRASUNNY' | Fixed daylight while the photos are taken. |
backgrounds, background | green and magenta, 'green' | The background colors, like a green screen. Magenta is for green garments. |
fov, pedFov, crop | 30.0, 40.0, 0.92 | The camera's angle, and the square of the screen that is photographed. |
box | 12 × 12 × 7 m | The colored box around the mannequin. |
loadTimeoutMs, settleMs | 6000, 200 | How long to wait for a garment to load, and a moment more for a sharp texture. |
face, hairColor | The mannequin's face, skin and hair color. The hair color can also be picked in the panel. | |
lights | three lights | The studio lights, in meters from the mannequin. |
base | every slot empty | The mannequin is invisible, so only the garment shows in the photo. |
shots | one framing per slot | Where the camera looks for each slot. glass and twoTone are for glasses. |
faceShot | The framing of the face photos (Heritage, in the barber). | |
maxPhotoKb, bps | 400, 2000000 | The largest photo, and the upload speed to the server. |
changeDistance | 10 | Pack checking: how different a photo may be and still count as the same garment. |
