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:
- The
drum_player_deviceenables — the Patchwork drums start thumping. - A HUD message pops up: "The dock comes alive with rhythm!"
- 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.