Configuration
Overview
shared/config.lua: Core settings, geiger items, battery, player effects, zones, vehicle/clothing protection, cure/immunity itemsserver/config_server.lua: Discord webhooks, admin permissions, rate limiting
Core Settings
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 = falseLocale: Language code for translationsMovegeiger: Command to reposition the Geiger Counter HUD on screenDebug: Enable debug prints in consoleUseRealTime: Use real-world time instead of GTA game time on the Geiger displayShowZoneNotifications: Show notifications when entering/leaving radiation zones (duration set by Config.ZoneNotificationDuration, default 15000 ms). Config.RequireGameplayReadyGate (default false) is an opt-in gate that suspends radiation processing during multicharacter/intro while ml_start reports that gameplay is not yet readyHealthSystemIntegration: Delegate radiation damage and visual effects toml_healthsystem. When true AND ml_healthsystem is running, the export handshake stays active; Config.HealthSystemSettings (disableDamage/disableVisuals) decides whether ml_radiation also cedes damage and visuals to ml_healthsystem. Default false = fully standaloneRealTerminalItem:true= Advanced mode (multiple Geiger items). Defaultfalse= Simple mode (single Geiger item), the shipped default
Geiger Counter Items
Advanced Mode
When Config.RealTerminalItem = true, each item opens a different Geiger Counter model and theme:
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}model: Display mode. Options:
- 'model-modern', 'model-standard', 'model-retro': Overlay mode: the interface renders as a screen overlay. Player can move freely, no prop or animation.
- 'dgm_geiger': DUI Prop mode: A physical 3D Geiger Counter object spawns and attaches to the player's chest. The interface renders directly onto the prop's texture via DUI texture replacement. The player plays a cellphone animation while holding the device.
theme: Color theme. Options:'theme-green','theme-blue','theme-orange'batteryMax: Maximum battery capacity (default 100, retro models use 120)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:
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 mode (model-modern, model-standard, model-retro): The Geiger UI renders as a screen overlay positioned via /movegeiger. No physical prop is created. The player can move and interact freely.
DUI Prop mode (dgm_geiger): A custom 3D model (dgm_geiger) spawns and attaches to the player's chest bone. The interface is rendered in real-time onto the prop's texture using DUI texture replacement. The player plays a holding animation while the Geiger is active. The prop is removed when the Geiger is closed.
Geiger UI
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 UIStatusThresholds.Warning: Radiation level at which the UI shows a warning stateStatusThresholds.Danger: Radiation level at which the UI shows a danger state
Battery System
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 indefinitelydrainPerMinute: Fallback drain rate (used when the item'sbatteryDrainis not set). Each item inConfig.AdvancedItemscan override this with its ownbatteryDrainlowThreshold: Battery percentage at which a low battery warning notification appearsrechargeItem: Inventory item consumed to recharge the batteryrechargeAmount: Battery percentage restored per use (capped at 100)
Battery level is stored in item metadata (meta.battery) and persists across sessions. Drain ticks every 60 seconds while the Geiger is active, and auto-saves every 30 seconds. At 0 battery, the Geiger Counter closes automatically and a notification is shown. Players recharge by using the rechargeItem from their inventory.
Player Effects
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 accumulateIncreaseSpeed: 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: Decrease rate per cycle when auto-remove is enabled. `SafeThreshold` = radiation only decays below this level (lower it for anti-abuse). `GracePeriod` = milliseconds of no new exposure before decay starts (default 12000)Damage.Enabled: Enable periodic health damage from radiationDamage.Interval: Milliseconds between damage ticksDamage.Thresholds: Damage applied at each radiation level. Checked highest-first.
Visual Effects
Screen effects intensify as radiation increases:
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:
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
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: Radiation multiplier inside vehicles.0.4= player receives that fraction of radiation. Default is 0.6 (player receives 60% = 40% protection); lower it for stronger shieldingExcludedClasses: Vehicle classes with no protection. Default excludes 8 (Motorcycles), 13 (Cycles), 14 (Boats), 15 (Helicopters); 16 (Planes) is set to `false` so planes do protectSpecificVehicles: Override multiplier per vehicle model.0.1= 90% protection,0.05= 95% protection
Clothing Protection
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
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 nameremoveAmount: Radiation points removed on useanimation: Optional animation with attached prop played during use
Immunity Items
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% protectionduration: Duration in minutes. Item is consumed on use.
Radiation Zones
Three zone types are supported. All use ox_lib zones internally.
Sphere Zone
1{
2 type = 'sphere',
3 coords = vec3(3559.61, 3775.89, 30.06),
4 radius = 300.0,
5 maxRadiation = 1000.0,
6 dynamic = true,
7 force = 2.5,
8 debug = false,
9}Box Zone
1{
2 type = 'box',
3 coords = vec3(447.12, -983.86, 30.68),
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
1{
2 type = 'poly',
3 points = {
4 vec3(-2048.81, 3128.59, 32.81),
5 vec3(-2045.18, 3140.89, 32.81),
6 vec3(-2058.42, 3145.24, 32.81),
7 vec3(-2061.85, 3132.88, 32.81),
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 throughoutmaxRadiation: Maximum radiation level inside the zoneforce: Accumulation speed multiplierdebug: Show zone wireframe in-game
Server Configuration
1ServerConfig.DiscordWebhook = ''
2ServerConfig.AdminWebhook = ''
3ServerConfig.AdminPermissions = { 'command', 'admin', 'god' }DiscordWebhook: Webhook URL for player radiation eventsAdminWebhook: Webhook URL for admin actionsAdminPermissions: ACE groups allowed to use admin commands- Rate limiting is applied per-event inside server/main.lua; there is no global cooldown key in config_server.lua.
Leave a webhook empty, or set it to the literal false, to disable that log. AdminPermissions ACE groups gate the admin notification path.