Overview
The Fishing Zone device marks an area of water that players can fish in (pair it with a Fishing Rod Barrel device so players have rods). It's the building block for three classic game patterns the device's own docs call out:
- Fishing competitions — count who catches the most.
- Collecting fish as a resource — feed catches into a crafting or score economy.
- Fishing minigames with rewards — grant something when a fish is caught.
From Verse you get two reactive events — CaughtEvent (someone caught a fish) and EmptyEvent (the last fish was caught and the pool is now empty) — plus three methods: Enable, Disable, and Restock. Reach for this device whenever fishing is part of your loop: the events let you award score or progress, and Restock/Disable let you open and close the pond on your own schedule (rounds, day/night, after a quest, etc.).
Restock has one rule worth remembering up front: it only refills the pool when the device's Pool Type option is set to Device Inventory. We'll come back to that in Gotchas.
API Reference
fishing_zone_device
Used to add fishing mechanics to experiences, such as: * Fishing competitions between players. * Collecting fish as a resource. * Fishing minigames with their own rewards.
Full public surface, resolved verbatim from the live Epic digest (Fortnite.digest.verse).
fishing_zone_device<public> := class<concrete><final>(creative_device_base):
Events (subscribe a handler to react):
| Event | Signature | Description |
|---|---|---|
CaughtEvent |
CaughtEvent<public>:listenable(agent) |
Signaled when an agent catches a fish. Sends the agent that caught the fish. |
EmptyEvent |
EmptyEvent<public>:listenable(agent) |
Signaled when all items have been caught and removed. Sends the agent that caught the last fish. |
Methods (call these to make the device act):
| Method | Signature | Description |
|---|---|---|
Enable |
Enable<public>():void |
Enables this device. |
Disable |
Disable<public>():void |
Disables this device. |
Restock |
Restock<public>():void |
Returns all caught and removed items to the inventory. This only works when Pool Type is set to Device Inventory. |
Walkthrough
Let's build a timed fishing contest. When the game begins we enable the pond. Every fish a player catches earns them a point (shown on screen). When the pool runs dry we announce it and automatically Restock so the next wave of fishers has something to catch.
using { /Fortnite.com/Devices }
using { /Fortnite.com/Characters }
using { /Verse.org/Simulation }
using { /UnrealEngine.com/Temporary/Diagnostics }
# Helper that turns a string into a localized message (params typed `message` need this).
fishing_msg<localizes>(S : string) : message = "{S}"
fishing_contest_device := class(creative_device):
# Drag your placed Fishing Zone here in the Details panel.
@editable
FishingZone : fishing_zone_device = fishing_zone_device{}
# Tracks how many fish each agent has caught this round.
var Scores : [agent]int = map{}
OnBegin<override>()<suspends>:void =
# Open the pond when the match starts.
FishingZone.Enable()
# React to every catch and to the pool emptying.
FishingZone.CaughtEvent.Subscribe(OnFishCaught)
FishingZone.EmptyEvent.Subscribe(OnPoolEmptied)
# Called each time an agent catches a fish.
OnFishCaught(Agent : agent) : void =
# Read the current score (0 if this is their first fish), then add one.
Current := Scores[Agent] or 0
NewScore := Current + 1
set Scores[Agent] = NewScore
if (FortChar := Agent.GetFortCharacter[]):
Player := FortChar.GetAgent[]
# (point counted in Scores; surface it however you like)
Print("A fish was caught! New score: {NewScore}")
# Called when the LAST fish is removed and the pool is empty.
OnPoolEmptied(Agent : agent) : void =
Print("Pool is empty — restocking the pond.")
# Refill the pool (requires Pool Type = Device Inventory).
FishingZone.Restock()
Line by line:
fishing_msg<localizes>— a tiny helper so any device option that wants amessage(localized text) gets one. There's noStringToMessage; you build messages with a<localizes>function.@editable FishingZone : fishing_zone_device— the field that lets you point this script at the actual placed device in UEFN. Without an@editablefield, callingFishingZone.Enable()would fail with Unknown identifier.var Scores : [agent]int— a map from each player to their catch count.- In
OnBegin,FishingZone.Enable()turns the zone on, then weSubscribeour two handler methods to the device's events. Handlers are methods at class scope. OnFishCaught(Agent : agent)— alistenable(agent)event hands the handler anagentdirectly here. We look up their current score withScores[Agent] or 0(theor 0supplies a default if they have no entry yet) and write the incremented value back withset.OnPoolEmptiedfires once when the final fish is taken; we callRestock()to put everything back for the next round.
Common patterns
Close the pond at the end of a round
Use Disable to stop fishing — for example after a timer, or when a quest is complete. Here we open the pond, wait, then shut it.
using { /Fortnite.com/Devices }
using { /Verse.org/Simulation }
fishing_round_device := class(creative_device):
@editable
FishingZone : fishing_zone_device = fishing_zone_device{}
OnBegin<override>()<suspends>:void =
# Open the pond for a 60-second fishing window.
FishingZone.Enable()
Sleep(60.0)
# Time's up — no more fishing.
FishingZone.Disable()
Restock only when the pool empties
A self-refilling pond: every time the last fish is caught, put them all back so the zone never stays dry.
using { /Fortnite.com/Devices }
using { /Verse.org/Simulation }
using { /UnrealEngine.com/Temporary/Diagnostics }
endless_pond_device := class(creative_device):
@editable
FishingZone : fishing_zone_device = fishing_zone_device{}
OnBegin<override>()<suspends>:void =
FishingZone.Enable()
FishingZone.EmptyEvent.Subscribe(OnEmpty)
OnEmpty(Agent : agent) : void =
Print("Last fish caught — refilling.")
# Only works with Pool Type set to Device Inventory.
FishingZone.Restock()
Track the single catch event for a reward
Grant or trigger something the moment any agent lands a fish, using just CaughtEvent.
using { /Fortnite.com/Devices }
using { /Fortnite.com/Characters }
using { /Verse.org/Simulation }
using { /UnrealEngine.com/Temporary/Diagnostics }
fishing_reward_device := class(creative_device):
@editable
FishingZone : fishing_zone_device = fishing_zone_device{}
OnBegin<override>()<suspends>:void =
FishingZone.Enable()
FishingZone.CaughtEvent.Subscribe(OnCaught)
OnCaught(Agent : agent) : void =
# Confirm we have a valid fort character before rewarding.
if (FortChar := Agent.GetFortCharacter[]):
Print("Reward this player for their catch!")
Gotchas
Restockneeds Device Inventory. The method only returns caught items if the device's Pool Type option is set to Device Inventory in the Details panel. With other pool types the call does nothing — no error, just no effect.- You must have an
@editablefield. A barefishing_zone_device.Enable()won't compile. Declare the device as an@editablefield on yourcreative_deviceclass and assign the placed device in UEFN. - The event gives you an
agentdirectly.CaughtEventandEmptyEventarelistenable(agent), so your handler signature is(Agent : agent)— no?agentunwrap needed here. Only convert to a character (withAgent.GetFortCharacter[], which is a failable[]call) if you actually need character data. EmptyEventsends the agent who took the LAST fish. It is not a generic 'pool is empty' broadcast detached from a player; the agent inOnPoolEmptiedis whoever emptied it.- Localized text, not strings. Any device/UI option typed
messageneeds a<localizes>helper likefishing_msg— passing a raw"..."string won't compile, and there is noStringToMessage. - Subscribe in
OnBegin. Subscriptions are set up once when the device starts; subscribing inside an event handler can stack duplicate handlers.