Skip to content

Configuration

All configuration for sd-selling is managed in config.lua located in the root of the resource folder. Logging is configured separately in server/logs.lua.

General Settings

lua
Config.Debug = false
SD.Locale.LoadLocale('en')
Config.PoliceJobs = { 'police', --[['sheriff']] }
Config.EnableLevels = true
Config.DisplayLevel = true
Config.EnableZones = true
Config.EnableMetadata = true
Config.EnableLaundering = false
Config.RetrieveCopsTime = 15
KeyTypeDefaultDescription
Config.DebugbooleanfalseEnable debug mode. Note: debug points for zones may appear slightly larger than the actual area.
SD.Locale.LoadLocalestring'en'Language locale to load. Change 'en' to any language file available in the locales folder.
Config.PoliceJobstable{ 'police' }Array of job names counted when checking the current number of on-duty police.
Config.EnableLevelsbooleantrueEnable the reputation / level system. Highly recommended to keep enabled for the best experience.
Config.DisplayLevelbooleantrueShow the player's current level in the reputation context menu.
Config.EnableZonesbooleantrueEnable zone-based selling. When false, the settings from Config.Zones[1] apply globally to all peds.
Config.EnableMetadatabooleantrueEnable ox_inventory metadata support so items with specific metadata (e.g., different weed strains) can be sold.
Config.EnableLaunderingbooleanfalseEnable the money laundering feature.
Config.RetrieveCopsTimenumber15Interval in minutes for the server to broadcast the current cop count to all connected players.

Payout Type

lua
Config.Payout = { Type = 'dirty', DirtyType = 'standard' }
Config.DirtyMoney = 'black_money'
KeyTypeDefaultDescription
Config.Payout.Typestring'dirty'Payout mode: 'dirty' or 'clean'. This applies only to deliveries and encounters, not regular drug sales (unless Config.EnableLevels is false).
Config.Payout.DirtyTypestring'standard'How dirty money is handled. 'standard' uses a 1-to-1 ratio.
Config.DirtyMoneystring'black_money'The item name used for 1-to-1 dirty money transactions when DirtyType is set to '1-1' in level settings.

INFO

Regular drug sale payouts are configured per-level inside Config.Levels. The Config.Payout table only governs deliveries and encounters.

Target Stand-Still

lua
Config.TargetStandStill = {
    Enable   = true,
    Duration = 4000,
}
KeyTypeDefaultDescription
EnablebooleantrueWhether targeting a ped forces them to stand still. Helpful when peds walk away while you are trying to interact.
Durationnumber4000How long (in milliseconds) the ped remains standing still after being targeted.

Selling Zones

Zones define where players can sell drugs. Each zone supports either a radius-based area (single coordinate + size) or a polygon-based area (array of corner-points).

TIP

When Config.EnableZones is false, the drug list and settings from Config.Zones[1] apply globally to every ped.

lua
Config.Zones = {
    [1] = {
        Coords = {x = 37.37, y = -1883.42, z = 22.44},
        -- Or, for a polygonal zone, supply an array of corner-points:
        --[[
        Coords = {
            { x = 42.67, y = -1388.19, z = 70.02 },
            { x = 532.56, y = -1790.96, z = 71.7 },
            { x = 273.98, y = -2292.74, z = 66.96 },
            { x = -255.44, y = -1761.41, z = 100.89 },
        },
        ]]
        Size = 250.0,
        PoliceRequirement = {Enable = false, Amount = 1},
        Cooldown = { Enable = true, Period = { Hour = 1, Min = 0 }, Max = 250 },
        LevelRestrict = { Enable = false, Level = 1 },
        Blip = {
            Enable = false,
            Name = 'Drug Selling Zone',
            Sprite = 51,
            Scale = 0.8,
            Colour = 1,
            Radius = {Enable = true, Colour = 1},
        },
        Drugs = {
            ['cokebaggy'] = {
                Label = "Cocaine",
                Icon = "fas fa-capsules",
                Price = {Randomize = true, Base = 100, Min = 80, Max = 120},
                Quantity = {Randomize = true, Base = 10, Min = 5, Max = 15},
                LevelRestrict = { Enable = false, Level = 1 },
            },
            -- more drugs...
        },
    },
}

Zone Settings

KeyTypeDefault (Zone 1)Description
Coordsvector / table{x=37.37, y=-1883.42, z=22.44}Center point for a radius zone, or an array of {x, y, z} points for a polygon zone.
Sizenumber250.0Radius of the zone (only used when Coords is a single point).
PoliceRequirement.EnablebooleanfalseWhether a minimum number of police must be online to sell in this zone.
PoliceRequirement.Amountnumber1Number of police required when enabled.
Cooldown.EnablebooleantrueEnable a per-player cooldown for this zone.
Cooldown.Periodtable{ Hour = 1, Min = 0 }Cooldown duration.
Cooldown.Maxnumber250Maximum number of sales allowed per cooldown period.
LevelRestrict.EnablebooleanfalseRestrict zone access by player level.
LevelRestrict.Levelnumber1Minimum level required when restriction is enabled.

Zone Blip Settings

KeyTypeDefaultDescription
Blip.EnablebooleanfalseWhether a map blip is shown for this zone. Polygon zones do not display a blip.
Blip.Namestring'Drug Selling Zone'Name displayed on the blip.
Blip.Spritenumber51Blip sprite icon ID.
Blip.Scalenumber0.8Blip scale on the map.
Blip.Colournumber1Blip colour ID.
Blip.Radius.EnablebooleantrueShow a radius circle around the blip.
Blip.Radius.Colournumber1Colour of the radius circle.

Zone Drug Entry

KeyTypeExampleDescription
Labelstring"Cocaine"Display name of the drug.
Iconstring"fas fa-capsules"FontAwesome icon class.
Price.RandomizebooleantrueRandomize the price between Min and Max, or use Base as a fixed price.
Price.Basenumber100Fixed price when Randomize is false.
Price.Min / Price.Maxnumber80 / 120Range for randomized pricing.
Quantity.RandomizebooleantrueRandomize the quantity the NPC wants to buy.
Quantity.Basenumber10Fixed quantity when Randomize is false.
Quantity.Min / Quantity.Maxnumber5 / 15Range for randomized quantity.
LevelRestrict.EnablebooleanfalseRestrict this specific drug to a minimum level.
LevelRestrict.Levelnumber1Minimum level required to sell this drug.

Metadata Variants

When Config.EnableMetadata is true, each drug entry can optionally include a MetadataVariants sub-table and a SellBaseItem boolean. This allows selling items with specific ox_inventory metadata (e.g., purity levels, batch identifiers) at different prices and quantities. See the commented examples in the config for cocaine and oxycodone.

Default Zones

The config ships with three example zones:

ZoneCenter CoordsSizePolice RequiredCooldownMax SalesLevel RequiredDrugs
137.37, -1883.42, 22.44250.0No1h / 250250NoCocaine, Crack, Ecstasy, Oxycodone
2284.0, 162.0, 104.0250.0No1h / 100100NoMeth, White Widow, Skunk, Purple Haze
3-1664.0, -1066.0, 18.0150.0Yes (1)1h / 5050Yes (1)OG Kush, Amnesia, AK-47, Ecstasy

Level System

The level system controls XP progression, selling hours, price multipliers, risk chances, payout types, money washing, taxes, and cooldowns. There are 5 levels by default.

WARNING

It is highly recommended to keep Config.EnableLevels = true. When disabled, some Level 1 settings apply globally, but many features lose their progression mechanics.

lua
Config.Levels = {
    {
        Level = 1,
        XPThreshold = 250,
        XPPerSale = 10,
        Multiplier = 1.0,
        PoliceNotify = {Enable = true, Chance = 30},
        Robbery = {Enable = false, Chance = 33},
        Rejection = {Enable = true, Chance = 25, PoliceNotify = {Enable = true, Chance = 25}},
        TimeRequirement = {Enable = true, AllowedTime = {From = 21, To = 2}},
        Encounter = { Enable = true, Chance = 2, Quantity = { Min = 25, Max = 40 } },
        MoneyType = { Type = 'clean', DirtyType = 'standard' },
        Washing = { Enable = true, Bills = { min = 750, max = 2000, chance = 10 }, Bands = { min = 750, max = 2000, chance = 15 }, Rolls = { min = 250, max = 750, chance = 20 } },
        Tax = { Enable = true, Percentage = 25 },
        Cooldown = { Enable = true, Period = { Hour = 1, Min = 0 }, Max = 10 },
    },
    -- Levels 2 through 5 follow the same structure...
}

All Five Levels at a Glance

SettingLevel 1Level 2Level 3Level 4Level 5
XP Threshold2501000200035001500*
XP Per Sale1020304050
Price Multiplier1.01.11.21.31.4
Selling Hours21:00 - 02:0020:00 - 04:0019:00 - 05:0018:00 - 06:0017:00 - 07:00
Police Alert Chance30%25%20%8%10%
Rejection Chance25%22%20%13%5%
Rejection Police Chance25%20%15%10%5%
Robbery EnabledNoYesYesYesYes
Robbery Chance33%15%13%20%3%
Encounter Chance2%3%4%5%6%
Encounter Quantity25 - 4025 - 4025 - 4025 - 4025 - 40
Money Typecleancleancleancleanclean
Dirty Typestandardstandardstandardstandardstandard
Money Tax25%15%15%10%5%
Cooldown1h / 10 max1h / 20 max1h / 40 max30m / 60 maxDisabled / 50 max

*Level 5's XPThreshold of 1500 is effectively ignored since there is no Level 6 by default. Add additional levels if desired.

Level Setting Details

KeyTypeDescription
LevelnumberThe level number.
XPThresholdnumberXP required to advance to the next level.
XPPerSalenumberXP earned per successful sale at this level.
MultipliernumberPrice multiplier applied to all sales at this level.
PoliceNotify.EnablebooleanWhether police can be alerted on a sale.
PoliceNotify.ChancenumberPercentage chance of a police alert per sale.
Robbery.EnablebooleanWhether the player can be robbed during a sale.
Robbery.ChancenumberPercentage chance of being robbed.
Rejection.EnablebooleanWhether the NPC can reject a sale.
Rejection.ChancenumberPercentage chance of rejection.
Rejection.PoliceNotify.EnablebooleanWhether police can be alerted on a rejection.
Rejection.PoliceNotify.ChancenumberPercentage chance of police alert on rejection.
TimeRequirement.EnablebooleanWhether selling is restricted to specific in-game hours.
TimeRequirement.AllowedTime.FromnumberStarting hour (24h format).
TimeRequirement.AllowedTime.TonumberEnding hour (24h format).
Encounter.EnablebooleanWhether random encounter/meetup events can trigger.
Encounter.ChancenumberPercentage chance per sale of triggering an encounter.
Encounter.Quantity.Min / MaxnumberRange of drug quantity exchanged in an encounter.
MoneyType.Typestring'clean' or 'dirty' -- type of money the player receives from sales.
MoneyType.DirtyTypestring'standard' uses framework defaults (e.g., markedbills on qb-core, black_money account on es_extended). '1-1' uses Config.DirtyMoney item at a 1:1 ratio.
Tax.EnablebooleanWhether a tax is applied to money washing payouts.
Tax.PercentagenumberTax percentage deducted from washed money.
Cooldown.EnablebooleanWhether a sale cooldown is active at this level.
Cooldown.Periodtable{ Hour, Min } -- cooldown duration.
Cooldown.MaxnumberMaximum number of sales allowed per cooldown period.

Money Washing (Per-Level)

Each level includes a Washing table that controls the chance and value of receiving laundered money items after a sale.

lua
Washing = {
    Enable = true,
    Bills = { min = 750, max = 2000, chance = 10 },
    Bands = { min = 750, max = 2000, chance = 15 },
    Rolls = { min = 250, max = 750, chance = 20 },
},
KeyTypeDescription
Washing.EnablebooleanEnable money washing rewards at this level.
Washing.Bills.min / maxnumberValue range for markedbills. On qb-core, if metadata is present it overrides these values.
Washing.Bills.chancenumberPercentage chance of receiving bills.
Washing.Bands.min / maxnumberValue range for bands.
Washing.Bands.chancenumberPercentage chance of receiving bands.
Washing.Rolls.min / maxnumberValue range for rolls.
Washing.Rolls.chancenumberPercentage chance of receiving rolls.

Default washing chances by level:

ItemLevel 1Level 2Level 3Level 4Level 5
Bills (750-2000)10%12%15%20%23%
Bands (750-2000)15%17%24%26%28%
Rolls (250-750)20%22%28%30%40%

Robbery Cooldown

lua
Config.RobberyCooldown = { Enable = true, Period = { Hour = 0, Min = 5 } }
KeyTypeDefaultDescription
EnablebooleantrueEnable a cooldown between robberies so the same player is not robbed repeatedly.
Period.Hournumber0Hours portion of the cooldown.
Period.Minnumber5Minutes portion of the cooldown.

Encounters

Encounters are special bulk-sale meetup events that can trigger randomly after a regular sale.

lua
Config.Encounters = {
    XPPerEncounter = 100,
    Cooldown = { Enable = true, Period = { Hour = 0, Min = 30 } },
    Locations = {
        { x = -471.2451, y = -936.0005, z = 22.59847, w = 87.16846 },
        -- 17 locations total...
    }
}
KeyTypeDefaultDescription
XPPerEncounternumber100XP awarded for completing an encounter.
Cooldown.EnablebooleantrueEnable a cooldown between potential encounters.
Cooldown.Periodtable{ Hour = 0, Min = 30 }Cooldown duration (30 minutes by default).
Locationstable17 coordinatesList of {x, y, z, w} positions where encounter NPCs can spawn. Add or remove entries as needed.

INFO

The per-level Encounter.Chance setting in Config.Levels determines how likely an encounter is to trigger after any given sale. The Config.Encounters table only controls XP, cooldown, and spawn locations.

Delivery Missions

Deliveries are route-based missions with three tiers: Small, Medium, and Large. Players pick a drug and a route, then complete stops along the way.

lua
Config.Delivery = {
    Level = { Enable = false, Level = 3 },
    DisplayLevel = true,
    Small  = { ... },
    Medium = { ... },
    Large  = { ... },
    Drugs  = { ... },
}

Delivery General Settings

KeyTypeDefaultDescription
Level.EnablebooleanfalseRequire a minimum level to access deliveries.
Level.Levelnumber3The minimum level required when enabled.
DisplayLevelbooleantrueShow the player's level in the delivery menu.

Delivery Tiers

SettingSmallMediumLarge
XP Per Stop202530
Drug Quantity50125250
Processing Time5 minutes5 minutes5 minutes
Route Count333
Route 1 Stops4-6 (0% boost)5-7 (0% boost)8-9 (0% boost)
Route 2 Stops7-8 (15% boost)8-9 (10% boost)9-10 (10% boost)
Route 3 Stops9-11 (20% boost)10-12 (20% boost)11-13 (20% boost)
Location Count766676

TIP

Longer routes provide a percentage boost on top of the base drug price, rewarding players who choose the harder path. The number of stops is randomized within the range shown.

Delivery Tier Structure

lua
Small = {
    XPPerStop = 20,
    Quantity = 50,
    ProcessingTime = { Enable = true, Period = { Hour = 0, Min = 5 } },
    Routes = {
        {Stops = math.random(4, 6), Boost = 0.0},
        {Stops = math.random(7, 8), Boost = 0.15},
        {Stops = math.random(9, 11), Boost = 0.20},
    },
    RouteCount = 3,
    Locations = { ... },
},
KeyTypeDescription
XPPerStopnumberXP earned for completing each delivery stop.
QuantitynumberNumber of drug units required per delivery.
ProcessingTime.EnablebooleanWhether a processing delay is required before starting.
ProcessingTime.Periodtable{ Hour, Min } -- the processing wait time.
RoutestableArray of route options. Each has Stops (randomized count) and Boost (price multiplier bonus).
RouteCountnumberNumber of routes offered to the player. If less than the routes table, a random subset is selected.
LocationstableArray of {x, y, z} delivery stop coordinates.

Delivery Drugs

lua
Drugs = {
    ['cokebaggy']        = { Label = "Cocaine",          Icon = "fas fa-capsules",                Price = 120 },
    ['crack_baggy']      = { Label = "Crack",            Icon = "fas fa-pills",                   Price = 100 },
    ['xtcbaggy']         = { Label = "Ecstasy",          Icon = "fas fa-tablets",                  Price = 75  },
    ['oxy']              = { Label = "Oxycodone",        Icon = "fas fa-prescription-bottle-alt",  Price = 135 },
    ['meth']             = { Label = "Methamphetamine",  Icon = "fas fa-flask",                    Price = 125 },
    ['weed_white-widow'] = { Label = "White Widow",      Icon = "fas fa-cannabis",                 Price = 45  },
    ['weed_skunk']       = { Label = "Skunk",            Icon = "fas fa-cannabis",                 Price = 50  },
    ['weed_purple-haze'] = { Label = "Purple Haze",      Icon = "fas fa-cannabis",                 Price = 55  },
    ['weed_og-kush']     = { Label = "OG Kush",          Icon = "fas fa-cannabis",                 Price = 60  },
    ['weed_amnesia']     = { Label = "Amnesia",          Icon = "fas fa-cannabis",                 Price = 65  },
    ['weed_ak47']        = { Label = "AK-47",            Icon = "fas fa-cannabis",                 Price = 70  },
}
KeyTypeDescription
LabelstringDisplay name shown in the delivery menu.
IconstringFontAwesome icon class.
PricenumberBase price per unit for this drug during deliveries.

INFO

Delivery drugs also support metadata variants when Config.EnableMetadata is true. Add a MetadataVariants sub-table with Label, Icon, Price, and Metadata keys, and optionally set SellBaseItem = false to prevent delivering the base item without metadata.

Milestones

Milestones reward players for reaching cumulative sale thresholds. There are general milestones (across all drugs combined) and drug-specific milestones.

lua
Config.Milestones = {
    Enable = true,
    ["general"] = { ... },
    ["oxy"] = { ... },
    -- etc.
}
KeyTypeDefaultDescription
Config.Milestones.EnablebooleantrueEnable or disable the entire milestone system. If disabled, the milestones menu option will not appear.

Reward Types

Milestone rewards can be one of three types:

TypeKeysDescription
"xp"AmountAwards XP to the player.
"item"Name, Label, AmountGives a specific item.
"money"Label, AmountAwards cash.

General Milestones

These count all drug sales combined.

#Required AmountReward TypeReward Details
15,000XP100 XP
210,000Item1x Advanced Lockpick (advancedlockpick)
320,000Money$1,000

Drug-Specific Milestones

Each drug can have its own milestone track. Below are the defaults:

Oxycodone (oxy)

#Required AmountReward TypeReward Details
11,000Item1x Advanced Lockpick (advancedlockpick)
25,000Money$1,000

Cocaine (cokebaggy)

#Required AmountReward TypeReward Details
1800XP50 XP
23,000XP150 XP

Crack (crack_baggy)

#Required AmountReward TypeReward Details
1600Item2x Medkit (medkit)
22,500XP200 XP

Ecstasy (xtcbaggy)

#Required AmountReward TypeReward Details
11,000XP100 XP
24,000XP200 XP

Methamphetamine (meth)

#Required AmountReward TypeReward Details
1900Item1x Body Armor (armor)
23,500XP200 XP

White Widow (weed_white-widow)

#Required AmountReward TypeReward Details
11,200XP100 XP
25,000XP200 XP

Skunk (weed_skunk)

#Required AmountReward TypeReward Details
11,200Item1x Lockpick (lockpick)
25,000XP200 XP

Purple Haze (weed_purple-haze)

#Required AmountReward TypeReward Details
11,400XP100 XP
26,000XP200 XP

OG Kush (weed_og-kush)

#Required AmountReward TypeReward Details
11,500Item1x Advanced Medkit (advanced_medkit)
26,000XP200 XP

Amnesia (weed_amnesia)

#Required AmountReward TypeReward Details
11,600XP50 XP
27,000XP100 XP

AK-47 (weed_ak47)

#Required AmountReward TypeReward Details
11,800Item1x Heavy Armor (heavyarmor)
27,500XP100 XP

Money Laundering / Washing

Item-Based Money Washing

lua
Config.MoneyWashing = {
    WashItem = { Enable = false, Chance = 100, ItemName = "black_money", MinAmount = 500, MaxAmount = 2500 },
}
KeyTypeDefaultDescription
WashItem.EnablebooleanfalseEnable item-based money washing with a 1-to-1 ratio (1 item = $1).
WashItem.Chancenumber100Percentage chance of a successful wash.
WashItem.ItemNamestring"black_money"The dirty money item to wash.
WashItem.MinAmountnumber500Minimum amount washed per transaction.
WashItem.MaxAmountnumber2500Maximum amount washed per transaction.

WARNING

When Config.MoneyWashing.WashItem.Enable is true, it overrides the per-level Washing settings. However, the per-level Tax percentage still applies. It is recommended to disable this if your server does not use a 1-to-1 ratio marked money item.

NPC Ped Spawning (Command)

The dynamic ped spawning command lets players spawn sellable NPCs around them.

lua
Config.Command = {
    Enable = false,
    Name = "cornerselling",
    Ped = {
        Models = { "a_m_y_hipster_01", "a_m_y_hipster_02", ... },
        DefaultModel = "a_m_y_business_01",
        Radius = 50.0,
        Network = false,
        DespawnDistance = 100.0,
        SpawnInterval = {min = 5000, max = 10000},
        MaxSpawned = 50,
        FieldOfView = 180,
        BehindPlayerDistance = 25.0,
        MaxZDifference = 0.5,
    },
}
KeyTypeDefaultDescription
EnablebooleanfalseEnable or disable the spawning command.
Namestring"cornerselling"The chat command name (used as /cornerselling).
Ped.Modelstable50 modelsList of ped model names that can be randomly selected for spawning.
Ped.DefaultModelstring"a_m_y_business_01"Fallback model if none from the list can be loaded.
Ped.Radiusnumber50.0Radius around the player in which peds spawn.
Ped.NetworkbooleanfalseWhether spawned peds are networked. false is highly recommended to keep them client-side.
Ped.DespawnDistancenumber100.0Distance at which spawned peds are automatically despawned.
Ped.SpawnInterval.min / maxnumber5000 / 10000Interval range (in milliseconds) between ped spawns.
Ped.MaxSpawnednumber50Maximum number of peds that can exist at once.
Ped.FieldOfViewnumber180Degrees in front of the player where peds should not spawn (to avoid appearing in view).
Ped.BehindPlayerDistancenumber25.0Minimum distance behind the player to spawn a ped.
Ped.MaxZDifferencenumber0.5Maximum allowed Z (height) difference above the player for ped spawning.

Delivery Ped

The delivery ped is the NPC that players interact with to start delivery missions.

lua
Config.Ped = {
    Enable = true,
    Location = {
        {x = 1075.619, y = -2330.657, z = 29.29169, w = 352.8969},
        {x = 864.2555, y = -967.3761, z = 26.86267, w = 293.9679},
        {x = -594.4417, y = -748.6177, z = 28.48703, w = 177.1182},
    },
    Model = "ig_ballasog",
    Interaction = {
        Icon = "fas fa-circle",
        Distance = 3.0,
    },
    Scenario = "WORLD_HUMAN_STAND_IMPATIENT",
}
KeyTypeDefaultDescription
EnablebooleantrueEnable or disable the delivery ped.
Locationtable3 locationsArray of {x, y, z, w} positions. One is randomly selected each time the resource starts.
Modelstring"ig_ballasog"Ped model to use.
Interaction.Iconstring"fas fa-circle"Target interaction icon.
Interaction.Distancenumber3.0Interaction distance in game units.
Scenariostring"WORLD_HUMAN_STAND_IMPATIENT"The ambient animation scenario the ped plays while idle.

Delivery Ped Blip

lua
Config.Blip = {
    Enable = false,
    Sprite = 480,
    Display = 4,
    Scale = 0.6,
    Colour = 1,
    Name = "Drug Lord Jeff",
}
KeyTypeDefaultDescription
EnablebooleanfalseWhether a map blip is displayed for the delivery ped.
Spritenumber480Blip sprite icon ID.
Displaynumber4Blip display type.
Scalenumber0.6Blip scale.
Colournumber1Blip colour ID.
Namestring"Drug Lord Jeff"Blip label on the map.

Animations

Animation configuration supports shared settings for all drug handshake animations and per-drug overrides.

lua
Config.Animations = {
    general = {
        cashModel = 'hei_prop_heist_cash_pile',
        cashPos   = { x = 0.13, y = 0.02, z = 0.0 },
        cashRot   = { x = -90.0, y = 0.0,  z = 0.0 },
        animDict  = 'mp_common',
        animClip  = 'givetake1_a',
    },
    drugs = {
        default = {
            drugModel = 'prop_weed_bottle',
            drugPos   = { x = 0.13, y = 0.02, z = 0.0 },
            drugRot   = { x = -90.0, y = 0.0,  z = 0.0 },
        },
        -- Per-drug overrides go here
    },
}

General Animation Settings

KeyTypeDefaultDescription
general.cashModelstring'hei_prop_heist_cash_pile'Model for the cash prop attached to the NPC's hand. Applies to all drugs.
general.cashPostable{x=0.13, y=0.02, z=0.0}Attachment position of the cash prop relative to the hand bone.
general.cashRottable{x=-90.0, y=0.0, z=0.0}Attachment rotation of the cash prop.
general.animDictstring'mp_common'Default animation dictionary for the handoff.
general.animClipstring'givetake1_a'Default animation clip for the handoff.

Per-Drug Animation Overrides

KeyTypeDefaultDescription
drugs.default.drugModelstring'prop_weed_bottle'Fallback drug prop model when no override exists.
drugs.default.drugPostable{x=0.13, y=0.02, z=0.0}Fallback attachment position.
drugs.default.drugRottable{x=-90.0, y=0.0, z=0.0}Fallback attachment rotation.

TIP

To add a custom animation for a specific drug, add a new entry under drugs keyed by the drug's spawn name. You can override drugModel, drugPos, drugRot, and optionally animDict / animClip. Any property not specified falls back to the general/default values.

Blacklisted Peds

Ped models that cannot be interacted with or used for selling drugs.

lua
Config.BlacklistedPeds = {
    [`s_m_y_ranger_01`]  = true,
    [`s_m_y_sheriff_01`] = true,
    [`s_m_y_cop_01`]     = true,
    [`s_f_y_sheriff_01`] = true,
    [`s_f_y_cop_01`]     = true,
    [`s_m_y_hwaycop_01`] = true,
}
KeyTypeDescription
Model hashbooleanSet to true to blacklist a ped model. Uses backtick hash notation.

The default blacklist includes all standard law enforcement ped models: rangers, sheriffs, cops, and highway patrol.

Stats

lua
Config.Stats = {
    Enable = true,
}
KeyTypeDefaultDescription
Config.Stats.EnablebooleantrueShow the Stats option in the menu. If disabled and Config.Milestones.Enable is true, only the Milestones option will appear. If both are disabled, no menu option is shown.

Police Alert

The policeAlert function is called whenever the police should be notified of suspicious dealings. It uses SD.PoliceDispatch and can be fully customized.

lua
policeAlert = function()
    SD.PoliceDispatch({
        displayCode = "10-31S",
        title = 'Suspicious Dealings',
        description = "Suspicious activities reported",
        message = "Suspects reported engaging in suspicious dealings",
        sprite = 310,
        scale = 1.0,
        colour = 1,
        blipText = "Suspicious Dealings",
        dispatchcodename = "suspicious_dealings",
    })
end
KeyTypeDefaultDescription
displayCodestring"10-31S"Dispatch code shown in the alert.
titlestring'Suspicious Dealings'Title used in cd_dispatch / ps-dispatch.
descriptionstring"Suspicious activities reported"Description of the incident.
messagestring"Suspects reported engaging in suspicious dealings"Additional message text.
spritenumber310Blip sprite for the dispatch alert.
scalenumber1.0Blip scale on the map.
colournumber1Blip colour (e.g., red).
blipTextstring"Suspicious Dealings"Text label on the blip.
dispatchcodenamestring"suspicious_dealings"Code name used by ps-dispatch in sv_dispatchcodes.lua or Config.Blips.

Logging

Logging is configured in server/logs.lua and supports multiple services.

lua
return {
    logs = {
        service     = 'none',
        dataset     = 'sd-selling',
        screenshots = false,
        events = {
            complete_stop      = true,
            add_xp             = true,
            stash_drugs        = true,
            return_drugs       = true,
            complete_encounter = true,
            redeem_milestone   = true,
            sell_drug          = true,
            money_launder      = true,
        },
    },
}

Logging Service

KeyTypeDefaultDescription
servicestring'none'Logging backend. Options: 'none', 'fivemanage', 'fivemerr', 'discord', 'loki', 'grafana'.
datasetstring'sd-selling'Fivemanage dataset ID (only used when service is 'fivemanage').
screenshotsbooleanfalseInclude screenshots with logs. Only applicable to Fivemanage and Fivemerr.

Loggable Events

EventDefaultDescription
complete_stoptrueA delivery stop is completed.
add_xptrueXP is awarded to a player.
stash_drugstrueDrugs are marked as stolen.
return_drugstrueStolen drugs are returned.
complete_encountertrueAn encounter finishes.
redeem_milestonetrueA milestone is redeemed.
sell_drugtrueA player sells drugs / receives payout.
money_laundertrueA player launders money.

Discord Webhook Settings

KeyTypeDefaultDescription
discord.namestring'Selling Logs'Webhook display name.
discord.linkstring''Webhook URL.
discord.imagestring''Webhook avatar image URL.
discord.footerstring''Webhook footer icon URL.

Loki Settings

KeyTypeDefaultDescription
loki.endpointstring''Loki push URL (without trailing slash).
loki.userstring''Basic auth username (optional).
loki.passwordstring''Basic auth password or API key (optional).
loki.tenantstring''X-Scope-OrgID header value (optional).

Grafana Cloud Logs Settings

KeyTypeDefaultDescription
grafana.endpointstring''Grafana Logs base URL (without trailing slash).
grafana.apiKeystring''Grafana API key (prefixed with 'Bearer ').
grafana.tenantstring''X-Scope-OrgID header value (optional).

Locale

Change the language by editing the locale loader near the top of config.lua:

lua
SD.Locale.LoadLocale('en')

Replace 'en' with any available language file from the locales folder.