Configuration
Configuration
ML Inventory adds three files under micio/config/. They hold every setting the layer adds and they are meant to be edited. The rest of the folder is your ox_inventory install and keeps behaving the way it does today.
Core
1MicioConfig.Debug = falseDebug, defaultfalse. Prints extra lines from the inventory layer to the console.
Grid
1MicioConfig.Grid = {
2 playerCols = 8,
3 playerRows = 4,
4 secondaryCols = 6,
5 dropCols = 6,
6 dropRows = 4,
7}playerCols, default8. Columns of the player grid.playerRows, default4. Rows of the player grid.secondaryCols, default6. Columns of the second grid on screen: stashes, trunks, gloveboxes and shops.dropCols, default6. Columns of a ground drop.dropRows, default4. Rows of a ground drop.
The player slot count follows the grid: playerCols times playerRows, plus the slots reserved for clothing and for the two weapon slots. Set the size here rather than with a slot count. A drop is sized the same way, from dropCols and dropRows.
Interface
1MicioConfig.UI = {
2 defaultTheme = '#00d4aa',
3 rarityStyle = 'fill-container',
4 enableThemePicker = true,
5 clothingPanelVisible = true,
6 virtualPed = true,
7 buttonTheme = false,
8 stockBadge = false,
9}defaultTheme, default'#00d4aa'. Accent colour a player starts with, as a hex string.rarityStyle, default'fill-container'. How the rarity colour is drawn on a slot.enableThemePicker, defaulttrue. Lets a player pick the accent colour from inside the inventory. Turn it off to keep everyone ondefaultTheme.clothingPanelVisible, defaulttrue. Shows the clothing panel beside the grid.virtualPed, defaulttrue. Shows the character preview beside the grid.buttonTheme, defaultfalse. Paints the action buttons with the accent colour.stockBadge, defaultfalse. Marks stackable and unique items with a badge on the slot.
Accent colour, interface scale, background opacity and panel positions are saved per player on their own machine. The values above are the starting point for a player who has changed nothing.
Item fields
Grid size, rarity and stack cap are set per item, in your items file or from the admin panel.
widthandheight: cells the item takes in the grid. One by one when absent.grid: shorthand for the two above, written as'2x1'.maxstock: how many units fit in one slot. Without it the grid puts no cap on a slot.rarity:common,uncommon,rare,epicorlegendary. Defaults tocommon.category: the tab the item falls into. Defaults tomisc.labelable: lets a player rename that item from the item menu.
ox_inventory settings
Every inventory: convar you already set keeps its normal meaning, and so does every file under data/. The values you run today carry over untouched. The grid size and the interface options are the exception: they live in the three files above instead of in convars.
Use setr for a convar the interface reads and set for server only values such as webhooks and loot tables. setr replicates the value to game clients; set keeps it on the server. 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 follows the ox_lib locale setting. One line in server.cfg:
1setr ox:locale "en"The files it reads are in locales/. ML Clothing picks its own from its own locales/ folder:
1Config.Language = 'en'ML Clothing configuration
ML Clothing runs as its own resource next to the inventory and keeps its settings in two files of its own. Every value below is shown with its default.
shared/config.luaholds the clothing, bag, armor plate, wear and anti-exploit settings.shared/invadmin_config.luaholds the settings for the admin panel.
General
1Config.Debug = false
2Config.Language = 'en'Config.Debug, defaultfalse. Prints diagnostic lines to the console. Keep itfalsein production.Config.Language, defaulten. Picks the file read from thelocales/folder, as covered under Language above.
Notifications
Each entry toggles one player message. Set an entry to false to suppress it.
1Config.Notifications = {
2 inventory_full_dropped = true,
3 not_enough_space = true,
4 inventory_full_add_failed = true,
5 outfit_updated = true,
6 clothing_slot_occupied = true,
7 no_carrier_equipped = true,
8 carrier_full = true,
9 plate_inserted = true,
10 plate_swapped = true,
11 plate_not_better = true,
12 bag_item_blocked = true,
13}inventory_full_dropped: an item was dropped on the ground because the inventory is full.not_enough_space: not enough room to equip the item.inventory_full_add_failed: an item could not be added back to the inventory.outfit_updated: the outfit changed.clothing_slot_occupied: the target clothing slot is reserved or already taken.no_carrier_equipped: a plate was used without a plate carrier equipped.carrier_full: the plate carrier has no free plate slot.plate_inserted: a plate was inserted.plate_swapped: a plate was swapped for a stronger one.plate_not_better: the inserted plate is weaker than what is already in the carrier.bag_item_blocked: an item was blocked from entering a bag by the bag blacklist.
Bags
1Config.BagEffect = true
2
3Config.Bag = {
4 DefaultWeight = 5000,
5 DefaultCols = 3,
6 DefaultRows = 3,
7
8 SpeedTable = {
9 { 0, 1.00 },
10 { 5, 0.97 },
11 { 10, 0.93 },
12 { 15, 0.88 },
13 { 18, 0.82 },
14 { 27, 0.75 },
15 { 36, 0.65 },
16 { 40, 0.55 },
17 },
18}Config.BagEffect, defaulttrue. A worn bag slows the player down by the weight it carries.Config.Bag.DefaultWeight, default5000. Bag capacity in grams used when the worn bag drawable has no entry inConfig.BagSizes.Config.Bag.DefaultColsandDefaultRows, default3and3. Bag grid used with the default weight.Config.Bag.SpeedTable: pairs of{ weight_kg, speed_multiplier }. The multiplier is interpolated linearly from the weight the bag carries.0kg gives full speed,40kg gives0.55.
Bag sizes
1Config.BagSizes = {
2 female = {
3 [111] = { weight = 10000, cols = 4, rows = 4},
4 [125] = { weight = 15000, cols = 6, rows = 4},
5 -- ...
6 },
7 male = {
8 [111] = { weight = 15000, cols = 6, rows = 4},
9 -- ...
10 },
11}Config.BagSizes: maps the worn bag drawable index, per gender, to a stash size. Each entry setsweightin grams,colsandrows. When a bag is equipped, the drawable index of the bag component on the ped decides which entry applies. A drawable with no entry falls back toConfig.Bag.DefaultWeightand the default grid. The file ships with a long default table formaleandfemale; edit, add or remove indices to match your bag models.
Progress
1Config.Progress = {
2 OpenDuration = 2500,
3}Config.Progress.OpenDuration, default2500. Length in milliseconds of the progress bar shown when a player opens a bag.
Armor plates
1Config.SyncPlatesEveryHit = true
2Config.UseBrokenPlates = true
3Config.BrokenPlateItem = 'brokenplate'
4
5Config.HeavyDrawables = {
6 male = { 12, 13, 15, 18 },
7 female = { 22, 23, 25, 28 },
8}
9
10Config.Plates = {
11 ['heavyplate'] = 50,
12 ['lightplate'] = 25,
13 ['brokenplate'] = 0,
14}Config.SyncPlatesEveryHit, defaulttrue. Plate health is written back on every damage event, so plate wear survives a disconnect at the cost of more frequent writes.Config.UseBrokenPlates, defaulttrue. A plate that reaches zero health becomes the broken plate item.Config.BrokenPlateItem, defaultbrokenplate. The item name used for a destroyed plate. It has to be a registered item.Config.HeavyDrawables: per gender drawable indices that count as heavy armor visuals and affect movement.Config.Plates: maps each plate item name to its armor value, 0 to 100. The armor a carrier grants is the sum of its plate health, capped at 100.
Clothing items
1Config.ClothingItems = {
2 hat = { slot = 11, type = 'prop', componentId = 0 },
3 undershirt = { slot = 12, type = 'component', componentId = 8 },
4 jacket = { slot = 13, type = 'component', componentId = 11 },
5 bodyarmor = { slot = 14, type = 'component', componentId = 9 },
6 gloves = { slot = 15, type = 'component', componentId = 3 },
7 pants = { slot = 16, type = 'component', componentId = 4 },
8 shoes = { slot = 17, type = 'component', componentId = 6 },
9 mask = { slot = 18, type = 'component', componentId = 1 },
10 glasses = { slot = 19, type = 'prop', componentId = 1 },
11 earrings = { slot = 20, type = 'prop', componentId = 2 },
12 chain = { slot = 21, type = 'component', componentId = 7 },
13 bracelet = { slot = 22, type = 'prop', componentId = 7 },
14 watch = { slot = 23, type = 'prop', componentId = 6 },
15 bag = { slot = 24, type = 'component', componentId = 5 },
16 decals = { slot = 25, type = 'component', componentId = 10 },
17}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.- From this table the resource builds
Config.ClothesSlotID,Config.ValidSlotsPerItemandConfig.ComponentMapping. Those three are filled in automatically; do not edit them by hand.
bodyarmor uses slot 14 and drives the plate carrier. Do not remap it and do not add it to the wear system. It has its own plate durability.
Default clothing
1Config.DefaultClothing = {
2 male = {
3 mask = { draw = 0, text = 0 },
4 hat = { draw = -1, text = -1 },
5 pants = { draw = 21, text = 0 },
6 shoes = { draw = 34, text = 0 },
7 -- ...
8 },
9 female = {
10 pants = { draw = 15, text = 0 },
11 shoes = { draw = 35, text = 0 },
12 -- ...
13 },
14}Config.DefaultClothing: the drawable and texture applied to a clothing slot when the item is removed, per gender. A value of-1clears the component or prop. These are the fallback values, so taking a jacket off does not leave a hole in the model.
Anti-exploit
1Config.AntiExploit = {
2 PlateSwapCooldown = 2000,
3 ValidatePlateHealth = true,
4 MaxHeavyPlates = 2,
5 MaxLightPlates = 1,
6 PreventArmorDupe = true,
7}PlateSwapCooldown, default2000. Minimum milliseconds between plate swaps, per player.ValidatePlateHealth, defaulttrue. Plate health is checked on the server on every plate action instead of trusting the client.MaxHeavyPlates, default2. Maximum heavy plates a player may carry.MaxLightPlates, default1. Maximum light plates a player may carry.PreventArmorDupe, defaulttrue. Blocks the known armor duplication paths.
Stash prefixes
1Config.Stash = {
2 PlateCarrierPrefix = 'platecarrier_',
3 BagPrefix = 'playerbag_',
4}Config.Stash.PlateCarrierPrefix, defaultplatecarrier_. Identifier prefix for plate carrier stashes.Config.Stash.BagPrefix, defaultplayerbag_. Identifier prefix for bag stashes. Both build unique stash identifiers; leave them alone unless they collide with another resource.
Bag blacklist
1Config.BagBlacklist = {
2 enabled = true,
3 denyBagInsideBag = true,
4
5 items = {
6 -- 'gold',
7 -- 'weapon_rpg',
8 },
9
10 prefixes = {
11 'blueprint_',
12 -- 'ammo_',
13 },
14}enabled, defaulttrue. Master switch for the bag content filter.falseturns the whole filter off.denyBagInsideBag, defaulttrue. Blocks putting a bag inside another bag.items: exact item names blocked from entering a bag.prefixes: any item whose name starts with one of these strings is blocked. The file ships withblueprint_.- The filter runs when the item is moved: a match has the move refused. The message shown to the player is toggled by
Config.Notifications.bag_item_blocked.
Wear and decay
1Config.WearDecay = {
2 Enabled = true,
3 Time = '60m',
4 OnDepleted = 'break',
5 Notify = true,
6
7 Repairable = false,
8 RepairItem = 'repair_kit',
9 RepairCount = 1,
10 RepairAmount = 100,
11
12 Items = {
13 ['antirad_mask'] = {
14 time = '30m',
15 male = {
16 { component = 1, drawable = 244, texture = 0 },
17 -- ...
18 },
19 },
20 ['antirad_suit'] = {
21 time = '60m',
22 unisex = {
23 { component = 11, drawable = 660, texture = 0 },
24 { component = 11, drawable = 731, texture = 0 },
25 },
26 },
27 },
28}Enabled, defaulttrue. Master switch for the wear system. When on, the drawables listed below 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 owntimeuse this value.OnDepleted, default'break'. What happens at zero durability.'break'keeps the piece worn but broken, giving no protection, and flags it as broken so other resources can react.Notify, defaulttrue. Tells the player when a piece breaks.Repairable, defaultfalse. Withfalsea worn piece cannot be repaired with an item and the player equips a fresh one to get the protection back.RepairItem,RepairCountandRepairAmount: the repair item, how many are consumed and how much durability is restored, for entries that do not set their own.Items: the drawables the wear system watches. An entry matches by drawable (component,drawable,texture) undermale,femaleorunisex, or by item name, and may set its owntime. An entry may override the repair defaults withrepairItem,repairCountandrepairAmount, andrepairItem = falsemakes that piece impossible to repair. The shipped entries cover gas masks and antirad suits. Do not addbodyarmorhere, it has its own plate durability._INSTALL/WEAR_DECAY.txthas the full setup notes.
Admin panel
The admin panel reads its own file.
1Config.AdminAce = nil
2Config.Command = 'invadmin'
3Config.OpenKey = nil
4Config.DefaultTheme = 'default'
5Config.MinimizeKey = 'F9'Config.AdminAce, defaultnil. An ACE permission that grants access to the panel. A player holding it passes the admin check. Leftnil, access falls back toBridge.HasPermission.Config.Command, defaultinvadmin. The chat command that opens the panel.Config.OpenKey, defaultnil. An optional key binding for the panel. Set to a non empty string, a keybind is registered and the player can rebind it. Leftnil, 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 restores it.
1Config.RateLimit = {
2 list = 500,
3 get = 400,
4 save = 1500,
5 delete = 1500,
6 upload = 1500,
7 playerList = 500,
8 playerGet = 400,
9 playerGive = 800,
10 playerRemove = 800,
11 stashList = 500,
12 stashGet = 400,
13 stashSave = 1500,
14 stashDelete = 1500,
15 weapons = 500,
16 weapon_get = 400,
17 clothingImages = 150,
18 playerImages = 150,
19}Config.RateLimit: cooldowns in milliseconds, one per panel action. Raising a value throttles that action harder, lowering it allows faster repeat use. Leave room on the browsing actions, a cooldown set too high makes the panel feel stuck.
1Config.Editor = {
2 DefaultGrid = { width = 1, height = 1 },
3 MaxGrid = 5,
4 DefaultWeight = 0,
5 DefaultStack = true,
6 DefaultClose = true,
7 NamePrefix = 'custom_',
8 Rarities = {
9 'common',
10 'uncommon',
11 'rare',
12 'epic',
13 'legendary',
14 },
15 ConsumableTypes = {
16 'food',
17 'drink',
18 'alcohol',
19 'medical',
20 'other',
21 },
22 MaxImageBytes = 524288,
23}DefaultGrid: grid size a new item starts with in the editor.MaxGrid, default5. Largest grid width or height the editor accepts.DefaultWeight, default0. Weight a new item starts with.DefaultStack, defaulttrue. Whether a new item stacks.DefaultClose, defaulttrue. Whether a new item closes the inventory when used.NamePrefix, defaultcustom_. Prefix applied to the name of an item created in the editor.Rarities: the rarity options the editor offers.ConsumableTypes: the consumable type options the editor offers.MaxImageBytes, default524288. Largest item image the editor accepts, in bytes.
1Config.DiscordWebhook = {
2 Default = 'INSERT_WEBHOOK_LINK_HERE',
3 GiveItem = 'INSERT_WEBHOOK_LINK_HERE',
4 RemoveItem = 'INSERT_WEBHOOK_LINK_HERE',
5 ItemEdit = 'INSERT_WEBHOOK_LINK_HERE',
6 ShopEdit = 'INSERT_WEBHOOK_LINK_HERE',
7 InventoryEdit = 'INSERT_WEBHOOK_LINK_HERE',
8 ClothingGive = 'INSERT_WEBHOOK_LINK_HERE',
9}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 toDefault, and aDefaultleft on the placeholder turns that log off.