Open vgnod opened 1 year ago
See https://github.com/godotengine/godot/issues/60625 for an example of this situation.
cc @lawnjelly
No expert at this here, and as for the core source code, there are plenty of examples of bad "gets" from the servers which should not have been implemented in the way they are. I'm loathe to write documentation, having only a little reverse engineered knowledge from the system.
As I understand it, the servers are written to be potentially run on a different thread than the scene tree, and communication between the client (scene tree etc) and servers takes place via a command queue. That is you push commands to the queue, and they are executed in order, but not necessarily at the same time you posted them to the queue.
This is the typical model for graphics APIs such as OpenGL. You feed the pipeline, and it gets done at a later time when makes sense for the server.
This works great for code that just pushes commands to the command queue. The problem comes when you have want to read some info back from the server. If you try and read something back, you can then potentially create a stall whereby it has run all the pending commands in the queue to catch up to the point where you read some data. This can potentially be very expensive, or cause a hitch / dropped frame etc.
So in general the data flow should be one way from the client to the server. Wherever possible reading back should be designed out of the API. If it has to be done it should be extremely carefully and should not be used in regular use except via mechanisms specifically for this purpose, such as sync points (e.g. physics), or deferred callbacks (where the data to be sent to the client is posted back by a deferred thread safe queue, see e.g. VisualServerCallbacks
in 3.x). The exception tends to be for things like loading level data, where the stall is just expected (glitches during loading a level are not necessarily a problem, unless say streaming).
Another alternative is to keep a copy of state client side, or duplicate processing client side, precisely to prevent stalls. The physics interpolation does this for instance in the get_global_transform_interpolated()
command, which would otherwise cause a stall.
Thank you for the reply. Well yes, something less vague than current description must be made by developers who work with the servers, and probably that will not happen any time soon. However, i think at least physics server's sync should be explained. It's basically
PhysicsServer3D::get_singleton()->sync();
PhysicsServer3D::get_singleton()->flush_queries();
if (OS::get_singleton()->get_main_loop()->physics_process(physics_step * time_scale)) {
exit = true;
break;
}
PhysicsServer3D::get_singleton()->end_sync();
Is there any caveats? If no, it can be mention in the docs that during _phycics_process it is safe to call the server. There is space and body direct states and technically they are part of the server i guess, and we use it freely.
Your Godot version: 3.5, "latest"
Issue description: In "Optimization using Servers:
What kind of knowledge is needed? Is it possible to make instructions containing said knowledge? If not, where one can educate himself? What system or peace of code should one explore to gain that knowledge?
Built - in functions often get data from servers each frame and multiple times a frame. What's the difference between build in function's calls to servers and user code calls? If there is some sort of system for proper arrangement of this calls, can it be accessed? If not, why? If there is no such system, can preferred call patterns be found in code, by exploring built in functions? Is it good idea to use their call patterns as reference?
URL to the documentation page (if already existing): https://docs.godotengine.org/en/latest/tutorials/performance/using_servers.html https://docs.godotengine.org/en/3.5/tutorials/performance/using_servers.html