I’m not sure what you consider a trash can, but there are considerations beyond how pretty one’s code looks. First and foremost is: Does it work?
Second after that is: Is it easily understandable and maintainable by someone other than the original coder? Is it documented either by being easily readable or by being well-commented? If you come along behind yourself in a year, are you going to understand what you did?
Third: How much time is it taking to do “the right way” according to one’s idea of ideal code?
If you don’t like the quick-and-dirty Match statement, a more elegant possibility would be using the Single Responsibility Principle. Godot is very object-oriented. So, create a TutorialStep class that inherits from Node:
extends Node
class_name TutorialStep
@export var text: String
@export var position: Vector2
func run_command(arg1: Variant) -> void:
return
Then create TutorialStep objects that extend that code.
extends TutorialStep
func run_command(arg1: Variant) -> void:
arg1.spawn_enemy(3)
await arg1.enemy_died #Note this will make your game unplayable as the game will stop executing until this condition happens
Then in global_script_guides.gd:
extends Node
@export var tutorial: Array[TutorialStep]
Drag-and-Drop all your tutorial steps into the exported array. Then in the code of the level:
@onready var spawner = $Manager/$Spawner #All variables start with lowercase in gdscript by convention. Uppercase is reserved for class names.
func tutorial() -> void:
for guide in guides.tutorial
var hint = hint_preload.instantiate()
hint.text = guide.text
hint.position = guide.position
add_child(hint) # The hint appears
guide.run_command(spawner)
This is one possible implementation that keeps the modularity you’re looking for, but leverages the OOP architecture of Godot. In my opinion it’s still overly complicated. Instead of editing a single Match statement, you now have a bunch of tutorial objects in a folder to maintain. But it is elegant.
A few additional thoughts:
- You are better off avoiding
await
in your code in gdscript. It doesn’t work the way it does in JavaScript, C#, Java, etc. The only time I would personally recommend using it is in unit testing.
- In my opinion, it’s worth it to learn the GDScript style guide — Godot Engine (stable) documentation in English. Then when you are looking at code examples, or you are sharing code examples, you avoid confusion.
- You might consider just having a label called $Hint in your UI, and passing it the text and changing its visibility. If not, you definitely want to garbage collect your hint object before it goes out of scope.