Reference Devices compiles

speaker_device: Dynamic Audio Control in Verse

The `speaker_device` lets you pipe Patchwork audio into your island and — crucially — toggle it on or off from Verse at exactly the right moment. Whether you want music that kicks in when a boss spawns, ambient sound that cuts out when a player enters a silent zone, or a victory jingle that plays when the last objective is captured, `speaker_device` gives you that runtime control. Its API is intentionally minimal: two methods, zero events, maximum clarity.

Updated Examples verified on the live UEFN compiler
Watch the Knotspeaker_device in ~90 seconds.

Overview

The speaker_device is a Patchwork audio output device — it plays whatever audio asset you've wired up in the UEFN editor and exposes two Verse methods: Enable and Disable. That's the whole surface, and it's all you need.

When to reach for it:

  • You want background music or ambient sound that starts or stops based on gameplay events (zone capture, boss spawn, round start/end).
  • You need to mute a speaker when a player enters a "silent zone" and restore it when they leave.
  • You want to stagger multiple audio layers — e.g., bring in a bass track when combat intensity rises.

speaker_device inherits from patchwork_device and lives in the /Fortnite.com/Devices/Patchwork module, so you'll need that import alongside the standard /Fortnite.com import.

API Reference

speaker_device

Output Patchwork audio for players to hear.

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

speaker_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.

Walkthrough

Scenario: A capture-point map. When the round starts, eerie ambient music plays. The moment a player steps on the capture plate, the ambient music cuts out and a tense combat sting kicks in. When the player leaves the plate, the ambient music resumes and the combat sting silences.

Place two speaker_device actors in your level (one for ambient, one for combat), a trigger_device set to fire on player enter, and a second trigger for player exit. Wire them all to this Verse device.

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

# capture_audio_manager
# Swaps between ambient and combat audio when a player
# steps onto (or off) the capture plate.
capture_audio_manager := class(creative_device):

    # Drag your ambient speaker device here in the Details panel
    @editable
    AmbientSpeaker : speaker_device = speaker_device{}

    # Drag your combat sting speaker device here
    @editable
    CombatSpeaker : speaker_device = speaker_device{}

    # Trigger placed on the capture plate — fires when a player enters
    @editable
    EnterTrigger : trigger_device = trigger_device{}

    # Trigger placed on the capture plate — fires when a player exits
    @editable
    ExitTrigger : trigger_device = trigger_device{}

    # Entry point — subscribe to both triggers, start ambient music
    OnBegin<override>()<suspends> : void =
        # Ambient music plays from the moment the round begins
        AmbientSpeaker.Enable()
        # Combat sting starts silent
        CombatSpeaker.Disable()

        # Subscribe to plate enter/exit events
        EnterTrigger.TriggeredEvent.Subscribe(OnPlayerEnterPlate)
        ExitTrigger.TriggeredEvent.Subscribe(OnPlayerExitPlate)

    # Called when any player steps onto the capture plate
    OnPlayerEnterPlate(Agent : ?agent) : void =
        # Silence the ambient track — tension rises
        AmbientSpeaker.Disable()
        # Bring in the combat sting
        CombatSpeaker.Enable()

    # Called when the player leaves the capture plate
    OnPlayerExitPlate(Agent : ?agent) : void =
        # Combat sting fades out
        CombatSpeaker.Disable()
        # Ambient music resumes
        AmbientSpeaker.Enable()

Line-by-line breakdown:

Lines What's happening
@editable fields Expose both speakers and both triggers to the UEFN Details panel so you can assign real placed devices without hardcoding.
AmbientSpeaker.Enable() in OnBegin Starts ambient audio immediately when the round begins.
CombatSpeaker.Disable() in OnBegin Ensures the combat sting is silent at round start — even if the device's "Start Enabled" property is checked in the editor, this guarantees the correct initial state from code.
EnterTrigger.TriggeredEvent.Subscribe(OnPlayerEnterPlate) Registers the handler; TriggeredEvent fires a listenable(?agent) so the handler receives Agent : ?agent.
AmbientSpeaker.Disable() / CombatSpeaker.Enable() The audio swap — one line each, no async needed.
OnPlayerExitPlate Reverses the swap when the plate is vacated.

Editor setup: In UEFN, place two Speaker devices, set each to a different Patchwork audio asset. Set Start Enabled to Off on both — Verse owns the initial state. Place two Trigger devices on the capture zone boundary (one for enter, one for exit). Assign all four devices to the Verse device's editable fields.

Common patterns

Pattern 1 — Round-gated music (Enable on round start, Disable on round end)

Use fort_round_manager to tie speaker state directly to round lifecycle.

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

# round_music_manager
# Plays a speaker only while a Fortnite round is active.
round_music_manager := class(creative_device):

    @editable
    RoundSpeaker : speaker_device = speaker_device{}

    OnBegin<override>()<suspends> : void =
        # Silence the speaker until a round actually starts
        RoundSpeaker.Disable()

        # GetFortRoundManager can fail (decides), so use 'if'
        if (RoundMgr := GetFortRoundManager[]):
            # SubscribeRoundStarted fires immediately if a round is already running
            RoundMgr.SubscribeRoundStarted(OnRoundStarted)
            RoundMgr.SubscribeRoundEnded(OnRoundEnded)

    # Async callback — must be suspends to satisfy SubscribeRoundStarted
    OnRoundStarted()<suspends> : void =
        RoundSpeaker.Enable()

    OnRoundEnded() : void =
        RoundSpeaker.Disable()

Note: GetFortRoundManager is an extension method on entity that uses <transacts><decides>, so it must be called inside an if expression. SubscribeRoundStarted requires a <suspends> callback — match that signature exactly.

Pattern 2 — Button-toggled speaker (Enable / Disable alternating)

A simple on/off toggle: press a button to silence or restore a speaker.

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

# speaker_toggle_device
# A button that alternates a speaker between enabled and disabled.
speaker_toggle_device := class(creative_device):

    @editable
    ToggleButton : button_device = button_device{}

    @editable
    TargetSpeaker : speaker_device = speaker_device{}

    # Track current state
    var SpeakerOn : logic = true

    OnBegin<override>()<suspends> : void =
        # Speaker starts enabled
        TargetSpeaker.Enable()
        ToggleButton.InteractedWithEvent.Subscribe(OnButtonPressed)

    OnButtonPressed(Agent : agent) : void =
        if (SpeakerOn?):
            TargetSpeaker.Disable()
            set SpeakerOn = false
        else:
            TargetSpeaker.Enable()
            set SpeakerOn = true

Pattern 3 — Multi-speaker zone reveal (Enable a bank of speakers at once)

A cinematic moment: when a player triggers a cutscene zone, silence all ambient speakers and enable the cinematic score.

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

# cinematic_audio_director
# Silences ambient speakers and activates the cinematic score
# when a player enters the boss arena trigger.
cinematic_audio_director := class(creative_device):

    # Up to three ambient speakers to silence
    @editable
    AmbientA : speaker_device = speaker_device{}
    @editable
    AmbientB : speaker_device = speaker_device{}
    @editable
    AmbientC : speaker_device = speaker_device{}

    # The dramatic boss-arena score
    @editable
    BossScore : speaker_device = speaker_device{}

    @editable
    ArenaTrigger : trigger_device = trigger_device{}

    OnBegin<override>()<suspends> : void =
        AmbientA.Enable()
        AmbientB.Enable()
        AmbientC.Enable()
        BossScore.Disable()
        ArenaTrigger.TriggeredEvent.Subscribe(OnArenaEntered)

    OnArenaEntered(Agent : ?agent) : void =
        # Kill all ambient layers
        AmbientA.Disable()
        AmbientB.Disable()
        AmbientC.Disable()
        # Unleash the boss score
        BossScore.Enable()

Gotchas

1. speaker_device is in the Patchwork module — don't forget the import

The type lives under /Fortnite.com/Devices/Patchwork, not the standard /Fortnite.com/Devices. If you omit using { /Fortnite.com/Devices/Patchwork } you'll get an Unknown identifier error on speaker_device. Always include both imports.

2. Enable / Disable are fire-and-forget — no return value, no await

Both methods return void and have no <suspends> effect, so you call them as plain statements. You do not need to await them or call them inside a spawn block. They take effect immediately on the game thread.

3. Editor "Start Enabled" vs. Verse initial state

If you set Start Enabled = On in the UEFN Details panel and call Disable() in OnBegin, Verse wins — the device will be disabled at runtime. Be explicit: always set the initial state in OnBegin so the code is the single source of truth, regardless of editor settings.

4. No events — you must drive it from another device's event

speaker_device has no events of its own. It cannot tell you when audio starts or stops. All logic must be driven by external events (triggers, buttons, round manager, etc.). If you need audio-completion callbacks, you'll need a timer or a separate signaling device.

5. trigger_device.TriggeredEvent hands you ?agent, not agent

If your handler needs the agent who triggered the event, unwrap the option first:

OnTriggered(MaybeAgent : ?agent) : void =
    if (A := MaybeAgent?):
        # use A as a concrete agent here
        SomeSpeaker.Enable()

Forgetting the unwrap and trying to use MaybeAgent directly as an agent is a compile error.

Device Settings & Options

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

Speaker Device settings and options panel in the UEFN editor — Audio Selection, Volume, Activate on Hit
Speaker Device — User Options in the UEFN editor: Audio Selection, Volume, Activate on Hit
⚙️ Settings on this device (3)

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

Audio Selection
Volume
Activate on Hit

Guides & scripts that use speaker_device

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

Build your own lesson with speaker_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 →