Advice on Networking Physics State between Client/Server

Questions about the LÖVE API, installing LÖVE and other support related questions go here.
Forum rules
Before you make a thread asking for help, read this.
Post Reply
User avatar
ArchAngel075
Party member
Posts: 319
Joined: Mon Jun 24, 2013 5:16 am

Advice on Networking Physics State between Client/Server

Post by ArchAngel075 »

Hi all, i frequent here alot, I have posted a few times some bold ideas (that have fallen away)
I am attempting a new approach to game dev - one that is slow and tedious instead of fast and buggy.

Currently i Used the Hardon Collider library to do phsysics, but have run into issues with it and since swapped to using Love2D Box2D library.

I use Socks for networking, i use a system that declares a network entity 'dirty' on the server - which results in a message to clients about the state of that entity. Clients replicate Entities locally - this plus Remote calls (server->client or client->server) allows for some pretty good sync between peers. Finally i ensure i reduce information where possible - ie i attempt to not send info that can be inferred from time (such as say a food items decay) and also i with-hold info sent to clients based on importance (a client will know a inventory holds X items, but until needed it does not know more about those items)

Currently moving to love.physics has worked well aside from syncing the client and server -
I am using socket.gettime() and a timestamp between love.update calls as a dt - it is more reliable i find.

HERE is how i sync physics states at present :


1. Server and Client creates a physics world local to itself.
2. Any time a client receives a currently unknown physics entity it creates it locally and applies the state change to it -
3. If the client receives a state for something it knows about it applies the changes
4.what is applied in a state to a physics entity is
position in world (x,y)
linear velocity (x,y)
angle (r)

Thus the server forces a state over what the client has for that entity on position, linear velocity and angle.
The client then continues to use the socket.gettime() method to calculate dt and perform its local world:update(dt) call
the server does the same.

5. The server - each time a collision begins or ends using World Callbacks the entities involved are set to 'dirty' and will send new forced state within that frame or the next to clients.
6. Thus it should be correct that clients will update themselves to what IS the servers physics world and can continue to update their own local physics world.

7. The REASON for this method is to avoid needing to send location, angle and velocity data constantly for many physics entities to many many clients (the less messages sent the better)

Sadly this seems to result in some wonky physics state for clients, two clients see things differently still - im not sure as to how or why this happens. If anyone has advice please share their approaches to syncing physics entities between a master server and many clients.
User avatar
ivan
Party member
Posts: 1911
Joined: Fri Mar 07, 2008 1:39 pm
Contact:

Re: Advice on Networking Physics State between Client/Server

Post by ivan »

This is a complicated problem. You might be able to pull it off with a few dynamic bodies, but don't expect a general purpose solution.
Are you passing the angular velocity too?
Generally speaking you need
1.position & velocity
2.angle & angular velocity
For joints it gets more complicated.
Ideally you want to pass just the input, instead of detailed state information.
Personally, I would start with client/server determinism.
This way you can "replay the input" on both machines and achieve the same end result every time.
But yea, synchronizing Box2D is a difficult problem.
User avatar
pgimeno
Party member
Posts: 3544
Joined: Sun Oct 18, 2015 2:58 pm

Re: Advice on Networking Physics State between Client/Server

Post by pgimeno »

ArchAngel075 wrote: Mon Oct 22, 2018 1:41 pm The client then continues to use the socket.gettime() method to calculate dt and perform its local world:update(dt) call
the server does the same.
This is a major problem. If you want the same physics, the clients must use the same dt as the server. Even then, there's risk of desync due to differences in how the platforms treat floats (especially with trigonometric functions and others, which I'm sure Box2D uses internally; also, I'm not sure if Box2D is compiled in a way that enforces usage of IEEE-754 semantics for the basic operations).

If the server and the clients use the same binaries and the same kind of computers (Intel family, for example), numeric drift is less likely to be a cause of problems. It's also possible, however, that there are differences between OSes, if the C++ library used to compile Box2D is lax about rounding modes and flush-to-zero/denormals-are-zero flags, and the OSes have different defaults for these flags.

See https://gafferongames.com/post/floating ... terminism/ for an article that explains the issues with what you're trying to achieve.
User avatar
ivan
Party member
Posts: 1911
Joined: Fri Mar 07, 2008 1:39 pm
Contact:

Re: Advice on Networking Physics State between Client/Server

Post by ivan »

Yes, using a fixed time step would be a good starting point anyways.
pgimeno wrote: Mon Oct 22, 2018 2:12 pm I'm not sure if Box2D is compiled in a way that enforces usage of IEEE-754 semantics for the basic operations).
No, Box2D is NOT deterministic across platforms. But this would be just one small part of the problem as a whole.
Post Reply

Who is online

Users browsing this forum: No registered users and 53 guests