How the File Is Organised#
Everything is configured in qs-treasure-hunter/config/config.lua, split into numbered sections. The text players read lives beside it in config/translations.lua.
Section | What it holds |
|---|---|
1. General | Detection, who can hunt, interaction, names, panel buttons, notifications and money. |
2. World | The blip, the job NPC and the boat rental. |
3. Hunts | The three missions and where each one takes place. |
4. Loot | What every chest can contain and what the shop pays for it. |
5. Levels | The experience curve, the perks, crew size and invite distance. |
6. Shop | The buy catalogue, free tools, keys and maps. |
7. Equipment | The metal detector, the diving gear and the ancient chest puzzle. |
8. Legendary | The server-wide legendary chest event. |
9. Leaderboard | Refresh rate, list size and the rewards. |
10–11. Marker, Debug | The floating marker over the NPC and console tracing. |
Webhooks, payout | Discord logs and how a crew is paid, at the end of the file. |
Sections 1, 5, 6 and 9 are the ones most servers change. Sections 2 to 4, 7 and 8 are content tables: edit the values and keep the structure.
This file is the single source of truth. Locations, loot, experience, prices and payouts are all read on the server and never re-sent by a client, so what you set here is exactly what anything is worth. Restart the resource after editing it.
General#
Option | Default | What it does |
|---|---|---|
| auto | Detected from the running resources. Leave the lines as they are. |
|
|
|
|
| Jobs allowed to hunt. Add as many as you need. |
|
| Third-eye targeting with |
|
| Floating "[E]" prompts. Off shows a hint line instead; both work the same. |
|
| Control ids for interacting (38) and for the boat's anchor (47), plus the anchor label the HUD shows. |
|
|
|
| Old Hank | The name and line on the card beside the NPC. |
|
| The panel's footer buttons. The boat rental is a shop tab, so it needs the shop on. |
|
|
|
|
|
|
|
| Locks qs-inventory during the diving outfit change. |
|
| Swaps the player into the diving outfit while the gear is on. |
|
| Creates the treasure hunter quests in qs-inventory and reports progress. |
|
| Registers the usable items through the framework, for inventories without |
World#
Config.EnableBlip and Config.Blip set the job blip. Config.StartJob.ped is the one NPC that opens everything — move it by changing its coords (with heading) and model. Config.AreaBlipColor colours the search circle and Config.AncientTreasureBlip marks an ancient site.
The boat rental#
Config.BoatRental = {
Enabled = true,
Spawn = vec4(2102.45, 3921.49, 29.65, 0.0), -- Z at water level, used as given
ReturnRadius = 45.0, -- metres from Spawn to hand a boat back
Refund = 40, -- % of the price paid back on return
ReturnTo = vector3(2104.51, 3902.32, 31.52), -- nil leaves the player where they are
WarnBefore = 120, -- seconds of warning before a rental runs out
Tiers = {
{ model = 'dinghy', label = 'Dinghy', requiredLevel = 1, price = 60,
minutes = 20, seats = 4, image = 'https://docs.fivem.net/vehicles/dinghy.webp' },
-- ...
},
}Each tier is a model, the level that unlocks it, its price, how many minutes it lasts (0 never expires), its seats and the picture the shop and the HUD draw. Config.BoatFadeTime is the fade in milliseconds, and Config.Fuel with Config.FuelExport fills the tank on spawn.
Hunts#
Config.Tasks holds the three missions the panel offers:
{
taskOrder = 1, -- do not touch
key = "detector", -- do not touch: detector, underwater or ancient
name = "Metal Detector Hunt",
img = "metal_detector_task.png",
description = "Sweep the marked area and dig up what the detector finds.",
recommendedPlayers = { 1, 4 }, -- shown on the panel, not enforced
levelRequired = 1, -- every crew member needs it
chestAmount = { 2, 3 }, -- { min, max } chests per run
chestExperience = 50, -- to whoever opens each chest
experience = 1000, -- for completing the hunt
money = 2000, -- for completing the hunt
},Where the hunts happen is three more tables. For the detector and underwater hunts a zone is picked at random, then a search circle centred somewhere inside its rectangle, then the chests inside that circle:
Config.MetalDetectorTreasureLocations = {
{ minX = 2060.0, maxX = 2226.0, minY = 3786.0, maxY = 3891.0, z = 32.0, areaRange = 50.0 },
}
Config.UnderwaterTreasureChestLocations = { -- keep these over water
{ minX = 167.0, maxX = 430.0, minY = 3989.0, maxY = 4064.0, z = 28.0, areaRange = 70.0 },
}
Config.AncientTreasureChestLocations = { -- exact positions, one picked per run
vector3(-3033.83, 3439.12, 4.94),
}z is only a fallback: each client finds the real ground or sea bed under every chest. areaRange is the radius of the circle on the map. Config.TreasureModels lists the props a sunken crate can be.
Loot#
Config.TreasureDrop (detector), Config.TreasureUnderwaterDrop and Config.AncientTreasureDrop say what each chest can hold:
Config.AncientTreasureDrop = {
{ name = "gold_ring", chance = 25, price = 300, maxAmount = 5 },
{ name = "gold_bracelet", chance = 25, price = 400, maxAmount = 5 },
{ name = "gold_necklace", chance = 20, price = 500, maxAmount = 5 },
{ name = "gold_nugget", chance = 15, price = 800, maxAmount = 5 },
{ name = "painting", chance = 15, price = 1000, maxAmount = 5 },
}A roll from 1 to 100 walks the list in order and the first entry it reaches wins, so list them commonest first: the rare-find perk upgrades a find to the next entry down. Chances do not have to add up to 100; a roll past the end falls back to the first entry. The amount is 1 to maxAmount, doubled by the extra-loot perk.
price is what the shop pays per unit, so these tables are also the sell catalogue. An item in two tables sells at the higher price.
Levels#
Config.LevelExperience = {
BaseExperience = 3500, -- experience for level 1
GrowthFactor = 1.1, -- each level needs this much more
DetectorRange = 1.0, -- % per level
OxygenBonus = 1.0,
DigSpeed = 0.8,
ExtraLoot = 0.5,
RareFind = 0.4,
}
Config.MaxBonusLevel = 60 -- perks stop growing here; levels do not
Config.MaxPartyMembers = 4 -- crew size, leader included
Config.InviteDistance = 20.0 -- metres, 0 = invite from anywhereA level needs BaseExperience × GrowthFactor^(level − 1). Set a perk to 0 to turn it off. Raising InviteDistance well past streaming range works, but members invited from far away show their initials instead of their face.
Shop#
Each Config.Shop row is one item for sale:
Field | Meaning |
|---|---|
| The item given, the name on the row and the cost per unit. |
| Level needed to buy it. |
|
|
| A line under the name, and a "one use" tag. |
|
|
Option | Default | What it does |
|---|---|---|
| 100 | Most of one item bought at once. |
|
| Hands a detector or diving gear to a hunter who starts without one, once per 15 minutes. |
|
| Each sunken crate needs a |
|
| The ancient chest needs an |
| 20 m / 25 m | Which hunt each map belongs to ( |
| 4000 ms | The reading animation, its paper prop, the bone and the duration. |
Equipment#
Option | Default | What it does |
|---|---|---|
|
| A short animation when the detector is taken out or put away. |
|
|
|
| 15 / 5 | Metres at which a chest first registers ( |
| 8000 | Milliseconds a dig takes at level 1. Never below 1.5 s. |
|
| The built-in diving gear and air. Turn it off when another resource handles diving. |
| 180 / 5 | Seconds of air in a full tank at level 1, and seconds regained per second out of the water. |
| 3 phrases | The phrases an ancient chest can ask for. One is picked per chest. |
| a–z, A–Z, 0–9, signs | The alphabet the cipher shuffles. Characters outside it pass through unchanged. |
| 3000 / 12000 / 25 / 5 |
|
| gold | Colour, range and intensity of the glow on crates and on an opened chest. |
Legendary Chest#
Config.LegendaryChestEvent = {
enabled = true,
chance = 20, -- % chance a cracked ancient chest wakes it
coords = vec4(487.06, 5586.50, 793.95, 300.0),
shakeScreen = true,
notifyAllPlayers = true, -- false: only players who can hunt are told
duration = 900, -- seconds before it sinks (0 = never)
blip = { name = "Legendary Chest", sprite = 587, size = 1.4, color = 1, display = 4 },
rewards = {
{ name = "gold_nugget", chance = 60, price = 800, minAmount = 20, maxAmount = 30 },
{ name = "painting", chance = 40, price = 1000, minAmount = 20, maxAmount = 30 },
},
puzzleTexts = { "Only the brave may open what time itself has sealed", --[[ ... ]] },
}Leaderboard#
Config.UpdateLeaderboard = 1 -- minutes between refreshes
Config.MaxLeaderboardPlayers = 100 -- rows per tab
Config.LeaderBoardRewards = {
Daily = { [1] = 550, [2] = 350, [3] = 200 }, -- every day at 00:00
Season = { [1] = 5000, [2] = 3500, [3] = 2000 }, -- 00:00 on the 1st of the month
}MaxLeaderboardPlayers is also the limit on the database query, so a higher number costs query time on every refresh. With Config.EnableLeaderboard off, no ranking is read, reset or paid.
Marker and Debug#
Config.PedMarker is the floating marker over the NPC: enabled, its type (a FiveM marker id), height above the head, view distance, bob, size and RGBA color.
Config.Debug = true makes the script narrate what it is doing in the server console and the F8 console. Leave it off on a live server — it prints a lot.
How a Crew Is Paid#
Config.MissionPayout = 'members' -- or 'split''members' pays every member the hunt's full money and experience, so a crew of four on a $2,000 hunt costs $8,000. 'split' divides both between the members present at the end, rounded down and never below 1. A hunt does not ask for more chests from a bigger crew, so 'members' is the generous setting; it ships as the default so an existing economy does not move.
Translations#
Set Config.Language in config/translations.lua to en, es, fr, de, it, pt, ru or tr, and edit the text inside the quotation marks. English is the reference: any key a language leaves out is filled from it, so a raw key name never shows in game. The guide's steps are translation keys too, so they can be reworded without touching code.
Webhooks are at the end of the same file; Integrations covers them along with the diving outfit and notifications.



