How to automatically set a script as Singleton / Autoload in GDExtension?

Godot Version

4.2.1

I’m following this documentation on GDExtension, Is there is a way to automatically set a script as Singleton (Autoload) without having to manually set it in the editor GUI?

The aim is that if you have the necessary GDExtension files (e.g. gdexample.h, gdexample.cpp, etc) they would automatically be set as an autoload without having to make any changes within the editor? i.e. simply open up the game engine and everything is ready to go

why is this needed?

writing this to avoid xy problem, I have a universal_sub_viewport.tscn scene with @tool mode as such:

EWhq3GZPl

and this creates a singleton within the editor every time I start it up, I’m trying to replicate this in GDExtension without having to go through the hassle of setting up anything within the editor GUI

If you really want to skip interacting with the Autoload UI, you can use a plugin to register autoloads. Which, don’t worry, you’ll still have to interact with the plugin UI.


If you look deeper, you will find that autoloads are just nodes added to the scene tree root on init. Back in the olden days, we fetched autoloads like this get_node("/root/autoload"), and then trekked through a forest, snow storm, and nuclear fallout to reach the bus stop.

You could do something like:

TheNode *the_node = // ...
SceneTree *tree = Object::cast_to<SceneTree>(OS::get_singleton()->get_main_loop());
tree->get_root()->add_child(the_node);

TheNode::get_autoload() // would do
tree->get_root()->get_node("TheNodeAutoloadName");

at a correct time which I wouldn’t be able to tell you.

Just stumbled upon this method: Engine.register_singleton(). Does that work for you?

Figured this one out myself recently. Inside your function where you register all you gdextension classes drop this bit of code.

ClassDB::register_class<AchievementManager>();
Engine::get_singleton()->register_singleton("AchievementManager", memnew(AchievementManager));

and then inside any gdextension class that needs to use said singleton can be called like so

Ref<AchievementManager> achievements = Ref<AchievementManager>(Engine::get_singleton()->get_singleton("AchievementManager"));

hope this helps!