Reference Devices

fishing_zone_device: Catch Fish, Score Points, Restock the Pond

The Fishing Zone device turns a patch of water into a spot players can fish — perfect for fishing competitions, resource-gathering loops, or reward minigames. In this guide you'll wire its CaughtEvent and EmptyEvent into real game logic and use Enable, Disable, and Restock to control the pond from Verse.

Updated
The code on this reference page is provided as-is and did not pass the latest compile check — treat the examples as a starting point and verify in your project.
Watch the Knotfishing_zone_device in ~90 seconds.

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 eventsCaughtEvent (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 a message (localized text) gets one. There's no StringToMessage; 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 @editable field, calling FishingZone.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 we Subscribe our two handler methods to the device's events. Handlers are methods at class scope.
  • OnFishCaught(Agent : agent) — a listenable(agent) event hands the handler an agent directly here. We look up their current score with Scores[Agent] or 0 (the or 0 supplies a default if they have no entry yet) and write the incremented value back with set.
  • OnPoolEmptied fires once when the final fish is taken; we call Restock() 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

  • Restock needs 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 @editable field. A bare fishing_zone_device.Enable() won't compile. Declare the device as an @editable field on your creative_device class and assign the placed device in UEFN.
  • The event gives you an agent directly. CaughtEvent and EmptyEvent are listenable(agent), so your handler signature is (Agent : agent) — no ?agent unwrap needed here. Only convert to a character (with Agent.GetFortCharacter[], which is a failable [] call) if you actually need character data.
  • EmptyEvent sends the agent who took the LAST fish. It is not a generic 'pool is empty' broadcast detached from a player; the agent in OnPoolEmptied is whoever emptied it.
  • Localized text, not strings. Any device/UI option typed message needs a <localizes> helper like fishing_msg — passing a raw "..." string won't compile, and there is no StringToMessage.
  • Subscribe in OnBegin. Subscriptions are set up once when the device starts; subscribing inside an event handler can stack duplicate handlers.

Device Settings & Options

The fishing_zone_device User Options panel in the UEFN editor — every setting you can tune.

Fishing Zone Device settings and options panel in the UEFN editor — Uses Allowed, Pool Type, Zone FX, Disable When Empty, Extra Ammo, Remove Caught Items, Item List
Fishing Zone Device — User Options in the UEFN editor: Uses Allowed, Pool Type, Zone FX, Disable When Empty, Extra Ammo, Remove Caught Items, Item List
⚙️ Settings on this device (7)

Setting names read from the panel above — may be partial; the screenshots are the source of truth.

Uses Allowed
Pool Type
Zone FX
Disable When Empty
Extra Ammo
Remove Caught Items
Item List

Guides & scripts that use fishing_zone_device

Step-by-step tutorials that put this object to work.

Build your own lesson with fishing_zone_device

Generate a personalized, step-by-step lesson plan built around this object — grounded in this exact reference and our compile-verified knowledge base.

Build a lesson →