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\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .