Configuration

15 min readUpdated 2 weeks ago

Overview

  • shared/config.lua: language, ranges, features, community projects, progression, blueprints, portable stations, model benches, fuel, base building and display
  • shared/config_models.lua: station model presets, bench prop, screen placement and camera
  • server/config_server.lua: battlepass and Discord webhooks

Stations, recipes, categories, blueprints, projects and custom station models live in the database and are built from the admin panel (/craftadmin). When the same setting exists in both places, such as fuel, durability, pickup rules and queue limits, the value saved in the panel wins.

General

shared/config.lua
1Config.Debug = false
2Config.Language = 'en'
3Config.Command = 'craftadmin'
  • Debug: prints extra console output
  • Language: language file loaded from the locales/ folder
  • Command: opens the admin panel

UI Theme

shared/config.lua
1Config.UITheme = {
2    preset = nil,
3    colors = {
4        primary = nil,
5        accent = nil,
6        background = nil,
7        surface = nil,
8        text = nil,
9    },
10}
  • preset: theme preset for this resource. 'default', 'wasteland', 'cyberpunk', 'noir' or 'fantasy'. nil follows the shared theme set in ml_bridge
  • colors: CSS hex values for single colors. Any nil value follows the shared theme. Each bench can also get its own tint in the admin panel

Interaction and Streaming

shared/config.lua
1Config.Interaction = {
2    TargetDistance = 2.5,
3    SpawnDistance = 80.0,
4    MaxOperationRange = 5.0,
5}
6
7Config.Stream = {
8    Radius = 200.0,
9    OutRadius = 250.0,
10    ReloadDistance = 100.0,
11    PollMinInterval = 1500,
12    PollMaxInterval = 4000,
13}
  • TargetDistance: meters to interact with a bench
  • SpawnDistance: meters at which bench props spawn and despawn
  • MaxOperationRange: highest distance the server accepts for any crafting action
  • Radius, OutRadius: benches inside Radius are loaded on the client, benches beyond OutRadius are dropped. Keep OutRadius larger
  • ReloadDistance: meters the player moves before the client asks the server for benches again
  • PollMinInterval, PollMaxInterval: position check interval in milliseconds, faster while moving and slower while standing

Features

shared/config.lua
1Config.Features = {
2    Spotlight = true,
3    PortableStations = true,
4    Blueprints = true,
5    QueuedCrafting = true,
6    PropPreview = true,
7    CraftAnimations = true,
8    DamageInterrupt = true,
9    MultipleCrafters = false,
10    Invincibility = false,
11    CommunityProjects = true,
12}
  • Spotlight: soft light above the bench while a player uses it, so the screen reads at night. Tuned in Config.WorkLight
  • PortableStations: benches players place with an item
  • Blueprints: recipes can need a blueprint, as an item or a permanent unlock
  • QueuedCrafting: start a craft, walk away and collect it later
  • PropPreview: 3D preview of the result while crafting
  • CraftAnimations: player animation while crafting
  • DamageInterrupt: taking damage stops the craft
  • MultipleCrafters: several players on the same bench at once. With false, one player at a time
  • Invincibility: the player takes no damage while crafting. Only with MultipleCrafters = false
  • CommunityProjects: server-wide goals players give materials to

Community Projects

The whole server works toward a goal. Players donate materials at a station, or advance the goal by crafting the item it asks for. At 100% the project pays rewards and can unlock recipes, categories or station types for everyone. Projects are created in the admin panel with no restart.

shared/config.lua
1Config.CommunityProjects = {
2    MaxPerDonation = 1000,
3    AnnounceAt = { 25, 50, 75 },
4    InstantReward = true,
5    RewardTiers = true,
6    Leaderboard = true,
7    ShowInAttract = true,
8    XpPerUnit = 1,
9    PlayerNameFormat = 'rp_full',
10    BoardRange = 25.0,
11    BoardTint = '',
12}
  • MaxPerDonation: highest amount one donation can give
  • AnnounceAt: progress percentages announced to the whole server
  • InstantReward: gives the XP of each donation at once instead of only at completion
  • RewardTiers: completion rewards by tier: top contributors, everyone above a share, or anyone who took part
  • Leaderboard: shows the contributor board. Each project can also hide its contributors
  • ShowInAttract: shows the running project on idle station screens
  • XpPerUnit: XP for each donated unit
  • PlayerNameFormat: name on the board. 'fivem' (account name), 'rp_first' (character first name) or 'rp_full' (first and last name, or the first name when there is no last name)
  • BoardRange: meters at which a community board screen turns on. Other stations use Config.DUI.Range
  • BoardTint: accent color of community boards. Empty uses the same accent as every other station. A tint set on the station in the panel wins
Community Boards

A community board is a placed station whose type is set to Community board in the admin panel. It opens the project list instead of the crafting menu, and skips fuel, wear and the queue. Other stations of the same bench type keep working as workbenches.

Internal Progression

Used only with Config.ExternalSkills.Enabled = false. Levels and XP are saved per player in the database.

shared/config.lua
1Config.Progression = {
2    Enabled = false,
3    GlobalXp = {
4        Base = 100,
5        Scaling = 1.4,
6        MaxLevel = 50,
7    },
8    CategoryXp = {
9        Base = 50,
10        Scaling = 1.3,
11        MaxLevel = 30,
12    },
13    Points = {
14        PerLevelUp = 1,
15        PerCategoryLevelUp = 1,
16    },
17}
  • Enabled: turns the built-in levels on
  • GlobalXp: XP needed per level is Base * (Scaling ^ (level - 1)), up to MaxLevel. Scaling = 1.0 is linear
  • CategoryXp: same formula for each recipe category
  • Points: points given on a level up

Skills

shared/config.lua
1Config.ExternalSkills = {
2    Enabled = true,
3    Resource = 'ml_skills',
4    Mapping = {
5        Category = '',
6        XpMultiplier = 1.0,
7        PerCategory = {},
8    },
9}
  • Enabled: levels, skill checks and XP come from ml_skills. false uses the internal progression
  • Resource: name of the skills resource
  • Mapping.Category: skill category used when a recipe has neither a required skill nor a category. XP goes first to the category of the required skill, then to the PerCategory match, then to the recipe category
  • Mapping.XpMultiplier: multiplier on recipe XP sent to ml_skills
  • Mapping.PerCategory: map of crafting category ID to skill category UID, when the names differ

Recipes and Queue

shared/config.lua
1Config.Recipes = {
2    HideUnavailable = true,
3    HideMissingBlueprint = true,
4    ShowLockedPreview = false,
5    MaxQueueSize = 3,
6    MaxBatchSize = 0,
7}
8
9Config.Queue = {
10    CleanupEnabled = true,
11    CleanupAfterDays = 7,
12    CleanupCheckInterval = 3600,
13    SharedView = true,
14    AllowSteal = true,
15}
  • HideUnavailable: hides recipes the player cannot craft yet
  • HideMissingBlueprint: hides recipes whose blueprint the player lacks
  • ShowLockedPreview: shows locked recipes as a preview the player cannot craft
  • MaxQueueSize: queued crafts per player, counted over all benches together. 0 for no limit. Bench types can set their own limit in the panel
  • MaxBatchSize: highest quantity of one craft. 0 for no limit
  • CleanupEnabled, CleanupAfterDays: removes finished crafts nobody collected after this many days
  • CleanupCheckInterval: seconds between two cleanup checks
  • SharedView: everyone at the bench sees the queue of every player
  • AllowSteal: players can collect the finished crafts of others. Each one is logged

Blueprints

shared/config.lua
1Config.Blueprints = {
2    GenericItemName = 'ml_blueprint',
3    DynamicPrefix = 'blueprint_',
4    StrictMode = false,
5    ConsumeOnCraft = false,
6    Durability = {
7        Enabled = false,
8        DefaultUses = 5,
9    },
10}
  • GenericItemName: one shared item that carries metadata.blueprint = '<blueprint id>'. Needs an inventory with metadata
  • DynamicPrefix: one item per blueprint, named blueprint_<label>. A custom item name can also be set per blueprint in the panel
  • StrictMode: every recipe needs a blueprint
  • ConsumeOnCraft: removes the blueprint item after crafting
  • Durability: gives blueprints a number of uses. Works with ConsumeOnCraft = true. Permanent unlocks are never used up

Portable Stations

shared/config.lua
1Config.PortableStations = {
2    GenericItemName = 'ml_workstation',
3    DynamicSuffix = '_workstation',
4    MaxPerPlayer = 5,
5    PlacementRange = 5.0,
6    DefaultPickupRule = 'owner',
7    DefaultPickupTimeOwner = 5,
8    DefaultPickupTimeTheft = 15,
9    TheftAnimation = 'mini@repair',
10    TheftAnimationName = 'fixing_a_ped',
11    LogTheft = true,
12    DeleteOld = 10,
13    DeleteOptions = {
14        DeleteOnlyIfNotCrafting = true,
15        DeleteOnlyIfNoFuel = true,
16        DeleteOnlyIfBroken = false,
17    },
18    RequireAnchor = {
19        Enabled = false,
20        Radius = 5.0,
21        Props = {
22            2139035592,
23            -1933224451,
24            -1924811947,
25            -1668132370,
26        },
27    },
28    PickupCooldown = 0,
29}
  • GenericItemName: base station item. The bench type comes from metadata.stationType. Bench types can also have an item of their own in the panel
  • DynamicSuffix: suffix of per-type station items, such as medic_workstation
  • MaxPerPlayer: placed stations per player
  • PlacementRange: highest placement distance from the player
  • DefaultPickupRule: who can pick a station up. 'owner', 'everyone' or a list of jobs. Bench types can change it in the panel
  • DefaultPickupTimeOwner, DefaultPickupTimeTheft: seconds to pick up your own station or someone else's
  • TheftAnimation, TheftAnimationName: animation played while stealing a station
  • LogTheft: logs theft attempts
  • DeleteOld: days without use before an abandoned station is deleted. false turns it off
  • DeleteOptions: keeps a station that still has a queue, fuel or durability left
  • RequireAnchor: placement needs one of the listed prop models within Radius, for example to keep stations inside a base. Hashes are signed numbers as returned by GetEntityModel
  • PickupCooldown: seconds after placement before pickup is allowed. 0 turns it off

Model Benches

Every world prop of a bound model becomes a bench of that type, with no coordinates to place.

shared/config.lua
1Config.ModelBenches = {
2    Enabled = true,
3    RequireVerification = false,
4    CleanupDays = 30,
5    Bindings = {
6    },
7}
  • Enabled: turns model benches on
  • RequireVerification: registers a prop only when Handlers.VerifyWorldBench confirms it. false accepts any bound prop a player uses
  • CleanupDays: days without use before a model bench forgets its fuel, durability and queue. false keeps them
  • Bindings: model is the prop, benchType the bench type name or ID from the panel, stationModel an optional preset from config_models.lua for the screen and camera. The list ships empty, for example { model = 'prop_tool_bench02', benchType = 'Weapons Bench' }

Admin

shared/config.lua
1Config.Admin = {
2    Permission = 'admin',
3    AcePermission = nil,
4    FullAccess = true,
5    MinimizeKey = 'F9',
6}
  • Permission: framework group needed for the admin panel
  • AcePermission: set an ACE permission, such as 'mlcraft.admin', to check it instead of the group
  • FullAccess: admins can use every bench and recipe
  • MinimizeKey: hides and restores the admin panel. F1 to F12, or a single letter or digit

Screen, Camera and Light

shared/config.lua
1Config.DUI = {
2    Range = 8.0,
3    MaxActive = 8,
4}
5
6Config.Camera = {
7    OffsetX = 0.0,
8    OffsetY = -1.10,
9    OffsetZ = 0.65,
10    LookZ = -1.05,
11    Fov = 58.0,
12    TransitionMs = 500,
13}
14
15Config.WorkLight = {
16    Color     = { r = 255, g = 240, b = 220 },
17    Height    = 2.0,
18    Range     = 7.0,
19    Intensity = 3.0,
20}
  • DUI.Range: meters at which a bench screen turns on and off
  • DUI.MaxActive: screen browsers kept ready and reused. Each one holds memory, so raise it only if many benches stand close together
  • Camera: default camera when a player uses a bench: offsets from the bench, look pitch, field of view and transition time. Station presets and single benches can override it
  • WorkLight: color, height, falloff range and brightness of the spotlight above the bench

Live Craft Prop

A hologram of the result above the bench while crafting. It uses the prop set on the recipe, or the model of the first result item.

shared/config.lua
1Config.LiveCraftProp = {
2    Enabled         = true,
3    Alpha           = 150,
4    ResultAnchor = {
5        RightFraction = 0.33,
6        VertFraction  = -0.07,
7        Hover         = 0.14,
8    },
9    OffsetRight     = 0.16,
10    OffsetForward   = 0.46,
11    OffsetZ         = 0.18,
12    DefaultRotX     = 0.0,
13    DefaultRotY     = 0.0,
14    DefaultRotZ     = 0.0,
15    Spin            = 25.0,
16    DefaultScale    = 1.0,
17    AutoFit          = true,
18    AutoFitMode      = 'both',
19    AutoFitThreshold = 0.30,
20    AutoFitTarget    = 0.22,
21    AutoFitMinScale  = 0.10,
22    AutoFitPushPerM  = 0.35,
23    AutoFitGroundZ   = 0.0,
24}
  • Alpha: transparency from 0 to 255. About 150 looks like a hologram
  • ResultAnchor: where the prop floats over the screen, next to the result image. Hover is the height above the screen
  • OffsetRight, OffsetForward, OffsetZ: position used when the bench has no screen prop. Each recipe can set its own prop_offset
  • DefaultRotX, DefaultRotY, DefaultRotZ: default rotation in degrees. Each recipe can set prop_rotation
  • Spin: degrees per second of spin. 0 turns it off
  • DefaultScale: starting scale of the 3D test in the recipe editor. A prop_scale on the recipe skips auto-fit
  • AutoFit, AutoFitMode: shrinks or pushes back large props so they fit. 'scale', 'push' or 'both'
  • AutoFitThreshold, AutoFitTarget, AutoFitMinScale, AutoFitPushPerM, AutoFitGroundZ: size that triggers auto-fit, size after shrinking, smallest scale, push per meter of leftover size, and height of the prop base

Fuel and Durability

Fuel and durability are optional per bench type and usually set in the admin panel, which wins over these defaults.

shared/config.lua
1Config.Fuel = {
2    mlFuel = {
3        enabled = false,
4        hintItems = {},
5        acceptedFuelTypes = {
6            'diesel',
7        },
8        typeLabels = {
9            ['fuel']        = 'Gasoline',
10            ['diesel']      = 'Diesel',
11            ['biofuel']     = 'Biofuel',
12            ['ethanol']     = 'Ethanol',
13            ['kerosene']    = 'Kerosene',
14            ['electricity'] = 'Electricity',
15        },
16        litersToSeconds = 60,
17    },
18}
19
20Config.Durability = {}

A bench type default can be added to either table by its ID:

shared/config.lua
1Config.Fuel['campfire'] = {
2    enabled = true,
3    max_fuel = 1800,
4    items = {
5        ['wood']     = { required = 1, amount = 300 },
6        ['charcoal'] = { required = 1, amount = 600 },
7    },
8}
9
10Config.Durability['campfire'] = {
11    enabled = true,
12    max_health = 72,
13    repair_items = {
14        ['steel'] = { required = 1, repair = 50 },
15        ['wood']  = { required = 3, repair = 25 },
16    },
17}
  • Config.Fuel['<bench_type>']: fuel for that bench type. max_fuel is the capacity in seconds, items lists each fuel item and the seconds it adds
  • mlFuel.enabled: accepts refillable jerrycans. Any item with metadata.fuelAmount and metadata.fuelType works. The item stays and only its fuel goes down
  • mlFuel.hintItems: container items listed on the bench even when empty, so players know what to refill
  • mlFuel.acceptedFuelTypes: fuel types the bench accepts. They must match the fuel types of ml_fuel
  • mlFuel.typeLabels: label of each fuel type
  • mlFuel.litersToSeconds: seconds of bench time per liter
  • max_health in Config.Durability: hours of crafting before the station stops working
  • repair_items: items that repair the station and the percentage each one restores

Each bench type also has a fuel mode in the panel: items only, jerrycans only, or both.

Base Building

These settings do nothing when Outpost (ml_base_building) is not running.

shared/config.lua
1Config.BaseBuilding = {
2    enabled = 'auto',
3    canPlaceOutsideBase = true,
4    permission = false,
5    blockDuringRaid = false,
6    whileLoading = 'deny',
7}
8
9Config.BaseMachines = {
10    Enabled = true,
11    Defaults = {
12        category     = 'production',
13        model        = 'xm3_prop_xm3_bench_04b',
14        stationModel = 'basemachine_toolbench',
15        tier         = 2,
16        life         = 6000.0,
17        bbox         = vec3(1.6, 0.8, 1.0),
18        cost         = { wood = 200, metal = 80 },
19        upkeep       = { wood = 5 },
20        useRange     = 3.0,
21        power = {
22            use            = 900,
23            priority       = 3,
24            offset         = vec3(0.0, 0.0, 1.1),
25            maxConnections = 4,
26        },
27    },
28}
  • enabled: 'auto' follows the base rules when the base resource runs. true does the same and warns once if it is missing. false turns it off
  • canPlaceOutsideBase: true allows portable stations anywhere except inside another player's base. false allows them only inside a base the player can build in
  • permission: false accepts any crew member in a base the player does not own. 'canBuild' also needs the build permission of the crew
  • blockDuringRaid: true blocks placing inside a base under raid
  • whileLoading: answer while bases are still loading after a restart. 'deny' makes the player retry, 'allow' lets the placement through
  • BaseMachines: bench types can be built as machines inside a base. The base owns the prop and the crafting script runs the machine. Defaults only fills in the fields a bench type leaves empty in the panel: build cost, upkeep, health, size, use range and power use

Station Models

shared/config_models.lua holds the model presets offered when creating a bench. Each preset sets a bench prop, the screen placement and an optional camera.

shared/config_models.lua
1Config.StationModels = {
2    ["woodbench"] = {
3        Title = 'Wood Bench',
4        SpawnMode = 'bench_screen',
5        Bench = {
6            Model = 'prop_tool_bench02_ld',
7        },
8        Screen = {
9            Texture = 'script_rt_sturm1',
10            Offset = vec3(0.12, 0.01, 0.959),
11            Rotation = vec3(0.0, 0.0, 88.8),
12            Scale = 0.8,
13        },
14        Camera = {
15            OffsetX = 0.0,
16            OffsetY = -0.31,
17            OffsetZ = 0.7,
18            AimMode = 'lookat',
19            LookAtX = -0.01,
20            LookAtY = 0.0,
21            LookAtZ = 0.0,
22            Fov = 78.0,
23        },
24    },
25}
  • SpawnMode: 'screen_only' is a floating screen with no bench, 'bench_only' draws the interface on a texture of the bench itself, 'bench_screen' is a bench with a screen above it
  • Bench.Model: any prop model
  • Screen.Texture: texture the interface replaces. 'script_rt_sturm1' on the shipped screen. For 'bench_only', a texture of the bench model
  • Screen.Offset, Rotation, Scale: screen placement on the bench
  • Camera: camera of this preset. nil uses Config.Camera

The screen prop ships with the resource. New presets can also be built in game with the model builder of the admin panel, which saves them in the database.

Battlepass

server/config_server.lua
1Config.Battlepass = { Enabled = true }
  • Enabled: with ml_battlepass running, finished crafts advance the battlepass objectives that ml_battlepass ties to the recipe. false turns it off. Without ml_battlepass this setting does nothing

Discord Webhooks

server/config_server.lua
1Config.Webhooks = {
2    crafting        = '',
3    craft_start     = '',
4    craft_complete  = '',
5    craft_failed    = '',
6    craft_refund    = '',
7    theft           = '',
8    exploit         = '',
9    admin_editor    = '',
10    admin_bench     = '',
11    admin_recipe    = '',
12    admin_blueprint = '',
13    admin_import    = '',
14}
  • crafting: fallback channel of the four craft logs below when their own webhook is empty
  • craft_start, craft_complete, craft_failed, craft_refund: craft start, completion, failure and ingredient refunds
  • theft: station thefts and queue steals
  • exploit: refused requests and distance violations. Denied admin actions go to the matching admin channel, or here when that one is empty
  • admin_editor, admin_bench, admin_recipe, admin_blueprint, admin_import: admin panel changes, with before and after values

Leave a webhook empty to skip that log. Craft logs fall back to crafting first.

Crafting Configuration, FiveM Docs | Micio Mods