See all glossary terms

Virtual base class

A virtual base class is a class that does not do anything by itself. It exists only for other classes to inherit from it.
A virtual base class defines a common interface that derived classes must implement. It's a way to ensure that all derived classes have the same methods and properties. This is useful when you want to group classes that behave similarly but need different code.
For example, you might have multiple visual effects used for spells in a game. You want a given projectile from the spell to be configurable, including its speed, damage, and visual effect. Also, for the visuals, you want to play an appearing and disappearing animation when the projectile is created and destroyed.
A virtual base class is a good way to ensure that all visual effects for spells have the same functions. You can define a virtual base class named SpellSkin with methods like appear() and disappear(). The script for the SpellSkin class might look like this:
class_name SpellSkin extends Node3D

## Virtual function. Override to define the skin's appear animation.
func appear() -> void:
	pass

## Virtual function. Override to define the skin's destroy animation.
func destroy() -> void:
	pass
Then, you can create derived classes like FireballSkin and IceBoltSkin that inherit from SpellSkin and implement the appear and disappear methods differently.
The FireballSkin class might look like this:
class_name FireballSkin extends SpellSkin

@onready var _fire_particles: GPUParticles3D = %FireParticles
@onready var _smoke_particles: GPUParticles3D = %SmokeParticles
@onready var _magic_sparks: GPUParticles3D = %MagicSparks
@onready var _core: MeshInstance3D = %Core


func appear() -> void:
	var effect: Node3D = preload("fireball_emission.tscn").instantiate()
	add_sibling(effect)
	effect.global_position = global_position
	effect.global_rotation = global_rotation


func destroy() -> void:
	_fire_particles.emitting = false
	_smoke_particles.emitting = false
	_magic_sparks.emitting = false
	
	var tween := create_tween()
	tween.tween_property(_core, "scale", Vector3.ZERO, 0.25)
	tween.tween_interval(1.0)
	tween.tween_callback(queue_free)
In this example, the appear() method spawns a visual effect for the fireball when it appears. The destroy() method stops the particles and scales down the core of the fireball when the fireball is destroyed.
In some languages like C++, you can mark a class as "virtual" to prevent it from being instantiated directly. This mechanism forces you to inherit from the class and implement its methods. This is not the case in GDScript.
In GDScript, you create a class that does nothing by itself and is meant to inherit from. This is a common pattern to create virtual base classes in scripting languages.