2013-03-25 3 views
6

Sto implementando un gioco a turni con modalità multiplayer tramite gamecenter. Ho 2 dispositivi (1 ipad, 1 iphone) da testare in modalità sandbox che funzionavano bene ma ultimamente ha iniziato a lottare nel processo di matchmaking automatico. Dopo aver inviato il primo turno da un utente, l'altro dispositivo non riconosce immediatamente quel gioco ma apre il suo nuovo gioco. Prima era in grado di individuare immediatamente il gioco iniziato nell'altro dispositivo e il matchmaking era abbastanza semplice. E non ricordo di aver cambiato nessuna parte relativa al matchmaking (NSCoding, GKTurnBasedEventHandler, GKTurnBasedMatchmakerViewControllerDelegate metodi delegati ecc.).Game Center Matchmaking GKTurnBasedMatch ha un ritardo significativo (~ 1 min)

Ora invio la prima svolta da un dispositivo e devo attendere circa 1 minuto affinché l'altro dispositivo possa connettersi con successo a quel gioco. Dopo la connessione, le chiamate endTurnWithMatchData funzionano senza problemi, possono inviare e ricevere dati entro 1-2 secondi. Ma non sarà un buon UX se gli utenti iniziano un nuovo gioco e devono aspettare 1 minuto in modo che un altro utente possa connettersi al suo gioco. Qualcuno ha avuto un ritardo significativo nel processo di matchmaking automatico? Non ho ancora implementato gli inviti, quindi non posso verificarlo. Il matchdata che ho archiviato con NSKeyedArchiver sembrava abbastanza grande, 3396 byte, anche per un gioco nuovo con quasi nessun dato. E qui ci sono parti rilevanti del mio codice:

GameOptionsViewController:

- (void)turnBasedMatchmakerViewControllerWasCancelled:(GKTurnBasedMatchmakerViewController *)viewController 
{ 
    [self dismissViewControllerAnimated:YES completion:nil]; 
} 

- (void)turnBasedMatchmakerViewController:(GKTurnBasedMatchmakerViewController *)viewController didFailWithError:(NSError *)error 
{ 
    [self dismissViewControllerAnimated:YES completion:nil]; 
} 

- (void)turnBasedMatchmakerViewController:(GKTurnBasedMatchmakerViewController *)viewController didFindMatch:(GKTurnBasedMatch *)match 
{ 
    [self dismissViewControllerAnimated:NO completion:nil]; 
    self.gcMatch = match; 
    [self performSegueWithIdentifier:@"GameMultiplayer" sender:self]; 
} 

- (void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender 
{ 
    if([segue.identifier isEqualToString:@"GameMultiplayer"]) 
    { 
     GameViewController *GameVC = (GameViewController *)segue.destinationViewController; 

     [GameVC setGameMode:GAMEMODE_MULTIPLAYER_SAMEDEVICE]; 

     //Multiplayer game it is 
     if(self.gcMatch != nil) 
     { 
      [GameVC setGameMode:GAMEMODE_MULTIPLAYER_GAMECENTER]; 
      GameVC.gcMatchDelegate = self; 
      GameVC.gcMatch = self.gcMatch; 
      NSLog(@"Game OVC Segue: Match ID | %@", self.gcMatch.matchID); 

     } 
    } 
    else 
    { 
     ... 
    } 
} 

GameViewController:

//This method is called according to user actions 
//It's the only method I use to send data to other participant 
-(void) sendCurrentGameDataWithNewTurn:(BOOL) newTurn 
{ 
    NSLog(@"Sending game data current participant : %@", gcMatch.currentParticipant.playerID); 

    //Update match data if it is corrupted anyhow 
    if (gcMatch.currentParticipant == nil) 
    { 
    [GKTurnBasedMatch loadMatchWithID:gcMatch.matchID withCompletionHandler:^(GKTurnBasedMatch *match, NSError *error) 
    { 
     if (error != nil) 
     { 
      NSLog(@"Error :%@", error); 
      return ; 
     } 
     [self sendCurrentGameDataWithNewTurn:newTurn]; 
    }]; 
} 
else 
{ 
    NSData *matchData = [NSKeyedArchiver archivedDataWithRootObject:game]; 

    //Game advances to new player, buttons are disabled 
    if(newTurn) 
    { 
     NSLog(@"SENDING NEW TURN"); 

     NSUInteger currentIndex = [gcMatch.participants 
            indexOfObject:gcMatch.currentParticipant]; 

     GKTurnBasedParticipant *nextParticipant; 
     nextParticipant = [gcMatch.participants objectAtIndex: 
          ((currentIndex + 1) % [gcMatch.participants count])]; 

     [gcMatch endTurnWithNextParticipants:[NSArray arrayWithObject:nextParticipant] turnTimeout:GC_TURN_TIMEOUT matchData:matchData completionHandler:^(NSError *error) { 
      NSLog(@"Sent"); 
      if (error) { 
       NSLog(@"SNT - %@", error); 
      } 
     }]; 
    } 
    else 
    { 
     NSLog(@"ONLY UPDATING DATA"); 
     [gcMatch saveCurrentTurnWithMatchData:matchData completionHandler:^(NSError *error) { 
      NSLog(@"Sent"); 
      if (error) { 
       NSLog(@"OUD - %@", error); 
      } 
     }]; 
    } 
} 

}

-(void) updateGameDataWithGCMatch 
{ 
    //Update whole game data 
    self.game = [NSKeyedUnarchiver unarchiveObjectWithData:self.gcMatch.matchData]; 

    //Update game ui 
    ... 
} 

-(void) handleTurnEventForMatch:(GKTurnBasedMatch *)match didBecomeActive:(BOOL)didBecomeActive 
{ 
    //Check if I got data for the currently active match that options vc forwarded me here, if not do some debug print and return 
    if(![self.gcMatch.matchID isEqual:match.matchID]) 
    { 
     //For debugging reasons I skip if i get info for any previous match (other player quit etc) 
     NSLog(@"GCMatch matchID: %@ match matchID: %@",self.gcMatch.matchID,match.matchID); 
     return; 
    } 

    NSLog(@"Turn event handle"); 

    self.gcMatch = match; 

    if([match.currentParticipant.playerID isEqualToString: [GKLocalPlayer localPlayer].playerID ]) 
    { 
     //Disable field buttons 
     [self setFieldButtonsEnabled:TRUE]; 
     [self turnChangeAnimationFromLeftToRight:FALSE]; 
    } 

    [self updateGameDataWithGCMatch]; 
} 
+1

Game Center può avere ritardi apparentemente arbitrari. Non so mai se è a causa della nostra rete, o qualcosa da parte di Apple. –

+0

ho avuto questo ritardo per le ultime 2-3 settimane ora. Ora è peggiorato o meglio. Posso chiederti di avere questi ritardi quando testi la tua app con account sandbox su 2 dispositivi. Se anche altri sviluppatori lo hanno, allora smetterò di cercare una soluzione; continuare a testare così com'è. – guenis

+0

Ho anche sperimentato un ritardo significativo quando si lavora con la sandbox GC. Sembra anche variare un po 'dalla sessione di lavoro alla sessione di lavoro. – crgt

risposta

0

Per quanto riguarda la tua domanda:

Io stesso mi sono un po 'temperato con il matchmaking su Game Center un po' e ho anche sperimentato ritardi abbastanza frequenti, che hanno dimostrato di non essere stati causati dal mio sito ma dai server di Apple Game Center.

Per quanto riguarda ulteriori indicazioni:

Per quanto posso vedere il tuo attuale approccio alla matchmaking su un dispositivo è:

un'occhiata se v'è una corrispondenza che può collegarsi a -> Se sì richiesta gamedata e connessione alla partita ELSE avvia la tua partita e trasmetti i matchdati

Dalla mia esperienza è meglio iniziare con matchrequestbroadcast, attendere fino a quando trovi un secondo giocatore, definire il dispositivo server (ad es. con un checksum più basso di nomi dei centri di gioco) e quindi iniziare il gioco su quel dispositivo.