Create Dynamic NPC Dialogue & UI Updates in UEFN
Tutorial intermediate

Create Dynamic NPC Dialogue & UI Updates in UEFN

Updated intermediate

What you'll learn

  • How to initialize a Verse creative device and declare editable references.
  • The difference between fallible (<decides>) and suspending (<suspends>) calls.
  • How to safely extract player UI and attach custom widgets at runtime.
  • Performing robust integer math for cycling through dialogue nodes.

How it works

UEFN's built-in Conversation Editor is powerful, but sometimes you need granular control over text rendering and interaction triggers. By placing a button_device in the world, we can intercept player inputs directly in Verse. When a player presses the button, our code subscribes to that event, retrieves the active player_ui instance (which fails gracefully if none exists), and commands a widget to display the next line from our data array. Because Verse is strongly typed and memory-safe, we use specialized total-int helpers to prevent runtime crashes when cycling through array indices.

Let's build it

Here is a complete, drop-in implementation that binds a button press to a rotating dialogue string displayed on the player's screen. Notice how GetPlayerUI uses brackets [] because it is a <decides> function, and how we calculate the next dialogue index safely.

using { /UnrealEngine.com/Temporary/UI }
using { /Fortnite.com/UI }
using { /Verse.org/Simulation }
using { /Verse.org/Verse }

my_dialogue_device := class<concrete>(creative_device):

    @editable Button : button_device = button_device{}
    @editable Label : widget = widget{}
    
    Lines : array{message} = array{"Greetings traveler.", "Tell me more.", "Safe travels!"}
    Index : int = 0
    
    // Total-int helper prevents division-by-zero or negative modulo crashes
    VC_IntMod(A:int, B:int):int =
        if (R := Mod[A, B]): R else: 0
        
    OnBegin<override>()<suspends> : void =
        Handler(Time: float) <suspends>: void =
            Player : player = Self.GetPlayspace().GetPlayers()[0]
            
            // GetPlayerUI returns a result<player_ui>, so it MUST be called with []
            // and wrapped in an if-statement to handle missing UI safely.
            if (PUI := GetPlayerUI[](Player)):
                // Fetch the current message from our Verse "Data Table"
                Message := Lines[Index]
                
                // Update the widget content and position
                SetText(Label, Message)
                SetVisibility(Label, widget_visibility::Visible)
                AddWidget(PUI, Label)
                
                // Cycle to the next index safely using our VC helper
                set Index = VC_IntMod(Index + 1, 3)
                
                Print("Showing line {Index}")
            else:
                Print("No player UI connected.")
                
        // Device events subscribe directly without parentheses on the property
        H := Button.ButtonActivatedEvent.Subscribe(Handler)

Try it yourself

  1. Add a third editable button_device reference and chain multiple buttons to increment different counters.
  2. Experiment with widget_visibility::Hidden to fade out the dialogue after a 3-second Sleep().
  3. Replace the hardcoded 3 in VC_IntMod with Length[Lines] once you become comfortable with array bounds checking.

Recap

By leveraging Verse’s effect system (<suspends> for async waits, <decides> for failure handling), you can build highly responsive, data-driven NPC interactions. Always remember to wrap fallible calls in if (Val := FailFunc[]) blocks, use total-int helpers for math, and subscribe to device events using the exact member names exposed by the engine. Mastering these patterns unlocks the true potential of programmable worlds in UEFN.

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 Dynamic NPC Dialogue System with Verse Data Tables and Runtime UI Updates 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