Docs

Rarx Fishing

Rarx Fishing

Server-authoritative fishing activity with fishing zones, a shop, fish selling and live tournaments — multi-framework and multi-inventory

  • Qbox
  • QBCore
  • ESX
  • rarx_fishing

Overview#

RARX Fishing is a complete fishing activity: players grab a rod and bait, head to one of several map zones, cast, beat a reel-in skill-check and land fish whose rarity scales with the zone. Caught fish can be sold to an NPC for cash, and a recurring tournament rewards the top anglers automatically.

The whole catch flow is server-authoritative — the server decides the zone (from the player's real position) and the fish before the line is even cast, so the client can only report whether the skill-check succeeded. There is nothing to spoof.

Features#

Multi-Framework

QBCore, QBox (qbx_core) and ESX — auto-detected

Multi-Inventory

ox_inventory, qb-inventory or ESX — auto-detected

Server-Authoritative Catch

Server picks zone & fish; client only reports the skill-check result

Fishing Zones

Multiple polygon zones, each with its own fish pool and wait time

Rods & Bait

Buyable rods and bait, where better bait shortens the wait

Sell Fish

Sell your catch to an NPC at a randomized per-fish price

Live Tournaments

Scheduled, server-run tournaments with a top-3 prize payout

ox_lib UI

Context menus, input dialogs and a Vue NUI panel/skill-check

Requirements#

Requirement Type
ox_lib Required
rarx_lib Required (locale/translation helper)
QBCore / QBox / ESX Required (a framework is needed — not standalone)
Any supported inventory Required (ox_inventory / qb / esx, auto-detected)
ox_target / qb-target Optional (only if Config.Target is set)
xsound Optional (ambient catch sounds)

Installation#

  1. Download & Extract

    Extract the resource into your resources folder.

  2. Add to server.cfg

    server.cfg
    ensure ox_lib
    ensure rarx_lib
    ensure rarx_fishing
  3. Set the Language

    server.cfg
    setr rarx-lang "en"   # or "es"
  4. Register the Items

    Add the fishing items (rod, bait and every fish) to your inventory's item list. See Required Items below.

  5. Restart & Test

    Buy a rod + bait from the shop NPC, head to a fishing zone, and cast.

Required Items#

All items handed out by the script must exist in your inventory's item database (ox_inventory/data/items.lua or qb-core/shared/items.lua). Item names are defined in shared/config.lua.

Type Item names
Rod fishingrod (must be usable)
Bait doublehook, triplehook, spoonlure
Fish stingray, largemouthbass, redfish, salmon, catfish, piranha, fish2, stripedbass, tuna

Item Definitions#

Copy the block for your inventory and paste it into the item list. Labels and weights are suggestions — tweak them freely. (Item images aren't included; the inventory will show a placeholder until you add your own .pngs.)

ox_inventory/data/items.lua
-- Fishing rod (usable starts a cast)
['fishingrod']     = { label = 'Fishing Rod',    weight = 1000, stack = false, close = true,  description = 'Cast it near water to fish.' },

-- Bait
['doublehook']     = { label = 'Double Hook',    weight = 50,   stack = true,  close = false, description = 'Basic fishing bait.' },
['triplehook']     = { label = 'Triple Hook',    weight = 50,   stack = true,  close = false, description = 'Premium bait — fish bite faster.' },
['spoonlure']      = { label = 'Spoon Lure',     weight = 50,   stack = true,  close = false, description = 'Premium lure — fish bite faster.' },

-- Fish
['stingray']       = { label = 'Stingray',       weight = 500,  stack = true,  close = false },
['largemouthbass'] = { label = 'Largemouth Bass',weight = 500,  stack = true,  close = false },
['redfish']        = { label = 'Redfish',        weight = 500,  stack = true,  close = false },
['salmon']         = { label = 'Salmon',         weight = 500,  stack = true,  close = false },
['catfish']        = { label = 'Catfish',        weight = 500,  stack = true,  close = false },
['piranha']        = { label = 'Piranha',        weight = 500,  stack = true,  close = false },
['fish2']          = { label = 'Mackerel',       weight = 500,  stack = true,  close = false },
['stripedbass']    = { label = 'Striped Bass',   weight = 500,  stack = true,  close = false },
['tuna']           = { label = 'Tuna',           weight = 800,  stack = true,  close = false },
qb-core/shared/items.lua
-- Fishing rod (useable starts a cast)
fishingrod     = { name = 'fishingrod',     label = 'Fishing Rod',     weight = 1000, type = 'item', image = 'fishingrod.png',     unique = false, useable = true,  shouldClose = true,  combinable = nil, description = 'Cast it near water to fish.' },

-- Bait
doublehook     = { name = 'doublehook',     label = 'Double Hook',     weight = 50,   type = 'item', image = 'doublehook.png',     unique = false, useable = false, shouldClose = false, combinable = nil, description = 'Basic fishing bait.' },
triplehook     = { name = 'triplehook',     label = 'Triple Hook',     weight = 50,   type = 'item', image = 'triplehook.png',     unique = false, useable = false, shouldClose = false, combinable = nil, description = 'Premium bait — fish bite faster.' },
spoonlure      = { name = 'spoonlure',      label = 'Spoon Lure',      weight = 50,   type = 'item', image = 'spoonlure.png',      unique = false, useable = false, shouldClose = false, combinable = nil, description = 'Premium lure — fish bite faster.' },

-- Fish
stingray       = { name = 'stingray',       label = 'Stingray',        weight = 500,  type = 'item', image = 'stingray.png',       unique = false, useable = false, shouldClose = false, combinable = nil, description = '' },
largemouthbass = { name = 'largemouthbass', label = 'Largemouth Bass', weight = 500,  type = 'item', image = 'largemouthbass.png', unique = false, useable = false, shouldClose = false, combinable = nil, description = '' },
redfish        = { name = 'redfish',        label = 'Redfish',         weight = 500,  type = 'item', image = 'redfish.png',        unique = false, useable = false, shouldClose = false, combinable = nil, description = '' },
salmon         = { name = 'salmon',         label = 'Salmon',          weight = 500,  type = 'item', image = 'salmon.png',         unique = false, useable = false, shouldClose = false, combinable = nil, description = '' },
catfish        = { name = 'catfish',        label = 'Catfish',         weight = 500,  type = 'item', image = 'catfish.png',        unique = false, useable = false, shouldClose = false, combinable = nil, description = '' },
piranha        = { name = 'piranha',        label = 'Piranha',         weight = 500,  type = 'item', image = 'piranha.png',        unique = false, useable = false, shouldClose = false, combinable = nil, description = '' },
fish2          = { name = 'fish2',          label = 'Mackerel',        weight = 500,  type = 'item', image = 'fish2.png',          unique = false, useable = false, shouldClose = false, combinable = nil, description = '' },
stripedbass    = { name = 'stripedbass',    label = 'Striped Bass',    weight = 500,  type = 'item', image = 'stripedbass.png',    unique = false, useable = false, shouldClose = false, combinable = nil, description = '' },
tuna           = { name = 'tuna',           label = 'Tuna',            weight = 800,  type = 'item', image = 'tuna.png',           unique = false, useable = false, shouldClose = false, combinable = nil, description = '' },

Configuration#

All settings live in shared/config.lua.

Integration#

Lua
Framework = 'auto'    -- 'auto' | 'qb' | 'qbx' | 'esx'  (a framework is required)
Inventory = 'auto'    -- 'auto' | 'ox_inventory' | 'qb' | 'esx'
Target    = false     -- 'ox_target' | 'qb-target' | false ([E] + ox_lib TextUI)
Notify    = 'ox_lib'  -- 'ox_lib' | 'framework'

Fishing Zones#

Each zone is a polygon with its own wait time and fish pool. The server checks the player's real position against these polygons — the client never tells the server which zone it is in.

Lua
GameZone = {
    zones = {
        {
            name = "fishZone1",
            points = { vec3(-2200.33, -447.65, 2.0), --[[ ... ]] },
            waitTime = { min = 5, max = 10 },
            fishList = { 'stingray', 'largemouthbass', 'redfish', 'salmon' },
        },
        -- fishZone2, fishZone3 ...
    },
}

Fish#

Each fish has a sale price range, a spawn chance (weight within its zone) and its tournament point value.

Lua
Fishes = {
    stingray = { price = { min = 20, max = 25 }, chance = 35, tournamentPoints = 15 },
    tuna     = { price = { min = 96, max = 101 }, chance = 5,  tournamentPoints = 45 },
    -- ...
}

Rods & Bait#

Lua
FishingRods = {
    fishingrod = { price = 1000, breakChance = 0 },
}

Bait = {
    doublehook = { price = 5,  waitDivisor = 1.0 }, -- normal wait
    triplehook = { price = 50, waitDivisor = 3.0 }, -- 3x faster bite
    spoonlure  = { price = 50, waitDivisor = 3.0 },
}

Higher waitDivisor = shorter wait before a fish bites.

Tournament#

Lua
Tournament = {
    Enabled    = true,
    Duration   = 1800,   -- run length, seconds (30 min)
    Cooldown   = 18000,  -- gap between tournaments, seconds (5 h)
    WarnBefore = 300,    -- "starts soon" warning, seconds
    MinPlayers = 1,      -- below this, the tournament ends with no prizes
    Prizes = {
        [1] = { money = 10000, account = 'bank' },
        [2] = { money = 5000,  account = 'bank' },
        [3] = { money = 2500,  account = 'bank' },
    },
}

Prizes can also grant an item: [1] = { money = 10000, account = 'bank', item = { name = 'goldbar', amount = 1 } }.

How It Works#

  1. Buy gear

    Talk to the shop NPC and buy a fishingrod plus some bait.

  2. Go to a zone

    Head to a fishing zone marked on the map. Using the rod outside a zone does nothing.

  3. Cast

    Use the rod. The server confirms your zone, consumes one bait, and secretly picks the fish you'll get.

  4. Reel in

    Wait for the bite, then beat the skill-check (press Space in the target area). Hold E at any point to cancel.

  5. Sell or keep

    Sell your catch to the NPC for cash, or hold onto it.

Tournaments#

When a tournament is live, every catch awards points based on the fish's rarity. The tournament is fully server-run: points can only be granted by a real server-verified catch, prizes are paid from a stable per-character identifier (so a reconnect can't misdirect a payout), and the public leaderboard never leaks server IDs to clients.

Admin commands (ACE group.admin):

Command Action
/starttournament Start a tournament immediately
/endtournament End the active tournament and pay prizes

Exports:

Lua
exports.rarx_fishing:IsTournamentActive()     -- boolean
exports.rarx_fishing:GetTournamentTimeLeft()  -- seconds remaining (server)

Localization#

Set the language with the shared rarx-lang convar:

server.cfg
setr rarx-lang "es"   # default: "en"

Translations live in translates/ (en.lua, es.lua) and use the RARX Lang (Locale) system. The NUI panel labels are pushed from the same locale.

Troubleshooting#

Items aren't given (catch/buy does nothing)

The fishing items aren't in your inventory's database. Add every item from Required Items to ox_inventory/data/items.lua (or qb-core/shared/items.lua), and make sure fishingrod is usable.

Using the rod does nothing

Confirm fishingrod is a usable item and that you are standing inside a fishing zone — casts outside a zone are rejected by the server.

No framework detected

The resource requires QBCore, QBox or ESX. Start one before rarx_fishing, or pin Framework in shared/config.lua.

Wrong inventory backend

Set Inventory in shared/config.lua to 'ox_inventory', 'qb' or 'esx' instead of 'auto' if detection picks the wrong one.

No NPC interaction prompt

With Config.Target = false, stand close to the NPC for the [E] prompt. To use a target system instead, set Config.Target to 'ox_target' or 'qb-target'.


Support#

Need help? Reach out: