Configuration

10 min readUpdated 2 weeks ago

Overview

  • shared/config.lua: Core settings, geiger items, battery, player effects, zones, vehicle/clothing protection, cure/immunity items
  • server/config_server.lua: Discord webhooks and admin permissions

Core Settings

shared/config.lua
1Config.Locale = 'en'
2Config.Movegeiger = 'movegeiger'
3Config.Debug = false
4Config.UseRealTime = false
5Config.ShowZoneNotifications = true
6Config.ZoneNotificationDuration = 15000
7Config.RequireGameplayReadyGate = false
8Config.HealthSystemIntegration = false
9Config.RealTerminalItem = true
  • Locale: language file to load from the locales/ folder
  • Movegeiger: Command to reposition the Geiger Counter HUD on screen
  • Debug: Enable debug prints in console
  • UseRealTime: Use real-world time instead of GTA game time on the Geiger display
  • ShowZoneNotifications: notifies the player on entering and leaving a radiation zone
  • ZoneNotificationDuration: how long the zone notification stays, in milliseconds
  • RequireGameplayReadyGate: pauses radiation during character selection and intro until your spawn resource sets the gameplayReady player state. Turn it on only if your spawn resource sets it
  • HealthSystemIntegration: with ml_healthsystem running, lets it take over the health loss and screen effects chosen in HealthSystemSettings. ml_healthsystem reads the radiation level on its own side through its radiation integration
shared/config.lua
1Config.HealthSystemSettings = {
2    disableDamage  = false,
3    disableVisuals = false,
4}
5
6Config.AdminExportResources = {
7    ml_radiation = true,
8    ml_healthsystem = true,
9    ml_staff = true,
10}
  • HealthSystemSettings: with the integration on, disableDamage = true lets ml_healthsystem apply the health loss and disableVisuals = true lets it drive the screen effects. With both false, as shipped, ML Radiation keeps them
  • AdminExportResources: resources allowed to call SetRadiation, AddRadiation and RemoveRadiation. Add your own staff resource here
  • RealTerminalItem: true uses the item list of Config.AdvancedItems, the shipped default. false uses the single item of Config.SimpleMode

Death and Respawn

shared/config.lua
1Config.OnDeath = {
2    StopEffects = true,     -- Freeze damage, contamination and visuals until the player is back up
3    ResetOnRespawn = false, -- Wipe contamination when the player gets back up
4}
  • StopEffects: While a player is down, contamination, damage, effects and sounds stop and the Geiger interface closes. Resumes on revive. Set false to keep it running on a downed player
  • ResetOnRespawn: Sets radiation to zero when the player gets back up. Default false keeps it across death, so it clears only with a cure item or the reset export
Downed states that keep the ped alive

Detection reads the framework death state. A downed state that leaves the ped alive is not seen as death. Handle those from your own script with the PauseRadiation and ResumeRadiation client exports.

Geiger Counter Items

Advanced Mode

When Config.RealTerminalItem = true, each item opens its own Geiger Counter model and theme:

shared/config.lua
1Config.AdvancedItems = {
2    { item = "geiger_modern_green",    model = "model-modern",   theme = "theme-green",  batteryMax = 100, batteryDrain = 0.5 },
3    { item = "geiger_modern_blue",     model = "model-modern",   theme = "theme-blue",   batteryMax = 100, batteryDrain = 0.5 },
4    { item = "geiger_modern_orange",   model = "model-modern",   theme = "theme-orange", batteryMax = 100, batteryDrain = 0.5 },
5    { item = "geiger_standard_green",  model = "model-standard", theme = "theme-green",  batteryMax = 100, batteryDrain = 0.5 },
6    { item = "geiger_standard_blue",   model = "model-standard", theme = "theme-blue",   batteryMax = 100, batteryDrain = 0.5 },
7    { item = "geiger_standard_orange", model = "model-standard", theme = "theme-orange", batteryMax = 100, batteryDrain = 0.5 },
8    { item = "geiger_retro_green",     model = "model-retro",    theme = "theme-green",  batteryMax = 120, batteryDrain = 0.8 },
9    { item = "geiger_retro_blue",      model = "model-retro",    theme = "theme-blue",   batteryMax = 120, batteryDrain = 0.8 },
10    { item = "geiger_retro_orange",    model = "model-retro",    theme = "theme-orange", batteryMax = 120, batteryDrain = 0.8 },
11    { item = "dgm_geiger",            model = "dgm_geiger",     theme = "theme-green",  batteryMax = 100, batteryDrain = 0.5 },
12    { item = "dgm_geiger_blue",       model = "dgm_geiger",     theme = "theme-blue",   batteryMax = 100, batteryDrain = 0.5 },
13    { item = "dgm_geiger_orange",     model = "dgm_geiger",     theme = "theme-orange", batteryMax = 100, batteryDrain = 0.5 },
14}
  • model: how the counter shows. 'model-modern', 'model-standard' and 'model-retro' are screen overlays. 'dgm_geiger' is a 3D device held by the player, see Display Modes
  • theme: Color theme. Options: 'theme-green', 'theme-blue', 'theme-orange'
  • batteryMax: battery capacity. The retro models ship with 120, the others with 100
  • batteryDrain: Battery units consumed per real-time minute while the Geiger is active

Simple Mode

When Config.RealTerminalItem = false, only a single item is used:

shared/config.lua
1Config.SimpleMode = {
2    item = "dgm_geiger",
3    model = "dgm_geiger",
4    theme = "theme-green",
5    batteryMax = 100,
6    batteryDrain = 0.5,
7}

Display Modes

The model field determines how the Geiger Counter is displayed:

  • Overlay (model-modern, model-standard, model-retro): the counter shows as a screen overlay you place with /movegeiger. No prop is created and the player moves freely
  • 3D device (dgm_geiger): the dgm_geiger model attaches to the player's chest and the interface draws live on its screen. The player plays a holding animation while it is open, and the prop is removed when it closes

Geiger UI

shared/config.lua
1Config.GeigerUI = {
2    ShowPlayerContaminationOnScreen = true,
3    StatusThresholds = {
4        Warning = 1.0,
5        Danger = 5.0,
6    },
7}
  • ShowPlayerContaminationOnScreen: Display the player's personal contamination level on the Geiger UI
  • StatusThresholds.Warning: Radiation level at which the UI shows a warning state
  • StatusThresholds.Danger: Radiation level at which the UI shows a danger state

Battery System

shared/config.lua
1Config.Battery = {
2    enabled = true,
3    drainPerMinute = 0.5,
4    lowThreshold = 20,
5    rechargeItem = 'battery',
6    rechargeAmount = 50,
7}
  • enabled: Enable/disable the battery system. When disabled, the Geiger runs indefinitely
  • drainPerMinute: Fallback drain rate (used when the item's batteryDrain is not set). Each item in Config.AdvancedItems can override this with its own batteryDrain
  • lowThreshold: battery units below which a low battery warning appears
  • rechargeItem: Inventory item consumed to recharge the battery
  • rechargeAmount: battery units restored per use, up to the item's batteryMax

The battery level is stored in the item metadata (meta.battery) and survives sessions. It drains once a minute while the counter is open and saves every 30 seconds. At 0 the counter closes with a notification. Players recharge it by using rechargeItem.

Player Effects

shared/config.lua
1Config.PlayerEffects = {
2    Enabled = true,
3    MaxRadiation = 1000.0,
4    IncreaseSpeed = 200,
5    AutoRemove = {
6        Enabled = true,
7        Rate = 1.0,
8        SafeThreshold = 150.0,
9        GracePeriod = 12000,
10    },
11    Damage = {
12        Enabled = true,
13        Interval = 5000,
14        Thresholds = {
15            { level = 500.0, damage = 1 },
16            { level = 700.0, damage = 2 },
17            { level = 850.0, damage = 4 },
18            { level = 950.0, damage = 8 },
19        },
20    },
21}
  • MaxRadiation: Maximum radiation a player can accumulate
  • IncreaseSpeed: Higher = slower accumulation (used as a divisor)
  • AutoRemove.Enabled: Radiation decreases naturally when outside zones, but only below SafeThreshold and after the GracePeriod elapses with no new exposure. Default true
  • AutoRemove.Rate: points removed every half second, 10 per 5-second server pass
  • AutoRemove.SafeThreshold: radiation decays only below this level
  • AutoRemove.GracePeriod: milliseconds without new exposure before decay starts
  • Damage.Enabled: Enable periodic health damage from radiation
  • Damage.Interval: Milliseconds between damage ticks
  • Damage.Thresholds: Damage applied at each radiation level. Checked highest-first.

Visual Effects

Screen effects intensify as radiation increases:

shared/config.lua
1Config.PlayerEffects.Visuals = {
2    Enabled = true,
3    Thresholds = {
4        { level = 5.0,   effect = "MP_Bull_tost",     force = 0.20 },
5        { level = 25.0,  effect = "MP_Bull_tost",     force = 0.50 },
6        { level = 75.0,  effect = "MP_Bull_tost",     force = 0.85 },
7        { level = 175.0, effect = "torpedo",          force = 0.55 },
8        { level = 350.0, effect = "torpedo",          force = 0.90 },
9        { level = 550.0, effect = "DRUG_gas_huffin",  force = 0.65 },
10        { level = 800.0, effect = "DRUG_gas_huffin",  force = 1.00 },
11    },
12}

Radiation Sounds

The Geiger Counter plays audio based on zone radiation level:

shared/config.lua
1Config.RadiationSounds = {
2    Enabled = true,
3    Thresholds = {
4        { level = 100.0, sound = 'rad_high',   volume = 0.4 },
5        { level = 20.0,  sound = 'rad_medium', volume = 0.3 },
6        { level = 1.0,   sound = 'rad_low',    volume = 0.2 },
7    },
8}

Vehicle Protection

shared/config.lua
1Config.VehicleProtection = {
2    Enabled = true,
3    DefaultMultiplier = 0.6,
4    ExcludedClasses = { [8] = true, [13] = true, [14] = true, [15] = true, [16] = false },
5    SpecificVehicles = {
6        ['insurgent'] = 0.1,
7        ['apc'] = 0.05,
8        ['zentorno'] = 0.5,
9    },
10}
  • DefaultMultiplier: share of radiation a player still receives inside a vehicle. The default 0.6 blocks 40%. Lower it for stronger shielding
  • ExcludedClasses: vehicle classes with no protection. The default excludes 8 (motorcycles), 13 (cycles), 14 (boats) and 15 (helicopters). 16 (planes) is false, so planes protect
  • SpecificVehicles: Override multiplier per vehicle model. 0.1 = 90% protection, 0.05 = 95% protection

Clothing Protection

shared/config.lua
1Config.ClothingProtection = {
2    Enabled = true,
3    RespectWear = true,
4    Suits = {
5        ['AntiRadSuit660'] = {
6            protection = 0.90,
7            male = { { component = 11, drawable = 660, texture = 0 } },
8        },
9        ['AntiRadMask244'] = {
10            protection = 0.60,
11            male = { { component = 1, drawable = 244, texture = 0 } },
12        },
13    },
14}
  • protection: Percentage of radiation blocked (0.70 = 70% protection)
  • male / female: Component/drawable/texture combinations that activate this suit. Add entries for both genders. RespectWear = true stops a worn-out suit/mask from protecting (ml_clothing wear). The default config ships AntiRad masks and suits already mapped

Cure Items

shared/config.lua
1Config.CureItems = {
2    Enabled = true,
3    Items = {
4        {
5            name = "radaway",
6            removeAmount = 550,
7            animation = {
8                duration = 5000,
9                label = 'Taking pills...',
10                dict = 'mp_player_intdrink',
11                clip = 'loop_bottle',
12                prop = {
13                    model = `prop_pill_container_01a`,
14                    bone = 60309,
15                    pos = vec3(0.1, -0.01, 0.0),
16                    rot = vec3(0.0, 0.0, -1.0),
17                },
18            },
19        },
20    },
21}
  • name: Inventory item name
  • removeAmount: Radiation points removed on use
  • animation: Optional animation with attached prop played during use

Immunity Items

shared/config.lua
1Config.ImmunityItems = {
2    Enabled = false,
3    Items = {
4        -- {
5        --     name = "iodine_pill",
6        --     protection = 1.0,
7        --     duration = 10,
8        --     animation = { ... },
9        -- },
10    },
11}
  • protection: Percentage of radiation blocked. 1.0 = 100% protection
  • duration: duration in minutes. The item is consumed on use

Immunity items ship turned off, with iodine_pill as a commented example. Set Enabled = true and add your entries.

Radiation Zones

Three zone shapes are supported. The file ships one sphere zone, and the box and poly entries below are commented examples.

Sphere Zone

shared/config.lua
1{
2    type = 'sphere',
3    coords = vector3(3540.7432, 3690.8889, 45.2284),
4    radius = 300.0,
5    maxRadiation = 1000.0,
6    dynamic = true,
7    force = 2.5,
8    debug = false,
9}

Box Zone

lua
1{
2    type = 'box',
3    coords = vec3(0.0, 0.0, 30.0),
4    size = vec3(4.0, 4.0, 10.0),
5    rotation = 45.0,
6    maxRadiation = 8.5,
7    dynamic = false,
8    force = 2.5,
9    debug = false,
10}

Poly Zone

lua
1{
2    type = 'poly',
3    points = {
4        vec3(0.0, 0.0, 0.0),
5        vec3(100.0, 0.0, 0.0),
6        vec3(100.0, 100.0, 0.0),
7        vec3(0.0, 100.0, 0.0),
8    },
9    thickness = 15.0,
10    maxRadiation = 50.0,
11    dynamic = true,
12    force = 1.0,
13    debug = false,
14}
  • type: Zone shape: 'sphere', 'box', or 'poly'
  • dynamic: true = radiation increases closer to center, false = flat radiation throughout
  • maxRadiation: Maximum radiation level inside the zone
  • force: falloff exponent of a dynamic zone. Higher values pack the radiation toward the center. A static zone ignores it
  • debug: Show zone wireframe in-game

Server Configuration

server/config_server.lua
1ServerConfig.DiscordWebhook = ''
2ServerConfig.AdminWebhook = ''
3ServerConfig.AdminPermissions = { 'command', 'admin', 'god' }
  • DiscordWebhook: Webhook URL for player radiation events
  • AdminWebhook: Webhook URL for radiation forced through the SetRadiation export
  • AdminPermissions: permission groups allowed to run /setradiation, which only exists with Config.Debug = true

Leave a webhook empty, or set it to false, to disable that log.