Abstract base class (or Virtual base class)

2026/08/16

Type
Learning Resource
Format
Glossary Article
Version
General
Subject Tags
Code
MIT
Game Assets
2016-2026, GDQuest© - All rights reserved
All else
2016-2026, GDQuest© - All rights reserved
Created
2026/08/26
Updated
2026/08/16

Abstract base class (or Virtual base class)

An abstract base class is a class that does not do anything (or not much) by itself. It exists only for other classes to inherit from it.

don't get confused!

In Godot, there's also virtual function: functions defined in C++ which you can override in GDScript, like _process() or _input().

An abstract 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 destroy(). The script for the SpellSkin class might look like this:

@abstract
class_name SpellSkin extends Node3D

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

## Virtual function. Override to define the skin's destroy animation.
@abstract
func destroy() -> void:
What is this abstract keyword?

The keyword @abstract is not strictly necessary: if you wrote the above without it, you'd get the same functionality. The keyword serves as a restriction:

  • classes marked with @abstract cannot be instantiated directly. This means you cannot create a new SpellSkin instance; you must use a derived class instead.
  • Methods marked with @abstract must be implemented by each derived classes. If you don't, you'll get an error.

Then, you can create derived classes like FireballSkin and IceBoltSkin that inherit from SpellSkin and implement the appear() and destroy() 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.

Become an Indie Gamedev with GDQuest!

Don't stop here. Step-by-step tutorials are fun but they only take you so far.

Try one of our proven study programs to become an independent Gamedev truly capable of realizing the games you’ve always wanted to make.

Nathan

Founder and teacher at GDQuest
  • Starter Kit
  • Learn Gamedev from Zero
Check out GDSchool

You're welcome in our little community

Get help from peers and pros on GDQuest's Discord server!

20,000 membersJoin Server

Contribute to GDQuest's Free Library

There are multiple ways you can join our effort to create free and open source gamedev resources that are accessible to everyone!

Site in BETA!found a bug?