Delay preload

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

Hi everyone,

I have the impression that my App crashes on startup on an old Galaxy A3 phone by CPU overload due to too many preloads like preload("res://path/Scene.tscn").instance().

(I believe that this is the according error message: platform/windows/os_windows.cpp:2965 - Condition "!process_map->has(p_pid)" is true. Returned: FAILED)

Now I wonder if I could circumvent that problem by delaying some preloads so they won’t preload at the same time like all the others but maybe a second later or so… is it possible to prevent preloads from loading at compile-time but instead “delay them” a bit?

:bust_in_silhouette: Reply From: Zylann

The point of preload is that the resource is loaded when the script itself is loaded, there is no way to delay it.

But you can can get more control with load instead, which will run when the line containing load is executed.
Note: load expects a full path to the resource, relative to res:// (the root of the project).

I’ve been trying load and yes, the app runs. Unfortunately the game then significantly stutters when “reaching” that load.

As you say “the resource is loaded when the script itself is loaded”: would it be possible to delay loading a script?

pferft | 2023-07-05 20:06

You can sort of delay a script yes, but only the same way you do with other resources, by instancing nodes and scenes manually, instead of leaving it to Godot.

Eventually you may want to group all expensive loadings to some sort of loading screen. And if you can identify which resources are actually slow to load, you could load only those on that loading screen and keep them in a variable so they stay loaded. Scripts are cheap to load, so the problem should not really be about delaying scripts.

Also I have no idea what !process_map->has(p_pid) means, but in Godot 4 it’s only called in export plugins (so in the editor, not the built game).

Zylann | 2023-07-05 20:26

“…so they stay loaded” you say, that’s very interesting. If I understand this right, a preload stays loaded whereas a load “vanishes” after being used and always has to be re-loaded when coming up. It would be very neat if I could keep a load staying… could you suggest how such a variable might look like?

pferft | 2023-07-05 21:12

load doesn’t make things vanish: it returns the loaded resource, which will remain loaded as long as it’s used by something. Being stored in a variable counts as “being used”. It will be unloaded when nothing uses it anymore. So if you load a scene and instance it, it will remain in memory until it leaves the scene and all script instances stop referencing it.

I mentionned to keep it in a variable (a global one in an autoload, for example) in case you want to keep it loaded for some reason. I might be wrong on that since there might be a cache, but it has even be mentionned as a reason for static variables not being implemented in GDScript for a while. And usually most resources remain loaded anyways because your game uses them.

Your problem is just that some resources are heavy so you’d want to control when they load to make it less noticeable.

Zylann | 2023-07-05 21:47

I see how this is supposed to work. If I not preload a scene on startup but load it into a variable a couple of seconds later and keep that variable, another load of the same scene at a later time will not shutter because it’s already loaded “somewhere else”… it’s basically a manual preload I can time as I please.
Thanks for your explanations!

(Everything would probably run smoothly on a slightly more powerful phone, but my goal is to make it work on weaker ones al well…)

pferft | 2023-07-05 23:10