Logic preferences

    In GDScript, there exists the global method. It loads resources as early as possible to front-load the “loading” operations and avoid loading resources while in the middle of performance-sensitive code.

    Its counterpart, the load method, loads a resource only when it reaches the load statement. That is, it will load a resource in-place which can cause slowdowns when it occurs in the middle of sensitive processes. The function is also an alias for which is accessible to all scripting languages.

    So, when exactly does preloading occur versus loading, and when should one use either? Let’s see an example:

    C#

    1. using System;
    2. using Godot;
    3. // C# and other languages have no concept of "preloading".
    4. public class MyBuildings : Node
    5. {
    6. public readonly PackedScene Building = ResourceLoader.Load<PackedScene>("res://building.tscn");
    7. public PackedScene ABuilding;
    8. public override void _Ready()
    9. {
    10. ABuilding = GD.Load<PackedScene>("res://office.tscn");
    11. }

    Preloading allows the script to handle all the loading the moment one loads the script. Preloading is useful, but there are also times when one doesn’t wish for it. To distinguish these situations, there are a few things one can consider:

    1. If one cannot determine when the script might load, then preloading a resource, especially a scene or script, could result in further loads one does not expect. This could lead to unintentional, variable-length load times on top of the original script’s load operations.
    2. If something else could replace the value (like a scene’s exported initialization), then preloading the value has no meaning. This point isn’t a significant factor if one intends to always create the script on its own.
    3. If one wishes only to ‘import’ another class resource (script or scene), then using a preloaded constant is often the best course of action. However, in exceptional cases, one my wish not to do this:
      1. If the ‘imported’ class is liable to change, then it should be a property instead, initialized either using an export or a load (and perhaps not even initialized until later).
      2. If the script requires a great many dependencies, and one does not wish to consume so much memory, then one may wish to, load and unload various dependencies at runtime as circumstances change. If one preloads resources into constants, then the only way to unload these resources would be to unload the entire script. If they are instead loaded properties, then one can set them to null and remove all references to the resource entirely (which, as a Reference-extending type, will cause the resources to delete themselves from memory).

    Large levels: static vs. dynamic

    If one is creating a large level, which circumstances are most appropriate? Should they create the level as one static space? Or should they load the level in pieces and shift the world’s content as needed?

    The naive answer is to use a static level that loads everything at once. But, depending on the project, this could consume a large amount of memory. Wasting users’ RAM leads to programs running slow or outright crashing from everything else the computer tries to do at the same time.

    No matter what, one should break larger scenes into smaller ones (to aid in reusability of assets). Developers can then design a node that manages the creation/loading and deletion/unloading of resources and nodes in real-time. Games with large and varied environments or procedurally generated elements often implement these strategies to avoid wasting memory.

    On the flip side, coding a dynamic system is more complex, i.e. uses more programmed logic, which results in opportunities for errors and bugs. If one isn’t careful, they can develop a system that bloats the technical debt of the application.

    1. To use a static level for smaller games.
    2. If one has the time/resources on a medium/large game, create a library or plugin that can code the management of nodes and resources. If refined over time, so as to improve usability and stability, then it could evolve into a reliable tool across projects.

    For an example of the various ways one can swap scenes around at runtime, please see the documentation.