Configuration

Database-backed settings flow and the full option reference for oxide-blackmarket.

Every setting in oxide-blackmarket, explained.

Times are in milliseconds. 1000 = 1 second, 60000 = 1 minute. So 300000 means 5 minutes.

How Configuration Is Stored

oxide-blackmarket keeps its live configuration in your database, in a shared table called oxide_settings. The .lua files are the factory defaults — the starting values the resource ships with. The table is created automatically on first start (you don't run any SQL by hand).

The flow:

  1. The first time the resource starts, every value from shared/config.lua and shared/items.lua is copied into oxide_settings. If you're upgrading from an older version and had customized those files, your customizations are copied in as-is — nothing is lost.
  2. From then on, the database is what the resource reads. The .lua files were only the defaults it filled the table from that first time.

What this means for you:

  • Setting up for the first time? Edit shared/config.lua and shared/items.lua exactly as this guide describes, before you start the resource for the first time. Your values are imported on that first start.
  • Changing a setting on a server that has already run the resource? Editing the .lua file will not change anything — the database already holds that value and wins. Change it in the database instead (below), then restart the resource.

Throughout these docs, "set Config.X" means the setting named X. Set it in shared/config.lua before the first start, or in the database afterward.

Changing a setting after the first start

The easiest way is the in-game settings menu: as an admin, run /blackmarket settings. Changes made there apply live and are saved to the database immediately — no restart needed. See Admin → Settings Menu.

You can also edit the database directly, which is handy for any setting the menu does not expose. Each setting is one row in oxide_settings, matched by resource = 'oxide-blackmarket' and setting_key. The setting_key is the top-level config name without the Config. prefix — e.g. DealerCount, or Market for the whole Config.Market group. The value column holds that setting as JSON (for a group like Market, the entire group is one JSON object, so you edit the field you want inside it).

  • Change one setting: update that row's value and restart the resource.
  • Reset one setting to its .lua default: delete that row and restart — the resource re-imports it from shared/config.lua on the next start.
  • Reset everything to the .lua files: delete every row where resource = 'oxide-blackmarket' (or drop the oxide_settings table) and restart — all values are imported fresh.

Settings added by a future update aren't in your database yet, so they come from the updated .lua file automatically on the next start — no re-import needed.

Developers can also read and write settings live from another resource — see Exports → Settings.

Config File Map

These files hold the default values imported into the database on first start:

FilePurpose
shared/config.luaDealer behavior, economy, money, police/arrest, loot, hit squad, spawn locations
shared/items.luaWhat the dealers buy and sell, with prices, reputation values, and category headers

General Settings

File: shared/config.lua

SettingTypeDefaultDescription
Config.DebugbooleanfalsePrints [oxide-blackmarket] lines to the console while things happen. Turn on while setting up or troubleshooting
Config.EnableTiersbooleantrueTurns the reputation system on or off. When false, every player sees the full shop and reputation is never gained or lost
Config.DealerCountnumber3How many dealers roam the map at once. Automatically capped at the number of entries in Config.Locations (no two dealers share a spot)
Config.RelocationIntervalnumber2700000How often each dealer moves to a new spot (45 minutes). Every dealer runs its own staggered timer
Config.DealerWeaponstring'WEAPON_PISTOL'The weapon a dealer carries (and pulls out if he turns hostile)
Config.DealerModelstring's_m_y_dealer_01'The dealer's character model

Dirty Money

File: shared/config.lua

Controls what currency the shop uses for buying, selling, and loot bag cash.

SettingTypeDefaultDescription
Config.DirtyMoney.modestring'account''account' uses a money account (like cash or ESX black money); 'item' uses an inventory item
Config.DirtyMoney.accountstring'cash'Which account to use in account mode
Config.DirtyMoney.itemstring'black_money'Which item to use in item mode
Config.DirtyMoney.useMetadatabooleanfalseIn item mode: read each bill's dollar value from the item's metadata instead of counting items
Config.DirtyMoney.metadataKeystring'worth'The metadata field that holds the bill's value (only used when useMetadata = true)

Recommended setups per framework (full walkthrough in the Installation Guide):

-- ESX (built-in black money account)
Config.DirtyMoney = {
    mode = 'account',
    account = 'black_money',
}

-- QBX (ox_inventory ships a black_money item; each item = $1)
Config.DirtyMoney = {
    mode = 'item',
    item = 'black_money',
}

-- Marked bills that carry their dollar value in metadata
Config.DirtyMoney = {
    mode = 'item',
    item = 'markedbills',
    useMetadata = true,
    metadataKey = 'worth', -- match the field your bill item actually uses
}

In metadata mode, when a player pays a price that doesn't match their bills exactly, the resource takes the smallest set of bills that covers the cost and hands the difference back as a new bill.

Blips and Discovery

File: shared/config.lua

Players who get close to a dealer see a brief "Suspicious Activity" blip flash on their map. Higher reputation keeps the blip on screen longer.

SettingTypeDefaultDescription
Config.BlipDetectionRangenumber200.0How close (in meters) a player must be for the blip to flash
Config.BlipCooldownnumber120000Minimum time between flashes for the same player (2 minutes)
Config.BlipSpritenumber140Blip icon (dollar sign)
Config.BlipColornumber1Blip color (red)

Config.BlipDuration sets how long the flash lasts, by reputation tier:

Config.BlipDuration = {
    [0] = 3000,   -- 3 seconds
    [1] = 4000,
    [2] = 5000,
    [3] = 6000,
    [4] = 10000,  -- 10 seconds
}

Reputation

File: shared/config.lua

SettingTypeDefaultDescription
Config.KillPenaltynumber500Reputation lost for killing a dealer

Tier thresholds (minRep is the reputation needed to reach that tier):

Config.Tiers = {
    [0] = { name = 'tier.unknown', minRep = 0 },
    [1] = { name = 'tier.street', minRep = 100 },
    [2] = { name = 'tier.connected', minRep = 300 },
    [3] = { name = 'tier.trusted', minRep = 600 },
    [4] = { name = 'tier.inner_circle', minRep = 1000 },
}

The name values are locale keys — edit the display names in locales/en.json.

Economy

File: shared/config.lua

Three systems shape prices and stock over time. All three keep their numbers in memory only, so they reset whenever the resource or server restarts.

Market saturation (Config.Market)

Selling a lot of an item drives its sell price down for everyone (there's one shared market across all dealers), and the price recovers over time. Buy prices are never affected.

SettingTypeDefaultDescription
Config.Market.enabledbooleantrueTurns sell-price saturation on or off. When false, sell prices stay fixed
Config.Market.decayPerSalenumber0.02How much the price drops per item sold (0.02 = 2% per item)
Config.Market.recoveryPerMinutenumber0.01How much the price recovers toward normal each minute (0.01 = 1% per minute)
Config.Market.minSellMultipliernumber0.4The floor — a sell price never falls below this share of its base (0.4 = 40%)

Periodic restock

Separate from relocation, each active dealer tops his stock back up toward its per-item maximum on a timer.

SettingTypeDefaultDescription
Config.RestockEnabledbooleantrueTurns periodic restocking on or off
Config.RestockIntervalnumber600000How often each dealer restocks (10 minutes)
Config.RestockPercentnumber0.25How much of each item's maximum stock is added each time (0.25 = +25% of max per tick, never above the maximum)

Daily sell caps (Config.DailySellCap)

Optional per-player, per-real-day limit on how much of an item can be sold to dealers. Off by default.

SettingTypeDefaultDescription
Config.DailySellCap.enabledbooleanfalseTurns daily caps on or off
Config.DailySellCap.defaultnumber0Cap applied to any sellable item without its own limit (0 = unlimited)
Config.DailySellCap.perItemtable{}Per-item overrides, e.g. ['weed_brick'] = 50
Config.DailySellCap = {
    enabled = false,
    default = 0,                -- 0 = unlimited
    perItem = {
        -- ['weed_brick'] = 50,
    },
}

Counts reset at the start of each real-world day (and on restart). A player who hits the cap is told how many more they can sell today.

Pager

File: shared/config.lua

SettingTypeDefaultDescription
Config.PagerCooldownnumber300000How long a player must wait between pager uses (5 minutes)
Config.PagerResponseDelaytable{ min = 3000, max = 6000 }How long the player waits for the reply — a random time between min and max is picked each use. The texting animation and progress bar run for this long

Chance the pager actually gets an answer, by tier (players below Tier 2 can't use it at all):

Config.PagerSuccessChance = {
    [2] = 0.40,   -- 40%
    [3] = 0.70,   -- 70%
    [4] = 1.00,   -- always works
}

How precise the answer is, by tier. detail controls what the anonymous tip email says — 'area' gives only the district, 'street' adds the street name, and 'exact' gives both. waypoint drops a GPS pin on the player's map:

Config.PagerIntel = {
    [2] = { detail = 'area',   waypoint = false },
    [3] = { detail = 'street', waypoint = false },
    [4] = { detail = 'exact',  waypoint = true  },
}

Config.PagerAnim sets the texting animation played while waiting for the reply (enter, looping idle, and exit clips). The default looks right for most peds — you normally don't need to touch it.

Police and Arrest

File: shared/config.lua

The arrest is a transport job: an officer cuffs a surrendered dealer, escorts him on foot, loads him into a vehicle, and drives him to a drop-off point to finalize. The reward is paid only when the dealer is delivered.

SettingTypeDefaultDescription
Config.ArrestRewardnumber5000Cash paid to the officer on a completed delivery (paid when ArrestRewardRecipient includes the officer)
Config.DepartmentCutnumber2500Society/department deposit on delivery (paid when ArrestRewardRecipient includes society)
Config.ArrestRewardRecipientstring'both'Who gets paid on delivery: 'officer' (personal cash only), 'society' (department deposit only), or 'both'
Config.ArrestPoliceIntegrationbooleanfalseWhen true and oxide-police is installed, the department cut is funded into the arresting officer's real oxide-police department treasury instead of a generic society deposit. Falls back to the standalone deposit if oxide-police is absent (see note below)
Config.ArrestRespawnDelaynumber900000How long after an arrest before that dealer reappears (15 minutes)
Config.DeathRespawnDelaynumber600000How long after a death before that dealer reappears (10 minutes)
Config.SubduedDeathPayoutnumber500Smaller police account deposit if someone kills a dealer while he has his hands up
Config.ArrestDistancenumber3.0How close (meters) an officer must be to show the cuff prompt on a surrendered dealer
Config.DropOffRadiusnumber15.0How close the officer's vehicle must be to a drop-off point to finalize the arrest
Config.EscortBreakFreeDistancenumber12.0If the officer strays this far (meters) from the cuffed dealer during the on-foot escort, the dealer breaks free
Config.EscortMaxDurationnumber180000Safety timer — the transport auto-releases (dealer breaks free) after this long (3 minutes)
Config.PoliceJobstablesee belowJob names that count as police
Config.PoliceJobs = { 'police', 'sheriff', 'bcso', 'sast', 'sasp', 'LSPD' }

Job names must match your server's job names exactly, including capitalization.

About Config.ArrestPoliceIntegration. When on, this moves the department cut into the arresting officer's real oxide-police department treasury on delivery. It does not create an arrest record, charge, or custody booking — an NPC can't be booked into a player-custody system. Leave it false if you don't run oxide-police; the standalone society deposit is used instead.

Arrest drop-off points

The cuffed dealer must be delivered to one of these points (the nearest one is used). Each is a vector4(x, y, z, heading):

Config.ArrestDropOffs = {
    vector4(454.6, -1017.4, 28.4, 90.0),    -- Mission Row PD rear lot
    vector4(361.5, -1584.6, 29.3, 230.0),   -- Davis Sheriff
    vector4(-447.5, 6012.7, 31.7, 226.0),   -- Paleto Bay
    vector4(1853.1, 3686.6, 34.3, 210.0),   -- Sandy Shores Sheriff
}

Add drop-offs near your own police stations so officers always have a delivery point within reach.

Dispatch Alerts

File: shared/config.lua

Config.DispatchAlerts has two alerts that go to your police dispatch system (through o-link, so it works with ps-dispatch, cd_dispatch, and others):

  • transaction — chance to alert when a player buys or sells (default 15%)
  • proximity — chance to alert when an officer gets near a dealer (default 10%)

Each alert has these fields:

FieldTypeDescription
enabledbooleanTurns the alert on or off
chancenumberChance to fire, from 0.0 (never) to 1.0 (always)
messagestringLocale key for the dispatch message
codestringDispatch code shown to officers (e.g. 10-31)
iconstringFont Awesome icon name
timenumberHow long the dispatch blip stays on the map (ms)
bliptableBlip sprite, color, and scale

The proximity alert also has a range (how close the officer must get, default 150.0 meters).

Death and Loot

File: shared/config.lua

SettingTypeDefaultDescription
Config.BodyFadeDelaynumber45000How long the dealer's body stays before fading away (45 seconds)
Config.DeathNotifyRadiusnumber500.0Players within this many meters hear about the dealer's death
Config.DeathNotifyMinTiernumber1Minimum tier to get the death notification (ignored when tiers are off)
Config.LootDropEnabledbooleantrueWhether a killed dealer drops a loot bag
Config.LootCashMinnumber500Minimum cash in the bag
Config.LootCashMaxnumber2500Maximum cash in the bag
Config.LootStockPercentnumber0.3How much of the dealer's remaining stock drops (30%)
Config.LootMaxItemsnumber5Max different item types in one bag
Config.LootBagModelstring'prop_cs_heist_bag_01'The bag prop model
Config.LootBagDespawnTimenumber300000Uncollected bags disappear after this long (5 minutes)

Target Settings

File: shared/config.lua

SettingTypeDefaultDescription
Config.TargetDistancenumber2.5How close (meters) a player must be to interact with a dealer
Config.TargetIconstring'fas fa-handshake'Icon on the interaction
Config.TargetLabelstring'target.trade_dealer'Locale key for the interaction label

Hit Squad

File: shared/config.lua

When someone kills a dealer, four armed NPCs spawn in a car and come after them.

SettingTypeDefaultDescription
Config.HitSquadEnabledbooleantrueTurns the hit squad on or off
Config.HitSquadEscapeDistancenumber500.0Get this far away (meters) and the squad gives up
Config.HitSquadCheckIntervalnumber1000How often the squad's behavior updates (1 second)
Config.HitSquadFootEngageDistancenumber50.0Within this range they get out of the car and fight on foot
Config.HitSquadDriveSpeednumber30.0Chase speed in meters/second (~67 mph). Above ~40 the AI loses control on corners
Config.HitSquadSpawnDistMinnumber200.0Closest the squad can spawn to the death location (meters)
Config.HitSquadSpawnDistMaxnumber300.0Farthest the squad can spawn (meters)
Config.HitSquadTaskRefreshIntervalnumber5000How often chase orders are re-issued (5 seconds)
Config.HitSquadMaxChaseDurationnumber90000If the squad spends this long driving without ever reaching the player, they give up (90 seconds — a safety net for bad roads)
Config.HitSquadDifficultystring'medium''easy', 'medium', or 'hard' — picks their weapons and accuracy
Config.HitSquadCombatMovementnumber2Fighting style: 0 = stationary, 1 = defensive, 2 = offensive, 3 = suicidal
Config.HitSquadCombatRangenumber2Preferred fighting distance: 0 = near, 1 = medium, 2 = far

Vehicles (one is picked at random — keep these as 4-door cars so all four NPCs fit):

Config.HitSquadVehicles = {
    'sultan',
    'sultan2',
    'oracle',
    'oracle2',
    'schafter2',
    'tailgater',
}

Ped models (picked at random per squad member):

Config.HitSquadPedModels = {
    'a_m_m_business_01',
    'a_m_y_business_01',
    'a_m_y_business_02',
    'a_m_m_soucent_01',
    'g_m_m_mexboss_01',
}

Weapons per difficulty (four entries = one per squad member):

Config.HitSquadWeapons = {
    easy = {
        'WEAPON_PISTOL',
        'WEAPON_PISTOL',
        'WEAPON_PISTOL',
        'WEAPON_PISTOL',
    },
    medium = {
        'WEAPON_PISTOL50',
        'WEAPON_SMG',
        'WEAPON_SMG',
        'WEAPON_PUMPSHOTGUN',
    },
    hard = {
        'WEAPON_COMBATPISTOL',
        'WEAPON_ASSAULTRIFLE',
        'WEAPON_ASSAULTRIFLE',
        'WEAPON_CARBINERIFLE',
    },
}

Accuracy per difficulty (0-100):

Config.HitSquadCombatAbility = {
    easy = 50,
    medium = 75,
    hard = 100,
}

Surrender and Flee

File: shared/config.lua

While the dealer has his hands up, he watches the nearest officer. If the officer drifts too far away, he may make a run for it.

SettingTypeDefaultDescription
Config.FleeDistanceThresholdnumber8.0If the officer is farther than this (meters), the dealer starts rolling escape attempts
Config.FleeChancenumber0.35Chance to bolt on each check (35%)
Config.FleeCheckIntervalnumber1000How often the escape roll happens (1 second)
Config.SurrenderCooldownTimenumber1000After fleeing, how long before the dealer can be forced to surrender again
Config.AimSurrenderDistancenumber10.0An officer aiming at the dealer within this range (meters) forces the surrender
Config.IdleWanderCheckDistancenumber50.0If a player is within this range and the dealer is standing still, he's nudged to start wandering again

Dealer Locations

File: shared/config.lua

The script ships with a curated list of dealer spawn locations across the map. The exact coordinates are intentionally omitted from the public docs so player communities cannot pre-emptively scout spawn points — the real defaults are in shared/config.lua after installation.

The structure looks like this:

Config.Locations = {
    vector4(0.0, 0.0, 0.0, 0.0), -- x, y, z, heading
    vector4(0.0, 0.0, 0.0, 0.0),
    -- add as many spawn points as you want
}

Each dealer spawns at its own random entry from this list — no two dealers share a spot, so you need at least as many locations as Config.DealerCount. Add as many as you like. Pick open outdoor areas — the dealer wanders around his spawn point, and cramped or indoor spots break his pathing.

Sellable Items

File: shared/items.lua

Items players can sell to dealers. price is the cash paid per item, rep is the reputation gained per item, and category is the heading the item appears under in the sell tab:

Config.SellableItems = {
    -- Weed
    ['weed_1g'] = { price = 30, rep = 1, category = 'Weed' },
    ['weed_eighth'] = { price = 100, rep = 3, category = 'Weed' },
    ['weed_quarter'] = { price = 190, rep = 5, category = 'Weed' },
    ['weed_half'] = { price = 360, rep = 8, category = 'Weed' },
    ['weed_ounce'] = { price = 700, rep = 15, category = 'Weed' },
    ['weed_brick'] = { price = 500, rep = 15, category = 'Weed' },
    ['joint'] = { price = 30, rep = 1, category = 'Weed' },
    ['blunt'] = { price = 40, rep = 1, category = 'Weed' },
    -- Meth
    ['meth_baggy'] = { price = 250, rep = 10, category = 'Meth' },
    ['meth_baggy_glass'] = { price = 325, rep = 13, category = 'Meth' },
    ['meth_baggy_blue_sky'] = { price = 400, rep = 18, category = 'Meth' },
    ['meth_baggy_purple_haze'] = { price = 375, rep = 16, category = 'Meth' },
    ['meth_baggy_lean_crystal'] = { price = 300, rep = 11, category = 'Meth' },
    ['meth_baggy_green_rush'] = { price = 285, rep = 10, category = 'Meth' },
    ['meth_baggy_dirty_sprite'] = { price = 360, rep = 15, category = 'Meth' },
    ['meth_baggy_street_mix'] = { price = 175, rep = 6, category = 'Meth' },
    ['meth_baggy_rocket_fuel'] = { price = 340, rep = 14, category = 'Meth' },
    ['meth_baggy_club_special'] = { price = 385, rep = 17, category = 'Meth' },
    ['meth_baggy_ice'] = { price = 375, rep = 16, category = 'Meth' },
    -- Misc
    ['phone'] = { price = 100, rep = 2, category = 'Misc' },
}

The defaults reference items from other Oxide resources (oxide-weed, oxide-meth). Remove or replace any item your server doesn't have. The category value is just a display heading — name it whatever you like; items with the same category are grouped together in the sell tab.

Shop Inventory

File: shared/items.lua

Items the dealers sell, grouped by reputation tier. A player sees their tier's items plus everything from the tiers below. Format:

{ item = 'item_name', label = 'Display Name', price = 1000, stock = 10, category = 'Tools' }
{ item = 'weapon_name', label = 'Name', price = 5000, stock = 2, info = { serie = '' }, category = 'Weapons' }
  • stock — how many of the item a dealer carries. Each dealer has its own stock pool; buying the last one from one dealer doesn't affect any other dealer. A dealer's stock refills when he relocates or respawns, and tops up over time (see Economy).
  • info — extra metadata attached to the purchased item. { serie = '' } gives weapons a blank serial number ("no serial").
  • category — the heading the item appears under in the buy tab. The defaults use Tools, Weapons, Ammo, Medical, Armor, Blueprints, and Drugs & Supplies. Name them however you like; items with the same category are grouped together.

Multiple entries can use the same item with different info (like the printer_usb blueprints below) — each entry keeps its own price, stock, and category.

The tier lists below show the item, label, price, and stock for each entry. Every default entry also carries a category (shown above) — open shared/items.lua to see or change it.

Tier 0

Config.ShopInventory[0] = {
    { item = 'lockpick', label = 'Lockpick', price = 300, stock = 10 },
    { item = 'joint', label = 'Joint', price = 50, stock = 20 },
    { item = 'rolling_papers', label = 'Rolling Papers', price = 10, stock = 50 },
    { item = 'lighter', label = 'Lighter', price = 15, stock = 20 },
    { item = 'weapon_switchblade', label = 'Switchblade', price = 200, stock = 5 },
}

Tier 1

Config.ShopInventory[1] = {
    { item = 'ammo_pistol', label = '9mm Ammo', price = 15, stock = 100 },
    { item = 'radio', label = 'Radio', price = 500, stock = 5 },
    { item = 'bandage', label = 'Bandage', price = 100, stock = 15 },
    { item = 'growing_manual', label = "Grower's Manual", price = 800, stock = 3 },
    { item = 'weapon_knife', label = 'Knife', price = 350, stock = 5 },
    { item = 'hydrogen_peroxide', label = 'Hydrogen Peroxide', price = 80, stock = 20 },
    { item = 'ammonia', label = 'Ammonia', price = 80, stock = 20 },
    { item = 'hydrochloric_acid', label = 'Hydrochloric Acid', price = 80, stock = 20 },
    { item = 'sodium_benzoate', label = 'Sodium Benzoate', price = 80, stock = 20 },
    { item = 'baggy', label = 'Empty Baggy', price = 10, stock = 50 },
}

Tier 2

Config.ShopInventory[2] = {
    { item = 'blackmarket_pager', label = 'Burner Pager', price = 2500, stock = 2 },
    { item = 'weapon_pistol', label = 'Pistol (No Serial)', price = 5000, stock = 2, info = { serie = '' } },
    { item = 'weapon_snspistol', label = 'SNS Pistol', price = 3500, stock = 3, info = { serie = '' } },
    { item = 'weapon_sawnoffshotgun', label = 'Sawed-Off Shotgun', price = 4500, stock = 2, info = { serie = '' } },
    { item = 'ammo_smg', label = 'SMG Ammo', price = 25, stock = 100 },
    { item = 'weapon_molotov', label = 'Molotov', price = 500, stock = 5 },
    { item = 'meth_table', label = 'Meth Table', price = 3000, stock = 2 },
    { item = 'meth_crystallizer', label = 'Meth Crystallizer', price = 4500, stock = 2 },
    { item = 'meth_manual', label = "The Cook's Notebook", price = 1500, stock = 3 },
    { item = 'gas_mask', label = 'Gas Mask', price = 500, stock = 5 },
    { item = 'cough_syrup', label = 'Cough Syrup', price = 60, stock = 15 },
    { item = 'pain_killer', label = 'Pain Killer', price = 40, stock = 15 },
    { item = 'cannabis_leaf', label = 'Cannabis Leaf', price = 50, stock = 15 },
    { item = 'lax_to_the_max', label = 'Lax to the Max', price = 45, stock = 15 },
}

Tier 3

Config.ShopInventory[3] = {
    { item = 'weapon_microsmg', label = 'Micro SMG', price = 12000, stock = 2, info = { serie = '' } },
    { item = 'weapon_pumpshotgun', label = 'Pump Shotgun', price = 15000, stock = 1, info = { serie = '' } },
    { item = 'ammo_rifle', label = 'Rifle Ammo', price = 50, stock = 100 },
    { item = 'ammo_shotgun', label = 'Shotgun Ammo', price = 40, stock = 50 },
    { item = 'med_armor', label = 'Body Armor', price = 5000, stock = 5 },
    { item = 'printer_usb', label = 'SNS Pistol USB', price = 2500, stock = 3, info = { blueprint = 'sns_pistol' } },
    { item = 'printer_usb', label = 'Pistol USB', price = 3000, stock = 3, info = { blueprint = 'pistol' } },
    { item = 'printer_usb', label = 'Micro SMG USB', price = 4000, stock = 2, info = { blueprint = 'micro_smg' } },
    { item = 'printer_usb', label = 'Pump Shotgun USB', price = 4000, stock = 2, info = { blueprint = 'pump_shotgun' } },
    { item = 'magnesium_oxide', label = 'Magnesium Oxide', price = 120, stock = 10 },
    { item = 'hazardous_waste', label = 'Hazardous Waste', price = 150, stock = 10 },
    { item = 'vanilla_unicorn_pills', label = 'V.U. Pills', price = 200, stock = 10 },
    { item = 'acetone', label = 'Acetone', price = 250, stock = 10 },
    { item = 'adrenaline', label = 'Adrenaline', price = 300, stock = 10 },
}

Tier 4

Config.ShopInventory[4] = {
    { item = 'weapon_assaultrifle', label = 'Assault Rifle', price = 35000, stock = 1, info = { serie = '' } },
    { item = 'weapon_carbinerifle', label = 'Carbine Rifle', price = 40000, stock = 1, info = { serie = '' } },
    { item = 'weapon_smg', label = 'SMG', price = 20000, stock = 2, info = { serie = '' } },
    { item = 'heavy_armor', label = 'Heavy Armor', price = 10000, stock = 3 },
    { item = 'ammo_sniper', label = 'Sniper Ammo', price = 100, stock = 50 },
    { item = 'printer_usb', label = 'Assault Rifle USB', price = 8000, stock = 1, info = { blueprint = 'assault_rifle' } },
    { item = 'printer_usb', label = 'Carbine Rifle USB', price = 8500, stock = 1, info = { blueprint = 'carbine_rifle' } },
    { item = 'printer_usb', label = 'Combat Pistol USB', price = 5000, stock = 2, info = { blueprint = 'combat_pistol' } },
    { item = 'toluene', label = 'Toluene', price = 400, stock = 8 },
}

Next Steps