Face Coverage, Clothing & Tattoos
On this page7
Three tables decide what a scanner can actually see: Config.FaceCoverage,
Config.Clothing and Config.Tattoos, plus the two exposure helpers
Config.ArmsExposure and Config.NakedSets.
Face coverage
Categories = { full = 1.00, half = 0.60, eyes = 0.35, hat = 0.15 },
Stack = 'add',| Key | Default | Allowed | What it does |
|---|---|---|---|
Categories.full | 1.00 | 0.0–1.0 | Full mask or closed helmet. 1.00 = the face cannot be recognised at all. |
Categories.half | 0.60 | 0.0–1.0 | Bandana, half mask. |
Categories.eyes | 0.35 | 0.0–1.0 | Sunglasses. |
Categories.hat | 0.15 | 0.0–1.0 | Hat or cap. |
Stack | 'add' | 'add' · 'max' · 'multiply' | How several items combine. add = values add up, capped at 100 %. max = only the strongest counts. multiply = each item hides part of what is left. |
ClearGlasses | 0.0 | 0.0–1.0 | How much see-through glasses hide. |
HiddenAt | 60 | 1–100 | From this coverage % the face counts as hidden for other scripts (IsFaceHidden, nametags). 60 = a bandana or more. |
UnknownMask | 'full' | 'full' · 'half' · 'eyes' · 'hat' · 'none' | Fallback for any face slot not listed in UnknownBySlot. |
Items nobody has classified yet
Until Auto-scan (or a manual override) has seen an item, it is treated by slot:
UnknownBySlot = {
['comp:1'] = 'full', -- unknown mask = full mask
['prop:0'] = { category = 'hat', hidesHair = true }, -- unknown hat / helmet = cap
['prop:1'] = 'eyes', -- unknown glasses = sunglasses
},Per-item overrides
For addon or EUP items you want to pin by hand. Key is
'<comp|prop>:<slot>:<collection>:<localIndex>' (collection '' = base game); value
is a category name or a number 0.0–1.0.
Overrides = {
m = {
['comp:1::52'] = 'half', -- base-game mask 52 only covers the lower face
},
f = {
['prop:0:my_eup_pack:3'] = 0.0, -- addon hat that hides nothing
},
},Admins can also set these from the panel. Use /recognition:tags in game to see
exactly what the game reports for what you are wearing.
Clothing
SlotWeights = { top = 30, pants = 20, undershirt = 10, shoes = 10,
hat = 10, bag = 5, accessories = 5, hair = 10 },| Slot | Default weight | Notes |
|---|---|---|
top | 30 | The single strongest signal. |
pants | 20 | |
undershirt | 10 | |
shoes | 10 | |
hat | 10 | |
bag | 5 | |
accessories | 5 | Mask, neck, vest, decals, glasses, ears, watch, bracelet. |
hair | 10 | The "style" slot: hair and beard. |
Any positive numbers work — they are scaled to 100 % between them.
| Key | Default | Allowed | What it does |
|---|---|---|---|
Config.Clothing.FaceItemsOnce | false | true / false | A cap, glasses or mask that was not worn when you learned the look. false = it counts twice: it hides part of the face and counts as a clothing change (someone you met bare-faced, now in a cap and sunglasses, reads Not sure 54 %, 50 % for a woman). true = it counts only through face coverage (Not sure 60 %). Built-in default false, so an older config.lua without the key behaves the same. |
Which component goes where
| Component | Slot | "Nothing worn" |
|---|---|---|
| 1 | accessories | {0} — mask (also a face item) |
| 4 | pants | |
| 5 | bag | {0} |
| 6 | shoes | |
| 7 | accessories | {0} — neck, chains, scarves |
| 8 | undershirt | |
| 9 | accessories | {0} — body armour, vest |
| 10 | accessories | {0} — decals, badges |
| 11 | top |
| Prop | Slot |
|---|---|
| 0 | hat (also a face item, hat tier) |
| 1 | accessories (glasses — also a face item, eyes tier) |
| 2 | accessories (ears) |
| 6 | accessories (watch) |
| 7 | accessories (bracelet) |
Component 0 (head/face) and component 3 (arms) are never clothing — arms are only used to work out sleeves and gloves.
Hair and beard
| Key | Default | Allowed | What it does |
|---|---|---|---|
StyleSlot.Enabled | true | true / false | false = hair and beard never count. |
StyleSlot.HairHiddenByHat | true | true / false | Hair does not count while a hat, helmet or hood hides it. |
StyleSlot.BeardHiddenByMask | true | true / false | Beard does not count under a half or full mask. |
Tattoos
Zones = {
hands = true, forearms = true, upperArms = true, torso = true,
back = true, neck = true, face = true, legs = true,
},Each zone only counts while it is visible right now:
| Zone | Visible when |
|---|---|
hands | no gloves |
forearms | short sleeves or less |
upperArms | sleeveless or shirtless |
torso, back | shirtless only |
neck, face | not covered by a mask or a high collar |
legs | shorts or a skirt |
Set a zone to false and tattoos there are ignored completely.
| Key | Default | Allowed | What it does |
|---|---|---|---|
IgnoreHairFades | true | true / false | Ignore the hair-fade "tattoos" hair shops add. |
BlockOverlays | {} | { collection = '…', overlay = '…' } entries | Extra overlays to ignore — badges and decals your server adds as tattoos. |
Sleeves and gloves
Config.ArmsExposure is a manual override for the arms drawable (component 3).
Most items are classified automatically at runtime from the game's shop tags and by
Auto-scan; this table wins over both.
Config.ArmsExposure = {
m = { [0] = 'short', [4] = 'none', [5] = 'sleeveless', [15] = 'bare' },
f = { [0] = 'short', [4] = 'none', [5] = 'sleeveless', [15] = 'bare' },
}| Class | Means | Tattoo zones it opens |
|---|---|---|
'none' | long sleeves | hands only |
'short' | short sleeves | + forearms |
'sleeveless' | sleeveless | + upper arms |
'bare' | shirtless | + torso, back |
Keys may also be '<collection>:<localIndex>' strings, with values
{ class = …, gloves = true|false }.
An arms drawable nobody has classified yet covers nothing on the arm: the top
decides the sleeves (an unclassified top counts as Config.Classifier.UnknownTop,
'long' by default). Whether it covers the hands is
Config.Classifier.UnknownGloves (default false = bare hands).
"Nothing worn" drawables
Config.NakedSets lists the base-game drawables that mean nothing worn here, per
gender. Shirtless = top and undershirt both in these lists.
Config.NakedSets = {
m = { top = { 15, 252 }, undershirt = { 15 }, arms = { 15 }, legs = { 61 }, shoes = { 34 } },
f = { top = { 15 }, undershirt = { 14 }, arms = { 15 }, legs = { 15 }, shoes = { 35 } },
}Unclassified items — the Auto-scan defaults
Until an item has been through Auto-scan, these decide what it counts as. The top and the pants err on the side of hiding more, because the alternative is that an unknown item is a free disguise. An unknown arms item hides nothing on the arm: the top decides the sleeves.
| Key | Default | Allowed | What it does |
|---|---|---|---|
Config.Classifier.UnknownTop | 'long' | 'long' · 'short' · 'sleeveless' | Sleeve class of a new top. |
Config.Classifier.UnknownGloves | false | true / false | New arms items count as covering the hands. false = bare hands until Auto-scan or an admin marks real gloves. |
Config.Classifier.UnknownLegs | 'long' | 'long' · 'short' | Leg coverage of new pants. |
Head props are not in that list: Config.FaceCoverage.UnknownBySlot['prop:0']
and ['prop:1'] are the one place that decides what an unclassified hat, helmet or
pair of glasses counts as.
When new items appear
At every start the server counts how many clothing drawables and props each freemode model has and compares that with the stored baseline. Nothing changed → the script says nothing. New items → admins are told how many, per model and slot:
[5code-recognition] 42 new clothing/prop items found (mp_f_freemode_01: 12, mp_m_freemode_01: 30). Run Auto-scan from the admin panel to classify them.| Key | Default | Allowed | What it does |
|---|---|---|---|
Config.Classifier.StartupCheck.Enabled | true | true / false | Run the check at all. |
.Models | { 'mp_m_freemode_01', 'mp_f_freemode_01' } | model names | Which models are counted. |
.RequestDelaySeconds | 120 | 10–600 | Wait after boot before asking a player's game, so addon packs have time to load. |
.RecheckHours | 6 | 1–168 | Do not run again within this many hours. |
.RetryMinutes | 10 | 1–60 | No eligible player, or no answer — try again after this long. |
.AnswerTimeoutSeconds | 20 | 5–60 | How long the asked game has to answer. |
.MinNewToNotify | 1 | 1–1000 | How many new items before anybody is told. |
.NotifyOnJoin | true | true / false | Tell admins in game when they join or open the panel. |
.NotifyJoinDelaySeconds | 10 | 0–120 | Delay after an admin's character loads before that one notice. |
.NotifyConsole | true | true / false | One console line when new items are found. |
.ConfirmAbove, .MaxCount, .JumpMax | 200, 50000, 20000 | counts | Sanity limits for very large counts or sudden jumps. Leave them as they are. |
.AutoRun | false | fixed | Auto-scan is never started automatically. Admins always click it themselves. |