J'écris un jeu qui a beaucoup d'aspects temporels. J'utilise le temps pour aider à estimer les positions des joueurs lorsque les blocages et les paquets du réseau ne passent pas (et le temps entre la réception des paquets et non). C'est un jeu de type pacman dans le sens où un joueur choisit une direction et ne peut pas arrêter de bouger, donc ce système a du sens (ou du moins je pense que oui).
J'ai donc deux questions: 1) Comment synchroniser les horloges des jeux au début car il y a un retard dans le réseau. 2) Est-il correct de ne pas les synchroniser et de simplement supposer qu'ils sont les mêmes (mon code est indépendant du fuseau horaire). Ce n'est pas un jeu super compétitif où les gens changeraient leurs horloges pour tricher, mais quand même.
Le jeu est en cours de programmation en Java et Python (développement parallèle en tant que projet)
Réponses:
Je pense que ce n'est certainement pas OK de synchroniser l'horloge dans le système . L'utilisateur ne s'attend pas à ce que vous touchiez les paramètres du système et de nombreux systèmes ne vous le permettront même pas.
Tout ce dont vous avez besoin est d'avoir une corrélation pour convertir l'horodatage de l'horloge d'un côté à l'horloge de l'autre côté. D'un autre côté, vous avez besoin que cette corrélation soit assez précise, disons au moins au centième de seconde, si vous voulez l'utiliser pour prédire les positions des joueurs. L'horloge système ne sera jamais aussi bien corrélée entre des machines aléatoires. Vous devez donc établir la corrélation vous-même, en utilisant une variation sur le thème NTP , probablement intégré dans vos autres messages pour conserver la bande passante du réseau.
L'idée de base pourrait être qu'avec chaque paquet que vous avez envoyé, vous avez envoyé l'horodatage et le numéro de séquence et l'horodatage lorsque vous avez reçu le dernier paquet de l'autre côté. À partir de cela, vous calculez l'aller-retour: Par exemple, si le paquet Q dit qu'il a été envoyé à 1000 et que le paquet P a été reçu à 500, alors que vous avez envoyé le paquet P à 0 et que vous recevez Q à 800, l'aller-retour est (800 - 0 ) - (1000 - 500) = 300. Il n'y a aucun moyen de connaître l'assymétrie, donc vous supposez simplement que le paquet prend la moitié (150) ticks dans les deux sens. Et cet horodatage distant est en avance sur le local de 1000 - (800 - 150) = 350 ticks. L'aller-retour variera. Si vous supposez que l'horloge est raisonnablement précise, vous devez utiliser une moyenne à long terme de la corrélation.
Notez que vous ne souhaitez pas non plus utiliser l'horloge système pour l'horloge. Ils peuvent se resynchroniser à mi-chemin, vous jetant hors piste. Vous devez utiliser
clock(CLOCK_MONOTONIC)
sur Unix ouGetTickCount
sur Windows (vous ne savez pas comment ces API sont encapsulées en Java ou Python en ce moment).Remarque: L'
SO_TIMESTAMP
option socket (voir socket (7) mentionnée par ott-- dans le commentaire sur la question) serait utile pour séparer l'effet de latence de la boucle d'événement qui reçoit les paquets. Que cela en vaille la peine dépend de la précision dont vous avez besoin.la source
Comment savez-vous quelle horloge de joueur est correcte? Ce n'est pas le cas, alors utilisez une horloge de référence .
NTP est exagéré ici - vous n'avez besoin que d'une précision d'environ 1 seconde - alors utilisez rdate ou choisissez quelque chose parmi l'un des nombreux algorithmes de synchronisation d'horloge.
Si vous avez choisi une méthode, demandez à la machine de chaque joueur de prendre le temps selon cette méthode (sans changer l'horloge de son système). Quelle que soit la différence entre l'heure UTC de référence et l'heure UTC de l'horloge système des joueurs, c'est leur décalage effectif. Chaque fois que vous effectuez des calculs liés au temps, par exemple pour extrapoler des mouvements de bot ou des puces à rayons, vous tenez compte de ce décalage après avoir obtenu l'heure système. L'utilisation de l'UTC éliminera les facteurs de fuseau horaire.
la source
Je soutiens deux fois que vous ne devez pas utiliser NTP ou vous approcher de l'horloge système pour cela. Si vous examinez réellement cette exigence, vous constaterez que vous avez les besoins suivants:
Il s'agit d'un plan simplifié - je n'essaie pas de traiter des problèmes tels que la latence / les paquets perdus / etc. - mais c'est le cadre de base sur lequel tout doit être basé.
Rien de tout cela ne doit s'approcher de l'horloge système ou se préoccuper de questions telles que les différents fuseaux horaires, bien que le dernier élément puisse utiliser un fuseau horaire si vous le souhaitez. L'important est que les temps réels écoulés soient mesurés à l'aide d'un minuteur haute résolution à base zéro, de sorte qu'ils soient complètement indépendants des différences de fuseau horaire. Vous voulez trouver l'heure actuelle sur le serveur? Ajoutez simplement le temps écoulé à son temps de base de référence et vous l'avez. De même pour le client.
la source