Configuration

Every setting in oxide-gangs — creation, treasury, bases and stash, garage, territory, wars, police alerts, radio, logs, and the two file-only configs.

Every setting in oxide-gangs, what it does, and what it starts as.

How Configuration Works

Settings live in your database, and you edit them in game.

Type /gangs settings as an admin and a panel opens with everything below in it, organised into the same groups. Change a value, click Save Changes, and it takes effect immediately — no restart, no file editing, no reconnecting players.

The files shared/config.lua and shared/config/*.lua are factory defaults only. The first time the resource starts, their values are copied into the oxide_settings database table, and from that moment the table is what the resource reads. Editing the files afterwards does nothing on an existing install. When an update adds a brand-new setting, it is filled in from the file automatically and your existing values are left alone.

Two files are the exception and stay file-only. They are covered at the end under File-Only Settings.

Reading the tables below:

  • Setting is the name used in the code and in this documentation. In the settings panel you will see the friendly label next to it.
  • Type is what kind of value it holds: boolean (on/off), number, string (text), table (a list or a group of values).
  • Default is what it ships as.

Creation

Settings panel: Core → Creation

Who can create gangs, and the limits applied to them.

SettingTypeDefaultDescription
Config.Creation.creationModestring'request'How gangs come into existence. 'request' = players ask and staff approve. 'admin_only' = only staff create gangs, and /gangs request tells players requests are off
Config.Creation.requestCooldownMinsnumber60Minutes a player must wait between gang creation requests. 0 = no wait
Config.Creation.creationFeenumber0Charged from the requester's bank account when their gang is approved. 0 = free. The requester must be online to be charged, and if they cannot pay, the approval is refused rather than half-completed
Config.Creation.maxGangsnumber0Most gangs that can exist at once. 0 = unlimited
Config.Creation.maxMembersPerGangnumber32Member cap per gang, enforced on both invites and applications
shared/config.lua
Config.Creation = {
    creationMode       = 'request',
    requestCooldownMins = 60,     -- minutes between creation requests per character
    creationFee        = 0,       -- charged to the requester on approval (0 = free)
    maxGangs           = 0,       -- 0 = unlimited
    maxMembersPerGang  = 32,
}

Blocked names

SettingTypeDefaultDescription
Config.NameBlocklisttablesee belowInternal gang names players may not request. Checked without regard to capitals

This list is the only name check beyond basic format rules, so add any job names you want kept off-limits. A gang can never reach a job's money regardless of its name — gang bank accounts are created under a gang_ prefix, so they cannot collide with a job account.

shared/config.lua
Config.NameBlocklist = { 'police', 'sheriff', 'ems', 'ambulance', 'admin', 'staff', 'government' }

The request form

SettingTypeDefaultDescription
Config.RequestFormtable5 questionsThe questions players answer on /gangs request. Add, remove, and reorder rows in the settings panel (up to 20)

Every row has these fields:

FieldTypeDescription
idstringA unique key for the question, up to 40 characters. Changing it orphans answers on already-submitted requests. motto is reserved — its answer becomes the gang's motto on approval
labelstringThe question the player sees, up to 100 characters
typestring'text' (one line), 'textarea' (multi-line), 'select' (dropdown), 'number', or 'toggle' (yes/no)
requiredbooleanThe request cannot be submitted without an answer
placeholderstringGhost text shown in an empty text box
helpstringA short hint under the question
maxLengthnumberCharacter limit for text answers. 0 or unset uses the default (120 for short text, 1000 for long text). The hard ceiling is 2000
optionstableThe list of choices. Only used by select questions

The gang's display name is always asked and is not a row you add.

A row with a missing or duplicate id, an unknown type, a blank label, or a select with no choices is quietly skipped — the rest of the form still works, so a typo can never break the form for your players.

shared/config.lua
Config.RequestForm = {
    { id = 'motto',     label = 'Gang motto', type = 'text', required = false,
      placeholder = 'A short slogan for your gang', maxLength = 120 },
    { id = 'backstory', label = 'Backstory', type = 'textarea', required = true,
      help = 'Who is the crew and where did they come from?', maxLength = 1000 },
    { id = 'discord',   label = 'Discord name', type = 'text', required = true,
      placeholder = 'e.g. playername', maxLength = 60 },
    { id = 'members',   label = 'Expected starting members', type = 'number', required = false,
      help = 'How many members do you expect to start with?' },
    { id = 'rp_plans',  label = 'Roleplay plans', type = 'textarea', required = false,
      help = 'What kind of RP will the gang bring to the server?', maxLength = 1000 },
}

Treasury

Settings panel: Economy → Treasury

Where gang money is kept.

SettingTypeDefaultDescription
Config.Treasury.useBankingAccountbooleanfalseOff = balances are stored by oxide-gangs itself. On = balances live in your banking resource as an account named gang_<name> (for example gang_ballas). Only turn this on if you run a banking resource o-link supports
Config.Treasury.startBalancenumber0Treasury balance a newly created gang starts with
shared/config.lua
Config.Treasury = {
    useBankingAccount = false,    -- delegate balances to olink.banking ('gang_<name>' accounts)
    startBalance      = 0,
}

Bases & Stash

Settings panel: World → Bases & Stash

Bases

SettingTypeDefaultDescription
Config.Bases.interactDistancenumber2.0How close a member must stand to a base interaction point to use it, in metres. Range 1–10
Config.Bases.blipsEnabledbooleantrueShow a map blip on the gang base. Only the gang's own members ever see it. Can also be turned off per base in the admin panel
Config.Bases.blipSpritenumber492The blip icon. Range 1–826
Config.Bases.blipColornumber1The blip colour. Range 0–85
Config.Bases.blipScalenumber0.8Blip size on the map. Range 0.1–2
shared/config.lua
Config.Bases = {
    interactDistance = 2.0,
    blipsEnabled     = true,
    blipSprite       = 492,
    blipColor        = 1,
    blipScale        = 0.8,
}

Stash

SettingTypeDefaultDescription
Config.Stash.defaultSlotsnumber50Inventory slots in a gang stash. Range 1–500. Can be overridden per base
Config.Stash.defaultMaxWeightnumber200000Total stash weight in grams — 200000 is 200 kg. Range 1000–10000000

Changing either value re-registers every gang stash straight away. No restart needed.

shared/config.lua
Config.Stash = {
    defaultSlots     = 50,
    defaultMaxWeight = 200000,
}

Invites

Marked Advanced in the settings panel.

SettingTypeDefaultDescription
Config.Invites.expireSecondsnumber60Seconds an invite stays valid before it lapses. Range 10–600
Config.Invites.inviteDistancenumber10.0Furthest apart the inviter and the invited player may be, in metres. Range 1–50
shared/config.lua
Config.Invites = {
    expireSeconds = 60,
    inviteDistance = 10.0,        -- max distance between inviter and target
}

Garage

Settings panel: World → Garage

SettingTypeDefaultDescription
Config.Garage.maxFleetSizenumber10Most vehicles one gang can own. Range 1–100
Config.Garage.storeRequiresAtBasebooleantrueOn = a gang car must be returned near the base garage point. Off = members can return one from anywhere
Config.Garage.interactDistancenumber5.0How close a member must stand to the garage point to use it, in metres. Range 1–20
Config.Garage.bayPreviewModelstring'asea'The ghost vehicle shown when staff place a spawn bay for a gang whose fleet is still empty. If the gang already owns a car, its first car is used instead
shared/config.lua
Config.Garage = {
    maxFleetSize       = 10,
    storeRequiresAtBase = true,
    interactDistance   = 5.0,
    bayPreviewModel    = 'asea',  -- ghost vehicle shown when placing spawn bays with an empty fleet
}

Territory

Settings panel: World → Territory

The influence engine — how turf is earned, how it bleeds away, and how it changes hands. Territories themselves are drawn in /gangs admin, not here. See Features → Territory for how these interact.

Master switch

SettingTypeDefaultDescription
Config.Territory.enabledbooleantrueTurns the whole territory system on or off

Where influence comes from

SettingTypeDefaultDescription
Config.Territory.saleGainPerDollarnumber0.05Influence per dollar of drug sales completed inside the zone. A $1,000 sale earns 50 influence at this value. Range 0–10
Config.Territory.baseActivityGainnumber2.0Influence each time a member opens the stash or uses the garage at a base inside the zone. Range 0–100
Config.Territory.presenceGainPerTicknumber1.0Influence per member standing in the zone, each presence check. Range 0–100
Config.Territory.presenceTickMinutesnumber5Minutes between presence checks. Range 1–60
Config.Territory.killGainnumber5.0Influence per war kill landed inside the zone. Only counts during an active war. Range 0–100
Config.Territory.captureGainnumber15.0Influence per war objective captured inside the zone. Range 0–500
Config.Territory.killShareOfInfluencenumber0.25The most that kills in one war may add on top, as a share of the influence the gang has already earned in that zone through activity. 0.25 = 25%. Kills amplify standing; they can never replace it. Range 0–1

Anti-farm caps

SettingTypeDefaultDescription
Config.Territory.hourlyCap.salenumber60.0Cap on drug-sale influence per gang per zone per hour
Config.Territory.hourlyCap.basenumber20.0Cap on base-activity influence per gang per zone per hour
Config.Territory.hourlyCap.presencenumber12.0Cap on presence influence per gang per zone per hour
Config.Territory.hourlyCap.killnumber30.0Cap on war-kill influence per gang per zone per hour
Config.Territory.hourlyCap.capturenumber45.0Cap on war-capture influence per gang per zone per hour
Config.Territory.hourlyCap.externalnumber30.0Cap on influence reported by third-party scripts per gang per zone per hour. Every external script shares this one cap
Config.Territory.charHourlySharenumber0.5The most of each hourly cap a single character can supply. 0.5 = 50%. This is what stops alt-account farming. Range 0.1–1

Setting any cap to 0 disables that source of influence entirely.

Decay

SettingTypeDefaultDescription
Config.Territory.decayTickMinutesnumber15Minutes between decay passes. Range 1–120
Config.Territory.decayPerHournumber1.0Influence every gang loses per zone per hour. Range 0–100
Config.Territory.decayPerHoldingnumber0.35Extra decay rate for each territory a gang owns beyond the first. 0.35 = +35% per extra zone. This is the rubber band that stops one gang owning the whole map. Range 0–5

Ownership

SettingTypeDefaultDescription
Config.Territory.ownershipThresholdnumber100.0Influence a gang needs before it can claim an unowned zone. Range 1–100000
Config.Territory.contestWindowHoursnumber6Real hours a contest stays open once a rival overtakes the owner. Standings settle when it closes — there are no instant flips. Range 1–168
Config.Territory.contestCooldownHoursnumber12Real hours after a contest settles before a new one can open on that zone. Range 0–336
Config.Territory.maxInfluencenumber1000.0Hard ceiling on influence per gang per zone. Range 100–1000000

Map display

SettingTypeDefaultDescription
Config.Territory.blipsEnabledbooleantrueShow a map blip for each territory, named after its owner. These are public — everyone sees them. Blips are also off per territory by default on the shipped districts
Config.Territory.turfMap.enabledbooleantrueThe filled turf areas on the minimap and pause map. Gang members only
Config.Territory.turfMap.alphanumber110How solid an owned zone's fill looks. 0 = invisible, 255 = fully solid
Config.Territory.turfMap.unownedAlphanumber70How solid an unclaimed zone's fill looks. 0–255
shared/config.lua
Config.Territory = {
    enabled             = true,
    -- Gain per source (influence points)
    saleGainPerDollar   = 0.05,   -- drug sales reported via o-link: sale value * this
    baseActivityGain    = 2.0,    -- stash/garage/treasury use at a base inside the zone
    presenceGainPerTick = 1.0,    -- per member standing in the zone per presence tick
    presenceTickMinutes = 5,
    killGain            = 5.0,    -- per war kill landed inside a territory (wars only)
    captureGain         = 15.0,   -- per war objective captured in the territory (wars only)
    killShareOfInfluence = 0.25,
    -- Anti-farm caps, per gang per territory per hour
    hourlyCap           = { sale = 60.0, base = 20.0, presence = 12.0, kill = 30.0, capture = 45.0, external = 30.0 },
    charHourlyShare     = 0.5,    -- one character may supply at most this share of each cap
    -- Decay, scaled by holdings: two territories is sustainable, eight bleeds
    decayTickMinutes    = 15,
    decayPerHour        = 1.0,    -- per (territory, gang) influence row
    decayPerHolding     = 0.35,   -- extra decay rate per owned territory beyond the first
    -- Ownership
    ownershipThreshold  = 100.0,  -- influence needed before a territory can be claimed
    contestWindowHours  = 6,      -- overtaking the owner opens a window; standings settle at its end
    contestCooldownHours = 12,    -- after a settle, a new contest can't open immediately
    maxInfluence        = 1000.0,
    blipsEnabled        = true,
    turfMap = {
        enabled      = true,
        alpha        = 110,   -- fill opacity for owned zones (0-255)
        unownedAlpha = 70,    -- fill opacity for unclaimed zones
    },
}

Territory Police Alerts

Settings panel: World → Territory → Police alerts (marked Advanced)

Alerts sent to police when turf goes contested or changes hands.

SettingTypeDefaultDescription
Config.TerritoryDispatch.enabledbooleantrueSend these alerts at all
Config.TerritoryDispatch.jobstable{ 'police', 'sheriff' }Which job names receive the alert. Spell them exactly as your framework has them
Config.TerritoryDispatch.codestring'10-90'The radio code shown on the alert
Config.TerritoryDispatch.prioritynumber2Alert priority, 1 (highest) to 5
Config.TerritoryDispatch.iconstring'fa-people-group'The Font Awesome icon name shown on the alert
Config.TerritoryDispatch.contestedTitlestring'Gang Activity'Title when a zone becomes contested
Config.TerritoryDispatch.contestedMessagestring'Reports of rising gang tension in %s'Body for a contested zone. %s is replaced with the zone's name
Config.TerritoryDispatch.flippedTitlestring'Territory Takeover'Title when a zone changes hands
Config.TerritoryDispatch.flippedMessagestring'%s has been claimed by a new crew'Body for a takeover. %s is replaced with the zone's name
Config.TerritoryDispatch.blipDatatable{ sprite = 310, color = 1, scale = 1.0, duration = 60 }The map marker dropped for responders: icon, colour, size, and how many seconds it lasts

Alert coordinates always come from the server — the centre of the zone, never from a player's game.

shared/config.lua
Config.TerritoryDispatch = {
    enabled  = true,
    jobs     = { 'police', 'sheriff' },
    code     = '10-90',
    priority = 2,
    icon     = 'fa-people-group',
    contestedTitle   = 'Gang Activity',
    contestedMessage = 'Reports of rising gang tension in %s',
    flippedTitle     = 'Territory Takeover',
    flippedMessage   = '%s has been claimed by a new crew',
    blipData = { sprite = 310, color = 1, scale = 1.0, duration = 60 },
}

Wars

Settings panel: World → Wars

War rules

SettingTypeDefaultDescription
Config.Wars.enabledbooleantrueTurns the whole war system on or off
Config.Wars.durationHoursnumber24Real hours a war runs once accepted. Locked in per war at the moment it is accepted — changing this later only affects wars accepted afterwards. Range 1–336
Config.Wars.pendingExpiryHoursnumber24Hours an unanswered declaration stays open before it lapses. Range 1–336
Config.Wars.rematchCooldownHoursnumber48Hours before the same two gangs can go to war again, in either direction. 0 = no cooldown. Range 0–720
Config.Wars.maxStakenumber1000000Largest stake per side. The defender must match the attacker's stake to accept; the winner takes both. 0 = unlimited. A stake of 0 is always allowed
Config.Wars.killScorenumber1.0Score per validated war kill. Range 0–100
Config.Wars.captureScorenumber5.0Score per objective capture, awarded to every member standing on the point. Range 0–500
Config.Wars.killRepeatCooldownSecondsnumber180Killing the same victim again inside this many seconds scores nothing. This is what stops two friends trading kills. Range 0–3600
Config.Wars.killMaxDistancenumber300.0Kills where the killer and victim are further apart than this are rejected. 0 turns the check off. Range 0–2000, in metres

Capture objectives

SettingTypeDefaultDescription
Config.Wars.objectives.enabledbooleantrueWhether capture points spawn during wars
Config.Wars.objectives.intervalMinutesnumber20Minutes between the war starting (or the last point ending) and the next point spawning. Range 1–240
Config.Wars.objectives.durationMinutesnumber10Minutes an uncaptured point stays up. Range 1–60
Config.Wars.objectives.radiusnumber25.0Size of the capture circle, in metres. Range 5–200
Config.Wars.objectives.holdSecondsnumber60Seconds of uncontested holding needed to capture. Range 5–600
Config.Wars.objectives.tickSecondsnumber2How often the server checks who is standing on the point, in seconds
Config.Wars.objectives.bliptable{ sprite = 378, color = 1, scale = 0.9 }The flashing map blip a live capture point shows to the warring gangs
shared/config.lua
Config.Wars = {
    enabled              = true,
    durationHours        = 24,     -- frozen per war at accept
    pendingExpiryHours   = 24,     -- unanswered declarations lapse
    rematchCooldownHours = 48,     -- between the same two gangs, either direction
    maxStake             = 1000000, -- per side; 0 = unlimited (stake 0 is always allowed)
    killScore            = 1.0,    -- contribution per validated kill
    captureScore         = 5.0,    -- contribution per objective capture, per member present
    killRepeatCooldownSeconds = 180, -- repeat kills on the same victim score nothing
    killMaxDistance      = 300.0,  -- server-side plausibility gate on kill reports (0 = off)
    objectives = {
        enabled         = true,
        intervalMinutes = 20,      -- between war start / last objective and the next spawn
        durationMinutes = 10,      -- how long a point stays up unclaimed
        radius          = 25.0,
        holdSeconds     = 60,      -- uncontested hold required to capture
        tickSeconds     = 2,       -- presence scan cadence while a point is live
        blip            = { sprite = 378, color = 1, scale = 0.9 },
    },
}

War Police Alerts

Settings panel: World → Wars → Police alerts (marked Advanced)

SettingTypeDefaultDescription
Config.WarDispatch.enabledbooleantrueSend these alerts at all
Config.WarDispatch.jobstable{ 'police', 'sheriff' }Which job names receive the alert
Config.WarDispatch.codestring'10-99'The radio code shown on the alert
Config.WarDispatch.prioritynumber3Alert priority, 1 (highest) to 5
Config.WarDispatch.iconstring'fa-gun'The Font Awesome icon name shown on the alert
Config.WarDispatch.declaredTitlestring'Gang War'Title when a war goes active
Config.WarDispatch.declaredMessagestring'Word on the street: %s and %s are at war'Body for a war start. The two %s are replaced with the attacking and defending gang names
Config.WarDispatch.objectiveTitlestring'Gang Shootout'Title when a capture point spawns
Config.WarDispatch.objectiveMessagestring'Armed gang activity reported in %s'Body for a capture point. %s is replaced with the zone's name
Config.WarDispatch.blipDatatable{ sprite = 378, color = 1, scale = 1.0, duration = 60 }The map marker dropped for responders

War-start alerts are anchored on the defender's base. If the defending gang has no base, the alert is skipped rather than dropped at the wrong place on the map.

shared/config.lua
Config.WarDispatch = {
    enabled  = true,
    jobs     = { 'police', 'sheriff' },
    code     = '10-99',
    priority = 3,
    icon     = 'fa-gun',
    declaredTitle    = 'Gang War',
    declaredMessage  = 'Word on the street: %s and %s are at war',
    objectiveTitle   = 'Gang Shootout',
    objectiveMessage = 'Armed gang activity reported in %s',
    blipData = { sprite = 378, color = 1, scale = 1.0, duration = 60 },
}

Radio

Settings panel: World → Radio

A private radio channel per gang. This only does anything if you also run oxide-radio — without it, nothing is registered and these settings are ignored.

SettingTypeDefaultDescription
Config.Radio.enabledbooleantrueGive every gang its own private channel
Config.Radio.frequencyBasenumber900A gang's channel number is this plus its gang ID, so gang #1 lands on 901. Pick a range clear of your job channels. Range 1–90000
Config.Radio.minRanknumber0Lowest gang rank allowed on the channel. 0 = every member. Range 0–100
Config.Radio.autoJoinbooleantrueTune members to their gang channel when they log in or join the gang. Auto-tune must also be switched on in oxide-radio's own settings

Gang channels are restricted channels, so they are allowed to sit outside oxide-radio's open civilian dial range. If another resource already holds a frequency a gang would land on, that gang's channel is skipped and a warning naming the clash is written to your server console.

shared/config.lua
Config.Radio = {
    enabled       = true,
    frequencyBase = 900,     -- gang channel = this + gang id; keep clear of job channels
    minRank       = 0,       -- lowest gang rank allowed on the channel (0 = every member)
    autoJoin      = true,    -- tune members in at login/gang join (needs radio auto-tune on too)
}

Logs

Settings panel: System → Logs (marked Advanced)

SettingTypeDefaultDescription
Config.Logs.retentionDaysnumber30Days gang activity logs are kept before being deleted. 0 = keep forever. Range 0–365. The cleanup runs at boot and then every six hours
Config.Logs.transactionLogLimitnumber100How many recent treasury transactions the dashboard shows. Range 10–500
shared/config.lua
Config.Logs = {
    retentionDays       = 30,
    transactionLogLimit = 100,
}

File-Only Settings

These two are not in the settings panel and are not stored in the database. They stay in their files, and the file is always what is read.

Default rank ladder

Config.DefaultGrades in shared/config/grades.lua is the rank ladder given to a newly created gang. It is a template, applied once at creation. Existing gangs manage their own ranks from the dashboard, so editing this file never changes a gang that already exists.

Each entry needs:

FieldTypeDescription
ranknumberThe rank number. Higher is more senior. Must be 0–100 and unique within the ladder
namestringThe internal name, lowercase. Used by other scripts
labelstringWhat players see
isBossbooleanA boss rank holds every permission automatically. At least one rank must be a boss rank
permissionstableWhich of the twelve permissions this rank gets. Ignored on a boss rank

The twelve permissions are: invite, kick, promote, demote, manage_ranks, withdraw, deposit, stash, garage, war, announce, edit_gang.

shared/config/grades.lua
Config.DefaultGrades = {
    {
        rank = 0, name = 'member', label = 'Member', isBoss = false,
        permissions = { deposit = true, stash = true },
    },
    {
        rank = 1, name = 'enforcer', label = 'Enforcer', isBoss = false,
        permissions = { deposit = true, stash = true, garage = true, invite = true },
    },
    {
        rank = 2, name = 'underboss', label = 'Underboss', isBoss = false,
        permissions = {
            deposit = true, stash = true, garage = true, invite = true,
            kick = true, promote = true, demote = true, withdraw = true,
            war = true, announce = true,
        },
    },
    {
        rank = 3, name = 'boss', label = 'Boss', isBoss = true,
        permissions = {},
    },
}

Shipped territory map

Config.DefaultTerritories in shared/config/territories.lua is the starting map: 34 Los Santos districts, each with its polygon, colour, blip settings, and economy modifiers.

It is read once, the first time the resource starts against an empty territory table. After that your drawn map is authoritative and this file is never read again — the shipped map cannot come back and overwrite your edits, and a district you delete stays deleted.

To change the map, use /gangs admin → Territories. To start over from the shipped map, empty the gang_territories table in your database and restart the resource.

Each district's modifiers are the four multipliers the Oxide drug resources read. 1 is neutral, 1.15 is +15%, 0.9 is −10%:

ModifierAffects
yieldHow much product an operation produces in that zone
growthHow fast plants grow in that zone
priceWhat dealers pay in that zone
buyerDensityHow many buyers turn up in that zone
shared/config/territories.lua
Config.DefaultTerritories = {
    {
        name = 'textile_city', label = 'Textile City', color = '#e21db7',
        blip = { enabled = false, sprite = 500, color = 0, scale = 0.8 },
        modifiers = { yield = 1.05, growth = 1.05, price = 1.05, buyerDensity = 1.05 },
        polygon = { points = {
            { x = 359.52, y = -672.72 }, { x = 262.89, y = -958.86 },
            { x = 500.25, y = -956.05 }, { x = 511.45, y = -672.72 },
        } },
    },
    -- ... 33 more districts
}

Next Steps

  • Features — what each of these settings actually changes in game
  • Admin — commands and the admin panel
  • Troubleshooting — when a setting does not seem to be taking effect