Game Center Quickmatch: Random Match Opponents (GKTurnBasedMatch)

I want my turn-based game to have Quickmatch mode, where the player is automatically matched to the first player to become available. I use my own user interface. My code looks like this:

- (void)quickMatch { GKMatchRequest *request = [[GKMatchRequest alloc] init]; request.minPlayers = 2; request.maxPlayers = 2; request.playersToInvite = nil; [GKTurnBasedMatch findMatchForRequest:request withCompletionHandler:^(GKTurnBasedMatch *match, NSError *error) { NSLog(@"MATCH: %@ %@ %@ %d",error,match,match.matchID,(int)match.status); }]; 

This successfully creates a match, but the second player in the game has the identifier null ( playerID:(null) status:Matching ).

I thought that if I ran the same code in a different instance using a different Game Center identifier, then both users would be mapped to each other ... but that doesn't seem to be true. Whenever I call the GKTurnBasedMatch loadMatchesWithCompletionHandler function, I keep retrieving the same matches, each of which has only 1 valid member (local player).

This question seems to be similar to iOS Development: how can I automatically match players in Game Center? which shows that setting request.playersToInvite = nil; should do auto-negotiation, but it doesn't seem to work for me.

How can I get Game Center to automatically match these players to each other?

+4
source share
1 answer

Let me look at the problems you see here. Firstly, there is no need to set the playersToInvite property to nil, since this is the default state if no players are assigned, but this does not cause your problem. I put this in quotation marks because you actually did the code correctly and only perceived the problem, which was not there. Let me tell you what happens when findMatchForeRequest is complete.

When the completion block is called, Game Center created a new GKTurnBasedMatch object with two participants, the first of which is the local player (you), and the second is the empty participant with the identifier nil. The reason for this is that Game Center does not appoint all participants when a match is created with random (unassigned) opponents. A random participant is assigned when a queue is sent to them. In your game, this match will not appear in the cloud so that others can play until you make your first turn.

Now, calling loadMatchesWithCompletionHandler on your other device / Game Center Identifier will not automatically display a match IF you have not specifically invited this player with ToInvite players (and already made your move, as indicated above). Think of it this way: if it worked, every player in the world would see every auto-negotiation when they call loadMatchesWithCompletionHandler.

The identifier of the other game center should actually call findMatchForRequest without the playersToInvite property set, in order to be matched with the free space available in the game, your other identifier. Thus, the paradigm is β€œalways your turn” when creating a match, but this player is now in the second slot, and not in the first. Just create a game on the second identifier in the same way as on the first one, and your game will be created with two participants, the first of which will be initially created, and the second - an identifier that joined the match by calling findMatchForRequest. The key here is findMatchForRequest, do NOT ALWAYS create a new match if playerToInvite is zero. If there is an existing match with an open space, it will simply match the local player.

Happy coding!
Corbin

+7
source

Source: https://habr.com/ru/post/1501194/


All Articles