Comment se présentent les protocoles des jeux de stratégie en temps réel tels que Starcraft et Age of Empires?

Je suis intéressé par la façon dont les protocoles (et la boucle de jeu) fonctionnent pour ce type de jeux; tout pointeur ou sharepoint vue est apprécié.

Je suppose que la boucle principale aurait un état mondial qui serait avancé de quelques “ticks” par seconde, mais comment les commandes des joueurs sont-elles exécutées? Quel type de données doit aller et venir?

    Je peux entrer dans beaucoup de détails à ce sujet, mais d’abord, lisez «1500 archers» http://www.gamasutra.com/view/feature/3094/1500_archers_on_a_288_network_.php et cela répondra à plusieurs de vos questions. Voici un résumé: Premièrement, la plupart des jeux utilisent le protocole UDP en raison de la nature en temps réel du jeu. La boucle de jeu ressemble à ceci:

    1. lire les données du réseau
    2. faire des prédictions côté client et comparer avec ce que le réseau dit que vos objects doivent être réellement
    3. gâcher avec la physique pour truquer ce que le réseau dit avec ce que votre état de jeu local est
    4. renvoyer des données sur le réseau en fonction de ce que vous avez fait cette image (le cas échéant)
    5. rendre

    Cela simplifie énormément la tâche et «relier la physique» pourrait facilement être un livre de 200 pages, mais il faut prédire où se trouve quelque chose, obtenir des données du serveur, mais indiquer exactement où un object devait être / devrait be, puis en interpolant ces valeurs pour que l’object apparaisse suffisamment proche de l’endroit où il est supposé être celui que personne ne remarque. C’est extrêmement critique dans les jeux de tir à la première personne, mais pas autant dans les stratégies en temps réel.

    Pour la stratégie en temps réel, ce qui se passe généralement, c’est un système au tour par tour où le temps est divisé en segments discrets appelés «tours» qui se produisent séquentiellement et chaque tour a un nombre généré par une fonction monotone qui garantit des valeurs sans cesse croissantes. des doublons. A chaque tour n, chaque client envoie un message à tous les autres clients avec l’action prévue au tour n + m, où m est un nombre arbitraire qui est généralement assez petit et qui peut être déterminé par des essais et des tests. Une fois que tous les clients ont envoyé l’action prévue, chaque client exécute toutes les actions envoyées au tour n + m. Cela introduit un léger retard lors de la commande d’une action par l’utilisateur et lors de son exécution, mais cela n’est généralement pas perceptible.

    Il existe plusieurs techniques qui peuvent également être utilisées pour manipuler le temps. Par exemple, si vous mettez une unité en surbrillance et que vous lui dites de bouger, cela produira un son et une animation quand elle commencera à bouger mais ne bougera pas tout de suite. Cependant, le message réseau d’une intention de déplacer cette unité est envoyé immédiatement, de sorte qu’au moment où l’écran répond à l’entrée du lecteur, les messages réseau ont déjà été envoyés et acquittés. Vous pouvez la modifier en introduisant un petit délai (environ 100 ms) entre le clic de la souris et la réponse de l’object du jeu. Ce n’est généralement pas perceptible par le joueur mais 100ms est une éternité dans un jeu LAN et même avec une connexion haut débit sur un ordinateur personnel, le ping moyen est d’environ 15-60ms, ce qui vous laisse suffisamment de temps pour envoyer le paquet le déménagement.

    En ce qui concerne les données à envoyer, il existe deux types de données dans les jeux: déterministes et non déterministes. les actions déterministes sont fondées sur la physique du jeu, de sorte que lorsque l’action commence, il y a une garantie à 100% que je peux prédire le résultat de cette action. Ces données ne doivent jamais être envoyées sur le réseau, car je peux déterminer ce qu’il sera sur le client en fonction de l’état initial. Notez que l’utilisation d’un générateur de nombres aléatoires avec la même graine sur chaque client transforme les événements “aléatoires” en comportement déterministe. Les données non déterministes sont généralement entrées par l’utilisateur, mais il est possible de prédire ce que les entrées d’un utilisateur sont susceptibles de représenter dans de nombreux cas. La manière dont ces paires se trouvent dans un jeu de stratégie en temps réel est que l’événement non déterministe est une sorte d’ordre à l’un de mes objects de jeu. Une fois que l’object de jeu a été commandé de bouger, la manière dont il se déplace est déterministe à 100%. Par conséquent, tout ce que vous avez besoin d’envoyer sur le réseau est l’ID de l’object, la commande donnée (en faire un enum pour économiser la bande passante) et la cible de la commande (le cas échéant, un sort ne peut avoir de cible s’il s’agit d’un zone d’affectation mais une commande de déplacement a une destination finale). Si l’utilisateur clique sur 100 fois pour effectuer un déplacement d’unité, il n’est pas nécessaire d’envoyer une commande de déplacement distincte pour chaque clic, car elles se trouvent toutes dans la même zone. bande passante

    Une dernière astuce pour gérer un éventuel délai entre une commande et son exécution est quelque chose appelé filtre de perception local. Si j’obtiens un ordre de déplacement t une fois que la commande a été passée, je sais quand l’unité doit commencer à bouger et je connais sa destination finale. Plutôt que de téléporter l’unité pour l’obtenir là où elle est censée être, je peux commencer son mouvement tardivement et ensuite me lancer dans la physique pour l’accélérer légèrement afin qu’elle puisse rattraper son retard, puis la ralentir à mettez-le au bon endroit. La valeur exacte dont vous avez besoin pour accélérer est également relative et le test de jeu est le seul moyen de déterminer la valeur correcte, car il suffit de “se sentir bien” pour qu’il soit correct. Vous pouvez faire la même chose en tirant des balles et des missiles et c’est très efficace pour cela. La raison pour laquelle cela fonctionne est que les humains ne sont pas terriblement doués pour voir de subtils changements de mouvements, en particulier si un object se dirige directement vers eux ou s’en éloigne, donc ils ne le remarquent pas.

    La prochaine chose à envisager est de réduire la bande passante. N’envoyez pas de messages aux clients qui ne pourraient pas voir ou interagir avec une unité en mouvement. N’envoyez pas le même message encore et encore car l’utilisateur clique. N’envoyez pas de messages immédiatement pour les événements sans effet immédiat. Enfin, n’exigez pas de reconnaissance pour les événements qui seront périmés s’ils ne sont pas reçus. Si je ne reçois pas de mise à jour de mouvement, au moment de retransmettre cette mise à jour, sa valeur sera tellement ancienne qu’elle ne sera plus pertinente. Il est donc préférable d’envoyer un autre mouvement et d’utiliser un filtre de perception local une spline cubique pour interpoler le mouvement afin qu’il soit plus correct ou quelque chose de cette nature. Cependant, un événement critique, tel que “vous êtes mort” ou “votre drapeau a été pris”, doit être reconnu et retransmis si nécessaire. J’enseigne la programmation de jeux en réseau chez Digipen, alors n’hésitez pas à poser d’autres questions à ce sujet, car je peux probablement vous fournir une réponse. La programmation de jeux en réseau peut être assez compliquée, mais en fin de compte, il s’agit de faire des choix dans votre implémentation et de comprendre les conséquences de votre choix.

    Découvrez Battle for Wesnoth.

    http://www.wesnoth.org/

    C’est gratuit, open source, et totalement génial. Vous pouvez apprendre beaucoup de creuser dans sa source.

    Discussion de l’architecture du réseau Age of Empires ici

    À mon humble avis, ce style d’architecture basée sur la lecture répétée en peer-to-peer est impressionnant, mais c’est un peu une impasse pour plus de huit joueurs.