NullSect
Systems nominal

Docs / Fishing / Installation

Installation — ns-fishing

  1. Put the ns-fishing folder into your resources (e.g. resources/[nullsect]/ns-fishing).

  2. Start the dependencies first. With Config.Database.autoMigrate = true (default) the tables are created on the first start. Otherwise import sql/ns-fishing.sql manually (updating by hand: from 0.4.x run sql/upgrade-0.5.0.sql once, from 0.5.x run sql/upgrade-0.6.0.sql once).

    ensure oxmysql
    ensure ox_lib
    ensure ox_inventory
    ensure ns-fishing
    add_ace group.admin ns-fishing.admin allow
    
  3. Register the items and copy the images. Automatic: FiveM blocks a resource from writing into another resource, so first allow it in server.cfg (QBCore: one line for qb-core and one for your inventory, e.g. qb-inventory):

    add_filesystem_permission ns-fishing write ox_inventory
    

    Restart the server, then type in the server console

    fishinstall check    (optional: only shows what is missing)
    fishinstall
    

    It adds the missing items to ox_inventory/data/items.lua (QBCore: qb-core/shared/items.lua) and copies the missing pictures to ox_inventory/web/images/ (QBCore: qb-inventory, ps-inventory or lj-inventory /html/images/). Items and images you already have are never changed. The first change saves a backup next to the item file (items.lua.ns-fishing.bak). Restart the server afterwards. While items are missing, ns-fishing prints a reminder on start (ox_inventory only).

    By hand: add the items from the section below and copy every .png in ns-fishing/images/ into your inventory's image folder. They are 256×256 with a transparent background.

  4. Check the example coordinates: markets (Config.Market.locations), docks (Config.Boats.docks) and fishing zones (data/zones.lua). Easiest: /fishlocations (admin) moves them in game and adds your own, saved at once. /fishpos prints your vector4 and the zone you stand in.

  5. Restart the server.

Items

ox_inventory is recommended: fish keep their weight and star quality (metadata). With qb-core / ESX inventories every fish sells at its average one-star price. Rods and the treasure chest are usable items (registered through the framework). Fish weights below are the average weight, capped at 50 kg. Change them freely.

-- ox_inventory/data/items.lua
['ns_rod_bamboo'] = { label = "Bamboo Rod", weight = 1500, stack = false, close = true },
['ns_rod_fiberglass'] = { label = "Fiberglass Rod", weight = 1500, stack = false, close = true },
['ns_rod_carbon'] = { label = "Carbon Rod", weight = 1500, stack = false, close = true },
['ns_rod_pro'] = { label = "Pro Rod", weight = 1500, stack = false, close = true },
['ns_rod_abyss'] = { label = "Abyss Rod", weight = 1500, stack = false, close = true },
['ns_bait_worm'] = { label = "Worm", weight = 20, stack = true, close = false },
['ns_bait_shrimp'] = { label = "Shrimp", weight = 20, stack = true, close = false },
['ns_bait_minnow'] = { label = "Live Minnow", weight = 20, stack = true, close = false },
['ns_bait_spinner'] = { label = "Spinner Lure", weight = 20, stack = true, close = false },
['ns_bait_squid'] = { label = "Squid Bait", weight = 20, stack = true, close = false },
['ns_bait_legend'] = { label = "Moonlit Lure", weight = 20, stack = true, close = false },
['ns_fish_bluegill'] = { label = "Bluegill", weight = 350, stack = false, close = false },
['ns_fish_perch'] = { label = "Perch", weight = 600, stack = false, close = false },
['ns_fish_carp'] = { label = "Carp", weight = 6500, stack = false, close = false },
['ns_fish_largemouth_bass'] = { label = "Largemouth Bass", weight = 2750, stack = false, close = false },
['ns_fish_rainbow_trout'] = { label = "Rainbow Trout", weight = 2250, stack = false, close = false },
['ns_fish_catfish'] = { label = "Catfish", weight = 13500, stack = false, close = false },
['ns_fish_pike'] = { label = "Pike", weight = 8500, stack = false, close = false },
['ns_fish_sturgeon'] = { label = "Sturgeon", weight = 45000, stack = false, close = false },
['ns_fish_mackerel'] = { label = "Mackerel", weight = 750, stack = false, close = false },
['ns_fish_sea_bream'] = { label = "Sea Bream", weight = 1500, stack = false, close = false },
['ns_fish_flounder'] = { label = "Flounder", weight = 2250, stack = false, close = false },
['ns_fish_sea_bass'] = { label = "Sea Bass", weight = 4500, stack = false, close = false },
['ns_fish_red_snapper'] = { label = "Red Snapper", weight = 5500, stack = false, close = false },
['ns_fish_halibut'] = { label = "Halibut", weight = 32500, stack = false, close = false },
['ns_fish_stingray'] = { label = "Stingray", weight = 40000, stack = false, close = false },
['ns_fish_mahi_mahi'] = { label = "Mahi-Mahi", weight = 11500, stack = false, close = false },
['ns_fish_yellowfin_tuna'] = { label = "Yellowfin Tuna", weight = 50000, stack = false, close = false },
['ns_fish_swordfish'] = { label = "Swordfish", weight = 50000, stack = false, close = false },
['ns_fish_mako_shark'] = { label = "Mako Shark", weight = 50000, stack = false, close = false },
['ns_fish_blue_marlin'] = { label = "Blue Marlin", weight = 50000, stack = false, close = false },
['ns_fish_sea_turtle'] = { label = "Sea Turtle", weight = 50000, stack = false, close = false },
['ns_fish_dusky_grouper'] = { label = "Dusky Grouper", weight = 25000, stack = false, close = false },
['ns_fish_great_white'] = { label = "Great White Shark", weight = 50000, stack = false, close = false },
['ns_fish_golden_trout'] = { label = "Golden Trout", weight = 4500, stack = false, close = false },
['ns_fish_alamo_leviathan'] = { label = "Alamo Leviathan", weight = 50000, stack = false, close = false },
['ns_fish_pier_goliath'] = { label = "Pier Goliath", weight = 50000, stack = false, close = false },
['ns_fish_ghost_marlin'] = { label = "Ghost Marlin", weight = 50000, stack = false, close = false },
['ns_fish_abyssal_squid'] = { label = "Abyssal Squid", weight = 50000, stack = false, close = false },
['ns_junk_boot'] = { label = "Old Boot", weight = 800, stack = false, close = false },
['ns_junk_can'] = { label = "Tin Can", weight = 200, stack = false, close = false },
['ns_junk_driftwood'] = { label = "Driftwood", weight = 1750, stack = false, close = false },
['ns_junk_seaweed'] = { label = "Seaweed", weight = 500, stack = false, close = false },
['ns_fishing_chest'] = { label = "Treasure Chest", weight = 2500, stack = true, close = true },
['ns_pearl'] = { label = "Pearl", weight = 20, stack = true, close = false },
['ns_pearl_black'] = { label = "Black Pearl", weight = 20, stack = true, close = false },
-- qb-core/shared/items.lua (QBCore only; Qbox uses ox_inventory)
ns_rod_bamboo = { name = 'ns_rod_bamboo', label = "Bamboo Rod", weight = 1500, type = 'item', image = 'ns_rod_bamboo.png', unique = true, useable = true, shouldClose = true, description = '' },
ns_rod_fiberglass = { name = 'ns_rod_fiberglass', label = "Fiberglass Rod", weight = 1500, type = 'item', image = 'ns_rod_fiberglass.png', unique = true, useable = true, shouldClose = true, description = '' },
ns_rod_carbon = { name = 'ns_rod_carbon', label = "Carbon Rod", weight = 1500, type = 'item', image = 'ns_rod_carbon.png', unique = true, useable = true, shouldClose = true, description = '' },
ns_rod_pro = { name = 'ns_rod_pro', label = "Pro Rod", weight = 1500, type = 'item', image = 'ns_rod_pro.png', unique = true, useable = true, shouldClose = true, description = '' },
ns_rod_abyss = { name = 'ns_rod_abyss', label = "Abyss Rod", weight = 1500, type = 'item', image = 'ns_rod_abyss.png', unique = true, useable = true, shouldClose = true, description = '' },
ns_bait_worm = { name = 'ns_bait_worm', label = "Worm", weight = 20, type = 'item', image = 'ns_bait_worm.png', unique = false, useable = false, shouldClose = false, description = '' },
ns_bait_shrimp = { name = 'ns_bait_shrimp', label = "Shrimp", weight = 20, type = 'item', image = 'ns_bait_shrimp.png', unique = false, useable = false, shouldClose = false, description = '' },
ns_bait_minnow = { name = 'ns_bait_minnow', label = "Live Minnow", weight = 20, type = 'item', image = 'ns_bait_minnow.png', unique = false, useable = false, shouldClose = false, description = '' },
ns_bait_spinner = { name = 'ns_bait_spinner', label = "Spinner Lure", weight = 20, type = 'item', image = 'ns_bait_spinner.png', unique = false, useable = false, shouldClose = false, description = '' },
ns_bait_squid = { name = 'ns_bait_squid', label = "Squid Bait", weight = 20, type = 'item', image = 'ns_bait_squid.png', unique = false, useable = false, shouldClose = false, description = '' },
ns_bait_legend = { name = 'ns_bait_legend', label = "Moonlit Lure", weight = 20, type = 'item', image = 'ns_bait_legend.png', unique = false, useable = false, shouldClose = false, description = '' },
ns_fish_bluegill = { name = 'ns_fish_bluegill', label = "Bluegill", weight = 350, type = 'item', image = 'ns_fish_bluegill.png', unique = false, useable = false, shouldClose = false, description = '' },
ns_fish_perch = { name = 'ns_fish_perch', label = "Perch", weight = 600, type = 'item', image = 'ns_fish_perch.png', unique = false, useable = false, shouldClose = false, description = '' },
ns_fish_carp = { name = 'ns_fish_carp', label = "Carp", weight = 6500, type = 'item', image = 'ns_fish_carp.png', unique = false, useable = false, shouldClose = false, description = '' },
ns_fish_largemouth_bass = { name = 'ns_fish_largemouth_bass', label = "Largemouth Bass", weight = 2750, type = 'item', image = 'ns_fish_largemouth_bass.png', unique = false, useable = false, shouldClose = false, description = '' },
ns_fish_rainbow_trout = { name = 'ns_fish_rainbow_trout', label = "Rainbow Trout", weight = 2250, type = 'item', image = 'ns_fish_rainbow_trout.png', unique = false, useable = false, shouldClose = false, description = '' },
ns_fish_catfish = { name = 'ns_fish_catfish', label = "Catfish", weight = 13500, type = 'item', image = 'ns_fish_catfish.png', unique = false, useable = false, shouldClose = false, description = '' },
ns_fish_pike = { name = 'ns_fish_pike', label = "Pike", weight = 8500, type = 'item', image = 'ns_fish_pike.png', unique = false, useable = false, shouldClose = false, description = '' },
ns_fish_sturgeon = { name = 'ns_fish_sturgeon', label = "Sturgeon", weight = 45000, type = 'item', image = 'ns_fish_sturgeon.png', unique = false, useable = false, shouldClose = false, description = '' },
ns_fish_mackerel = { name = 'ns_fish_mackerel', label = "Mackerel", weight = 750, type = 'item', image = 'ns_fish_mackerel.png', unique = false, useable = false, shouldClose = false, description = '' },
ns_fish_sea_bream = { name = 'ns_fish_sea_bream', label = "Sea Bream", weight = 1500, type = 'item', image = 'ns_fish_sea_bream.png', unique = false, useable = false, shouldClose = false, description = '' },
ns_fish_flounder = { name = 'ns_fish_flounder', label = "Flounder", weight = 2250, type = 'item', image = 'ns_fish_flounder.png', unique = false, useable = false, shouldClose = false, description = '' },
ns_fish_sea_bass = { name = 'ns_fish_sea_bass', label = "Sea Bass", weight = 4500, type = 'item', image = 'ns_fish_sea_bass.png', unique = false, useable = false, shouldClose = false, description = '' },
ns_fish_red_snapper = { name = 'ns_fish_red_snapper', label = "Red Snapper", weight = 5500, type = 'item', image = 'ns_fish_red_snapper.png', unique = false, useable = false, shouldClose = false, description = '' },
ns_fish_halibut = { name = 'ns_fish_halibut', label = "Halibut", weight = 32500, type = 'item', image = 'ns_fish_halibut.png', unique = false, useable = false, shouldClose = false, description = '' },
ns_fish_stingray = { name = 'ns_fish_stingray', label = "Stingray", weight = 40000, type = 'item', image = 'ns_fish_stingray.png', unique = false, useable = false, shouldClose = false, description = '' },
ns_fish_mahi_mahi = { name = 'ns_fish_mahi_mahi', label = "Mahi-Mahi", weight = 11500, type = 'item', image = 'ns_fish_mahi_mahi.png', unique = false, useable = false, shouldClose = false, description = '' },
ns_fish_yellowfin_tuna = { name = 'ns_fish_yellowfin_tuna', label = "Yellowfin Tuna", weight = 50000, type = 'item', image = 'ns_fish_yellowfin_tuna.png', unique = false, useable = false, shouldClose = false, description = '' },
ns_fish_swordfish = { name = 'ns_fish_swordfish', label = "Swordfish", weight = 50000, type = 'item', image = 'ns_fish_swordfish.png', unique = false, useable = false, shouldClose = false, description = '' },
ns_fish_mako_shark = { name = 'ns_fish_mako_shark', label = "Mako Shark", weight = 50000, type = 'item', image = 'ns_fish_mako_shark.png', unique = false, useable = false, shouldClose = false, description = '' },
ns_fish_blue_marlin = { name = 'ns_fish_blue_marlin', label = "Blue Marlin", weight = 50000, type = 'item', image = 'ns_fish_blue_marlin.png', unique = false, useable = false, shouldClose = false, description = '' },
ns_fish_sea_turtle = { name = 'ns_fish_sea_turtle', label = "Sea Turtle", weight = 50000, type = 'item', image = 'ns_fish_sea_turtle.png', unique = false, useable = false, shouldClose = false, description = '' },
ns_fish_dusky_grouper = { name = 'ns_fish_dusky_grouper', label = "Dusky Grouper", weight = 25000, type = 'item', image = 'ns_fish_dusky_grouper.png', unique = false, useable = false, shouldClose = false, description = '' },
ns_fish_great_white = { name = 'ns_fish_great_white', label = "Great White Shark", weight = 50000, type = 'item', image = 'ns_fish_great_white.png', unique = false, useable = false, shouldClose = false, description = '' },
ns_fish_golden_trout = { name = 'ns_fish_golden_trout', label = "Golden Trout", weight = 4500, type = 'item', image = 'ns_fish_golden_trout.png', unique = false, useable = false, shouldClose = false, description = '' },
ns_fish_alamo_leviathan = { name = 'ns_fish_alamo_leviathan', label = "Alamo Leviathan", weight = 50000, type = 'item', image = 'ns_fish_alamo_leviathan.png', unique = false, useable = false, shouldClose = false, description = '' },
ns_fish_pier_goliath = { name = 'ns_fish_pier_goliath', label = "Pier Goliath", weight = 50000, type = 'item', image = 'ns_fish_pier_goliath.png', unique = false, useable = false, shouldClose = false, description = '' },
ns_fish_ghost_marlin = { name = 'ns_fish_ghost_marlin', label = "Ghost Marlin", weight = 50000, type = 'item', image = 'ns_fish_ghost_marlin.png', unique = false, useable = false, shouldClose = false, description = '' },
ns_fish_abyssal_squid = { name = 'ns_fish_abyssal_squid', label = "Abyssal Squid", weight = 50000, type = 'item', image = 'ns_fish_abyssal_squid.png', unique = false, useable = false, shouldClose = false, description = '' },
ns_junk_boot = { name = 'ns_junk_boot', label = "Old Boot", weight = 800, type = 'item', image = 'ns_junk_boot.png', unique = false, useable = false, shouldClose = false, description = '' },
ns_junk_can = { name = 'ns_junk_can', label = "Tin Can", weight = 200, type = 'item', image = 'ns_junk_can.png', unique = false, useable = false, shouldClose = false, description = '' },
ns_junk_driftwood = { name = 'ns_junk_driftwood', label = "Driftwood", weight = 1750, type = 'item', image = 'ns_junk_driftwood.png', unique = false, useable = false, shouldClose = false, description = '' },
ns_junk_seaweed = { name = 'ns_junk_seaweed', label = "Seaweed", weight = 500, type = 'item', image = 'ns_junk_seaweed.png', unique = false, useable = false, shouldClose = false, description = '' },
ns_fishing_chest = { name = 'ns_fishing_chest', label = "Treasure Chest", weight = 2500, type = 'item', image = 'ns_fishing_chest.png', unique = false, useable = true, shouldClose = true, description = '' },
ns_pearl = { name = 'ns_pearl', label = "Pearl", weight = 20, type = 'item', image = 'ns_pearl.png', unique = false, useable = false, shouldClose = false, description = '' },
ns_pearl_black = { name = 'ns_pearl_black', label = "Black Pearl", weight = 20, type = 'item', image = 'ns_pearl_black.png', unique = false, useable = false, shouldClose = false, description = '' },

ESX (without ox_inventory): add the same item names to the items table (name, label, weight in kg, rare, can_remove).

Verify

CheckExpected
Server console[ns-fishing:SV] [INFO] ready (framework=qbox, inventory=ox, metadata=true, core=…)
Databasetables ns_fishing_meta, ns_fishing_profiles, ns_fishing_collection, ns_fishing_market, ns_fishing_orders, ns_fishing_tournaments, ns_fishing_tournament_entries, ns_fishing_prizes, ns_fishing_achievements
Marketthe market ped opens the panel; buy a Bamboo Rod and worms
Fishinguse the rod (or /fish) on the Del Perro pier, cast with E, strike when the float dips, win the minigame
Boatsthe dock ped rents a dinghy, the deposit comes back at the return point
/fishreset <id>works for admins, refused (and logged) for normal players
/fishlocations, move a market with Move herethe seller and blip move for everyone at once; data/locations.json is written
/fishtournament start count 5, land a fisheveryone sees the start; your place shows on the HUD and under Tournament in the panel
/fishevent start frenzy 3announced, the zone flashes on the map, the HUD shows the chip while you fish
Achievements tabyour medals and progress; with 10 fish landed First Bites is unlocked and paid

Troubleshooting

  • oxmysql is not started → start oxmysql before ns-fishing.
  • Migration v… failed → the database user needs CREATE / ALTER permission, or import the SQL file.
  • No inventory found → set Config.Inventory or start ox_inventory / a framework inventory.
  • "There is nothing to catch here" → you are outside every zone in data/zones.lua; check with /fishpos.
  • "You need to be on a boat" → deep-sea zones (requireBoat = true) need you in a boat (not at the helm) or on its deck.
  • "This item is not set up on the server yet" → the items are not in ox_inventory: run fishinstall and restart.
  • fishinstall: ... unexpected layout → your item file does not end with the closing } of the item table; add the items by hand. cannot write / SaveResourceFile refused the write → the add_filesystem_permission line from step 3 is missing from server.cfg (or the server was not restarted after adding it).
  • fishinstall does nothing in game → it is a server console command (txAdmin Live Console works).
  • No tournament starts at the scheduled time → the schedule uses the server's clock (os.date), not the in-game hour; check the time zone of the server machine.
  • Updating from 0.4.x: copy the new Config.Features switches and the Config.Tournament, Config.Events, Config.Achievements, Config.Leaderboard sections into your config (a missing switch counts as off, so these features stay off until you add them). Keep data/locations.json.
  • Updating from 0.5.x: copy Poaching and Crews into Config.Features and the Config.Poaching and Config.Crew sections into your config (a missing section keeps the feature off and is logged at start). If you keep edited data files, copy the protected species from data/species.lua, the two reserves from data/zones.lua and the crew achievements from data/achievements.lua. Run fishinstall again for the three new items. Without autoMigrate run sql/upgrade-0.6.0.sql once. Keep data/locations.json.
  • Police cannot inspect / no alerts → their job name must be in Config.Poaching.policeJobs and they must be on duty. Without a dispatch resource the built-in alert (notification + area blip) is used; check the console for dispatch: ... did not take the alert when a dispatch resource is installed but nothing arrives. With a dispatch resource, that resource decides who sees the alert: the job list sent to it is Config.Poaching.dispatchJobs (or policeJobs when unset). Default ps-dispatch filters by job type, so set dispatchJobs = { 'leo' } there.
  • Protected species never bite → stand in a marine reserve (protected = true zone), have enough police on duty (Config.Poaching.minPolice, 0 disables the rule) and the level / rod the species needs.
  • Rods do nothing when used → the item is not registered as usable in your inventory/framework; /fish always works.

Cart

Your cart is empty.