0
\$\begingroup\$

I am new to game networking.

In various articles on the internet, I found that there are usually two loops on the server: one for physics updates and the other for sending snapshots to the client (network updates). As I understand, loops can run in parallel, which makes me think they should run on different threads.

Now, in terms of concurrency, physics thread is the writer and the network thread is the reader. Given that the threads can run concurrently, there can be race conditions: reader thread can read inconsistent game state if the writer thread is currently modifying it.

How to deal with this race condition? The crude approach would be just to use lock on the game state, but it seems to me that this will introduce delays. For some reason I can't find anything on the web.

\$\endgroup\$
5
  • \$\begingroup\$ Once you're done with a simulation step, you copy the state to a buffer, your network thread reads the buffer. \$\endgroup\$
    – Vaillancourt
    Commented Jan 6, 2021 at 21:23
  • \$\begingroup\$ @Vaillancourt , this solution has two disadvantages: 1) copying full game state or even game state delta might be time-consuming. 2) "simulation step" usually called much more often (15ms for physics, 45ms for network), which also brings ineffectivity - you make three copies in 45ms and two of them will not be used at all (i.e. sent to client) \$\endgroup\$ Commented Jan 6, 2021 at 22:29
  • \$\begingroup\$ 1) Okay, how long does it take to copy the state? 2) Then do it once every 3 frames? \$\endgroup\$
    – Vaillancourt
    Commented Jan 7, 2021 at 1:18
  • \$\begingroup\$ 1) Not so long (maybe about 0.1-0.01 ms for each player), but looks like it increase frame processing time at least twice. 2) Loops can easily came out of sync, so this will still introduce delays (I suppose). Summing up, your suggestion is the best solution I found, but it still has disadvantages. I just hoped there exists solution without disadvantages :) \$\endgroup\$ Commented Jan 7, 2021 at 9:08
  • \$\begingroup\$ I've made the comments into an answer. You can wait and see if some better approaches come up from other users if you feel like it. \$\endgroup\$
    – Vaillancourt
    Commented Jan 7, 2021 at 15:10

1 Answer 1

1
\$\begingroup\$

One option is to copy the state to a buffer after each simulation step. This operation is typically not that time consuming when compared to performing the step per se. The network thread then consumes this static buffer instead of the main game state.

Given that the simulation step is done 3 times more often than the network step, one could think about only performing the "copy-to-buffer" step only once every three step. Although this could save some time in performing the copy, you could get introduced delays when the network thread waits for a fresh version of the state buffer. You'll need to experiment with your setup to see if the delay introduced by the thread waiting is ultimately more expensive than the delay introduced by copying the state every frame.

\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .