Synchronizing a ball in my pong game

Started by
8 comments, last by theonecalledtom 16 years, 1 month ago
I know I've seen this topic before (Synchronizing data) but for the life of me I can't seem to find it... Anyways, quick scenario, I've got my pong game networked and working fine except for one issue. The server starts a little while ahead of the client, the server calcs where the ball is and sends it after every move. The client starts late and receives a bunch of old server data, so the ball on the client basically lags behind the server. What's a good way to synchronize the balls, I was thinking it would be nice when the client finally joins to flush the receiving queue... can this be done or is there a better way?... anyways, any advice on a good way to get these sychronized would be appreciated... I'm using sockets in VC++2008... Thanks, Vanz
Advertisement
Typically, you will use some form of extrapolation based on the server data. If the server says "at time X, the ball was at position Y moving with velocity Z" then you can do dead reckoning on the client to put the ball where it "ought" to be at the current time.
enum Bool { True, False, FileNotFound };
you are starting to delve into the world of ping and client-side predictions. if it takes 100ms for the data to get to the client no amount of flushing of anything will change the fact that your client will forever be 100ms behind the server, so therefore your client needs to account for the fact that it's behind and calculate the ball position 100ms from where it was last told it was and then let your client run its simulation of the current environment until the server gives it more information, then recalc again.

Really there are at least 2 versions of your game happening. The server has a version which is the judge jury and executioner, and you have your client version which also runs it's own code but doesn't make any changes to anything important and only takes a guess as to where things are situated and their current position etc etc... and when the server sends out a message telling your client some new piece of information your client then updates it's own version of things and takes into account the lag and so on.
hmm, okay thanks nb, so I have my client calc how far ahead, like 3 or 4 game loops, or does it depend on the ping...i.e ping=120ms, game loop=30ms, calc 4 loops in advance I guess... then when I get a new packet of data I calc again 4 loops in advance every single time... Seems like a lot of calculaing per ever piece of info, may be going 8-10 times in advance per every game loop. For pong it's no big deal but for moving an army of elves I could see a prob...

You have any good articles/links on this? Has this got a specific name? I'll start googling "client-side predictions"...

Thanks guys...

rh
I don't know about your "calculate n loops in advance" but a little suggestion for your Pong game:
- Your server sends to the client: ok at time t, the ball was at (x,y) and its velocity was (vx, vy) (in pixel/seconds).
- Your client receives that message, then it knows that between its internal time and the message time, the elapsed time is dt seconds.
- Your client draws the ball at (x+vx*dt, y+vy*dt).

Is that applicable to your game ?
There are a few different ways to solve problems like this. For predicting ahead for pong, it's no problem to use (x+vx*dt, y+vy*dt) like Splo said, as long as you check for collisions with walls and paddles. This only works because the ball travels in a straight line and bounces predictably (I assume?).

If you had objects that followed arbitrarily curved paths, then you would have to use a form of approximating an integral, such as Runge-Kutta. These would have the best balance of computational speed and accuracy in most situations.
-- Paul Kernfeld
look at it this way. if i told you that 5 seconds ago i was walking north at 1 metre a second... how far north have i travelled up until now? 5 metres right? well it's the same thing with client server relationships. If you know how long it takes for data to travel from your pc to wherever the server is (or the opposite direction too) then you know how much you need to calculate forward to compensate for the fact that whatever data you receive right now is actually for 50ms ago or 124ms ago or whatever. you know what the velocity and direction of whatever object you are receiving data for is at the time the server sent you the message and you know how long ago that was sent to you, so now you just calculate how far the object has travelled in that time and in that direction.

it's absolutely NOT about looping more than one time to try to compensate... it's about saying "ok i just got some information telling me where something is and what it's doing, and i know that this data was sent X ms ago. That means that really it's actually (do calculations) HERE now. I just need to now adjust the object to match this new piece of information".

last example for now. Say you have a friend going on holiday. One day you suddenly receive a letter from him/her saying they are now in country XYZ and plan to trek across country going east at about 50km's per day. You look at the date they dated the letter and see that it was a week ago... this means that they are NOT where they originally wrote the letter and instead you need to work out 50km's per day multiplied by 7 days since it was a week ago this information was mailed. Now you roughly know where they should be.
nb is basically right BUT you need to consider ways in which the ball has NOT simply moved in a straight line. For Pong that's bounces off the walls and paddles, so you need to run your collision detection and resolution on the client unless you want your extrapolated position to end up in impossible places and then jump back. Which you don't ;).
I've not yet tackled issues like this, but I'd imagine the tricky part comes when you have to figure out the bounce after it hits the other players paddle. It's probably 100-300ms behind too then throw in a predicted ball position and it seems like it gets messy. Maybe since the other players paddle's position is going to be forward extrapolated everything will kinda just work out. I think =)

The real fun is that unlike the ball having a predictable path even if its forward extrapolated, the other players paddle will not. You could predict its position 300 ms into the future but what happens when the player stops moving the paddle. It's going to need to be snapped back to where it stopped which might look a bit funky.

-=[ Megahertz ]=-
-=[Megahertz]=-
You might want to consider using UDP (faster and leaner) and time stamping your messages to discard those older than ones you have already received. People suggestion for DR are good though - you'll want that. Run any simulation of ball collisions on both client and server - normally they should correspond. Do you have player input? if so delay send inputs too and delay local application by some time X (perhaps similar to ping time) so that they are applied remotely at nearly the same time as locally.

You can hide jumping around by finding the difference between your local ball position and received position and lerping over X frames (again I've found that some relation to ping time works well - say 2X ping time).

This topic is closed to new replies.

Advertisement