Reference Verse compiles

string.Length: Reading Player Input on a Pirate Cove HUD

Every string in Verse exposes a `.Length` property that tells you how many UTF-8 code units it contains — no import needed, no helper function required. On a sun-drenched pirate cove island you can use `.Length` to check whether a player's typed alias is too short, too long, or just right, then flash the result on a `hud_message_device` so the whole crew can see it. This article walks you through the full pattern: reading `.Length`, branching on it, and driving real HUD + trigger devices with th

Updated Examples verified on the live UEFN compiler

Overview

In Verse, text is stored in the string type — letters, numbers, punctuation, spaces, even emojis. Every string carries a .Length member that tells you how many UTF-8 code units it contains. There is no separate string-length device: length is a built-in property you read off any string value with a dot, exactly like "Hello".Length.

The game problem it solves is validation and formatting. On a sunny island cove you might have a sign-in terminal where players type a codename: too short and it looks empty, too long and it overflows your 2D cel-shaded banner. Reading .Length lets you gate a granter, light a signal, or pick which localized message to show — all driven by how much text the player supplied.

One subtlety to keep in your back pocket: .Length counts code units, not visible characters. "José".Length is 5 (the accented é takes two units) while "Jose".Length is 4. For ASCII names they match; for fancy text they don't. We'll return to this in Gotchas.

API Reference

(API surface could not be resolved for this device.)

Walkthrough

The scene: a wooden sign-in post on a cove dock. A player walks up and hits a button to "claim" their spot. We read the player's platform name, check its .Length, and react: names that are too short get a warning message, good-length names light up a billboard with a welcome and trigger a prop mover / vault — here modeled as an item_granter_device that hands the player a celebratory item.

We declare the placed devices as @editable fields, subscribe to the button in OnBegin, and do all the length logic in the handler.

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

cove_signin := class(creative_device):

    # The button the player presses to claim their spot on the cove.
    @editable
    ClaimButton : button_device = button_device{}

    # The billboard sign that shows the welcome / warning text.
    @editable
    WelcomeSign : hud_message_device = hud_message_device{}

    # Hands the player a celebratory item when their name fits.
    @editable
    RewardGranter : item_granter_device = item_granter_device{}

    # Localized text helpers (a message param needs a localized value).
    TooShort<localizes>(S : string) : message = "Name too short: {S}"
    WelcomeMsg<localizes>(S : string) : message = "Welcome aboard, {S}!"

    OnBegin<override>()<suspends> : void =
        # React each time a player interacts with the sign-in button.
        ClaimButton.InteractedWithEvent.Subscribe(OnClaim)

    OnClaim(Agent : agent) : void =
        # Read the player's display name off their character/agent.
        if (Player := player[Agent]):
            Name := Player.GetFortCharacter[].GetAgent[].GetName[]
            OnNameChecked(Agent, Name)

    OnNameChecked(Agent : agent, Name : string) : void =
        # .Length is the number of UTF-8 code units in the string.
        Len := Name.Length
        if (Len < 3):
            # Too short — show a warning on the sign, no reward.
            WelcomeSign.Show(Agent, TooShort(Name))
        else:
            # Good length — welcome them and hand out the reward.
            WelcomeSign.Show(Agent, WelcomeMsg(Name))
            RewardGranter.GrantItem(Agent)

Line by line:

  • The four @editable fields let you drop the real placed devices into these slots in the UEFN Details panel. Without the class(creative_device) wrapper, calling ClaimButton.Something() would fail with Unknown identifier.
  • TooShort and WelcomeMsg are <localizes> functions. A message parameter (what Show expects) needs a localized value — you cannot pass a raw string, and there is no StringToMessage. These helpers wrap the interpolated string into a message.
  • OnBegin subscribes OnClaim to the button's InteractedWithEvent so it runs every press.
  • In OnClaim we unwrap the agent into a player with player[Agent], then dig out the name. GetName[] returns a string.
  • OnNameChecked is where .Length earns its keep: Name.Length gives an int, we branch on it, and drive the sign (Show) and granter (GrantItem) with the result. Note the length lives entirely in Verse — no extra device required.

Common patterns

Pattern 1 — Clamp overly long names before display. If the name is longer than the sign can hold, slice the string down using a subrange, then show the trimmed version. .Length tells us whether trimming is needed.

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

name_trimmer := class(creative_device):

    @editable
    NameButton : button_device = button_device{}

    @editable
    Sign : hud_message_device = hud_message_device{}

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

    OnBegin<override>()<suspends> : void =
        NameButton.InteractedWithEvent.Subscribe(OnPress)

    OnPress(Agent : agent) : void =
        if (Player := player[Agent], Name := Player.GetFortCharacter[].GetAgent[].GetName[]):
            var Display : string = Name
            # If longer than 8 code units, keep only the first 8.
            if (Name.Length > 8):
                if (Cut := Name[0..7]):
                    set Display = Cut
            Sign.Show(Agent, Label(Display))

Pattern 2 — Gate a checkpoint by minimum length. A cliff-top gate (an item_granter_device standing in for the vault reward) only opens if the codename meets a minimum. Empty strings have .Length of 0.

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

codename_gate := class(creative_device):

    @editable
    EnterButton : button_device = button_device{}

    @editable
    GateGranter : item_granter_device = item_granter_device{}

    OnBegin<override>()<suspends> : void =
        EnterButton.InteractedWithEvent.Subscribe(OnEnter)

    OnEnter(Agent : agent) : void =
        if (Player := player[Agent], Name := Player.GetFortCharacter[].GetAgent[].GetName[]):
            # Require at least 4 code units before granting entry.
            if (Name.Length >= 4):
                GateGranter.GrantItem(Agent)

Pattern 3 — Compare against a fixed target string's length. A treasure sign hides a password; the player is only "close" if their guess matches the secret's length exactly. Both strings expose .Length.

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

length_hint := class(creative_device):

    @editable
    GuessButton : button_device = button_device{}

    @editable
    HintSign : hud_message_device = hud_message_device{}

    Secret : string = "coconut"

    RightLen<localizes>() : message = "Right length! Keep guessing."
    WrongLen<localizes>() : message = "Wrong length, try again."

    OnBegin<override>()<suspends> : void =
        GuessButton.InteractedWithEvent.Subscribe(OnGuess)

    OnGuess(Agent : agent) : void =
        if (Player := player[Agent], Guess := Player.GetFortCharacter[].GetAgent[].GetName[]):
            # Compare the two .Length values as ints.
            if (Guess.Length = Secret.Length):
                HintSign.Show(Agent, RightLen())
            else:
                HintSign.Show(Agent, WrongLen())

Gotchas

  • .Length counts code units, not characters. "José".Length is 5, "Jose".Length is 4. For plain ASCII names they agree, but accents, emojis, and other multi-byte glyphs count as more than one. Don't assume .Length equals what the player sees on screen.
  • .Length is an int. Verse never auto-converts int↔float, so if you ever need to compute a float ratio from it you must convert explicitly. Comparisons like < 3, >= 4, and = are all int operations.
  • You cannot pass a string where a message is required. Devices like hud_message_device.Show take a localized message. Wrap your text in a <localizes> helper (Label<localizes>(S:string):message = "{S}") and pass Label(Name) — there is no StringToMessage.
  • Slicing a string is failable. Name[0..7] is a subrange that can fail if the range is invalid, so it must be used inside an if (if (Cut := Name[0..7]):). Only trim after you've confirmed with .Length that the string is long enough.
  • Unwrap the agent first. Button/trigger handlers give you an agent; get the player with player[Agent] and read the name via the failable GetName[] — all inside an if, since any step can fail.
  • Empty strings are length 0, not a failure. An empty codename "" still has a valid .Length of 0; guard your minimums explicitly rather than relying on the read to fail.

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 →