-
Notifications
You must be signed in to change notification settings - Fork 57
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
The physics server is not thread-safe #356
Comments
Hello, In godotengine/godot-proposals#7308 (comment) you mention that you plan to do this in the same way as godot does it by creating an interface like PhysicsServer3DWrapMT. I would say that with the locking interfaces that Jolt provides, it should be possible to create a far more performant version and I wouldn't expect this to be a lot of work. Is there a reason why you think this is hard? |
To start with, I don't have a ton of experience with parallel programming, outside of your average mutex/atomic. I would certainly much rather rely on Jolt's existing locking. If it was just about acting as a middle-man between Godot's API and the actual Jolt bodies then most of the work would have already been done for me, but considering the amount of my own mutable state in just As an example, Obviously that example isn't an insurmountable obstacle, but trying to imagine all the different ins-and-outs of this machinery is difficult for me. On top of that I typically find that multi-threading bugs manifest themselves in very random/non-deterministic ways that can be frustrating or downright impossible to debug, so this "wall of synchronization" that With all that said, seeing as how Anyway, that probably came off more defensive than I meant for it to sound. I just don't think I can pull this off by myself in a way that wouldn't make me lose sleep at night. If you can see some way of easily accommodating for this then I'm all ears, of course. |
Ok, you convinced me :) Let's first make a working version, then we can always decide to make it better later. |
Agreed though i kind of think the safest and performant approach could be using jolt internal stuff, as it was designed for high multithreading. |
Is there documentation for Jolt and Godot like UML graphs ( state, activity, sequence, etc ) regarding physics engine that would help anyone wanting to contribute, to better understand what is what, how it works and how they could be interconnected in an efficient way ? |
Not that I'm aware of. You have this for Godot and for Jolt I guess you have the "Simulation Step in Detail" section in this document. Neither of them will be of much help with regards to contributing to this particular issue though. The work required for this issue is largely "just" about recreating something similar to I've also toyed with the idea of making a pull request for Godot to allow other physics servers to leverage the existing I would frankly prefer to be in control of whatever solution is used though, which is why I haven't chased this down, but it could very well be the more pragmatic solution here. Getting something like that in for Godot 4.2 at this point in the release cycle seems optimistic though, meaning we probably wouldn't see it until Godot 4.3 releases some time around March anyway, at which point I'm sure we'll have this sorted out anyway. EDIT: Thinking about it some more, relying on the existing |
As a side question, would making the physics server threadsafe make it also capable of doing the same kind of processing as with Unity Dots/ECS + jobs, etc regarding physics ? |
I'm not very familiar with how DOTS works, so I can't speak to any specific discrepancies, but from what I understand However, many of the interesting things you'd probably want to do from separate threads, like messing with a body's state or performing physics queries, can only be done through None of these limitations are inherent to the API though, and could be addressed by employing more fine-grained locking at an implementation level, but that's a scary task that I'm hoping to avoid by utilizing something like |
Hi! May I ask what the status of this is? Have the required changes to Godot been merged, or is there an issue on the Godot side that can be tracked? Also, I have discovered that when loading a scene containing physics bodies using |
I haven't worked on this at all yet, and I don't currently have any plans to. It's looking likely that this extension might get merged into Godot as an official module in a (hopefully) not too distant future, in which case thread-safety largely comes for free through Godot's own
It's almost certainly related. No part of the API is thread-safe and will result in errors/crashes/corruption when used from multiple threads at the same time, which I would imagine includes |
I would like to add a note about one aspect of threading that is a bit different from what Godot does with its MT wrapper. I raised this to mihe a while ago, but didn't post it anywhere: TLDR: I need to create mesh collision shape resources safely in my threads, and not have their baking be delayed to the last moment on the main thread. This is mostly independent of the physics server being multi-threaded or not. See also this older proposal in which I mention this. When generic collision support is enabled, my voxel terrain project requires to bake mesh colliders at runtime and frequently. Chunks get meshed in multiple threads my module spawns in its own pool to handle prioritised chunk tasks that can last longer than a frame. This shouldn't require to simulate physics on different threads, but it is very much desired that the creation of shapes can happen in these threads, because baking mesh colliders is even more expensive than the meshes themselves, due to a data structure (such as BVH) having to be built from geometry. In theory, even though I couldn't find this documented, I might be able to do this safely with GodotPhysics colliders, even if multithreaded physics is turned off (but at least set to "single-safe" so RID maps are safe), as long as I just do the baking of the shape resource, and I don't assign them to a body. This is because the creation and baking of the shape should be isolated from the physics world. I'm assuming Jolt supports this under a similar assumption (correct me if not though). But with GodotJolt, from the last discussion we had, it seems the shape's baking is intentionally delayed to the very last moment, when it gets attached to a body pretty much. This is very bad for my use case, because it pushes the expensive part down to the main thread and out of my control. Also, it generally prevents from loading scenes or shape resources asynchronously if they contain GodotJolt shapes. If changing this is still not planned, we also discussed that there could be at least an alternative way of creating mesh colliders using the PhysicsServer3D API: Side exploratory note: if Jolt can also make assumptions about the way the mesh is structured, that could be sent as an option to speed up baking: Transvoxel meshes have all their triangles constrained into grid cells, and vertices on edges of that grid, so unless the mesh is simplified with a MeshOptimizer pass, building a BVH could get simpler? Maybe the structure itself could be made into a grid instead of a BVH? If not, just ignore this for now ;) |
Yes, Jolt supports this just fine.
I know you're already aware of this, but for anyone in this thread who might not be, the reason I did it this way is due to how Godot deals with modified properties for scene nodes, where modified properties will "trickle in" one-by-one as the node is loaded, which would cause the shape to be rebuilt multiple times over. This applies when creating a shape node procedurally as well, since each property change will trigger the This is all made worse by the fact that there is no signal/call/whatever from Godot saying "alright, all properties are set, now commit those to the underlying shape", which means I don't have much of a choice (with the current API) but to defer building the shape until it's absolutely necessary, which is either when the shape's body actually enters a physics space (i.e. The worst offender of this is Another reason why I did it this way was because of the fact that these "trickled" property changes also mean you'll need to build shapes that are in intermediate states, which may or may not make sense to Jolt, and may or may not emit errors when building. This was mostly a problem with
This has been in the back of my mind since we last spoke about this, but I've hesitated a bit due to what I mentioned earlier in this thread, namely that this extension is likely to be merged into Godot as an official module, so I've tried my best to avoid introducing any API discrepancies that could make that transition more difficult. In my mind this issue would be one of several issues best addressed/discussed as part of that transition in some way.
I don't know enough about the inner workings of |
Unlike Godot's default physics server, which gets wrapped in
PhysicsServer3DWrapMT
to buffer and flush commands coming in from other threads, there is currently no support in Godot Jolt for calling the physics server from anything but the main thread.There are different ways this can be solved. Jolt itself has excellent support for interacting with its physics system from multiple threads, but sadly the code in Godot Jolt does not at the moment. The most realistic near-term solution to this is to take a similar approach to Godot Physics and wrap the physics server in another proxy server that buffers and flushes commands in a similar manner.
This also opens up for support of things like the project setting
physics/3d/run_on_separate_thread
.The text was updated successfully, but these errors were encountered: