0
\$\begingroup\$

I've been building a game center game for iOS and it works great so far. I finally started testing the game and theres (obviously) some latency, which is causing the game to be out of sync.

Basically I have 2 players, each controlling a game character. The game character can shoot fireballs and iceballs etc. These attacks do damage, and they have effects. For example. the ice ball effect will freeze the opponent for 3 seconds if it makes contact. the fireball will do extended fire damage for 3 seconds.

so the problem is, when I was playing against my brother, because of the latency, my game said I had 40 health left and he was down to 0, while on his device, the game said I had 0 and he had 20.

This means that attacks were registering/colliding on one device (based on the positions of the characters/fireballs) and not on the other. and vice versa.

I'm currently using the default peer-to-peer game-center architecture. Would using a client-server architecture (one person becomes the server) solve this out-of-sync problem?

if not, what other options do I have with the game kit API?

\$\endgroup\$
1
\$\begingroup\$

I've found a solution to this problem.

Note: this will be a relatively long answer.

One thing that I did implement was the use of udp for some of my data transfers that are not as critical as others. For example, since I'm sending movement data about 10 times a second, I figured its ok if 1 or 2 of the 10 get lost once in a while.


Now to the actual problem:


So what was happening is the following- since I'm using a p2p architecture, both clients have a delay when they see the game 'world'. This means that on my device, I see the enemy player at a position that is delayed 100-200 milli seconds. (so he was actually there 100-200 ms in the past).

The problem with this, is that, when I shoot a projectile at the enemy, and I see a collision, if the collision was right on the edge of his sprite (his feet or head), in his screen, he was already past that position - PLUS - my fireball appears 100ms delayed on his screen. This means on his device, he was able to dodge my attack. This can happen a random number of times, but I'd guess its probably below 30% of the time. 70%, both devices see the collision.


The solution


What I came up with is to send a message to the other player when either device sees a collision. And remember, each device has no idea if the other saw a collision or not. So I have no way of knowing whether both devices saw a collision, or only 1, and the other saw that the attack was dodged.

This means I have to send a message to the other player every time theres a collision. Now, because of the way I've architected my game, when a collision is sent, I'm automatically applying the collision event (meaning, damage dealt, projectile effect that took place - like ice bolt freezing the player it collided with) This is problematic, because what if both devices saw the collision. That means both devices are sending each other a message of collision, and applying collisions again.

To get around this, I've added a "spell number" to each spell/attack, and when a collision happens, I save this number with the player that the collision happened with as the "last collision spell number". So if a collision takes place with that spell, the player knows he/she already collided with that specific object, so collision logic doesn't run twice.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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