Need help with orphan nodes

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By YuleTide

Hello I have a lot of objects in my game which I am creating with call_deferred("add_child", i)and when I am looking to remove them I have a call_deferred("queue_free")

When I run the game though it all seems to work in the editor but I have hundreds, and eventually thousands of orphaned nodes. I must be doing something wrong but I dont understand what. Can anyone help me to understand how to either remove the orphan nodes or even better what I should do to stop it happening?

Without seeing anything about how you manage the children, how you store them, how you refer to them and how you delete them, not much direction can be given.
Btw, you are not “creating” objects with add_child(), you parent nodes with it.
But if accumulating new nodes doesn’t stop and it’s not by design it seems like you are not actually saving them anywhere, just creating them. And if you don’t save them anywhere, you can’t refer to them later to delete them.

zhyrin | 2023-02-10 20:59

Thank you for your comment, i appreciate your help. My code is to create an instance of the object, then remove it from the script inside the object, some example code below

adding child

func addEnemy(position, speed, health)
	var i = MonsterA.instance()
	i.position = position
	i.Speed = Speed
	call_deferred("add_child", i)

and to remove them in the code for the different types of monster I have the code

func deathSelf():
    call_deferred("queue_free")

YuleTide | 2023-02-10 21:11

Can you see your added nodes in the remote scene tree while running the game in the editor?
Does the deathSelf() function get called?

zhyrin | 2023-02-10 21:13

I dont think I see them in the scene tree of the game editor, but the deathSelf definately gets called. I have had a print statement in there and it gets triggered plus the enemy does dissapear when it is supposed too.

YuleTide | 2023-02-10 21:19

If you don’t see them in the scene tree, then… Well, they won’t be part of the scene tree, they’ll be orphaned.
If you only expect to be able to refer to them by being children of a node in the scene tree then you can’t access them to call deathSelf() on them.
Is the class calling call_deferred("add_child", i) actually a node derived type?

zhyrin | 2023-02-10 21:29

There are two scripts which are creating children with this, one is the top node of the scene which is just a node type “node” (basic node) and the other is a kinematicbody2d.

YuleTide | 2023-02-10 21:32

I see.
I created a sample project based on your code and it works as expected.
Without further knowledge of your codebase I don’t think I can give any help.
Try printing in MonsterA s _tree_entered() and _ready(), maybe even put breakpoints into these functions and debug it.
Is it possible you simply create the monster faster than they get deleted?

zhyrin | 2023-02-10 21:45

Another thing you could try is not only add the instances as children, but also put them in a container like an array or dictionary.
You can compare the node’s children with the contents of this container and see if it has any that did not became children of the node.

zhyrin | 2023-02-10 21:50

Thank you for trying to help. I have been trying to debug it for two weeks now and I am getting a bit burnt out trying to solve this. I have read through all the documentation and it suggests what I am doing should work so I dont understand why they are becoming orphaned. Maybe someone else will be able to build on the questions you have asked I will hold on a little. Thanks so much again for trying to help.

YuleTide | 2023-02-10 21:55

Can the project be made available for further inspection? That’s probably the quickest / easiest way for someone to provide more targeted input…

jgodfrey | 2023-02-10 22:04

Hello, thanks for trying to help Jgodfrey. I have backups of the project on an external hard drive but I could look into setting up a github somewhere over the weekend? Its quite large now though but the issues only happen on the scenes where I have added monsters so I am pretty sure it is something to do with the way I am adding and removing them. The thing is they show on screen fine, behave as normal and dissapear when killed as expected but for some reason they are always orphaned.

YuleTide | 2023-02-10 22:24

Oh my god I am so embarrased!!!

I was stepping through the code as zhyrin suggested although I have done it a million times already and I suddenly spotted that a timer I use in the monster script has no add_child() on it…

I was creating timers and never adding them!!!

I cannot believe I have spent weeks on this and just spotted it just like that!!!

YuleTide | 2023-02-10 22:49

Well I’m glad you found it in the end :slight_smile:

zhyrin | 2023-02-11 07:24

Yes thank you for your help, sorry I wasted your time. I must have looked at that code 100 times but I became so fixated on the assumption that it was something to do with how I was creating the enemies I just didnt see it!

YuleTide | 2023-02-11 10:39

No worries! I recommend to give more context and information next time, as you can see your solution didn’t come from people trying to help you, we really didn’t have anything to go by.

zhyrin | 2023-02-11 11:44