Configuration

23 min readUpdated 2 weeks ago

Overview

  • shared/config.lua: all gameplay settings: fuel types, items, jerry cans, consumption, tank size, scavenging, siphoning, upgrades, conversions, electric vehicles, HUD
  • shared/config_server.lua: Discord webhooks
  • shared/config/minigames/*.lua: minigame provider files (ox_lib, MGC, PS-UI). Each self-skips when its resource is missing

Item names in the shipped config are working defaults. Rename them to match your inventory and keep the keys consistent across Config.FuelItems, Config.JerryCans and your inventory item registry.

General

shared/config.lua
1Config.Debug              = false
2Config.Locale             = 'en'
3Config.FuelMode           = 'auto'
4Config.DefaultFuelType    = 'fuel'
5Config.GlobalLootCooldown = 60
  • Debug: console debug output
  • Locale: language file loaded from the locales/ folder
  • FuelMode: 'auto' picks 'advanced' when the inventory supports metadata. 'advanced' uses refillable jerry cans tracked in item metadata. 'simple' uses one-use fuel items only
  • DefaultFuelType: fallback fuel type. Must be a key of Config.FuelTypes
  • GlobalLootCooldown: shared cooldown in seconds across siphoning, wreck scavenging and pump scavenging. Any consumed loot action starts it. 0 disables

Feature Toggles

shared/config.lua
1Config.Features = {
2    Consumption = true,
3    RealisticConsumption = true,
4    DynamicTankSize = true,
5    Siphoning = true,
6    WreckScavenging = true,
7    PumpScavenging = true,
8    TankUpgrades = true,
9    FuelConversion = true,
10    WeatherEffects = true,
11    FuelGaugeUI = true,
12    Electric = true,
13    Generators = true,
14}
  • Consumption: fuel drains while driving
  • RealisticConsumption: drain derived from handling data (mass, acceleration, drivetrain) instead of a flat rate
  • DynamicTankSize: tank capacity in liters calculated from vehicle mass and class
  • Siphoning: steal fuel from parked vehicles into a jerry can
  • WreckScavenging: search wreck props for leftover fuel
  • PumpScavenging: extract fuel from abandoned gas station pumps
  • TankUpgrades: install capacity upgrades, persisted per plate
  • FuelConversion: convert a vehicle to another fuel type with a kit, persisted per plate
  • WeatherEffects: weather multiplies consumption
  • FuelGaugeUI: fuel gauge HUD while driving
  • Electric: charging stations and power cells
  • Generators: refuel base building generators from jerry cans

Permissions

shared/config.lua
1Config.Permissions = {
2    useFrameworkAdmin = true,
3    aces = { 'group.admin', 'group.superadmin', 'command', 'admin', 'god', 'superadmin' },
4}
  • useFrameworkAdmin: accepts the admin check of your framework
  • aces: ACE permissions that also count as admin

These gate /mlfuel, /showpumps, /mlwreckreset and the debug menu.

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. nil follows the shared theme set in ml_bridge
  • colors: CSS hex values for single colors. Any nil value follows the shared theme

Interaction

shared/config.lua
1Config.Interaction = {
2    mode = 'target',
3    key = 'E',
4    inspectOption = true,
5    inspectRequiredItem = nil,
6    inspectJobs = {},
7    inspectRequireUnlocked = false,
8}
  • mode: 'hybrid' (target + textui + item use), 'target' (ox_target + item use), 'textui' (text prompt + keybind + item use), 'item' (inventory item use only)
  • key: default key for the textui interaction. Registered as the ml_fuel_interact key mapping, so players can rebind it in the GTA keybind settings
  • inspectOption: adds a Check Fuel System target option on every vehicle
  • inspectRequiredItem: item, or list of items, needed to see that option. nil needs none
  • inspectJobs: jobs or gangs that see the option. Empty means everyone
  • inspectRequireUnlocked: the vehicle must be unlocked to inspect it
Inventory item use

Registered jerry cans and fuel items can open the refuel flow from the inventory in each interaction mode. An item with skipUseItem enabled needs the use handler from the resource that owns it, or the vehicle target.

Fuel Types

shared/config.lua
1Config.FuelTypes = {
2    ['fuel'] = {
3        label = 'Gasoline',
4        color = '#2ecc71',
5        consumptionRate = 1.0,
6    },
7    ['diesel'] = {
8        label = 'Diesel',
9        color = '#f1c40f',
10        consumptionRate = 0.85,
11    },
12    ['kerosene'] = {
13        label = 'Kerosene',
14        color = '#90CAF9',
15        consumptionRate = 0.9,
16    },
17    ['electricity'] = {
18        label = 'Electricity',
19        color = '#00E5FF',
20        consumptionRate = 0.7,
21    },
22}

The file also has biofuel and ethanol, commented out. Uncomment them to use them.

  • key: fuel type id. Stored on the vehicle state and inside jerry can metadata
  • label: display name used in the HUD, notifications and item tooltips
  • color: hex color in the HUD and Transfer UI
  • consumptionRate: drain multiplier for vehicles running this fuel

Fuel Type per Vehicle

shared/config.lua
1Config.VehicleCategories = {
2    [0]  = 'fuel',   -- Compacts
3    [1]  = 'fuel',   -- Sedans
4    [7]  = 'diesel', -- Super
5    [10] = 'diesel', -- Industrial
6    [12] = 'diesel', -- Vans
7    [14] = 'diesel', -- Boats
8    [15] = 'kerosene', -- Helicopters
9    [16] = 'kerosene', -- Planes
10    [19] = 'diesel', -- Military
11    [20] = 'diesel', -- Commercial
12    -- one entry per GTA vehicle class index (0-21)
13}
14
15Config.VehicleOverrides = {
16    [`wapoc3`] = 'diesel',
17    -- [`insurgent`] = 'diesel',
18}
  • VehicleCategories: fuel type per GTA vehicle class index. Used when a vehicle has no override
  • VehicleOverrides: force a fuel type for specific models. Keys are model hashes (backtick syntax)

Fuel Items (Simple Consumables)

One-use containers. The item is removed on use and its liters go into the tank.

shared/config.lua
1Config.FuelItems = {
2    ['fuel_liter'] = {
3        fuelType = 'fuel',
4        liters = 1.0,
5        label = 'Gasoline (1L)',
6        propKey = 'bottle',
7    },
8    ['fuel_canister'] = {
9        fuelType = 'fuel',
10        liters = 5.0,
11        label = 'Gasoline Canister (5L)',
12        propKey = 'jerrycan',
13    },
14    ['diesel_liter']    = { fuelType = 'diesel', liters = 1.0, label = 'Diesel (1L)', propKey = 'bottle' },
15    ['diesel_canister'] = { fuelType = 'diesel', liters = 5.0, label = 'Diesel Canister (5L)', propKey = 'jerrycan' },
16    ['kerosene_can']    = { fuelType = 'kerosene', liters = 5.0, label = 'Kerosene Can (5L)', propKey = 'jerrycan' },
17    ['fuel_sample']     = { fuelType = 'fuel', liters = 0.5, label = 'Fuel Sample (0.5L)', propKey = 'bottle' },
18}
  • fuelType: must match a key in Config.FuelTypes. The vehicle must run the same type
  • liters: liters added when the item is consumed
  • label: display name in menus and notifications
  • propKey: optional. References Config.Props to override the in-hand prop during the refuel animation
  • skipUseItem: optional, default false. Set true when another resource registers the same item name; ml_fuel then skips its use-item hook and the item still works through the vehicle target

Jerry Cans (Advanced Mode)

Refillable containers. Fuel amount and type live in item metadata; the item itself is never consumed. Requires FuelMode = 'advanced' and a metadata-capable inventory.

shared/config.lua
1Config.JerryCans = {
2    ['jerrycan_empty'] = {
3        skipUseItem = true,
4        label = 'Jerry Can',
5        capacity = 25,
6        acceptsFuel = { 'fuel', 'diesel' },
7        propKey = 'prop_jerrycan_01a',
8    },
9    ['plastic_bottle_empty'] = {
10        skipUseItem = true,
11        label = 'Plastic Bottle',
12        capacity = 0.5,
13        acceptsFuel = { 'fuel', 'diesel' },
14    },
15    -- ['fuel_barrel'] = { label = 'Fuel Barrel', capacity = 200, acceptsFuel = { 'fuel', 'diesel' } },
16}
  • capacity: maximum liters the container holds. Written to the maxCapacity metadata key
  • acceptsFuel: fuel types the container accepts. A can holding one type refuses a different one until emptied
  • label: display name in the Transfer UI and notifications
  • propKey: optional in-hand prop override for the pour/hold/siphon animations
  • skipUseItem: optional. Skip the use-item registration when another resource owns the same item name (the vehicle target still works)

Consumption

shared/config.lua
1Config.Consumption = {
2    tickInterval = 1000,
3    baseRate = 0.02,
4    damageMultiplier = 2.0,
5    tankHealthThreshold = 700,
6    replicationInterval = 15,
7    globalMultiplier = 4.0,
8    onlyWhenEngineRunning = true,
9    excludedClasses = { 13 },
10    exemptModels = {},
11    exemptJobs = {},
12    jobMultipliers = {},
13    engineControl = 'own',
14
15    outOfFuel = {
16        killEngine = true,
17        blockRestart = true,
18        notifyPlayer = true,
19        stutterBelowPercent = 5.0,
20        stutterChance = 10,
21        stutterDurationMs = 250,
22    },
23
24    idleDrain = {
25        enabled = true,
26        tickInterval = 10000,
27        ratePercent = 0.05,
28    },
29}
  • tickInterval: ms between drain ticks while driving
  • baseRate: percent drained per tick when RealisticConsumption is disabled
  • damageMultiplier: drain multiplier when the petrol tank is damaged
  • tankHealthThreshold: petrol tank health below this value counts as damaged (leak)
  • replicationInterval: fuel is replicated to other clients every N ticks; between replications the level is local to the driver
  • globalMultiplier: scales all drain. 1.0 = realistic, higher = faster economy
  • onlyWhenEngineRunning: drain only while the engine runs. Keep true
  • excludedClasses: vehicle classes that never use fuel. 13 is cycles
  • exemptModels: models that never use fuel, such as { police, ambulance }
  • exemptJobs: jobs whose members never use fuel while driving
  • jobMultipliers: consumption multiplier per job, such as { mechanic = 0.5, trucker = 1.5 }
  • engineControl: 'own' turns the engine off here at 0 fuel. 'event' only fires ml_fuel:client:outOfFuel so another script can handle it
  • outOfFuel: what happens on an empty tank. killEngine stops the engine, blockRestart keeps it off, notifyPlayer shows the message, and below stutterBelowPercent the engine sputters with stutterChance percent per tick for stutterDurationMs
  • idleDrain: server-side drain for vehicles left running with no driver: ratePercent of the tank every tickInterval ms. The engine shuts off at 0

Realistic Consumption

Used when Config.Features.RealisticConsumption = true. Drain is computed per tick from class base consumption, distance, speed band, handling data, engine state and environment.

shared/config.lua
1Config.RealisticConsumption = {
2    baseLitersPerKm = 1.2,
3    handlingFactors = {
4        massWeight = 0.6,
5        accelerationWeight = 0.5,
6        maxSpeedWeight = 0.2,
7        drivetrainWeight = 0.1,
8    },
9    drivetrainMultipliers = { FWD = 0.9, RWD = 1.0, AWD = 1.25 },
10    speedModifiers  = { idle = 0.2, city = 1.0, highway = 0.8, racing = 1.5 },
11    speedThresholds = { idle = 5, city = 60, highway = 120, racing = 150 },
12    engineStateModifiers = { accelerating = 1.3, braking = 0.5, coasting = 0.3, reversing = 1.2 },
13    environmentModifiers = { offroad = 1.4, water = 1.8, incline = 1.2 },
14    classBaseConsumption = {
15        [0]  = 0.05, -- Compacts
16        [6]  = 0.15, -- Sports
17        [7]  = 0.20, -- Super
18        [8]  = 0.04, -- Motorcycles
19        [10] = 0.25, -- Industrial
20        [15] = 0.50, -- Helicopters
21        [16] = 0.80, -- Planes
22        -- one entry per GTA vehicle class index (0-21)
23    },
24}
  • baseLitersPerKm: global base before modifiers
  • handlingFactors: weights for mass, acceleration, top speed and drivetrain read from the vehicle handling file
  • drivetrainMultipliers: multiplier by drive layout
  • speedModifiers / speedThresholds: consumption band by current speed (km/h)
  • engineStateModifiers: accelerating burns more, coasting burns less
  • environmentModifiers: extra cost offroad, in water, on an incline
  • classBaseConsumption: liters-per-km base by vehicle class

Tank Size

shared/config.lua
1Config.TankSize = {
2    defaultTankLiters = 60.0,
3    classMultipliers = {
4        [0]  = 0.7, -- Compacts
5        [8]  = 0.6, -- Motorcycles
6        [12] = 2.0, -- Vans
7        [15] = 2.5, -- Helicopters
8        [16] = 5.0, -- Planes
9        [19] = 3.0, -- Military
10        -- one entry per GTA vehicle class index (0-21)
11    },
12    overrides = {
13        [`zentorno`]  = 75.0,
14        [`insurgent`] = 200.0,
15    },
16    handlingBasedCalculation = {
17        enabled = true,
18        massMultiplier = 0.04,
19        minTankLiters = 25.0,
20        maxTankLiters = 600.0,
21    },
22}
  • defaultTankLiters: base tank when mass-based calculation is disabled
  • classMultipliers: scales the tank by vehicle class
  • overrides: exact tank size in liters for specific models
  • handlingBasedCalculation: when enabled, tank = vehicle mass × massMultiplier × class multiplier, clamped between minTankLiters and maxTankLiters

Refuel

shared/config.lua
1Config.Refuel = {
2    maxDistance = 3.0,
3    fuelCapBones = { 'petrolcap', 'petroltank', 'petroltank_l', 'hub_lr', 'engine' },
4    animation = { dict = 'weapon@w_sp_jerrycan', clip = 'fire' },
5    fullThreshold = 99.5,
6    requireUnlocked = true,
7    minDuration = 2000,
8    maxDuration = 30000,
9    itemUseDuration = 2000,
10}
  • fullThreshold: tank percentage that counts as full
  • requireUnlocked: the vehicle must be unlocked to refuel it
  • minDuration, maxDuration: shortest and longest refuel progress bar in ms
  • itemUseDuration: progress bar of a single-use fuel item in ms
  • maxDistance: max distance from the vehicle to refuel
  • fuelCapBones: bones probed to locate the fuel cap. Falls back to the entity position when none exist
  • animation: refuel animation dictionary and clip

Tank Upgrades

shared/config.lua
1Config.TankUpgrades = {
2    ['tank_expansion_small'] = {
3        label = 'Small Tank Expansion',
4        bonusLiters = 15.0,
5        maxStacks = 2,
6        duration = 20000,
7        requiredTool = 'siphon_hose',
8        animation = { dict = 'mini@repair', clip = 'fixing_a_ped' },
9    },
10    ['tank_expansion_medium'] = {
11        label = 'Medium Tank Expansion',
12        bonusLiters = 30.0,
13        maxStacks = 2,
14        duration = 35000,
15        requiredTool = 'siphon_hose',
16        animation = { dict = 'mini@repair', clip = 'fixing_a_ped' },
17    },
18    ['tank_expansion_large'] = {
19        label = 'Large Tank Expansion',
20        bonusLiters = 100.0,
21        maxStacks = 1,
22        duration = 50000,
23        requiredTool = 'siphon_hose',
24        vehicleClasses = { 7, 10, 12, 19, 20 },
25        animation = { dict = 'mini@repair', clip = 'fixing_a_ped' },
26    },
27}
  • key: the upgrade item name. The item is consumed on install
  • bonusLiters: liters added to the tank. Persisted per plate in the database
  • maxStacks: how many of this upgrade a single vehicle can hold
  • duration: install time in ms
  • requiredTool: item the player must carry (not consumed)
  • vehicleClasses: optional. Restrict the upgrade to these class indexes

Fuel Conversion

shared/config.lua
1Config.ConversionKits = {
2    ['diesel_conversion_kit'] = {
3        targetFuel = 'diesel',
4        duration = 30000,
5        animation = { dict = 'mini@repair', clip = 'fixing_a_ped' },
6    },
7}
  • targetFuel: fuel type the vehicle runs after conversion. Must exist in Config.FuelTypes to be usable

The file also has biofuel and ethanol kits, commented out. Uncomment them together with the matching Config.FuelTypes entry.

  • duration: conversion time in ms. The kit is consumed

Conversions are stored per plate in ml_fuel_conversions and reapplied when the vehicle spawns. Electric vehicles cannot be converted.

Siphoning

shared/config.lua
1Config.Siphoning = {
2    requiredItem = 'siphon_hose',
3    degradeItem = true,
4    degradeAmount = 5,
5
6    minigame = {
7        enabled = true,
8        minigame = nil,
9        difficulty = 'medium',
10        onFail = {
11            notifyPlayer = true,
12            alertDispatch = false,
13            dispatch = {
14                jobs = { 'police' },
15                code = '10-31',
16                messageKey = 'dispatch_siphon',
17                descriptionKey = 'dispatch_siphon_desc',
18                blip = { sprite = 361, scale = 1.0, color = 1, flash = true },
19            },
20        },
21    },
22
23    maxSiphonPercent = 50,
24    maxLitersPerAttempt = 20,
25    siphonRate = 3.0,
26    duration = 30000,
27    cooldownSeconds = 60,
28    perPlayerCooldown = 90,
29    claimTimeoutMs = 90000,
30    minVehicleFuelPercent = 5,
31    requireUnlocked = true,
32    alertOwner = false,
33    blockOwnedVehicles = false,
34
35    animation = {
36        dict = 'timetable@gardener@filling_can',
37        clip = 'gar_ig_5_filling_can',
38        flags = 49,
39        propKey = nil,
40    },
41
42    protectedVehicles = {
43        models = { `whelix`, `whelix1`, `whelix2` },
44        plates = {},
45    },
46}
  • requiredItem: tool the player must carry (siphon hose)
  • degradeItem / degradeAmount: durability lost by the hose per siphon
  • maxSiphonPercent: at most this percent of the fuel currently in the tank can be drawn per attempt
  • maxLitersPerAttempt: hard liter cap per attempt
  • cooldownSeconds: per-vehicle cooldown between siphons
  • perPlayerCooldown: per-player cooldown across all vehicles
  • siphonRate: liters per second while the player holds the extract button
  • claimTimeoutMs: a vehicle being siphoned is released after this many ms if the player disconnects
  • minVehicleFuelPercent: the vehicle must have at least this much fuel to be offered
  • requireUnlocked: the vehicle must be unlocked
  • alertOwner: notifies the owner of a player-owned vehicle after a siphon
  • blockOwnedVehicles: block siphoning from player-owned vehicles (read from the owned vehicles table)
  • protectedVehicles: model hashes and plates that can never be siphoned
Occupied vehicles

Siphoning a vehicle with someone inside is always blocked. Only one player can siphon a given vehicle at a time.

Vehicle Wrecks

shared/config.lua
1Config.VehicleWrecks = {
2    enabled = true,
3    requiredItem = 'siphon_hose',
4    cooldownMinutes = 30,
5    maxDistance = 2.0,
6
7    findChance = 65,
8    minLiters = 0.5,
9    maxLiters = 5.0,
10
11    fuelTypeWeights = {
12        fuel = 70,
13        diesel = 30,
14    },
15
16    minigame = { enabled = true, difficulty = 'medium', --[[ same shape as Siphoning.minigame ]] },
17
18    animation = {
19        dict = 'timetable@gardener@filling_can',
20        clip = 'gar_ig_5_filling_can',
21        flags = 49,
22        duration = 8000,
23        propKey = 'prop_jerrycan_01a',
24    },
25
26    props = {
27        [`prop_rub_carwreck_13`] = { multiplier = 1.0 },
28        [`prop_rub_buswreck`] = {
29            multiplier = 1.5,
30            fuelType = 'diesel',
31            maxLiters = 10.0,
32        },
33        -- 25 vanilla wreck props ship enabled; add your MLO/addon wreck props here
34    },
35}
  • cooldownMinutes: per-wreck cooldown shared by all players. Resets on server restart
  • findChance / minLiters / maxLiters: global roll, overridable per prop
  • fuelTypeWeights: probability per fuel type, must sum to 100
  • props: wreck models that can be searched. Per-prop keys: multiplier, fuelType, minLiters, maxLiters, findChance

Pump Scavenging

shared/config.lua
1Config.PumpScavenging = {
2    requiredItem = 'electric_pump',
3
4    models = {
5        `prop_gas_pump_old2`, `prop_gas_pump_1a`, `prop_vintage_pump`,
6        `prop_gas_pump_old3`, `prop_gas_pump_1c`, `prop_gas_pump_1b`,
7        `prop_gas_pump_1d`,
8    },
9
10    interactionDistance = 2.0,
11    perPlayerCooldown = 120,
12    duration = 8000,
13    failChance = 20,
14
15    minigame = { enabled = true, difficulty = 'easy', --[[ same shape as Siphoning.minigame ]] },
16
17    -- Advanced mode: fuel goes into jerry can metadata via the Transfer UI
18    fuel = {
19        findChance = 75,
20        minLiters = 2.0,
21        maxLiters = 20.0,
22        availableFuelTypes = { 'fuel', 'diesel' },
23    },
24
25    -- Simple mode: give items directly (no metadata)
26    rewards = {
27        { item = 'plastic_bottle_empty', min = 7, max = 10, chance = 80 },
28        { item = 'jerrycan_empty',       min = 1, max = 2,  chance = 20 },
29    },
30
31    availability = {
32        enabled = true,
33        minActiveStations = 10,
34        maxActiveStations = 18,
35        refreshMinMinutes = 15,
36        refreshMaxMinutes = 30,
37    },
38
39    stationLockTimeoutMs = 12000,
40
41    staffCommand = {
42        command = 'showpumps',
43        blipDuration = 30,
44        blipSprite = 361,
45        blipColor = 2,
46    },
47
48    zoneRadius = 30.0,
49    locations = {
50        vec3(49.4187, 2778.793, 58.043),
51        vec3(263.894, 2606.463, 44.983),
52        -- 27 gas station coordinates ship by default
53    },
54}
  • requiredItem: tool needed to work a pump (electric pump)
  • models: pump prop models detected inside station zones
  • perPlayerCooldown: seconds after a successful scavenge before the same player can scavenge any station
  • fuel: advanced mode yield: chance, liter range, and the fuel types a pump can produce (picked at random per scavenge)
  • rewards: simple mode yield: physical items with quantity ranges and chances
  • failChance: percent chance an attempt yields nothing (both modes)
  • availability: station rotation. A random subset of stations is active with a random number of charges; each successful scavenge consumes one charge; depleted stations stay empty until the next rotation. Disable to keep every station always active
  • reservoir: every station has its own tank, saved in ml_fuel_reservoirs. capacityLitres is the most it holds, refillLitresPerHour what it regains per real hour, initialFillPercent how full it is the first time it is seen, minDrawLitres the level below which it counts as dry, and offlineRefill counts server downtime toward the refill
  • stationLockTimeoutMs: a station is locked while someone scavenges it; the lock auto-releases after this many ms if the player disconnects
  • staffCommand: admin command name and blip settings for showing active stations
  • zoneRadius / locations: detection zones built around each gas station coordinate

Minigames

Pump scavenging, wreck scavenging and siphoning can each require a minigame. The built-in mlfuel_flow minigame takes its timings from Config.Minigames:

shared/config.lua
1Config.Minigames = {
2    difficultySettings = {
3        easy = { timeLimit = 15, complexity = 3 },
4        medium = { timeLimit = 12, complexity = 4 },
5        hard = { timeLimit = 10, complexity = 5 },
6        extreme = { timeLimit = 8, complexity = 6 },
7    },
8}
  • timeLimit: seconds to finish
  • complexity: from 2 to 6

Every feature carries the same minigame block:

shared/config.lua
1minigame = {
2    enabled    = true,
3    minigame   = nil,      -- explicit ID from Config.AvailableMiniGames, nil = use difficulty
4    difficulty = 'medium', -- 'easy' | 'medium' | 'hard' | 'extreme'
5    onFail = {
6        notifyPlayer  = true,
7        alertDispatch = false,
8        dispatch = {
9            jobs = { 'police' },
10            code = '10-31',
11            messageKey = 'dispatch_siphon',
12            descriptionKey = 'dispatch_siphon_desc',
13            blip = { sprite = 361, scale = 1.0, color = 1, flash = true },
14        },
15    },
16}
  • minigame: pin one specific minigame ID. When nil, the ID is resolved from difficulty through Config.DefaultMinigameByDifficulty
  • onFail.notifyPlayer: show the failure notification
  • onFail.alertDispatch: send a dispatch alert to the configured jobs with the given code and blip
shared/config.lua
1Config.DefaultMinigameByDifficulty = {
2    easy    = 'ox_skillcheck_easy',
3    medium  = 'ox_skillcheck_medium',
4    hard    = 'ox_skillcheck_hard',
5    extreme = 'ox_skillcheck_hard_wasd',
6}

Available IDs are registered by the provider files in shared/config/minigames/. The ox_lib provider always registers ox_skillcheck_easy, ox_skillcheck_medium, ox_skillcheck_hard, ox_skillcheck_hard_wasd and ox_skillcheck_easy_medium. The MGC and PS-UI providers register their own IDs only when those resources are running. Open the provider files for the full list.

Fuel Gauge HUD

shared/config.lua
1Config.UI = {
2    theme = 'default',
3    showFuelType = true,
4    showPercentage = true,
5    showLiters = true,
6    gaugeStyle = 'minimal',
7    lowFuelWarning = 15,
8    gaugePosition = 'bottom-right',
9    gaugeOffsetX = 0,
10    gaugeOffsetY = 0,
11    gaugeScale = 1.0,
12}
  • theme: theme of the gauge and panels. 'default', 'wasteland', 'cyberpunk', 'noir' or 'fantasy'
  • showFuelType, showPercentage, showLiters: what the gauge shows
  • gaugeStyle: 'minimal', 'survival' or 'modern'
  • lowFuelWarning: the gauge turns red below this percentage
  • gaugePosition: 'bottom-right', 'bottom-left', 'top-right' or 'top-left'
  • gaugeOffsetX, gaugeOffsetY: nudge in vw and vh
  • gaugeScale: size, 1.0 is the default

The gauge shows while driving when Config.Features.FuelGaugeUI is on.

Transfer UI

shared/config.lua
1Config.TransferUI = {
2    enabled = true,
3    maxFlowRate = 0.8,
4    easingTime = 1.0,
5    tickRate = 50,
6
7    sounds = {
8        enabled = true,
9        pourStart = { name = 'NAV_UP_DOWN', set = 'HUD_FRONTEND_DEFAULT_SOUNDSET' },
10        pourStop  = { name = 'BACK', set = 'HUD_FRONTEND_DEFAULT_SOUNDSET' },
11        complete  = { name = 'WEAPON_PURCHASE', set = 'HUD_AMMO_SHOP_SOUNDSET' },
12    },
13}
  • maxFlowRate: liters per second at full flow while holding to pour or siphon
  • easingTime: seconds for the flow to ramp up to full speed
  • sounds: GTA frontend sound and sound set per phase. Set enabled = false to mute

Props and Animations

shared/config.lua
1Config.Props = {
2    jerrycan = {
3        model = 'prop_jerrycan_01',
4        bone = 57005,
5        pos = vec3(0.11, 0.03, 0.05),
6        rot = vec3(0.0, -90.0, 0.0),
7    },
8}
9
10Config.Animations = {
11    holdJerryCan      = { dict = 'weapon@w_sp_jerrycan', clip = 'idle', flags = 49, propKey = 'jerrycan' },
12    pourIntoVehicle   = { dict = 'weapon@w_sp_jerrycan', clip = 'fire', flags = 49, propKey = 'jerrycan' },
13    siphonFromVehicle = { dict = 'anim@amb@clubhouse@tutorial@bkr_tut_ig3@', clip = 'machinic_loop_mechandplayer', flags = 49, propKey = nil },
14    useFuelBottle     = { dict = 'weapon@w_sp_jerrycan', clip = 'fire', flags = 49, propKey = 'bottle' },
15}
  • Props: reusable in-hand prop presets attached to the right hand (bone 57005). Items and animation presets reference them via propKey
  • Animations: animation presets for holding, pouring, siphoning and one-shot bottle use. Flag 49 = loop + upper body + player control

Weather Effects

shared/config.lua
1Config.WeatherEffects = {
2    enabled = true,
3    modifiers = {
4        [`RAIN`] = 1.15,
5        [`THUNDER`] = 1.20,
6        [`SNOW`] = 1.25,
7        [`BLIZZARD`] = 1.30,
8        [`SNOWLIGHT`] = 1.15,
9        [`FOGGY`] = 1.05,
10        [`SMOG`] = 1.08,
11    },
12    default = 1.0,
13}
  • modifiers: consumption multiplier per weather type hash
  • default: multiplier for any weather not listed

No-Loot Zones

shared/config.lua
1Config.NoLootZones = {
2    enabled = true,
3    zones = {
4        {
5            type = 'sphere',
6            coords = vec3(2203.33, 3185.1, 49.01),
7            radius = 150.0,
8            blockWreckScavenge = true,
9            blockPumpScavenge = true,
10            blockSiphon = true,
11        },
12        -- { type = 'box', coords = vec3(100, 200, 30), size = vec3(50, 50, 10), rotation = 0, blockSiphon = true },
13    },
14}
  • zones: sphere or box areas where looting is blocked. Each zone picks which actions it blocks: blockWreckScavenge, blockPumpScavenge, blockSiphon

Electric Vehicles

shared/config.lua
1Config.ElectricVehicles = {
2    'voltic', 'voltic2', 'tezeract', 'cyclone', 'cyclone2',
3    'raiden', 'neon', 'imorgon', 'dilettante', 'dilettante2',
4    'surge', 'khamelion', 'caddy', 'caddy2', 'caddy3',
5    'airtug', 'rcbandito', 'omnisegt',
6}

A model on this list always counts as electric. Other models are checked with the native electric flag on the client.

Charging Stations

shared/config.lua
1Config.ChargingStations = {
2    enabled = true,
3    useModelTargets = false,
4    models = { `prop_electricbox_02a`, `prop_elecbox_16` },
5    maxDynamicStations = 128,
6    interactionDistance = 2.5,
7
8    canChargeVehicle = true,
9    canChargePowerCell = true,
10
11    storageEnabled = true,
12    maxCapacityKwh = 500.0,
13    rechargeRatePerMinute = 5.0,
14    initialFillPercent = 100,
15    offlineRecharge = true,
16
17    vehicleChargeRatePerSecond = 4.0,
18    cellChargeRatePerSecond = 2.0,
19    kwhPerVehiclePercent = 0.5,
20    kwhPerCellPercent = 0.3,
21
22    animation = {
23        dict = 'anim@heists@prison_heiststation@cop_reactions',
24        clip = 'cop_b_idle',
25    },
26
27    locations = {
28        -- { coords = vec3(x, y, z), heading = 0.0, storage = 500.0 },
29    },
30}
  • useModelTargets: true turns every world prop of models into a charging station, up to maxDynamicStations
  • locations: charging station spots. Empty by default, add coordinates or turn on useModelTargets
  • initialFillPercent: charge of a station the first time it is seen
  • offlineRecharge: counts server downtime toward the recharge
  • storageEnabled: stations hold a kWh reserve that depletes as players charge and refills at rechargeRatePerMinute
  • vehicleChargeRatePerSecond / cellChargeRatePerSecond: percent gained per second by vehicles and power cells
  • kwhPerVehiclePercent / kwhPerCellPercent: kWh drained from the station per percent charged

Power Cells

shared/config.lua
1Config.PowerCells = {
2    ['power_cell'] = {
3        label = 'Power Cell',
4        maxCapacity = 100,
5        chargePerPercent = 1.0,
6        weight = 3000,
7    },
8    ['power_cell_heavy'] = {
9        label = 'Heavy Power Cell',
10        maxCapacity = 200,
11        chargePerPercent = 1.0,
12        weight = 8000,
13    },
14    ['solar_cell'] = {
15        label = 'Solar Power Cell',
16        maxCapacity = 50,
17        chargePerPercent = 1.0,
18        weight = 2000,
19        rechargesFromSun = true,
20        solarRechargeRate = 0.5,
21    },
22}
  • maxCapacity: charge units the cell holds. The current charge lives in the item metadata
  • chargePerPercent: cell units spent per vehicle percent when used on an electric vehicle
  • rechargesFromSun / solarRechargeRate: solar cells recharge in daylight, solarRechargeRate kWh per tick
shared/config.lua
1Config.SolarCharging = {
2    enabled = true,
3    tickMinutes = 1,
4    dayStartHour = 6,
5    dayEndHour = 20,
6    requireOutdoors = true,
7    blockedWeather = { `RAIN`, `THUNDER`, `SNOW`, `BLIZZARD`, `FOGGY` },
8}
  • tickMinutes: real minutes between two recharge ticks
  • dayStartHour, dayEndHour: in-game hours of daylight charging
  • requireOutdoors: no charging inside interiors
  • blockedWeather: weather types that stop the charge

Generators

shared/config.lua
1Config.Generators = {
2    providers = { 'ml_base_building' },
3    maxDistance = 5.0,
4}
  • providers: base building resources whose generators can be refuelled. The first one running is used. Outpost (ml_base_building) works as shipped
  • maxDistance: highest distance in meters between the player and the generator

Rate Limits

Most actions have a per-player limit: at most max requests every interval milliseconds.

shared/config.lua
1Config.RateLimits = {
2    transfer        = { interval = 1000,  max = 5 },
3    siphon          = { interval = 10000, max = 1 },
4    siphonOpen      = { interval = 5000,  max = 3 },
5    wreckSearch     = { interval = 5000,  max = 1 },
6    minigameAttempt = { interval = 2000,  max = 1 },
7    pumpScavenge    = { interval = 3000,  max = 1 },
8    refuel          = { interval = 1000,  max = 4 },
9    fuelItem        = { interval = 1000,  max = 3 },
10    conversion      = { interval = 3000,  max = 1 },
11    upgrade         = { interval = 3000,  max = 1 },
12    charge          = { interval = 1000,  max = 5 },
13    chargeDiscover  = { interval = 10000, max = 2 },
14    generator       = { interval = 1000,  max = 3 },
15    emptyCan        = { interval = 2000,  max = 2 },
16}

Raise a value only if players hit the limit during normal play.

Discord Webhooks

shared/config_server.lua
1Config.Logger = 'discord'
2
3Config.Log = {
4    FuelActions    = '',
5    Conversions    = '',
6    PumpScavenging = '',
7    Exploits       = '',
8    JerryCanRefuel = '',
9    JerryCanSiphon = '',
10    TankUpgrades   = '',
11    WreckScavenge  = '',
12    AdminActions   = '',
13}
14
15Config.LogSettings = {
16    AuthorName = 'ML Fuel',
17    AuthorIcon = 'https://i.imgur.com/IG2pTbK.png',
18    Footer     = nil,
19}
  • Logger: log destination, 'discord', 'ox_lib', 'fivemanage', 'both' or 'all'
  • Log: one webhook URL per category: refuels, conversions, pump scavenges, exploit warnings, jerry can refuels and siphons, tank upgrades, wreck scavenges, admin actions
  • LogSettings: author name, icon and footer of the log embeds. Footer = nil uses the ML Bridge default

Leave a webhook empty, or set it to false, to disable that log. Admin permission is set in Config.Permissions.