Farseer real-time networking and Body::Position

Topics: Developer Forum, User Forum
Feb 2, 2014 at 6:37 AM
Hi there, haven't found any viable info on the matter. I need to implement player movement prediction on a Body object and i think i've done it, but the problem is that it's not 100% accurate and sometimes i need to correct player position according to data from server.

If i use only Body::ApplyForce() and Body::Rotation all looks smooth but when i'm trying to set Body::Position movements seems to became jerky. I'm not quite sure am i doing smth wrong with Farseer logic when i'm trying to set position manualy or it is possible prediction algorithm bug?

If anyone had done similar task before please let me know of your experience, thanks.
Feb 2, 2014 at 1:35 PM
Edited Feb 2, 2014 at 1:37 PM
Not sure if this is will help in your situation but we're also making a networked game using Farseer. We've tried a few different approaches and so far the one that works best is to send input changes whenever they occur and on the remote peer, apply the resulting forces to a ghost body. Then, the player state is networked periodically (eg every 2 seconds) and the ghost body will pop to the new position (plus velocity * latency for prediction). The actual body is always moving towards the ghost body but not faster than the some maximum speed. This gives you some smoothing. We're still working through some problems, but it seems to be a decent solution.
Feb 2, 2014 at 4:27 PM
Thanks for sharing :) I've managed to upgrade prediction logic to get +/- smooth movement. I've used Valve approach (link below) and also added additional interpolation cycles during the dead times when i got no data packets from server. Currently i send velocity and position. Velocity is mainly used to additionaly smooth movement in dead time intervals.

Honestly, i don't realy get it if it will be better to work with user input too. I have some objects being moved by ApplyForce() while holding the button and if i just send button press/release events i'll also need to take prediction into the acccount. For ex., if got key release event with 200ms lag i need to cancel the effect for the velocity back in time for ~200ms. Not sure how to cook this stuff. Always had problems with physics :(

I think the additional interpolation i've implemented is somewhat similar to your ghost body logic :) As i've understood correctly you use that body as the main collision/position checker and rendered sprite is always trying to smoothly sync with it?

Also, currently i'm managing non-player controlled objects collisions on the host player machine and send the force/position to everyone on contact. I'm not sure that this is the right way to do so and haven't looked at this yet. If you have some ideas to share on this i'd be happy. I'm not sure if this is correct approach to spam forces/position updates for all objects.

https://developer.valvesoftware.com/wiki/Source_Multiplayer_Networking
Feb 2, 2014 at 10:39 PM
The problem with the key release events is a tricky one that we are still trying to solve. I think you will have the same problem just sending position and velocity... If the player stops just after their state is sent, the remote peer won't know until the next state is sent, by which time they've moved the avatar along.

Our ghost body is not actually used for any collision events - those are still based on the main body which lags behind. The ghost body does collide with terrain though to avoid moving into walls.

Not sure about networking general physics objects yet - that's something we don't have much of so we've not tackled it yet. Your idea sounds reasonable, but I'd worry if there were more than a few active that the bandwidth would rapidly become a problem. The alternative is to run the physics on all peers and try to keep them in sync, which also sounds challenging!
Feb 3, 2014 at 6:04 AM
Possibly you can solve release key event as i did for velocity and position by storing finite number of object states with the timestamps so when the command arrives you can track back approx state that corresponds to message delay and reset object into the interpolated position between current and stored states. Back in time technique :)

The bad thing that as i see it is nearly impossible to identicaly simulate physics on all clients so position pings are necessary making the system more complicated.
Feb 5, 2014 at 7:38 PM
Now i've got the point for the ghost body in the input send mechanics. Trying to implement the system you told me about right now :) Currently i have no ghost body implemented and i'm trying to sort out how to better implement it. Can you please tell me more about ghost body logic?

Do you use any state buffer for the ghost body movement prediction or just apply the position?
Do you allow client to calculate physics or just maintain ghost body position?
What else problems you had encountered while implementing this stuff?

Thanks.
Feb 5, 2014 at 9:50 PM
Keep in mind that our ghost body approach is not well tested. So far it seems to work ok but we don't have many dynamic bodies other than the players and they only really have physics interactions with the terrain... Also gravity does not affect them.

We send input changes continuously and input state periodically in case of dropped packets. We also send pos and velocity periodically, currently every 2 seconds.

There is no state buffering. The current input state ends up as a force which is applied to both the player and their ghost body. When the periodic pos and vel come in, they are used to pop the ghost body to its predicted position taking into account the latency. The actual player body has its position changed to make it smooth towards the ghost body over time.

So far the major problem is that the remote peer will see a network player smooth backwards to the static position every time they stop moving. This is due to the latency and prediction assuming they'd moved further than they had. It's worse when the input change that stops them gets dropped because then they must wait on the periodic input state message.
Feb 17, 2014 at 8:01 PM
Edited Feb 17, 2014 at 8:02 PM
Have you managed to get the things to work as you want ? :) I've currently stumbled with networking, movement seems jittery even with smoothing... not quite sure where is the problem but all this stuff is blowing my mind.

Btw, how do you compensate latency for moving object on the server when key input is received with the delay? Currently i'm setting Body::ApplyForce() number of times in a cycle dependant on latency, for ex. 200ms latency / 16.6 msec screen rendering == 12 times i should apply force (assuming that the acceleration key was pressed all the time). But i'm not sure if it is equivalent to call Body::ApplyForce() each cycle and 12 times in one cycle. And i'm not sure how to correctly not take any actions, eg. slowdown due to dampering same 12 times...

PS: Currently i'm calculating physics on both server and client. Server physics is used for sync (sending pos and velocity every 50ms).