The Godot Q&A is currently undergoing maintenance!

Your ability to ask and answer questions is temporarily disabled. You can browse existing threads in read-only mode.

We are working on bringing this community platform back to its full functionality, stay tuned for updates. | Twitter

0 votes

TL;DR: How can I query Physics2DDirectSpaceState from a thread a whole bunch of times.

When I first load a new level (as a scene) as part of the initialization of that level I want to make many, many queries to Physics2DDirectSpaceState. To handle doing this I make a thread that belongs to the parent of the level which runs initialization functions. This is the script of the thread that is created and owned by the parent:

var queue = []
var worker_semaphore
var worker_mutex
var worker_thread
var run_worker_thread

func stop():
    run_worker_thread = false

func post_function(node, f_name, args):
        'n' : node,
        'f' : f_name,
        'a' : args

func _worker_thread_process(u):
    while run_worker_thread:


        if queue.size() > 0:
            var current_function_set = queue[0]

            var node = current_function_set['n']
            var thread_func = current_function_set['f']
            var thread_args = current_function_set['a']

            # call given function
            # is this thread safe?
            node.callv(thread_func, thread_args)



func start():
    # start up worker thread
    worker_semaphore =
    worker_mutex =
    worker_thread =
    run_worker_thread = true
    var err = worker_thread.start(self, "_worker_thread_process", null, Thread.PRIORITY_NORMAL)
    if err != OK:

Then levels that are being initialized post the functions that they want initialized and then wait until the thread finishes with that function and emit the init_finished signal which tells the parent that the new level is done initializing and is ready to be used:

var space_state
signal init_finished

func _ready():
    # get direct space state outside of thread
    space_state = get_world_2d().direct_space_state
    # tell parent to give this level's function to its thread
    get_parent().post_function(self, "_init", [])

# simplified init function
func _init():
    # prepare physics query
    var shape_query =
    var shape =
    # do a whole bunch of physics queries (anywhere from 20,000 to 200,000)
    for idx in range(20000):
        var result = space_state.intersect_shape(shape_query, 1)
        if result:
            # do something

The issue is that my game crashes if I run too many queries at once with the message: ERROR: CowData<class RID>::get: FATAL: Index p_index=0 out of size (size()=0). My guess is:
The physics thread is simply overwhelmed by my queries during a single frame and blows up.
In this case should I wait for another frame to finish making my queries? Or maybe sink the user thread to the main thread every once in a while?

I would like to know if the Physics2DDirectSpaceState tries to handle any queries its given during one frame, or if it handles queries some other way.

If you think that I am crashing for another reason or one of my assumptions is wrong, I would consider responses to those issues very greatly as well.

in Engine by (283 points)
edited by

Please log in or register to answer this question.

Welcome to Godot Engine Q&A, where you can ask questions and receive answers from other members of the community.

Please make sure to read Frequently asked questions and How to use this Q&A? before posting your first questions.
Social login is currently unavailable. If you've previously logged in with a Facebook or GitHub account, use the I forgot my password link in the login box to set a password for your account. If you still can't access your account, send an email to [email protected] with your username.