Mining Operations
A comprehensive guide to installing and configuring the Mining Job. Includes Setup, Database, Items, and a line-by-line explanation of the configuration.
Database Installation
You must run this SQL query to create the table where player levels, XP, and equipment tiers are saved.
- Open HeidiSQL or phpMyAdmin.
- Select your server database.
- Go to the Query tab, paste the code below, and run it.
CREATE TABLE IF NOT EXISTS `xada_mining` (
`identifier` varchar(60) NOT NULL, -- Steam Hex / Citizen ID
`level` int(11) DEFAULT 1, -- Player Level
`xp` int(11) DEFAULT 0, -- Current XP
`equipment_tier` int(11) DEFAULT 1,-- Drill Level (1-3)
`truck_tier` int(11) DEFAULT 1, -- Truck License (1-3)
`processing_tier` int(11) DEFAULT 0, -- Refinery Upgrade
`scanner_tier` int(11) DEFAULT 0, -- Gem Scanner
`total_earned` int(11) DEFAULT 0, -- Total Money Made
`total_mined` int(11) DEFAULT 0, -- Total Rocks Mined
`deliveries_completed` int(11) DEFAULT 0, -- Total Runs
PRIMARY KEY (`identifier`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;Item Setup
Add the required items to your inventory system. Only use the section matching your framework.
Option A: Ox Inventory
ox_inventory/data/items.lua
['sandstone'] = { label = 'Raw Sandstone', weight = 1000, stack = true },
['refined_sand'] = { label = 'Refined Sand', weight = 500, stack = true },
['limestone'] = { label = 'Raw Limestone', weight = 1200, stack = true },
['concrete_mix'] = { label = 'Concrete Mix', weight = 800, stack = true },
['iron_ore'] = { label = 'Iron Ore', weight = 1500, stack = true },
['steel_ingot'] = { label = 'Steel Ingot', weight = 1000, stack = true },
['paydirt_bag'] = { label = 'Paydirt Bag', weight = 800, stack = true },
['washed_gravel'] = { label = 'Washed Gravel', weight = 200, stack = true },
['diamond'] = { label = 'Rough Diamond', weight = 10, stack = true },
['emerald'] = { label = 'Rough Emerald', weight = 10, stack = true },
['sapphire'] = { label = 'Rough Sapphire', weight = 10, stack = true },
['gold'] = { label = 'Gold Nugget', weight = 20, stack = true },Option B: QB-Core
qb-core/shared/items.lua
['sandstone'] = {['name'] = 'sandstone', ['label'] = 'Raw Sandstone', ['weight'] = 1000, ['type'] = 'item', ['image'] = 'sandstone.png', ['unique'] = false, ['useable'] = false, ['shouldClose'] = false, ['combinable'] = nil, ['description'] = 'Raw sandstone debris.'},
['refined_sand'] = {['name'] = 'refined_sand', ['label'] = 'Refined Sand', ['weight'] = 500, ['type'] = 'item', ['image'] = 'refined_sand.png', ['unique'] = false, ['useable'] = false, ['shouldClose'] = false, ['combinable'] = nil, ['description'] = 'Refined sand for construction.'},
['limestone'] = {['name'] = 'limestone', ['label'] = 'Raw Limestone', ['weight'] = 1200, ['type'] = 'item', ['image'] = 'limestone.png', ['unique'] = false, ['useable'] = false, ['shouldClose'] = false, ['combinable'] = nil, ['description'] = 'Heavy limestone rock.'},
['concrete_mix'] = {['name'] = 'concrete_mix', ['label'] = 'Concrete Mix', ['weight'] = 800, ['type'] = 'item', ['image'] = 'concrete_mix.png', ['unique'] = false, ['useable'] = false, ['shouldClose'] = false, ['combinable'] = nil, ['description'] = 'Industrial concrete mix.'},
['iron_ore'] = {['name'] = 'iron_ore', ['label'] = 'Iron Ore', ['weight'] = 1500, ['type'] = 'item', ['image'] = 'iron_ore.png', ['unique'] = false, ['useable'] = false, ['shouldClose'] = false, ['combinable'] = nil, ['description'] = 'Unrefined iron ore.'},
['steel_ingot'] = {['name'] = 'steel_ingot', ['label'] = 'Steel Ingot', ['weight'] = 1000, ['type'] = 'item', ['image'] = 'steel_ingot.png', ['unique'] = false, ['useable'] = false, ['shouldClose'] = false, ['combinable'] = nil, ['description'] = 'Pure steel ingot.'},
['paydirt_bag'] = {['name'] = 'paydirt_bag', ['label'] = 'Paydirt Bag', ['weight'] = 800, ['type'] = 'item', ['image'] = 'paydirt_bag.png', ['unique'] = false, ['useable'] = false, ['shouldClose'] = false, ['combinable'] = nil, ['description'] = 'A bag of dirty river mud.'},
['washed_gravel'] = {['name'] = 'washed_gravel', ['label'] = 'Washed Gravel', ['weight'] = 200, ['type'] = 'item', ['image'] = 'washed_gravel.png', ['unique'] = false, ['useable'] = false, ['shouldClose'] = false, ['combinable'] = nil, ['description'] = 'Worthless rocks.'},
['diamond'] = {['name'] = 'diamond', ['label'] = 'Rough Diamond', ['weight'] = 10, ['type'] = 'item', ['image'] = 'diamond.png', ['unique'] = false, ['useable'] = false, ['shouldClose'] = false, ['combinable'] = nil, ['description'] = 'A shiny rough diamond.'},
['emerald'] = {['name'] = 'emerald', ['label'] = 'Rough Emerald', ['weight'] = 10, ['type'] = 'item', ['image'] = 'emerald.png', ['unique'] = false, ['useable'] = false, ['shouldClose'] = false, ['combinable'] = nil, ['description'] = 'A green gemstone.'},
['sapphire'] = {['name'] = 'sapphire', ['label'] = 'Rough Sapphire', ['weight'] = 10, ['type'] = 'item', ['image'] = 'sapphire.png', ['unique'] = false, ['useable'] = false, ['shouldClose'] = false, ['combinable'] = nil, ['description'] = 'A blue gemstone.'},
['gold'] = {['name'] = 'gold', ['label'] = 'Gold Nugget', ['weight'] = 20, ['type'] = 'item', ['image'] = 'gold.png', ['unique'] = false, ['useable'] = false, ['shouldClose'] = false, ['combinable'] = nil, ['description'] = 'A heavy gold nugget.'},Option C: ESX Legacy
Run this SQL Query:
INSERT INTO `items` (`name`, `label`, `weight`, `rare`, `can_remove`) VALUES
('sandstone', 'Raw Sandstone', 1000, 0, 1),
('refined_sand', 'Refined Sand', 500, 0, 1),
('limestone', 'Raw Limestone', 1200, 0, 1),
('concrete_mix', 'Concrete Mix', 800, 0, 1),
('iron_ore', 'Iron Ore', 1500, 0, 1),
('steel_ingot', 'Steel Ingot', 1000, 0, 1),
('paydirt_bag', 'Paydirt Bag', 800, 0, 1),
('washed_gravel', 'Washed Gravel', 200, 0, 1),
('diamond', 'Rough Diamond', 10, 1, 1),
('emerald', 'Rough Emerald', 10, 1, 1),
('sapphire', 'Rough Sapphire', 10, 1, 1),
('gold', 'Gold Nugget', 20, 1, 1);Adding Images
Copy all .png files from the img/ folder in the download to your inventory images folder.
- Ox Inventory:
ox_inventory/web/images/ - QB Inventory:
qb-inventory/html/images/ - QS Inventory:
qs-inventory/html/img/
Line-by-Line Configuration
Below is a complete breakdown of modules/mining/config.lua.
Core & Framework
Config.Debug = false
Config.Locale = 'en'
Config.Framework = 'qb'
Config.InteractionType = 'textui'
Config.InventorySystem = 'ox'Debug: If true, it draws red boxes around locations and prints extra info in console (F8). Useful if you are editing locations.Locale: Matches a file in thelocales/folder (e.g., 'en', 'fr', 'es').Framework: Set to'esx'or'qb'. This auto-detects your job and money functions.InteractionType:'textui': Shows a popup "Press E to Mine".'target': Uses ox_target or qb-target (Third Eye).
InventorySystem: Set to'ox','qb','qs', or'esx'. This ensures the script checks for items correctly.
UI Providers
Config.NotifyProvider = 'xada'
Config.TextUIProvider = 'xada'
Config.ProgressProvider = 'xada'These control the visual style.
• 'xada' uses the xada_lib included in your download (Modern Look).
• 'ox' uses standard ox_lib styling.
• 'esx' / 'qb' uses legacy notifications.
Discord Webhook Setup
Config.Discord = {
Enabled = true,
Webhook = "", -- PASTE HERE
BotName = "Mining Logistics",
...
}How to get a Webhook URL:
- Open your Discord Server settings.
- Go to Integrations → Webhooks.
- Click New Webhook.
- Name it (e.g., "Mining Logs") and choose a channel.
- Click Copy Webhook URL.
- Paste it inside the
Webhook = "PASTE_HERE"quotes.
Progression System
Config.Leveling = {
BaseXP = 500,
Multiplier = 1.2,
MaxLevel = 50
}BaseXP: XP needed to go from Level 1 to 2.Multiplier: The difficulty curve.
Example: Level 2 requires500 * 1.2 = 600 XP.
Level 3 requires600 * 1.2 = 720 XP.MaxLevel: The hard cap. Players cannot level up past this.
Locations & Blips
Config.JobCenter = {
Location = vector3(2946.5, 2746.9, 43.4),
Marker = {
Enable = true,
Type = 27, -- Standard Cylinder
Color = {r = 255, g = 165, b = 0, a = 150}, -- RGBA Color
},
Blip = {
Enable = true,
Sprite = 478, -- The Map Icon ID
Color = 5, -- The Map Icon Color
Scale = 0.8, -- Size
Name = "Davis Quartz Logistics" -- Map Name
}
}To change the location, use /coords in-game and replace the vector3 numbers.
Note: Config.Processing and Config.Export work exactly the same way.
Job Contracts
This defines the actual jobs. Do not change the ID unless you also change the database/item name.
[1] = {
id = 'sandstone', -- Internal ID (Matches Item Name)
label = 'Raw Sandstone',-- Name shown in Menu
level = 1, -- Min Level required
xp = 50, -- XP earned per action
prop = 'prop_rock_1_a', -- The rock object to spawn
payout = {min = 150, max = 300}, -- Visual estimate shown in UI
sellPrice = 250, -- Actual money given per item sold
locations = { ... }, -- List of coordinates where rocks spawn
-- Refining Logic
recipe = {
input = "sandstone", -- Item taken
output = "refined_sand", -- Item given
duration = 5000 -- Time in ms
}
}Equipment Shop
Config.Equipment = {
{
category = "Extraction Tools",
id = "drills",
items = {
{
id = "drill_t1", -- Unique ID
label = "Rusted Jackhammer",
price = 0, -- Cost
level = 1, -- Level Req
tier = 1 -- DB Value (1 = Slow, 3 = Fast)
},
}
}
}Important: These are not physical items. When a player buys "Drill T2", the script updates their equipment_tier column in the database to 2. It does not give a physical drill item. The script checks this tier to decide how fast you mine.