I'm currently working on a multiplayer game for iPhone. The problem I have, as with all multiplayer games, is that the other user will always see everything at a non-constant delay. The game I'm making needs to have an almost pixel perfect collision detection, but 1 or 2 pixels off is not that big of a deal. How can I possibly get this working? I guess I could just set local player to also be at X ms delay. However this will probably just be worse and feel sloppy when the user input. I know this problem is probably something network programmers deal with everyday and I would be glad if someone could give me a possible solution for this.
The game I'm making need to have a almost pixel perfect collision detection, but 1 or 2 pixels off is not that big of a deal. How can I possibly get this working?
Honestly, you probably can't. Part of your job as a game engineer is to give feedback to design on gameplay elements that simply aren't feasible. Getting perfect visual collision on all clients in a networked game isn't feasible, at least until we manage to break the speed of light.
"Pixel-perfect" implies client-side visuals while the collision is gameplay-related implying server-side physics. There is latency between the server and client and latency between all clients and each other. There isn't a way to make that not the case. The gameplay is going to be out of sync with the visuals and the best you can do is compensate for that fact and hide its consequences from players.
Your game is going to have to deal with the fact that the client won't actually know where any other client is with great accuracy. It's simply impossible; no matter how good you get your latency compensation, the remote game code won't know about the input from the client until X ms later (where X will likely be from 15 to 300, or more for some mobile/wireless networks).
You could as you say delay all input on the local client by the worst latency of all clients, but that is going to make your game feel incredibly sluggish and obnoxious to play, plus it won't account for spikes (your game won't even know if another client is experiencing a spike until well after the spike in many cases).
With any networked game, a large portion of what you have to do is hide the latency, often with gameplay compromises (and art) and hides how objects aren't in quite the same positions on all the clients. This is a problem for gameplay-relevant physics.
You can do the physics on the server and then, again, use gameplay compromises and art to hide the fact that objects might be colliding and reacting to things that are off from what the player actually sees.
Another option is to do the collision client-side but the results server-side. That is, if my client thinks we collided, tell the server. The server does some verification to make sure the collision was possible, some analysis to detect aimbots or cheating or the like, and then actually does whatever gameplay thing is supposed to happen in response to the collision. The collision results will not be "pixel-perfect" due to the latency (you can play the visual effects or sounds immediately on my client, though, since the client can assume it isn't being hacked and no cheating is going on) but the other players are going to see the effects of the latency no matter what you do. This optimizes for the best visual experience on the local client when attacking, which is usually what you want (optimize for the player with the most agency in a situation to get the best player experience... usually).
Art and gameplay rules can hide the effects of latency to a large degree. There was a great GDC talk on Halo 2 and how the "armor lock" shield system included in its design a variable-time activation delay that allowed for all clients to agree that there would be a shield before the shield activated, and then each client played the animation at the appropriate local speed to make the armor appear active at the moment it would actually be active. There was latency between the clients but that fact was hidden (outside of exceptionally laggy circumstances) to players.
Overall, though, you're almost certainly going to have to give up on pixel-perfect collision over the network in the general case. The design must deal with that fact.
Networking for games is hard. Valve knows this and have shared details on how they do it for games like Counter Strike.
You should do the following:
- Perform collision detection on both the server and client. It will allow the clients to performs physics locally, whilst waiting for the authoritative response from the server.
- Do entity interpolation and possibly some input prediction on client-side. Interpolation will make moving entities smoother in case of lag spikes (high intermittent delays). Prediction is something like the first point of this list where the client assumes what will happen in the next frame(s).
- Make sure you send a snapshot (e.g. absolute entity world position) every once in a while to clients. This will synchronize the entities, but might cause them to "snap" a bit. This can be mediated using interpolation.
You might not have to deal with all that since there should be many game/networking libraries out there that solve these issues.