Configuration

12 min readUpdated Today

Overview

  • shared/config.lua: Global behavior, language, theme, interaction ranges, features, progression, blueprints, portable stations, fuel and durability defaults
  • shared/config_models.lua: Station model presets, bench prop, screen texture placement, per-model camera
  • server/config_server.lua: Discord webhooks

Stations, recipes, categories, blueprints and custom station models are not defined in the config. They live in the database and are built from the in-game admin panel (/craftadmin). Where the same setting exists in both places, fuel, durability, pickup rules, queue limits, the value saved in the admin panel takes priority over the config default.

General

shared/config.lua
1Config.Debug = false
2Config.Language = 'en'
3Config.Theme = 'default'
4Config.MainColor = nil
5Config.Command = 'craftadmin'
  • Debug: Console output for troubleshooting, including the /craftpooldump diagnostic command
  • Language: Locale code, must match a file in locales/.
  • Theme: Interface theme: 'default', 'wasteland', 'cyberpunk', 'noir', 'fantasy'
  • MainColor: Hex accent color override. nil uses the theme default. Individual benches can override it again with a tint color from the admin panel
  • Command: Chat command that opens the admin editor

Interaction & Streaming

shared/config.lua
1Config.Interaction = {
2    TargetDistance = 2.5,
3    SpawnDistance = 80.0,
4    DuiActivation = 12.0,
5    MaxOperationRange = 5.0,
6}
7
8Config.Stream = {
9    Radius = 200.0,
10    OutRadius = 250.0,
11    ReloadDistance = 100.0,
12    PollMinInterval = 1500,
13    PollMaxInterval = 4000,
14}
  • TargetDistance: Range in meters to interact with a bench
  • SpawnDistance: Distance at which bench props spawn and despawn
  • DuiActivation: Distance at which the screen content starts rendering
  • MaxOperationRange: Server-side maximum distance for any crafting action. Requests from further away are rejected
  • Radius / OutRadius: Benches inside Radius enter the client cache, benches beyond OutRadius drop from it. Keep OutRadius larger than Radius
  • ReloadDistance: Meters of player movement before the client asks the server for benches again
  • PollMinInterval / PollMaxInterval: Position poll interval in ms, faster while moving, slower while standing still

Feature Toggles

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}
  • Spotlight: Light above the bench while a player uses it
  • PortableStations: Player-placeable benches via inventory item
  • Blueprints: Blueprint requirement system (item or permanent unlock)
  • QueuedCrafting: Timed crafting queue, start a craft, walk away, collect later
  • PropPreview: 3D preview of the result item floating above the bench while crafting
  • CraftAnimations: Player animation during the craft
  • DamageInterrupt: Taking damage interrupts the craft in progress
  • MultipleCrafters: Allow several players on the same bench at once. When false, a bench lock keeps it to one user at a time
  • Invincibility: Player cannot be damaged while crafting. Only applies when MultipleCrafters = false

Internal Progression

Used only when Config.ExternalSkills.Enabled = false. Levels and XP are stored 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}
  • GlobalXp: XP needed per level follows Base * (Scaling ^ (level - 1)). Scaling = 1.0 is linear, above 1.0 grows exponentially, capped at MaxLevel
  • CategoryXp: Same formula per recipe category, each category levels separately
  • Points: Points granted on level up

External Skills (ml_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: Delegate levels, skill checks and XP to ml_skills. Set false to use the internal progression above
  • Resource: Name of the external skills resource
  • Mapping.Category: Fixed ml_skills category for all crafting XP. Leave empty to auto-route by recipe category or by the recipe's required skill (recommended)
  • Mapping.XpMultiplier: Multiplier applied to recipe XP before it is sent to ml_skills
  • Mapping.PerCategory: Explicit map of ml_crafting category id to ml_skills category UID, for when the names differ

Recipe Display & Limits

shared/config.lua
1Config.Recipes = {
2    HideUnavailable = true,
3    HideMissingBlueprint = true,
4    ShowLockedPreview = false,
5    MaxQueueSize = 3,
6    MaxBatchSize = 0,
7}
  • HideUnavailable: Hide recipes the player cannot craft yet
  • HideMissingBlueprint: Hide recipes whose blueprint the player does not own
  • ShowLockedPreview: Show locked recipes as a preview without allowing the craft
  • MaxQueueSize: Maximum queued crafts per player across all benches. 0 = unlimited. Bench types can set their own queue limit in the admin panel
  • MaxBatchSize: Maximum quantity per single craft operation. 0 = unlimited

Crafting Queue

shared/config.lua
1Config.Queue = {
2    CleanupEnabled = true,
3    CleanupAfterDays = 7,
4    CleanupCheckInterval = 3600,
5    SharedView = true,
6    AllowSteal = true,
7}
  • CleanupEnabled / CleanupAfterDays: Uncollected ready crafts are removed after this many days
  • CleanupCheckInterval: Cleanup check interval in seconds
  • SharedView: Everyone at the bench sees everyone else's queue entries
  • AllowSteal: Players can collect other players' finished crafts. Every theft is logged through Bridge.Log

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 inventory item that carries metadata.blueprint = '<blueprint id>'. Works with metadata-capable inventories
  • DynamicPrefix: Alternative pattern, one dedicated item per blueprint, named blueprint_<label> (a custom item name can also be set per blueprint in the admin panel)
  • StrictMode: Every recipe requires a blueprint, even recipes without one assigned
  • ConsumeOnCraft: Remove the blueprint item after crafting
  • Durability.Enabled / DefaultUses: Give blueprints a number of uses instead of a single consume. Only active together with ConsumeOnCraft = true. Permanent unlocks always bypass consumption

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 placeable item. The bench type it deploys comes from metadata.stationType. Bench types can also bind their own dedicated item in the admin panel
  • MaxPerPlayer: Placed stations allowed per player
  • PlacementRange: Maximum placement distance from the player in meters
  • DefaultPickupRule: Who can pick a station up: 'owner', 'everyone', or a list of job names. Overridable per bench type in the admin panel
  • DefaultPickupTimeOwner / DefaultPickupTimeTheft: Seconds of progress bar to pick up your own station versus someone else's
  • TheftAnimation / TheftAnimationName: Animation played during a theft pickup
  • LogTheft: Send theft attempts to the webhook log
  • DeleteOld: Days without interaction before an abandoned station is deleted. false disables the cleanup
  • DeleteOptions: Extra conditions, keep the station if it still has an active queue, remaining fuel, or intact durability
  • RequireAnchor: When enabled, placement requires one of the listed prop models (signed int32 hashes) within Radius meters, for example, restrict stations to a base
  • PickupCooldown: Seconds after placement before pickup is allowed. 0 = disabled

Admin Permissions

shared/config.lua
1Config.Admin = {
2    Permission = 'admin',
3    AcePermission = nil,
4    FullAccess = true,
5}
  • Permission: Bridge.HasPermission group required for the admin panel and admin commands. Set it to the staff group name of your framework
  • AcePermission: When set (for example 'mlcraft.admin'), an ACE permission check is used instead of the framework group
  • FullAccess: Admins can use every bench and recipe regardless of restrictions

Screen & Camera

shared/config.lua
1Config.DUI = {
2    Range = 8.0,
3    MaxActive = 16,
4    Width = 1920,
5    Height = 1080,
6}
7
8Config.Camera = {
9    OffsetX = 0.0,
10    OffsetY = -1.10,
11    OffsetZ = 0.65,
12    LookZ = -1.05,
13    Fov = 58.0,
14    TransitionMs = 500,
15}
  • Range: Distance at which a bench screen turns on and off
  • MaxActive: Maximum bench screens rendering at the same time
  • Width / Height: Screen render resolution
  • Camera: Default focus camera when a player uses a bench, offsets relative to the bench, look pitch, field of view and transition time. Station model presets and individual benches can override it

Live Craft Prop

The hologram of the result item shown above the bench while crafting. Removed on completion or failure. Uses the recipe's prop model override, or the first result item's model as fallback.

shared/config.lua
1Config.LiveCraftProp = {
2    Enabled         = true,
3    Alpha           = 150,
4    OffsetRight     = 0.16,
5    OffsetForward   = 0.46,
6    OffsetZ         = 0.18,
7    DefaultRotX     = 0.0,
8    DefaultRotY     = 0.0,
9    DefaultRotZ     = 0.0,
10    Spin            = 25.0,
11    DefaultScale    = 1.0,
12    AutoFit          = true,
13    AutoFitMode      = 'both',
14    AutoFitThreshold = 0.30,
15    AutoFitTarget    = 0.22,
16    AutoFitMinScale  = 0.10,
17    AutoFitPushPerM  = 0.35,
18    AutoFitGroundZ   = 0.0,
19}
  • Alpha: Prop transparency, 0-255. Around 150 reads as a hologram
  • OffsetRight / OffsetForward / OffsetZ: Default position in the bench's local frame. Overridable per recipe (prop_offset)
  • DefaultRotX/Y/Z: Default rotation in degrees, overridable per recipe (prop_rotation)
  • Spin: Continuous yaw spin in degrees per second. 0 = off
  • DefaultScale: Starting scale. A per-recipe prop_scale overrides auto-fit entirely
  • AutoFit: Automatically shrink or push back oversized props (furniture, crates, heavy weapons) so they fit above the bench. AutoFitMode picks the strategy: 'scale', 'push' or 'both'
  • AutoFitThreshold / AutoFitTarget / AutoFitMinScale / AutoFitPushPerM / AutoFitGroundZ: Size above which auto-fit triggers, the target size after shrinking, the minimum allowed scale, how far residual oversize is pushed back, and the target height of the prop's base

Fuel

Fuel is optional and set per bench type. The usual place to configure it is the admin panel, whose values take priority. The config can seed defaults per bench type id:

shared/config.lua
1Config.Fuel = {
2    -- ['campfire'] = {
3    --     enabled = true,
4    --     max_fuel = 1800,
5    --     items = {
6    --         ['wood']     = { required = 1, amount = 300 },
7    --         ['charcoal'] = { required = 1, amount = 600 },
8    --     }
9    -- }
10
11    mlFuel = {
12        enabled = false,
13        hintItems = {},
14        acceptedFuelTypes = {
15            'diesel',
16        },
17        typeLabels = {
18            ['fuel']        = 'Gasoline',
19            ['diesel']      = 'Diesel',
20            ['biofuel']     = 'Biofuel',
21            ['ethanol']     = 'Ethanol',
22            ['kerosene']    = 'Kerosene',
23            ['electricity'] = 'Electricity',
24        },
25        litersToSeconds = 60,
26    },
27}
  • ['<bench_type>']: Consumable fuel for that bench type, max_fuel capacity in seconds and items mapping each fuel item to the seconds it adds
  • mlFuel.enabled: Accept refillable jerrycans. Any item with metadata.fuelAmount (liters) and metadata.fuelType is recognized; the item stays in the inventory and only its metadata is decremented
  • mlFuel.hintItems: Container items shown in the bench fuel list even when empty, so players know what to refill. Replace with your inventory's item names
  • mlFuel.acceptedFuelTypes: Fuel types the bench accepts. Must match Config.FuelTypes in ml_fuel
  • mlFuel.typeLabels: Display label per fuel type. A missing key falls back to the raw type name
  • mlFuel.litersToSeconds: Bench runtime seconds granted per liter

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

Durability

shared/config.lua
1Config.Durability = {
2    -- ['campfire'] = {
3    --     enabled = true,
4    --     max_health = 72,
5    --     repair_items = {
6    --         ['steel'] = { required = 1, repair = 50 },
7    --         ['wood']  = { required = 3, repair = 25 },
8    --     }
9    -- }
10}
  • max_health: Hours of active crafting before the station stops working
  • repair_items: Items accepted for repair and the percentage each restores

Like fuel, durability is normally configured per bench type in the admin panel, which overrides these defaults.

Station Models

shared/config_models.lua defines the model presets selectable when creating a bench. Each preset combines 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' (floating screen, no bench prop), 'bench_only' (interface drawn on the bench's own texture), 'bench_screen' (bench prop plus a screen above it)
  • Bench.Model: Any prop model name. This is configurable
  • Screen.Texture: Texture name on the prop that the interface replaces. For the shipped screen this is 'script_rt_sturm1'; for 'bench_only' presets, name a texture of the bench model itself
  • Screen.Offset / Rotation / Scale: Screen placement relative to the bench
  • Camera: Per-model camera. nil falls back to Config.Camera
Screen model

The screen prop itself is managed by the script and ships with the resource; a Screen.Model value set here is ignored. You control the bench prop, the texture, and the screen's offset, rotation and scale. New model presets can also be built entirely in-game with the admin panel's model builder, which saves them to the database.

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. Any action whose own webhook is empty logs here
  • craft_start / craft_complete / craft_failed / craft_refund: Craft lifecycle, failures and ingredient refunds
  • theft: Station theft and queue steals
  • exploit: Rejected requests, distance violations, token mismatches, denied admin actions
  • admin_editor / admin_bench / admin_recipe / admin_blueprint / admin_import: Admin panel activity with before/after diffs