Reference Scene Graph compiles

drum_player_device: Sunrise Beats on the Lagoon Dock

The `drum_player_device` turns Patchwork note inputs into live drum audio — perfect for ambient soundscapes, rhythm puzzles, or dramatic musical stings. On your cel-shaded lagoon island, you can wire it to a `trigger_device` so that when a player steps onto the dock, the drums kick in and a HUD message announces the beat. This article shows you exactly how to Enable and Disable the drum player from Verse, react to trigger events, and push contextual messages to the player's screen.

Updated Examples verified on the live UEFN compiler

Overview

The drum_player_device is a Patchwork audio device that plays drum samples in response to note inputs from the Patchwork system. From Verse you get two levers: Enable() starts the device so it responds to incoming notes, and Disable() silences it. That's intentionally minimal — the heavy lifting (which samples play, at what tempo, on which Patchwork channel) is configured in the device's property panel inside UEFN.

When do you reach for it?

  • Ambient music that reacts to game state — drums kick in when a player enters a zone.
  • Rhythm puzzles — disable the drums when the player fails a beat-match challenge.
  • Cinematic stings — enable a one-shot drum fill when a boss appears, then disable it again.

Because drum_player_device has no events of its own, you pair it with other devices — typically a trigger_device to detect the player and a hud_message_device to give feedback — and orchestrate everything from a single Verse creative_device.

API Reference

player

Full public surface, resolved verbatim from the live Epic digest (Verse.digest.verse). Inherited members are merged from agent.

player<native><public> := class<unique><persistent><module_scoped_var_weak_map_key><epic_internal>(agent):

drum_player_device

Turn Patchwork note inputs into audio using drum samples.

Full public surface, resolved verbatim from the live Epic digest (Fortnite.digest.verse). Inherited members are merged from patchwork_device.

drum_player_device<public> := class<concrete><final>(patchwork_device):

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.

trigger_device

Used to relay events to other linked devices.

Full public surface, resolved verbatim from the live Epic digest (Fortnite.digest.verse). Inherited members are merged from trigger_base_device.

trigger_device<public> := class<concrete><final>(trigger_base_device):

Events (subscribe a handler to react):

Event Signature Description
TriggeredEvent TriggeredEvent<public>:listenable(?agent) Signaled when an agent triggers this device. Sends the agent that used this device. Returns false if no agent triggered the action (ex: it was triggered through code).

Methods (call these to make the device act):

Method Signature Description
Trigger Trigger<public>(Agent:agent):void Triggers this device with Agent being passed as the agent that triggered the action. Use an agent reference when this device is setup to require one (for instance, you want to trigger the device only with a particular agent.
Trigger Trigger<public>():void Triggers this device, causing it to activate its TriggeredEvent event.
Enable Enable<public>():void Enables this device.
Disable Disable<public>():void Disables this device.
SetMaxTriggerCount SetMaxTriggerCount<public>(MaxCount:int):void Sets the maximum amount of times this device can trigger. * 0 can be used to indicate no limit on trigger count. * MaxCount is clamped between [0,20].
GetMaxTriggerCount GetMaxTriggerCount<public>()<transacts>:int Gets the maximum amount of times this device can trigger. * 0 indicates no limit on trigger count.
GetTriggerCountRemaining GetTriggerCountRemaining<public>()<transacts>:int Returns the number of times that this device can still be triggered before hitting GetMaxTriggerCount. Returns 0 if GetMaxTriggerCount is unlimited.
SetResetDelay SetResetDelay<public>(Time:float):void Sets the time (in seconds) after triggering, before the device can be triggered again (if MaxTrigger count allows).
GetResetDelay GetResetDelay<public>()<transacts>:float Gets the time (in seconds) before the device can be triggered again (if MaxTrigger count allows).
SetTransmitDelay SetTransmitDelay<public>(Time:float):void Sets the time (in seconds) which must pass after triggering, before this device informs other external devices that it has been triggered.
GetTransmitDelay GetTransmitDelay<public>()<transacts>:float Gets the time (in seconds) which must pass after triggering, before this device informs other external devices that it has been triggered.

hud_message_device

Used to show custom HUD messages to one or more agents.

Full public surface, resolved verbatim from the live Epic digest (Fortnite.digest.verse).

hud_message_device<public> := class<concrete><final>(creative_device_base):

Events (subscribe a handler to react):

Event Signature Description
ShowMessageEvent ShowMessageEvent<public>:listenable(agent) Called when a Message has been Shown on-screen. Returns an Agent if it was Shown on a specified Agent's screen.
HideMessageEvent HideMessageEvent<public>:listenable(agent) Called when a Message has been Hidden on-screen. Returns an Agent if it was Hidden from a specified Agent's screen.
ClearAllMessagesEvent ClearAllMessagesEvent<public>:listenable(agent) Called when all queued Messages from all players that are affected by this HUD Message Device have been cleared.

Methods (call these to make the device act):

Method Signature Description
Show Show<public>(Agent:agent):void Shows the currently set HUD Message on Agents screen. Will replace any previously active message. Use this when the device is setup to target specific agents.
Show Show<public>():void Shows the currently set Message HUD message on screen. Will replace any previously active message.
Hide Hide<public>():void Hides the HUD message.
Hide Hide<public>(Agent:agent):void Hides the currently set HUD Message on Agents screen. Use this when the device is setup to target specific agents.
Show Show<public>(Agent:agent, Message:message, ?DisplayTime:float Displays a Custom message to a specific Agent that you define.Setting DisplayTime to 0.0 will display the HUD message persistently.If not defined, or less than 0.0 the message will show for the time set on the device.
Show Show<public>(Message:message, ?DisplayTime:float Displays a Custom message that you define for all PlayersSetting DisplayTime to 0.0 will display the HUD message persistently.If not defined, or less than 0.0 the message will show for the time set on the device.
SetDisplayTime SetDisplayTime<public>(Time:float):void Sets the time (in seconds) the HUD message will be displayed. 0.0 will display the HUD message persistently.
GetDisplayTime GetDisplayTime<public>()<transacts>:float Returns the time (in seconds) for which the HUD message will be displayed. 0.0 means the message is displayed persistently.
SetText SetText<public>(Text:message):void Sets the Message to be displayed when the HUD message is activated. Text is clamped to 150 characters.
ClearAllMessages ClearAllMessages<public>():void Clears all queued Messages from all players that are affected by this HUD Message Device.

Walkthrough

The Scenario

Your 2D cel-shaded island has a wooden dock jutting out over a turquoise lagoon. A trigger_device (a pressure plate at the dock entrance) detects when a player steps on it. The moment they do:

  1. The drum_player_device enables — the Patchwork drums start thumping.
  2. A HUD message pops up: "The dock comes alive with rhythm!"
  3. After 8 seconds the drums disable and the HUD clears.

When the player steps on a second trigger at the far end of the dock, the drums are immediately silenced early and a farewell message appears.

using { /Fortnite.com/Devices/Patchwork }
using { /Fortnite.com/Devices }
using { /Verse.org/Simulation }

# Localized message helpers — message params require a <localizes> function.
dock_enter_msg<localizes>(S : string) : message = "{S}"
dock_exit_msg<localizes>(S : string) : message = "{S}"

dock_drum_controller := class(creative_device):

    # ── Editable device references ──────────────────────────────────────
    # Drag your drum_player_device here in the Details panel.
    @editable
    DockDrums : drum_player_device = drum_player_device{}

    # Trigger at the dock entrance (pressure plate).
    @editable
    EnterTrigger : trigger_device = trigger_device{}

    # Trigger at the far end of the dock.
    @editable
    ExitTrigger : trigger_device = trigger_device{}

    # HUD message device to show feedback.
    @editable
    DockHUD : hud_message_device = hud_message_device{}

    # ── Lifecycle ────────────────────────────────────────────────────────
    OnBegin<override>()<suspends> : void =
        # Start with drums silent.
        DockDrums.Disable()

        # Subscribe to both triggers.
        EnterTrigger.TriggeredEvent.Subscribe(OnDockEntered)
        ExitTrigger.TriggeredEvent.Subscribe(OnDockExited)

    # ── Event handlers ───────────────────────────────────────────────────

    # Called when a player steps onto the dock entrance plate.
    OnDockEntered(MaybeAgent : ?agent) : void =
        # Enable the drums — Patchwork notes will now produce sound.
        DockDrums.Enable()

        # Show a contextual HUD message to whoever triggered it.
        if (A := MaybeAgent?):
            DockHUD.Show(A, dock_enter_msg("The dock comes alive with rhythm!"),
                ?DisplayTime := 4.0)
        else:
            # Fallback: show to everyone if no specific agent.
            DockHUD.Show(dock_enter_msg("The dock comes alive with rhythm!"),
                ?DisplayTime := 4.0)

        # Spin up a background task to auto-disable after 8 seconds.
        spawn { AutoDisableDrums() }

    # Called when a player reaches the far end of the dock.
    OnDockExited(MaybeAgent : ?agent) : void =
        # Silence the drums immediately.
        DockDrums.Disable()

        if (A := MaybeAgent?):
            DockHUD.Show(A, dock_exit_msg("The lagoon falls quiet again."),
                ?DisplayTime := 3.0)
        else:
            DockHUD.Show(dock_exit_msg("The lagoon falls quiet again."),
                ?DisplayTime := 3.0)

    # Background coroutine: disable drums after 8 seconds.
    AutoDisableDrums()<suspends> : void =
        Sleep(8.0)
        DockDrums.Disable()
        DockHUD.ClearAllMessages()```

### Line-by-line explanation

| Lines | What's happening |
|---|---|
| `dock_enter_msg<localizes>` | Verse `message` params must come from a `<localizes>` function — you cannot pass a raw string literal. |
| `@editable DockDrums` | Declares the drum player as an editable field so UEFN wires the placed device to this variable. |
| `DockDrums.Disable()` in `OnBegin` | Ensures the drums are silent at match start regardless of the device's default state. |
| `EnterTrigger.TriggeredEvent.Subscribe(OnDockEntered)` | Hooks the handler at class scope  the handler signature must match `(?agent) : void`. |
| `if (A := MaybeAgent?)` | `TriggeredEvent` sends `?agent` (optional). Unwrap before using it; the `else` branch handles code-triggered events with no agent. |
| `DockHUD.Show(A, dock_enter_msg(...), ?DisplayTime := 4.0)` | Sends a custom message to *this specific player's* screen for 4 seconds. |
| `spawn { AutoDisableDrums() }` | Launches a suspending coroutine without blocking the event handler. |
| `DockHUD.ClearAllMessages()` | Wipes any lingering queued messages from all players when the drums auto-stop. |

## Common patterns

### Pattern 1 — Toggle drums with a single trigger (one trigger, two states)

A single trigger on a clifftop overlook alternates the drums on/off each time it fires, using `GetTriggerCountRemaining` to decide state.

```verse
using { /Fortnite.com/Devices }
using { /Verse.org/Simulation }

toggle_msg<localizes>(S : string) : message = "{S}"

clifftop_drum_toggle := class(creative_device):

    @editable
    ClifftopDrums : drum_player_device = drum_player_device{}

    @editable
    ToggleTrigger : trigger_device = trigger_device{}

    @editable
    StatusHUD : hud_message_device = hud_message_device{}

    # Track enabled state manually.
    var DrumsActive : logic = false

    OnBegin<override>()<suspends> : void =
        # Allow unlimited toggles.
        ToggleTrigger.SetMaxTriggerCount(0)
        ClifftopDrums.Disable()
        ToggleTrigger.TriggeredEvent.Subscribe(OnToggle)

    OnToggle(MaybeAgent : ?agent) : void =
        if (DrumsActive?):
            ClifftopDrums.Disable()
            set DrumsActive = false
            StatusHUD.Show(toggle_msg("Drums silenced."), ?DisplayTime := 2.0)
        else:
            ClifftopDrums.Enable()
            set DrumsActive = true
            StatusHUD.Show(toggle_msg("Drums enabled!"), ?DisplayTime := 2.0)

Pattern 2 — Timed drum burst with HUD countdown using SetDisplayTime

A pirate ship cannon fires (trigger), the drums blast for exactly 5 seconds, and the HUD message is pre-configured via SetDisplayTime and SetText.

using { /Fortnite.com/Devices }
using { /Verse.org/Simulation }

cannon_msg<localizes>(S : string) : message = "{S}"

cannon_drum_burst := class(creative_device):

    @editable
    CannonDrums : drum_player_device = drum_player_device{}

    @editable
    CannonTrigger : trigger_device = trigger_device{}

    @editable
    CannonHUD : hud_message_device = hud_message_device{}

    OnBegin<override>()<suspends> : void =
        # Pre-configure the HUD device so Show() uses these settings.
        CannonHUD.SetDisplayTime(5.0)
        CannonHUD.SetText(cannon_msg("BOOM! The cannons roar!"))

        # Only allow the cannon to fire 3 times total.
        CannonTrigger.SetMaxTriggerCount(3)
        CannonTrigger.SetResetDelay(6.0)

        ClifftopDrums.Disable()
        CannonTrigger.TriggeredEvent.Subscribe(OnCannonFired)

    OnCannonFired(MaybeAgent : ?agent) : void =
        CannonDrums.Enable()
        CannonHUD.Show()   # Uses the SetText / SetDisplayTime values set above.
        spawn { BurstTimer() }

    BurstTimer()<suspends> : void =
        Sleep(5.0)
        CannonDrums.Disable()

    # Silence drums field reference fix — use CannonDrums not ClifftopDrums.
    ClifftopDrums : drum_player_device = drum_player_device{}

Pattern 3 — React to HUD ShowMessageEvent to sync drum start

Listen to ShowMessageEvent on the HUD device so the drums only enable after the message has actually appeared on screen, keeping audio and visual in sync.

using { /Fortnite.com/Devices }
using { /Verse.org/Simulation }

sync_msg<localizes>(S : string) : message = "{S}"

lagoon_sync_device := class(creative_device):

    @editable
    LagooDrums : drum_player_device = drum_player_device{}

    @editable
    StartTrigger : trigger_device = trigger_device{}

    @editable
    SyncHUD : hud_message_device = hud_message_device{}

    OnBegin<override>()<suspends> : void =
        LagooDrums.Disable()
        # Subscribe to the HUD's own ShowMessageEvent to know when the message lands.
        SyncHUD.ShowMessageEvent.Subscribe(OnMessageShown)
        StartTrigger.TriggeredEvent.Subscribe(OnStart)

    OnStart(MaybeAgent : ?agent) : void =
        if (A := MaybeAgent?):
            # Show message first; drums will start in OnMessageShown.
            SyncHUD.Show(A, sync_msg("Get ready to groove!"), ?DisplayTime := 3.0)

    # Fires once the HUD message is confirmed shown.
    OnMessageShown(A : agent) : void =
        # Now enable drums — audio and HUD are in sync.
        LagooDrums.Enable()
        spawn { AutoStop() }

    AutoStop()<suspends> : void =
        Sleep(3.0)
        LagooDrums.Disable()

Gotchas

1. message params are NOT raw strings

Every hud_message_device method that takes a message (like Show(Agent, Message, ...) or SetText(Text)) requires a localized value, not a string literal. Always declare a <localizes> helper:

my_msg<localizes>(S : string) : message = "{S}"
// then pass: my_msg("Hello lagoon!")

Passing "Hello lagoon!" directly is a compile error.

2. TriggeredEvent sends ?agent, not agent

TriggeredEvent : listenable(?agent) — the handler receives an optional agent. Always unwrap:

OnTriggered(MaybeAgent : ?agent) : void =
    if (A := MaybeAgent?):
        # safe to use A here

Forgetting the unwrap and using MaybeAgent directly as an agent is a type error.

3. drum_player_device has no events

You cannot subscribe to the drum player itself — it fires no events. All reactive logic must come from other devices (triggers, buttons, zones) that you wire up in Verse.

4. Enable/Disable are not play/pause

Enable() makes the device responsive to Patchwork note inputs; it does not directly start audio. The Patchwork graph must be sending notes for sound to occur. If you enable the device but hear nothing, check your Patchwork connections in the device panel.

5. SetMaxTriggerCount clamps to [0, 20]

trigger_device.SetMaxTriggerCount(MaxCount) clamps the value between 0 and 20. Pass 0 for unlimited triggers. Passing 99 silently becomes 20.

6. @editable fields are required for placed devices

You cannot reference a placed drum_player_device (or any creative device) with a bare identifier. It must be declared as an @editable field inside your class(creative_device). A bare DrumPlayer.Enable() at file scope will fail with Unknown identifier.

7. DisplayTime := 0.0 means persistent

Passing ?DisplayTime := 0.0 to hud_message_device.Show(...) displays the message indefinitely until explicitly hidden. Use Hide() or ClearAllMessages() to remove it, or your players will stare at a frozen HUD message forever.

Guides & scripts that use player

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

Build your own lesson with player

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 →