36 votes

Synchronisation des jeux multi-joueurs

J'ai mis en place une architecture serveur/client, où tous les changements d'état sont envoyés à la fonction, validés et diffusés à tous les clients connectés. Cela fonctionne plutôt bien, mais le système ne maintient pas la synchronisation entre les instances clientes du jeu pour le moment.

S'il y avait un décalage de 5 secondes entre le serveur et un client particulier, celui-ci recevrait le changement d'état 5 secondes après le reste des clients, ce qui le laisserait avec un état de jeu non synchronisé. J'ai cherché différentes façons d'implémenter un système de synchronisation entre les clients mais je n'ai rien trouvé jusqu'à présent.

Je suis novice en matière de programmation réseau, et pas assez naïf pour penser que je peux inventer moi-même un système fonctionnel sans y consacrer beaucoup de temps. L'idée que j'ai eue, cependant, est de garder une sorte de système de temps, de sorte que chaque changement d'état serait connecté à un horodatage spécifique dans le jeu. De cette façon, lorsqu'un client reçoit un changement d'état, il sait exactement à quel moment du jeu le changement s'est produit, et il est capable d'établir une corrélation avec le décalage. Le problème avec cette méthode est que dans ces n Les secondes de décalage que le jeu aurait eu se poursuivraient du côté client, et donc le client devrait revenir en arrière pour mettre à jour le changement d'état, ce qui serait certainement désordonné.

Je cherche donc des articles discutant des sujets ou des algorithmes qui le résolvent. Peut-être que toute ma conception du fonctionnement du système multijoueur est défectueuse, dans le sens où l'instance de jeu d'un client ne devrait pas être mise à jour à moins que la notion ne soit reçue du serveur ? Actuellement, les clients se mettent à jour dans leur boucle de jeu en supposant que les états n'ont pas changé.

0 votes

Je crois que vous devriez reconsidérer la réponse acceptée. Havenard n'a rien dit au sujet du calcul à l'aveugle ou de toute autre technique de dissimulation du décalage utilisée aujourd'hui. Les jeux ne se contentent pas de déclarer que "les joueurs souffrant de lag doivent accepter leur condition" ; ils font un effort pour cacher le lag afin de rendre le jeu plus jouable. Après tout, si je jouais à un jeu où les gens sautaient partout et où je ne pouvais pas jouer, je quitterais ce jeu assez rapidement.

17voto

Martin Harris Points 18057

L'approche de base pour cela s'appelle Dead Reckoning et un article très intéressant à ce sujet peut être trouvé ici. Il s'agit essentiellement d'un algorithme de prédiction de la position des entités entre deux mises à jour du serveur.

Il existe des méthodologies plus avancées qui s'appuient sur ce concept, mais c'est un bon point de départ.


Vous trouverez également une description de la façon dont cela est géré dans le moteur source (le moteur de Valve pour le premier jeu Half Life). aquí Le principe est fondamentalement le même - jusqu'à ce que le serveur vous dise le contraire, utilisez un algorithme de prédiction pour déplacer l'entité le long d'un chemin attendu - mais cet article traite de l'effet que cela a sur la tentative de tirer quelque chose plus en profondeur.

11voto

Kevin Points 3692

Les meilleures ressources que j'ai trouvées dans ce domaine sont ces deux articles de Valve Software :

7voto

Kylotan Points 14114

Il n'y aura jamais de moyen de garantir une synchronisation parfaite entre plusieurs points de vue en temps réel - les lois de la physique rendent la chose impossible. Si le soleil explosait maintenant, comment pourriez-vous garantir que les observateurs sur Alpha Centauri verraient la supernova en même temps que nous sur Terre ? L'information prend du temps à voyager.

Par conséquent, vous avez le choix entre modéliser tout de manière précise avec une latence qui peut différer d'un spectateur à l'autre (ce qui est le cas actuellement), ou modéliser de manière imprécise sans latence et de manière largement synchronisée entre les spectateurs (c'est là que la prédiction, le calcul à l'aveugle et l'extrapolation entrent en jeu). Les jeux lents, comme la stratégie en temps réel, ont tendance à suivre la première voie, tandis que les jeux rapides suivent la seconde.

En particulier, vous ne devez jamais supposer que le temps de parcours sera constant. Cela signifie que le simple envoi de messages de démarrage et d'arrêt pour déplacer des entités ne suffira jamais, quel que soit le modèle. Vous devez envoyer des mises à jour périodiques de l'état réel (généralement plusieurs fois par seconde pour les jeux rapides) afin que le destinataire puisse corriger les erreurs dans ses prédictions et interpolations.

2voto

Havenard Points 9023

Si le client voit les événements se produire à la vitesse à laquelle le serveur le nourrit, ce qui est la façon normale de faire (j'ai travaillé avec des protocoles d'Ultima Online, KalOnline et un peu de World of Warcraft), alors ce retard momentané de 5 secondes lui ferait juste recevoir ces 5 secondes d'événements d'un coup et voir ces événements passer très vite ou presque instantanément, comme les autres joueurs le verraient "marcher" très vite sur une courte distance si ses sorties retardaient aussi. Après cela, tout se déroule à nouveau normalement. En fait, à l'exception de la normalisation graphique et physique, je ne vois pas de besoins particuliers pour que la synchronisation se fasse correctement, elle se synchronise toute seule.

Si vous avez déjà joué à des jeux Valve sur deux ordinateurs proches, vous remarquerez qu'ils ne se soucient guère de détails mineurs comme "l'endroit exact où vous êtes mort" ou "l'endroit où votre cadavre a volé". Tout dépend du côté client et est totalement affecté par la latence, mais cela n'a rien à voir.

Après tout, les joueurs en retard doivent accepter leur condition, ou fermer leur satanée eMule.

0 votes

Donc vous dites que je devrais retourner dans le passé sur mon client et remettre à jour l'état du jeu ? Disons que j'ai un joueur qui se déplace vers le sud. Il va continuer à le faire sur toutes les machines clientes sans que le serveur ne lui dise quoi que ce soit. Si, à un moment donné, il commence à se déplacer vers le nord, tous les clients continueront à le percevoir comme se déplaçant vers le sud jusqu'à ce qu'ils reçoivent une notification, et une fois qu'ils l'auront fait, ils devront revenir en arrière dans le temps et mettre à jour sa position puisqu'il ne se déplaçait pas vers le sud tout ce temps. Puisqu'il n'est pas possible de revenir en arrière et de réévaluer, je suppose que je pourrais envoyer au joueur un positionnement absolu à un intervalle spécifique.

0 votes

C'est comme ça que ça devrait être fait. Cette interpolation de mouvement doit avoir une limite, il restera quelques pas en avant à moins que le serveur n'intervienne avec de nouvelles informations sur ses mouvements.

0 votes

Dans KalOnline, il est fait par la correction des coordonnées, chaque étape qu'il fait met à jour le point xyz du joueur dans le monde avec 3 octets signés pour X, Y et Z. Les autres clients se contentent d'interpoler la position du modèle au point xyz final. L'interpolation n'est même pas sautée lorsque de nouveaux changements surviennent, elle considère simplement le nouveau point xyz final à partir de ce moment.

1voto

Lasse V. Karlsen Points 148037

La meilleure solution consiste à renvoyer les modifications au client à partir du futur, de sorte qu'elles arrivent au client au même moment que pour les autres clients qui n'ont pas de problèmes de décalage.

0 votes

C'est une réponse évidente, mais qui ouvre sûrement une faille potentielle pour les personnes qui gèlent volontairement leur machine avant de l'accélérer juste après un rafraîchissement ? Avoir la possibilité d'effectuer des actions avant tout le monde ?

1 votes

Bien sûr que ça n'a pas de sens, je pensais que c'était évident :P

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X