# Configuration > Configuration reference for ML Recycler Category: RECYCLER · Source: https://miciomods.it/docs/ml-recycler-configuration · Last updated: 2026-07-09 ## Overview - `shared/config.lua`: Core settings, features, the recycler definition, recipes, upgrades, durability, fuel, fixed stations - `shared/data/item_models.lua`: 3D prop mappings for the sinking animation - `server/config_server.lua`: Discord webhooks and rate limiting The recipes and upgrades shipped in `shared/config.lua` are working examples. Replace them with the items your server uses. ## General **shared/config.lua** ```lua Config.Debug = false Config.Language = 'en' Config.Theme = 'default' Config.MaxRecyclersPerPlayer = 1 Config.DuiResolution = { width = 1920, height = 1080 } Config.InteractionDistance = 3.0 Config.PlacementDistance = 5.0 ``` - `Debug`: Console output for troubleshooting - `Language`: Locale code. See the `locales/` folder. - `Theme`: Visual theme for the screen. The shipped theme is `'default'`. - `MaxRecyclersPerPlayer`: Maximum player-placed recyclers per character - `DuiResolution`: Render resolution of the screen on the prop. `960x540` is lighter, `1920x1080` is sharper - `InteractionDistance`: Range in meters to interact with a placed machine - `PlacementDistance`: Maximum distance from the player a new machine can be placed ## Placement Rules **shared/config.lua** ```lua Config.PlacementRestriction = { enabled = false, radius = 25.0, requiredProps = {}, } Config.PickupCooldown = { enabled = true, seconds = 300, } ``` - `PlacementRestriction.enabled`: When `true`, a recycler can only be placed within `radius` meters of one of the prop model hashes in `requiredProps` - `PickupCooldown.enabled`: Locks pickup for `seconds` after placing, blocking place-then-instant-pickup abuse ## Feature Toggles **shared/config.lua** ```lua Config.Features = { bulkRecycling = true, queueSystem = true, fuelSystem = true, breakdownAnimations = true, ambientSounds = true, propSinking = true, lootReveal = true, upgradeSystem = true, durabilitySystem = true, } ``` - `bulkRecycling`: Insert a stack of the same item in one action - `queueSystem`: Items queue when all slots are busy and auto-promote as slots free up - `fuelSystem`: Fuel is consumed while processing. When `false`, the fuel bar is hidden and refuel/consumption are disabled - `breakdownAnimations`: Particle effects during processing - `ambientSounds`: 3D loop sound through xsound while running - `propSinking`: Inserted item models sink into the slot as they process - `lootReveal`: Show the loot preview before collecting - `upgradeSystem`: Allow upgrade installation - `durabilitySystem`: Degradation, slowdown, malfunction and repair ## The Recycler **shared/config.lua** ```lua Config.Recycler = { label = _L('recycler_label'), item = 'recycler', baseSlots = 3, maxSlots = 6, processSpeedMultiplier = 1.0, spawnDistance = 50.0, screenDistance = 10.0, } ``` - `label`: Name shown in the UI and notifications - `item`: Inventory item used to place the recycler - `baseSlots`: Slots available before upgrades (each slot processes one item) - `maxSlots`: Absolute slot cap. Base plus a slot-expansion upgrade can never exceed this - `processSpeedMultiplier`: Base speed. `1.0` is normal, below `1.0` is faster - `spawnDistance`: Distance at which the prop streams in for nearby players - `screenDistance`: Distance at which the screen becomes visible > **TIP:** Recipe tier > > Recipes can gate outputs and bonuses behind a recycler tier. The recycler runs at tier `1` by default. Add `tier = 2` (or `3`) to `Config.Recycler` to unlock higher-tier outputs and bonuses everywhere. ## Fuel Read only when `Config.Features.fuelSystem = true`. **shared/config.lua** ```lua Config.Fuel = { capacity = 100, perMinute = 2, items = { ['industrial_battery'] = 25, ['fuel_canister'] = 50, }, mlFuel = { enabled = true, hintItems = {}, acceptedFuelTypes = { 'diesel' }, typeLabels = { ['diesel'] = 'Diesel', ['fuel'] = 'Gasoline' }, litersToUnits = 5, }, } ``` - `capacity`: Tank size in units. The `extra_tank` upgrade raises it - `perMinute`: Units burned per minute of active processing - `items`: One-shot fuel items. `['item'] = units`. The item is removed on use - `mlFuel.enabled`: Accept reusable jerrycans from `ml_fuel`. Any item carrying `metadata.fuelAmount` and `metadata.fuelType` is treated as a jerrycan: it is kept in the inventory and only emptied, never consumed - `mlFuel.acceptedFuelTypes`: Fuel types the machine accepts. Must match keys in `ml_fuel` `Config.FuelTypes` - `mlFuel.typeLabels`: UI label per fuel type - `mlFuel.litersToUnits`: How many recycler fuel units one liter of `ml_fuel` becomes ## Recipes The key is the input item. Each recipe defines the time and the possible outputs. **shared/config.lua** ```lua Config.RecycleRecipes = { ['broken_phone'] = { baseTime = 20, outputs = { { item = 'glass', min = 1, max = 2, chance = 100 }, { item = 'copper', min = 1, max = 2, chance = 60 }, { item = 'microchip', min = 1, max = 1, chance = 15, tierRequired = 3 }, }, tierBonuses = { [2] = { chanceBoost = 10, quantityBoost = 1 }, [3] = { chanceBoost = 25, quantityBoost = 2 }, }, }, } ``` - `baseTime`: Processing time in seconds. Effective time = `baseTime * processSpeedMultiplier`, then upgrade and durability modifiers - `outputs`: Possible results. Each has `item`, `min`/`max` quantity, and `chance` (0-100). Add `tierRequired = 2` to gate an output behind a recycler tier - `tierBonuses`: Applied automatically by recycler tier. `chanceBoost` adds chance points to every output, `quantityBoost` adds to each output `max` ## Rarity Colors and labels for the loot preview. **shared/config.lua** ```lua Config.Rarity = { common = { color = '#9ca3af', label = _L('rarity_common') }, uncommon = { color = '#22c55e', label = _L('rarity_uncommon') }, rare = { color = '#3b82f6', label = _L('rarity_rare') }, epic = { color = '#a855f7', label = _L('rarity_epic') }, legendary = { color = '#f59e0b', label = _L('rarity_legendary') }, } ``` ## Upgrades **shared/config.lua** ```lua Config.MaxUpgradesPerRecycler = 3 Config.Upgrades = { ['turbo_motor'] = { label = _L('upgrade_turbo_motor'), item = 'turbo_motor', icon = 'turbo_motor', effects = { processSpeedBonus = -0.20 } }, ['extra_tank'] = { label = _L('upgrade_extra_tank'), item = 'extra_tank', icon = 'extra_tank', effects = { fuelCapacityBonus = 0.50 } }, ['silencer_kit'] = { label = _L('upgrade_silencer_kit'), item = 'silencer_kit', icon = 'silencer_kit', effects = { soundDistanceMultiplier = 0.40 } }, ['solar_panel'] = { label = _L('upgrade_solar_panel'), item = 'solar_panel', icon = 'solar_panel', effects = { fuelRegenPerMinute = 1 } }, } ``` - `MaxUpgradesPerRecycler`: Upgrade slots per machine - `effects.processSpeedBonus`: Multiplier change to processing time. `-0.20` is 20% faster - `effects.fuelCapacityBonus`: Fraction added to tank size. `0.50` is +50% - `effects.soundDistanceMultiplier`: Multiplies the ambient and zombie-noise radius. `0.40` is 60% quieter - `effects.fuelRegenPerMinute`: Passive fuel units generated per minute Upgrades are consumed on install and returned to the player on removal, carrying their state. To make a slot-expansion module, add an upgrade with `effects = { slotBonus = N }`, give it an item, and the machine unlocks `N` extra slots up to `maxSlots`. The `upgrade_slot_expansion` label is already in the locale files. > **TIP:** Optional wear > > Upgrades are permanent by default. Add a `wear` table to an upgrade definition to give it a durability curve that drains on use and auto-removes the module at zero: > > ```lua > ['turbo_motor'] = { > label = _L('upgrade_turbo_motor'), item = 'turbo_motor', icon = 'turbo_motor', > effects = { processSpeedBonus = -0.20 }, > wear = { enabled = true, startDurability = 100, degradePerProcess = 1 }, > } > ``` ## Durability **shared/config.lua** ```lua Config.Durability = { degradePerProcess = 2, slowdownThreshold = 50, slowdownMultiplier = 1.20, malfunctionThreshold = 25, malfunctionChance = 15, malfunctionCooldown = 600, brokenThreshold = 0, } ``` - `degradePerProcess`: Durability points lost per completed slot - `slowdownThreshold`: Below this percent, processing runs at `slowdownMultiplier` time - `malfunctionThreshold`: Below this percent, each process can jam - `malfunctionChance`: Malfunction probability (0-100) - `malfunctionCooldown`: Lockout in seconds after a malfunction - `brokenThreshold`: At this value the machine stops until repaired ## Repair Items **shared/config.lua** ```lua Config.RepairItems = { ['repair_kit'] = { restore = 100, label = _L('repair_item_repair_kit') }, ['patch_kit'] = { restore = 50, label = _L('repair_item_patch_kit') }, ['lubricant'] = { restore = 25, label = _L('repair_item_lubricant') }, } ``` - `restore`: Durability points the item restores on use ## Zombie Noise **shared/config.lua** ```lua Config.ZombieNoise = { enabled = false, resourceName = 'ml_zombies', defaultRadius = 50.0, defaultDuration = 0, } ``` - `enabled`: A running machine attracts zombies within `defaultRadius` - `resourceName`: Zombie resource to signal. The hook only fires if it is started - `defaultDuration`: `0` keeps the noise active until processing stops The `silencer_kit` upgrade multiplies `defaultRadius` down through `soundDistanceMultiplier`. ## Fixed Stations Permanent recyclers you place in the world. Players cannot pick them up. **shared/config.lua** ```lua Config.FixedStations = { { id = 'unique_station_id', coords = vec3(0.0, 0.0, 0.0), heading = 0.0, infiniteFuel = false, permanentUpgrades = { 'turbo_motor', 'silencer_kit' }, }, } ``` - `id`: Unique station id, stored in the database - `infiniteFuel`: When `true`, this station never runs out of fuel - `permanentUpgrades`: Upgrades installed for good. Players cannot remove them and the wear system ignores them ## Permissions **shared/config.lua** ```lua Config.DefaultPermissions = { onlyOwnerCanUse = false, onlyOwnerCanRemove = true, onlyOwnerCanRefuel = false, onlyOwnerCanUpgrade = false, } ``` - Applies to every player-placed recycler. Fixed stations always allow public upgrade access so a town can share one machine ## Discord Webhooks **server/config_server.lua** ```lua ServerConfig.DiscordWebhook = '' ServerConfig.RecyclingWebhook = '' ServerConfig.PlacementWebhook = '' ServerConfig.ErrorWebhook = '' ServerConfig.ExploitsWebhook = '' ServerConfig.RateLimitCooldown = 1000 ``` - `DiscordWebhook`: Fallback webhook used by any channel left empty - `RecyclingWebhook`: Recycling started, collected, refueled, repaired, upgrade install/remove - `PlacementWebhook`: Recycler placed and picked up - `ErrorWebhook`: Database failures and rollback events - `ExploitsWebhook`: Rate-limit spam, payload type mismatches, distance and origin checks - `RateLimitCooldown`: Minimum milliseconds between actions per player Set any webhook to `false` to disable that log entirely.