Configuration
Overview
shared/config/config.lua: general settings, raid HUD, admin alerts, loot key, presets, stealth, NPC defaults, limits, permissions and battlepassshared/config/camps.lua: camps seeded into the database on first boot. Ships emptyshared/config/peds.lua: ped models offered in the editor (pedModelList)shared/config/weaponlist.lua: weapons offered in the editor (WeaponsList)shared/config/zombies.lua: walk styles and attack animations for zombie NPC groupsserver/config_server.lua: log channels
Camps are built and edited in the admin panel and saved in the database. The HUD and loot key values below are first boot defaults: once you save the settings window in the panel, the saved values are used.
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'
16Config.Admin.MinimizeKey = 'F9'Locale: language file loaded from thelocales/folderDebug: prints extra console outputCreatorCommand: opens the admin panel. Needs theCreatorpermissionMoveHudCommand: lets any player drag and resize their own raid HUD.''turns it offSyncRadius: players within this range of a camp see its NPCs and live blipsUnloadDelay: seconds with no player insideSyncRadiusbefore an active camp despawns and goes back to idleCombatGrace: seconds after the last contact before an engaged camp can reset to full strengthCorpseCleanupDelay: seconds a dead camp NPC stays on the groundSeedExampleCamps: on first boot, with an emptyml_campstable, copies the camps ofshared/config/camps.luainto the databaseBlipsEnabled:falsehides every camp blipNotifyOnEnter: notifies a player who walks into an active campTheme: theme of the raid HUD and the admin panel.'default','wasteland','cyberpunk','noir'or'fantasy'MinimizeKey: hides and restores the admin panel. F1 to F12, or a single letter or digit
UI Theme
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.nilfollows the shared theme set inml_bridgecolors: CSS hex values for single colors. Anynilvalue follows the shared theme
Raid HUD
1Config.HUD = {
2 Enabled = true,
3 Position = 'top-right',
4 ResetVisibilityDefault = 'timer',
5}Enabled: shows the raid HUD while the player is inside a campPosition:'top-right','top-center','left-center'or'bottom-right'. Players can move their own copy with/raidhudResetVisibilityDefault: what the HUD shows after a clear.'timer'shows the respawn countdown,'status'a cleared badge with no countdown,'hidden'hides the HUD. With'status'or'hidden'players cannot wait out the timer at the camp. Each camp can override it in the editor
Admin Alerts
1Config.Alerts = {
2 Enabled = true,
3 AbandonedSeconds = 480,
4 StaleCooldownSeconds = 120,
5}Alerts show on the Home and Live tabs of the panel. They only flag a camp and never act on it.
Enabled: turns the alerts on or offAbandonedSeconds: an active camp with no players for this long is flagged as abandonedStaleCooldownSeconds: a camp still on cooldown this long after its timer ended is flagged as stuck
Loot Key
1Config.LootKey = {
2 Mode = 'virtual',
3 Item = 'camp_key',
4 ConsumeOnOpen = true,
5}Mode:'virtual'tracks the key on the server with no item.'item'hands out an inventory item, which you must register (see Installation)Item: item name of the key in item modeConsumeOnOpen: removes the key when its holder opens the first crate
Turn the key on per camp with Require key in the editor. One random camp NPC carries it. When that NPC dies, the nearest raider gets the key. If the camp is cleared before the carrier dies, the first credited raider gets it. One key opens every crate of that camp for its holder. In item mode the key carries metadata.camp, so it only opens the camp it came from.
Camp Types and Crates
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}
7
8Config.CrateProps = {
9 { model = 'prop_box_ammo04a', label = 'Ammo Crate' },
10 { model = 'prop_box_ammo01a', label = 'Ammo Box' },
11 { model = 'prop_box_wood04a', label = 'Wooden Crate' },
12 { model = 'prop_box_wood02a_pile', label = 'Wooden Crate (pile)' },
13 { model = 'prop_mil_crate_01', label = 'Military Crate' },
14 { model = 'prop_barrel_02a', label = 'Barrel' },
15 { model = 'prop_cs_cardbox_01', label = 'Cardboard Box' },
16 { model = 'prop_ld_case_01', label = 'Briefcase' },
17 { model = 'prop_money_bag_01', label = 'Money Bag' },
18 { model = 'prop_drug_package', label = 'Package' },
19}CampTypes: types offered in the editor, with their default blip. A camp can use any other type name and override its own blipCrateProps: crate models offered in the editor. Admins can also type any prop model
Aggression
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:1holds ground,2advances on the playercombatAbility:1average,2professionaluseCover: the NPC takes cover in firefightscanCharge: the NPC can rush the player at close range
Each NPC group picks one preset by name. A new key here shows up in the editor.
Stealth
1Config.Stealth = {
2 crouchRangeMult = 0.55,
3 sprintHearMult = 0.8,
4 detectTicks = 2,
5 alertRadius = 35.0,
6}crouchRangeMult: a crouched player is seen at this fraction of the NPC seeing rangesprintHearMult: a sprinting player is heard within the hearing range multiplied by this valuedetectTicks: detection cycles a player must stay in view before an NPC engages. Hearing alone needs one morealertRadius: when one NPC engages, the camp NPCs within this range join in
Shooting within hearing range, hurting an NPC or aiming at one starts combat at once. The NPC blip goes 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 headshotKills = true,
10 canRagdoll = true,
11 weaponMode = 'fixed',
12 weapon = 'WEAPON_PISTOL',
13 patrolStopChance = 0.5,
14 patrolWaitDefault = 5,
15}Values used when an NPC group leaves a field empty. The fields are explained under Camp Definition.
headshotKills:truekills an NPC with one headshot whatever its health.falsemakes a headshot count as a body shotcanRagdoll:falsekeeps the NPC on its feet when shot, hit by a car or caught in a blastpatrolStopChance: chance from0to1that a random stop waypoint pauses the NPC on a lappatrolWaitDefault: seconds a stop waypoint pauses the NPC when the point has no duration of its own
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}The server clamps every camp to these values, camps saved from the panel included.
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 panel, creates, edits and deletes camps, changes the global settingsLiveActions: force clear, force reset and teleport from the Live tab. Without this block it usesCreatoruseDefaultAdmins: also accepts every playerml_bridgetreats as adminace: ACE permissions accepted for that tier, for exampleadd_ace group.mod ml_camps.creator allow
The checks live in open/handlers_server.lua, where you can replace them.
Battlepass
1Config.Battlepass = { Enabled = true }Enabled: withml_battlepassrunning, clearing a camp advances battlepass objectives for every player who took part.falseturns it off. Withoutml_battlepassthis setting does nothing
Camp Definition
Camps are normally built in the editor. The fields below are what the editor saves and what shared/config/camps.lua accepts for the first boot seed. After the first boot the database is used and the file is not read again.
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 and underscore onlytype: aConfig.CampTypeskey or any other nameenabled: a disabled camp keeps its data and never spawnscenter,radius: the camp zone. A player who walks in activates the camp and counts as a raiderrespawnEnabled:falsemakes a spawn-once camp. After a clear it stays depleted until staff press Force ResetrespawnDelay: seconds a cleared camp stays on cooldownresetDelay: seconds an engaged camp must be up before it can go back to full strength. It also needsCombatGraceseconds with no contactmaxRaiders: players who get loot credit on a clear, in the order they enteredresetOnRestart:truemakes the camp ignore its saved cooldown or cleared state when the script restartshud.resetVisibility:'inherit','timer','status'or'hidden'blip: map blip.showRadiusdraws the zone circle. The 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: one ped model, or a list to pick from on each spawn. Addon peds workcount: NPCs spawned from this groupweaponMode:'fixed'usesweapon,'random'picks fromweaponPoolon each spawnhealth,armor,accuracy: combat stats, clamped byConfig.Limitsaggression: aConfig.AggressionpresetdetectionRange,fovAngle: seeing and hearing range in meters, and field of view in degreesbehavior:'static'holds position,'patrol'walkspatrolPointsin a loop or wanders when there are none,'guard'defends aguardRadiusaround its spawnspawnMode:'auto'scatters the NPCs around the center,'fixed'cycles throughspawnPointspatrolPoints: route placed in game from the editor. A pass-through point only shapes the walk. A stop pauses the NPC for a set number of seconds. A random stop pauses it on some laps only. PressRwhile placing to change the type, and use the mouse wheel to set the direction a paused NPC faces
A group can also use Zombie Mode: no guns, a shambling walk, melee lunges and damage per hit. Walk styles and attack animations come from shared/config/zombies.lua.
Horde Mode
Turn on Horde Mode in the editor and the camp fights in waves. Crates unlock after the last wave.
1horde = { enabled = true, waves = 3, delay = 15, scaling = 100, spawnMode = 'perimeter' },waves: number of waves, up to 10delay: seconds between two waves, up to 300scaling: size of each wave compared with the one before, from50to300percent.100keeps the same sizespawnMode:'perimeter'sends later waves in from the camp edge, already hostile.'layout'uses the spawn points of the first wave
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'or'both'delivery:'direct', the default, gives each credited raider a loot roll of their own on the clear.'prop'rolls the loot once and spreads the items and the money across the crates. A camp with no crates pays directlyrequireKey: turns on the loot key for this campprops: one crate per entry. Place them in game from the editor, or leavecoordsout to spawn them near the center. The first credited raider who searches a crate takes its sharefixedLoots: guaranteed drops. Each entry picks one item fromitemsand gives betweenminandmax. Items can carryitemMetadataprobabilityLoots: chance tables. The whole set rollslooptimes, up to 10, and each entry drops with itsprobabilitypercentmoneyConfig:'cash'or'bank', a random amount betweenminandmax, up to 100000
With ML Inventory running, the loot editor also offers a Clothing reward: a fixed piece, or a random piece from a series of drawables, with a photo of each model.
Every item in a loot table must exist in your inventory, or that drop is skipped. The item picker in the editor only lists registered items.
Log Channels
1Config.Logs = {
2 Enabled = true,
3 Provider = 'discord',
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 Exploit = { webhook = '', dataset = 'ml_camps_exploit' },
15 },
16}Enabled: turns every log on or offProvider:'discord','fivemanage','ox_lib','both'(Discord and FiveManage) or'all'Activated: a raid startsCleared: a camp is cleared, with the credited raidersLoot: a player loots a crate, with the items and moneyKey: a player gets a camp keyReset: a camp goes back to full strengthDespawn: a camp despawns with no players nearbyCampEdit: staff create, edit or delete a campLiveActions: staff force clear, force reset or teleportSettings: staff change the HUD or key settingsExploit: a player fails a server check, such as looting from out of range or calling an admin action without permission
Each channel has its own webhook and FiveManage dataset. Leave a webhook empty to skip that channel on Discord.