# Configuration > Configuration reference for ML Inventory Category: INVENTORY · Source: https://miciomods.it/docs/ml-inventory-configuration · Last updated: 2026-10-02 # Configuration The inventory keeps its settings in three files inside the resource folder: - `micio/config/core.lua`: debug output, interface language, optional item placement and reserved slot rescue. - `micio/config/grid.lua`: grid sizes and durability stacking. - `micio/config/ui.lua`: interface, HUD, holding and giving, renaming, tooltip metadata. ML Clothing keeps its own two files: - `shared/config.lua`: clothing slots, bags, armor plates, wear, bag blacklist. - `shared/invadmin_config.lua`: the admin panel. Every other file of your ox_inventory install keeps working the way it does today, `data/` included. The admin panel has a Settings tab that reads the three inventory files and writes them back without stopping the server. Each key is shown with the one line spec written next to it in the file. A value is accepted only in the type the key already holds, and `Language`, `UI.rarityStyle`, `UI.Hud.style` and `UI.Give.consent` are offered as closed lists. The file is backed up before every change. The inventory reads these files at start, so restart the resource for a saved value to take effect. ## Core **micio/config/core.lua** ```lua MicioConfig.Debug = false MicioConfig.Rescue = { enabled = true, report = true, } ``` - `Debug`, default `false`. Prints boot and slot rule detail to the server console. - `Rescue.enabled`, default `true`. Items sitting in a reserved slot are moved into free grid cells when the character loads, once per character. An item that finds no free cell stays in the slot it was in, and if the pass cannot complete, every item is left where it was saved. - `Rescue.report`, default `true`. Prints the capacity comparison at boot. **micio/config/core.lua** ```lua MicioConfig.PlaceAllItems = true ``` `true` enables placement when a provider is available. `false` uses normal drops. See Developer for the hook contract. ## Grid **micio/config/grid.lua** ```lua MicioConfig.Grid = { playerCols = 8, playerRows = 4, secondaryCols = 6, dropCols = 6, dropRows = 4, durabilityStackTolerance = 5, durabilityStackPerItem = {}, } ``` - `playerCols`, default `8`. Columns in the pocket grid. - `playerRows`, default `4`. Rows in the pocket grid. - `secondaryCols`, default `6`. Columns of the right hand panel for shops, vehicle storage and another player. A stash or container sizes itself from its own slot count instead, unless the script that created it set its columns: `exports.ox_inventory:RegisterStash(id, label, { slots = 30, cols = 6 }, weight)`, or `exports.ox_inventory:mlSetInventoryCols(id, cols)` on a stash you did not register yourself. - `dropCols`, default `6`. Columns of a bag left on the ground. - `dropRows`, default `4`. Rows of a bag left on the ground. - `durabilityStackTolerance`, default `5`. Percentage points two durability values may differ and still stack in one slot. `0` stacks only identical values. - `durabilityStackPerItem`, default `{}`. Per item override of the tolerance above, written as `['sandwich'] = 25`. Player capacity follows the grid: `playerCols` times `playerRows` cells of pocket space, with the reserved slots on top of that count. Size the inventory here rather than with a slot count. A grid under 8 cells, or a `playerCols` or `playerRows` that is not a whole number of at least 1, is refused at boot. A warning names `micio/config/grid.lua` and 8 by 4 is used instead. The reserved slots sit outside the grid and never constrain it. `secondaryCols`, `dropCols` and `dropRows` fall back to 6, 6 and 4 the same way, without a warning. ## Interface **micio/config/ui.lua** ```lua MicioConfig.UI = { defaultTheme = '#00d4aa', rarityStyle = 'border', enableThemePicker = true, virtualPed = true, stockBadge = false, walkWhileOpen = true, family = 'tactical', families = { 'tactical', 'glass', 'slate' }, defaultScale = 100, defaultOpacity = 100, layoutVersion = 1, layoutStudio = false, } ``` - `defaultTheme`, default `'#00d4aa'`. Accent colour a player starts with, any hex value. - `rarityStyle`, default `'border'`. How rarity shows on a slot. Accepts `border`, `full` or `glow`. - `enableThemePicker`, default `true`. Lets each player pick an accent colour. Turn it off to keep everyone on `defaultTheme`. - `virtualPed`, default `true`. Shows the live character preview next to the inventory. Needs ML Clothing running. If `ox_inventory:virtualPed` is already set in `server.cfg`, that convar wins and this key is ignored: remove the line to drive the preview from here. - `stockBadge`, default `false`. Marks stackable items with a badge on the slot and a line in the tooltip. - `walkWhileOpen`, default `true`. Movement keys and sprint stay active while the inventory is open. While a text field has the cursor the keys type. `false` holds the player in place. - `family`, default `'tactical'`. Style family a player starts with. - `families`, default `{ 'tactical', 'glass', 'slate' }`. Families offered in the settings. Each name is a file in `web/themes/`. A saved choice missing from the list falls back to `family`. - `defaultScale`, default `100`. Interface scale a player starts with, percent. - `defaultOpacity`, default `100`. Background opacity a player starts with, percent. - `layoutVersion`, default `1`. Raise it and every player gets the panel positions from `Panels` once, their own saved positions cleared. - `layoutStudio`, default `false`. Adds the layout studio button to the settings. See below. ### Default layout **micio/config/ui.lua** ```lua MicioConfig.UI.Panels = { pockets = { x = 28, y = 3.7 }, clothing = { x = 2, y = 4 }, weapons = { x = 28, y = 36 }, armor = { x = 68, y = 37 }, bag = { x = 68, y = 3.7 }, secondary = { x = 64.6, y = 55.6 }, shop = { x = 64.6, y = 40 }, crafting = { x = 64.6, y = 40 }, loot = { x = 64.6, y = 55.6 }, settings = { x = 40, y = 20 }, } ``` Top left corner of each panel as a percent of screen width and height, so one layout holds on every resolution. A player who drags a panel keeps that position on their own machine until you raise `layoutVersion`. To build the layout in game: set `layoutStudio = true`, restart the resource, open the settings and press Open next to Layout studio. Every panel appears at once with sample items, the shop and the crafting bench included. Drag them where you want them, set the family, the accent colour, the scale and the opacity from the settings, then press Copy layout. The snippet lands in the clipboard and in the F8 console, with `layoutVersion` already raised by one. Paste it at the end of `micio/config/ui.lua`, where it overrides the keys above it, set `layoutStudio` back to `false` and restart. ### Style families Three families ship in `web/themes/`, one CSS file each: `tactical.css`, dark; `glass.css`, light and translucent, tinted by the accent colour; `slate.css`, flat neutral grey with square corners. A family is a set of CSS custom properties on `:root[data-family='name']` plus any extra rules. To add one, copy a file under a new name, edit it and add the name to `families`. The file is loaded at start and on every switch. Panel and slot backgrounds are computed from the accent colour and the background opacity, starting from the bases the family declares. A base is a grey level from 0 to 255 and an alpha from 0 to 1: **web/themes/glass.css** ```css :root[data-family='glass'] { --fam-tint: 0.18; --fam-bg-primary: 240 0.84; --fam-bg-secondary: 236 0.86; --fam-bg-slot: 255 0.62; --fam-bg-slot-hover: 255 0.9; --fam-bg-slot-empty: 250 0.34; --fam-bg-overlay: 246 0.97; } ``` `--fam-tint` moves each grey toward the accent colour: 0 neutral, 1 the accent itself. The alpha is scaled by the background opacity. `--fam-alpha-floor` sets the lowest point of that scale, so a light family keeps its text readable at the bottom of the slider: glass uses `0.85`. A missing base takes the tactical value. The tokens every family defines: Property — What it paints `--surface-1` — Panel backgrounds `--surface-2` — Slots and cards `--surface-3` — Hovered or raised elements `--surface-empty` — Empty slots `--line` — Hairlines and borders `--line-strong` — Borders of hovered or focused elements `--ink` — Primary text `--ink-dim` — Secondary text `--ink-faint` — Placeholder text and disabled controls `--shadow` — Shadow colour under floating elements `--backdrop` — Full-screen dim behind dialogs `--accent-primary` and `--accent-rgb` come from the player's choice in the settings. Rarity colours, durability gradients and ammo tones are the same in every family. ### Screen effects **micio/config/ui.lua** ```lua MicioConfig.UI.Effects = { enabled = true, blur = false, tint = true, vignette = 0.6, } ``` - `enabled`, default `true`. Vignette behind the open inventory; the character preview stays clear. Players can switch it off in the settings. - `blur`, default `false`. `true` blurs the game world while the inventory is open, character preview included. ML Inventory drives the blur itself, so `inventory:screenblur` can stay `false`. - `tint`, default `true`. Vignette in the player's accent colour instead of black. - `vignette`, default `0.6`. Edge darkness, 0 to 1. ### Keys **micio/config/ui.lua** ```lua MicioConfig.UI.Keys = { wheel = 'z', hotkeys = { '1', '2', '3', '4', '5' }, hud = 'TAB', } MicioConfig.UI.Wheel = { enabled = true, } ``` - `wheel`, default `'z'`. Opens the item wheel. Rebindable per player in the FiveM keybind settings. - `hotkeys`, default `{ '1', '2', '3', '4', '5' }`. Keys of the five quick slots, in order. Rebindable per player. - `hud`, default `'TAB'`. Shows the HUD while `Hud.mode` is `'key'`. Rebindable per player. - `Wheel.enabled`, default `true`. `false` removes the radial wheel and its key. The quick slots and their keys stay. The keys for the item in hand are under Holding and giving items below. The key that opens the inventory itself belongs to ox_inventory and stays in its `inventory:keys` convar. ### Giving with consent **micio/config/ui.lua** ```lua MicioConfig.UI.Give = { consent = 'prompt', timeout = 15, distance = 5.0, acceptKey = 'Y', declineKey = 'N', } ``` - `consent`, default `'prompt'`. `prompt` opens a dialog on the receiver's screen with the giver's name, the item image, label and count, and waits for the answer. `auto` hands the item over at once, also when the `Give` block is absent. - `timeout`, default `15`. Seconds the receiver has to answer. When the time runs out the offer lapses and the giver is told. - `distance`, default `5.0`. Metres the two players may be apart while an offer is open. Past that the offer is refused before it starts, and an offer already waiting is cancelled and both players are told. Values are held between `1.0` and `50.0`. - `acceptKey`, default `'Y'`. Accepts an offer. Each player can rebind it in the FiveM keybind settings. - `declineKey`, default `'N'`. Declines an offer. Also rebindable. The dialog sits in the middle of the screen with an Accept and a Decline button, the countdown, and the two keys printed under the buttons as shortcuts. It works with the inventory closed: the offer takes the mouse cursor while it waits, the player keeps walking and driving, and the cursor goes back to the game as soon as the dialog closes. Escape declines. Give from the item context menu and the handover of the item in hand both go through this. The server holds the item until the answer arrives, then checks that both players are still connected, still within `distance` and still holding the same item in the same slot before it moves anything. After a declined or lapsed offer the giver waits a few seconds before offering again. While `prompt` is on, the `ox_inventory:giveItem` server event is refused: another resource cannot move an item out of a player's pockets without the receiver seeing the offer. Resources that hand out items should use `exports.ox_inventory:AddItem` instead. ### HUD The HUD is drawn while the inventory is closed: a card for the weapon in slot 1, a slimmer card for slot 2, and the five quick slots of the item wheel. The card of the weapon in hand takes the accent colour and shows magazine and reserve, red with an empty magazine, yellow with no reserve. The other weapon is dimmed. A weapon drawn from any other slot gets its own card while it is in hand. Each quick slot shows the item, its count, its wear and its key. **micio/config/ui.lua** ```lua MicioConfig.UI.Hud = { enabled = true, style = 'tactical', locked = false, x = 97, y = 96, scale = 100, emptySlots = true, mode = 'always', showSeconds = 5, } ``` - `enabled`, default `true`. Draws the HUD. - `style`, default `'tactical'`. `tactical` dark cards with a rarity edge, `classic` rounded cards in the inventory colours, `minimal` flat, `rarity` cards filled with the rarity colour, `glass` light translucent cards. Unknown values fall back to `tactical`. - `locked`, default `false`. `true` holds every player to the style, position and scale set here. - `x`, default `97`. Percent of screen width. 60 or more aligns the HUD to its right edge, 40 or less to its left edge, anything between centres it. - `y`, default `96`. Percent of screen height for the bottom edge of the HUD. - `scale`, default `100`. Percent, 60 to 140. - `emptySlots`, default `true`. `false` hides empty quick slots. - `mode`, default `'always'`. `always` keeps the HUD on screen. `key` shows it for `showSeconds` after `Keys.hud` or a quick slot key. - `showSeconds`, default `5`. Seconds on screen in `key` mode. A new press restarts the count. Edit mode closes the inventory and leaves the cursor on the HUD. Drag it, change the style, Enter or Done keeps the layout, Escape restores the previous one. ### Holding and giving items **micio/config/ui.lua** ```lua MicioConfig.UI.Hold = { enabled = true, useKey = 'G', stowKey = 'X', give = true, giveKey = 'H', giveDistance = 2.5, blockControls = {}, } ``` - `enabled`, default `true`. Using an item that has portions takes it into the hand instead of consuming it at once. - `useKey`, default `'G'`. Takes a portion from the item in hand. Each player can rebind it in the FiveM keybind settings. - `stowKey`, default `'X'`. Puts the item in hand away. - `give`, default `true`. Allows handing the item in hand to a player standing in front. - `giveKey`, default `'H'`. Starts aiming at the player to hand it to. Also rebindable. - `giveDistance`, default `2.5`. Metres between the two players for the handover to be accepted. - `blockControls`, default `{}`. Extra control ids disabled while an item is in hand. The keys above are already covered. ### Renaming **micio/config/ui.lua** ```lua MicioConfig.UI.Rename = { enabled = true, blacklist = {}, } ``` - `enabled`, default `true`. Lets players give an item their own name from its context menu. Every item is renamable while this is on. - `blacklist`, default `{}`. Item names players may not rename, written as `{ 'water', 'bandage' }`. ### Tooltip metadata **micio/config/ui.lua** ```lua MicioConfig.UI.Tooltip = { metadataWhitelist = { 'type', 'registered' }, showUnlisted = false, metadataPerItem = {}, } ``` - `metadataWhitelist`, default `{ 'type', 'registered' }`. Metadata keys shown in the tooltip. Keys registered through ox_inventory's `displayMetadata` are added on their own and need no entry here. - `showUnlisted`, default `false`. `true` shows every metadata key the item carries instead of the list above. - `metadataPerItem`, default `{}`. Per item override: `['note'] = { 'author' }` adds keys for that item, `true` shows all of them, `false` shows none. These keys are rendered elsewhere in the tooltip and are left out of the metadata list: `description`, `image`, `imageurl`, `label`, `weight`, `durability`, `degrade`, `serial`, `ammo`, `components`, `rotated`, `source`. A key whose value is empty, or is itself a table, is left out as well, whitelisted or not. > **INFO:** Per player settings > > Accent colour, interface scale, background opacity, panel positions and the HUD position, style and scale are saved on the player's own machine. The values above are what a player who has changed nothing starts with. `Hud.locked` takes the HUD back under owner control. ## Item fields Grid size, rarity, category and stack cap are set per item in `data/items.lua`, and from the item editor in the admin panel. - `width` and `height`: cells the item takes in the grid. Set both or neither: if either one is missing or is not a number, the item is 1 by 1. - `grid`: shorthand for the two above, written as `'2x1'`. On ammo, weapon components and tints only the width is taken and the height stays 1. - `maxstock`: how many units fit in one slot. Without it a slot holds any amount of that item. - `rarity`: `common`, `uncommon`, `rare`, `epic` or `legendary`. Defaults to `common`, and drives the slot colour and the rarity sort. - `category`: the tab the item falls into. Defaults to `misc`. - `description`: the text under the item name in the tooltip. `{key}` in the text is replaced with the value of that metadata key, and a `description` in the item metadata wins over the one in the definition. The text is rendered with `**bold**`, `*italic*`, lines starting with `-` or `*` as bullets, and line breaks kept. - `portions`: number of servings the item is used in, from 2 to 20. The item goes into the hand instead of being consumed at once, each use takes one serving and applies its share of the item's status effects. Ignored on weapons, ammo, weapon components and tints. - `use`: `food`, `drink` or `smoke`. Sets the action label and the wording of the portions line in the tooltip. Without it the kind is read from the status effects the item applies. - `decay` and `returndecay`: with `decay` set and `returndecay` naming another item, one unit of that item is added to the inventory when the durability timer runs out. ox_inventory's own item fields keep their meaning, `displayMetadata` included. ## ox_inventory settings Every `inventory:` convar you already set keeps its normal meaning. On qb-core, set `setr inventory:framework "qbx"` in `server.cfg`. ox_inventory only accepts esx, nd, ox or qbx in that convar, and reads its database table names from it. With `qbx` set, qb-core support loads whenever qb-core is running and qbx_core is not. The server prints a warning at boot when qb-core runs with any other value. The grid is the exception. `inventory:slots`, `inventory:gridcols`, `inventory:gridrows`, `inventory:secondarygridcols`, `inventory:dropcols` and `inventory:dropslots` are written at boot from `micio/config/grid.lua`, so a line for any of them in `server.cfg` has no effect. `inventory:imagepath` and `inventory:screenblur` are only given a value when you have not set one: an unset `inventory:screenblur` is written as `false`. Setting it true while the character preview is on blurs the preview with the rest of the frame, and the server says so at boot. Pointing `inventory:imagepath` at a resource that is not on the server is also reported at boot: item icons go missing there and in every other script that reads the convar. > **WARNING:** set vs setr > > Use `setr` for a convar the interface reads and `set` for server only values such as webhooks and loot tables. A client facing convar written with plain `set` never reaches the client, which then falls back to its built in default with no error anywhere. ## Language The inventory reads its own strings from `micio/translations/`. **micio/config/core.lua** ```lua MicioConfig.Language = 'auto' ``` - `Language`, default `'auto'`. Follows the `ox:locale` convar. Set a language code present in `micio/translations/` to force one regardless of the convar. **server.cfg** ```cfg setr ox:locale "en" ``` ox_inventory's own messages keep coming from its `locales/` folder. ML Clothing reads its in game strings from its own `locales/` folder, and `'auto'` follows the same convar. **shared/config.lua** ```lua Config.Language = 'auto' ``` - `Config.Language`, default `'auto'`. Follows the `ox:locale` convar, for the in game messages and for the admin panel alike. Set a language code present in `locales/` to force one regardless of the convar. ## ML Clothing configuration ### General **shared/config.lua** ```lua Config.Debug = false ``` - `Config.Debug`, default `false`. Prints diagnostic lines to the console. Keep it `false` in production. ### Notifications Each entry toggles one player message. Set an entry to `false` to suppress it. **shared/config.lua** ```lua Config.Notifications = { outfit_updated = true, clothing_slot_occupied = true, plate_inserted = true, bag_item_blocked = true, } ``` - `outfit_updated`, default `true`. Tells the player the worn outfit was saved. - `clothing_slot_occupied`, default `true`. Tells the player an item was refused because the clothing slot it belongs to is taken. - `plate_inserted`, default `true`. Tells the player an armor plate went into the carrier. - `bag_item_blocked`, default `true`. Tells the player an item was refused entry into a bag by the bag blacklist. ### Bags **shared/config.lua** ```lua Config.BagEffect = true Config.Bag = { DefaultWeight = 5000, DefaultCols = 3, DefaultRows = 3, SpeedTable = { { 0, 1.00 }, { 5, 0.97 }, { 10, 0.93 }, { 15, 0.88 }, { 18, 0.82 }, { 27, 0.75 }, { 36, 0.65 }, { 40, 0.55 }, }, } ``` - `Config.BagEffect`, default `true`. A worn bag slows the player down by the weight it carries. - `Config.Bag.DefaultWeight`, default `5000`. Bag capacity in grams used when the worn bag drawable has no entry in `Config.BagSizes`. - `Config.Bag.DefaultCols`, default `3`. Columns of the bag grid used with that default weight. - `Config.Bag.DefaultRows`, default `3`. Rows of the bag grid used with that default weight. - `Config.Bag.SpeedTable`: pairs of `{ weight_kg, speed_multiplier }`, interpolated linearly from the weight the bag carries. `0` kg gives full speed, `40` kg gives `0.55`. ### Bag sizes **shared/config.lua** ```lua Config.BagSizes = { female = { [111] = { weight = 10000, cols = 4, rows = 4}, [125] = { weight = 15000, cols = 6, rows = 4}, }, male = { [111] = { weight = 15000, cols = 6, rows = 4}, [113] = { weight = 10000, cols = 4, rows = 4}, }, } ``` - `Config.BagSizes`: maps the drawable index of the worn bag, per gender, to a stash size. Each entry sets `weight` in grams, `cols` and `rows`. A drawable with no entry falls back to `Config.Bag.DefaultWeight` and the default grid. The file ships a long table for `male` and `female`. The block above is an extract. Edit, add or remove indices to match your bag models. ### Armor plates **shared/config.lua** ```lua Config.SyncPlatesEveryHit = true Config.UseBrokenPlates = true Config.BrokenPlateItem = 'brokenplate' Config.HeavyDrawables = { male = { 12, 13, 15, 18 }, female = { 22, 23, 25, 28 }, } Config.Plates = { ['heavyplate'] = 50, ['lightplate'] = 25, ['brokenplate'] = 0, } ``` - `Config.SyncPlatesEveryHit`, default `true`. Plate health is written back on every damage event, so plate wear survives a disconnect at the cost of more frequent writes. - `Config.UseBrokenPlates`, default `true`. A plate that reaches zero health becomes the broken plate item. - `Config.BrokenPlateItem`, default `'brokenplate'`. Item name used for a destroyed plate. It has to be a registered item. - `Config.HeavyDrawables`: vest drawable indices, per gender, that make a plate carrier a heavy carrier. A heavy carrier holds two plates, any other carrier holds one, and the carrier stash is sized to match. Movement is not affected by this list. - `Config.Plates`: maps each plate item name to its armor value. A new plate is created with that value as its health, clamped to 50, so a value above 50 has no extra effect. The armor a carrier grants is the sum of the health of the plates inside it, capped at 100: two 50 point plates in a heavy carrier fill the bar. ### Clothing collections **shared/config.lua** ```lua Config.BagCollectionSizes = { male = {}, female = {} } Config.HeavyCollectionDrawables = { male = {}, female = {} } Config.ClothingCollectionRequirements = { male = {}, female = {} } ``` Use `male` or `female`, the exact GTA/FiveM collection name, and a zero-based drawable index within that collection. **shared/config.lua** ```lua Config.BagCollectionSizes.male['your_collection'] = { [0] = { cols = 4, rows = 3, weight = 12000 }, } Config.HeavyCollectionDrawables.male['your_collection'] = { 0, 2 } Config.ClothingCollectionRequirements.male['your_collection'] = { bodyarmor = { [0] = { { component_id = 3, collection = '', localDrawable = 0, texture = 0 }, }, }, } ``` The example names and indices are placeholders. Use valid values for the character model and installed pack. An empty collection name selects the base game collection. Bag entries set columns, rows and capacity in grams. Missing entries or fields use the default bag settings. Items with a global drawable keep using the existing bag size table; the base collection can also use that table with its local index. The heavy list selects armor models with two plate slots; models outside the list use one. It does not set plate protection. Global drawable items keep using the existing heavy model list. Requirements are indexed by clothing item name and local drawable. Each entry sets a component ID, texture, and either a collection with local drawable or a global drawable. The extra components are applied with the item and restored when it is removed. ### Clothing items **shared/config.lua** ```lua Config.ClothingItems = { hat = { slot = 11, type = 'prop', componentId = 0 }, undershirt = { slot = 12, type = 'component', componentId = 8 }, jacket = { slot = 13, type = 'component', componentId = 11 }, bodyarmor = { slot = 14, type = 'component', componentId = 9 }, gloves = { slot = 15, type = 'component', componentId = 3 }, pants = { slot = 16, type = 'component', componentId = 4 }, shoes = { slot = 17, type = 'component', componentId = 6 }, mask = { slot = 18, type = 'component', componentId = 1 }, glasses = { slot = 19, type = 'prop', componentId = 1 }, earrings = { slot = 20, type = 'prop', componentId = 2 }, chain = { slot = 21, type = 'component', componentId = 7 }, bracelet = { slot = 22, type = 'prop', componentId = 7 }, watch = { slot = 23, type = 'prop', componentId = 6 }, bag = { slot = 24, type = 'component', componentId = 5 }, decals = { slot = 25, type = 'component', componentId = 10 }, } ``` - `Config.ClothingItems`: the map from item name to inventory slot and ped component. Each entry has three fields. - `slot`: the inventory slot the item locks into, unique per item. The shipped values run 11 to 25. - `type`: `'component'` for a ped component, `'prop'` for a ped prop. - `componentId`: the game component or prop index the item drives. - `Config.ClothesSlotID`, `Config.ValidSlotsPerItem` and `Config.ComponentMapping` are built from this table when the resource loads. Leave them alone. > **WARNING:** Slot 14 is the plate carrier > > `bodyarmor` uses slot 14 and drives the plate carrier. Do not remap it and do not add it to the wear system. Its durability comes from the plates inside it. ### Default clothing **shared/config.lua** ```lua Config.DefaultClothing = { male = { mask = { draw = 0, text = 0 }, hat = { draw = -1, text = -1 }, pants = { draw = 21, text = 0 }, shoes = { draw = 34, text = 0 }, }, female = { pants = { draw = 15, text = 0 }, shoes = { draw = 35, text = 0 }, }, } ``` - `Config.DefaultClothing`: the drawable and texture applied to a clothing slot when its item is removed, per gender. `-1` clears the component or prop. The file ships an entry for each of the 15 clothing slots in both genders. The block above is an extract. ### Plate sync cooldown **shared/config.lua** ```lua Config.AntiExploit = { ArmorSyncCooldown = 150, } ``` - `ArmorSyncCooldown`, default `150`. Minimum milliseconds between two plate damage reports from the same player. Raise it on a server where players take hits in fast bursts, lower it only if plate wear feels late. ### Stash prefixes **shared/config.lua** ```lua Config.Stash = { PlateCarrierPrefix = 'platecarrier_', BagPrefix = 'playerbag_', } ``` - `Config.Stash.PlateCarrierPrefix`, default `'platecarrier_'`. Identifier prefix for plate carrier stashes. - `Config.Stash.BagPrefix`, default `'playerbag_'`. Identifier prefix for bag stashes. Both build unique stash identifiers. Leave them alone unless they collide with another resource, and change them only on a fresh database: existing stashes keep the old identifier. ### Bag blacklist **shared/config.lua** ```lua Config.BagBlacklist = { enabled = true, denyBagInsideBag = true, items = { }, prefixes = { 'blueprint_', }, } ``` - `enabled`, default `true`. Master switch for the filter. `false` turns it off. - `denyBagInsideBag`, default `true`. Refuses a bag item put inside another bag. - `items`, default empty. Exact item names refused entry into a bag. - `prefixes`, default `{ 'blueprint_' }`. Any item whose name starts with one of these strings is refused. The filter runs when the item is moved into a bag. A match refuses the move and the item stays where it was. The message the player gets is toggled by `Config.Notifications.bag_item_blocked`. ### Wear and decay **shared/config.lua** ```lua Config.WearDecay = { Enabled = true, Time = '60m', OnDepleted = 'break', Notify = true, Repairable = false, RepairItem = 'repair_kit', RepairCount = 1, RepairAmount = 100, Items = { ['antirad_mask'] = { time = '30m', male = { { component = 1, drawable = 244, texture = 0 }, { component = 1, drawable = 247, texture = 0 }, }, }, ['antirad_suit'] = { time = '60m', unisex = { { component = 11, drawable = 660, texture = 0 }, { component = 11, drawable = 731, texture = 0 }, }, }, }, } ``` - `Enabled`, default `true`. Master switch for the wear system. With it on, the pieces listed under `Items` lose durability while worn. - `Time`, default `'60m'`. How long a piece lasts while worn. Takes a number with a unit suffix (`'45s'`, `'30m'`, `'2h'`, `'1d'`) or a plain number, read as minutes. Entries without their own `time` use this value. - `OnDepleted`, default `'break'`. What happens at zero durability. `'break'` keeps the piece worn but broken, giving no protection, and flags it so other resources can react. `'remove'` takes it off instead. - `Notify`, default `true`. Tells the player when a piece breaks. - `Repairable`, default `false`. With `false` a worn piece cannot be repaired with an item and the player equips a fresh one to get the protection back. - `RepairItem`, default `'repair_kit'`. Item consumed to repair a worn piece. - `RepairCount`, default `1`. How many of that item a repair consumes. - `RepairAmount`, default `100`. Durability restored by one repair. - `Items`: the pieces the wear system watches, keyed by a name of your choice. An entry can match by drawable, by item name, or by both. For drawables, list `component`, `drawable` and `texture` under `male`, `female` or `unisex`. For item names, use `item = 'hazmat_suit'`, or a list of names. An entry may set its own `time`, for example `['work_gloves'] = { time = '30m', item = 'work_gloves' }`. The repair defaults can be overridden per entry with `repairItem`, `repairCount` and `repairAmount`, and `repairItem = false` makes that piece impossible to repair. A fuller `Items` table, with entries matched by drawable, by item name, and with their own repair rules: **shared/config.lua** ```lua Config.WearDecay.Items = { ['gas_mask'] = { time = '60m', male = { { component = 1, drawable = 247, texture = 0 } }, female = { { component = 1, drawable = 247, texture = 0 } }, repairItem = 'mask_filter', repairCount = 2, repairAmount = 100, }, ['hazmat_suit'] = { time = '2h', item = 'hazmat_suit', repairItem = 'duct_tape', repairCount = 3, repairAmount = 50, }, ['work_gloves'] = { time = '30m', item = 'work_gloves' }, ['dust_mask'] = { time = '10m', item = 'dust_mask', repairItem = false }, } ``` Repair happens when a player uses the repair item from the inventory: the most worn piece that uses that item is repaired, `repairCount` of the item is consumed and `repairAmount` durability comes back. In the table above a gas mask needs two mask filters, a hazmat suit needs three rolls of duct tape and only gets half its durability back, and a dust mask is thrown away when it breaks. Every repair item has to exist in `data/items.lua`: **data/items.lua** ```lua ['repair_kit'] = { label = 'Repair Kit', weight = 500, stack = true, close = true }, ['mask_filter'] = { label = 'Mask Filter', weight = 100, stack = true, close = true }, ['duct_tape'] = { label = 'Duct Tape', weight = 100, stack = true, close = true }, ``` A broken piece is exposed to other resources through the `ml_clothingBroken` state bag, the wear exports and the `OnGearBroken` and `OnGearRepaired` hooks, all on the [developer page](https://miciomods.it/docs/ml-inventory-developer). An item the wear system manages must not also carry `decay` or `degrade` in your items file. Both write the same durability value. ### Admin panel The admin panel reads its own file. **shared/invadmin_config.lua** ```lua Config.AdminAce = nil Config.Command = 'invadmin' Config.OpenKey = nil Config.DefaultTheme = 'default' Config.MinimizeKey = 'F9' Config.ClothingCatalogUrl = 'http://127.0.0.1:3960/api/catalog' ``` - `Config.AdminAce`, default `nil`. An ACE permission that opens the panel. A player holding it passes the admin check. Left `nil`, access falls back to the framework admin group. - `Config.Command`, default `'invadmin'`. The chat command that opens the panel. - `Config.OpenKey`, default `nil`. Key that opens the panel, for example `'F7'`. Set to a non empty string, a keybind is registered and each player can rebind it. Left `nil`, the panel opens by command only. - `Config.DefaultTheme`, default `'default'`. The panel theme a player starts on. - `Config.MinimizeKey`, default `'F9'`. Shrinks the open panel to a pill and brings it back. - `Config.ClothingCatalogUrl`, default `'http://127.0.0.1:3960/api/catalog'`. Endpoint the Clothing tab reads its catalog from. When the URL answers with anything other than a 200 and a JSON body, the Clothing tab shows an empty catalog. **shared/invadmin_config.lua** ```lua Config.RateLimit = { list = 500, get = 400, save = 1500, delete = 1500, upload = 1500, playerList = 500, playerGet = 400, playerGive = 800, playerRemove = 800, stashList = 500, stashGet = 400, stashSave = 1500, stashDelete = 1500, weapons = 500, weapon_get = 400, clothingImages = 150, playerImages = 150, } ``` - `Config.RateLimit`: cooldown in milliseconds per panel action. Higher values throttle that action harder. The list and get actions run on every navigation, so raising those two is what makes the panel feel unresponsive. **shared/invadmin_config.lua** ```lua Config.Editor = { MaxGrid = 5, NamePrefix = 'custom_', MaxImageBytes = 524288, } ``` - `MaxGrid`, default `5`. Largest width or height the item editor accepts. - `NamePrefix`, default `'custom_'`. Prefix added to the name of an item created in the editor. - `MaxImageBytes`, default `524288`. Largest item image the editor accepts, in bytes. **shared/invadmin_config.lua** ```lua Config.DiscordWebhook = { Default = 'INSERT_WEBHOOK_LINK_HERE', GiveItem = 'INSERT_WEBHOOK_LINK_HERE', RemoveItem = 'INSERT_WEBHOOK_LINK_HERE', ItemEdit = 'INSERT_WEBHOOK_LINK_HERE', ShopEdit = 'INSERT_WEBHOOK_LINK_HERE', InventoryEdit = 'INSERT_WEBHOOK_LINK_HERE', ClothingGive = 'INSERT_WEBHOOK_LINK_HERE', } ``` - `Config.DiscordWebhook`: one webhook per action, so each kind of admin action can land in its own channel. An entry left on the placeholder falls back to `Default`, and a `Default` left on the placeholder turns that log off. A value is only used when it starts with `http`.