My code is trying to call a deleted node

Godot Version

4.3 Stable

Question

Hello! I’m making a script where I create instances and after a button is pressed a certain amount of times, it’s deleted. I’m using a for loop to increase the amount until it’s deleted, and when it gets to the amount where it deletes, it successfully gets freed. The problem is when I try to increase the amount after that. I think queue_free() doesn’t fully delete the node…
Here’s my code

for i in range(len(sequence)):  #repeates until it reaches the number of instances
		var p = $".".get_child(i+1) #the parent node of the instances is calling the next instance
		###this is calling the expiration for the instance
		#this isn't where the problem is, so don't worry too much
		var food = p.get_child(0).text
		var expiration = new_item[food + str(base)]
		expiration = int(expiration)
		###
		Callable(p,"_change_expiration").call(expiration,cur_day)
		#calls the function within specified instance

func _change_expiration(expiration,cur_day):
	###not too important, it's setting a label within the instance
	#this is not where the problem occurs
	var p = self.get_child(1).text
	p = expiration-cur_day
	self.get_child(1).text = str(p)
	###
	if p == 0: #this is where the problem starts
		self.get_parent().remove_child(self)
		#the instance is removing itself, which is working fine
		#the problem is when 
		##var food = p.get_child(0).text##
		# is called, it tries to call a null node

TL;DR, I think queue_free() doesn’t delete a node, but makes it instead. Is there another way to delete a node permanently?

To add onto this, I checked the instances by using self.get_children(), and it did correctly show the children- which means the problem isn’t a possible node, but instead, something is storing a value in a variable

CORRECTION
The problem is with the sequence variable.
NEW PROBLEM
How do I remove a value from an array?

queue_free() delays deletion to end of frame, when all methods that use call_deferred() did their job, nodes will be erased. Using free() is instant deletion and happens where it called, but most times works badly for nodes. You may set_meta(&‘is_valid’, false) and check if it still exist but shouldn’t be used.

why not just iterate over children like:

for node in get_children():
	var food = node.text
	#and so on...

Thanks for the knowledge! But unfortunately, the problem is with how many times the for loop is repeated. I’m trying to go through my code and fix it. Thanks for your help!

this thing looks horrible

just use

queue_free()
2 Likes

But you aren’t using it.
You are using remove_child() and the documentation specifically states it doesn’t delete the node.

PS: Relying on node placement in the scene tree isn’t ideal. As your game design and code grows things get moved and tracking injudicious usage of get_child()'s will lead to confusion. (It also makes it very hard for other people to understand your code)

1 Like