shared/config.lua
Owner options in shared/config.lua, what each value does.
Edit options in shared/config.lua. Framework, inventory, notify, job, and skill bridges live in client/edit.lua and server/edit.lua. Do not put that logic in this file.
Restart gs_metaldetect after you change config. Item spawn names here must match Items. Player loop: Using the detector.
Debug, framework, locale, inventory
Config.Debug = false
Config.Framework = "auto" -- qbcore | qbox | esx | custom
Config.Locale = 'en' -- en | es | pt | de | fr | pl
Config.Inventory = "auto" -- ox_inventory | custom| Option | What it does |
|---|---|
Debug | Extra [gs-metaldetect] prints on the server. Leave false on a live city. |
Framework | "auto" uses the first started of qb-core, then qbx_core, then es_extended. Force a name if auto is wrong. "custom" skips the built-in core object. You then fill client/edit.lua and server/edit.lua. If auto finds no qb/esx core, it also falls back to "custom". |
Locale | Loads locales/<code>.json. See Localization. |
Inventory | "auto" uses ox_inventory when that resource is started, otherwise the framework inventory. "ox_inventory" forces ox. "custom" skips ox and the framework inventory. Fill the inventory functions in server/edit.lua. |
Sites
The server builds a pool of buried targets at start, then slowly replaces collected ones.
Config.Sites = {
total = 100,
maxTargetsRange = 120.0,
respawnIntervalMs = 15 * 60 * 1000,
respawnBatch = 4,
maxActive = 120,
}| Field | What it does |
|---|---|
total | How many sites to spawn when the resource starts. Picked from Config.Zones using each zone's weight. |
maxTargetsRange | How far (meters) the client looks for nearby sites while scanning. Keep this at or above your longest Config.Scan.bars distance. |
respawnIntervalMs | Milliseconds between respawn ticks. Default is 15 minutes. |
respawnBatch | How many new sites appear each tick. |
maxActive | Hard cap. Respawn will not go above this, even if total is higher. |
There is no database. All sites are in memory and reset on resource restart.
Hotspot blips
Optional map markers for type = 'hotspot' zones only. General zones never get a blip.
Config.HotspotBlips = {
enabled = true,
requireDetector = true,
sprite = 485,
color = 46,
scale = 0.65,
shortRange = true,
showRadius = true,
radiusAlpha = 80,
}| Field | What it does |
|---|---|
enabled | Master switch for hotspot blips. |
requireDetector | true shows blips only while a detector is equipped. false always shows them. |
sprite / color / scale | Standard GTA blip look. |
shortRange | true hides the blip when the player is far (GTA short-range blips). |
showRadius | Draws a radius circle matching the zone radius. |
radiusAlpha | Circle opacity, 0 to 255. |
Battery
Charge is stored on the detector item (metadata.charge on ox_inventory, info.charge on QBCore). Using a battery while a detector is equipped writes a new charge and consumes one battery.
Config.Battery = {
item = 'battery',
installCharge = 100,
drainIntervalMs = 12000,
}| Field | What it does |
|---|---|
item | Inventory spawn name. Must match the battery you pasted in Items. Skip adding a new battery item if you already have this name. |
installCharge | Charge written after a successful install, 0 to 100. Default fills the detector. |
drainIntervalMs | How often charge ticks down while scanning, in milliseconds. Actual amount removed per tick comes from the equipped detector's drainPerTick (and GetSkillProfile.drainMultiplier). |
A dead detector still equips. The LCD shows NO PWR and digging is blocked until a battery is installed.
Detectors
Each row is one usable item. Use the item to equip or put away. Add more rows if you want extra tiers.
Config.Detectors = {
{
item = 'metaldetector',
label = 'Basic Detector',
rangeMultiplier = 1.0,
digRadius = 2.5,
drainPerTick = 3.0,
},
}| Field | What it does |
|---|---|
item | Inventory spawn name. Must match Items. |
label | Name shown on the LCD and in start notifies. |
rangeMultiplier | Scales scan reach. 1.0 is the Config.Scan.bars table as written. 1.5 treats sites as closer (Pro). Skill scanClarityBonus adds on top (0.2 = another +20%). |
digRadius | Meters to the site before the HUD switches to [E] Dig. If omitted, Config.Scan.digRadius is used. |
drainPerTick | Charge subtracted every Config.Battery.drainIntervalMs while scanning. Higher = dies faster. |
Bundled defaults: Basic 1.0 / 3.0 drain, Advanced 1.25 / 2.0, Pro 1.5 / 1.0.
Prop
World model in the player's hand while scanning. The ytyp is requested from stream/. If the model is missing, the client shows error.model_missing.
Config.Prop = {
model = `w_am_metaldetect`,
bone = 18905,
offset = vector3(0.15, 0.1, 0.0),
rotation = vector3(270.0, 90.0, 80.0),
animDict = 'mini@golfai',
animClip = 'wood_idle_a',
animFlag = 49,
}| Field | What it does |
|---|---|
model | Prop hash. Keep the streamed w_am_metaldetect unless you ship a replacement. |
bone | Ped bone index the prop attaches to. 18905 is the right hand. |
offset / rotation | Position and rotation relative to that bone. Nudge these if the coil clips the ground or the hand. |
animDict / animClip | Idle hold animation while scanning. |
animFlag | Playback flag. 49 is upper-body, moveable. |
Scan
Signal bars, facing, keys, and dig timing.
Config.Scan = {
bars = {
{ dist = 100.0, bars = 0, wait = 9000 },
{ dist = 80.0, bars = 1, wait = 7500 },
-- closer rows...
{ dist = 0.0, bars = 10, wait = 400 },
},
facingDegrees = 25.0,
digControl = 38,
stopControl = 75,
audioControl = 140,
digRadius = 2.5,
digCooldownMs = 2500,
}bars: keep rows sorted far to near. The client walks the list and uses the first row where current distance is greater than dist. bars is LCD fill (0 to 10). wait is milliseconds between beeps. Closer sites beep faster.
Effective distance is realDistance * zone.difficulty / detector.rangeMultiplier. A hotspot at difficulty = 1.0 with a Pro detector (1.5) feels closer than a difficulty = 1.35 inland zone with a Basic detector.
| Field | What it does |
|---|---|
facingDegrees | How closely the player must face the site to lock the directional hint (Signal locked, move closer). Smaller = pickier. |
digControl | GTA control index to dig. 38 is E. |
stopControl | Put the detector away. 75 is F. |
audioControl | Toggle beeps. 140 is R. Does nothing at 0 charge. |
digRadius | Fallback dig range if a detector row omits digRadius. |
digCooldownMs | Milliseconds after a successful dig before the next one. GetSkillProfile.digCooldownMs overrides this per player when it is a number. |
These are control indexes, not ox_lib keybinds. Players rebind them in GTA Settings.
Loot
When a player digs, the server picks a pool, then a drop inside that pool.
Config.Loot = {
bands = {
common = 72,
uncommon = 22,
valuable = 6,
hotspotValuableBonus = 3,
},
common = {
{ 'metalscrap', {12, 22}, 32, 'SCRAP' },
},
uncommon = { -- ...
},
valuable = { -- ...
},
}bands are relative odds, not percents. Default 72 + 22 + 6 = 100, so common is 72% inland. In a type = 'hotspot' zone, hotspotValuableBonus is added to the valuable weight (6 + 3 here). Skill lootWeightMultipliers can scale any of those four keys (see server/edit.lua).
Each drop can be a list or a table:
{ 'metalscrap', {12, 22}, 32, 'SCRAP' }
-- item, count (number or {min, max}), weight inside this pool, LCD reading
{ item = 'rolex', count = 1, weight = 8, reading = 'GOLD' }| Field | What it does |
|---|---|
| item | Inventory spawn name given to the player. Change these to names that exist on your server. Missing items fail the give. |
| count | Fixed number, or { min, max } rolled inclusive. |
| weight | Chance inside that pool. Higher is more likely. |
| reading | LCD category when the site is identified: SCRAP, COPPER, STEEL, PARTS, TECH, SILVER, GOLD. Locale keys are ui.scrap and so on. |
Loot items are not in items/items.lua. Only detectors and battery are. If CanCarryItem fails, the dig is rejected and the site stays.
Zones
Sites spawn inside these circles. Add, remove, or move rows to fit your map.
{ name = 'vespucci_beach', type = 'hotspot', coords = vector3(-1433.52, -1323.54, 3.55), radius = 95.0, weight = 14, difficulty = 1.0 },| Field | What it does |
|---|---|
name | Id for logs and your own notes. Keep it unique. |
type | 'hotspot' gets blips (if enabled) and the valuable band bonus. 'general' is inland / park / street detecting. |
coords | Center. Z should sit on the ground. |
radius | Meters from center. Sites are placed at a random point inside the circle. |
weight | How often this zone is chosen when spawning or respawning. Beach hotspots ship higher than inland rows. |
difficulty | Multiplies scan distance. 1.0 is baseline. Above 1.0 makes the signal feel weaker (player must get closer). Grove Street ships at 1.35. |
Related: Integrations for job gates and skill scaling.
