Godot Version
v4.3.stable.official [77dcf97d8]
Question
Hello! My friend and I are relatively new to game development and are having trouble understanding the proper way to remove instances from memory.
To give some context, we’re trying to make a pachinko/ball dropper idle game, where the player will be able to drop many balls at once consistently.
The “Spawn Ball” button click handler calls the following function, both in main.gd
(which will likely need to be moved in the future):
var ball = preload("res://Scenes/Pachinko/ball.tscn")
func spawnBall () -> void:
var instance = ball.instantiate()
# set ball's position
add_child(instance)
Once that ball enters a score zone, it should be despawned using the following function in score_zone.gd
:
func _on_area_2d_body_entered(body: Node2D) -> void:
# add score
body.queue_free()
To solve the problem of a ball getting stuck balancing on the top of a peg, we do this in ball.gd
:
@onready var rigid_body_2d: RigidBody2D = $RigidBody2D
func _process(delta: float) -> void:
if is_instance_valid(rigid_body_2d):
# adjust ball's velocity if it's 0
else:
print("invalid")
This is where the problem arises. Once the queue_free()
is called on the ball, the body becomes invalid, as we expect. However, this script instance continues running and checking its validity each frame (as we can tell by the print()
). Such is the case for every spawned ball. For only a few balls, this isn’t a problem, but as time goes on and more balls are spawned, the memory leak grows.
Shouldn’t the ball.gd
script instance associated with a ball instance terminate once queue_free()
is called on its corresponding ball? Is there something we’re missing to properly terminate this?
Any help/advice would be greatly appreciated. Thanks!