Comment compenser les objets en mouvement avec la prédiction côté client?

11

J'implémente un serveur de jeu qui prend en charge la mêlée de type Star Control . Vous avez donc des navires qui volent et tirent, avec une physique super simple de vitesse / accélération / amortissement pour conduire le mouvement.

entrez la description de l'image ici

J'ai lu Valve, Gafferon et Gambetta et mis en œuvre l'algorithme de Gambetta pour la prédiction client:

entrez la description de l'image ici

La prédiction client fonctionne sur le vaisseau joueur en mettant à jour sa position depuis le serveur au fur et à mesure, puis en réappliquant l'entrée non encore traitée par le serveur au vaisseau joueur.

Malheureusement, cela ne fonctionne pas bien pour mon jeu. Je crois que cela a à voir avec le fait que l'exemple de Gambetta ne prend pas en compte les objets qui sont déjà en mouvement, ou les commandes qui sont mises à jour pas à pas. (par "étape", je veux dire le cadre). Donc, dans mon jeu, le joueur appuie pour accélérer le vaisseau (déjà en mouvement), qui continue de se déplacer sur le client, envoie la commande au serveur et reçoit généralement l'instantané du monde du serveur à l'étape suivante. Je reçois quelque chose de plus comme:

entrez la description de l'image ici

La commande player s'exécute à l' étape 3 du client , mais sur le serveur, elle ne s'exécute qu'à l' étape 5 du serveur . Au moment où l'instantané du monde est reçu par le client à l' étape 6 du client , la prédiction est loin, en particulier à des vitesses plus rapides.

Le nœud du problème est que le client exécute la commande à l' étape 5 , mais le serveur l'exécute à l' étape 6 . J'ai pensé à envoyer peut-être l'étape client avec la commande, et faire revenir le serveur et réexécuter la commande avec le pas de temps client. Cela pourrait conduire à une foule d'autres problèmes - comme ce qui arrive aux commandes reçues depuis la restauration, ou comment les clients tricheurs peuvent exploiter en changeant l'étape envoyée.

Lire et regarder des vidéos comme celle-ci de Google mentionne une approche différente, où vous modifiez progressivement la position du joueur pour correspondre à celle de l'instantané en quelques étapes.

Mes questions:

  • Pouvez-vous faire fonctionner l'algorithme de Gambetta avec un mouvement de pas constant? Ou est-il conceptuellement incompatible avec mon jeu?

  • L'interpolation progressive sur les étapes est-elle alors la bonne voie à suivre? Si c'est le cas, comment interpoler un objet déjà en mouvement depuis la position du client pour correspondre à celui qui vient d'être reçu du serveur?

  • Ces méthodes, l'interpolation progressive et l'algorithme de Gambetta peuvent-ils fonctionner en tandem, ou sont-ils mutuellement exclusifs?

OpherV
la source
J'ai fait la même chose et j'ai rencontré exactement le même problème. Dès que j'ai ajouté des vitesses en appliquant l'état du serveur et en réappliquant les entrées, on s'est débarrassé des changements de vitesse déjà traités. J'ai essayé de réappliquer toutes les mises à jour depuis le dernier message reçu, mais ce n'est pas encore très fluide. Avez-vous déjà trouvé une solution à cela?
MakuraYami
@MakuraYami Oui - j'ai commencé à écrire un article décrivant la solution. Mettra à jour bientôt!
OpherV
J'ai travaillé davantage sur mon projet et trouvé une solution utilisable et quelques bonnes ressources pour parler de ce problème. Je suis intéressé à discuter plus avant, à comparer des solutions, etc. Faites-moi savoir où je peux vous contacter :)
MakuraYami
@makurayami mon nom d'utilisateur sur Gmail
OpherV

Réponses:

5

Pendant les 6 mois depuis que j'ai posé cette question, j'ai fini par développer un serveur de jeu open source complet pour faire face à ce problème exact (et bien d'autres!): Http://lance.gg

entrez la description de l'image ici

La R&D impliquée me permet désormais de répondre à mes propres questions:

  • Pouvez-vous faire fonctionner l'algorithme de Gambetta avec un mouvement de pas constant? Ou est-il conceptuellement incompatible avec mon jeu?

    L'algorithme de Gambetta ne fonctionnera pas lorsque le mouvement de l'entité n'est pas déterministe (à partir du POV du client). Si une entité peut être affectée sans contribution de la physique ou d'autres acteurs, par exemple, une approche plus détaillée doit être adoptée.

  • L'interpolation progressive sur les étapes est-elle alors la bonne voie à suivre? Si c'est le cas, comment interpoler un objet déjà en mouvement depuis la position du client pour correspondre à celui qui vient d'être reçu du serveur?

    Cela touche à un sujet différent, à savoir la réconciliation des mises à jour du serveur par le client. L' interpolation progressive fonctionne, mais pour les jeux au rythme très rapide comme celui de la question, il est préférable d'implémenter réellement l' extrapolation

  • Ces méthodes, l'interpolation progressive et l'algorithme de Gambetta peuvent-ils fonctionner en tandem, ou sont-ils mutuellement exclusifs?

    Ils peuvent fonctionner ensemble, mais uniquement si le mouvement d'entité est déterministe à partir du PDV client. Cela ne fonctionnera donc pas si l'entité est affectée par la physique ou la pseudo-physique comme l'insertion, le glisser, etc.

OpherV
la source
1

Votre jeu semble être trop "en temps réel" pour penser en termes de pas de temps. Je ne penserais en termes de "tours" que si le jeu pouvait être considéré "au tour par tour". Sinon, abandonnez simplement l'idée de virages ou de marches. Tout devient alors plus facile :)

Notez que vous prédisez localement pour votre joueur et n'interpolez que pour d'autres entités (comme expliqué dans le 3ème article de la série). La façon de gérer les mises à jour du serveur pour les objets qui étaient déjà en mouvement est la réconciliation côté serveur, expliquée dans la moitié inférieure du 2e article (celui vers lequel vous avez établi un lien).

J'espère que cela t'aides :)

ggambett
la source
Juste pour clarifier - par «étape», je veux dire «cadre», qui s'exécute 60 fois par seconde. Je l'appelle étape (et non image) pour différencier la progression réelle du jeu du rendu, et idéalement, ils sont tous deux synchronisés à 60 par seconde. J'ai déjà implémenté votre version de réconciliation côté serveur qui fonctionne à merveille. Cette question ne concerne que le vaisseau du joueur - qui se déplace constamment quelle que soit la commande du joueur (en raison de l'insertion). C'est là que réside ma difficulté. Des réflexions là-dessus? :)
OpherV
Les cadres sont différents des étapes. Les étapes se déplacent dans un ordre constant et prévisible. Les images se déplacent pendant une durée variable, de sorte que toute progression doit être multipliée par le temps delta pour cette image.
Tealr
@Tealr en effet, c'est pourquoi j'ai utilisé le terme "étape" pour commencer - je voulais juste préciser que l'utilisation de "étape" n'est pas limitée aux jeux au tour par tour, et dans mon jeu, une étape prend exactement 1 / 60 de seconde quel que soit le rendu.
OpherV
Juste quelque chose que je note pour mes propres expérimentations: 1 / 60s. est inhabituellement rapide et je parie que la plupart des jeux en ligne avec plus de participation 1x1 fonctionnent à 1 / 10s. mises à jour ou à peu près.
Patrick Hughes