How Integrations Work#
Nothing inside Fishing Job's escrowed code knows which framework, inventory or key script you run. Every one of them is reached through a small, open file — server/framework/, client/framework/, client/vehiclekeys/ — and the right one is picked at start by looking at what is already running.
Layer | Supported | Without it |
|---|---|---|
Framework |
| Required — money, items, jobs and names come from it. |
Inventory |
| Works on any. Only ox_inventory sells each fish by its weight. |
Target |
| On-screen "press E" prompts at the NPC, traps, nets, fires and sharks. |
Vehicle keys | Eleven scripts — see below | Rented boats are handed over without keys. |
Outfits |
| Players keep their own clothes on duty and when diving. |
3D prompts |
| Plain drawn text. |
Company money |
| Mission payouts go straight to the player in cash. |
Positional sound |
| The speargun and the grill are silent for other players. |
Firewood |
| Nobody can light a fire, and the console says so. |
Quests |
| Off unless |
Scheduled events |
| Scheduled tournaments are off; random ones and the admin panel still work. |
Every optional integration degrades silently. A missing resource makes its feature stand down instead of erroring, and the boot line in the console says what was detected:
[qs-fishingjob] framework qb · inventory ox · vehicle keys qs-vehiclekeys.
Notifications and Prompts#
Notifications#
Fishing Job ships its own notifications, styled to match the rest of the interface. To send them through your server's notification resource instead, turn them off and fill in SendTextMessage at the top of config/config.lua:
Config.DefaultNotifications = false
function SendTextMessage(msg, type) -- type is 'info', 'error' or 'success'
exports['okokNotify']:Alert('Fishing', msg, 5000, type)
endThe key hints at the bottom of the screen and the help lines while fishing always use the script's own interface, whatever this is set to.
Target or key prompts#
Config.Target = true -- third-eye instead of "press E"
Config.TargetScript = 'ox' -- 'ox' for ox_target, 'qb' for qb-target
Config.DrawText3D = true -- show the floating "press E" text when Target is offWith a target, the fisherman, crab-trap buoys, rented boats with a net out, campfires and speared sharks all get a third-eye option. The keys themselves are control ids in Config.Keys; change InteractKeyLabel with InteractKey, because the game cannot turn a control id into a name and the prompts would name the wrong key.
Vehicle Keys#
A rented boat is handed to the player through the first key script found running, in this order, and its keys are taken back when the boat is returned:
qs-vehiclekeys → qbx_vehiclekeys → qb-vehiclekeys → wasabi_carlock → F_RealCarKeysSystem
→ fivecode_carkeys → glfp10_carkeys → mono_carkeys → ti_vehicleKeys → vehicles_keys → xd_locksystemEach one is a few lines in client/vehiclekeys/<name>.lua defining AddVehiclekeys(vehicle, plate) and RemoveVehiclekeys(vehicle, plate). glfp10_carkeys and mono_carkeys issue keys as an item, which a rental does not create, so boats come without a key on those two. With no key script at all, none.lua does nothing and boats simply start.
Outfits#
With Config.Clothing = true, a player goes into the fisher outfit when a mission starts and back into their own clothes when it ends, and into a wetsuit while the dive tank is on. Both outfits, male and female, are tables at the top of client/clothing.lua — drawable and texture ids you can change freely.
-- client/clothing.lua
['male'] = {
['arms'] = 5, ['tshirt_1'] = 0, ['tshirt_2'] = 2,
['torso_1'] = 303, ['torso_2'] = 22,
['pants_1'] = 130, ['pants_2'] = 1,
['shoes_1'] = 110, ['shoes_2'] = 0,
['helmet_1'] = 104, ['helmet_2'] = 20,
...
}ESX loads it through esx_skin and skinchanger; QBCore and Qbox through qb-clothing. On qs-inventory, set Config.QuasarInventory = true so the inventory is locked during the change.
Discord Logs#
Six kinds of event can be posted to Discord as an embed. Paste a webhook into Config.Webhooks.Url, turn Enabled on, and choose per event: true sends it to the shared URL, false does not send it, and a URL of its own sends it to a separate channel.
Event | Sent when |
|---|---|
| A player or crew leader takes a mission: what it asks for, the crew, the pay. |
| The last fish is in and the mission pays out. |
| Abandoned from the panel, or left behind by disconnecting. |
| A mission payout, a sale at the shop, or an achievement collected. |
| Every experience grant, with the level before and after. |
| An admin changes or resets a setting from the panel — the audit trail of who moved what. |
-- config/config.lua
Config.Webhooks = {
Enabled = true,
Url = 'https://discord.com/api/webhooks/...',
Name = 'qs-fishingjob',
Avatar = '',
Timestamp = true,
Events = {
MissionStarted = true,
MissionFinished = true,
MissionAbandoned = true,
MoneyPaid = 'https://discord.com/api/webhooks/staff-channel',
ExperienceGiven = false,
ConfigChanged = 'https://discord.com/api/webhooks/staff-channel',
},
}qs-inventory Quests and Job Money#
With Config.QuasarInventoryQuests = true and qs-inventory running, three quests are created for every player as they load — Fisher Progress (levelling up), Finish fisher quests and Catch fish — and progress is reported as they play. The hooks live in the open server/missions.lua, where the titles, rewards and steps can be changed.
With qs-job-management running, mission payouts go to the fisher company account instead of the player's cash. Shop sales always pay the player.
Dive Tanks from Another Resource#
The dive tank is called dive_tank on purpose, so it never collides with another resource's diving_gear. If qs-treasure-hunter already sells diving equipment on your server, decide whether the fishing shop sells the tank too:
Config.Speargun.Breath = {
Shop = 'auto', -- 'auto' · 'always' · 'never'
ExternalResource = 'qs-treasure-hunter', -- 'auto' hides the tank while this runs
Seconds = 600, -- air in a full tank
Regen = 5, -- seconds of air back per second at the surface
}This decides only whether it is on the shelf — a tank a player already owns keeps working.
Adding a Framework#
A framework that is not on the list, or a renamed core, is supported by editing the open bridge files. Keep Config.Framework as it is and adapt the closest file:
Server side
server/framework/qb.luaoresx.luadefines a short list of functions the rest of the script calls:GetPlayeridentifier,IsPlayerFisher,GetItemCountFromInventory,AddInventoryItem,RemoveInventoryItem,AddMoney,RemoveMoney,GetMoney,GetUserNameandRegisterUsableItems. Point each at your core.Client side
client/framework/*.lualoads the player, follows job changes (which decide the blip, tournaments and whether a mission may continue) and spawns the fisherman.Money account
The shop and missions pay in cash —
moneyon ESX,cashon QBCore. To pay into the bank, change the account name inAddMoney,RemoveMoneyandGetMoney.
Languages#
Eight complete translations ship in config/translations.lua: English (en), Italian (it), Spanish (es), French (fr), Portuguese (pt), German (de), Russian (ru) and Turkish (tr). Pick one with Config.Language or from the admin panel's Setup section. Every line of the interface, the notifications and the guide is in there; edit only the text between the quotes. To add a language, copy the ['en'] block under a new code and translate it — it appears in the admin panel's language picker on its own.
Currency is set in the same file (CURRENCY_TYPE), and Config.CurrencyPosition puts the symbol before ($500) or after (500 zł) the amount.



