Queue_free() bug

Godot Version

Godot 4.2.1

Question

My game has many projectiles and effects, all of which use “queue_free()” when they’ve either collided with an object or their animation has finished playing. Based on my limited research I would’ve expected a slowdown in performance, but instead the game outright crashes withing seconds of running. Is this a known issue with this release of Godot? Most of the solutions seem like patchwork and would only prolong an inevitable crash down the road. This is also troubling because the nodes are in the low hundreds as apposed to the thousands. I’m wondering if this is being worked on or if there’s an alternative to “queue_free()”; I should note that object pooling isn’t quite the answer because as it might fix the issue with projectiles, I have a lot of other nodes that reparent meshes for an origin shifting technique and rendering on a minimap, which requires me to individually free all those nodes independently.

Is not normal, first you need to understand the nature of the problem, analyse it and see if is a bug in the engine, in your code, and then look for solutions/workarounds.

Here it would be helpful if you can show the error messages.

Found an answer here: https://www.reddit.com/r/godot/comments/8hp3ok/use_call_deferredfree_instead_of_queue_free/

Essentially: I suggest you to use a mix between queue_free and call_deferred(‘free’). If you are updating a UI (panel_container for example), you might go with a queue_free. But if you are updating multiples bodies with physics for example, you want them to be always available unless you free them . So calling call_deferred(‘free’) will allow you to check if the object exists using obj != null. And if the object is not null, it means that it exists, otherwise it has been freed.

there were no error messages unfortunately, but I did find a solution :slight_smile:

Maybe errors appeared in the Editor log (you can see it if you open the editor from the command line), it happens if there are engine-level errors, it shouldn’t crash, though.

When checking for objects that may be dying you also need to look first if the object is_queued_for_deletion.

So it was a mutlithreading issue, hence why there was no crash report or error in the terminal. Here was my solution:

Originally I didn’t pick up on the issue because there were never many physics bodies on screen at a given time, so a root object that was an Area3D node for example was able to call “queue_free()” on reparented mesh references while also freeing itself. However, once there were over 100 Area3D nodes calling queue_free() things began to break down. Narrowing it down to multithreading helped because it explained why I wasn’t getting anything in the console. Once I made the physics engine single threaded everything worked peachy keen, but for my game I’ll need them on separate threads. Using queue_free.call_deferred() helped with the symptoms but it still crashed if there were 500+ Area3D nodes calling their destruction methods.

My solution thus far has been to introduce a timer set to around 0.25 seconds (it could be lower) that emits a signal that frees the Area3D node after all the meshes on the main thread have been freed.

1 Like

So in summary it wasn’t just about freeing the Area3D node itself, it was freeing multiple objects from a node that talked to the physics thread.

If you can, make a reproduction project and report it on github, it will help to fix the issue on future versions.

(and just in case, try 4.3dev5 because there were a lot of improvements on threading issues)

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.