Skip to content

Configuration

Configuration is split across configs/, scoped by folder. configs/shared/ is read by both the client and the server, configs/client/ is client-only, and configs/server/ is excluded from the manifest's files{} so it never reaches a client.

Why the split matters

Drop coordinates, the radio-mast pool, the prop-to-item loot map and the whole fence economy live in configs/server/. Moving any of them into a shared file would make them dumpable by a client.

Root

configs/config.lua

lua
Locale = 'en',
Debug = true,
DebugPrints = false,
KeyTypeDefaultDescription
Localestring'en'Loads locales/<Locale>.json, falling back to English per key
DebugbooleantrueDeveloper logging and target zone outlines
DebugPrintsbooleanfalseVery verbose per-call prints from the framework, inventory and target bridge
DebugCategoriestablecommented outFilters bridge prints by tag, e.g. { ['bridge:inventory'] = true }

DANGER

Debug ships as true. Set it to false on a production server.

Intrusion

configs/shared/trigger.lua

This is the block that defines the co-op shape of the heist.

lua
Intrusion = {
    Flush = 300,
    Required = 2,
    Defenses = 2,
    Cooldown = 30,
    CoopBreach = false,
    TriangulateWindow = 15,
    Triangulate = 8,
},
KeyTypeDefaultDescription
Flushnumber300Seconds from the first intrusion before the network flushes everyone off the towers. One shared window for the whole crew
Requirednumber2Relays that must be fully breached inside that window to call a drop
Defensesnumber2Defence layers to crack per relay. Each layer is one successful daemon run
Cooldownnumber30Seconds a daemon is benched after a failed run before the same player can retry it
CoopBreachbooleanfalsetrue lets several players pool progress on the same relay. false means one intruder per relay
TriangulateWindownumber15Seconds for the whole crew to run calldrop together
Triangulatenumber8Duration of the shared triangulation bar. Closing the terminal aborts it for everyone

Tuning for your playerbase

Required and CoopBreach are the two dials that set crew size. Leaving CoopBreach off and raising Required to 3 means three players in three different places. Setting CoopBreach = true lets a smaller crew share a mast, and Required = 1 makes the heist soloable.

Masts

lua
Prop = 'prop_radiomast02',
SpawnDistance = 500.0,
Blip = { enabled = true, sprite = 866, color = 1, scale = 0.8, shortRange = true, display = 4, alpha = 255 },
KeyTypeDefaultDescription
Propstring'prop_radiomast02'Mast prop spawned at each tower
SpawnDistancenumber500.0Metres at which a mast streams in, so the whole set never loads at once
Blip.enabledbooleantrueMaster switch for mast blips
Blip.shortRangebooleantruefalse makes masts visible across the whole map

The candidate tower positions themselves are server-only, in configs/server/trigger.lua.

USB Kits

lua
Tablet = {
    StashSlots = 8,
    StashWeight = 4000,
    USBHacks = {
        deaddrop_usb_1 = { 'maze', 'cipher' },
        deaddrop_usb_2 = { 'capture', 'typing' },
        deaddrop_usb_3 = { 'evasion', 'signal', 'pipe' },
        deaddrop_usb_4 = { 'snake', 'firewall', 'breakout' },
    },
    Durability = {
        Hack = { Enabled = true, Cost = 10 },
        Practice = { Enabled = true, Cost = 5 },
        RemoveAtZero = false,
    },
},
KeyTypeDefaultDescription
StashSlotsnumber8Slots in the tablet's USB storage
StashWeightnumber4000Capacity of that stash in grams
USBHackstable4 kitsWhich daemon modules each USB item provides while inserted
Durability.Hack.Costnumber10Durability spent per daemon run against a relay
Durability.Practice.Costnumber5Durability spent per practice run
Durability.RemoveAtZerobooleanfalsetrue deletes a stick worn to 0 instead of leaving it fried in the stash

Keep item descriptions in sync

Which daemons a USB provides is config, not a property of the item. If you retune USBHacks, update the matching item description in your inventory so players are not told the wrong thing.

Proof of Play

lua
Proof = {
    MinFloor = 3.0,
    Grace = 2.0,
    Safety = 0.85,
},
KeyTypeDefaultDescription
MinFloornumber3.0No daemon is ever accepted faster than this, whatever the per-game floor works out to
Gracenumber2.0Survival games use timeLimit - Grace as their floor
Safetynumber0.85Throughput floors are multiplied by this, so lag never rejects a genuine run

Per-game tuning keys sit under the same block. The floors are derived from each minigame's own difficulty settings, so raising a minigame's difficulty raises its floor automatically.

Event Pacing

configs/shared/event.lua

lua
PublicDropIntel = false,
Containers = { Min = 2, Max = 3, MinDistance = 500 },
Phases = {
    LeadSeconds = 200,
    FlightSeconds = 120,
    DropSeconds = 110,
    SettleSeconds = 15,
    ResolveSeconds = 8,
},
KeyTypeDefaultDescription
PublicDropIntelbooleanfalsefalse marks the search area only for the triggering crew and snitch buyers. true marks it for everyone
Containers.Min / Maxnumber2 / 3Containers per drop, rolled between the two
Containers.MinDistancenumber500Minimum metres between any two landing spots
Phases.LeadSecondsnumber200Seconds from the signal going out to the plane launching
Phases.FlightSecondsnumber120Corridor flight time to the drop point
Phases.DropSecondsnumber110Package glide time. Fall speed follows from this and the drop altitude
Phases.SettleSecondsnumber15Dwell on the ground before the contest clock arms. Breaching is already allowed
ContestSecondsnumber1200Maximum contested lifetime before the event abandons itself
CooldownMinutesnumber30Global lockout after a resolve. Relays report "high security" until it elapses

Breach

lua
Breach = {
    BreachTime = 10000,
    RequiredItem = 'powersaw',
    RequiredItemLabel = 'Power Saw',
    NameRequiredItem = false,
    Wear = { Mode = 'durability', Durability = 10, BreakChance = 0.33, RemoveAtZero = false },
},
KeyTypeDefaultDescription
BreachTimenumber10000Milliseconds the breach scene runs. Matches the animation length
RequiredItemstring'powersaw'Tool required to breach, re-checked server-side. false requires no tool
NameRequiredItembooleanfalsetrue names the item in the refusal message
Wear.Modestring'durability'One of 'off', 'durability', 'remove', 'chance'
Wear.Durabilitynumber10Durability points docked per breach in 'durability' mode
Wear.BreakChancenumber0.33Odds the tool breaks in 'chance' mode

WARNING

Do not change BreachTime unless you are also changing the animation. The value matches the clip length.

The Drop

configs/shared/world.lua

lua
Drop = {
    Altitude = 700.0,
    RenderDistance = 1000.0,
    Release = { Behind = 8.0, Below = 4.0, Lead = 250.0 },
    Sway = { Amplitude = 4.0, Speed = 700.0 },
    Chute = { Count = 1, Height = 6.0, CutHeight = 5.0, FadeMs = 800 },
},
Wind = { Speed = 6.0, DriftScale = 1.0 },
KeyTypeDefaultDescription
Drop.Altitudenumber700.0Metres the plane cruises at, which is the height packages drop from
Drop.RenderDistancenumber1000.0Packages inside this range animate per frame. Beyond it they step every 250 ms
Release.Leadnumber250.0Metres before its landing point a package releases, so it glides in on a diagonal. 0 releases directly overhead
Sway.Amplitudenumber4.0Maximum pendulum tilt in degrees. 0 disables sway
Chute.Countnumber1Canopies per container
Chute.CutHeightnumber5.0Metres above ground the canopies are cut free
Wind.Speednumber6.0Horizontal drift in m/s during descent. 0 falls straight down

Drop Intel

lua
DropBlip = { radius = 250.0, offset = 110.0, color = 1, alpha = 80 },
KeyTypeDefaultDescription
radiusnumber250.0Minimum search-circle radius, grown to enclose a wide cluster
offsetnumber110.0How far off-centre the circle sits from the real cluster

TIP

The offset is deliberate. It marks an area to search rather than pinpointing the crates.

Flight corridors and the curated landing spots are server-only, in configs/server/world.lua.

Containers and Carry

configs/shared/containers.lua

lua
Carry = {
    Enabled = true,
    OneAtATime = true,
    Props = { ['deaddrop_item_1'] = 'prop_mil_crate_01', ... },
},
KeyTypeDefaultDescription
Carry.Enabledbooleantruefalse disables the held prop, the animation and the control lock
Carry.OneAtATimebooleantrueAt most one carry item per player. Handing a crate to someone else is still allowed
Carry.Propstable12 entriesMaps each loot item to the prop held in the hands
Carry.Offsetstableper propPer-prop attachment overrides, tuned in-game with /deaddrop_carrytune

WARNING

If you turn OneAtATime off, turn Enabled off too. Several held crates would still visibly haul only one, which reads wrong.

Layouts in the same file holds the cosmetic interior prop sets, one picked per container. Capture new ones in-game with /deaddrop_loadout.

Contact

configs/shared/contact.lua holds the display and the on/off switches. The economy is server-only in configs/server/contact.lua.

lua
PedModel = 's_m_y_dealer_01',
GreetSpeech = 'GENERIC_HI',
Scenario = 'PROP_HUMAN_SEAT_CHAIR',
SpawnDistance = 50.0,
KeyTypeDefaultDescription
PedModelstring's_m_y_dealer_01'Contact ped model
Scenariostring'PROP_HUMAN_SEAT_CHAIR'Ambient scenario. false stands him frozen
SpawnDistancenumber50.0Metres at which the ped streams in
Buy.EnabledbooleantrueWhether the contact sells gear
Selling.Enabledbooleantruefalse hides every sell option and the backend refuses the callbacks
Selling.Trunk.EnabledbooleantrueSell a parked vehicle's whole trunk in one deal. ox_inventory only
Snitch.EnabledbooleantrueWhether drop locations can be bought
Notify.EnabledbooleantrueWhether drop-alert subscriptions can be bought
Reputation.RewardsbooleantrueMaster switch for one-time level-up rewards

Economy

configs/server/contact.lua

KeyDefaultDescription
PayoutType'clean''clean' credits an account, 'dirty' pays an item
CleanAccount'cash'Account credited when paying clean
ClaimDistance5.0Metres the player must be within for buy, snitch, notify and reward claims
Heat.Max100The heat scale items are stamped on
Heat.Floor0.25Never sell below this fraction of base value, however hot
Snitch.MinLevel3Reputation level required to buy drop intel
Snitch.Fee5000Flat fee per successful snitch
Notify.MinLevel3Reputation level required to subscribe to drop alerts
Notify.Fee10000One-time subscription fee
Buy.Account'bank'Account gear purchases come from

Sellables sets the price and XP of every sellable item, Levels is the five-rung reputation ladder with its XP thresholds and reward items, and Catalog is the gear list with its per-item level gates.

Wiring drop alerts to your phone

Notify.OnDrop is a server-side hook called for every subscriber when a drop is called. Point it at your phone resource to deliver the ping however you like.

Heat

configs/server/heat.lua

lua
Decay = { Amount = 10, Every = 300 },
StartingHeat = { Default = 60, Items = {} },
KeyTypeDefaultDescription
Decay.Amountnumber10Heat points removed per interval while the item is held
Decay.Everynumber300Seconds per decay tick. Either value at 0 disables decay
StartingHeat.Defaultnumber60Heat stamped on any item without its own entry
StartingHeat.ItemstableemptyPer-item overrides

Police and Rivals

configs/shared/pressure.lua

Police Response

lua
Police = {
    Enabled = true,
    MinCops = 0,
    DispatchEvent = 'sd-deaddrop:police:alert',
    Title = 'Containers being breached',
    Blip = { sprite = 161, color = 1, scale = 1.1, time = 300 },
},
KeyTypeDefaultDescription
EnabledbooleantrueFires once when a container is first breached
MinCopsnumber00 always alerts, leaving cop counting to your dispatch
DispatchEventstringsee aboveServer event fired with { coords, title }. Bridge it to your dispatch, or set false to skip

A broadcast map blip is drawn regardless of the dispatch event.

Rival Crew

lua
Rivals = {
    Enabled = false,
    Min = 4,
    Max = 6,
    Radius = 120.0,
    MinPlayerDistance = 100.0,
    Loot = { Enabled = true },
},
KeyTypeDefaultDescription
EnabledbooleanfalseSpawns a Merryweather recovery crew when the first container is breached
Min / Maxnumber4 / 6Rivals per drop, rolled between the two
Radiusnumber120.0Spawn scatter around the breached container
MinPlayerDistancenumber100.0Never spawn within this of any player
Loot.EnabledbooleantrueWhether dead rivals can be searched

WARNING

Keep Radius above MinPlayerDistance, or no spawn point can ever qualify.

Archetypes defines each rival type with its weight, model, weapon, health, armour, accuracy and combat ability. criticalHits = false prevents one-shot headshots while letting headshots land as normal damage.

Minigames

configs/client/minigame.lua exposes every difficulty knob for all ten daemons. Keys match the module names shown by the terminal's games command.

ModuleDaemonMain difficulty levers
mazenet-maze.exewidth, height, visibility, dataNodes, timeLimit
capturenode-grab.exegridSize, nodeDuration, capturesRequired, maxMisses
ciphercipher-lock.exetimeLimit, speed, spawnRate, playerLives
snakedata-worm.exenodesRequired, initialSpeed, grid size
firewallfw-defense.exerows, cols, waves, fireRate, shootCooldown
evasionhighway-evade.exetimeLimit, speed, spawnRate, roadWidth
typingcode-inject.exestringLength, timePerString, stringsRequired
signalsig-replay.exesequenceLength, startLength, flashSpeed, inputWindow
pipepipe-route.exegridWidth, gridHeight, timeLimit, rounds
breakoutice-break.exerows, cols, ballSpeed, paddleWidth

Difficulty and anti-cheat move together

Proof-of-play floors are derived from these values, so raising a minigame's difficulty raises its accepted minimum completion time automatically. You do not need to retune the anti-cheat by hand.

Terminal

configs/client/terminal.lua

KeyTypeDefaultDescription
WatermarkbooleantrueFaded monogram behind the console text. false gives a plain background
Banner.colorstring'#f14c4c'Any CSS colour for the ASCII boot banner
Banner.linestableASCII artDrawn top to bottom. Keep every line the same character width. Banner = false disables it

Audit Logging

configs/server/logs.lua

lua
Enabled = true,
Events = { event_start = true, breach = true, loot = true, fence_sell = true, ... },

Logging is routed through ox_lib's logger, so the backend is whatever your ox:logger convar points at. Enabled = false disables all of it, and each event has its own switch. A missing key counts as on.

Notable events include suspect for server-side rejects that look like exploit attempts, usb_fried, defense_knock and admin_command.

Loot

configs/server/loot.lua holds the reveal-grid pools, grid sizes and reward tables. configs/server/containers.lua maps each prop model to the item it yields when looted, with DefaultItem as the fallback.

Entries accept three forms:

lua
['prop_gold_bar'] = 'goldbar',
['prop_cash_case_01'] = { item = 'black_money', min = 10000, max = 15000 },
['prop_mil_crate_01'] = { item = 'deaddrop_item_1', count = 1 },

WARNING

Keep the deaddrop_item_* carry crates at a plain 1x entry. Carry.OneAtATime expects a single crate per grab.