terça-feira, 15 de julho de 2025

UEFN Verse: Module

A Verse module allows you to organize multiple code elements for reuse across your project. A module can also be distributed for use in other projects.

The first Verse lines of a creative device have the using statement that imports Verse modules from UEFN with the necessary elements.  

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

A module is created using the module keyword. A module can contain other modules, classes, constants, functions, and other elements.

A folder within the UEFN project is treated as a module. For example, you can create a folder with your domain to store your modules that can be distributed to the public.

To create a folder that will be used as a module, follow these steps:

  • Open Verse Explorer
  • Right-click on the Content folder.
  • Select the Create Submodule option.
  • Uncheck the Hide Empty Directories so that the new folder is displayed.
  • Right click on the new folder and rename it with the name of your module.

The image below shows the folder I created for my RomeroBlueprints module. My module contains the dice.verse file, which is one of the files we'll create in this article.


As an example, let's create the Dice module. This module contains the following elements:

  • The die class with fields and a method to roll the die.
  • The GenerateDice function that receives as parameters the amount of dice and the number of faces on the dice. The function creates and returns an array of dice (instances of the die class).
  • The SumDice function, which receives an array of dice as a parameter, adds up the values of all the dice and returns the result of the sum.

Right-click on the folder that was created, in my example the folder name is RomeroBlueprints, and choose the Create New Verse File option.

Use the name dice for the file and click the Create Empty button.

Copy the Verse code below into the dice file:

using { /Verse.org/Random }

Dice<public> := module:

    die<public> := class():

        NumFaces<public> : int = 6
        var TopFace<public> : int = 1

        Roll<public>(): int =
            set TopFace = GetRandomInt(1, NumFaces)
            TopFace

    GenerateDice<public>(Amount: int, _NumFaces: int): []die =

        var DiceArray : []die = array{}

        for (Counter := 1..Amount):
            CurrentDie := die{NumFaces:= _NumFaces}
            CurrentDie.Roll()
            set DiceArray += array{CurrentDie}
        
        DiceArray

    SumDice<public>(DiceArray: []die): int =

        var sum : int = 0

        for (Currentdie : DiceArray):
            set sum += Currentdie.TopFace

        sum

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

To use the Dice module in another Verse file that is in the project's Content folder, you need to import the module with the using statement with the folder name and the module name separated by "." as shown in the line below:

using { RomeroBlueprints.Dice }

This way, the die class and functions from the Dice module will be available to be used in another Verse file.

Let's create a device in UEFN to test the Dice module. In Verse Explorer, right-click on the project name and choose the Add new Verse file to project option.

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

Copy the Verse code below into the module_device file:

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

using { RomeroBlueprints.Dice }

module_device := class(creative_device):

    DieInstance : die = die{}

    var DiceArray : []die = array{}

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

        DieInstance.Roll()
        Print("DieInstance.TopFace = {DieInstance.TopFace}")

        set DiceArray = GenerateDice(10,6)

        Print("Dice generated:")

        for( CurrentDie : DiceArray):
            Print("{CurrentDie.TopFace}")

        Print("The sum of the dice is { SumDice(DiceArray) }")

The module_device contains an instance of the die class and an array of die instances. The OnBegin method executes the functions available in the Dice module to generate 10 dice and add their values. The results of these functions are written in the log.

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 module_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: Modulo (pt-BR)

Um módulo Verse permite a organização de vários elementos de código para serem reutilizados no projeto. Um módulo também pode ser distribuído para ser utilizado em outros projetos.

As primeiras linhas Verse de um dispositivo criativo tem a instrução using que importa módulos Verse do UEFN com os elementos necessários.  

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

A criação de um módulo é feito usando a palavra chave module. Um módulo pode conter outros módulos, classes, constantes, funções e outros elementos.

Uma pasta dentro do projeto UEFN é tratada como um módulo. Por exemplo, você pode criar uma pasta com o seu domínio para guardar os seus módulos que poderão ser distribuídos ao público.

Para criar uma pasta que será usada como módulo, siga estes passos:

  • Abra o Verse Explorer
  • Clique com o botão direito na pasta Content.
  • Selecione a opção Create Submodule.
  • Desmarque a opção Hide Empty Directories para que a nova pasta seja exibida.
  • Clique com o botão direito na nova pasta e renomeie com o nome do seu módulo.

A imagem abaixo mostra a pasta que eu criei para o meu módulo RomeroBlueprints. O meu módulo contém o arquivo dice.verse que é um dos arquivos que vamos criar neste artigo.


Como exemplo vamos criar o módulo Dice (dados em inglês). Este módulo contém os seguintes elementos:

  • A classe die (dado em inglês) com campos e um método para rolar o dado.
  • A função GenerateDice que recebe como parâmetro a quantidade de dados e o número de faces dos dados. A função cria e retorna um array de dados (instâncias da classe die).
  • A função SumDice que recebe como parâmetro um array de dados, soma os valores de todos os dados e retorna o resultado da soma.

Clique com o botão direito na pasta que foi criada, no meu exemplo o nome da pasta é RomeroBlueprints, e escolha a opção Create New Verse File

Use o nome dice para o arquivo clique no botão Create Empty.

Copie o código Verse abaixo para o arquivo dice:

using { /Verse.org/Random }

Dice<public> := module:

    die<public> := class():

        NumFaces<public> : int = 6
        var TopFace<public> : int = 1

        Roll<public>(): int =
            set TopFace = GetRandomInt(1, NumFaces)
            TopFace

    GenerateDice<public>(Amount: int, _NumFaces: int): []die =

        var DiceArray : []die = array{}

        for (Counter := 1..Amount):
            CurrentDie := die{NumFaces:= _NumFaces}
            CurrentDie.Roll()
            set DiceArray += array{CurrentDie}
        
        DiceArray

    SumDice<public>(DiceArray: []die): int =

        var sum : int = 0

        for (Currentdie : DiceArray):
            set sum += Currentdie.TopFace

        sum

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

Para usar o módulo Dice em outro arquivo Verse que está na pasta Content do projeto é preciso importar o módulo com a instrução using com o nome da pasta  e o nome do módulo separados por "." como mostra a linha abaixo:

using { RomeroBlueprints.Dice }

Assim, a classe die e as funções do módulo Dice estarão disponíveis para serem usados em outro arquivo Verse.

Vamos criar um dispositivo no UEFN para testar o módulo Dice. No 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 module_device clique no botão Create Empty.

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

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

using { RomeroBlueprints.Dice }

module_device := class(creative_device):

    DieInstance : die = die{}

    var DiceArray : []die = array{}

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

        DieInstance.Roll()
        Print("DieInstance.TopFace = {DieInstance.TopFace}")

        set DiceArray = GenerateDice(10,6)

        Print("Dice generated:")

        for( CurrentDie : DiceArray):
            Print("{CurrentDie.TopFace}")

        Print("The sum of the dice is { SumDice(DiceArray) }")

O module_device possui uma instância da classe die e um array de instâncias da classe die. No método OnBegin são executadas as funções disponíveis no módulo Dice para gerar 10 dados e somar os seus valores. Os resultados das funções são registrados no log.

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 module_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


domingo, 6 de julho de 2025

UEFN Verse: Access Specifiers

Access specifiers are used to define the visibility of elements in Verse code. They can be used on classes, fields, methods, and other elements.

The <public> specifier indicates that the element is available anywhere in the code.

The <protected> specifier indicates that the element is available in the class itself and in its subclasses.

The <private> specifier indicates that the element is available within the class itself but subclasses cannot access it.

When no access specifier is used, the element uses the default <internal> specifier which indicates that the element is available in the module it is in. The next article will be about modules.

The code below is an example of a class that was created just to show the application of access specifiers in the class, fields and method. 

weapon<public> := class():

    var<protected> ammunition<public>: int = 10

    calibration<private> : float = 0.03	

    Fire<public>(): void =
        if (ammunition > 0):
            set ammunition -= 1 
            Print("Weapon fired")
        else:
            Print("No ammo")

In variables, the specifier used next to var indicates where it can be modified. The specifier used next to the variable name indicates where it can be accessed. In the example above, the variable ammunition can be accessed anywhere but can only be modified within the class itself and its subclasses.

Consider WeaponInstance an instance of the weapon class that is being used inside another class. The following accesses are valid because the elements are <public>:

Print("{WeaponInstance.ammunition}")
WeaponInstance.Fire()

The accesses below are invalid because calibration is <private> and the var of ammunition is <protected>:

Print("{WeaponInstance.calibration}")
set WeaponInstance.ammunition = 15

The code below creates the rifle_grenade subclass using weapon as the superclass. The grenades variable is using the default access specifier which is <internal>.

rifle_grenade<public> := class(weapon):

    var grenades: int = 3

    LaunchGrenade<public>():void =
        if (grenades > 0):
            set grenades -= 1 
            Print("Grenade launched")
        else:
            Print("No grenade")

    RifleStatus<public>():void =
        Print("ammunition: {ammunition} | grenades: {grenades}")

In the RifleStatus() method we can see that the ammunition variable of the weapon superclass is accessible. It can also be modified in the subclass.

The calibration variable is not accessible in the rifle_grenade subclass because it is <private>.

The code below shows these example classes in a single file so you can test them on UEFN. I created a verse device called access_specifiers_device and used this code:

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

weapon<public> := class():

    var<protected> ammunition<public>: int = 10

    calibration<private> : float = 0.03	

    Fire<public>(): void =
        if (ammunition > 0):
            set ammunition -= 1 
            Print("Weapon fired")
        else:
            Print("No ammo")

rifle_grenade<public> := class(weapon):

    var grenades: int = 3

    LaunchGrenade<public>():void =
        if (grenades > 0):
            set grenades -= 1 
            Print("Grenade launched")
        else:
            Print("No grenade")

    RifleStatus<public>():void =
        Print("ammunition: {ammunition} | grenades: {grenades}")

access_specifiers_device := class(creative_device):

    RifleGrenade : rifle_grenade = rifle_grenade{}

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

        Print("{RifleGrenade.ammunition}")
        RifleGrenade.Fire()
        RifleGrenade.LaunchGrenade()
        RifleGrenade.RifleStatus()

This Verse device creates an instance of the rifle_grenade class and accesses the ammunition variable and the Fire() method of the weapon superclass and two more methods of the rifle_grenade class.


UEFN Verse: Especificadores de acesso

Os especificadores de acesso são usados para definir a visibilidade de elementos no código Verse. Eles podem ser usados em classes, campos, métodos e outros elementos.

O especificador <public> indica que o elemento está disponível em qualquer parte do código. 

O especificador <protected> indica que o elemento está disponível na própria classe e em suas subclasses.

O especificador <private> indica que o elemento está disponível na própria classe mas as subclasses não conseguem acessar.

Quando não é usado um especificador de acesso, o elemento usa o especificador padrão que é o <internal> que indica que o elemento está disponível no módulo em que ele está. O próximo artigo será sobre módulos. 

O código abaixo é um exemplo de classe que foi criada apenas para mostrar a aplicação dos especificadores de acesso na classe, em campos e no método. 

weapon<public> := class():

    var<protected> ammunition<public>: int = 10

    calibration<private> : float = 0.03	

    Fire<public>(): void =
        if (ammunition > 0):
            set ammunition -= 1 
            Print("Weapon fired")
        else:
            Print("No ammo")

Nas variáveis o especificador usado ao lado de var indica onde ela pode ser modificada. O especificador usado ao lado no nome da variável indica onde ela pode ser acessada. No exemplo acima a variável ammunition pode ser acessada em qualquer lugar mas só pode ser modificada na própria classe e nas subclasses.

Considere WeaponInstance uma instância da classe weapon que está sendo usada dentro de outra classe. Os acessos abaixo são válidos porque os elementos são <public>:

Print("{WeaponInstance.ammunition}")
WeaponInstance.Fire()

Os acessos abaixo são inválidos porque calibration é <private> e o var de ammunition é <protected>:

Print("{WeaponInstance.calibration}")
set WeaponInstance.ammunition = 15

O código abaixo cria a subclasse rifle_grenade usando weapon como superclasseA variável grenades está usando o especificador de acesso default que é o <internal>.

rifle_grenade<public> := class(weapon):

    var grenades: int = 3

    LaunchGrenade<public>():void =
        if (grenades > 0):
            set grenades -= 1 
            Print("Grenade launched")
        else:
            Print("No grenade")

    RifleStatus<public>():void =
        Print("ammunition: {ammunition} | grenades: {grenades}")

No método RifleStatus() podemos ver que a variável ammunition da superclasse weapon é acessível. Ela também pode ser modificada na subclasse.

A variável calibration não é acessível na subclasse rifle_grenade porque ela é <private>.

O código abaixo mostra estas classes de exemplo em um único arquivo para poder testar no UEFN. Eu criei um dispositivo verse chamado access_specifiers_device e usei este código:
using { /Fortnite.com/Devices }
using { /Verse.org/Simulation }
using { /UnrealEngine.com/Temporary/Diagnostics }

weapon<public> := class():

    var<protected> ammunition<public>: int = 10

    calibration<private> : float = 0.03	

    Fire<public>(): void =
        if (ammunition > 0):
            set ammunition -= 1 
            Print("Weapon fired")
        else:
            Print("No ammo")

rifle_grenade<public> := class(weapon):

    var grenades: int = 3

    LaunchGrenade<public>():void =
        if (grenades > 0):
            set grenades -= 1 
            Print("Grenade launched")
        else:
            Print("No grenade")

    RifleStatus<public>():void =
        Print("ammunition: {ammunition} | grenades: {grenades}")

access_specifiers_device := class(creative_device):

    RifleGrenade : rifle_grenade = rifle_grenade{}

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

        Print("{RifleGrenade.ammunition}")
        RifleGrenade.Fire()
        RifleGrenade.LaunchGrenade()
        RifleGrenade.RifleStatus()

Este dispositivo Verse cria uma instância da classe rifle_grenade e acessa a variável ammunition e o método Fire() da superclasse weapon e mais dois métodos da própria classe rifle_grenade.


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