Before You Begin#
Before installing Vending Machine Creator, make sure your server meets the requirements. A framework, an inventory and the two ox resources are mandatory; everything else is optional and detected on its own.
Requirement | Status | Notes |
|---|---|---|
| Required | Stores every placed machine, its products, owner, stock and earnings. |
| Required | The product menu, callbacks, the progress bar and the robbery skill check. |
OneSync | Required | Declared as a dependency; the resource does not start without it. |
Framework | Required |
|
Inventory | Required |
|
| Optional | Styled |
| Optional | Its HUD is hidden while the creator or the owner's panel is open. |
Quasar Smartphone | Optional | The VendGo app, through its |
The framework and the inventory are picked by looking at what is already running when the resource starts:
Layer | Detected from |
|---|---|
Framework |
|
Inventory |
|
Run one inventory from that list. Integrations explains how to set either layer by hand.
github.comReleases · overextended/oxmysqlMySQL resource for FXServer.github.comReleases · overextended/ox_libA FiveM resource and script library for Lua and JS.Downloading Vending Machine Creator#
After purchasing Vending Machine Creator, the resource is automatically linked to your CFX Portal account.
Sign in to the CFX Portal using the same account used during checkout, open Granted Assets, and download Vending Machine Creator.
After extracting the download, you should have the following folders:
[vendingmachine]/
├── qs-vendingmachine-creator/ -- the resource
├── [sql]/
│ ├── qs_vendingmachines.sql -- the machines table (required)
│ └── items_esx.sql -- the products, for ESX
└── [img]/ -- product icons for your inventoryFolder | What it is |
|---|---|
| The resource — the only folder that goes into |
| SQL to run in your database. Not a resource. |
| Icons to copy into your inventory. Not a resource. |
Inside the resource, these are the parts you may edit:
qs-vendingmachine-creator/
├── config/main.lua -- every setting
├── custom/ -- framework bridges, notifications, police alert
├── server/custom/inventory/ -- inventory bridges and image paths
├── locales/ -- 41 languages
└── web/build/ -- the interface, already builtThe folder must be named
qs-vendingmachine-creator. Quasar Smartphone's VendGo app looks for the resource under that exact name, so a renamed copy is reported as not running.
Installing the Resource#
Move the qs-vendingmachine-creator folder into your server's resources directory. It can live anywhere inside it, including a category folder:
resources/
└── [qs]/
└── qs-vendingmachine-creator/Once copied, open your server.cfg and make sure every dependency starts before Vending Machine Creator:
ensure oxmysql
ensure ox_lib
# Framework
ensure es_extended
# ensure qb-core
# ensure qbx_core
# Inventory
ensure ox_inventory
# Optional
ensure qs-textui
ensure qs-smartphone
ensure qs-vendingmachine-creator
# VendGo, after both the phone and the machines
ensure phone-vendingmachineThe loading order matters. Detection reads which resources are started at the moment Vending Machine Creator starts, so a framework or inventory that starts after it is not found.
The Database#
Open your database manager (HeidiSQL, phpMyAdmin, DBeaver…), select your server's database and run [sql]/qs_vendingmachines.sql. It creates a single table, qs_vendingmachines, with one row per placed machine:
Columns | Hold |
|---|---|
| The machine's name, its model, where it stands and which way it faces, and its map blip. |
| The products — item, label, price and stock — and the account they are paid from. |
| Whether a player can buy the machine and for how much, and whether it can be forced open. |
| Who bought it, and the earnings waiting to be collected. |
| The Access Control list set in the creator. |
| Who placed it, and when. |
Updating from an older version? Keep your table. On every start the resource checks for the ownership and robbery columns —
for_sale,price,owner,owner_name,earnings,robbable— and adds any that are missing without touching your machines. That check only runs on a table that exists, so a fresh server must import the file first.
The Products#
Vending Machine Creator hands out items — it never creates them and never makes them usable. Eating and drinking are your inventory's or your consumables script's job. The seven machine types in config/main.lua sell these:
Item | Label | Sold by |
|---|---|---|
| Water | Drink Machine, Drink Fridge, Water Dispenser |
| Cola | Drink Machine, Drink Fridge |
| Orange Soda | Drink Machine |
| Energy Drink | Drink Machine, Sprunk Machine |
| Beer | Drink Fridge |
| Sprunk | Sprunk Machine |
| Lime Soda | Sprunk Machine |
| Chips, Chocolate, Nuts, Candy | Snack Machine |
| Cookies, Donut, Cupcake | Snack Machine 2 |
| Coffee, Espresso, Cappuccino | Coffee Machine |
| Lockpick | Needed for robberies ( |
Already have equivalents on your server, such as water or sandwich? Point Config.MachineTypes at them instead of creating new ones — Usage shows how. Otherwise, declare the products where your inventory reads its items:
Add them to ox_inventory/data/items.lua, on any framework:
['water_bottle'] = { label = 'Water', weight = 500, client = { status = { thirst = 200000 }, usetime = 2500 } },
['cola'] = { label = 'Cola', weight = 350, client = { status = { thirst = 200000 }, usetime = 2500 } },
['orange_soda'] = { label = 'Orange Soda', weight = 350, client = { status = { thirst = 180000 }, usetime = 2500 } },
['energy_drink'] = { label = 'Energy Drink', weight = 350, client = { status = { thirst = 150000 }, usetime = 2500 } },
['beer'] = { label = 'Beer', weight = 500, client = { status = { thirst = 150000 }, usetime = 3000 } },
['sprunk'] = { label = 'Sprunk', weight = 350, client = { status = { thirst = 200000 }, usetime = 2500 } },
['lime_soda'] = { label = 'Lime Soda', weight = 350, client = { status = { thirst = 180000 }, usetime = 2500 } },
['chips'] = { label = 'Chips', weight = 100, client = { status = { hunger = 150000 }, usetime = 2500 } },
['chocolate'] = { label = 'Chocolate', weight = 100, client = { status = { hunger = 150000 }, usetime = 2500 } },
['nuts'] = { label = 'Nuts', weight = 100, client = { status = { hunger = 120000 }, usetime = 2500 } },
['candy'] = { label = 'Candy', weight = 50, client = { status = { hunger = 100000 }, usetime = 2000 } },
['cookies'] = { label = 'Cookies', weight = 150, client = { status = { hunger = 180000 }, usetime = 2500 } },
['donut'] = { label = 'Donut', weight = 150, client = { status = { hunger = 180000 }, usetime = 2500 } },
['cupcake'] = { label = 'Cupcake', weight = 150, client = { status = { hunger = 180000 }, usetime = 2500 } },
['coffee'] = { label = 'Coffee', weight = 200, client = { status = { thirst = 150000 }, usetime = 3000 } },
['espresso'] = { label = 'Espresso', weight = 150, client = { status = { thirst = 120000 }, usetime = 2500 } },
['cappuccino'] = { label = 'Cappuccino', weight = 200, client = { status = { thirst = 150000 }, usetime = 3000 } },
['lockpick'] = { label = 'Lockpick', weight = 100 },For the eating or drinking animation, add anim and prop inside client, the way ox_inventory's own water and burger do.
Add them to qb-core/shared/items.lua — on QBox with qs-inventory, to qs-inventory/shared/items.lua:
['water_bottle'] = { name = 'water_bottle', label = 'Water', weight = 500, type = 'item', image = 'water_bottle.png', unique = false, useable = true, shouldClose = true, description = 'Bottle of fresh water' },
['cola'] = { name = 'cola', label = 'Cola', weight = 350, type = 'item', image = 'cola.png', unique = false, useable = true, shouldClose = true, description = 'A cold cola' },
['orange_soda'] = { name = 'orange_soda', label = 'Orange Soda', weight = 350, type = 'item', image = 'orange_soda.png', unique = false, useable = true, shouldClose = true, description = 'Orange flavoured soda' },
['energy_drink'] = { name = 'energy_drink', label = 'Energy Drink', weight = 350, type = 'item', image = 'energy_drink.png', unique = false, useable = true, shouldClose = true, description = 'Wings not included' },
['beer'] = { name = 'beer', label = 'Beer', weight = 500, type = 'item', image = 'beer.png', unique = false, useable = true, shouldClose = true, description = 'A cold one' },
['sprunk'] = { name = 'sprunk', label = 'Sprunk', weight = 350, type = 'item', image = 'sprunk.png', unique = false, useable = true, shouldClose = true, description = 'The refreshing choice' },
['lime_soda'] = { name = 'lime_soda', label = 'Lime Soda', weight = 350, type = 'item', image = 'lime_soda.png', unique = false, useable = true, shouldClose = true, description = 'Lime flavoured soda' },
['chips'] = { name = 'chips', label = 'Chips', weight = 100, type = 'item', image = 'chips.png', unique = false, useable = true, shouldClose = true, description = 'A bag of chips' },
['chocolate'] = { name = 'chocolate', label = 'Chocolate', weight = 100, type = 'item', image = 'chocolate.png', unique = false, useable = true, shouldClose = true, description = 'A chocolate bar' },
['nuts'] = { name = 'nuts', label = 'Nuts', weight = 100, type = 'item', image = 'nuts.png', unique = false, useable = true, shouldClose = true, description = 'A bag of salted nuts' },
['candy'] = { name = 'candy', label = 'Candy', weight = 50, type = 'item', image = 'candy.png', unique = false, useable = true, shouldClose = true, description = 'Sweet candy' },
['cookies'] = { name = 'cookies', label = 'Cookies', weight = 150, type = 'item', image = 'cookies.png', unique = false, useable = true, shouldClose = true, description = 'Freshly baked cookies' },
['donut'] = { name = 'donut', label = 'Donut', weight = 150, type = 'item', image = 'donut.png', unique = false, useable = true, shouldClose = true, description = 'Cops love them' },
['cupcake'] = { name = 'cupcake', label = 'Cupcake', weight = 150, type = 'item', image = 'cupcake.png', unique = false, useable = true, shouldClose = true, description = 'A sweet cupcake' },
['coffee'] = { name = 'coffee', label = 'Coffee', weight = 200, type = 'item', image = 'coffee.png', unique = false, useable = true, shouldClose = true, description = 'Hot coffee' },
['espresso'] = { name = 'espresso', label = 'Espresso', weight = 150, type = 'item', image = 'espresso.png', unique = false, useable = true, shouldClose = true, description = 'Short and strong' },
['cappuccino'] = { name = 'cappuccino', label = 'Cappuccino', weight = 200, type = 'item', image = 'cappuccino.png', unique = false, useable = true, shouldClose = true, description = 'Coffee with milk foam' },
['lockpick'] = { name = 'lockpick', label = 'Lockpick', weight = 100, type = 'item', image = 'lockpick.png', unique = false, useable = true, shouldClose = true, description = 'Opens what is not yours' },useable = true only marks the item as usable — what it does when used comes from your consumables script.
On ESX, inventories that read the items table — qs-inventory and ESX's own — need every product there. An item missing from that table cannot be carried, whatever any Lua file says. Import [sql]/items_esx.sql, or run:
INSERT IGNORE INTO `items` (`name`, `label`, `weight`, `rare`, `can_remove`) VALUES
('water_bottle', 'Water', 1, 0, 1),
('cola', 'Cola', 1, 0, 1),
('orange_soda', 'Orange Soda', 1, 0, 1),
('energy_drink', 'Energy Drink', 1, 0, 1),
('beer', 'Beer', 1, 0, 1),
('sprunk', 'Sprunk', 1, 0, 1),
('lime_soda', 'Lime Soda', 1, 0, 1),
('chips', 'Chips', 1, 0, 1),
('chocolate', 'Chocolate', 1, 0, 1),
('nuts', 'Nuts', 1, 0, 1),
('candy', 'Candy', 1, 0, 1),
('cookies', 'Cookies', 1, 0, 1),
('donut', 'Donut', 1, 0, 1),
('cupcake', 'Cupcake', 1, 0, 1),
('coffee', 'Coffee', 1, 0, 1),
('espresso', 'Espresso', 1, 0, 1),
('cappuccino', 'Cappuccino', 1, 0, 1),
('lockpick', 'Lockpick', 1, 0, 1);Drop rare and can_remove if your table does not have them. The items table has no image column, so the owner's panel shows a default picture for these products — buying and stock are not affected.
On tgiann-inventory, codem-inventory or origen_inventory, declare them wherever that inventory keeps its item list.
Product icons#
Copy the icons from [img]/ into your inventory's image folder:
Inventory | Folder |
|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
Creator Access#
Placing, editing and deleting machines happens in the creator, opened with /vendingcreator. It opens for either of these:
Automatic, nothing to configure. On ESX, the admin and superadmin groups. On QBCore and QBox, the admin and god permissions, and anyone allowed the command ace.
Config.CreatorJobs in config/main.lua lets players with a job in as well:
Config.CreatorJobs = {
{ job = 'police', grade = false }, -- every grade
{ job = 'mechanic', grade = { 3, 4 } }, -- only grades 3 and 4
}grade is false for every grade, or a list of the grades allowed. Write a single grade as a list too — { 4 }, not 4.
Configuring the Resource#
Every setting lives in config/main.lua, outside escrow. The rest of the editable files are for plumbing:
File | Contents |
|---|---|
| Language, price format, creator jobs, payment accounts, ownable machines, robberies, the phone, machine types, prompt height, sounds and debug. |
| Every text players see, in 41 languages. |
| The ESX and QBCore bridges, notifications, the prompts and the police alert. |
| One bridge per inventory: the item list and where its pictures live. |
The values worth reviewing first:
Config.Locale = 'en' -- 41 languages in locales/
Config.Intl = { -- how prices are written in the panels
locales = 'en-US',
options = { style = 'currency', currency = 'USD', minimumFractionDigits = 0 },
}
Config.CreatorJobs = { ... } -- jobs allowed into the creator, besides admins
Config.Ownable.enabled = true -- machines players can buy
Config.Robbery.enabled = true -- break-ins
Config.Robbery.allowSelfRobbery = false -- testing only
Config.Phone.enabled = true -- the VendGo app
Config.Debug = false -- console output, testing onlyUsage explains every setting, and Integrations every file.
Verifying the Installation#
After completing the installation, restart your server and read the console. The bridge for your framework reports itself:
[INFO] Successfully loaded the framework. esxIf a red [ERROR] Using standalone inventory line repeats every few seconds instead, no supported inventory was running when the resource started — move its ensure above ensure qs-vendingmachine-creator.
Then join your server and work through the first loop:
Use a machine on the map
Walk up to any eCola machine in the city.
[E] - Use Drink Machineappears; pick a product and your character buys it.Place a machine of your own
/vendingcreator→ + → Apply Template → Select under Placement, aim, left click → Create Machine. It appears for every player at once.Put it up for sale
Turn on For sale, save, and walk up to it:
[E] - Buy machine. Once bought, the prompt becomes[E] - Manageand opens the owner's panel. Usage takes it from there.
Players pay but receive nothing until the products exist in your inventory — see The Products above.



