Configuration — ns-fishing
Everything a server owner changes stays editable under escrow: config.lua, data/*.lua, locales/*.lua.
config.lua
| Option | Default | Description |
|---|---|---|
Config.Framework | 'auto' | 'auto', 'qbox', 'qbcore', 'esx', 'standalone' |
Config.Locale | 'en' | Active language; missing keys fall back to Config.FallbackLocale |
Config.Debug | false | Debug output (Config.DebugCategories filters: fishing, market, boats) and enables /fishtest |
Config.Inventory | 'auto' | 'auto', 'ox', 'framework'. Weight and stars need ox_inventory |
Config.Features.* | all true | Fishing, Market, Shop, Upgrades, Boats, Collection, Legendary, Treasure, Orders, Windows, Durability, LineBreak, Tournaments, Events, Achievements, Leaderboard, Poaching, Crews |
Config.Environment.source | 'auto' | Hour / weather for species windows: 'auto' (weather sync state bags GlobalState.currentTime / weather, else the server clock), 'fixed' (fixedHour, fixedWeather), 'real' |
Config.Environment.fallbackWeather | 'CLEAR' | Weather when no weather sync resource publishes one |
Config.Durability.max | 100 | Durability of a new / repaired rod (1–100; ox_inventory reads higher values as a timestamp) |
Config.Durability.catchBase / catchPerDifficulty / legendaryMultiplier | 1 / 25 / 2 | Wear per landed fish: catchBase + difficulty / catchPerDifficulty, ×2 for legendaries |
Config.Durability.escape / lineBreak | 1 / 6 | Wear when the fish gets away / the line snaps |
Config.Durability.repairFactor / repairMin | 0.35 / 25 | Full repair = rod shop price × factor (scaled by the missing durability), at least repairMin |
Config.Job | not required | required, name, minGrade, requireOnDuty |
Config.Progression | 120 / 1.35 / 50 | XP for level n → n+1 = xpBase * n ^ xpGrowth, maxLevel |
Config.Fishing.command | 'fish' | Starts fishing with your best rod ('' disables) |
Config.Fishing.allowNoBait | true | Fishing without bait: slower bites, more junk |
Config.Fishing.biteDelay / minBiteDelay | 8-22 / 3 s | Bite time before bait and hook bonuses, and its floor |
Config.Fishing.reactionWindow | 1600 ms | Time to strike after the bite |
Config.Fishing.latencyGrace | 600 ms | Network allowance on server-side windows |
Config.Fishing.boatDeckRadius | 7.0 | Standing this close to a boat counts as "on a boat" |
Config.Fishing.castRange | 18.0 | Water must be within this range ahead (client check) |
Config.Fishing.controls | 38 / 47 / 73 | Cast/strike (E), bait (G), stop (X) control ids |
Config.Fishing.scenario | WORLD_HUMAN_STAND_FISHING | Standing pose with a rod |
Config.Catch.junkChance | 0.07 | Base junk chance (bait multiplies it; no bait ×2) |
Config.Catch.treasureChance | 0.025 | Chest chance per catch (hook upgrade and legendary bait raise it) |
Config.Catch.starQuality | 1.0 / 1.35 / 1.8 | Price multiplier for 1 / 2 / 3 stars |
Config.Catch.firstCatchXp | 40 | Journal bonus for a new species |
Config.Minigame.* | see file | Time limit, start meter, gain, decay, decay per difficulty, anti-cheat tolerance |
Config.Minigame.tensionRate / tensionPerDifficulty / tensionRelief | 0.45 / 0.006 / 0.6 | Line tension per second while reeling with the fish below the bar, and how fast it relaxes (LineBreak) |
Config.Legendary.announce | true | Tell everyone when a legendary is caught |
Config.Market.account | 'cash' | Sales, shop and upgrade account |
Config.Market.updateMinutes | 30 | Price tick |
Config.Market.volatility / meanReversion / supplyPressure | 0.08 / 0.2 / 0.006 | Random step, pull to 1.0, drop per fish sold |
Config.Market.min / max | 0.55 / 1.75 | Multiplier bounds |
Config.Market.hotBonus / hotRotateTicks | 0.5 / 4 | "Hot" species bonus and how often it changes |
Config.Market.locations | examples | { id, label, coords = vector4 }, ped model, blip |
Config.Orders.* | 3 per day | Quantity range, 2-star chance, price bonus, XP per fish, max species level |
Config.Treasure.loot | see file | Weighted loot: money = { min, max } or item + amount = { min, max } |
Config.Boats.account | 'bank' | Rent, deposit and refund account |
Config.Boats.rentMinutes | 60 | After this the deposit is no longer refunded |
Config.Boats.returnRadius | 25.0 | Boat and player must be this close to a return point |
Config.Boats.docks | examples | { id, label, ped = vector4, spawns = { vector4 }, returnPoint = vector3, boats = { model } } |
Config.Boats.models | 5 boats | { label, price, deposit, minLevel } per model |
Config.VehicleKeys.provider | 'auto' | qbx_vehiclekeys, qb-vehiclekeys, none, custom |
Config.Fuel.provider | 'auto' | ox_fuel, LegacyFuel, cdn-fuel, ps-fuel, native, custom |
Config.ZoneBlips | true | Radius blips for the fishing zones |
Config.Locations.command | 'fishlocations' | Command of the in-game location tool (admins) |
Config.Locations.file | 'data/locations.json' | Where places set in game are saved |
Config.Locations.viewDistance | 300.0 | Tool markers are drawn this far around the admin |
Config.Tournament.account | 'bank' | Prize money account |
Config.Tournament.announce / boardSize | true / 10 | Start / winner announcements, places shown on the board |
Config.Tournament.schedule | 2 examples | { day, hour, minute, kind, minutes, species? }. day: 'daily', 'mon' … 'sun' (server clock). kind: 'heaviest' (best single fish), 'count' (most fish), 'weight' (most kg). species: optional id, only that fish counts |
Config.Tournament.prizes | 3 places | { money, xp } per place, 1st first. Offline winners are paid on their next login |
Config.Events.intervalMinutes | 45–90 | A random event may start this often (one at a time) |
Config.Events.minPlayers | 1 | Online players needed for a random event |
Config.Events.blip | sprite 68 | Map marker of frenzy / migration (radius + flashing blip) |
Config.Events.types.frenzy | 10 min | One zone: biteSpeed ×2, junkMultiplier ×0.5 |
Config.Events.types.migration | 15 min | A species visits one zone (same kind of water, at most 5 levels above the zone): it can bite there, rarityMultiplier ×4 |
Config.Events.types.golden_hour | 10 min | Catch XP xpMultiplier ×1.5 for everyone |
Config.Events.types.market_rush | 15 min | One species sells for priceMultiplier ×2 |
Config.Events.types.*.enabled / weight | true / see file | Switch a type off, or change how often it is picked |
Config.Achievements.account | 'bank' | Achievement reward account |
Config.Leaderboard.size / cacheSeconds | 10 / 60 | Rows per list, how often the lists are read from the DB |
Config.Leaderboard.announceRecords | true | Tell everyone when a species record is beaten |
Config.Poaching.policeJobs | police, sheriff | Jobs that may inspect players and receive the alerts (on duty only) |
Config.Poaching.minPolice | 1 | Protected species bite only with this many police on duty (0 = always) |
Config.Poaching.catchAlertChance / reserveAlertChance / sellAlertChance | 0.35 / 0.10 / 0.20 | Alert chance for a landed protected fish / any other fish in a reserve / a black market sale |
Config.Poaching.alertOffset / alertCooldown / alertBlipSeconds | 50–150 m / 120 s / 120 s | Random distance between the real position and the alert; seconds between two alerts about one player; built-in alert duration |
Config.Poaching.dispatch | 'auto' | 'auto' (ps-dispatch, cd_dispatch, rcore_dispatch, core_dispatch, else built-in), one of those names, 'custom' or 'builtin' |
Config.Poaching.dispatchJobs | nil | Jobs sent to the dispatch resource (nil = policeJobs). Default ps-dispatch filters by job type: use { 'leo' } |
Config.Poaching.custom | returns false | function(src, coords, kind, message) for dispatch = 'custom'; return true when sent (a false / error falls back to the built-in alert) |
Config.Poaching.inspectCommand / inspectDistance | 'fishinspect' / 3.0 | Police command that inspects the closest player (also a target option on players) |
Config.Poaching.fine | 1500 / 150 % / 'bank' | Fine = max(perFish × fish, value × valuePercent / 100), charged from account, never below zero |
Config.Poaching.blackMarketMultiplier / blackMarketRadius / blackMarketPed | 1.8 / 3.0 / see file | Black market price = fish market price × multiplier (cash, not counted as market earnings) |
Config.Poaching.blackMarkets | 1 example | { id, label, coords = vector4 }, no map blip; also editable with /fishlocations |
Config.Crew.command | 'fishcrew' | Crew panel; /fishcrew invite / accept / decline / leave |
Config.Crew.maxSize / inviteDistance / inviteTimeout | 4 / 5.0 / 60 s | Crew size, invite range, invite lifetime |
Config.Crew.radius | 40.0 | A member this close (or in the same vehicle) counts as near |
Config.Crew.biteBonusPerMember / biteBonusMax | 0.05 / 0.15 | Bite speed per near member and its cap |
Config.Crew.xpBonusPerMember / xpBonusMax | 0.10 / 0.30 | Catch XP per near member and its cap |
Config.Crew.goal.minutes / cooldownMinutes / goalsPerHour | 30 / 5 / 3 | Goal time, pause before the next goal, rewards per player per hour |
Config.Crew.goal.kinds | see file | count / weight / species with weight (how often) and perMember (goal size per member) |
Config.Crew.goal.reward | 1500 + 250 / member, 400 xp | Paid to every member who landed a fish for the goal |
Config.Security.*, Config.Admin.*, Config.Notifications.*, Config.Target.*, Config.Standalone.* | see file | Shared NullSect options |
data/species.lua
One entry per catchable: id, item, habitats (fresh / salt / deep), optional zones (only bites there),
rarity, minLevel, minRod, kg = { min, max }, price (average weight, one star), xp, difficulty (1–100),
behavior (smooth, mixed, dart, sinker, floater), tags (small, bottom, predator, big),
legendary, junk, protected, optional when. A protected species bites only in
protected zones (with enough police on duty), sells only at a black market and never appears in orders, tournaments or
events; it cannot be legendary or junk. Data.Valuables lists fixed-price items (pearls). A new species needs an item and
a locale key item_<item>.
when limits when a species bites (with Config.Features.Windows):
when = { hours = { 21, 5 } } -- 21:00-05:00 (wraps past midnight, the end hour is excluded)
when = { weather = { 'RAIN', 'THUNDER' } } -- GTA weather names
when = { hours = { 21, 5 }, weather = { 'THUNDER' } } -- both must match
A malformed when skips the species with an error in the console. Weather names shown in the journal come from the
locale keys weather_<NAME>.
data/gear.lua
Data.Rods:item,tier,price(0 = not sold),minLevel,bar,power,size.Data.Baits:item,price,minLevel,speed,tags = { tag = multiplier },junk,legendary,treasure.Data.Upgrades: per kind the effect per level andlevels = { { price, minLevel } }.line.tensionlowers the line tension rate per level.
data/achievements.lua
{ id, stat, goal, tier, reward = { money, xp }, title? }. Name from the locale key ach_<id>, title from
title_<title>. stat is one of fish_caught, legendary_caught, treasures_found, total_earnings, biggest_kg,
species (discovered), orders_done, tournament_wins, three_star_catches, crew_goals. tier 1 / 2 / 3 shows a bronze / silver /
gold medal. Rewards are paid once when the goal is reached, also for goals reached before the achievement existed
(checked when the player connects). Invalid entries are skipped with a console error.
data/zones.lua
{ id, type, center = vector3, radius, minLevel, requireBoat, blip, protected }. protected = true makes a marine reserve
(protected species live there; any catch there can be reported). The smallest circle containing the player wins.
Locale key zone_<id> names the zone. Zones placed with /fishlocations carry their own name.
Admin
| Command | What it does |
|---|---|
/fishreset <player id> | Resets progression, upgrades and journal; ends the fishing session |
/fishlevel <player id> <level> | Sets the fishing level (xp jumps to the start of that level) |
/fishxp <player id> <amount> | Adds xp |
/fishupgrade <player id> <reel|line|hook> <level> | Sets a tackle upgrade (0 to its max level) |
/fishgive <player id> <item> [amount] | Gives an ns-fishing item; rods come with durability, fish with an average weight |
/fishlocations | Opens the in-game location tool (see below) |
/fishpos | Prints your vector4 and the zone you stand in |
/fishmarket [tick] | Prints market multipliers in the server console; tick forces a price step |
/fishtest | Config.Debug only: a test session (2 s bite, no bait used, no rewards) |
/fishtournament start <heaviest|count|weight> <minutes> [species] | Starts a tournament now |
/fishtournament end / stop | Ends the tournament now with prizes / cancels it without prizes |
/fishtournament | Shows the running tournament |
/fishevent start <frenzy|migration|golden_hour|market_rush> [minutes] | Starts an event now |
/fishevent stop / /fishevent | Stops the event / shows it |
All need ACE ns-fishing.admin (or framework admin with Config.Admin.useFrameworkAdmin).
/fishlevel, /fishxp, /fishupgrade, /fishgive, /fishtournament and /fishevent also work from the server
console. The player must be online. /fishreset also removes the player's achievements and title.
Location tool (/fishlocations)
Place fish markets, boat docks and fishing zones in game. Every change is saved to data/locations.json and used at
once by every player: no restart.
- The panel docks on the right so you still see the world: a sea chart with every zone (to scale), market and dock, a list per kind and a form for the selected place. Click a place on the chart or in the list.
- New ... where I stand / Move here switches to placement: walk, drive or fly to the spot and face the way the seller (or the boat) should look. E places it, Backspace goes back to the panel.
- Zones: name, waters (freshwater / coast / deep sea), radius (the ring in the world follows the slider), fishing level, boat-only rule and the map circle.
- Docks: name, the boats it rents out, the seller, up to 8 boat spawns on the water and the return point. A new dock shows needs setup until it has a spawn and a return point.
- Markets: name and seller position. Players trade within
Config.Market.radiusmetres. - The markets / docks in
config.luaand the zones indata/zones.luastay the defaults. The tool can edit them, switch them off and restore them exactly as shipped. Places added in game are deleted for good. - The eye button keeps the markers in the world after the panel is closed.
- Coordinates always come from your position on the server; the client only says what to place.
- Legendary fish are bound to zone ids (
zones = { ... }indata/species.lua). The form warns when a zone has them; switching such a zone off makes those fish uncatchable until it is restored. - Keep
data/locations.jsonwhen you update ns-fishing: it holds everything placed in game. If the file cannot be read on start it is copied todata/locations.json.brokenand the defaults are used.
Hooks for other resources
AddEventHandler('ns-fishing:hook:securityFlag', function(src, reason, detail) end) — every suspicious request
(for example minigame_too_fast, cast_id_mismatch, invalid_boat_model).