J'ai 2 à 3 clients qui peuvent échanger des messages via Apple Game Center.
La seule synchronisation dont j'ai besoin est: démarrer le jeu au même moment.
Je suppose que cela implique une synchronisation d'horloge. Comment y parvenir?
networking
multiplayer
game-center
GameCoder
la source
la source
now
et que vous envoyez un message pour commencer exactementnow + halfSecond
alors tant qu'ils reçoivent tous le message dans la demi-seconde et tant que leurs horloges système sont correctement synchronisées, elles démarreront toutes en même temps.Réponses:
Le commentaire de Steven est juste: c'est théoriquement impossible à faire.
Heureusement, dans la pratique, vous pouvez vous en approcher, c'est ainsi que fonctionnent des choses comme le NTP .
Par exemple, mieux que d'envoyer simplement un message à 3 clients disant "commencer maintenant", vous pouvez échanger quelques messages ping au préalable pour mesurer le temps nécessaire pour envoyer un message au client, et lorsque vous envoyez le message de démarrage, au lieu de "commencer maintenant", dites "démarrer dans X millisecondes" et ajustez X pour les différents temps pris pour qu'un message arrive.
par exemple.:
Cela ne peut pas garantir la synchronisation car le temps nécessaire pour envoyer un message sur Internet varie et parce qu'il peut être différent dans chaque direction. Le premier, vous pouvez réduire les effets en effectuant la mesure plusieurs fois et en prenant une lecture médiane. La seconde est plus délicate et peut être théoriquement impossible à résoudre (bien que je ne me souvienne pas de la preuve pour le moment). La bonne nouvelle est que vous n'avez probablement pas besoin de beaucoup de précision.
la source
Comme mentionné, c'est impossible, alors j'essaierais une autre approche:
Si vous n'avez pas de serveur dédié, élisez un client participant pour devenir l'hôte (cela peut être transféré si le besoin s'en fait sentir).
L'hôte exécutera désormais toutes les logiques de jeu importantes, telles que la détection des coups, les contrôles de l'IA, la gestion des stocks, etc., ainsi que le suivi du temps (c'est-à-dire la dictée du temps de jeu).
Les autres clients essaieront simplement de rester synchronisés avec l'hôte, en essayant d'estimer ou d'approximer la valeur attendue. Si le décalage augmente ou qu'il y a perte de paquets, les choses peuvent devenir saccadées, mais il est trivial de rattraper le retard, essentiellement en attendant la prochaine mise à jour.
La plupart des jeux (en particulier les FPS) cachent ce fait en faisant leur propre calcul local pour le propre mouvement du joueur, les coups de feu tirés, etc. pour éviter que le jeu ne se sente lent. Tout est toujours corrigé en fonction des données du serveur. Cela peut entraîner une certaine confusion, par exemple, vous vous voyez tirer sur l'ennemi, mais au même moment où vous tombez mort (sans que l'ennemi ne frappe), mais c'est toujours une bien meilleure approche que la synchronisation complète.
Si vous insistez toujours pour que tout soit synchronisé, vous voudrez probablement créer une sorte de compteur d'étapes ou de trames, de sorte que tous les clients ne traitent qu'une seule étape logique, puis synchronisent leurs données, etc. Gardez à l'esprit que cela peut être à la fois de la bande passante intensive ainsi que laggy, donc je ne recommanderais pas de le faire à moins d'avoir beaucoup de données autrement et votre gameplay est basé sur le tour (par exemple les jeux de style Artillerie / Worms).
la source
Je recommande de synchroniser les temporisateurs système sur tous les clients et le serveur au moyen du protocole NTP [Stratum 2], puis le serveur envoie une commande pour démarrer le jeu à l'heure spécifiée, disons, lorsque tous les temporisateurs atteignent 0:05:00. Cette approche devrait vous donner une synchronisation précise de 3 à 4 ms, je crois.
la source