je fais un jeu de physique rapide qui est un hockey sur table. Avec deux maillets et une rondelle. Le jeu fonctionne sur iPhone / iPad et je fais la partie multijoueur via GameCenter.
C'est ainsi que fonctionne le système réseau. Le client qui met en vedette la correspondance sera défini comme le serveur et celui qui accepte la demande de correspondance est le client.
Le «serveur» a la physique en cours d'exécution et la réponse est immédiate et le client a également sa physique en cours d'exécution de sorte qu'il semble fluide entre les échanges de messages. Ce que je fais en tant que serveur, c'est que j'envoie au client ma vitesse de palet et ma position et que le client ajuste sa vitesse / position de palet par rapport au serveur pour le synchroniser. Sinon, la physique se désynchronise et elle le gâche.
Lorsque la latence du réseau est bonne, en dessous de 100 ms, les résultats sont plutôt bons, j'ai un jeu jouable fluide côté client et le comportement étrange est minimum. Le problème se produit lorsque le décalage est d'environ 150 à 200 ms. Dans ce cas, il arrive que mon palet client ait déjà touché un bord et une direction inversée mais il reçoit un message de retard du serveur et il recule un peu provoquant une sensation étrange au comportement de la balle.
J'ai lu quelques trucs à ce sujet:
Cliquez sur Exemple de synchronisation
Wikipédia sur la synchronisation d'horloge
Alors, comment puis-je résoudre ce problème? Dans la mesure où j'ai lu la meilleure option que j'ai, c'est de faire une synchronisation d'horloge sur le serveur / client avec un horodatage afin que lorsque je reçois des messages de retard liés à mon horloge, j'ignore simplement alors et laisse la simulation des clients faire la emploi. Êtes-vous d'accord avec ça? Et comme j'envoie des données non fiables (UDP), je peux obtenir des messages retardés ou des messages hors service.
Si c'est la meilleure approche, comment puis-je implémenter la synchronisation d'horloge. J'ai lu les étapes mais je ne l'ai pas bien compris.
Il dit que:
- Le client marque l'heure locale actuelle sur un paquet de "demande de temps" et l'envoie au serveur.
- Dès réception par le serveur, le serveur tamponne l'heure du serveur et retourne
- À la réception par le client, le client soustrait l'heure actuelle de l'heure envoyée et la divise par deux pour calculer la latence. Il soustrait l'heure actuelle de l'heure du serveur pour déterminer le delta de temps client-serveur et ajoute la demi-latence pour obtenir le delta d'horloge correct. (Jusqu'à présent, cet algothim est très similaire à SNTP)
- Le client répète les étapes 1 à 3 cinq fois ou plus, en faisant une pause de quelques secondes à chaque fois. Un autre trafic peut être autorisé dans l'intervalle, mais doit être minimisé pour de meilleurs résultats. Les résultats des réceptions de paquets sont accumulés et triés dans l'ordre de latence la plus faible à la latence la plus élevée. La latence médiane est déterminée en choisissant l'échantillon médian dans cette liste ordonnée.
- Tous les échantillons supérieurs à environ 1 écart-type de la médiane sont rejetés et les échantillons restants sont moyennés à l'aide d'une moyenne arithmétique.
En suivant cet exemple, j'aurais ceci:
Imaginons que le jeu soit chargé et que mon temps client soit maintenant 0, donc j'envoie au serveur que mon temps est 0.
Le message met 150 ms pour arriver au serveur mais l'horloge du serveur a déjà démarré et a une seconde d'avance sur le client. Lorsque le serveur recevra le message, l'heure sera: 1.15 et enverra cette heure au client, sommes-nous bons? Imaginons que notre décalage soit constant à 150 ms.
Maintenant, le client reçoit l'heure 1.15 et soustrait l'heure actuelle de l'heure envoyée et divise par deux pour calculer la latence. Ce qui est: 0,3 - 0 = 0,3 / 2 -> 150 ms.
Il soustrait l'heure actuelle de l'heure du serveur pour déterminer le delta d'heure client-serveur et ajoute la demi-latence pour obtenir le delta d'horloge correct:
Heure du client: 0,3 Heure du serveur 1,15
0,3 - 1,15 = 0,85 + latence (0,15) = 1
Comment est-ce synchronisé? Qu'est-ce que je rate?
C'est ma première fois sur l'expérience multijoueur et réseau, donc je suis un peu confus.
Je vous remercie.
Réponses:
L'algorithme publié était correct, mais dans votre exemple, vous oubliez le temps nécessaire au paquet serveur pour arriver au client, donc:
Maintenant, comme vous pouvez le voir, si le client a changé son horloge à 1,15, il serait de 0,15 derrière le serveur, c'est pourquoi vous devez ajuster le Ping (alias Round Trip Time [RTT]). Voici le calcul du temps delta complet effectué sur plusieurs étapes:
Cela nous donne le temps delta correct de 1,00 secondes
la source