Networked physics with Farseer & Lidgren

In addition to SCP-CB v.1.1, for the past few weeks I’ve been working on the networking part of Subsurface (physics in particular). It turned out that the way I’d implemented framerate-independent physics made it almost impossible to keep the networked clients in sync, but after some modifications everything seems to be running smoothly even with high latency.

Previously I was using a variable timestep, which basically means that if the game is running at 50% of the preferred framerate for example, we’ll just move everything twice as fast each frame. This worked somewhat acceptably in single player mode, but the problem was that the behavior of the physics simulation wasn’t 100% consistent on every framerate. As the framerate dropped and the timestep increased, the physics and the animations of the characters started to get a little “off”, and with a large enough timestep, the physics joints would just go crazy and the characters would basically explode. The physics seemed to work fine on framerates above ~25 though, so I just limited the timestep so that the game doesn’t try to compensate the dropping FPS too much and break the physics.

When I started testing on syncing the physics between a server and client, it turned out the variable timestep just doesn’t work. Even though the physics looked consistent on framerates above ~25 FPS in the single player mode, the slightest differences between the two simulations would cause them to get out of sync. An item hits the ground in a slightly different angle in one of the simulations, bounces off to a different direction and ends up in a different place than in the other simulation.

After some googling I found this fantastic article about fixed timesteps. The technique described in the article wasn’t hard to implement, and now I have a physics simulation that behaves the same no matter what the framerate is.

I took some shortcuts and simplified the way the physics are synced between the clients. The characters or any other physics objects that can be manipulated by the players don’t collide with each other, and this isn’t an FPS game where it can be crucial if a character is “actually” in a slightly different position than it appears to be on your screen, so I decided to skip latency compensation altogether. This means that the server and other clients are always a little behind a client controlling a character (you can see it in the second half of the youtube clip below). As there is essentially no way for a client to collide with or otherwise manipulate any of the other clients, at the moment it doesn’t make much difference. The only case were it could be noticeable, would be if two players were trying to pick up an item at the same time: it might look like you picked it up first, but actually the other player was closer to it and his key press arrived to the server before you, in which case the item would be pulled from your character to the other one as soon as the “player 2 just picked up that item (not you)”-message from the server arrives.

There will be various weapons (or tools that can be used as weapons) in the game though, so this kind of simple system might turn out to be insufficient in the future in which case I’ll have to implement some kind of latency compensation, but atm it works great!

 

Subscribe to our newsletter

Comments

  • February 2, 2015
    reply
    juanjpro

    How do you handle packet loss? Does the server trust the players (i.e. allow them to apply arbitrary forces to themselves) or does it perform actions based on keypresses?

      • February 2, 2015
        reply
        juanjpro

        I read that Lidgren supports optional packet reliability, maybe you can make pickup-packets reliable to guarantee that players will pick up items if they try.

Post a Comment