Bite-Sized Godot: Five more small GDScript tips


In case the previous post wasn’t enough, here’s a few more quick tips for working with GDScript.

Better float comparison

Floating point numbers are prone to tiny inaccuracies that can make them a pain to work with, especially when trying to compare them to one another. We may not care whether or not two numbers differ at the 10th decimal place, but our code does, declaring any comparisons as not equal. To help deal with this, Godot offers two functions for comparing floats that takes this into account: is_equal_approx and is_zero_approx.

As the names imply, is_equal_approx compares two floating point values and determines if they’re “close enough” based on their relative size, meaning smaller numbers will have tighter tolerances than larger numbers, while is_zero_approx is a faster form of is_equal_approx when you want to know if a number is approximately zero. Use these two functions to help prevent annoying comparison failures.

extends Node2D

func _ready() -> void:
	# Will print 'false'
	print(1.123456789 == 1.123456788)

	# Will print 'true
	print(is_equal_approx(1.123456789, 1.123456788))

	# Will print 'false'
	print(0.0000000001 == 0.0)

	# Will print 'true'
	print(is_zero_approx(0.0000000001))

Wrapping values

If you have a value you want to cycle through a certain range when modifying it, wrapf, for floats, and wrapi, for integers, are the functions for you. These functions will keep your number above themin, inclusively, and below the max, exclusively, wrapping the values around either end of the range as needed.

extends Node2D

func _ready() -> void:
	# Will print 1
	print(wrapi(4, 1, 4))
	
	# Will print 3
	print(wrapi(0, 1, 4))

	# Will print 1.123
	print(wrapf(4.123, 0, 3))

	# Will print 0.5
	print(wrapf(-0.5, 0, 1))

Smoother interpolation

Linear interpolation too linear for you? The smoothstep function lets you interpolate between two values using an S-curve instead, meaning values will gradually ease away from the from parameter, have the maximum delta in the middle, and gradually ease back into the to parameter.

extends Node

func _ready() -> void:
    # Will print 0
    print(smoothstep(0, 1, 0))
    # Will print 0.15625
    print(smoothstep(0, 1, 0.25))
    # Will print 0.5
    print(smoothstep(0, 1, 0.5))
    # Will print 0.84375
    print(smoothstep(0, 1, 0.75))
    # Will print 1
    print(smoothstep(0, 1, 1))

Manually throwing errors and warnings

Assertions are a great way to ensure your application is running as intended when debugging, but they also stop the application in its tracks when they fail. If you’d prefer to just be made aware of an undesirable condition without stopping the execution of the application, you can use the push_error and push_warning functions to throw errors and warnings in both the Godot debugger and the terminal of your application.

extends Node

func _ready() -> void:
    push_warning('This is a warning')
    push_error('This is an error')

Mapping a value to a range

This last one really just speaks for itself. With the range_lerp function, you can easily map a value from one range to another.

extends Node2D


func _ready() -> void:
	# Will print out 30
	# As 55 is halfway between 10 and 100
	# and 30 is halfway between 20 and 40
	print(range_lerp(55, 10, 100, 20, 40))

Conclusion

And that’s it for today!