I've been writing an MMORTS game that's a 2d top-down space shooter style game. We have multiple players that can shoot bullets and fire at each other, it's pretty spiffy. Farseer is amazing for what we're doing and I'm so glad we didn't have to code all
of this ourselves! We tried... But when we started getting into Einstein's theory of relativity to solve gravity and light speed related equations... yeah. I don't know how the devs here do it!
So, what we're working on right now is a client-side prediction algorithm that we can use to close the gap with latency. 100-250ms latency is a case that I know will exist pretty normally, and having an algorithm that can cleanly predict player movement
will be very nice.
Our game has every client running it's own physics simulations. (we'll change it later) Each client sends the server it's position and the server relays this to all other clients. My question can be broken into two sections.
Section 1 - Non-Jittery Movement:
- Clients are updated between 16-24 times per second depending on load
- Rate of update is not high enough for 'smooth' stepping of each player
- Need basic algorithm that hides the movement time between each step
Each Message that the client sends/receives contains:
That looks much better adding velocity, but it's still bad. I was thinking a simple check that prevents the classic 'rubberbanding' effect in most cases. Here's some pseudocode of what I'm thinking.
- every ship on every client is located at some currentPosition and
moving at some currentVelocity
- define 2 radii around every ship: smallRadius, mediumRadius
- then say a message is received with another player's newPosition and
newVelocity, do the following:
(1) if the other player's currentPosition is within smallRadius of the
newPosition in the message,
then leave the ship where it is and set currentVelocity = newVelocity
(2) else if the other player's currentPosition is within mediumRadius
of newPosition in the message,
leave the ship where it is and set it's velocity to (newPosition -
currentPosition) to make it move to where it should be
(3) else if the other player's currentPosition is outside both radii, then
teleport the ship to the newPosition and set the currentVelocity to
Has anybody tackled this problem before here, and does this look alright?
Section 2 - Time Sync Between Clients:
- Clients add LocalTime to Update Message
- We calculate the time in the message and the current time
- We then step the object to it's projected position based on that information
This would be taking the time difference (latency) between the clients and predicting the future physics simulation of that object. My problem is that I don't know how to step a specific object forward in time inside of Farseer. I don't want to do a World.Step()
because that would update all objects, and that is the opposite of what I want.
Has anybody had to do this before or something similar? A check around the board here didn't reveal anything. Does anybody have any suggestions or talk a bit about how they perform their network-physics management?
Thank you guys!
P.S. For more info of what I'm doing, check the screenshots on my blog at http://spacerambles.com/