Verse Damage API: Programmatic Health Control with UI
Tutorial intermediate

Verse Damage API: Programmatic Health Control with UI

Updated intermediate

What you'll learn

You will learn how to:

  1. Subscribe to a button_device interaction event and identify the acting agent.
  2. Convert an agent into a fort_character and use it as a damageable to call Damage(Amount:float).
  3. Build a canvas + text_block widget and attach it to the player's HUD with GetPlayerUI[] / AddWidget.

How it works

Fortnite characters implement a stack of interfaces including damageable, which exposes Damage(Amount:float):void. An agent is not itself damageable, so we first resolve the agent's fort_character with Agent.GetFortCharacter[] (a <decides> call — it lives inside an if). Once we have the character we can treat it as damageable and call Damage.

To give feedback we use the Verse UI system. GetPlayerUI[Player] fails-or-returns the player_ui for a player, and AddWidget(Widget) places a widget on their screen. We create the widget once in OnBegin, keep a reference to its text_block, and update its text each time damage is dealt with SetText.

Because Damage and HUD updates are one-way side effects, we validate everything (the agent maps to a player, the character exists, the UI resolves) before mutating state.

Let's build it

Place a button_device in your level and assign it to the @editable TriggerButton slot. Paste this into a new Verse file, build, and drop the device into the level.

using { /Fortnite.com/Devices }
using { /Fortnite.com/Characters }
using { /Fortnite.com/Devices/Patchwork }
using { /Verse.org/Simulation }
using { /UnrealEngine.com/Temporary/UI }
using { /UnrealEngine.com/Temporary/Diagnostics }

# Damages the player who presses a button and shows feedback on their HUD.
damage_ui_device := class<concrete>(creative_device):

    # Button whose interaction triggers the damage.
    @editable TriggerButton : button_device = button_device{}

    # How much damage each press applies.
    @editable DamageAmount : float = 15.0

    # Per-player HUD text block, kept so we can update it on repeat hits.
    var StatusTexts : [player]text_block = map{}

    OnBegin<override>()<suspends>: void =
        # Device events subscribe WITHOUT parentheses on the event name.
        TriggerButton.InteractedWithEvent.Subscribe(OnButtonPressed)

    # Handler receives the agent who interacted with the button.
    OnButtonPressed(Agent : agent) : void =
        # Resolve the acting agent to a concrete player.
        if (Player := player[Agent]):
            # Make sure the HUD text exists for this player, then apply damage.
            Text := EnsureStatusText(Player)
            # An agent is not damageable; its fort_character is. GetFortCharacter is <decides>.
            if (Char := Agent.GetFortCharacter[]):
                # fort_character implements damageable, so call Damage directly.
                Char.Damage(DamageAmount)
                Text.SetText(StringToMessage("Took {DamageAmount} damage!"))
                Print("Applied {DamageAmount} damage to player")

    # Returns the player's text_block, creating and attaching its HUD the first time.
    EnsureStatusText(Player : player) : text_block =
        if (Existing := StatusTexts[Player]):
            return Existing
        NewText := text_block{DefaultText := StringToMessage("Ready")}
        # Position the text with a canvas slot and add it to the player's UI.
        Root := canvas:
            Slots := array:
                canvas_slot:
                    Anchors := anchors{Minimum := vector2{X := 0.5, Y := 0.1}, Maximum := vector2{X := 0.5, Y := 0.1}}
                    Widget := NewText
        if (UI := GetPlayerUI[Player]):
            UI.AddWidget(Root)
        set StatusTexts[Player] = NewText
        return NewText

    # Small helper so interpolation returns a message for SetText/DefaultText.
    StringToMessage<localizes>(S : string) : message = "{S}"

Try it yourself

  • Change DamageAmount in the details panel and confirm the HUD text reflects the new value.
  • Track cumulative damage per player in a second [player]float map and show a running total in the text block.
  • Guard the damage behind a damage_volume_device and only apply it when Volume.IsInVolume[Agent] succeeds, so players are safe outside the zone.
  • Swap the plain text_block for a styled color by setting its text color, or add a second canvas_slot for a title line.

Recap

You subscribed to a button_device.InteractedWithEvent, resolved the acting agent to a player, converted it to a fort_character with the fallible GetFortCharacter[], and called the damageable interface's Damage(Amount:float). For feedback you built a canvas holding a text_block, attached it via GetPlayerUI[] and AddWidget, and updated it with SetText. The key idioms: fallible calls (player[...], GetFortCharacter[], GetPlayerUI[...], map indexing) live inside if, device events subscribe without parentheses, and one-way UI/damage side effects run only after all validations pass.

Check your understanding

Test yourself with an interactive quiz and track your progress + earn XP — free for members.

Turn this into a guided course

Add Applying Damage via Verse API to your free study plan — we'll suggest related pages and stitch the lot into one compile-checked, self-guided lesson with worked examples and quizzes.

Original tutorial generated by Verse Island from the Verse/UEFN knowledge base, with references to the Epic Games sources above. Code is validated against the knowledge base.

Comments

    Sign in to vote, comment, or suggest an edit. Sign in