Replace singleton with subclass instance

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By CyberShadow

As part of working out a modding framework for a game, I’m trying to replace an auto-loaded singleton with a different object instance at runtime (when a mod is loaded).

According to https://forum.godotengine.org/95097/engine-has_singleton-engine-get_singleton-behaving-expected?show=95163#a95163 , singletons are nodes on the /root node, so I tried replacing e.g. SomeSingleton as follows:

var tmpResource = ResourceLoader.load("res://my-mod/SomeSingleton.gd", "", true)
var inst = tmpResource.new()
inst.name = 'SomeSingleton'
$"/root".call_deferred('remove_child', $'/root/SomeSingleton')
$"/root".call_deferred('add_child', inst)

However, this does not affect the game’s code which refers to SomeSingleton directly - it still accesses the original instance.

I tried adding

ResourceLoader.load("res://path/to/SomethingThatUsesSomeSingleton.gd", "", true)

in the subclass’s _enter_tree to reload a game code file, hoping that would make it use the new $"/root/SomeSingleton" but that did not have any effect.

:bust_in_silhouette: Reply From: CyberShadow

The solution I ended up using is to place the code (which is to replace the singleton) in the _init another singleton, placed earlier in the auto-load list. At this point, Resource.take_over_path will affect the singleton’s creation.