2023-01-12 20:49:14 +01:00
|
|
|
|
2022-03-18 17:46:08 +01:00
|
|
|
|
|
|
|
Autoloads versus regular nodes
|
|
|
|
==============================
|
|
|
|
|
2024-03-16 20:56:52 +01:00
|
|
|
Pandemonium offers a feature to automatically load nodes at the root of your project,
|
2022-03-18 17:46:08 +01:00
|
|
|
allowing you to access them globally, that can fulfill the role of a Singleton:
|
2023-01-12 19:29:11 +01:00
|
|
|
`doc_singletons_autoload`. These auto-loaded nodes are not freed when you
|
2023-01-12 19:30:47 +01:00
|
|
|
change the scene from code with `SceneTree.change_scene`.
|
2022-03-18 17:46:08 +01:00
|
|
|
|
|
|
|
In this guide, you will learn when to use the Autoload feature, and techniques
|
|
|
|
you can use to avoid it.
|
|
|
|
|
|
|
|
The cutting audio issue
|
|
|
|
-----------------------
|
|
|
|
|
|
|
|
Other engines can encourage the use of creating manager classes, singletons that
|
2024-03-16 20:56:52 +01:00
|
|
|
organize a lot of functionality into a globally accessible object. Pandemonium offers
|
2022-03-18 17:46:08 +01:00
|
|
|
many ways to avoid global state thanks to the node tree and signals.
|
|
|
|
|
|
|
|
For example, let's say we are building a platformer and want to collect coins
|
2023-01-12 19:29:11 +01:00
|
|
|
that play a sound effect. There's a node for that: the `AudioStreamPlayer
|
2023-01-12 20:47:54 +01:00
|
|
|
( AudioStreamPlayer )`. But if we call the `AudioStreamPlayer` while it is
|
2022-03-18 17:46:08 +01:00
|
|
|
already playing a sound, the new sound interrupts the first.
|
|
|
|
|
|
|
|
A solution is to code a global, auto-loaded sound manager class. It generates a
|
2023-01-12 19:43:03 +01:00
|
|
|
pool of `AudioStreamPlayer` nodes that cycle through as each new request for
|
|
|
|
sound effects comes in. Say we call that class `Sound`, you can use it from
|
|
|
|
anywhere in your project by calling `Sound.play("coin_pickup.ogg")`. This
|
2022-03-18 17:46:08 +01:00
|
|
|
solves the problem in the short term but causes more problems:
|
|
|
|
|
|
|
|
1. **Global state**: one object is now responsible for all objects' data. If the
|
2023-01-12 19:43:03 +01:00
|
|
|
`Sound` class has errors or doesn't have an AudioStreamPlayer available,
|
2022-03-18 17:46:08 +01:00
|
|
|
all the nodes calling it can break.
|
|
|
|
|
2023-01-12 19:43:03 +01:00
|
|
|
2. **Global access**: now that any object can call `Sound.play(sound_path)`
|
2022-03-18 17:46:08 +01:00
|
|
|
from anywhere, there's no longer an easy way to find the source of a bug.
|
|
|
|
|
2023-01-12 19:43:03 +01:00
|
|
|
3. **Global resource allocation**: with a pool of `AudioStreamPlayer` nodes
|
2022-03-18 17:46:08 +01:00
|
|
|
stored from the start, you can either have too few and face bugs, or too many
|
|
|
|
and use more memory than you need.
|
|
|
|
|
2023-01-12 20:55:57 +01:00
|
|
|
Note:
|
|
|
|
|
2022-03-18 17:46:08 +01:00
|
|
|
|
|
|
|
About global access, the problem is that Any code anywhere could pass wrong
|
2023-01-12 19:43:03 +01:00
|
|
|
data to the `Sound` autoload in our example. As a result, the domain to
|
2022-03-18 17:46:08 +01:00
|
|
|
explore to fix the bug spans the entire project.
|
|
|
|
|
|
|
|
When you keep code inside a scene, only one or two scripts may be
|
|
|
|
involved in audio.
|
|
|
|
|
2023-01-12 19:43:03 +01:00
|
|
|
Contrast this with each scene keeping as many `AudioStreamPlayer` nodes as it
|
2022-03-18 17:46:08 +01:00
|
|
|
needs within itself and all these problems go away:
|
|
|
|
|
|
|
|
1. Each scene manages its own state information. If there is a problem with the
|
|
|
|
data, it will only cause issues in that one scene.
|
|
|
|
|
|
|
|
2. Each scene accesses only its own nodes. Now, if there is
|
|
|
|
a bug, it's easy to find which node is at fault.
|
|
|
|
|
|
|
|
3. Each scene allocates exactly the amount of resources it needs.
|
|
|
|
|
|
|
|
Managing shared functionality or data
|
|
|
|
-------------------------------------
|
|
|
|
|
|
|
|
Another reason to use an Autoload can be that you want to reuse the same method
|
|
|
|
or data across many scenes.
|
|
|
|
|
2023-01-12 19:43:03 +01:00
|
|
|
In the case of functions, you can create a new type of `Node` that provides
|
2023-01-12 19:32:38 +01:00
|
|
|
that feature for an individual scene using the `name
|
2023-01-12 20:47:54 +01:00
|
|
|
( doc_gdscript_basics_class_name )` keyword in GDScript.
|
2022-03-18 17:46:08 +01:00
|
|
|
|
|
|
|
When it comes to data, you can either:
|
|
|
|
|
2023-01-12 19:30:47 +01:00
|
|
|
1. Create a new type of `Resource` to share the data.
|
2022-03-18 17:46:08 +01:00
|
|
|
|
|
|
|
2. Store the data in an object to which each node has access, for example using
|
2023-01-12 19:43:03 +01:00
|
|
|
the `owner` property to access the scene's root node.
|
2022-03-18 17:46:08 +01:00
|
|
|
|
|
|
|
When you should use an Autoload
|
|
|
|
-------------------------------
|
|
|
|
|
|
|
|
Auto-loaded nodes can simplify your code in some cases:
|
|
|
|
|
|
|
|
- **Static Data**: if you need data that is exclusive to one class, like a
|
|
|
|
database, then an autoload can be a good tool. There is no scripting API in
|
2024-03-16 20:56:52 +01:00
|
|
|
Pandemonium to create and manage static data otherwise.
|
2022-03-18 17:46:08 +01:00
|
|
|
|
|
|
|
- **Static functions**: creating a library of functions that only return values.
|
|
|
|
|
|
|
|
- **Systems with a wide scope**: If the singleton is managing its own
|
|
|
|
information and not invading the data of other objects, then it's a great way to
|
|
|
|
create systems that handle broad-scoped tasks. For example, a quest or a
|
|
|
|
dialogue system.
|
|
|
|
|
2024-03-16 20:56:52 +01:00
|
|
|
Until Pandemonium 3.1, another use was just for convenience: autoloads have a global
|
2022-03-18 17:46:08 +01:00
|
|
|
variable for their name generated in GDScript, allowing you to call them from
|
2023-01-12 19:43:03 +01:00
|
|
|
any script file in your project. But now, you can use the `name` keyword
|
2022-03-18 17:46:08 +01:00
|
|
|
instead to get auto-completion for a type in your entire project.
|
|
|
|
|
2023-01-12 20:55:57 +01:00
|
|
|
Note:
|
|
|
|
|
2022-03-18 17:46:08 +01:00
|
|
|
|
|
|
|
Autoload is not exactly a Singleton. Nothing prevents you from instantiating
|
|
|
|
copies of an auto-loaded node. It is only a tool that makes a node load
|
|
|
|
automatically as a child of the root of your scene tree, regardless of your
|
|
|
|
game's node structure or which scene you run, e.g. by pressing :kbd:`F6` key.
|
|
|
|
|
|
|
|
As a result, you can get the auto-loaded node, for example an autoload called
|
2023-01-12 19:43:03 +01:00
|
|
|
`Sound`, by calling `get_node("/root/Sound")`.
|