So I am following HeartBeast's Action RPG tutorial and while waiting for new videos to be uploaded I am attempting to add new features. Right now I am attempting to have coins and gems spawn when grass is cut (Link). The programming seems to work fine, gems and coins spawn but when I look in output I get this error.

0:00:02.608 area_set_shape_disabled: Can't change this state while flushing queries. Use call_deferred() or set_deferred() to change monitoring state instead. <C++ Error> Condition "area->get_space() && flushing_queries" is true. <C++ Source> servers/physics_2d/physics_2d_server_sw.cpp:409 @ area_set_shape_disabled() <Stack Trace> Grass.gd:28 @ spawn() Grass.gd:15 @ create_grass_effect() Grass.gd:18 @ _on_HurtBox_area_entered()

From what I have found online, it seems I am having a problem with overlapping areas, and the error report suggests using either call_deffered() or set_deffered(). My problem is where do I do that? Everything I have tried either comes up with the same error or crashes.

    extends Node2D
    
    var rng = RandomNumberGenerator.new()
    var press = 0
    
    func _ready():
    	rng.randomize()
    
    func create_grass_effect():
    	var GrassEffect = load("res://Effects/GrassEffect.tscn")
    	var grassEffect = GrassEffect.instance()
    	var world = get_tree().current_scene	
    	world.add_child(grassEffect)
    	grassEffect.global_position = global_position
    	spawn()
    
    func _on_HurtBox_area_entered(_area: Area2D) -> void:
    	create_grass_effect()
    	queue_free()
    	
    func spawn():
    	rng = (rng.randi_range(16, 1) * press) - press 
    	print(rng)
    	if rng == 6 || rng == 8 || rng == 10 || rng == 21 || rng == 24 || rng == 30 || rng == 36|| rng == 39 || rng == 42:
    		print(str("coin")+' ', press)
    		var CoinSpawn = load("res://Coin/Coin.tscn")
    		var coinSpawn = CoinSpawn.instance()
    		get_tree().get_root().get_node("World").find_node("YSort").add_child(coinSpawn)
    		coinSpawn.global_position = global_position
    	
    	elif rng == 0 || rng == 3:
    		print(str("gem")+' ', press)
    		var GemSpawn = load("res://Coin/Rupee.tscn")
    		var gemSpawn = GemSpawn.instance()
    		get_tree().get_root().get_node("World").find_node("YSort").add_child(gemSpawn)
    		gemSpawn.global_position = global_position
    		
    	else:
    		print("you get nothing")
    
    func _input(event: InputEvent) -> void:
    	if event is InputEventKey and event.pressed and not event.is_echo():
    		press += 1
    		if press == 4:
    			press = 1

Thank you for reading.

I'm following his tutorial too. He is awesome! I'm very new as well (and i'm having this same error but with a reparenting function). Until someone with more knowledge answers your question.. my guess would be your spawn function. How i've seen call_deferred used is like this: func spawn(): call_deferred("deferred_spawn") func deferred_spawn(): #Your actual spawn function goes here and then you'd just call your spawn() where you needed it. Not sure if that would fix it.. but worth a shot :P

by:Aireek

I changed this topic from a discussion to a question, so any posts can be marked as the answer. (I would offer help with the issue itself, but I have not used call_deferred with Godot and am not sure what is causing the issue).

9 months later

Following a similar tutorial by Mathew (HeartBeast), his method for adding effects mostly works, but it can try to add an effect (child) while the node is busy, giving an error. His method for deleting objects can have the same problem.

I prefer to use call_deferred('free')instead ofqueue_free to avoid the confect on deletion. This only seems necessary when you are using an object with physics, or if you make a lot of other calls with queue_free. And I use main.call_deferred("add_child", child) instead of main.add_child(child) when adding a child. I'm still new at this myself, but it seems to work.

2 years later