Why does halting the _physics_process() thread also halt the _process() thread?

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

For reference, this will stop the physics thread and main thread after 2 seconds even though the semaphore.wait() is being called from the physics thread:

var frames = 0
var i = 0
func _process(delta):
	#this will also stop printing after the wait() call
	frames+=1
	if frames > 60:
		print(i)
		i+=1
		frames = 0

var semaphore = Semaphore.new()
func _ready():
    yield(get_tree().create_timer(2),"timeout")
    yield(get_tree(),"physics_frame")
    semaphore.wait()

I thought they were in separate threads and that _process() would be able to run independently. Unfortunately this means that running intensive physics calculations will cause my entire project to stutter.

:bust_in_silhouette: Reply From: Wakatta

The main loop in the Scene tree will probably look like this.

#MainLoop.gd
var running = true

while running:
    for node in scene_tree:
        if node.is_ready:
            node._ready()
        node._unhandled_input()
        node._input()
        node._process()
        node._physics_process()

So when you call yield in a function it not only stops execution of other functions in that node but also further nodes in the tree after that node.

Unless of course the devs have set yield to only affect the calling node which is doubtful.

Your code only runs on the main thread and you will have to create a new one for your CPU intensive calculations.

Using Threads with Mutexs and Semaphore are great in C++ but in GDScript have seen it used with call_deferred which works way faster.

That clears things up so they aren’t really being called from separate threads independently, they require each other to complete before continuing.

My “CPU intensive calculations” are partly several hundred calls using direct_space_state for collision testing which cannot be made from a thread without risking a “locked” error (which I was in fact getting when I tried running my AI algorithm entirely within a thread).

Godot physics runs by default in the same thread as game logic, but may be set to run on a separate thread to work more efficiently. Due to this, the only time accessing space is safe is during the Node._physics_process() callback. Accessing it from outside this function may result in an error due to space being locked.

So I am forced to have stuttering when it comes to these physics function calls unfortunately.

I’ll probably make a suggestion to make calls with direct_space_state wait in a cue until it is unlocked instead of throwing an error and crashing the project.

KnightNine | 2022-10-28 03:21

If memory serves well that option is in Project settings > Rendering > Threads

Wakatta | 2022-10-28 03:38

What would that allow me to do exactly? there’s also two options thread_model and thread_safe_BVH.

KnightNine | 2022-10-28 04:35