General scripting paradigms
Created: 2020-05-12 08:41:41 -0700 Modified: 2020-05-21 18:11:56 -0700
About
Section titled AboutThis note is about scripting paradigms that should pertain to all languages allowed by Godot, but the examples will be in GDScript since that’s what I used.
Paradigms
Section titled ParadigmsSignals from factories
Section titled Signals from factoriesSuppose there’s a UI that should only listen to player characters, and you have a factory somewhere creating all characters. You could have the CharacterFactory
emit a signal like character_created(character: Character)
, then have something listen for that and add signals to the Character
itself, e.g. character.health_changed.connect([...])
.
Without the signal on the factory, it would typically be hard to get access to the Character
to be able to set signals up.
Getting access to some other node or script in the scene tree
Section titled Getting access to some other node or script in the scene treeSuppose you have a scene tree like this:
- root
- Game
- Map
…and you want to get access to “Game” from “Map”. Here are many different ways of doing it:
- Go from the root down through the scene tree:
$"/root/Game"
- Use a relative path:
get_parent().get_node("Game")
- Consider using autoload so that you have a singleton
- Inject Game into Map when initializing it
- Set a group:
Infrequent logic
Section titled Infrequent logic- Timers are easy to set up, but be careful because they’re in seconds, not milliseconds
- They suggest that if you don’t need logic every single frame, consider yielding to a timer (reference)
Switching scenes (reference)
Section titled Switching scenes (reference)Suppose you’re in a character-select scene and want to swap to a gameplay scene.
Note: the reference link talks about nuances like swapping vs. hiding vs. deleting so that you could, for example, keep processing a scene even though it’s not showing. However, for the methods below, I’m just talking about a high-level view of how to switch scenes.
- Method #1: make a “Main” class that keeps track of all of this for you. It would have code to add the new scene as a child and free the old scene.
- Method #2: make use of change_scene from the scenes themselves. E.g. TitleScreen.gd would have get_tree().change_scene(“res://Gameplay.tscn”)
Method #1’s code looks like this:
Method #2 doesn’t need the concept of a Main scene. Instead, make CharacterSelect.tscn your primary scene that runs when you start your game.
- Pros
- There’s no need for tracking names
- No need for a signal to connect
- No need to explicitly call free (reference, reference2)
- Cons
- If you want to initialize the scene you’re changing to; there are only hacky ways for doing so (reference), e.g.
- changescene exists on a SceneTree, you end up changing _everything in the tree, so if you wanted a wrapper node at the top of your tree, you would have to include it in every scene that you’re changing to.
Loading vs. preloading (reference)
Section titled Loading vs. preloading (reference)Preloading will try loading as soon as the game runs. You can tell that’s the case by doing this:
Here, if you replace “preload” with “load”, the syntax error in Gameplay.gd will never actually be hit.