quarta-feira, 2 de julho de 2025

UEFN Verse: Class Specifiers

Class specifiers are used when creating classes to define behaviors and characteristics. This article will present the main ones.

The <abstract> specifier is used to create superclasses with common fields and methods to be inherited by subclasses.

An abstract class allows the declaration of methods without a body (it has no code) that must be overridden in a subclass.

The code below creates the abstract class base_bonus. The ApplyBonus() method has no body.

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

    ApplyBonus() : void

It is not possible to create instances of an abstract class. The code below generates a compilation error.

BaseBonus : base_bonus = base_bonus{BonusValue := 20,  Name := "Generic"}


The <concrete> specifier indicates that all fields of the class must have default values, allowing the creation of instances with an empty archetype.

The code below creates the concrete class score_bonus using base_bonus as the superclass. All fields have been given default values ​​and the ApplyBonus() method has been overridden.

score_bonus := class<concrete>(base_bonus):
    BonusId<override> : int = 2
    Name<override> : string = "Score MEDIUM"
    BonusValue<override>: int = 50
	
    ApplyBonus<override>() : void =
        Print("Adding {BonusValue} to SCORE.")

This code creates an instance of score_bonus using an empty archetype {}.

ScoreBonusDefault : score_bonus = score_bonus{}


The <final> specifier is used to indicate that a class cannot have subclasses. This specifier can also be used on fields and methods to indicate that they cannot be overridden.

The code below creates the final class time_bonus using base_bonus as the superclass.

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

The new time_bonus class cannot be used as a superclass. The following code generates a compilation error.

time_bonus_variation := class(time_bonus):


Let's combine these examples into a single file so we can test it on UEFN. I created a verse device called class_specifiers_device and used this code:

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

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

    ApplyBonus() : void

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

score_bonus := class<concrete>(base_bonus):
    BonusId<override> : int = 2
    Name<override> : string = "Score MEDIUM"
    BonusValue<override>: int = 50
	
    ApplyBonus<override>() : void =
        Print("Adding {BonusValue} to SCORE.")		

class_specifiers_device := class(creative_device):

    TimeBonus : time_bonus = time_bonus{BonusValue := 30, Name := "Time MEDIUM"}

    ScoreBonusDefault : score_bonus = score_bonus{}

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

        Print( ScoreBonusDefault.BonusData() )
        ScoreBonusDefault.ApplyBonus()

This Verse device simply executes the two methods of the ScoreBonusDefault instance to write some messages to the log. The device was created to illustrate the use of class specifiers. 


Table of Contents Verse


UEFN Verse: Especificadores de classe

Os especificadores de classe são usados na criação das classes para definir comportamentos e características. Neste artigo serão apresentados os principais.

O especificador <abstract> é usado para criar superclasses com campos e métodos comuns para serem herdados por subclasses.

Uma classe abstrata permite a declaração de métodos sem corpo (não possui código) que devem ser sobrescritos em uma subclasse.

O código abaixo cria a classe abstrata base_bonus. O método ApplyBonus() não tem corpo.

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

    ApplyBonus() : void

Não é possivel criar instâncias de uma classe abstrata. O código abaixo gera um erro de compilação.

BaseBonus : base_bonus = base_bonus{BonusValue := 20,  Name := "Generic"}


O especificador <concrete> indica que todos os campos da classe tem de ter valores default permitindo a criação de instâncias com um arquétipo vazio.

O código abaixo cria a classe concreta score_bonus usando base_bonus como superclasse. Todos os campos receberam valores default e o método ApplyBonus() foi sobrescrito.

score_bonus := class<concrete>(base_bonus):
    BonusId<override> : int = 2
    Name<override> : string = "Score MEDIUM"
    BonusValue<override>: int = 50
	
    ApplyBonus<override>() : void =
        Print("Adding {BonusValue} to SCORE.")

Este código cria uma instância de score_bonus usando um arquétipo vazio {}.

ScoreBonusDefault : score_bonus = score_bonus{}


O especificador <final> é usado para indicar que uma classe não pode ter subclasses. Este especificador também pode ser usado em campos e métodos para indicar que eles não podem ser sobrescritos.

O código abaixo cria a classe final time_bonus usando base_bonus como superclasse.

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

A nova classe time_bonus não pode ser usada como superclasse. O código a seguir gera um erro de compilação.

time_bonus_variation := class(time_bonus):


Vamos juntar estes exemplos em um único arquivo para poder testar no UEFN. Eu criei um dispositivo verse chamado class_specifiers_device e usei este código:

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

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

    ApplyBonus() : void

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

score_bonus := class<concrete>(base_bonus):
    BonusId<override> : int = 2
    Name<override> : string = "Score MEDIUM"
    BonusValue<override>: int = 50
	
    ApplyBonus<override>() : void =
        Print("Adding {BonusValue} to SCORE.")		

class_specifiers_device := class(creative_device):

    TimeBonus : time_bonus = time_bonus{BonusValue := 30, Name := "Time MEDIUM"}

    ScoreBonusDefault : score_bonus = score_bonus{}

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

        Print( ScoreBonusDefault.BonusData() )
        ScoreBonusDefault.ApplyBonus()

Este dispositivo Verse apenas executa os dois métodos da instância ScoreBonusDefault para escrever algumas mensagens no log. O dispositivo foi criado para ilustrar o uso dos especificadores de classe. 


Sumário Verse


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.