terça-feira, 16 de setembro de 2025

UEFN Verse: Tuple

A Tuple is a container that stores a sequence of elements that can be of different types in a simple way. Tuple elements can be accessed by an index that indicates their position.

In the example below, PersonData is a Tuple with three elements of type string, int and float. 

PersonData : tuple(string, int, float) = ("Romero", 47, 1.80)

Print("Name: { PersonData(0) }")
Print("Age: { PersonData(1) }")
Print("Height: { PersonData(2) }")

One of the uses of Tuple is that it allows a function to return more than one value. A function's return type can be a Tuple with multiple elements, as shown in the following code.

GenerateWarriorData(): tuple(string, int, float) =

    var Name : string = ""

    if( RandomName := WarriorNames[ GetRandomInt(0, WarriorNames.Length - 1) ] ):
        set Name = RandomName 
	
    ArmorLevel := GetRandomInt(2,6)

    Speed := GetRandomFloat(5.0, 10.0)

    # Returns this tuple
    ( Name, ArmorLevel, Speed )

WarriorNames is a string array containing some names. The GenerateWarriorData function generates some random values ​​that are returned as a Tuple.

Another interesting feature of the Tuple is that it can be passed to a function when the function's parameters have types equivalent to the Tuple's elements. This will be demonstrated in the main example of this article.

An element of a tuple can be an array or another Tuple. My suggestion is to avoid creating complex Tuples with many elements because the programmer will need to check the meaning of each element, which can lead to difficult-to-find errors.

Instead of creating a complex Tuple, create a struct or class with well-defined field names.

In the example Verse device, I will show different ways to call a function with Tuples. 

In any UEFN project, open Verse Explorer, right-click on the project name and choose the Add new Verse file to project option.

In Device Name put tuple_device and click the Create Empty button.

Copy the Verse code below into the tuple_device file:

using { /Fortnite.com/Devices }
using { /Verse.org/Simulation }
using { /Verse.org/Random }
using { /UnrealEngine.com/Temporary/Diagnostics }

tuple_device := class(creative_device):

    WarriorNames : []string = array{"Archon", "Aryss", "Alarik", "Dessloch", 
                   "Cryss", "Nikita", "Drimacus", "Rhea", "Raynor", "Kira"}

    OnBegin<override>()<suspends>:void=
        
        var Warrior1 : tuple(string, int, float) = ("", 0, 0.0)

        set Warrior1 = GenerateWarriorData()

        Warrior2 := GenerateWarriorData()

        ShowWarriorData( Warrior1(0), Warrior1(1), Warrior1(2) )

        ShowWarriorData( Warrior2 )

        ShowWarriorData( GenerateWarriorData() )

    GenerateWarriorData(): tuple(string, int, float) =

        var Name : string = ""

        if( RandomName := WarriorNames[ GetRandomInt(0, WarriorNames.Length - 1) ] ):
            set Name = RandomName 
        
        ArmorLevel := GetRandomInt(2,6)

        Speed := GetRandomFloat(5.0, 10.0)

        # Returns this tuple
        ( Name, ArmorLevel, Speed )

    ShowWarriorData(Name:string, ArmorLevel:int, Speed:float):void =
        Print("Name: {Name} | Armor Level: {ArmorLevel} | Speed: {Speed}")

The ShowWarriorData() function is called 3 times:

  • The first time, each element of the Tuple is accessed by index and passed as a parameter. 
  • The second time, the Tuple is passed as a parameter. This is allowed when the types of the Tuple's elements are equivalent to the types of the function's parameters.
  • The third time, the Tuple resulting from the GenerateWarriorData() function will be passed as a parameter.


Save the file and compile the Verse code using the Verse > Build Verse Code option from the UEFN menu.

Access the Content Drawer and add the tuple_device to the level. Save the level and click the Launch Session button to load it into Fortnite. 

After starting the Fortnite session, press the Tab key and select the Log tab to view the log with the messages written with the generated data.


UEFN Verse: Tupla

Uma Tupla é um container que armazena de uma forma simples uma sequência de elementos que podem ser de tipos diferentes. Os elementos da Tupla podem ser acessados por um índice que indica a posição.

No exemplo abaixo, PersonData é uma Tupla com três elementos do tipo string, int e float

PersonData : tuple(string, int, float) = ("Romero", 47, 1.80)

Print("Name: { PersonData(0) }")
Print("Age: { PersonData(1) }")
Print("Height: { PersonData(2) }")

Uma das utilidades da Tupla é permitir que uma função retorne mais de uma valor. O tipo de retorno de uma função pode ser uma Tupla com vários elementos como mostra o código a seguir.

GenerateWarriorData(): tuple(string, int, float) =

    var Name : string = ""

    if( RandomName := WarriorNames[ GetRandomInt(0, WarriorNames.Length - 1) ] ):
        set Name = RandomName 
	
    ArmorLevel := GetRandomInt(2,6)

    Speed := GetRandomFloat(5.0, 10.0)

    # Retorna esta tupla
    ( Name, ArmorLevel, Speed )

WarriorNames é um array de string que possui alguns nomes armazenados. A função GenerateWarriorData gera alguns valores aleatórios que são retornados dentro de uma Tupla.

Outra característica interessante da Tupla é que ela pode ser passada para uma função quando os parâmetros da função tem os tipos equivalentes aos elementos da Tupla. Isto será demonstrado no exemplo principal deste artigo.

Um elemento de uma Tupla pode ser um array ou outra Tupla. Minha sugestão é de não criar Tuplas complexas com muitos elementos porque o programador vai precisar checar o significado de cada elemento e isso pode provocar erros difíceis de encontrar. 

Ao invés de criar uma Tupla complexa, crie uma struct ou class com os nomes de campos bem definidos.

No dispositivo Verse de exemplo, será mostrado diferentes forma de chamar uma função com Tuplas. 

Em qualquer projeto UEFN, abra o Verse Explorer, clique com o botão-direito no nome do projeto e escolha a opção Add new Verse file to project.

Em Device Name coloque tuple_device clique no botão Create Empty.

Copie o código Verse abaixo para o dispositivo tuple_device:

using { /Fortnite.com/Devices }
using { /Verse.org/Simulation }
using { /Verse.org/Random }
using { /UnrealEngine.com/Temporary/Diagnostics }

tuple_device := class(creative_device):

    WarriorNames : []string = array{"Archon", "Aryss", "Alarik", "Dessloch", 
                   "Cryss", "Nikita", "Drimacus", "Rhea", "Raynor", "Kira"}

    OnBegin<override>()<suspends>:void=
        
        var Warrior1 : tuple(string, int, float) = ("", 0, 0.0)

        set Warrior1 = GenerateWarriorData()

        Warrior2 := GenerateWarriorData()

        ShowWarriorData( Warrior1(0), Warrior1(1), Warrior1(2) )

        ShowWarriorData( Warrior2 )

        ShowWarriorData( GenerateWarriorData() )

    GenerateWarriorData(): tuple(string, int, float) =

        var Name : string = ""

        if( RandomName := WarriorNames[ GetRandomInt(0, WarriorNames.Length - 1) ] ):
            set Name = RandomName 
        
        ArmorLevel := GetRandomInt(2,6)

        Speed := GetRandomFloat(5.0, 10.0)

        # Retorna esta tupla
        ( Name, ArmorLevel, Speed )

    ShowWarriorData(Name:string, ArmorLevel:int, Speed:float):void =
        Print("Name: {Name} | Armor Level: {ArmorLevel} | Speed: {Speed}")

A função ShowWarriorData() é chamada 3 vezes:

  • Na primeira vez, cada elemento da tupla é acessado pelo índice e passado como parâmetro. 
  • Na segunda vez, a Tupla é passado como parâmetro. Isto é permitido quando os tipos dos elementos da Tupla são equivalentes aos tipos dos parâmetros da função.
  • Na terceira vez, a Tupla resultante da função GenerateWarriorData() será passada como parâmetro.


Salve o arquivo e compile o código Verse usando a opção Verse > Build Verse Code do menu do UEFN. 

Acesse o Content Drawer e adicione o dispositivo tuple_device ao nível. Salve o nível e clique no botão Launch Session para carregar o nível no Fortnite.  

Após iniciar a partida no Fortnite, pressione a tecla Tab e selecione a aba Registro para visualizar o log com as mensagem escritas com os dados gerados.

terça-feira, 9 de setembro de 2025

UEFN Verse: Enum (enumeration)

The Enumeration (Enum) is used to create a new data type whose possible values ​​are restricted to the set of constants defined in the enumeration.

In the example below, difficulty is an Enumeration with five possible values.

difficulty := enum{Story, Easy, Normal, Hard, Expert}

To define a difficulty type constant that can be modified in the editor, do this:

@editable
Difficulty : difficulty = difficulty.Normal


An Enumeration can be closed or open. The difficulty Enumeration we created is closed because it's the default. A closed Enumeration cannot be modified after the island (map or experience) has been published in Fortnite, so it should only be used when you're sure the Enumeration won't change.

To create an open Enumeration, use the <open> specifier as shown in the code below which defines some states that will be used by an NPC guard:

guard_states := enum<open>{Idle, Patrolling, Searching, Attacking}


Let's create a device in UEFN to demonstrate the use of Enumeration. In any UEFN project, open Verse Explorer, right-click on the project name and choose the Add new Verse file to project option.

In Device Name put enum_device and click the Create Empty button.

Copy the Verse code below into the enum_device file:

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

difficulty := enum{Story, Easy, Normal, Hard, Expert}

enum_device := class(creative_device):

    @editable
    Difficulty : difficulty = difficulty.Normal 

    var EnemyAttackModifier : float = 1.0

    OnBegin<override>()<suspends>:void=

        case(Difficulty):
            difficulty.Story => 
                set EnemyAttackModifier = 0.5
                Print("Enemy Attack Modifier of 50% in Story Difficulty.")

            difficulty.Easy =>
                set EnemyAttackModifier = 0.75
                Print("Enemy Attack Modifier of 75% in Easy Difficulty.")

            difficulty.Normal =>
                set EnemyAttackModifier = 1.0
                Print("Enemy Attack Modifier of 100% in Normal Difficulty.")

            difficulty.Hard =>
                set EnemyAttackModifier = 1.25
                Print("Enemy Attack Modifier of 125% in Hard Difficulty.")

            difficulty.Expert =>
                set EnemyAttackModifier = 1.5
                Print("Enemy Attack Modifier of 150% in Expert Difficulty.")


This example will assign different values ​​to the EnemyAttackModifier variable depending on the difficulty selected in enum_device.

Note that the case does not contain the default block "_". This is not required when the Enumeration used in the case is closed and all Enumeration values ​​have code blocks.

Save the file and compile the Verse code using the Verse > Build Verse Code option from the UEFN menu.

Access the Content Drawer and add the enum_device to the level. Select the enum_device in the level and in the Details tab, click the Difficulty field dropdown to select one of the Enumeration values.



Save the level and click the Launch Session button to load it into Fortnite. After starting the Fortnite session, press the Tab key and select the Log tab to view the log with the message written according to the selected difficulty.



UEFN Verse: Enum (enumeração)

A Enumeração (Enum) é usada para criar um novo tipo de dado cujo possíveis valores são restritos ao conjunto de constantes definidas na enumeração.

No exemplo abaixo, difficulty é uma Enumeração com cinco possíveis valores.

difficulty := enum{Story, Easy, Normal, Hard, Expert}

Para definir uma constante do tipo difficulty que pode ser modificada no editor, faça assim:

@editable
Difficulty : difficulty = difficulty.Normal


Uma Enumeração pode ser closed ou open. A Enumeração difficulty que criamos é closed por que este é o padrão. Uma Enumeração closed não pode ser modificada depois que a ilha (mapa ou experiência) foi publicada no Fortnite, por isso ela deve ser usada somente quando você tem certeza de que a Enumeração não vai mudar.

Para criar uma Enumeração open, use o especificador <open> como mostra o código abaixo que define alguns estados que serão usados por um guarda NPC:

guard_states := enum<open>{Idle, Patrolling, Searching, Attacking}


Vamos criar um dispositivo no UEFN para demonstrar o uso da Enumeração. Em qualquer projeto UEFN, abra o Verse Explorer, clique com o botão-direito no nome do projeto e escolha a opção Add new Verse file to project.

Em Device Name coloque enum_device clique no botão Create Empty.

Copie o código Verse abaixo para o dispositivo enum_device:

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

difficulty := enum{Story, Easy, Normal, Hard, Expert}

enum_device := class(creative_device):

    @editable
    Difficulty : difficulty = difficulty.Normal 

    var EnemyAttackModifier : float = 1.0

    OnBegin<override>()<suspends>:void=

        case(Difficulty):
            difficulty.Story => 
                set EnemyAttackModifier = 0.5
                Print("Enemy Attack Modifier of 50% in Story Difficulty.")

            difficulty.Easy =>
                set EnemyAttackModifier = 0.75
                Print("Enemy Attack Modifier of 75% in Easy Difficulty.")

            difficulty.Normal =>
                set EnemyAttackModifier = 1.0
                Print("Enemy Attack Modifier of 100% in Normal Difficulty.")

            difficulty.Hard =>
                set EnemyAttackModifier = 1.25
                Print("Enemy Attack Modifier of 125% in Hard Difficulty.")

            difficulty.Expert =>
                set EnemyAttackModifier = 1.5
                Print("Enemy Attack Modifier of 150% in Expert Difficulty.")


Este exemplo irá atribuir valores diferentes para a variável EnemyAttackModifier conforme a dificuldade selecionada no enum_device.

Observe que o case não contém o bloco padrão "_". Ele não é obrigatório quando a Enumeração usada no case é closed e todos os valores da Enumeração possuem blocos de código.

Salve o arquivo e compile o código Verse usando a opção Verse > Build Verse Code do menu do UEFN. 

Acesse o Content Drawer e adicione o dispositivo enum_device ao nível. Selecione o enum_device no nível e na aba Details, clique no dropdown do campo Difficulty para selecionar um dos valores da Enumeração.



Salve o nível e clique no botão Launch Session para carregar o nível no Fortnite.  Após iniciar a partida no Fortnite, pressione a tecla Tab e selecione a aba Registro para visualizar o log com a mensagem escrita conforme a dificuldade selecionada.



segunda-feira, 1 de setembro de 2025

UEFN Verse: Case (Control Flow)

Case is a control flow expression that compares a value to a list of options to decide which block of code should be executed.

In the example below, Mode is a string variable. There are code blocks associated with the values ​​"EASY", "NORMAL", and "HARD". The _ symbol represents the default block that will be executed if the Mode value has no associated block.

case (Mode):
    "EASY" =>
        set NumberOfEnemies = 15
        Print("Easy mode selected")
    "NORMAL" => 
        set NumberOfEnemies = 25
        Print("Normal mode selected")
    "HARD" =>
        set NumberOfEnemies = 35
        Print("Hard mode selected")
    _ => 
        Print("Mode is invalid")

A expressão usada no teste do Case pode ser dos tipos int, logic, string, char e enum. No artigo sobre enum (enumeração) veremos como usar o Case com enum.

The expression used in the Case test can be of the int, logic, string, char, or enum types. In the article on enum (enumeration), we'll see how to use Case with enum.

To demonstrate how to use the Case, we'll create a device that will function as a fortune message generator. The device will have references to a button device and a billboard device. When the player presses the button, one of the messages will be selected and displayed on the billboard.

In any UEFN project, open Verse Explorer, right-click on the project name and choose the Add new Verse file to project option.

In Device Name put case_device and click the Create Empty button.

Copy the Verse code below into the case_device file:

using { /Fortnite.com/Devices }
using { /Verse.org/Simulation }
using { /UnrealEngine.com/Temporary/Diagnostics }
using { /Verse.org/Random }

case_device := class(creative_device):

    @editable
    BillboardDevice : billboard_device = billboard_device{}

    @editable
    ButtonDevice : button_device = button_device{}

    var IndexOfMessage : int = 0
    var FortuneString : string = ""

    OnBegin<override>()<suspends>:void=

        loop:
            ButtonDevice.InteractedWithEvent.Await()

            set IndexOfMessage = GetRandomInt(1, 5)

            set FortuneString = case (IndexOfMessage):
                1 => "A journey of a thousand miles begins with a single step."
                2 => "One bad chapter doesn't mean your story is over."
                3 => "It is easier to stay out than to get out."
                4 => "Experience is the best teacher."
                5 => "Try and fail, but never fail to try."
                _ => "Message not found."

            BillboardDevice.SetText( ConvertToMessage(FortuneString) )
            Sleep(2.0)

    ConvertToMessage<localizes>(StringValue:string) : message = "{StringValue}"

The OnBegin function contains a loop. The first expression within the loop waits until the player interacts with the button. After interacting with the button, a random number from 1 to 5 is generated and stored in IndexOfMessage to be used as a test expression in the case.

Each case block results in a string that will be stored in the FortuneString variable. The BillboardDevice's SetText() function takes a message as a parameter, so it was necessary to create the ConvertToMessage() function to convert from a string to a message.

The Sleep() function is used to pause for 2 seconds before restarting the loop and waiting again for the player to press the button to see another message.

Save the file and compile the Verse code using the Verse > Build Verse Code option from the UEFN menu.

Access the Content Drawer and add our case_device to the level.

Add a Button Device and a Billboard Device to the level. Select the Billboard Device and in the Details tab, check the Show Border field to make the billboard visible on the level.

Select the case_device in the level. In the Details tab, add the Billboard Device and Button Device references.



Save the level and click the Launch Session button to load the level into Fortnite. Interact with the button to display one of the messages on the Billboard. Press again to see another message. 




UEFN Verse: Case (controle de fluxo)

Case é uma expressão de controle de fluxo que compara um valor a uma lista de opções para decidir qual bloco de código deve ser executado.

No exemplo abaixo, Mode é uma variável do tipo string. Existem blocos de código associados aos valores "EASY", "NORMAL" e "HARD". O símbolo _ representa o bloco default que será executado caso o valor de Mode não tenha um bloco associado.

case (Mode):
    "EASY" =>
        set NumberOfEnemies = 15
        Print("Easy mode selected")
    "NORMAL" => 
        set NumberOfEnemies = 25
        Print("Normal mode selected")
    "HARD" =>
        set NumberOfEnemies = 35
        Print("Hard mode selected")
    _ => 
        Print("Mode is invalid")

A expressão usada no teste do Case pode ser dos tipos int, logic, string, char e enum. No artigo sobre enum (enumeração) veremos como usar o Case com enum.

Para demonstrar o uso do Case, vamos criar um dispositivo que funcionará como um gerador de mensagens da sorte. O dispositivo terá referências para um button device e um billboard device. Quando o jogador pressionar o botão, será selecionada uma das mensagens e exibida no billboard (quadro de aviso).

Em qualquer projeto UEFN, abra o Verse Explorer, clique com o botão-direito no nome do projeto e escolha a opção Add new Verse file to project.

Em Device Name coloque case_device clique no botão Create Empty.

Copie o código Verse abaixo para o dispositivo case_device:

using { /Fortnite.com/Devices }
using { /Verse.org/Simulation }
using { /UnrealEngine.com/Temporary/Diagnostics }
using { /Verse.org/Random }

case_device := class(creative_device):

    @editable
    BillboardDevice : billboard_device = billboard_device{}

    @editable
    ButtonDevice : button_device = button_device{}

    var IndexOfMessage : int = 0
    var FortuneString : string = ""

    OnBegin<override>()<suspends>:void=

        loop:
            ButtonDevice.InteractedWithEvent.Await()

            set IndexOfMessage = GetRandomInt(1, 5)

            set FortuneString = case (IndexOfMessage):
                1 => "A journey of a thousand miles begins with a single step."
                2 => "One bad chapter doesn't mean your story is over."
                3 => "It is easier to stay out than to get out."
                4 => "Experience is the best teacher."
                5 => "Try and fail, but never fail to try."
                _ => "Message not found."

            BillboardDevice.SetText( ConvertToMessage(FortuneString) )
            Sleep(2.0)

    ConvertToMessage<localizes>(StringValue:string) : message = "{StringValue}"

Na função OnBegin tem um loop. A primeira expressão dentro do loop fica esperando até que o jogador interaja com o botão. Após a interação com o botão é gerado um número aleatório de 1 a 5 que é armazenado em IndexOfMessage e usado como expressão de teste no case.

Cada um dos blocos do case resulta em uma string que será armazenada na variável FortuneString. A função SetText() do BillboardDevice recebe como parâmetro uma message, por isso foi preciso fazer a função ConvertToMessage() para converter de string para message.

A função Sleep() é usada para fazer uma pausa de 2 segundos antes de reiniciar o loop e esperar novamente que o jogador pressione o botão para ver outra mensagem.

Salve o arquivo e compile o código Verse usando a opção Verse > Build Verse Code do menu do UEFN. 

Acesse o Content Drawer e adicione o dispositivo case_device ao nível. Adicione um Button Device e um Billboard Device no nível. Selecione o Billboard Device e na aba Details marque o campo Show Border para que o billboard fique visível no nível.

Selecione o case_device no nível. Na aba Details adicione as referências do Billboar Device e do Button Device.



Salve o nível e clique no botão Launch Session para carregar o nível no Fortnite. Interaja com o botão para exibir uma das mensagens no Billboard. Pressione novamente para ver outra mensagem.



quarta-feira, 20 de agosto de 2025

UEFN Verse: Branch (Time Flow)

Branch is a time flow control expression that executes other expressions and immediately ends, continuing the flow with the existing expressions after the branch. If the async context (such as OnBegin) ends, the expressions initiated by the branch are automatically canceled if they are still active.

The Branch can be used for side tasks that don't affect the main game logic, such as background animations.

Let's create a simple example to demonstrate how to use Branch. We'll use a function that continuously rotates a creative_prop. We'll use the Sleep function to keep the async context active for a few seconds so we can view the rotation initiated by Branch. When the timer expires, the OnBegin function will exit, and the rotation will automatically stop.

In any UEFN project, open Verse Explorer, right-click on the project name and choose the Add new Verse file to project option.

In Device Name put branch_device and click the Create Empty button.

Copy the Verse code below into the branch_device file:

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

branch_device := class(creative_device):

    @editable
    PropToRotate : creative_prop = creative_prop{}

    OnBegin<override>()<suspends>:void=
       
        branch:
            RotateProp(PropToRotate)

        Sleep(10.0)
        Print("The RotateProp is canceled when the OnBegin completes")
                
    RotateProp(Prop : creative_prop)<suspends>:void=

        loop:
            PropTransform := Prop.GetTransform()
            PropLocation  := PropTransform.Translation
            PropRotation  := PropTransform.Rotation

            NewRotation := PropRotation.ApplyYaw(180.0)

            Prop.MoveTo(PropLocation, NewRotation, 2.0)

The branch expression in the example above calls the RotateProp() function, which will rotate the creative_prop and then terminates. The Sleep() function will wait for 10 seconds before the OnBegin function completes and the RotateProp() function is canceled.

Save the file and compile the Verse code using the Verse > Build Verse Code option from the UEFN menu.

Access the Content Drawer and add our branch_device to the level. Add some Prop to the level to be rotated by our device. I used Office Chair 02.

Select the branch_device in the level. In the Details tab, add the Prop reference in PropToRotate field.



Save the level and click the Launch Session button to load the level into Fortnite. Watch the Prop rotate. After 10 seconds, it will stop rotating because the function initiated by Branch will be automatically canceled.