See all glossary terms

Singleton (Autoload)

The singleton design pattern limits instantiating a class to a single instance. In other words, a singleton class has only one instance in the entire program.
Also, typically, singletons are globally accessible. You can access the singleton instance from anywhere in your code.
This pattern is useful when you need a piece of data and code shared across your entire application. For example, you might use a singleton to store the database of items in a game or to keep audio playing across different scenes.
Another good use case for singletons is when you need to provide an API to the rest of your codebase. For example, in Godot, the Input singleton offers an API to access the player's input from any script.

Creating a singleton in Godot

In GDScript in Godot, you cannot create a true singleton as there's no way to prevent a class from being instantiated more than once, and the singleton pattern is supposed to enforce that. However, in practice, we mostly use singletons in games to provide globally accessible data and APIs.
Godot has a built-in way to an instance of a node script or scene and make it globally accessible using the "autoload" feature. It is not quite a singleton but serves most of the same purpose, and it is what Godot users typically use instead of a true singleton.
The autoload feature registers a script or scene, creates an instance at the root of the scene tree when the game starts, and makes it accessible from anywhere in your code by writing the autoload name. It's very convenient! A little too convenient.
Here's how you can create a singleton in Godot:
  1. Create a new scene or script that you want to access globally in your codebase. This script should extend Node or any derived class.
  2. Go to Project -> Project Settings... -> AutoLoad.
  3. Enter the path to the file you want to use. Click the folder icon to browse your project.
  4. Enter a name for the autoload or use the one suggested by Godot. This name is how you will access it from your code.
  5. Click Add to add the autoload to the autoload list.
Now, you can access the auto-loaded node or scene from anywhere in your code using the name you chose in the autoload tab. Again, this is not a true singleton, but it serves the same purpose in practice.
Can I create a true singleton in Godot with GDScript?
You can prevent instantiating an autoload multiple times using a static variable to store a reference to the singleton instance. Here's an example of how you can do this:
class_name MySingleton extends Node

static var singleton_instance: MySingleton = null

func _init() -> void:
	if singleton_instance == null:
		singleton_instance = self
	else:
		printerr("Trying to create another instance of MySingleton. Deleting it.")
		queue_free()
This is the closest you can get in GDScript, as you cannot override the new() method of classes or the instantiate() method of scenes. So, you cannot prevent instantiating the class a second time; you can only delete the second instance if it happens.

When to use singletons

Singletons are powerful tools, but they can also lead to problems if overused. The main risk with singletons is creating globally accessible data that can be modified from anywhere in your code. If you are not careful, as your code grows, it can become hard to track where and when the singleton data is modified, leading to hard-to-find bugs.
Also, the more you use a singleton, the more you couple your code to it. If you decide to change how the singleton works, you have to change a lot of your code and risk introducing bugs in many places.
Here are a few good cases when you may use singletons relatively safely:
  • Read-only global data: If you need to provide data with read-only access to the rest of your codebase, singletons can be a good choice. For example, you might use a singleton to store the list of items in your game.
  • Widely-used APIs: If you need to provide an API that your game needs to access a lot and that manages some hidden data to the rest of your codebase, singletons can be a good choice. An example could be a quest system where many different parts of your game need to access the current quest.
If you need an API composed of only static functions or used in specific parts of your codebase, you might not need a singleton. You can use a regular class with static functions instead or a class you instantiate in the parts of your codebase that need it.
If you need data that can be easily saved and loaded from multiple places in your codebase, a resource is a better choice than a singleton. You can load the same resource from various places in your codebase, and it will point to the same instance. This is a good way to share data across your game without exposing it globally.