Verse Inheritance: Base Classes and Subclasses
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:
- Override a method with
<override>to change its behavior in the subclass. - Call the parent version with
(super:)MethodName(...)to reuse the base logic and add to it. - Add new fields that only exist on the subclass (like
Armorontank).
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
- Add a
healer := class(base_character):subclass whoseTakeDamageoverride calls(super:)TakeDamage(Amount)and thenset Health = Health + 5. - Add a new
Heal<public>(Amount:int)<transacts>:voidmethod tobase_characterand call it from the healer override instead of settingHealthdirectly. - Store a
healerinstance on the device and damage it insideOnInteractto 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
InteractedWithEventand acting on the receivedagentmakes 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.