_SET_FISHING_BAIT spawns the hook/bobber as real entities — you do NOT need _SET_TASK_FISHING for bobber and line
Context
Widespread assumption (including in our own README): the bobber and line are "owned by the game's fishing task", so you have to get _SET_TASK_FISHING (0xF3735ACD11ACD501) to start in order to get them. That assumption cost many rounds and one client crash before anyone tested it.
It is wrong. _SET_FISHING_BAIT (0x9B0C7FA063E67629) spawns the props immediately, with the fishing task never running.
Measured live (build 1491, FXServer v1.0.0.25770)
After Citizen.InvokeNative(0x9B0C7FA063E67629, ped, "p_baitWorm01x", false, true):
local pos = GetEntityCoords(ped)
GetClosestObjectOfType(pos.x, pos.y, pos.z, 30.0, GetHashKey("p_fishHook02x"), false, false, false)
-- -> valid entity, DoesEntityExist == 1
GetClosestObjectOfType(pos.x, pos.y, pos.z, 30.0, GetHashKey("p_baitWorm01x"), false, false, false)
-- -> valid entity
Both report IsEntityAttached() == 1 (to the rod bone; IsEntityAttachedToEntity(obj, ped) is false), and sit ~1.3 m from the player at rod-tip height.
They can be detached and moved freely:
DetachEntity(obj, true, true)
SetEntityCoords(obj, tx, ty, waterHeight + 0.05, false, false, false, false)
FreezeEntityPosition(obj, true)
Verified: the hook could be placed 8 m out, at z 40.55 against a measured water surface of 40.50.
Confirmed independently of the struct documentation
The fishing-research pastebin that _GET_TASK_FISHING links to (https://pastebin.com/NmK5ZLVs) lists:
- slot 11 =
hook(Entity) - slot 12 =
bobber(Entity)
So the game itself holds these as entity references. Two independent sources point the same way.
Why this is worth knowing
_SET_TASK_FISHING is hard: p1 is documented as Any, but in practice it is a pointer to a struct (28 slots, 8-byte stride — not 4). Scalar values (0/1/2/3/-1) always return false because they are interpreted as a null pointer. And _GET_TASK_FISHING with an undersized buffer corrupts the heap (crash citizen-scripting-lua.dll+43E8F4, and later ntdll.dll+FF489 even with 224 bytes).
If all you need is the bobber/line visually, skip that whole minefield. Take the props _SET_FISHING_BAIT has already created, and place them yourself. TEST_VERTICAL_PROBE_AGAINST_ALL_WATER (0x2B3451FA1E3142E2) gives the exact water height — but it must be called from JS, not Lua, since the float* out-parameter is not marshalled correctly in RedM's Lua runtime.
The line is drawn as a DrawLine from the SKEL_R_Hand bone to the bobber, every frame.
Pitfall
The props are the game's, but once you move them out of the game's own setup they can be left dangling on unexpected interruptions (death, disconnect, resource crash). Clean up explicitly, and register them in your prop tracker if you have one.
Valid bait strings are listed in the _SET_FISHING_BAIT doc. Note that p_lgoc_spinner_v4 is listed, but not v6.
Linked natives
_SET_FISHING_BAIT(0x9B0C7FA063E67629)_SET_TASK_FISHING(0xF3735ACD11ACD501)TEST_VERTICAL_PROBE_AGAINST_ALL_WATER(0x2B3451FA1E3142E2)
Tags: fishing, bait, bobber, entities, props, water, task
Category: natives
Created: 2026-09-09T23:36:46.636Z