Search code examples
iosios8sprite-kitgame-centergamekit

Strange GameKit Bug. GKLocalPlayer is returning the opponent


I'm making a Sprite Kit multiplayer game using game center.

I'm using the following code to get the local player.

GKLocalPlayer.localPlayer()

I use this to get stuff like the player ID and alias like so:

GKLocalPlayer.localPlayer().playerID
GKLocalPlayer.localPlayer().alias

Pretty straightforward. But the strangest thing happens. Occasionally during the match GKLocalPlayer.localPlayer() will return the OPPONENT's (i.e. the other player) player ID and alias. As you can imagine, this causes all sorts of problems.

Some Additional Info:

  • Yes I authenticated all users.
  • Both users are logged in to Game Center sandbox servers under different accounts.
  • As explained above, the local player is correct initially. But then after the connection between players is established and I starting sending packets of data, occasionally the local player returns the wrong user. And it continues to return the wrong info afterwards until the App is reset.
  • I've tested this for hours. I'm positive it's not me. In fact, as far as i'm aware of Apple doesn't allow you to programmatically change the GKLocalPlayer.
  • I'm running on iOS 8 on actual devices.

Is this a known issue? Does anyone have any recommendations? I'm really at a loss. I suppose maybe I could try calling GKLocalPlayer.localPlayer() and save the properties (before the strange bug happens) instead of continuously calling GKLocalPlayer.localPlayer() to get access to the local player. But then again, that would just be a workaround.

Edit:

To test this issue, i'm running a simple timer like so:

NSTimer .scheduledTimerWithTimeInterval(1.0, target: self, selector: "test", userInfo: nil, repeats: true)
func test() {
        println("\(GKLocalPlayer.localPlayer().playerID)")
    }

And the output is like this: (I'm not showing the entire player ID). Notice how the playerID changes. And I checked, it is indeed changing to the opponent's playerID. This is also true for the alias, etc.

G:43...
G:43...
G:43...
G:43...
G:43...
G:43...
G:84...
G:84...
G:84...
G:84...

Solution

  • I ran into this problem as well. The issue is that you are passing the local player back and forth. So, when the local player comes in, after being deserialized, the player passed in becomes the local player.

    I got around this by implementing my own player object that has displayName and playerID. You may be able to create a guest player from local player and use that to pass around. Just don't pass around the local player.