Configuration
Overview
shared/config/config.lua: Global settings, raid HUD, loot key, presets, limits, permissionsshared/config/camps.lua: Example camps, seeded into the database once on first bootshared/config/peds.lua: Ped models offered by the editor model picker (pedModelList)shared/config/weaponlist.lua: Weapons offered by the editor weapon picker (WeaponsList)server/config_server.lua: Log channels (Discord webhooks, FiveManage datasets). Never sent to clients
Camps are created and edited in-game through the admin panel and stored in the database. The config values below are defaults: the settings modal inside the panel writes HUD and loot-key values to the database, and from then on the saved values win over Config.HUD and Config.LootKey.
General
1Config.Settings = {
2 Locale = 'en',
3 Debug = false,
4 CreatorCommand = 'campsadmin',
5 MoveHudCommand = 'raidhud',
6 SyncRadius = 250.0,
7 UnloadDelay = 120,
8 CombatGrace = 60,
9 CorpseCleanupDelay = 60,
10 SeedExampleCamps = true,
11 BlipsEnabled = true,
12 NotifyOnEnter = true,
13}
14
15Config.Theme = 'default'Locale: Locale key fromlocales/*.lua. See that folder for the shipped files.Debug: Console debug outputCreatorCommand: Chat command that opens the admin panel. Permission-gated throughConfig.Permissions.CreatorMoveHudCommand: Command any player runs to drag and scale their own raid HUD. Set''to disableSyncRadius: Players within this range of a camp receive its peds and live blipsUnloadDelay: Seconds with no players insideSyncRadiusbefore an active camp despawns back to idleCombatGrace: Seconds after last contact before an engaged camp may reset to full strengthCorpseCleanupDelay: Seconds a dead camp ped stays in the world before cleanupSeedExampleCamps: On first boot, if theml_campstable is empty, insert the example camps fromshared/config/camps.luaBlipsEnabled: Master switch for world map blipsNotifyOnEnter: Notify a player when they enter an active camp zoneTheme: UI theme: 'default' | 'wasteland' | 'cyberpunk' | 'noir' | 'fantasy'
Raid HUD
1Config.HUD = {
2 Enabled = true,
3 Position = 'top-right',
4 ResetVisibilityDefault = 'timer',
5}Enabled: Master switch for the raid HUD shown while inside a camp radiusPosition: Default anchor: 'top-right' | 'top-center' | 'left-center' | 'bottom-right'. Each player can override their own position and size with theMoveHudCommandcommandResetVisibilityDefault: What the HUD shows after a camp is cleared: 'timer' (respawn countdown), 'status' (cleared badge, no countdown), 'hidden' (HUD disappears). 'status' and 'hidden' stop respawn-timer metagaming. Each camp can override this in the editor (Reset Info)
Saving the settings modal in the admin panel writes the HUD values to the ml_camps_settings table. From then on the database values are used and pushed live to every player; the config values only act as first-boot defaults.
Loot Key
1Config.LootKey = {
2 Mode = 'virtual',
3 Item = 'camp_key',
4 ConsumeOnOpen = true,
5}Mode: 'virtual' (key tracked server-side, no inventory item) | 'item' (physical inventory item carrying camp metadata; the item must be registered, see the Installation page)Item: Item mode only. Inventory item name handed out as the keyConsumeOnOpen: Remove the key when the holder opens their first crate
The key gate is enabled per camp in the editor (Require key). A random camp NPC carries the key; when it dies, the key is granted to the nearest raider. If the camp is cleared before the carrier drops it, the first credited raider receives it. One key unlocks every crate of that camp for its holder. In item mode the key carries metadata.camp, so it only opens the camp it was looted from. These values can also be changed from the settings modal in the admin panel and are then stored in the database.
Camp Types
1Config.CampTypes = {
2 bandit = { label = 'Bandit Camp', blip = { sprite = 84, color = 1, scale = 0.9 } },
3 military = { label = 'Military Outpost', blip = { sprite = 489, color = 5, scale = 0.9 } },
4 scavenger = { label = 'Scavenger Den', blip = { sprite = 364, color = 47, scale = 0.9 } },
5 cartel = { label = 'Cartel Stronghold', blip = { sprite = 51, color = 1, scale = 0.9 } },
6}- Presets offered by the editor type field, driving the default blip look. Custom type strings are allowed; every camp can override its blip sprite, color and scale individually
Config.CrateProps: Loot crate prop presets ({ model, label }) offered by the editor crate picker. Admins can also type any custom prop model
Aggression Presets
1Config.Aggression = {
2 defensive = { combatMovement = 1, combatAbility = 1, useCover = true, canCharge = false },
3 balanced = { combatMovement = 2, combatAbility = 1, useCover = true, canCharge = false },
4 aggressive = { combatMovement = 2, combatAbility = 2, useCover = true, canCharge = true },
5 berserk = { combatMovement = 2, combatAbility = 2, useCover = false, canCharge = true },
6}combatMovement: 1 defensive, 2 will advance on the playercombatAbility: 1 average, 2 professionaluseCover: NPC takes cover during firefightscanCharge: NPC may rush the player at close range
Each NPC group picks one preset by name. Adding a new key here makes it selectable in the editor.
Stealth
1Config.Stealth = {
2 crouchRangeMult = 0.55,
3 sprintHearMult = 0.8,
4 detectTicks = 2,
5 alertRadius = 35.0,
6}crouchRangeMult: Crouched players are seen at this fraction of an NPC's seeing rangesprintHearMult: Sprinting players are heard within hearing range multiplied by this valuedetectTicks: Detection cycles a player must stay in view before an NPC engages. Hearing alone needs one extra tickalertRadius: When one NPC engages, other camp NPCs within this range also alert
Shooting inside hearing range, damaging an NPC, or aiming directly at one triggers combat immediately. The per-NPC blip turns from neutral to suspicious to alerted as detection builds.
NPC Defaults
1Config.NpcDefaults = {
2 health = 200,
3 armor = 0,
4 accuracy = 35,
5 aggression = 'balanced',
6 detectionRange = 40.0,
7 fovAngle = 110.0,
8 behavior = 'static',
9 weaponMode = 'fixed',
10 weapon = 'WEAPON_PISTOL',
11}- Fallbacks applied when a camp NPC group omits a field. Field meanings are described under Camp Definition below
Limits
1Config.Limits = {
2 maxNpcsPerCamp = 40,
3 maxHealth = 5000,
4 maxArmor = 500,
5 maxRadius = 300.0,
6 maxRaiders = 64,
7 minRespawnDelay = 30,
8 minResetDelay = 30,
9}- Hard ceilings clamped server-side on every camp definition, including camps saved from the admin panel
Permissions
1Config.Permissions = {
2 Creator = {
3 useDefaultAdmins = true,
4 ace = { 'ml_camps.creator', 'admin', 'god', 'superadmin', 'command', 'group.admin', 'group.superadmin' },
5 },
6 LiveActions = {
7 useDefaultAdmins = true,
8 ace = { 'ml_camps.admin', 'admin', 'god', 'superadmin', 'group.admin', 'group.superadmin' },
9 },
10}Creator: Opens the admin panel, creates/edits/deletes camps, changes global settingsLiveActions: Force clear, force reset and teleport from the Live tabuseDefaultAdmins: Also accept anyone ml_bridge recognizes as a server adminace: ACE permissions accepted for the tier. Grant a single group with e.g.add_ace group.mod ml_camps.creator allow
Permission checks are implemented in open/handlers_server.lua and can be replaced with custom logic. See the Developer page.
Camp Definition
Camps are normally built in the editor; the fields below are what the editor produces and what shared/config/camps.lua seeds on first boot. After the first boot the database is the source of truth and the file is no longer read.
1Config.Camps['bandit_grapeseed'] = {
2 id = 'bandit_grapeseed',
3 label = 'Grapeseed Bandit Camp',
4 type = 'bandit',
5 enabled = true,
6 center = { x = 2447.0, y = 4968.0, z = 45.5 },
7 radius = 60.0,
8 respawnEnabled = true,
9 respawnDelay = 1800,
10 resetDelay = 600,
11 maxRaiders = 6,
12 hud = { resetVisibility = 'inherit' },
13 blip = { enabled = true, sprite = 84, color = 1, scale = 0.9, showRadius = true },
14 npcs = { ... },
15 loot = { ... },
16}id: Unique key, letters/numbers/underscore onlytype: AConfig.CampTypeskey or any custom stringenabled: Disabled camps keep their data but never spawncenter/radius: The camp zone. A player crossing the radius activates the camp and is tracked as a raiderrespawnEnabled:falsemakes the camp spawn-once: after a clear it goes todepletedand stays empty until a staff Force ResetrespawnDelay: Seconds a cleared camp stays on cooldown before it can spawn againresetDelay: Seconds before an engaged-but-not-cleared camp respawns to full strength (combined withConfig.Settings.CombatGrace)maxRaiders: Players eligible for loot credit on clear, ordered by who entered the zone firsthud.resetVisibility: Per-camp override of the HUD reset info: 'inherit' | 'timer' | 'status' | 'hidden'blip: Map blip.showRadiusdraws the zone circle. The blip color follows the live camp status
NPC groups
1npcs = {
2 {
3 modelPool = { 'g_m_y_lost_01', 'g_m_y_lost_02', 'g_m_y_lost_03' },
4 count = 4,
5 weaponMode = 'fixed', weapon = 'WEAPON_PISTOL',
6 health = 200, armor = 0, accuracy = 30,
7 aggression = 'balanced', detectionRange = 40.0,
8 behavior = 'patrol', spawnMode = 'auto',
9 },
10}model/modelPool: Single ped model, or a pool one is picked from per spawn. Custom addon peds are allowedcount: NPCs spawned from this groupweaponMode: 'fixed' usesweapon, 'random' picks fromweaponPoolper spawnhealth/armor/accuracy: Combat stats, clamped byConfig.Limitsaggression: AConfig.Aggressionpreset namedetectionRange/fovAngle: Seeing and hearing range in meters, and field of view in degreesbehavior: 'static' (holds position), 'patrol' (walkspatrolPointsin order, or wanders the area when none are set),'guard'(defends aguardRadiusaround its spawn)spawnMode: 'auto' scatters spawns around the camp center, 'fixed' cycles throughspawnPointspatrolPoints: The route a patrol NPC walks, in order, looping back to the start, placed in-game from the editor. Each waypoint carries a type: apass-throughpoint only shapes the walk, astopparks the NPC there for a set number of seconds, and arandom stoppauses it on some laps and walks it past on others. Cycle the type withRas you drop each point, or change it per point in the list. Random-stop odds default toConfig.NpcDefaults.patrolStopChance, and a point with no set duration falls back topatrolWaitDefault. A stop, or a random stop when it fires, can also face a heading you set with the mouse wheel as you place it, so a paused guard looks where you want.
Loot
1loot = {
2 rewardType = 'both',
3 delivery = 'prop',
4 requireKey = false,
5 props = {
6 { model = 'prop_box_ammo04a' },
7 },
8 fixedLoots = {
9 { items = { 'bandage' }, min = 1, max = 2 },
10 },
11 probabilityLoots = {
12 loop = 3,
13 items = {
14 { items = { 'lockpick' }, min = 1, max = 1, probability = 40.0 },
15 { items = { 'weapon_pistol' }, min = 1, max = 1, probability = 8.0 },
16 },
17 },
18 moneyConfig = { account = 'cash', min = 200, max = 600 },
19}rewardType: 'money' | 'items' | 'both'delivery: 'direct' pays everything straight into eligible raiders' inventories on clear. 'prop' and 'both' put items into lootable crates while money is still paid directly on clear. When no crates are defined, items fall back to direct deliveryrequireKey: Enables the loot key gate for this camp (see Loot Key above)props: One lootable crate per entry. Optionalcoords(placed in-world from the editor); without coords crates spawn near the camp center. Each crate yields a full loot roll to the first eligible raider who searches itfixedLoots: Guaranteed drops. Each entry picks one item fromitemsand rollsmin:maxof it. OptionalitemMetadataper itemprobabilityLoots: Random tables. The whole set is rolledlooptimes (max 10); each group drops withprobabilitypercent per rollmoneyConfig: Account 'cash' or 'bank', random amount betweenminandmax(capped at 100000)
Every item name used in loot tables must exist in your inventory, or that drop is silently skipped. The editor item picker only offers registered items.
Log Channels
1Config.Logs = {
2 Enabled = true,
3 Provider = 'discord', -- 'discord' | 'fivemanage' | 'ox_lib' | 'both' | 'all'
4 Channels = {
5 Activated = { webhook = '', dataset = 'ml_camps_activated' },
6 Cleared = { webhook = '', dataset = 'ml_camps_cleared' },
7 Loot = { webhook = '', dataset = 'ml_camps_loot' },
8 Key = { webhook = '', dataset = 'ml_camps_key' },
9 Reset = { webhook = '', dataset = 'ml_camps_reset' },
10 Despawn = { webhook = '', dataset = 'ml_camps_despawn' },
11 CampEdit = { webhook = '', dataset = 'ml_camps_campedit' },
12 LiveActions = { webhook = '', dataset = 'ml_camps_live' },
13 Settings = { webhook = '', dataset = 'ml_camps_settings' },
14 },
15}Enabled: Master switch for all loggingProvider: 'discord' (webhooks), 'fivemanage' (datasets), 'ox_lib' (server console), 'both' (Discord + FiveManage), 'all'Activated: A camp was activated (raid started)Cleared: A camp was cleared, with the credited raider listLoot: A player claimed loot from a crate, with the exact items and moneyKey: A camp key was granted to a playerReset: A camp reset to full strengthDespawn: A camp despawned with no players nearbyCampEdit: Staff created, edited or deleted a campLiveActions: Staff force clear, force reset or teleportSettings: Staff changed the global HUD or key settingsExploit: A player failed a server-side check (out-of-range activate/loot, or an unauthorized admin call)
Each channel has its own webhook and its own FiveManage dataset. Leave a webhook empty to silence that channel on Discord, or point several channels at the same webhook for fewer destinations.