Quels sont les problèmes rencontrés lors de la mise en œuvre de jeux multijoueurs en temps réel?

StackOverflow https://stackoverflow.com/questions/90423

Question

J'ai quelques expériences dans la création de tour par tour multijoueurs à l'aide de sockets, mais je n'ai jamais essayé de jouer à un jeu d'action en temps réel. Quels types de problèmes supplémentaires devrais-je traiter? Dois-je conserver un historique des actions des joueurs au cas où des joueurs retardés feraient quelque chose dans le passé? Dois-je vraiment utiliser des paquets UDP ou TCP suffira-t-il? Quoi d'autre?

Je n'ai pas vraiment décidé quoi faire, mais pour les besoins de cette question, vous pouvez envisager un jeu en 2D à 10 joueurs avec un mouvement XY.

Était-ce utile?

La solution

  • "serveur client" ou "peer to peer" ou quelque chose entre les deux: quel ordinateur a autorité sur quelles actions de jeu.

Avec les jeux au tour par tour, il est généralement très facile de simplement dire "le serveur a l'autorité ultime et nous avons terminé". Avec les jeux en temps réel, cette conception est souvent un excellent point de départ, mais dès que vous ajoutez de la latence, le mouvement / les actions du client se sentent insensible. Vous ajoutez donc une sorte de «masquage de latence» permettant aux clients d’affecter leur personnage ou leurs unités immédiatement pour résoudre ce problème, et vous devez maintenant traiter des problèmes de réconciliation lorsque le jeu des clients et des serveurs commence à diverger. 9 fois sur 10, cela va très bien, vous sautez ou lerpez les objets que le client a affectés à la position faisant autorité, mais 1 fois sur 10, lorsque l'objet est l'avatar du joueur ou quelque chose du genre, cette solution est inacceptable, alors vous commencez donner au client l'autorité sur certaines actions. Maintenant, vous devez réconcilier les multiples niveaux de jeu sur le serveur et vous exposer à un risque de "triche" via un client malveillant, si vous vous souciez de ce genre de chose. C’est essentiellement là où chaque téléport / dupe / quel que soit le bug / la triche qui se présente.

Bien sûr, vous pouvez commencer avec un modèle dans lequel "chaque client a autorité sur" ses "objets et ignorer le problème de tricherie (très bien dans quelques cas). Mais maintenant, vous êtes vulnérable à un impact énorme sur la simulation du jeu si ce client décède, ou même "prend juste un peu de retard dans le suivi de la simulation". En effet, chaque jeu de joueur finira par être / ressentira les effets d'un client en retard ou autrement sous-performant, soit en attendant que le client en retard rattrape son retard, soit en désynchronisant le contrôle du jeu qu'il contrôle.

  • 'synchronisé' ou 'asynchrone'

Une stratégie courante pour s’assurer que tous les joueurs travaillent dans le même état de jeu consiste simplement à s’entendre sur la liste des entrées de joueur (via l’un des modèles décrits ci-dessus), puis à faire jouer la simulation de jeu de manière synchrone sur toutes les machines. Cela signifie que la logique de simulation doit correspondre exactement, sinon les jeux ne seront plus synchronisés. C'est en fait à la fois plus facile et plus difficile qu'il n'y paraît. C'est plus facile, car un jeu consiste uniquement en code, et le code s'exécute pratiquement de la même manière lorsqu'il donne la même entrée (même des générateurs de nombres aléatoires). C'est plus difficile, car il existe deux cas où ce n'est pas le cas: (1) lorsque vous utilisez accidentellement une simulation aléatoire en dehors de votre simulation de jeu et (2) lorsque vous utilisez des flotteurs. La première solution est corrigée par des règles / assertions strictes sur les types de RNG utilisés par quels systèmes de jeu. Ce dernier est résolu en n'utilisant pas de flotteurs. (Les flotteurs ont en fait 2 problèmes, ils fonctionnent très différemment en fonction de la configuration d’optimisation de votre projet, mais même si cela a été réglé, ils fonctionnent de manière incohérente sur différentes architectures de processeur atm, lol). Starcraft / Warcraft et tous les jeux offrant une "répétition" utilisent probablement ce modèle. En fait, disposer d’un système de relecture est un excellent moyen de vérifier que vos GNA restent synchronisés.

Avec une solution asynchrone, les autorités de l’État du jeu diffusent simplement cet état entier à tous les autres clients à une certaine fréquence. Les clients prennent ces données et les intègrent dans leur portefeuille (et effectuent normalement une extrapolation simpliste jusqu'à la prochaine mise à jour). Voici où "udp" devient une option viable, car vous spammerez le jeu dans son intégralité toutes les ~ 1sec, il est inutile de supprimer une fraction de ces mises à jour. Pour les jeux qui ont relativement peu d’état (quake, world of warcraft), c’est souvent la solution la plus simple.

Autres conseils

La configuration du mode multijoueur est soumise à quelques facteurs

  1. Le protocole, il est important que vous décidiez si vous voulez TCP ou UDP. UDP génère moins de frais généraux mais sa livraison n'est pas garantie. Inversement, TCP est plus fiable. Chaque jeu aura son protocole préféré. UDP par exemple fonctionnera pour un tireur à la première personne mais ne conviendra peut-être pas pour un RTS où les informations doivent être cohérentes

  2. Pare-feu / Connexion. Assurez-vous que votre jeu multijoueur ne doit pas établir 2000 connexions sortantes et utilise un port standard, ce qui facilite le transfert de port. L’interfacer avec le pare-feu Windows constituera probablement un atout supplémentaire.

  3. Bande passante. C'est important, combien de données comptez-vous transmettre via une connexion réseau? J'imagine que cela va se résumer à tester et enregistrer le débit. Si vous avez besoin de plus de 200 Ko / s pour chaque client, vous voudrez peut-être repenser certaines choses.

  4. Charge du serveur. Ceci est également important, combien de traitement est requis par un serveur pour un jeu normal? Avez-vous besoin d’un serveur super 8 avec 16 Go de RAM pour l’exécuter? Y at-il des moyens de le réduire?

Je suppose qu'il y en a beaucoup plus, mais vous voulez vraiment un jeu qui soit confortable à jouer sur le réseau et sur une variété de connexions.

La planification est votre meilleure amie. Déterminez quels sont vraiment vos besoins.

Chargement des données: chaque ordinateur aura-t-il les mêmes modèles et graphiques, et seuls les noms et les emplacements sont déplacés sur le réseau. Si chaque joueur peut personnaliser son personnage ou d’autres objets, vous devrez déplacer ces données.

Tricher: avez-vous à vous en préoccuper? Pouvez-vous faire confiance à ce que chaque client dit. Si ce n'est pas le cas, votre logique côté serveur sera différente de votre logique côté client. Imaginez ce cas simple, chacun de vos 10 joueurs peut avoir une vitesse de déplacement différente à cause des power-ups. Pour minimiser les tricheries, vous devez calculer la distance que chaque joueur peut parcourir entre les mises à jour de communication depuis le serveur, sinon un joueur pourrait accélérer et rien ne les arrêterait. Si un joueur est toujours un peu plus rapide que prévu ou effectue un saut unique, le serveur le repositionnera simplement à l'emplacement le plus proche possible, car il s'agit probablement d'un décalage d'horloge ou d'une interruption des communications. Cependant, si un joueur se déplace constamment deux fois plus loin que possible, il peut être prudent de le mettre à la porte. Plus vous maîtrisez les calculs, plus le nombre de parties du jeu que vous pouvez vérifier sur le serveur est important, plus le jeu sera cohérent, ce qui rendra la tricher plus difficile.

Comment se fait peer to peer: même si le jeu va être peer to peer, vous voudrez probablement qu’un seul joueur commence un jeu et l’utilise comme serveur, c’est beaucoup plus facile que d’essayer de gérer certains plus d'approches basées sur le cloud. S'il n'y a pas de serveur, vous devez utiliser un protocole pour résoudre les conflits entre 2 machines dont l'état du jeu est incohérent.

Encore une fois, la planification est votre meilleure amie. Planifiez, planifiez, planifiez. Si vous pensez suffisamment à un problème, vous pouvez vous débrouiller pour résoudre la plupart des problèmes. Ensuite, vous pouvez commencer à penser à ceux que vous n'avez pas encore résolus.

Quelle est l'importance d'éviter de tricher? [Pouvez-vous faire confiance aux informations provenant d’un client ou peuvent-elles être authentifiées et authentifiées?]

Modèle d'objet Comment les objets sont-ils communiqués d'une machine à une autre? Comment les actions sont-elles effectuées sur un objet?

Faites-vous client / serveur ou peer to peer?

Nombres aléatoires Si vous effectuez un peer to peer, vous devez les garder synchrones et synchroniser les nombres aléatoires.

Si vous êtes client / serveur, comment gérez-vous le lag? [Jugement mort?]

Le codage réseau pose de nombreux problèmes non triviaux.

Découvrez RakNet, le téléchargement de code et les groupes de discussion sont gratuits.

TCP convient si vous utilisez un réseau local. Mais si vous voulez jouer en ligne, vous devez utiliser UDP et implémenter votre propre couche de type TCP: il est nécessaire de passer les routeurs NAT.

Vous devez choisir entre une communication Peer-to-Peer ou Client-Serveur. Dans le modèle client-serveur, la synchronisation et l'état du monde sont plus faciles à mettre en œuvre, mais vous pouvez avoir un manque de réactivité en ligne. En mode peer-to-peer, c'est plus compliqué, mais plus rapide pour le joueur.

Ne conservez pas l'historique des actions des joueurs pour les besoins du jeu (faites-le, mais uniquement pour la fonctionnalité de rejeu). Si vous atteignez un point où cela est nécessaire, préférez faire attendre chaque joueur.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top