Is preload fine inside a loop?

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

I have seen several code examples that instantiate nodes like this:

var MyScene = preload("res://my_scene.tscn")

func create_instances():
    for _i in 10:
        var instance = MyScene.instantiate()
        add_child(instance)

What is the advantage of storing the PackedScene in a variable? Is there a performance disadvantage for the following code?

func create_instances():
    for _i in 10:
        var instance = preload("res://my_scene.tscn").instantiate()
        add_child(instance)

My understanding of preload is that it loads the resource at compile time. To me, this sounds like both code snippets have the same performance since both supposedly preload the resource only once, regardless of any looping. Even if this function is called multiple times, doesn’t “compile time” mean the preload is called only once regardless? Is my understanding incorrect? Or is there another advantage of storing the PackedScene in a variable?

:bust_in_silhouette: Reply From: Oian

Well if it works, then it should be fine.

However it is good practice to use preload() as the top of your class as a const and use load() when you want to do it further down in code like in your second example.

:bust_in_silhouette: Reply From: zhyrin

Semantics.
If you have a preload up front, you indicate that the same resource will be used multiple times.
If you have a (pre)load in a loop, the reader would expect that each iteration’s load is different.
You give extra overhead of thinking about what your code means.

My primary reason for considering preload in the loop is that the scene I am loading has class_name MyScene. If I preload to a PackedScene const up front, I would want to name the variable implied by the style guide, MyScene, which is the same name as the scene’s class name. At that point, two complications arise.

  1. When calling MyScene.instantiate(), the IDE colors MyScene like it is a class name, even though in this context, it is a constant’s name.
  2. As far as I can tell, if a script has a variable with the same name as a class name, there is no way to call static functions in that other class.

The obvious solution to this is to name the PackedScene something different, like MySceneScene, but I don’t including type information in my variable names when I can avoid it.

Beamer159 | 2023-03-09 15:24

I think the best way to think about it is that the preloaded scene is a type alias.
Some programming languages allow you to create type aliases, and as an example, if you use type aliases in python (through the typing library), even there, you essentially create variables that will denote types.

MySceneScene is fine (other than the fact that MyScene is not very descriptive), in a complex game I very often preloaded both scenes and their associated scripts like so:

const TargetUI := preload("res://path/to/target.gd")
const TargetUIScene := preload("res://path/to/target.tscn")

I don’t think you should name a preloaded scene purely based on the class’ name that it uses as a script, you would expect a type named such to have the members and functions of that class, but it would just be a packed scene.

zhyrin | 2023-03-09 16:26