I want there to be a "Quickmatch" mode in my turn-based game, where the player gets automatically matched with the first player to become available. I'm using my own custom UI. My code so far 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 2nd participant in the match has a null
ID (playerID:(null) status:Matching
).
I thought that if I ran this same code on another instance, using a different Game Center ID, then the two users would be matched against each other... but that does not appear to be correct. Whenever I call the GKTurnBasedMatch loadMatchesWithCompletionHandler
function, I continue to retrieve the same matches, each with only 1 valid participant (the local player).
This question appears to be similar to iOS Development: How do I auto match players in Game Center? which does indicate that setting request.playersToInvite = nil;
should accomplish auto-matching, yet this doesn't appear to be working for me.
How can I cause Game Center to automatically match these players against each other?
Let me address the issues you are seeing here. First off, it is not necessary to set the playersToInvite property to nil, as that is the default state unless players are assigned to it, however that is not causing your "issue". I put that in quotes because you actually did the code correctly, and only perceive a problem that isn't there. Let me walk you through what happens when findMatchForeRequest is completed.
When the completion block is called, Game Center has created a new GKTurnBasedMatch object with two participants, the first is the local player (you), and the second is actually an empty participant with a nil playerID. The reason for this is that Game Center does not assign all participants when a match is created with random (unassigned) opponents. A random participant is assigned when the turn is sent to them. In your game, that match will not show up in the cloud for others to play in until you take your first turn.
Now, calling loadMatchesWithCompletionHandler on your other device/Game Center ID will not automatically display the match UNLESS you specifically invited that player with playersToInvite (and have already taken your turn as specified above). Think about it like this: if it worked that way, every player in the world would see every auto-match in existence when they called loadMatchesWithCompletionHandler.
The other Game Center ID must actually call findMatchForRequest with no playersToInvite property set in order to be matched into the empty seat available in the game your other ID created. This way the paradigm of "it's always your turn" when creating a match is preserved, but that player is now in the second slot, not the first. Simply create a game on the second ID in the exact same way you did on the first, and your game will be created with two participants, the first being from the ID that originally created it, and the second being the ID that joined the match by calling findMatchForRequest. The key here is findMatchForRequest doesn't ALWAYS create a new match if playersToInvite is nil. If there is an existing match with an open seat, it will simply match the local player into that.
Happy Coding!
Corbin
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With