6 ms·
Help with server logic for a multiplayer game server in GO/Unity
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.
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.
I read somewhere that Agar does not use any client side prediction/correction so it must be possible to continue without that.
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 11y agoThis is a good article - http://gafferongames.com/networking-for-game-programmers/what-every-programmer-needs-to-know-about-game-networking/ http://gafferongames.com/networking-for-game-programmers/wha... 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%20GameKit.key https://dl.dropboxusercontent.com/u/508075/GameCenter%20and%... 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 11y agoI 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 11y agoFrom 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 11y agoThis 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.