RPC thread safety across peers...

Godot Version

v4.4.1.stable.mono.official [49a5bc7b6]

Question

I’ve looked everywhere, but I can’t find the answer to what feels like an important question about the fundamentals of RPC. Almost every example I see uses RPC to manipulate some state. It all seems super easy and intuitive to use. However, I don’t see any documentation that answers…

Is RPC threadsafe? No, I don’t mean spawning threads in the engine itself. But what happens if client 1 and client 2 make the same RPC call at the “same” time? It’s unclear if every single RPC call that mutates state needs some external mechanism to prevent race conditions. All of the examples make it seem fine to have an RPC call that increments a counter or changes some dictionary.

Does Godot queue RPC requests somewhere to ensure that only one thing is touching state at a time? Or are all of the examples just meant to be toy examples (nothing wrong with that), and the real use case requires a read-write lock or something?

“Thead Safety” is different from avoiding race conditions. RPCs are queued up as any networked packet will be, then polled one by one on the main thread like any other function. So no mutexes are needed to use RPCs. Did you run into any problems yourself?

UDP focuses on speed so packets can be easily dropped or arrive out-of-order, if you want to guarentee a RPC you can use @rpc("reliable"), but this is certainly slower than unreliable methods. Surprisingly most functions are perfectly suited to unreliable communication! Anything with regular updates is fairly resilient to the odd hiccup, such as tracking player movement.