Hi, I am having a werid crash problem when deleting a Node3D with a child Area3D node.
Basically I create like 30 objects with Area3D + CollisionShape3D(with a Box collision shape) per mouse click,
then I give them a timed-life of a 8 seconds, after 8 seconds they queue-free themselves.
But it seems after I spam like a few hundreds of Node3D, the game just crashes to desktop with an error in console:

"ERROR:ERROR:ERROR: FATAL: Index p_index = 0 is out of bounds (shapes.size() = 0).
FATAL: Index p_index = 0 is out of bounds (shapes.size() = 0).
FATAL: Index p_index = 0 is out of bounds (shapes.size() = 0).
at: at: get_shape_transform (servers/physics_3d/godot_collision_object_3d.h:128)
get_shape_transform (servers/physics_3d/godot_collision_object_3d.h:128)"

I did read about the docs about node deletion, it seems I don't need to manually free 'children' of a parent Node , since it frees all siblings automatically with queue-free function.

Here is the object I spammed in game to stress-test the problem:

And this is the code I used to auto-free upon object timeout:

extends Node3D

var speed : Vector3 = Vector3.ZERO

var life_start : float = -1.0
var life_span : float = 8.0

var dying : bool = false

# Called when the node enters the scene tree for the first time.
func _ready():
	pass # Replace with function body.


# Called every frame. 'delta' is the elapsed time since the previous frame.
func _process(delta):
	if self.is_queued_for_deletion():
		return
	
	var now_time : float = Time.get_unix_time_from_system()
	
	if life_start < 0:
		life_start = now_time
		
	var life_elapsed = now_time - life_start
	
	if life_elapsed >= life_span:
		dying = true
		hide()
		queue_free()
	
	
	var desire_x = delta * speed.x
	var desire_y = delta * speed.y
	var desire_z = delta * speed.z
	
	self.transform.origin.x += desire_x
	self.transform.origin.y += desire_y
	self.transform.origin.z += desire_z
	
	
func set_velocity(vel):
	speed = vel
	pass

Thanks.

EDIT::
Update:
Just tested spamming objects without 'queue-freeing' them, the number of objects actively reached 4k, and there is still no sign of crash after a few minutes -.-

  • DaveTheCoder replied to this.
  • [unknown] Your project is a bit messy. You're not actually instantiating rpg_7.tscn as you described earlier but some scene that's embedded in player2.tscn and has a StaticBody3D as a root node and rgp_7.tscn as its child. This may or may not contribute to the problem.

    Anyway, never instantiate new physics objects including areas from _physics_process(). So don't call shoot() from there, call it from _input() instead.

    Also don't mix _input() event handler and Input object queries for handling input. It's confusing and non-elegant. Use one or the other.

    • Try commenting out those lines
    	var desire_x = delta * speed.x
    	var desire_y = delta * speed.y
    	var desire_z = delta * speed.z
    	
    	self.transform.origin.x += desire_x
    	self.transform.origin.y += desire_y
    	self.transform.origin.z += desire_z
    • Or try to use call_deferred("queue_free") instead of queue_free()
    • I have no such experience and I don't really understand the errors, those are merely stuff I'd try to do to understand what's happening

      BroTa
      Thanks for the reply, the part you just mentioned seemed has nothing to do with the crash:
      I just commented the lines with 'hide()' and 'queue_free()', it just run with 4k+ objects updating without a single crash after like 10 mins.

      I looked up the source code of 4.1 stable, it seems the error is caused by the engine trying to delete a collision shape3D with an index less than or equal to 0, which raised a fatal level assertion or exception in engine that caused the crash, though I don't know why queue-freeing node with Area3D would trigger 'null shape size' in that function.

      I will try replacing queue_free with call_deferred to see if that fixes the problem.

      BroTa queue_free() is already deferred.

      @MagickPanda The problem might be somewhere else in the code. Are you storing/accessing those instances elsewhere? Let's see the instantiation code too.

        xyz

        Here is the function used to manually create 20 instances of the object:

        func shoot():
        	var projectiles_node : Node = $"../Projectiles"
        	
        	for i in range(0, 20):
        		var proj_inst = _projectile_scene.instantiate()
        		
        		var gtran : Transform3D = $Head/SpringCamera.global_transform
        		
        		var direction = gtran.basis.z
        		
        		var camera_pos : Vector3 = $Head/SpringCamera.global_transform.origin
        		var test_pos : Vector3  = camera_pos + direction * -3
        		
        		proj_inst.transform.origin = camera_pos + direction * -3
        		
        		
        		var velocity : Vector3 = Vector3.ZERO
        		
        		velocity = direction * -20.0
        		
        		proj_inst.transform.basis = gtran.basis
        		
        		proj_inst.set_velocity(velocity)
        		
        		var rpg : RPG7 = proj_inst.get_node("RPG7") as RPG7
        		
        		rpg.set_creator(self)
        		
        		projectiles_node.add_child(proj_inst)

        Edit: Tried call_defered but it still crashes with same error.

        • xyz replied to this.

          And I also have 6 npc aircrafts shooting at 20ms interval at my character, they spam like 300ish objects per second, and throw them at my character, the objects also get deleted after 4 seconds, but those objects don't seem to have the crash problem as the one shot by my character manually, The only different betwee my player's projectile and npc projectile is the shape of the CollisionShape3D, so I think the the BoxShape3D I am using for the problematic player-shot projectile object is the culprit of the crash. But that is just my guess though.

          Edit: Changed from BoxShape3D to SphereShape3D as CollisionShape3D, and it still crashes after spamming like 300 objects =/

          xyz I uploaded the whole project, it's just a side project/sandbox to test some stuff for my other game, I will make this game open-source soon anyway. -.-

          godetteofvictoryrev0.zip
          22MB

          Steps to reproduce:

          1. Spam clicking left-mouse-button at any location or facing, it should crash after 8 seconds or so (after the first free of the rocket timeout)
          • xyz replied to this.

            MagickPanda That's not a minimal project that reproduces the problem. Making it can often help to figure it out yourself. So put in some effort and make a minimal project instead of just uploading the whole project in the state you got stuck in.

            Wild guess: Try setting the CollisionShape3D's disabled property to true before calling queue_free().

            • I was really interested to know what the problem is so I tried to recreate what you did using only what you showed us here, and with some naming and scene tree related modifications, your code actually works flawlessly except for one thing.
            • The console shouted at me with an Invalid call nonexistent function 'set_creator' I had to comment it out.
            • At first I thought it was a built-in method of some class, haha silly me.
            • So what does this function do? I suspect your problem lies in this function or the RPG7 class.
            • As you said, you face the problem when the player shoots the objects and not when the aircrafts do.
            • If you make the aircrafts shoot RPG7 projectiles, and use the same shoot function showed here (except that the transforms are from the aircraft and not the camera), do you get thrown an error?
            • If you make the player shoot whatever the aircrafts are shooting, and/or use their shoot() function, does it work with no problems.

            set_creator is method to assign and store rpg's parent as attacker, to do some player buff/weapon info query later, like damage, speed etc, but it has no function atm.

            I think the crash is related to 2 or more Area 3Ds got freed when they overlapped at the same location, that's why I created 20 Area3D node with one click. But for some reason it's not 100% triggering the crash if you don't spam enough rocket projectiles.
            I tested on a few PC ranging from windows and ubuntu or ubuntu_like OS, they seem to all have the crashing problem, and on some platform it just freezes the entire OS. -.-

            I will give Dave's method a try, hopefully it will rectify the crash.

            godetteofvictoryrev1.zip
            22MB

            Tried disabling physics with set_physics_process/internal, but it still crashes upon first deletion of rocket object.
            So pls lemme know if I did something wrong with using/deleting area3D or disabling it -.-

            Thanks.

            [unknown] Your project is a bit messy. You're not actually instantiating rpg_7.tscn as you described earlier but some scene that's embedded in player2.tscn and has a StaticBody3D as a root node and rgp_7.tscn as its child. This may or may not contribute to the problem.

            Anyway, never instantiate new physics objects including areas from _physics_process(). So don't call shoot() from there, call it from _input() instead.

            Also don't mix _input() event handler and Input object queries for handling input. It's confusing and non-elegant. Use one or the other.

            [unknown]

            I think I have already replaced rpg_7's root node 'projectile.tscn' from StaticBody3D to Node3D to avoid potential conflicts, I will double-check if its type is changed 'Node3D'.

            The rpg_7 is a child node of projectile.tscn, I have projectile as packed scene in player2.tscn, and instantiate projectile.tscn in 'shoot' function:

            @export var _projectile_scene : PackedScene

            func shoot():
            	var projectiles_node : Node = $"../Projectiles"
            	
            	for i in range(0, 20):
            		var proj_inst = _projectile_scene.instantiate()
                    blahblah...

            So I assume projectile's child nodes got instantiated too when projectile packedscene node got instantiated, though I am not 100% sure about godot's hierarchiral instantiating behaviors.

            Your project is a bit messy. You're not actually instantiating rpg_7.tscn as you described earlier but some scene that's embedded in player2.tscn and has a StaticBody3D as a root node and rgp_7.tscn as its child. This may or may not contribute to the problem.

            Thanks for the insight. I will move them to input function, and stick to one input event to handle all input events.

            Anyway, never instantiate new physics objects including areas from _physics_process(). So don't call shoot() from there, call it from _input() instead.

            Also don't mix _input() event handler and Input object queries for handling input. It's confusing and non-elegant. Use one or the other.

            P.S:Moving the input and shoot functions from 'physics_process' to 'process' seemed to fix the problem. Any testing is appreciated.

            • xyz replied to this.

              MagickPanda Moving the input and shoot functions from 'physics_process' to 'process' seemed to fix the problem. Any testing is appreciated.

              I already tested it. Adding collision nodes from _physics_process() is the culprit. The rest I just mentioned in passing.

              [unknown] Wow, good to know!
              Is it a bug or is there some known reason?

              • xyz replied to this.

                BroTa Hard to tell. But introducing new colliders in the middle of the physics frame processing is bound to produce at least some strange behavior. I wasn't exactly excepting crashes though.

                Thanks again for the helps guys.
                Just curious is there somewhere in the doc mentioning what you should NOT do in the process, physics_process?
                I think people will more likely to avoid falling into the pitfall like the one I just crawled out, and it's nign impossible to find the mistake I made without your helps -.-