I am making a multiplayer game for iOS and I read the material in Apple Developer Center, specifically this one. Here is my code for custom matchmaking, which is pretty straightforward:
- (void)findProgrammaticMatch {
GKMatchRequest *request = [[GKMatchRequest alloc] init];
request.minPlayers = 2;
request.maxPlayers = 2;
request.defaultNumberOfPlayers = 2;
request.playersToInvite = nil;
request.playerAttributes = 0;
request.playerGroup = 0;
UILabel *loading = (UILabel *)[aiw viewWithTag:792];
[[GKMatchmaker sharedMatchmaker] findMatchForRequest:request withCompletionHandler:^(GKMatch *match, NSError *error) {
if (error){
//error handling
[loaderLayer stopAnimating];
UIButton *cancelButton = (UIButton *)[loaderLayer viewWithTag:442];
[cancelButton setTitle:@"Go Back" forState:UIControlStateNormal];
loading.text = @"Cannot find any players. Please try again later.";
} else if (match != nil) {
//save match
self.match = match;
self.match.delegate = self;
loading.text = @"Found a player. Preparing session...";
if (!self.matchStarted && match.expectedPlayerCount == 0) {
self.matchStarted = YES;
//begin game logic
[self.scene setState:1];
self.myTicket = 1000+arc4random_uniform(999);
[self.scene send:self.myTicket];
[self stopLoading];
}
}
}];
}
However, matchmaking fails when one or more devices are connected to the internet via cellular networks. When I investigated the underlying error I found out that even if it is a wifi to wifi case, the completion handler does not work as intended. That is, match.expectedPlayerCount
is never 0. Instead, the game starts when - (void)match:(GKMatch *)match player:(NSString *)playerID didChangeState:(GKPlayerConnectionState)state
handler is invoked after the completion handler as following:
...
- (void)match:(GKMatch *)match player:(NSString *)playerID didChangeState:(GKPlayerConnectionState)state {
switch (state) {
case GKPlayerStateConnected:
self.matchStarted = YES;
//begin game logic
[self.scene setState:1];
self.myTicket = 1000+arc4random_uniform(999);
[self.scene send:self.myTicket];
[self stopLoading];
break;
...
The problem now is if a device with 3g is connected (and matched-sort of) didChangeState
is never invoked. I checked for several other related questions on the internet and this site, although they are far from being satisfactory. I also read that sandbox servers of Game Center are not reliable and for some people production version worked perfectly(it just works!) despite the errors in sandbox mode, but I don't want to take that risk. Has anybody have experienced similar problem with their multiplayer game?