How to make cars position syncronization on clients in 2D multiplayer racing game?
Members - Reputation: 100
Posted 22 August 2010 - 12:43 AM
I make a 2D multiplayer racing game. The target is to make it work when clients connected to server via internet connections with different latency up to 300 mls.
One game has 10 active players maximum.
For now it works as described below:
Control keys presses are passed to server. Physics and cars positions are calculated on server and the state or the hole race is passed back to clients. So the clients only show the
situation on server. The inet protocol is TCP.
Now the problem is how to make all clients show the same situation at the same moment. Keep in mind that one client can be connected to server via LAN with ping <10 and others may be connected via
hight latency internet connection with variable ping from 100 to 300.
And the second problem is: The hardest thing that I should syncronize _physics_.
We get some kind of situation snapshot from server and till next snapshot I should guess how car will be moving. But physics calculations has errors (small differencies due to tolerance issues in calculations and so on) and these errors
are getting bigger with time, so when we get next server snapshot the car positions may be very different.
May be someone could point me at some kind of good example or game in sources or book which describes main problems and solutions for such kind of game?
Any suggestion or samples are welcome.
Members - Reputation: 216
Posted 22 August 2010 - 08:23 AM
- packet ordering and guaranteed delivery might delay packets.
UDP drops packets but you can have your game compensate these drops especially in physics.
you should really read:
Moderators - Reputation: 6734
Posted 22 August 2010 - 09:06 AM
For example, if a player locally detects that he collides with another (forward extrapolated) player, you may be able to do local physics, and add lots of smoke and camera shake, and if the remote player doesn't detect that collision, it's not very noticeable to the local player.
You should google for "Shawn Hargreaves" and "MotoGP"; he wrote a few posts on how they did this back in the day (when the internet was slow :-), on the XNA forums, which may give some more insight.
Members - Reputation: 154
Posted 22 August 2010 - 02:14 PM
hplus0603 touched on being "fair" and with a 2D top down racing game this can be difficult when it comes to the start finish line and close races.
If you're going to be using interpolation (or a lagged updated) as the primary method to smooth out visible jitter then you have to consider how far a player can move for that time period and if that will make a finish appear to be unfair. For example if the permanent lag is set to be 100ms this might mean a player at top speed (usually the case over the finish line) is displayed on each client as eight pixels behind where they are in reality. So with a close finish a local player could see themselves something like four pixels slightly ahead in first place only to be told by the server that they were in second place. The server should always be the one who decides who really won a race, of course. :) Even in a peer-to-peer network game there is usually one authoritative client (i.e. the "server" or the game session creator) who gets to decide on something really happening. Even if that client only has the job of asking all other clients who they though really won the race and taking a "vote" then distributing that result to others.
Without any interpolation (without permanently lagged updates) then you're using extrapolation, which can produce slightly more jittery movement for poor network connections. This is because packet updates can arrive with jitter, the network layer will then apply these updates as and when they arrive. With some permanent lag (interpolation) the network layer has a chance to apply these updates with some buffering smoothing out the rendered positions.
I think some balance between interpolation and extrapolation will be needed. For example in my object update system with class members having update filters, the floating point type updates are detailed here, you can choose between using some permanently lagged updates then setting the extrapolation filter to smooth out jitter beyond the lagged time. You can then use GetLatencyToSessionID to tweak the amount of interpolation used depending on the network latency to each client. This means if you're lucky enough to have good connections to other clients the game will appear to be more fair and if you have bad connections then at least the other clients will not appear to be so jittery with their movements. Using such a system means it is easy to tweak numbers to use various already tested models for object movement.
I would also suggest not using TCP, this can lead to horrible bunches of updates arriving very late. Instead use UDP which can fire out updates and it doesn't matter if one position update packet is lost since another newer update packet will be along quite quickly.