I’m delving into a somewhat advanced topic and could use some clarification. Although I’m new to Godot, I have extensive experience with other engines.
I’m current trying to implement a simple mouse pickup mechanic. From the doc, I’ve identified two primary methods in Godot:
Utilizing Raycast3D (or 2D) to retrieve raycast results in _process(), which essentially involves continuous raycasting every frame.
Employing the intersect_ray() function within _physics_process() to manually query space and store the result as a member variable, subsequently utilizing it in _process().
Upon inspecting the C++ implementation of Raycast3D, it appears that these two methods are essentially equivalent.
However, a statement in the documentation has sparked some concern:
“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.”
This raises the question: could _physics_process() and _process() potentially run on different threads simultaneously in Godot? If so, what implications does this have for thread safety?
For instance, in my scenario, the raycast result could be altered by _physics_process() while simultaneously being read by _process(). This potential concurrency issue seems like it could lead to challenging debugging scenarios if not handled with care.
I’m seeking clarification on how threading is designed in Godot and what best practices exist for syncing data between different _process() functions. Any insights or illustrative examples would be greatly appreciated.
Yes, data races and null references. You need to take extra care. The engine in some scenarios may be able to warn you that you are messing with a physics resource in a process function. Mutex and semaphore classes are available.
For best practices, there are three scenarios.
Data is only read by one thread and is not critical and there is only one simple native type (int, float bool, vector, etc). In most cases this is assumed atomic and nothing needs to be done.
Data is only read by one thread but it is critical to have all state synced first, this is for large classes data structures ( array, dictionary) and writing multiple variables in the critical section. Use a mutex to guard thread access.
Data is read and written between threads. Mutex.
This problem is fundamentally common in software development so any resource on the matter would apply.
Threading in Godot leverages normal operating system thread api.
The game loop and all process functions run synchronous. All physic_process run in another loop. You can spawn threads, but they will execute outside the main loop.
While the multithreading of physics may seem like a beneficial approach for performance enhancement, it could be somewhat complex for beginners to comprehend. This is because most other engines halt the physical world during their ‘_process()’ function. As a result, when users perform actions like mouse picking or shooting, they don’t need to grapple with understanding the underlying processes.
It would be more newbie-friendly if Godot’s ‘_process()’ and ‘_physics_process()’ were synchronized. Asynchronous physics could then be offered as an option for more advanced users.