7
\$\begingroup\$

I want to serialize the state mid-game, send it over the network to an identical computer (same CPU, same OS, same binary), load it there, and have the two games run in tandem doing the exact same simulation, without one of them drifting off and going haywire.

In short: I want pop-in, pop-out networking support on my HIGHLY physics-intensive game, where sending object coordinates every few seconds is impossible, due to having thousands of objects, and many clients.

I tried this with Box2D, and saving an object's location/velocity/etc wasn't enough... there's internal state that's not accessible through any public methods.

My current workaround is to force EVERY client to save its entire worldstate and reload it from scratch, whenever a new player connects... but this is obviously bad practice, because it hangs the game for everyone whenever someone new connects. However, it works, with zero desynchronization.

So, anyone know of any other techniques that can help me? Or should I just kiss my project goodbye?

\$\endgroup\$
6
  • 2
    \$\begingroup\$ Interesting question, but asking for an engine is probably off topic. I would re-word it to simply ask "how do I fix this?". If an engine ends up in the answers, that's not a problem. \$\endgroup\$ Sep 12, 2013 at 17:00
  • 1
    \$\begingroup\$ You wouldn't have to scrap the project, just the pop-in support. Maybe you could have checkpoints along the way? Places where the game would pause to allow new players to join? This would at least be an expected pause. Related: gamedev.stackexchange.com/questions/8619/… gamedev.stackexchange.com/questions/53887/… gamedev.stackexchange.com/questions/13789/… \$\endgroup\$
    – House
    Sep 12, 2013 at 17:11
  • \$\begingroup\$ Limiting times when users can join is definitely an interesting idea that I hadn't thought of... and I'll probably use it to improve my ugly workaround a bit. But an ugly workaround is still an ugly workaround, no matter how you squint at it. \$\endgroup\$
    – Whyte
    Sep 12, 2013 at 19:24
  • \$\begingroup\$ I came to same solution with JBox2D. I rebuild the world from scratch on each client when a new client joins, and it also works for me with everything staying synchronized. So far I'd pushed worrying about this into the future if/when it became a problem, but I'm glad you asked this question. Sorry I'm not more help! \$\endgroup\$ Oct 3, 2013 at 19:40
  • 1
    \$\begingroup\$ Here's one idea: what if you rebuild the world from scratch in the background a few objects at a time per update loop. Then when you're ready to switch over you play any commands that occurred from the start of the rebuild to now (to catch the new build up to the present state) and then switch over. It's possible you'll see a small jump from replaying the commands to a slightly different physics state but it shouldn't hang the game while you rebuild the world at least. Even that could be lessened with interpolation. \$\endgroup\$ Oct 3, 2013 at 19:58

3 Answers 3

0
\$\begingroup\$

You could try https://rapier.rs/ instead of box2d, it has the ability to take a snapshot of the world and send it as a hash string over network to produce the same physics results on both clients

\$\endgroup\$
1
  • \$\begingroup\$ Heh, yeah, very old question but I agree. I'm actually already donating a bit to the project, dimforge is awesome. \$\endgroup\$
    – Whyte
    May 14, 2022 at 15:26
1
\$\begingroup\$

I've faced the same problem (synchronizing box2d worlds for browser clients with world on node.js server) and my resolution: synchronozing box2d worlds on the fly - impossible. So I've cut off all physics from clients, and now they are receving discrete timestamped positions of objects (and some events) from server (which is running box2d) and interpolating between them. Box2d uses values generated on previous steps to calculate nex step, so you need go deep under the hood to make box2d network-compatible.

\$\endgroup\$
2
  • \$\begingroup\$ That's the usual approach in games, and the one I considered first... but it's not possible due to the huge amount of items that are physically active, and because of how fast things go completely different in my simulations (an object would bounce in a completely different direction in less than 0.5 seconds of the last synchronization). \$\endgroup\$
    – Whyte
    Oct 3, 2013 at 18:11
  • 1
    \$\begingroup\$ May be you could try to use update rate less than 0.5 seconds? In my case update rate is 45 ms and it's working pretty good through websocket. Huge amount of network traffic could be reduced by compression and transmitting only position deltas. Also some parts of physics can be implemented on client for immediate reaction for user input or some advanced interpolation (non-linear) can be used. \$\endgroup\$
    – Zuker
    Oct 4, 2013 at 8:35
0
\$\begingroup\$

Run your simulation on the Server, send Clients timestamped object state updates (delta-compressed) at a fixed rate, send other game event messages as they occur, and let Clients deal with interpolating/extrapolating between network state updates. You don't need to send updates for all objects in the game, to all clients. Simulate the player camera frustums (3D) or view rect (2D) on the Server, and choose your preferred spatial partitioning algorithm to determine which objects a given client can see, only send updates for what a client can see. This will put more load on the server cpu, but will reduce network band on the server to something reasonable.

\$\endgroup\$

You must log in to answer this question.

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