Verse Inheritance: Base Classes and Subclasses
Tutorial intermediate compiles

Verse Inheritance: Base Classes and Subclasses

Updated intermediate Code verified

What you'll learn

You will define a base class (base_character) that holds shared fields and methods, then create two concrete subclasses (tank and dps) that inherit from it and <override> a method to specialize behavior. You'll also see how to call the parent implementation with (super:), and wire the whole thing to a real button_device.InteractedWithEvent so it runs against the interacting agent.

How it works

A class in Verse is a template for objects. When you write class tank(base_character):, tank inherits every field and method of base_character. From there you can:

  1. Override a method with <override> to change its behavior in the subclass.
  2. Call the parent version with (super:)MethodName(...) to reuse the base logic and add to it.
  3. Add new fields that only exist on the subclass (like Armor on tank).

Because methods that mutate fields have side effects, they are marked <transacts>. The InteractedWithEvent handler receives the interacting agent, so our device does real work: it takes that agent, looks up the character objects, applies damage, and reports the result. Note that Verse does not guarantee a fixed init-block execution order across an inheritance hierarchy, so keep field defaults self-contained.

Let's build it

This device holds one tank and one dps instance. When a player interacts with the button, both characters take damage through their overridden TakeDamage method, and the results are printed for the interacting agent.

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

# Base class: shared character logic every subclass inherits.
base_character := class:
    # Shared mutable field (var so subclasses can modify it).
    var Health<public> : int = 100

    # Shared method. <transacts> because it mutates Health (a side effect).
    TakeDamage<public>(Amount:int)<transacts>:void =
        set Health = Health - Amount
        Print("Base: took {Amount} damage, Health now {Health}")

# Subclass 1: tank has extra armor and overrides TakeDamage.
tank := class(base_character):
    Armor<public> : int = 50

    # Override: run the parent logic first, then add tank flavor.
    TakeDamage<override>(Amount:int)<transacts>:void =
        (super:)TakeDamage(Amount)          # call base_character's version
        Print("Tank: {Armor} armor softened the blow")

# Subclass 2: dps is fragile and overrides TakeDamage.
dps := class(base_character):
    ExtraDamage<public> : int = 5

    TakeDamage<override>(Amount:int)<transacts>:void =
        (super:)TakeDamage(Amount + ExtraDamage)   # takes bonus damage
        Print("DPS: critical vulnerability, took {Amount + ExtraDamage} total")

inheritance_demo_device := class<concrete>(creative_device):

    # Wire a real button in the editor to drive the demo.
    @editable InteractButton : button_device = button_device{}

    # Persistent subclass instances stored on the device.
    var MyTank : tank = tank{}
    var MyDps : dps = dps{}

    OnBegin<override>()<suspends>: void =
        # Subscribe to the button; handler receives the interacting agent.
        InteractButton.InteractedWithEvent.Subscribe(OnInteract)

    # Handler is <transacts> because it calls the mutating TakeDamage methods.
    OnInteract(Agent:agent)<transacts>:void =
        Print("--- Applying damage to characters ---")
        # Each call dispatches to the SUBCLASS override, not the base.
        MyTank.TakeDamage(10)
        MyDps.TakeDamage(10)
        # Access the shared inherited field on each instance.
        Print("Tank Health: {MyTank.Health}, DPS Health: {MyDps.Health}")

Try it yourself

  1. Add a healer := class(base_character): subclass whose TakeDamage override calls (super:)TakeDamage(Amount) and then set Health = Health + 5.
  2. Add a new Heal<public>(Amount:int)<transacts>:void method to base_character and call it from the healer override instead of setting Health directly.
  3. Store a healer instance on the device and damage it inside OnInteract to compare its net health loss.

Recap

  • Inheritance: class sub(base): gives the subclass every field and method of the base.
  • Override: <override> replaces a method's behavior in the subclass; calls dispatch to the most specific version.
  • Super: (super:)MethodName(...) runs the parent implementation from inside an override.
  • Transacts: methods that mutate fields are <transacts>, and any caller of them must be <transacts> too.
  • Real work: subscribing to InteractedWithEvent and acting on the received agent makes the technique actually do something at runtime.

Check your understanding

Test yourself with an interactive quiz and track your progress + earn XP — free for members.

Turn this into a guided course

Add Implementing Class Inheritance and Subclassing in Verse to your free study plan — we'll suggest related pages and stitch the lot into one compile-checked, self-guided lesson with worked examples and quizzes.

Original tutorial generated by Verse Island from the Verse/UEFN knowledge base, with references to the Epic Games sources above. Code is validated against the knowledge base.

Comments

    Sign in to vote, comment, or suggest an edit. Sign in