This project has moved and is read-only. For the latest updates, please go here.

[Solved] Syncing Farseer over a network

Topics: User Forum
Sep 1, 2012 at 4:53 AM

I'm working on a multiplayer game and I would like to be able to use farseer for the physics.
The question is: Is it possible to sync 3 or more farseer worlds across a network where you can expect network lag of up to 200ms? If this is possible, how would I go about doing that? IE, what is the ideal networking model/architecture, and what functions would I use?

My base networking model is a client/server where the simulation is running on both.  I am sending the user input to the server, and back to all other clients as fast as it can go, and then just doing a sync event where the server sends out the position and velocity of all objects to correct for any drift or errors. Will this work with farseer and how? is there a better way of doing this?

Also, is there a document somewhere that just lists all the functions in farseer?

Thanks in advance.

Sep 1, 2012 at 11:15 AM
Edited Sep 1, 2012 at 11:16 AM

If you are writing a multiplayer physics game there is little doubt that clients that run their own simulations + authoritative server for syncing is a good model. If you haven't done it already I'd suggest you also have a look at the Lidgren library for UDP networking which is amazing overall and also offers some nice debugging possibilities like simulating bad network conditions.

There is a small variation in the communications strategy in the sense that instead of the classical velocity+position you could also be sending input commands (or rather actions) like player->StartMovingLeft(speed=2 m/s) and let the simulation process those. It's an interesting approach inspired by the Remote Procedure Calls programming and has some advantages although it's not yet adopted by the game community.

The syncing is the tricky part, though. Taking for granted that deterministic network physics is impossible what will happen if you just send a sync event every now and then is probably you game will stutter on the clients and be unplayable. It's a very very complicated topic. The solution has made the fortune of companies like Valve, Epic games and CCP. Check this for starters:

Sep 1, 2012 at 4:51 PM

I actually over simplified the description of my networking design. Heres what I'm doing:

I have a thread that is getting the user input on the client and sending it to the server, and the server processes that data for the local simulation and then sends that input data to all the other clients.

The server entity base class has an "age" which is just the time that it was last synced on all the clients. This is slightly randomized at the start of the simulation on the server (to prevent a large lump of updates at one time. The server then "syncs" all entities that have not been synced within the last 200ms.

On top of the "age" the server also tracks the entities that are within a particular area around the players and only sends them updates (with the 200ms age) for the entities that they may actually see. All the rest are only updated at something like 500ms, or perhaps more (still havent finished implementing all these systems so some of this is just theory).

I am in-fact already using Lidgren, its a fantastic networking library.

So I suppose my questions are:

1. When one of the entities needs to be updated, can I just pass the velocity and position of a particular physics body and update it without screwing up the physics simulation?

2. how do I prevent the client simulation from running faster than the server simulation? or slower for that matter?

3. Can I add shapes to a body at runtime?

Sep 1, 2012 at 10:55 PM

1. You should have no problems updating velocity and positions as long as the simulation is valid (no teleporting into rigid terrain causing interpenetration, updating all bodies linked with joints with the same transform etc.) 

2. Use a fixed time step (which you should be using anyways regardless of anything).

3. You can add and remove fixtures at will. A fixture is a collision perimeter described by a shape. Again be careful with unphysical situations like interpenetration - deep penetration into the terrain might be difficult for the solver (at least it is in my simulations against edge shapes and connected bodies with joints).

Sep 3, 2012 at 3:30 PM

I'm also doing gameplay over network with Farseer Physics and I am doing it by updating the position to the server when it changes on the client's side. The server then takes this packet and relays it to other connected clients. And also when the server player's position updates or anything that requires updating updates, he then broadcasts this info to the others. 

The packets only contain positions for me, no velocity. This has worked fine thus far, except for one part. When a new player connects, the server serializes the world and sends the info over the network to the connecting client. The serialization itself causes bodies attached with joints to "wiggle" around, causing them to jump about and stuff. Apart from that, the idea of updating positions (and velocities?) over the network works fine. 

Oct 23, 2012 at 10:04 PM

Hi, I am doing this too. I have reduced the wiggling by simulating my network updates in a modified farseer sample project. What I did was run the simulation on the object I wanted to synchronize, and then 'teleport' it to a location I selected with the mouse, along with a rotation. Wiggling ensued, so I ran through the simulation frame by frame to find out what happened. What I found was that my synchronization calculations weren't perfect causing the model to be completely invalid for a frame. Farseer then tries to make the model valid again, solving all joints, this results in forces which cause the wiggling.

Now, my model still wiggles, and I am still in the process of resolving this, I suspect I don't deserialize the joints properly still. Sadly other problems have taken priority in the project so I haven't worked on it for a while. I think jerrysb was working on this as well, does your comment mean you succeeded at this jerrysb?

Anyway, I am very interested in wether either of you manages to deserialize your worlds without wiggling. I myself will post my results too when I get back to it.

Oct 25, 2012 at 1:14 PM

I think there are two parts of this issue. First of all deserializing a complete world could cause jitter/wingling/instabilities or better let's call it some time to reach equilibrium because of some caching information that is not serialized (warm starting) and the order of updates (the solver processes each object one at a time so the order is important). But this is solved by simply running the world for a few steps until it reaches equilibrium.

In a network game deserializing the whole world is impractical and unnecessary. The wiggling is harder to solve when using transforms+velocities. I'm no expert but I think it's also because joints are soft and obtaining stiff joints is quite a difficult theoretical problem for the solvers. I don't see how this could be resolved without gradually teleporting the articulated objects so that the corrections are small per time step and therefore imperceptible. This will require interpolation and not just teleporting. The new box2d has a motor joint in svn that Erin Catto recommended:

P.S: In my simulation I try to have very rigid joints (which leads to some very complicated constructs). Also I try to have as little DoFs as possible (e.g. sticking 2 revolute joints with different anchors, playing with mass so that one body acts as a "director", using kinematic "ghost" bodies). This is a very custom solution not generalizable especially because more joints means slower processing. But before complicating stuff one should make sure the sync code is free of bugs and everything is teleported properly as an island with no distortions in the local frame. One could also let the world step for a bit before updating graphics after a teleport treating the articulated body as a single rigid construct before switching to a finer level of detail.

Oct 28, 2012 at 10:39 PM

Today I finally succeeded in making my networked game wiggle free. Or at least, there's no perceptible wiggling anymore.

So as I mentioned before, the issue turned out to be with the joints. I discovered the revolute joints carry a lot of state which I did not serialize.

The simulation I am running is that of the topview car, so a box with four wheels, two of which do steering. The steering wheels used revolute joints do rotations. Since I did not require very accurately simulated steering, I did something a bit hacky. Instead of synchronising the revolute joints, I replaced them with weldjoints, which carry no state worth mentioning at all. I then modified the weldjoint to have an accessible ReferenceAngle setter.

The steering is now done by directly setting the ReferenceAngle of the joint. I synchronize the reference angle, and now there's no missing state and the simulation is very accurate, no jiggling anymore :)

I am so happy with this :P