

Help with server logic for a multiplayer game server in GO/Unity - diericx

I am trying to create a simple multiplayer server for a simple game using GO. I currently have it so that users can join, sign in, connect, and see other users. The issue I currently have is that moving around is very laggy because I send user input to the server and all actions are performed on the server rather than on the client. Clients and the server only get and send packets every 20 milliseconds.<p>I was wondering what the best solution to this is. I feel like I have 2 options: exchange a lot more packets to make the game run a lot smoother for the client, or create some sort of prediction on the client where the client will do what it thinks is right until corrected by the server.<p>I read somewhere that Agar does not use any client side prediction&#x2F;correction so it must be possible to continue without that.<p>What is the down side to sending more packets? Is that a reasonable way to solve this lag issue? And if so should I only send more on one side of the game to be optimized correctly (as in send a lot of packets from the server but not a lot from the client)?
======
iamflimflam1
This is a good article - [http://gafferongames.com/networking-for-game-
programmers/wha...](http://gafferongames.com/networking-for-game-
programmers/what-every-programmer-needs-to-know-about-game-networking/)

If you really are sending packets every 20ms then that is the equivalent of
50fps - I suspect that if you log out how often you are getting packets from
the server you'll find that you are not actually getting packets at that rate,
or the jitter on the packets is unacceptable.

Client side prediction doesn't have to be very clever. You can get good
results with very simple algorithms.

I gave a talk on this a few years ago at iOSDevUK -
[https://dl.dropboxusercontent.com/u/508075/GameCenter%20and%...](https://dl.dropboxusercontent.com/u/508075/GameCenter%20and%20GameKit.key)

I'm not an expert in games, but even my simple code worked pretty well.

From what I remember I was sending user inputs from the client side every 0.2
seconds - and from the server once I had the client prediction in place I
could get away with very slow updates from the server and still have the
illusion of 60fps.

~~~
diericx
I actually just noticed a bug in my code where I was only looking for data
from the server every 20 milliseconds rather than every frame. Now the
movement is smooth but the controls feel a bit sticky. I made the client send
every 10 milliseconds and it looks pretty good, but this is a really bad way
to solve this problem. I'll look at your links and try to optimize it better!
Thanks a ton for those:)

Edit: I read your keynote and I'm not sure how exactly your client prediction
worked. Is there any video anywhere of the keynote? Or could you give a brief
description?

~~~
iamflimflam1
From what I remember, the way I approached it was to have the client stepping
the game world forward every frame based on whatever the current state was of
all the players.

So for example if a player is going left, every time the game steps forward
one frame move the player left.

Then when a message comes from the server with the current game state, update
everything to the server positions and then step your game world forward to
now.

So a simplified example - we have one object in our game that has an x
position and a delta x to move it.

    
    
      Local
      Frame   x       server_message        info
      0     ____     no message             no real idea of what the game state is
      1     ____     no message
      2     ____     no message
      3     ____     no message
      4     ____     no message
      5     100     Frame=5 x=100 dx=5      we can start displaying where things are
      6     105     no message
      7     110     no message
      8     115     no message
      9     120     no message 
      10    125     no message
      11    126     Frame=7 x=110 dx=4 (x = 110 + 4 * 4)    
    

So we set our local state to what the server says and then step forward by 4
frames to get what we think the current state should be.

    
    
      12    130     no message
      13    134     Frame=6 x=105 dx=5
    

We ignore this message from the server as it's out of order (we've already
received frame 7)

    
    
      14    138     no message
      15    142     Frame=15 x=142 dx=4
    

No need to do any stepping forward from this server state as we are in sync.

One thing to be careful of is that normally it's not just a case of saying
it's 4 frames so I just multiply everything by 4 to get the new positions.
With physics engines and more complete calculations you probably want to step
the world forward frame by frame to get a better simulation of where
everything is.

Hope that all makes sense.

~~~
diericx
This is all really interesting, thank you so much for sharing this with me! I
just have a few questions:

Wouldn't the numbers for the current frame get really huge as the game
progresses?

How would this method of sending the current frame (from the server) and
matching it with the client work if there were a lot of people on the server?
Would the server have to keep track of the current frame of each player?

Why does dx change? Are we not assuming in this example that the character is
moving right at a consistent speed?

I am using TCP, I shouldn't have to worry too much about packets coming in
incorrect orders right? But it's probably still good to implement your method
of dealing with it just in case.

~~~
iamflimflam1
dx is changing in response to the user making inputs.

Imagine you are showing a different players character - at first the server
tells us he is moving to the right by 5 pixels per frame. So we start moving
him, in the absence of any more information we keep moving him, then we get a
message from the server saying 'actually several frames a go the player
decided to move at 4pixels per frame' we have rewind our predictions back to
the when that happened and then replay with the new movement speed.

For the current frame I just took the first packet received from the server as
the baseline frame.

So if you get a packet from the server saying "the game is currently at frame
100" that's your baseline frame, start counting from there.

You're right, if you're using TCP then you don't need to worry about out of
order frames.

One of the issues with TCP is that if you are going over a slow connection to
some players they will get behind the gameplay. With UDP packets if they are
on a slow connection the packets will just be thrown away and they should keep
up with the latest game state.

If you do a search "udp vs tcp games" you'll find a whole host of discussions.

e.g. [http://gafferongames.com/networking-for-game-
programmers/udp...](http://gafferongames.com/networking-for-game-
programmers/udp-vs-tcp/)

Personally I prefer udp - but then you have to be careful about packet sizes.

This is a pretty good library that lets you mostly forget about udp or tcp -
[http://enet.bespin.org/](http://enet.bespin.org/)

