Bite-Sized Godot: Five small GDScript tips
As I work with Godot, I come across a variety of useful tidbits too small to make their own post about, so here’s a few of those items:
Custom string casting with _to_string
By default, when you cast a node or custom class to a string, you tend to get a pretty ugly and unusable output:
extends Node2D
var title: String = 'Player 1'
var health: float = 99.0
var mana: float = 15.0
# Will print something like [Node2D:1920]
func _ready() -> void:
print(self)
But by overriding the _to_string()
function, you can choose what should be returned when the node is cast to a string:
extends Node2D
var title: String = 'Player 1'
var health: float = 99.0
var mana: float = 15.0
# Will print 'Player 1 | Health: 99 | Mana: 15'
func _ready() -> void:
print(self)
func _to_string() -> String:
return '%s | Health: %s | Mana: %s' % [title, health, mana]
While you’ll probably want to define a custom function for most player-facing strings, this can be very helpful for debugging your game or even just casually tracking changes to certain elements while playtesting it.
Exporting values to a dropdown
It’s often helpful to have exported variables that come from a fixed set of options, rather than having to manually remember and parse strings or integers. If you have an enumerator containing your values, you can use it as the exported variable type (export (MyEnum) var value
). If you want to manually define values, you can use the type of int or string followed by a comma separated list of choices, ie export (int, "Chaotic", "Neutral", "Lawful") var alignment
or export (String, "Sara", "Jonathan", "Ashton") var party_member
, depending on if you want the value returned to you in code to be an integer or a string.
enum WeaponType {
Sword,
Bow,
Staff
}
export (WeaponType) var weapon
# Will return the string value of the selection
export (String, "Sara", "Jonathan", "Ashton") var party_member
# Will return an integer value, similar to the enumerator above
export (int, "Chaotic", "Neutral", "Lawful") var alignment
Safe lines
Ever noticed that the line numbers in Godot’s built-in script editor aren’t always the same color? That’s due to safe lines, a built-in feature that can detect whether or not a line is type-safe before running your project. If a line number is highlighted, that means Godot is able to reasonably verify that the code on a line matches up with the expected types of the objects being acted upon. If a line isn’t highlighted, that means Godot is unable to verify that everything is type-safe. It doesn’t necessarily mean there’s a problem, just that the line can’t be verified before running the app. You can also help Godot out with this by using as
to cast objects of an unclear type.
If desired, you can go into your editor settings to disable / enable this feature or to change the highlight color:
Using underscores to make large numbers more readable
Have some big numbers in you code and wish they were easier to read? Underscores are ignored at compile time for numbers and are a great way to add readability to your code.
extends CenterContainer
var my_big_number = 1_000_000_000_000
func _ready() -> void:
$Label.text = str(my_big_number)
Snapping / rounding a number to a specific increment using stepify()
And lastly, we have the stepify() function, which let’s you snap a value to a given step. For example, you can use this function to round a float to a certain number of decimal places, or to snap it to the nearest X:
extends CenterContainer
onready var label_top = $VBoxContainer/label_top
onready var label_bottom = $VBoxContainer/label_bottom
func _ready():
randomize()
# Round to two decimal places
label_top.text = str(stepify(randf(), 0.01))
# Pick a number between 0 and 100,000 but round the label to the nearest hundred
label_bottom.text = str(stepify(randf() * 100000, 100))
Conclusion
And that’s a quick look at some handy GDScript tips. Expect more in the future!