Configuration
Every option in STG Vanaheim Market, from language, target and blips to staff, the supplier, NPC customers, thefts, ranks, stores, products and decorations.
Most settings live in stg-vanaheimmarket/shared/config.lua. Stores are in shared/shops.lua, notifications and integrations in shared/functions.lua, the product catalog in shared/products.lua and the decorations in shared/decorations.lua. These files stay editable in the escrow version. Restart the resource after a change.
Language
Config.Language = 'en'Available: en, de, fr, es, pt, it, nl, pl, sv, no, fi, cs, ar, he, jp, ko, zh. To change a text, edit the matching file in stg-vanaheimmarket/locales/. The blip name, the staff, shelf and permission names are in the same files.
Target system
Config.Target = 'auto'Prop
Type
Blips
Config.Blips = {
Enabled = true,
UseStoreName = true,
Sprite = 52,
Color = 2,
OwnedSprite = 52,
OwnedColor = 5,
Scale = 0.8,
ShortRange = true,
NearestOnly = false,
}Prop
Type
Vanaheim Fuel
Config.FuelStorePrice = trueA store with a fuelStation key in shared/shops.lua belongs to whoever owns that Vanaheim Fuel gas station. It cannot be bought, sold or transferred on its own, and the safes of the store and the station stay separate.
Prop
Type
Stores without an owner
Config.UnownedShop = {
Enabled = true,
PriceMultiplier = 1.0,
Items = { 'water', 'sprunk', 'ecola', 'coffee', 'sandwich', 'burger', 'hotdog', 'donut', 'chips', 'egochaser', 'bread', 'firstaid', 'painkillers', 'lighter', 'cigarettes' },
}Until someone buys a store, a clerk stands behind the counter and sells the basics, so players can always buy food and drinks. The clerk leaves as soon as the store is bought. Money from these sales goes to no one.
Prop
Type
Economy
Config.WithdrawTax = 5
Config.Business = {
SellbackRate = 60,
PayrollIntervalMinutes = 60,
}Prop
Type
Deposits, withdrawals and salaries always use the player's bank account. Customers pay at the register with cash or bank.
NPC staff
Config.Staff = {
cashier = { hireCost = 5000, wage = 750 },
stocker = { hireCost = 4000, wage = 600 },
}The owner hires staff in the Staff tab. hireCost is paid once from the safe, wage on every payroll cycle. If the safe cannot pay a wage, that NPC quits and the owner is told.
- Cashier: serves NPC customers at the register on their own. Without a cashier, a member behind the counter serves every customer with the barcode scanner.
- Shelf Stocker: carries boxes from the storage room and refills slots that have Auto on, even while the store is closed.
Supplier
Config.Supplier = {
DeliveryFee = 15,
DeliveryMinutes = 5,
Pickup = vec4(153.04, -3077.83, 5.9, 88.52),
}Members with stock permission build an order list in the Stock tab. The order is paid from the safe, then they either drive to the supplier and bring the cargo back for free, or pay a fee and wait for delivery. Delivered stock lands in the store warehouse.
Prop
Type
/cancelmarketorder cancels a running pick up and refunds the order cost to the safe.
Warehouse and shelves
Config.WarehouseCapacity = 2000
Config.Shelves = {
MaxPrice = 100000,
RestockThreshold = 25,
}Prop
Type
NPC customers
Config.Simulation = {
Customers = { Min = 1, Max = 1 },
ItemsPerVisit = 2,
MaxUnitsPerItem = 3,
QueueMax = 4,
QueuePatience = 120,
ServeTip = 5,
VisualCustomers = {
Enabled = true,
Group = { Min = 1, Max = 1 },
WaveCooldown = { Min = 30, Max = 30 },
},
}Every minute, customers visit each open store that has a cashier or a member inside. Prices below the market price of a product sell faster, prices above it sell slower. Without a cashier, customers line up at the register and a member behind the counter serves them with the barcode scanner, then the customer pays by card and leaves a tip.
Prop
Type
Customers who find the shelves empty leave upset, and online members get an out of stock alert.
Thefts
Config.Events = {
Enabled = true,
TheftChance = 4,
TheftUnits = { Min = 5, Max = 15 },
}While a member is inside an open store, a thief can sneak into the storage room, grab a box from the warehouse and run. The store alarm rings, the thief shows on the map and hired staff join the chase. Knock the thief down and carry the box back to the storage point, or let the shelf stocker do it. If the thief gets away, the stock is lost.
Prop
Type
Layout editor
Config.Editor = {
MaxFurniture = 10,
MaxDecorations = 20,
}Prop
Type
Owners open the editor from Shelves > Edit Layout in the management menu. Controls, rebindable in the FiveM key settings:
| Key | Action |
|---|---|
G | Show or hide the cursor |
Left mouse | Drag the gizmo |
E / R | Move or rotate mode |
Q | World or local axes |
F | Freecam |
Left / Right | Select the previous or next piece, or change the type of a new piece |
B | Snap to the floor |
Delete | Remove the piece |
Enter | Save |
Backspace | Cancel |
Ranks
Config.DefaultRanks = {
{ name = 'Owner', level = 100, salary = 0, owner = true,
permissions = { manage = true, hire = true, manageStock = true, manageMembers = true, withdraw = true, viewFinance = true } },
{ name = 'Manager', level = 50, salary = 1000, owner = false,
permissions = { manage = true, hire = true, manageStock = true, manageMembers = true, withdraw = false, viewFinance = true } },
{ name = 'Employee', level = 10, salary = 500, owner = false,
permissions = { manage = false, hire = false, manageStock = true, manageMembers = false, withdraw = false, viewFinance = false } },
}Ranks every store starts with. In the management menu, members with Manage Members can add custom ranks, rename them and move members between ranks below their own. Only the owner can change salaries and permissions, so these only set the starting point. The owner rank always holds every permission and is never paid, and new members join on the lowest rank.
| Permission | Allows |
|---|---|
manage | Rename the store, open or close it and edit the layout |
hire | Hire or dismiss the cashier and shelf stocker |
manageStock | Set shelf products and prices, restock and order from the supplier |
manageMembers | Invite, remove and change the rank of members |
withdraw | Withdraw money from the safe |
viewFinance | See sales, transactions and business statistics |
Stores
The script ships with 14 stores in shared/shops.lua. The key, for example strawberry, is how the store is saved in the database, so never rename it once the server is live.
| Key | Store | Gas station |
|---|---|---|
strawberry | Strawberry 24/7 | |
grove_street | Grove Street LTD | station_26 |
banham_canyon_24_7 | Banham Canyon 24/7 | |
chumash_24_7 | Chumash 24/7 | |
mount_chiliad_24_7 | Mount Chiliad 24/7 | station_17 |
sandy_shores_24_7 | Sandy Shores 24/7 | station_15 |
harmony_24_7 | Harmony 24/7 | |
grand_senora_desert_24_7 | Grand Senora Desert 24/7 | station_14 |
tataviam_mountains_24_7 | Tataviam Mountains 24/7 | station_6 |
downtown_vinewood_24_7 | Downtown Vinewood 24/7 | |
little_seoul_ltd | Little Seoul LTD | station_24 |
richman_glen_ltd | Richman Glen LTD | station_21 |
mirror_park_ltd | Mirror Park LTD | station_4 |
grapeseed_ltd | Grapeseed LTD | station_16 |
Every store sells for $150,000. Strawberry uses every option:
Config.Shops = {
['strawberry'] = {
label = 'Strawberry 24/7',
salePrice = 150000,
center = vec3(28.6, -1344.6, 29.5),
radius = 14.0,
hideModels = { 'v_66_fridge' },
placeSpawn = vec4(28.6, -1344.6, 29.5, 0.0),
management = vec4(25.2683, -1345.1144, 29.4971, -85.75),
register = vec4(25.75, -1346.35, 29.5, 90.0),
cashier = vec4(24.47, -1346.62, 29.5, 271.66),
stocker = vec4(27.3567, -1348.5425, 29.4971, 2.9121),
storage = vec3(29.9, -1338.9, 29.5),
dropoff = vec4(31.2, -1337.5, 29.5, 0.0),
storageProp = nil,
entrance = vec4(29.3, -1350.6, 29.33, 0.0),
customerSpawns = {},
fuelStation = nil,
lights = {
brightness = 1.5,
range = 8.0,
color = { 255, 241, 222 },
points = {
vec3(27.5, -1347.5, 30.7),
vec3(31.0, -1347.5, 30.7),
vec3(27.5, -1342.5, 30.7),
vec3(31.0, -1342.5, 30.7),
},
},
doors = {
{ model = 1196685123, coords = vec3(27.82, -1349.17, 29.65) },
{ model = 997554217, coords = vec3(30.42, -1349.17, 29.65) },
},
},
-- ...
}Prop
Type
Adding a store
Admins with the command.marketsetup ace can add a store in game:
- Stand inside the store and type
/marketsetup. - Walk to every point it asks for and press E: the middle of the store, the office desk, behind the counter, the customer side of the counter, the stocker spot, the storage point and the entrance door. Backspace goes back a step, X cancels.
- Enter the store name and sale price, and tick the box pile option if the store has no stock room look.
- The finished block is copied to your clipboard. Paste it inside
Config.Shopsinshared/shops.luaand restart the resource.
The default name, the hidden fridge models and the doors are filled in for you, and the store is linked to the nearest Vanaheim Fuel gas station when one is close by.
Products
Every product is defined in shared/products.lua. Only items listed here can be ordered from the supplier and placed on the shelves.
Config.Products = {
['water'] = { label = 'Water', category = 'Drinks', wholesale = 3, market = 8, demand = 1.3, prop = 'prop_ld_flow_bottle' },
['burger'] = { label = 'Burger', category = 'Food', wholesale = 7, market = 18, demand = 1.1, prop = 'prop_cs_burger_01',
hold = { Bone = 18905, Offset = vec3(0.13, 0.05, 0.02), Rotation = vec3(-50.0, 16.0, 60.0) } },
-- ...
}Prop
Type
The key is the inventory item the customer receives, so it must exist in your inventory. The product image in the menus is loaded from web/assets/img/products/<key>.png. When you add a product, add its image there too.
Decorations
Decorations are in shared/decorations.lua. They hold no stock, they only make the store look lived in. The Decor tab lists them in the order of this file.
Config.Decorations = {
{ id = 'plant_tall', label = 'Indoor Plant', model = 'prop_plant_int_01a', price = 350 },
{ id = 'atm', label = 'ATM', model = 'prop_atm_01', price = 2500 },
-- ...
}Prop
Type
Notifications and integrations
In shared/functions.lua:
Config.Functions = {
CustomNotify = false,
Notify = function(type, message)
lib.notify({ type = type, description = message })
end,
ShowHelpNotify = function(message)
lib.showTextUI(message, { position = 'left-center' })
end,
HideHelpNotify = function()
lib.hideTextUI()
end,
-- ...
}- CustomNotify:
falseuses the script's own notifications, prompts and progress bar.truesends them throughNotify,ShowHelpNotifyandHideHelpNotifyand uses theox_libprogress bar. Replace the bodies to use your own notification system. - HideHud / ShowHud: hide the HUD while the management screen, the barcode scanner or the layout editor is open. They support
stg-hudandjg-hud, otherwise the minimap is hidden. - CanCarryItem: checks whether a player can carry what they buy. It supports
ox_inventory,qb-inventoryandqs-inventory. - AddEntityTarget, RemoveEntityTarget, AddBoxTarget, RemoveBoxTarget: connect the store to
ox_target,qb-targetor the floating prompt, followingConfig.Target.
Still having trouble?
Open a ticket on our Discord. Our team answers around 15 hours a day.