Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Simple online pong game network synchronization

I'm writing a simple online pong game for two players playing over the network. It's a client-server application, with a game logic on the server side. I have some problems with game synchronization on the client side, and the result is pretty unsatisfying. This is how it currently works:

  1. On the server side I've got a game object that stores position of the players and the ball, each object has its x, y position and x,y velocity. Based on that position of the objects is updated in the loop. On the client side there is same local object with the same data, and it is also beeing updated in the loop.
  2. When player presses/releases up or down client sends a network packet with one integer, so that the player object starts/stops to move in the game object on the server.
  3. Server sends a synchronization packet every 50 milliseconds with position and velocity of all three objects. When client receives this packet it changes positions of the game objects accordingly.

This method doesn't work very well as it moves the game objects back and forth on the client side. Any ideas how to improve it?

like image 265
macjack Avatar asked Jan 17 '11 13:01

macjack


1 Answers

Admit you have a latency of 30ms between client and server. The client send "I wanna move my racket down" and its racket is at y=100px with a velocity of 0.1px/ms

30ms seconds later:

  • client racket is at y=100+30*0.1= 103px
  • server receives the order from the client and start moving the racket (which is currently still at y=100px on the server side)

20ms seconds later:

  • client racket is at y=103+20*0.1 = 105px
  • server-side client racket is at y=100+20*0.1= 102px
  • server sends to client the new position (102px)

30ms seconds later:

  • client rarcket is at y=105+30*0.1= 108px
  • client receives from server the new positon of the racket: 102px

At this point, the client racket "jumps" backward from 108 to 102px...

How to cope with the network latency? Two complementary ways:

  • await server acknowlegment before doing an action
  • predict results of actions (on the client and server sides)

The first aproach is used when the effect on the client is hardly linked with the result and cannot be "rollback". Example: when a client shots a missile, its not addmitable that this missile is being suppressed by the server on the next update because the client had in fact no more missile stock. So in this case, client application will launch the missile only afer the server sent an acknowlegment.

The second is always used to avoid these "jumps" when server sync. You have to monitor network latency to predict movment of your game elements. Here two ways: compute the ping or synchronize server and client time at startup (the easiest and more robust way). The general idea is:

  • client sends "I wanna move my racket down at time=1265871" and start moving

30ms later:

  • client racket at y=100+30*0.1= 103px
  • server receives the move and compute the 30ms latency (by ping or time sync difference) and set the racket position at y=100+latency*0.1= 100+30*0.1= 103px

Perfect! They are synchronized.

20ms later:

  • server and client racket both at y=103+20*0.1= 105px
  • server sends new position AND direction

30ms later:

  • client racket at y=105+30*0.1= 108px
  • client receives new position AND direction (105px moving down), computes the 30ms latency and set the racket position at y=105+latency*0.1= 105*30*0.1= 108px

Again, client and server are synchronized!

Desync can happens on the other client when the first client stop moving. In this case the player racket will "jump" a little bit. When this is not critical, it's possible to smooth this transition.

Hope it will help.

like image 154
Pierre Avatar answered Sep 24 '22 13:09

Pierre