Polling Game Center for match data?

When Game Center determines a player is forced to disconnect from a match, Game Center sends a disconnect message via the "didChange state" function. However, not all devices connected to the match are receiving the disconnect state change message. One device will think the player is disconnected, but there is still messaging passing from the (supposedly) disconnected player to the other players in the match.


The only way I can think to resolve this issue is have all players poll Game Center to obtain updated match information. Based on this updated match information then all players can determine what players are truly still connected properly or not.


Can Game Center be polled to obtained updated match information? If so, how?


Any other ideas how to resolve the issue when all players do not receive the same disconnect state chaneg from Game Center?

Replies

>However, not all devices connected to the match are receiving the disconnect state change message.


This is incorrect. All players get the call to didChangeState. Isn't that cool!

>>This is incorrect. All players get the call to didChangeState. Isn't that cool!

It would be cool if it was working that way, but it is not working that way :>(


I understand all players in the game should be receiving a "didChange state" disconnect message, however, I have proven that this is not occurring when Game Center initiates the disconnect itself. When a "didChange state" disconnect comes in, I have my code play a particular "sound file" so I can prove whether the disconnect came in via "didChange state" on all iPhone devices playing the game. When this issue occurs, some player devices (iPhones) are not playing the sound file, so this indicates some player devices are not getting the "didChange state" disconnect indication. The device which did not play the sound file are truly still connected to the player who seemingly disconnected from Game Center as well


No players in the game are actually disconnecting themselves so the disconnect is being generated from Game Center. MOST times, when Game Center initiates a disconnect for a player then only 1 (or occasionally 2) other players receive the disconnect message via "didChange state" only, thus leaving the game out of sync. I have seen Game Center initiate spurious disconnects in my 3 and 4-player games. My card game takes about 20-25 minutes to play and a Game Center initiated disconnect will occur in about 60% of the games played, thus very annoying.


Sometimes even the player Game Center indicated has disconnected might not receive the "didChange state" disconnect message themselves and that player will still remain connected to other players and can still send/receive data. It is very odd.


The player that Game Center disconnected actually remains connected to some of the other players in the game and can send data back and forth with these other players. The player who "received" the disconnect from Game Center can also interact with some of the remaining players as well, but is truly disconnected from the player the Game Center disconnect was related to (of course). This means Game Center is only reporting the disconnect related to the network connection which has gone down only, and not informing all players about this disconnection.


If all players were to receive the same disconnect from Game Center, as expected, then my game would handle the disconnect properly and allow the remaining players to finish their game. However, when only some of the players receive a disconnect then the game is compeltely out of sync and there is nothing I can do ... unless there is a way I can poll Game Center for a fresh overall match status of all players to determine whether any other players have been truly disconnected without some players knowing about it. I would then be able to initiate the proper "missing" disconnects myself and save my game play.

TMI. Check your code to be sure it is doing what you say it is doing. Note that if you issue a sound off the main queue it won't make a sound. (i.e. in didChangeState you need dispatch_async(dispatch_get_main_queue(), ^{ ). And be sure the device in question is set to issue the

sound (Do Not Distrurb, that switch on teh side, etc.).


Then - file a bug report.

>>Check your code to be sure it is doing what you say it is doing

Code is functioning perfectly and everything works as designed until Game Center sends a disconnect to only some of the players.


>>Note that if you issue a sound off the main queue it won't make a sound. (i.e. in didChangeState you need dispatch_async(dispatch_get_main_queue(), ^{ ).

Sound is already inside DispatchQueue.main.async (see below)


func match(_ match: GKMatch, player: GKPlayer, didChange state: GKPlayerConnectionState)
{
    switch (state)
    {
        case GKPlayerConnectionState.connected:
            etc.

        case GKPlayerConnectionState.disconnected:

            DispatchQueue.main.async {
                self.soundError?.play()
                etc.
            }

        default:
            print("state unknown")
    }
}



>> .. be sure the device in question is set to issue the sound (Do Not Distrurb, that switch on teh side, etc.).

All iPhone devices used during testing have the sound enabled. Also my Mac has the sound on for the Xcode simulator player as well.

Do me a favor and do a definitive +/- test - add the two NSLog statements (or the equivalent in Swift) just to be sure. Then, when one fires and the other doesn't, file a bug report.





case GKPlayerConnectionState.connected:
            NSLog(@"Connected!!!!);
            etc.  
case GKPlayerConnectionState.disconnected:  
            NSLog(@"Disconnected");
            DispatchQueue.main.async {  
                self.soundError?.play()  
                etc.  
            }

I already have print statements for connect/disconnect (see updated code snippet below). I simply did not want to bother you with print statements earlier so did not include them.


When the issue is reproduced and one of the players who did not receive the disconnect message was connected to the Xcode simulator then the disconnect "print" statements are not seen at all. I decided to play a sound file instead so I could confirm the results on all connected devices which were not connected to the simulator.


Note: The "player connected" print statement always is seen for initial connection of all players



func match(_ match: GKMatch, player: GKPlayer, didChange state: GKPlayerConnectionState)
{
    switch (state)
    {
        case GKPlayerConnectionState.connected:

            print("PLAYER CONNECTED! = \(player.displayName)")
            etc.

        case GKPlayerConnectionState.disconnected:

            print("PLAYER DISCONNECTED! - \(player.displayName)")

            DispatchQueue.main.async {
                print("PROCESSING PLAYER DISCONNECT - \(player.displayName)")
                self.soundError?.play()
                etc.
            }

        default:
            print("state unknown")
    }
}



PS: The player that Game Center has indicated was disconnected remains connected with some of the other players in the game and can still send/receive data. Based on this additional fact, I know some of the other players did not receive the disconnect themselves and still maintain a network connection via Game Center

Just for clarity, the method will be called on the device of player 1. It will be referencing a player "player: GKPlayer" who I will refer to as player2. It is player 2 who has the status of GKPlayerConnectionState not player 1.


What you described is a bug. Please report it.

>>It is player 2 who has the status of GKPlayerConnectionState not player 1

Agreed. Player 1 receives the disconnect which informs Player 1 that Player 2 has disconnected.



I will look into how to report a bug.

I created a ticket for this issue --> Follow Up 733460705


I created a test application which sends/receives data between connected devices similar to how my game sends/receives data between the players in the game. It allows one player to be the host and other players to be non-hosts. When the test application starts, it will create the matches like my applicaiton does and then start sending/receiving data between the players. The test application displays the connection status (Connected/Disconnected) for each player and also indicates which player is currently sending/receiving data. I will provide this application to Apple when requested.


When running the test application, I can have one player quit the match and see that all players do not receive a disconnect message. usually 1 of the 3 remaining players gets the discsonnect only.

  • Was there any outcome to this issue? I'm seeing the same thing with my own code and testing.

Add a Comment