Overview
The audio_player_device lets you trigger, stop, and manage audio playback entirely from Verse code. You configure the actual sound asset (a sound wave or sound cue) in the UEFN Details panel, then drive when and for whom it plays through the API.
Reach for it when you need:
- Reactive music — start a combat track when a player enters a danger zone, stop it when they leave.
- Per-player audio — play a private success jingle only for the player who solved a puzzle (Heard by Instigator mode).
- Managed ambient loops — enable the device at round start, disable it (which also stops playback) at round end.
- Dynamic registration — add and remove players from the audio target list at runtime.
The device has two playback modes set in the Details panel:
- Heard by Everyone —
Play()/Stop()affect all players. - Heard by Instigator —
Play(Agent)/Stop(Agent)target a single player;Register/Unregistermanage the active target list.
API Reference
audio_player_device
Used to configure and play audio from the device location or from registered
agents.
Full public surface, resolved verbatim from the live Epic digest (Fortnite.digest.verse).
audio_player_device<public> := class<concrete><final>(creative_device_base):
Methods (call these to make the device act):
| Method | Signature | Description |
|---|---|---|
Enable |
Enable<public>():void |
Enables this device. Allows this device to be triggered from other linked devices (i.e. triggers) and allow calls to Play to succeed. |
Disable |
Disable<public>():void |
Disables this device. No longer allows this device to be triggered from other linked devices (i.e. triggers) and will stop any currently playing audio. |
Play |
Play<public>(Agent:agent):void |
Starts playing audio from this device for Agent. This can only be used when the device is set to be Heard by Instigator. |
Play |
Play<public>():void |
Starts playing audio from this device. |
Stop |
Stop<public>(Agent:agent):void |
Stops any audio playing from this device for Agent. This can only be used when the device is set to be Heard by Instigator. |
Stop |
Stop<public>():void |
Stops any audio playing from this device. |
Register |
Register<public>(Agent:agent):void |
Adds Agent as a target to play audio from when activated. |
Unregister |
Unregister<public>(Agent:agent):void |
Removes Agent as a target to play audio from when activated. |
UnregisterAll |
UnregisterAll<public>():void |
Removes all previously registered agents as valid targets to play audio from when activated. |
Show |
Show<public>()<transacts>:void |
Shows this device in the world. |
Hide |
Hide<public>()<transacts>:void |
Hides this device from the world. |
Walkthrough
Scenario: A vault door puzzle. When a player steps on a pressure plate, a dramatic sting plays only for that player (Instigator mode). If they step off before the vault opens, the sting stops. When the vault is solved, a global fanfare plays for everyone and the sting device is disabled so it can't fire again.
# vault_audio_controller.verse
# Place this device in your scene alongside a trigger_device (pressure plate),
# two audio_player_devices, and a button_device (vault solve button).
using { /Fortnite.com/Devices }
using { /Verse.org/Simulation }
using { /Fortnite.com/Playspaces }
vault_audio_controller := class(creative_device):
# The pressure plate trigger — player steps on it
@editable
PressurePlate : trigger_device = trigger_device{}
# Audio player set to "Heard by Instigator" in Details panel
# Assign a tense sting sound cue to this device
@editable
StingPlayer : audio_player_device = audio_player_device{}
# Audio player set to "Heard by Everyone" in Details panel
# Assign a victory fanfare sound cue to this device
@editable
FanfarePlayer : audio_player_device = audio_player_device{}
# Button the player interacts with to "solve" the vault
@editable
VaultSolveButton : button_device = button_device{}
# Track whether the vault has been solved so we ignore late triggers
var VaultSolved : logic = false
OnBegin<override>()<suspends> : void =
# Subscribe to the pressure plate — fires with ?agent
PressurePlate.TriggeredEvent.Subscribe(OnPlateTriggered)
# Subscribe to the vault solve button
VaultSolveButton.InteractedWithEvent.Subscribe(OnVaultSolved)
# Called when a player steps on the pressure plate
OnPlateTriggered(MaybeAgent : ?agent) : void =
if (not VaultSolved?):
if (A := MaybeAgent?):
# Register this agent so the device tracks them,
# then play the sting privately for them
StingPlayer.Register(A)
StingPlayer.Play(A)
# Called when the player interacts with the vault solve button
OnVaultSolved(Solver : agent) : void =
if (not VaultSolved?):
set VaultSolved = true
# Stop the per-player sting for the solver
StingPlayer.Stop(Solver)
# Clear all registered agents — clean slate
StingPlayer.UnregisterAll()
# Disable the sting device entirely so it can't re-trigger
StingPlayer.Disable()
# Play the victory fanfare for everyone
FanfarePlayer.Play()
Line-by-line breakdown:
| Lines | What's happening |
|---|---|
@editable fields |
Bind the four placed devices. Without @editable the Verse identifiers are unknown at compile time. |
PressurePlate.TriggeredEvent.Subscribe(OnPlateTriggered) |
Hooks the plate's event. The handler receives ?agent (optional). |
if (A := MaybeAgent?) |
Unwraps the optional agent — mandatory before passing to Play(Agent). |
StingPlayer.Register(A) |
Adds the agent to the device's internal target list (required for Instigator mode). |
StingPlayer.Play(A) |
Plays the sting privately for that agent only. |
StingPlayer.Stop(Solver) |
Stops the sting for the solver when the vault is cracked. |
StingPlayer.UnregisterAll() |
Clears every registered agent so no stale targets remain. |
StingPlayer.Disable() |
Disables the device — stops any residual audio and blocks future Play calls. |
FanfarePlayer.Play() |
Plays the fanfare for the whole lobby (Heard by Everyone mode). |
Common patterns
Pattern 1 — Enable/Disable to gate audio across rounds
Disable the music device between rounds so stray triggers from linked devices can't fire it. Re-enable at round start.
# round_music_gate.verse
# Disable the audio player between rounds; enable it when a new round begins.
# Wire RoundStartTrigger and RoundEndTrigger to your round-management devices.
using { /Fortnite.com/Devices }
using { /Verse.org/Simulation }
round_music_gate := class(creative_device):
# Audio player with looping background music assigned in Details
@editable
BattleMusic : audio_player_device = audio_player_device{}
# Trigger fired by your round manager at round start
@editable
RoundStartTrigger : trigger_device = trigger_device{}
# Trigger fired by your round manager at round end
@editable
RoundEndTrigger : trigger_device = trigger_device{}
OnBegin<override>()<suspends> : void =
# Start disabled — no music in the lobby phase
BattleMusic.Disable()
RoundStartTrigger.TriggeredEvent.Subscribe(OnRoundStart)
RoundEndTrigger.TriggeredEvent.Subscribe(OnRoundEnd)
OnRoundStart(MaybeAgent : ?agent) : void =
# Enable the device so Play calls and linked triggers work
BattleMusic.Enable()
# Immediately start the music for everyone
BattleMusic.Play()
OnRoundEnd(MaybeAgent : ?agent) : void =
# Disable stops current playback AND blocks future triggers
BattleMusic.Disable()
Pattern 2 — Per-player registration for a team-specific soundtrack
Register only the members of a winning team so the victory music plays exclusively for them.
# team_victory_audio.verse
# After a team wins, register each winner and play a private victory track.
# Assumes you have a way to get the winning agents (here via a trigger per player).
using { /Fortnite.com/Devices }
using { /Verse.org/Simulation }
using { /Fortnite.com/Playspaces }
team_victory_audio := class(creative_device):
# Audio player set to "Heard by Instigator" in Details panel
@editable
VictoryMusicPlayer : audio_player_device = audio_player_device{}
# A trigger that fires once per winning player (e.g. from a Class Selector)
@editable
WinnerRegistrationTrigger : trigger_device = trigger_device{}
# A trigger that fires once to actually start the music
@editable
PlayMusicTrigger : trigger_device = trigger_device{}
# A trigger that fires to stop and clear everything (e.g. next round)
@editable
ClearMusicTrigger : trigger_device = trigger_device{}
OnBegin<override>()<suspends> : void =
WinnerRegistrationTrigger.TriggeredEvent.Subscribe(OnRegisterWinner)
PlayMusicTrigger.TriggeredEvent.Subscribe(OnPlayVictoryMusic)
ClearMusicTrigger.TriggeredEvent.Subscribe(OnClearMusic)
# Register each winning agent as they are identified
OnRegisterWinner(MaybeAgent : ?agent) : void =
if (A := MaybeAgent?):
VictoryMusicPlayer.Register(A)
# Once all winners are registered, play for all of them at once
OnPlayVictoryMusic(MaybeAgent : ?agent) : void =
# Play() with no argument plays for ALL registered agents
# when the device is in Heard by Instigator mode
VictoryMusicPlayer.Play()
# Clean up between rounds
OnClearMusic(MaybeAgent : ?agent) : void =
VictoryMusicPlayer.Stop()
VictoryMusicPlayer.UnregisterAll()
Pattern 3 — Show/Hide the speaker prop dynamically
Reveal a visible speaker prop when a secret room unlocks, then hide it again when the room resets.
# secret_room_speaker.verse
# The audio_player_device's mesh is hidden until the secret room opens.
# A button reveals the speaker and starts music; a reset trigger hides it again.
using { /Fortnite.com/Devices }
using { /Verse.org/Simulation }
secret_room_speaker := class(creative_device):
# The audio player whose speaker mesh we want to show/hide
@editable
SecretSpeaker : audio_player_device = audio_player_device{}
# Button that unlocks the secret room
@editable
UnlockButton : button_device = button_device{}
# Trigger that resets the room
@editable
ResetTrigger : trigger_device = trigger_device{}
OnBegin<override>()<suspends> : void =
# Hide the speaker mesh at game start
SecretSpeaker.Hide()
UnlockButton.InteractedWithEvent.Subscribe(OnRoomUnlocked)
ResetTrigger.TriggeredEvent.Subscribe(OnRoomReset)
OnRoomUnlocked(Unlocker : agent) : void =
# Reveal the speaker prop and start the music
SecretSpeaker.Show()
SecretSpeaker.Play()
OnRoomReset(MaybeAgent : ?agent) : void =
SecretSpeaker.Stop()
SecretSpeaker.Hide()
Gotchas
1. Play(Agent) and Stop(Agent) only work in Heard by Instigator mode
If your device is set to Heard by Everyone in the Details panel, calling Play(Agent) or Stop(Agent) will silently do nothing. Swap to the no-argument overloads Play() / Stop() for that mode.
2. Always unwrap ?agent before passing it to the API
The TriggeredEvent on a trigger_device sends ?agent (an optional). You must unwrap it with if (A := MaybeAgent?): before passing A to Register, Play(Agent), or Stop(Agent). Passing the raw optional is a compile error.
3. Disable() stops audio AND blocks future Play calls
Disable() is not a mute — it fully deactivates the device. Any subsequent call to Play() or Play(Agent) will do nothing until you call Enable() again. Use Stop() if you just want to pause playback while keeping the device active.
4. Register does not automatically start playback
Calling Register(Agent) only adds the agent to the target list. You still need to call Play() or Play(Agent) to actually start audio. Conversely, UnregisterAll() removes targets but does not stop currently playing audio — call Stop() first if needed.
5. Show() and Hide() are <transacts> — they can be rolled back
Show and Hide carry the <transacts> effect, meaning they participate in Verse's transaction system. If the enclosing expression fails, the visibility change is rolled back. Call them in a context where failure is handled, or outside a decision context if you want the change to always stick.
6. You cannot pass a raw string to SetInteractionText on companion devices
This doesn't apply to audio_player_device directly, but if you're combining it with a button_device that uses SetInteractionText, remember that the parameter is message, not string. Declare a localizes helper: MyLabel<localizes>(S:string):message = "{S}" and pass MyLabel("Unlock Music"). There is no StringToMessage function.