Reference Devices compiles

hud_message_device: Put Words on Screen When It Matters

The `hud_message_device` is your direct line to the player's screen — it lets you push text onto the HUD the moment something important happens, whether that's a vault unlocking, a wave of enemies arriving, or a countdown kicking off. You can target every player at once or whisper a message to a single agent, swap the text at runtime, control how long it lingers, and react to show/hide events with your own Verse logic. If your game needs to communicate state to players without a billboard or UI

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

Overview

The hud_message_device solves a fundamental game-design problem: players need feedback. When a guard spots them, when the final zone opens, when they earn a bonus — they need to know. The HUD message device lets you surface that information as an on-screen text overlay without building custom UI from scratch.

Key capabilities:

  • Show to everyone (Show()) or show to one player (Show(Agent)) — great for personal score updates vs. global announcements.
  • Inline custom text at runtime via SetText(Text:message) or the overloaded Show(Agent, Message, ?DisplayTime) / Show(Message, ?DisplayTime) — no need to pre-bake every string in the editor.
  • Control display duration with SetDisplayTime / GetDisplayTime; pass 0.0 to pin the message permanently.
  • React to lifecycle eventsShowMessageEvent, HideMessageEvent, and ClearAllMessagesEvent let your Verse code respond when messages appear or disappear.
  • Clean up with Hide(), Hide(Agent), or ClearAllMessages() when the moment has passed.

Reach for this device whenever you need lightweight, event-driven text feedback: countdown timers, wave announcements, per-player kill streaks, objective updates, or tutorial hints.

API Reference

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

Scenario: Vault Alert System

A player steps on a pressure plate. The vault door opens, and:

  1. A global "Vault Opened!" message flashes for 3 seconds.
  2. The player who triggered it gets a personal persistent message: "You found the vault — grab the loot!"
  3. When that personal message is hidden, we log it via HideMessageEvent.

This walkthrough uses SetText, SetDisplayTime, Show(), Show(Agent, Message, ?DisplayTime:=...), Hide(Agent), HideMessageEvent, and ClearAllMessages.

vault_alert_device := class(creative_device):

    # Wire these up in the UEFN editor
    @editable
    Plate : trigger_device = trigger_device{}

    # One device for the global broadcast, one for the personal tip
    @editable
    GlobalHUD : hud_message_device = hud_message_device{}

    @editable
    PersonalHUD : hud_message_device = hud_message_device{}

    # Localizer helper — message params must be of type `message`
    VaultOpened<localizes>(S : string) : message = "{S}"
    PersonalTip<localizes>(S : string) : message = "{S}"

    OnBegin<override>()<suspends> : void =
        # Subscribe to the pressure plate
        Plate.TriggeredEvent.Subscribe(OnPlateTriggered)

        # React when the personal message is hidden
        PersonalHUD.HideMessageEvent.Subscribe(OnPersonalMessageHidden)

        # Pre-configure the global HUD: 3-second flash
        GlobalHUD.SetDisplayTime(3.0)
        GlobalHUD.SetText(VaultOpened("⚠ Vault Opened!"))

        # Personal HUD will be shown persistently (DisplayTime = 0.0)
        # We'll pass that inline when we call Show

    # Handler called when a player steps on the plate
    # trigger_device fires listenable(?agent)
    OnPlateTriggered(Agent : ?agent) : void =
        # 1. Global announcement to every player
        GlobalHUD.Show()

        # 2. Personal persistent message for the triggering player only
        if (A := Agent?):
            PersonalHUD.Show(A, PersonalTip("You found the vault — grab the loot!"), ?DisplayTime := 0.0)

    # Called when the personal message is hidden for any agent
    OnPersonalMessageHidden(A : agent) : void =
        # Clean up any remaining queued messages across all players
        PersonalHUD.ClearAllMessages()

Line-by-line breakdown:

Line(s) What it does
@editable Plate Wires the pressure plate placed in the level.
@editable GlobalHUD / PersonalHUD Two separate hud_message_device instances — one for everyone, one per-player.
VaultOpened<localizes> Wraps a raw string into a message — required for any method that takes message.
GlobalHUD.SetDisplayTime(3.0) Tells the global device to auto-hide after 3 seconds.
GlobalHUD.SetText(...) Pre-loads the text so Show() has something to display.
GlobalHUD.Show() Broadcasts to all players simultaneously.
PersonalHUD.Show(A, ..., ?DisplayTime := 0.0) Shows a custom inline message to one agent, pinned permanently (0.0).
PersonalHUD.HideMessageEvent.Subscribe(...) Fires whenever the personal message is hidden on any screen.
PersonalHUD.ClearAllMessages() Wipes the queue for all affected players — good housekeeping.

Common patterns

Pattern 1 — Dynamic countdown using SetText + SetDisplayTime

Update the HUD message every second to show a live countdown, then clear it when time is up.

countdown_hud_device := class(creative_device):

    @editable
    CountdownHUD : hud_message_device = hud_message_device{}

    CountdownText<localizes>(N : int) : message = "Round starts in {N}..."
    GoText<localizes>(S : string) : message = "{S}"

    OnBegin<override>()<suspends> : void =
        # Pin the message — we'll clear it manually
        CountdownHUD.SetDisplayTime(0.0)

        var SecondsLeft : int = 5
        loop:
            if (SecondsLeft <= 0):
                break
            CountdownHUD.SetText(CountdownText(SecondsLeft))
            CountdownHUD.Show()
            Sleep(1.0)
            set SecondsLeft = SecondsLeft - 1

        # Show "GO!" for 2 seconds then clear
        CountdownHUD.SetDisplayTime(2.0)
        CountdownHUD.SetText(GoText("GO!"))
        CountdownHUD.Show()
        Sleep(2.0)
        CountdownHUD.ClearAllMessages()

Covers: SetText, SetDisplayTime, Show(), ClearAllMessages


Pattern 2 — Per-player elimination streak with Show(Agent, Message)

When a player gets an elimination, show them a personal streak message without interrupting other players' HUDs.

streak_hud_device := class(creative_device):

    @editable
    EliminationManager : elimination_manager_device = elimination_manager_device{}

    @editable
    StreakHUD : hud_message_device = hud_message_device{}

    StreakMsg<localizes>(N : int) : message = "Elimination streak: {N}!"

    # Track per-player streak counts
    var Streaks : [agent]int = map{}

    OnBegin<override>()<suspends> : void =
        EliminationManager.EliminationEvent.Subscribe(OnElimination)

    OnElimination(Result : elimination_result) : void =
        if (Eliminator := Result.EliminatingAgent?):
            CurrentStreak : int =
                if (S := Streaks[Eliminator]):
                    S
                else:
                    0
            NewStreak := CurrentStreak + 1
            if (set Streaks[Eliminator] = NewStreak) {}
            # Show personal message for 2.5 seconds
            StreakHUD.Show(Eliminator, StreakMsg(NewStreak), ?DisplayTime := 2.5)

Covers: Show(Agent, Message, ?DisplayTime)


Pattern 3 — React to ShowMessageEvent and hide for a specific agent

Listen for when any message appears, then hide it for a specific VIP agent who shouldn't see spoilers.

vip_filter_hud_device := class(creative_device):

    @editable
    AnnouncementHUD : hud_message_device = hud_message_device{}

    # The VIP player agent reference (set via game logic elsewhere)
    var VIPAgent : ?agent = false

    OnBegin<override>()<suspends> : void =
        AnnouncementHUD.ShowMessageEvent.Subscribe(OnMessageShown)

        # Simulate acquiring a VIP after 2 seconds
        Sleep(2.0)
        Playspace := GetPlayspace()
        Players := Playspace.GetPlayers()
        if (First := Players[0]):
            set VIPAgent = option{First.GetAgent[]}

        # Broadcast a message to everyone
        AnnouncementHUD.SetDisplayTime(5.0)
        AnnouncementHUD.SetText(SpoilerText("Boss location revealed!"))
        AnnouncementHUD.Show()

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

    # Fires for each agent the message is shown to
    OnMessageShown(A : agent) : void =
        # If this is our VIP, immediately hide it for them
        if (VIP := VIPAgent?):
            if (A = VIP):
                AnnouncementHUD.Hide(VIP)

Covers: ShowMessageEvent, SetText, SetDisplayTime, Show(), Hide(Agent)


Gotchas

1. message is NOT a string — use <localizes>

Every method that takes text (SetText, Show(Agent, Message, ...), Show(Message, ...)) expects a message type, not a plain string. There is no StringToMessage function. You must declare a localizer:

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

Then call SetText(MyLabel("Hello!")). Passing a raw string literal directly will fail to compile.

2. DisplayTime := 0.0 means forever, not "instant hide"

Passing 0.0 to SetDisplayTime or the ?DisplayTime parameter pins the message on screen indefinitely. You must call Hide(), Hide(Agent), or ClearAllMessages() to remove it. This is intentional and useful for persistent objective text, but easy to forget.

3. Show() replaces the active message — queue carefully

Calling Show() while a message is already visible will replace it immediately. If you need sequential messages, Sleep between calls or use GetDisplayTime() to know when the current one expires.

4. Unwrap ?agent before calling Show(Agent)

Events like trigger_device.TriggeredEvent fire listenable(?agent) — an optional agent. You must unwrap it before passing to Show(Agent:agent):

OnTriggered(MaybeAgent : ?agent) : void =
    if (A := MaybeAgent?):
        MyHUD.Show(A)  # safe — A is agent, not ?agent

Passing ?agent directly to a method expecting agent is a compile error.

5. ClearAllMessagesEvent fires with an agent parameter

Despite clearing all messages, ClearAllMessagesEvent is typed listenable(agent). Your handler must accept an agent argument. It represents one of the affected agents — don't assume it's a specific player.

6. Text is clamped to 150 characters

SetText silently clamps its input. If your dynamic string might exceed 150 characters, truncate it in Verse before passing it in — there's no error or event to warn you.

7. Use two devices for global + per-player simultaneously

You cannot send a global Show() and a targeted Show(Agent) from the same device instance in the same tick and have both work independently. Use two separate hud_message_device instances — one configured for all players, one for targeted messages.

Device Settings & Options

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

Hud Message Device settings and options panel in the UEFN editor — Message, Time From Round Start
Hud Message Device — User Options in the UEFN editor: Message, Time From Round Start
⚙️ Settings on this device (2)

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

Message
Time From Round Start

Guides & scripts that use hud_message_device

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

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