Take the 2-minute tour ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

I'm using cocos2d 2.0 and Gamekit for networking. I've got a server/client model. It works over wifi (local) and bluetooth. (Xcode 4.3, Objective C)

Basically, there's a ball and 2 or more players. What I wanted to do is:

The physics is completely simulated on the server. The clients send their inputs to the server and the server sends the position (only the position and rotation that's it) to the clients. The clients than set the position of the objects to the given position datas. The ball is also simulated on the server.

Problem: There can be a high latency and the gameplay would be not smooth on the client side. The players can freely move around and interact with the ball (just pusing it and such things).

I read about prediction but how should it be possible to guess the movement of the player? The player can move completely free (360°). I also read about Servertime and clienttime but I didn't get it very well :/

How could I reduce lag? Please explain your solution because I don't want to just copy and paste it, I want to understand it.

PS: Probably I will have very low ping (1-5 ms) on wifi (local, both devices on the same network), I guess but I want to implement Gamecenter too and than I would need to handle the lag. But handling the lag on wifi/bluetooth would be great to, to achieve smoother gameplay.

share|improve this question

migrated from stackoverflow.com Jul 11 '12 at 17:51

This question came from our site for professional and enthusiast programmers.

2  
You need to spend more time reading the articles again, more carefully. Networking is an advanced topic, even for the very experienced programmer. When I need to learn new and difficult tricks, I find as many sources as possible and over a few days I read through them (as many times as necessary) to get a basic example up and running. Optimisation techniques come afterward, and that is essentially what you're asking here, which is why you have so many questions rather than just one. Make a start first. Get a basic example running between your box & a remote host. THEN start looking at tweaks. –  Nick Wiggill Jul 11 '12 at 21:04
add comment

2 Answers 2

Lag results from the speed of light limitation, and the processing speed of network protocol translation and switching in intermediate networking devices and at end points. From yours and your players' point of view, these are invariant factors.

Game that deal effectively with lag do so by adjusting player perception of the impacts of lag. One example is in how Diablo II originally dealt with player damage in networked games, versus how it did later (and how consequently how WoW does it): never apply full damage all at once, because the player's in-game mistake that caused them to take damage may well have been caused by lag. In proportion to the round-trip packet time, then, be forgiving toward the player, such as (in D2) by dropping health at a certain (possibly increasing) rate, such that they know they have taken damage, they have a good chance of knowing how massive it's going to be, and they have fractionally more time to deal with it by drinking a potion.

You asked about prediction (extrapolation). Players' view of lag can be improved by running your rendering one frame behind, for reasons discussed here (see comments as well, search on "behind"). The idea is that you can extrapolate the next frame's state by looking at motion over the last two frames. Extrapolation works by looking at the deltas (eg. velocities, linear and possibly also rotational) over the last two frames, averaging them, and adding them to the current state. Doing this in 1 dimension (eg. along a straight train track), might be as follows:

  • Train velocity in 2nd last frame is 15 units per second
  • Train velocity in last frame is 12 units per second
  • The delta between these two frames is 12 - 15 = -3 (last minus 2nd last)
  • The new velocity in the frame you are about to calculate is 12 + (-3) = 9.

This is a very simplistic example, and there are certainly more physically accuracter ways of doing this (correct use of the equations of motion). However doing this in 2 or 3 dimensions is much the same, only you'll be using some trig (Pythagoras) to calculate actual vector magnitudes so as to do the extrapolation step.

Gaffer's Networked Physics article is a great place to get up to speed on the various concerns and potential solutions.

Possibly most importantly, you will not want to do your testing on your home network, cf. the experience of the X-Wing vs Tie Fighter team! Instead, get a realistic, even slow remote system that you can work with to do your testing, or alternatively use a lag-simulation app to give you a high latency, possibly packet-lossy environment in which to do your testing. This will be hard to start with but will reduce time spent on implementation in the long run.

share|improve this answer
    
Ok. I got it how you make the calculations. But when would you actually use prediction? when it lags? But there would be a lag all the time (minimal lags). So should I predict the position all the time? I read gaffers article but I didn't got it very well that's why I'm asking about it here. Another question. How do I calculate the latency? And how does it influence the way I call the "predic method"? PS: I would be nicer if you could answer in your answer above and not in the comment section here (if the answer is a long one). Thanks. –  cocos2dbeginner Jul 11 '12 at 19:45
    
If using prediction, the idea is not To do or not to do?, but rather How much? Lag is always present, even 1ms ping is lag. How much prediction is based on metrics you gather between client and server. If you find that you have an 80ms roundtrip time (within last 2 seconds or so) / 40ms one-way time, you'll need to predict each frame that would be drawn during those 40ms, ensuring each frame of simulation LOOKS like where it would be if you'd just got a packet before starting to draw that frame. Higher ping causes more intensive prediction as it happens over more time = greater error. –  Nick Wiggill Jul 11 '12 at 20:52
1  
Latency calculation is straightforward, Gaffer covers that too in his articles. Basically, you're taking a running average, update by update, of round trip time, and dividing it by two. You might look at the avg. over a hundred updates (use a queue limited by no. of entries), or over a fixed period of time (use a queue where each entry has an insertion timestamp, and discard entries older than eg. 2 seconds). Round trip time is calculated by sending the server a packet with ID and timestamp, and having it send a packet with same ID and timestamp back again. –  Nick Wiggill Jul 11 '12 at 20:55
    
+1 for Gaffer and insights. Many other answers on gamedev are hit and miss... –  Prof. Falken Nov 28 '12 at 21:57
add comment

Prediction is the way to go. It still works with 360° movement. All Quake games use it for example.

The thing with prediction is that it fails as soon as the direction of movement of a predicted object changes (significantly). If this happens very frequently, prediction can't help you much.

There is no other "magic" to fix latency, other than trying to reduce latency as much as possible. One being not to allow play over high-latency connections (3G).

You also have some influence by the amount of data you're sending, and how many packets you're sending. If you're choking the line with too much data, lag is increased. Or maybe what you perceive as lag is merely packets being dropped, never to arrive.

Most multiplayer games compress the data they send, or are very clever about when and how often they send certain information.

For example if you send position information, that's usually a CGPoint. A CGPoint consists of two float values (x,y). Each is 4 Bytes, which makes each CGPoint 8 bytes. You can safely reduce that to two Int16 to a total of 4 Bytes. Convert to Int16 by multiplying the point coordinates by 10, and on the receiving end divide by 10. For example: x,y = 1.2094, 204.7897 multiplied by 10 and represented as Integer gives you: 12, 2048. On the receiving end you'll divide by 10.0f and you get x,y = 1.2, 204,8.

In many cases it is ok to lose floating point precision in favor of saving bandwidth. Your object positions are also limited to a range of -3200 to 3200 (or 0 to 6500 if you use UInt16). But I doubt doing this optimization will have an effect on your game as it doesn't sound full of game objects.

Another issue is sending at 60 fps, which may easily be overkill. Imagine you accumulate 100 Bytes to be sent over the network every frame. At 60 fps that makes 6 Kilobytes per second. That's significant for mobile phone upstream rates. If you only send the same data every 6 frames you can cut the datastream down to 1 Kilobyte per second.

share|improve this answer
    
how does prediction work? Could you make an example or go more in detail? :) –  cocos2dbeginner Jul 11 '12 at 18:23
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.