terça-feira, 24 de junho de 2025

UEFN Verse: Class inheritance and <override>

Class inheritance is a fundamental concept for understanding Verse programming in UEFN.

To create a creative device in Verse, you need to create a subclass of the creative_device class. The new class will inherit the fields (constants and variables) and methods (functions) of the creative_device class that is used as a superclass as shown in the following line:

inheritance_device := class(creative_device):

The superclass is also known as the parent class or base class. The subclass is the child class.

The example below shows a base_bonus class with three fields and two methods. The base_bonus class is used as a superclass in the creation of the time_bonus class which will inherit the three fields and two methods of base_bonus.

base_bonus := class:
    BonusId : int = 1
    Name : string 
    BonusValue: int
	
    BonusData(): string =
        "BonusId: {BonusId} | Name: {Name} | BonusValue: {BonusValue}"

    ApplyBonus() : void =
        Print("Adding {BonusValue} to SCORE.")

time_bonus := class(base_bonus):
    BonusId<override> : int = 2
	
    ApplyBonus<override>() : void =
        Print("Adding {BonusValue} to TIME.")

The <override> specifier is being used to be able to initialize the BonusId field with a different value than the value used in the superclass. It is also being used to create a new version of the ApplyBonus()method in the time_bonus class.

Let's create a device in UEFN that uses the classes base_bonus and time_bonus. 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 inheritance_device and click the Create Empty button.

This device has an array to store references to base_bonus instances. The array is initialized with instances of base_bonus and time_bonus. This is possible because an instance of time_bonus is also of type base_bonus.

Copy the Verse code below into the inheritance_device file:

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

base_bonus := class:
    BonusId : int = 1
    Name : string 
    BonusValue: int
	
    BonusData(): string =
        "BonusId: {BonusId} | Name: {Name} | BonusValue: {BonusValue}"

    ApplyBonus() : void =
        Print("Adding {BonusValue} to SCORE.")

time_bonus := class(base_bonus):
    BonusId<override> : int = 2
	
    ApplyBonus<override>() : void =
        Print("Adding {BonusValue} to TIME.")

inheritance_device := class(creative_device):

    BonusArray : []base_bonus = array{ base_bonus{BonusValue := 50,  Name := "Score MEDIUM"},
				       base_bonus{BonusValue := 100, Name := "Score MAX"},
				       time_bonus{BonusValue := 30, Name := "Time MEDIUM"},
				       time_bonus{BonusValue := 60, Name := "Time MAX"} }

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

        for (Bonus : BonusArray):
            Print( Bonus.BonusData() )
            Bonus.ApplyBonus()

In the OnBegin method, the for loop is being used to iterate through all the elements of the array. For each element, the BonusData() and ApplyBonus() methods are executed. If the instance is of the time_bonus type, the version of ApplyBonus() that was overridden in the time_bonus class will be executed.

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 inheritance_device to the level.

Click the Launch Session button located in the UEFN toolbar to load the level into Fortnite. 

After starting the session in Fortnite, press the Tab key and select the Log tab to view the log with the messages written by the Print functions.


Table of Contents Verse


UEFN Verse: Herança de classe e <override>

Herança de classe é um conceito fundamental para entender a programação em Verse no UEFN. 

Para criar um dispositivo criativo no Verse, é preciso criar uma subclasse da classe creative_device. A nova classe herdará os campos (constantes e variáveis) e métodos (funções) da classe creative_device que é usada como superclasse como mostra a linha a seguir:

inheritance_device := class(creative_device):

A superclasse também é conhecida como classe pai ou classe base. A subclasse é a classe filha.

O exemplo abaixo mostra uma classe base_bonus com três campos e dois métodos. A classe base_bonus é usada como superclasse na criação da classe time_bonus que herdará os três campos e dois métodos de base_bonus.

base_bonus := class:
    BonusId : int = 1
    Name : string 
    BonusValue: int
	
    BonusData(): string =
        "BonusId: {BonusId} | Name: {Name} | BonusValue: {BonusValue}"

    ApplyBonus() : void =
        Print("Adding {BonusValue} to SCORE.")

time_bonus := class(base_bonus):
    BonusId<override> : int = 2
	
    ApplyBonus<override>() : void =
        Print("Adding {BonusValue} to TIME.")

O especificador <override> está sendo usado para poder inicializar o campo BonusId com um valor diferente do valor usado na superclasse. Ele também está sendo usado para criar uma nova versão do método ApplyBonus() na classe time_bonus.

Vamos criar um dispositivo no UEFN que usa as classes base_bonus e time_bonusEm 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 inheritance_device clique no botão Create Empty.

Este dispositivo possui um array para armazenar referências às instâncias de base_bonus. O array é inicializado com instâncias de base_bonus e de time_bonus. Isto é possível porque uma instância de time_bonus também é do tipo base_bonus.

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

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

base_bonus := class:
    BonusId : int = 1
    Name : string 
    BonusValue: int
	
    BonusData(): string =
        "BonusId: {BonusId} | Name: {Name} | BonusValue: {BonusValue}"

    ApplyBonus() : void =
        Print("Adding {BonusValue} to SCORE.")

time_bonus := class(base_bonus):
    BonusId<override> : int = 2
	
    ApplyBonus<override>() : void =
        Print("Adding {BonusValue} to TIME.")

inheritance_device := class(creative_device):

    BonusArray : []base_bonus = array{ base_bonus{BonusValue := 50,  Name := "Score MEDIUM"},
				       base_bonus{BonusValue := 100, Name := "Score MAX"},
				       time_bonus{BonusValue := 30, Name := "Time MEDIUM"},
				       time_bonus{BonusValue := 60, Name := "Time MAX"} }

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

        for (Bonus : BonusArray):
            Print( Bonus.BonusData() )
            Bonus.ApplyBonus()

No método OnBegin está sendo usado o laço for para percorrer todos os elementos do array. Para cada elemento são executados os métodos BonusData() e ApplyBonus(). Se a instância for do tipo time_bonus, será executada a versão do ApplyBonus() que foi sobrescrita na classe time_bonus.

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 Verse inheritance_device ao nível. 

Clique no botão Launch Session localizado na barra de ferramentas do UEFN 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 mensagens escritas pelas funções Print.


Sumário Verse


sexta-feira, 6 de junho de 2025

UEFN Verse: Introduction to specifiers

Specifiers are used in the Verse language to define behaviors for some Verse elements. The symbols < and > are used by specifiers. The OnBegin function, present in Verse devices, has two specifiers: override and suspends. 

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

The <override> specifier indicates that the OnBegin function is overriding the OnBegin function of the parent class creative_device. We will look at the <override> specifier in more detail in an article on class inheritance.

The <suspends> specifier is used to define asynchronous functions that execute in parallel. This means that they can be suspended and then resumed to continue their execution.

Another common specifier is <decides> used to create failable expressions. You can generate a failure inside the function by using the expression false? .

If you create a function using only the <decides> specifier, when you try to call the function you will get a compilation error with the following message:

"This invocation calls a function that has the 'no_rollback' effect, which is not allowed by its context."

To avoid this error, you can use the <transacts> specifier which indicates that expressions executed inside the function can be rolled back.

The line below shows an example of a function declaration using <decides> and <transacts>:

    IncreaseExperience(Points: int)<decides><transacts>:void=


Let's create a device in UEFN applying these specifiers. 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 specifiers_device and click the Create Empty button.

This device will call the IncreaseExperience function once per second, passing in a different value that will be added to a variable called ExperiencePoints. There is a 1 in 6 chance that the IncreaseExperience function will fail. If it fails, the ExperiencePoints variable will roll back its value.

Copy the Verse code below into the specifiers_device file:

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

specifiers_device := class(creative_device):
    
    var ExperiencePoints : int = 0

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

        var XpGain : int = 0
        
        loop:
            set XpGain += 1

            if( IncreaseExperience[XpGain] ):
                Print("XpGain is valid")
            else:
                Print("*** XpGain is INVALID ***") 
                Print("ExperiencePoints rolled back to {ExperiencePoints}")

            Sleep(1.0)

    IncreaseExperience(Points: int)<decides><transacts>:void=

        set ExperiencePoints += Points
        Print("ExperiencePoints set to {ExperiencePoints}")

        if( GetRandomInt(1, 6) = 1 ):
            false?   #this is a failure

Note that in the OnBegin function, a loop is being used without a break or return expression to exit the loop. The loop repeats the expressions in its code block, and the Sleep() function suspends the OnBegin function for a second.

The IncreaseExperience function is a failable function due to the use of <decides>, so we use [ ] instead of ( ) in the call.

The GetRandomInt() function generates a random number between two numbers. The numbers used as parameters can be part of the result. To use this function, you need to include the Verse.org/Random module at the beginning of the file.

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 specifiers_device to the level.

Click the Launch Session button located in the UEFN toolbar to load the level into Fortnite. 

After starting the session in Fortnite, press the Tab key and select the Log tab to view the log with the messages written by the Print functions.


Table of Contents Verse


UEFN Verse: Introdução aos especificadores

Especificadores são usados na linguagem Verse para definir comportamentos em alguns elementos do Verse. Os símbolos < e > são usados pelos especificadores. A função OnBegin, presente nos dispositivos Verse, tem dois especificadores: override e suspends

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

O especificador <override> indica que a função OnBegin está sobrescrevendo a função OnBegin da classe pai creative_device. Vamos ver mais detalhes do especificador <override> em um artigo sobre herança de classe.

O especificador <suspends> é usado para definir funções assíncronas que são executadas em paralelo. Isto significa que elas podem ser suspensas e depois  retomadas para continuar sua execução.

Outro especificador comum é o <decides> usado para criar expressões falíveis.  Você pode gerar uma falha dentro da função usando a expressão false? .

Se você criar uma função usando somente o especificador <decides>, ao tentar chamar a função aparecerá um erro de compilação com a seguinte mensagem:

"This invocation calls a function that has the 'no_rollback' effect, which is not allowed by its context."

Para evitar este erro, você pode usar o especificador <transacts> que indica que as expressões executadas dentro da função podem ser revertidas.

A linha abaixo mostra um exemplo de declaração de função usando <decides> e <transacts>:

    IncreaseExperience(Points: int)<decides><transacts>:void=


Vamos criar um dispositivo no UEFN aplicando estes especificadores. 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 specifiers_device clique no botão Create Empty.

Este dispositivo chamará a função IncreaseExperience uma vez por segundo passando como parâmetro um valor diferente que será adicionado a uma variável chamada ExperiencePoints. Existe uma chance de 1 em 6 da função IncreaseExperience falhar. Se ocorrer uma falha, a variável ExperiencePoints terá seu valor revertido.

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

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

specifiers_device := class(creative_device):
    
    var ExperiencePoints : int = 0

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

        var XpGain : int = 0
        
        loop:
            set XpGain += 1

            if( IncreaseExperience[XpGain] ):
                Print("XpGain is valid")
            else:
                Print("*** XpGain is INVALID ***") 
                Print("ExperiencePoints rolled back to {ExperiencePoints}")

            Sleep(1.0)

    IncreaseExperience(Points: int)<decides><transacts>:void=

        set ExperiencePoints += Points
        Print("ExperiencePoints set to {ExperiencePoints}")

        if( GetRandomInt(1, 6) = 1 ):
            false?   #isto é uma falha

Observe que na função OnBegin está sendo usado um loop sem uma expressão break ou return para sair do loop. O loop repete as expressões do seu bloco de código e a função Sleep() suspende a função OnBegin por um segundo.

A função IncreaseExperience é uma função falível devido o uso de <decides> por isso usamos [ ] ao invés de ( ) na chamada.

A função GetRandomInt() gera um número aleatório entre dois números. Os números usados como parâmetros podem fazer parte do resultado. Para usar esta função é preciso incluir o módulo Verse.org/Random no início do arquivo.

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 Verse specifiers_device ao nível. 

Clique no botão Launch Session localizado na barra de ferramentas do UEFN 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 mensagens escritas pelas funções Print.


Sumário Verse


quinta-feira, 20 de fevereiro de 2025

UEFN Verse: Fortnite.digest

In this article, I'll show you how to use the Fortnite.digest file to look up information about the functions and events of the creative devices that are available for use with Verse.

In Visual Studio Code, in your UEFN project Explorer, you'll notice that there are a few ".digest.verse" files. These files are generated during a Fortnite build and should not be modified manually. They serve as a reference to see what is available in the Verse API.


The Fortnite.digest file is the most up-to-date documentation for creative devices in UEFN/Verse. When a new creative device is made available in Verse, it may not yet be in the web documentation, but it will definitely be in Fortnite.digest.

In your UEFN/Verse project, if you Ctrl+click on the name of a creative device class, Visual Studio Code will open Fortnite.digest where the class is defined. In the image below, I clicked on the timer_device class.

Another option is to search directly in the Fortnite.digest file. For example, if you see a creative device that you have in the UEFN editor and want to know what the equivalent Verse class is. In Visual Studio Code, open Fortnite.digest and press F3 to open the search box. The class name follows the pattern name_device.


The image below shows part of the timer_device class. Here we can see the events available to subscribe a function. The events have :listenable and the required parameter is in parentheses. In addition to the events, we have the Enable, Disable and Reset functions that allow the Timer to be controlled using Verse code.

For example, SuccessEvent is an event that receives a ?agent (optional agent) as a parameter. So we need to create a function that receives a ?agent as a parameter to be able to subscribe to the SuccessEvent.

If you don't know how to subscribe a function in an event, see my article UEFN Verse: Functions.

Also, If you don't know how to call the functions of a class, I recommend my other article UEFN Verse: Classes and Instances.

Not all creative device features that appear in the UEFN editor are available for Verse. The Fortnite.digest file is a quick way to look up what's available for Verse within Visual Studio Code.


UEFN Verse: Fortnite.digest (pt-BR)

Neste artigo vou mostrar como usar o arquivo Fortnite.digest para buscar informações sobre as funções e eventos dos dispositivos criativos que estão disponíveis para serem usados com Verse.

No Visual Studio Code, no Explorer do seu projeto UEFN, veja que existem alguns arquivos ".digest.verse". Esses arquivos são gerados durante uma build do Fortnite e não devem ser modificados manualmente. Eles servem como uma referência para vermos o que está disponível na Verse API.


O arquivo Fortnite.digest é a documentação mais atualizada que existe dos dispositivos criativos no UEFN/Verse. Quando um novo dispositivo criativo é disponibilizado em Verse, pode ser que ele ainda não esteja na documentação web, mas com certeza ele estará no Fortnite.digest.

No seu projeto UEFN/Verse, se você pressionar a tecla Ctrl e clicar no nome de uma classe de dispositivo criativo, o Visual Studio Code vai abrir o Fortnite.digest no local onde a classe é definida. Na imagem abaixo eu cliquei na classe timer_device.

Outra opção é pesquisar direto no arquivo Fortnite.digest. Por exemplo, quando você ver um dispositivo criativo que tem no editor UEFN e quer saber qual é a classe Verse equivalente. No Visual Studio Code, abra o Fortnite.digest e pressione F3 para abrir a caixa de pesquisa. O nome da classe segue o padrão nome_device.


A imagem abaixo mostra uma parte da classe timer_device. Aqui podemos ver os eventos disponíveis para registrarmos uma função. Os eventos possuem :listenable e entre parênteses está o parâmetro necessário. Além dos eventos, temos as funções Enable, Disable e Reset que permite o controle do Timer usando código Verse.

Por exemplo, SuccessEvent é um evento que recebe como parâmetro um ?agent (agent opcional). Então precisamos criar uma função que receba como parâmetro um ?agent para poder registrar no SuccessEvent.

Se você não sabe como registrar uma função em um evento, veja o meu artigo UEFN Verse: Funções.

Caso você não saiba como chamar as funções de uma classe eu recomendo o meu outro artigo UEFN Verse: Classes e Instâncias.

Nem todos os recursos de um dispositivo criativo que aparecem no editor UEFN estão disponível para a linguagem Verse. O arquivo Fortnite.digest é um local onde você pode pesquisar rapidamente direto no Visual Studio Code o que está disponível para Verse.


segunda-feira, 17 de fevereiro de 2025

UEFN Verse: Map

A Map allows the storage of key->value pairs. This is used to make associations between values. The example below creates a Map variable using string for the key type and int (integer) for the value type.

var HealthItemSizes : [string]int = map{"small" => 25, "medium" => 50, "big" => 75, "mega" => 100}

To get a value associated with a key in a Map, use the key inside [] as shown in the example below. Accessing a value in a Map is a failable expression.

if(Points := HealthItemSizes["medium"]):
    Print("The medium Health Item recovers {Points} health points.")

You can add elements to a Map variable using set with a new key. If the key used already exists in the Map, the value associated with this key will be updated.

if(set HealthItemSizes["ultra"] = 150):
    Print("Size ultra added to the map.")

The number of elements in a Map can be accessed using the Length property.

Print("Number of elements in the Map: {HealthItemSizes.Length}")

The For loop can be used to iterate through the elements of a Map as shown in the following example. At each iteration of the For loop, the key and value of an element in the Map are stored in local constants.

for (Key->Value : HealthItemSizes):
    Print("Size: {Key} | Points: {Value}")

Let's create a device in UEFN to demonstrate these Map concepts. 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 map_device and click the Create Empty button.

Copy the Verse code below into the map_device file:

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

map_device := class(creative_device):

    @editable
    HealthExtended : logic = true

    var HealthItemSizes : [string]int = map{"small" => 25, "medium" => 50, "big" => 75, "mega" => 100}

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

        if(HealthExtended?):        
            if(set HealthItemSizes["ultra"] = 150, set HealthItemSizes["monster"] = 200):
                Print("Health Extended elements added to the map.")
            
        Print("The medium Health Item recovers {GetHealthItemPoints("medium")} health points.")
        
        Print("------- MAP CONTENTS -------")

        for (Key->Value : HealthItemSizes):
            Print("Size: {Key} | Points: {Value}")

        Print("Number of elements in the Map: {HealthItemSizes.Length}")

    GetHealthItemPoints(Size:string):int=

        if(Points := HealthItemSizes[Size]):
            Points
        else:
            0

    # The return keyword is optional. The function returns the result of the last executed expression.


The HealthExtended constant can be edited in the UEFN editor. It is being used to add other elements to the Map.

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 map_device to the level.

Click the Launch Session button located in the UEFN toolbar to load the level into Fortnite. 

After starting the session in Fortnite, press the Tab key and select the Log tab to view the log with the messages written by the Print functions.