lation scripts
scriptsmembershipdocs
see the scripts
Skip to Content
lation ui
lation interact
lation banking
lation shops
lation jobs
lation weed
lation chop shop

classics

money laundering
drug sales
coke processing
meth crafting
metal detecting
DetectingConfigurationDevelopersChangelog
scuba diving
metal detecting

Developers

The metal detecting client and server exports, its notify event, the hooks in its open files, and the bridge you edit for another framework, inventory or interface.

Every export is called on exports.lation_detecting. Server exports that act on a player take their server id as source; client exports work on the local player. A player's identifier is the ESX identifier on ESX and the citizenid on Qbox and QBCore.

Server exports

ExportReturns
GetPlayerData(source, type?)A player's record, or one field of it
AddPlayerData(source, dataType, amount)Nothing
GetLevelData()The XP for each level

GetPlayerData

Server export

local data = exports.lation_detecting:GetPlayerData(source, type)

Parameters

sourcenumber
The player's server id
typestringoptionaldefault nil
One field: level, experience, items_found or money_earned. The whole record when left out.

Returns

table | number | nil
The record (below), or the value of type. nil when the player isn't loaded in your framework.

The first time a player is looked up, a row is made for them at level 1. The record is the cached one, so treat it as read-only and change it with AddPlayerData. A record read from the database also carries identifier.

{
    level = 3,
    experience = 35500,   -- total XP
    items_found = 412,    -- items dug up
    money_earned = 58915, -- paid by the sell shop
}
server.lua
local level = exports.lation_detecting:GetPlayerData(source, 'level')
if level and level >= 3 then
    -- the player can use the Treasure Trove Tracker
end

AddPlayerData

Server export

exports.lation_detecting:AddPlayerData(source, dataType, amount)

Parameters

sourcenumber
The player's server id
dataTypestring
experience, items_found or money_earned
amountnumber
How much to add. Anything 0 or below does nothing.

Returns

Nothing

Adding experience levels the player up past each threshold they cross, shows You just leveled up in metal detecting! and writes the level_up log when it is on. XP stops at the last level's. There is no way to take XP away, and a level added directly is replaced by the level their XP reaches at their next XP gain, so give XP instead.

Nothing is written straight away: the record is saved when the player leaves, when the resource stops and when txAdmin shuts the server down.

server.lua
exports.lation_detecting:AddPlayerData(source, 'experience', 500)

GetLevelData

Server export

local levels = exports.lation_detecting:GetLevelData()

Returns

table
The total XP for each level, keyed by level: Config.Detecting.levels
{ [1] = 0, [2] = 12500, [3] = 25000, [4] = 50000, [5] = 100000 }

Client exports

ExportDoes
OpenMenu()Opens the stats menu
GetPlayerData(type?)Returns the local player's record, or one field
GetLevelData()Returns the XP for each level
OpenDetectorShop()Opens the detector shop
OpenSellShop()Opens the sell shop

OpenMenu

Client export

exports.lation_detecting:OpenMenu()

Opens the stats menu, as /metaldetecting does: Current Level, Current Progress, Items Found and Money Earned.

GetPlayerData (client)

Client export

local data = exports.lation_detecting:GetPlayerData(type)

Parameters

typestringoptionaldefault nil
One field: level, experience, items_found or money_earned. The whole record when left out.

Returns

table | number | nil
The same as the server export, for the local player

It asks the server and waits for the answer, so call it inside a thread or an event handler.

client.lua
CreateThread(function()
    local found = exports.lation_detecting:GetPlayerData('items_found')
    print(('You have dug up %s items'):format(found or 0))
end)

GetLevelData (client)

Client export

local levels = exports.lation_detecting:GetLevelData()

Returns

table
The total XP for each level, keyed by level

OpenDetectorShop

Client export

exports.lation_detecting:OpenDetectorShop()

OpenSellShop

Client export

exports.lation_detecting:OpenSellShop()

Both open the shop's menu wherever the player is: buying and selling don't check the distance to the shopkeeper, so you can put a shop on your own ped, prop or place. The job requirement still applies, and the server still checks every purchase and sale against the player's money and items.

client.lua
exports.ox_target:addModel('a_m_m_beach_01', {
    {
        name = 'md_sell',
        label = 'Sell finds',
        icon = 'fas fa-sack-dollar',
        onSelect = function()
            exports.lation_detecting:OpenSellShop()
        end,
    },
})

Events

lation_detecting:Notify

Client event

TriggerClientEvent('lation_detecting:Notify', source, message, notifyType)

Parameters

messagestring
The text
notifyTypestring
success, error, info and the like, as your notification system reads them

Send it from the server to show a notification through the system set in Config.Setup.notify, titled Metal Detecting.

server.lua
TriggerClientEvent('lation_detecting:Notify', source, 'The beach closes at sunset', 'info')

The script's other events carry its own steps between client and server (lation_detecting:UseDetector, lation_detecting:ItemAssigned, lation_detecting:UseShovel, lation_detecting:StartDigging, lation_detecting:ItemFound, lation_detecting:BuyDetector, lation_detecting:BuyShovel, lation_detecting:SellOne, lation_detecting:SellAll and the bridge's lation_detecting:onPlayerLoaded). Don't trigger them from your own scripts; use the exports and hooks.

Hooks

Hooks are plain functions in the open files: edit them in place, and keep a copy of your changes before you update.

Server hooks

In server/functions.lua.

CanUseDetector

Server hook

function CanUseDetector(source, model)
    return true
end

Parameters

sourcenumber
The player's server id
modelstring
The detector's item name, such as blue_metaldetector

Returns

boolean
true to let the player take the detector out, false to stop them

Runs each time a player uses a detector, after the job, level, area and ban checks. A false stops them without a message, so send your own. GetItemCount is the bridge's.

server/functions.lua
-- Players need a permit to detect
function CanUseDetector(source, model)
    if GetItemCount(source, 'detecting_permit') < 1 then
        TriggerClientEvent('lation_detecting:Notify', source, 'You need a detecting permit', 'error')
        return false
    end
    return true
end

ItemFound

Server hook

function ItemFound(source, model, item, quantity)
end

Parameters

sourcenumber
The player's server id
modelstring
The detector's item name, such as blue_metaldetector
itemstring
The item found, such as md_goldring
quantitynumber
How many

Runs after a find has gone into the player's inventory, before its XP is added. The script shows no message of its own for a find; the inventory's add-item notice tells the player what they got.

server/functions.lua
-- Tell everyone when someone digs up something rare
local rare = { md_presidentialwatch = true, md_platinumnugget = true }

function ItemFound(source, model, item, quantity)
    if rare[item] then
        local message = ('%s dug up something rare on the beach'):format(GetName(source))
        TriggerClientEvent('lation_detecting:Notify', -1, message, 'info')
    end
end

Client hooks

In client/functions.lua. All four are empty.

FunctionRuns
StartedDetecting()When the player takes the detector out
StoppedDetecting()When it's put away, also just before digging
StartedDigging()When digging starts
StoppedDigging()When digging ends, just before the server hands over the find

The bridge's DisableInventory() and EnableInventory() keep players out of their inventory on ox_inventory, qb-inventory and qs-inventory. To stop the shovel from being dropped mid-dig:

client/functions.lua
function StartedDigging()
    DisableInventory()
end

function StoppedDigging()
    EnableInventory()
end

Open files

These files ship open, so you can read and change them:

PathWhat it's for
config.lua, logs.luaThe configuration
strings.luaEvery line players read. See language.
bridge/client.lua, bridge/server.luaFramework and inventory support: player data, jobs, items and labels, money, usable items, and turning the inventory off and on. Each function has a slot for a custom framework or inventory.
client/functions.luaNotifications, text prompts, menus and dialogs with their custom slots, the target systems, the shopkeepers, how often the detector beeps (GetBeepTime) and the client hooks
server/functions.luaThe server hooks, and where logs and debug lines go

The bridges detect es_extended, qbx_core and qb-core, in that order, and ox_inventory, qb-inventory, qs-inventory, ps-inventory, origen_inventory and codem-inventory. For anything else, fill in the -- Add custom framework here and -- Add custom inventory here slots.

Still stuck? Ask in our Discord: the people who write the scripts answer.

Last updated November 11, 2026

Configuration

Every metal detecting option in config.lua and logs.lua with its default and what it changes, the text prompt setting in client/functions.lua, and the strings file.

Changelog

Every metal detecting release since version 2, newest first, with what it added, changed and fixed.

On this page

Server exportsGetPlayerDataAddPlayerDataGetLevelDataClient exportsOpenMenuGetPlayerData (client)GetLevelData (client)OpenDetectorShopOpenSellShopEventslation_detecting:NotifyHooksServer hooksCanUseDetectorItemFoundClient hooksOpen files
lation scripts

FiveM scripts for Qbox, QBCore and ESX servers, made to look and work like one product.

store

  • all scripts
  • membership
  • classics

help

  • docs
  • discord
  • email support

legal

  • terms
  • refunds
  • privacy
© 2026 Lation Labslationscripts.com
  • home
  • scripts
  • membership
  • docs