La physique ne se synchronise pas correctement sur le réseau lors de l'utilisation de Bullet

11

J'essaie d'implémenter un système physique client / serveur à l'aide de Bullet, mais j'ai des problèmes pour synchroniser les choses.

J'ai implémenté un état de mouvement personnalisé qui lit et écrit la transformation de mes objets de jeu et cela fonctionne localement, mais j'ai essayé deux approches différentes pour les jeux en réseau:

  1. Les objets dynamiques sur le client qui se trouvent également sur le serveur (par exemple, les débris aléatoires et autres éléments sans importance) sont rendus cinématiques. Cela fonctionne correctement mais les objets ne se déplacent pas très facilement
  2. Les objets sont dynamiques sur les deux mais après chaque message du serveur indiquant que l'objet a bougé, j'ai défini la vitesse linéaire et angulaire sur les valeurs du serveur et j'ai appelé btRigidBody :: procéderToTransform avec la transformation sur le serveur. J'appelle également btCollisionObject :: activate (true); pour forcer l'objet à mettre à jour.

Mon intention avec la méthode 2 était essentiellement de faire la méthode 1 mais de détourner Bullet pour faire la prédiction d'un pauvre homme au lieu de faire la mienne pour lisser la méthode 1, mais cela ne semble pas fonctionner (pour des raisons qui ne sont pas claires à 100% pour moi même en passant par Bullet) et les objets se retrouvent parfois à des endroits différents.

Suis-je dans la bonne direction? Bullet semble avoir son propre code d'interpolation intégré. Cela peut-il m'aider à améliorer la méthode 1? Ou mon code de méthode 2 ne fonctionne-t-il pas parce que je le piétine accidentellement?

EDIT: Un autre problème avec la méthode 1 que je viens de remarquer est que la réponse de collision sera très éloignée pour les collisions contre des objets non synchronisés. Les corps cinétiques tirent parfois à l'infini car ils ne peuvent pas être repoussés.

Lucas
la source
Quelques éléments qui pourraient vous aider à obtenir une réponse: Quelle langue / quel moteur utilisez-vous? De quel type de connexion s'agit-il? Quelle est la gravité du déficit de synchronisation par rapport au ping vers le serveur?
Fibericon
2
La deuxième option ne fonctionne pas car vous ne définissez les vitesses sur les valeurs du serveur qu'après quelques images, donc entre chaque paquet, il y a quelques images où les choses peuvent dériver. Je recommanderais de lire tous les articles de Gaffer sur la physique des jeux, vous devriez probablement d'abord lire `` fixer votre horodatage '' mais voici le dernier article qui parle de la physique en réseau gafferongames.com/game-physics/networked-physics
Roy T.
J'utilise un moteur développé en C ++. Cependant, je suis presque sûr que le déficit de synchronisation n'est pas si grave, probablement 1 image sur ping si je devais deviner, mais je fais toujours principalement des tests LAN uniquement. Je vais consulter ces articles et oui, vous avez raison de dire que les vitesses sont coupées. Mais les choses sont ainsi loin, comme la caisse est sur la carte. Le réglage explicite de la transformation ne devrait-il pas finalement rendre la chose généralement conforme? (même si ce n'est pas encore joli, trémousse, etc.)
Lucas
J'ai lu le post de Gaffer et c'était instructif mais il semblait concerner principalement le mouvement des joueurs, ce que je travaille déjà. J'ai lu autour et il semble que mon code de méthode 2 soit pratiquement identique à la méthode utilisée dans le moteur Unreal . Ils ne fournissent pas beaucoup de détails mais je me demande si l'idée est bonne mais mon utilisation de Bullet est tout simplement incorrecte.
Lucas
Une lecture intéressante, qui est en partie liée à votre sujet: gamasutra.com/view/feature/3094/… . Il s'agit d'un rts et ce n'est pas de la physique, mais ils arrivent au point où ils doivent synchroniser une simulation sur le serveur et les clients. La façon dont ils le font? Ils exécutent des simulations indépendantes sur le client et le serveur, mais le serveur envoie des packages qui garantissent que la simulation client ne diverge pas et est corrigée, si cela se produit ...
tom van green

Réponses:

4

Vous avez besoin d'une bonne prédiction côté client .

Vous devriez vraiment lire en détail le lien que Roy T. vous a fourni dans son commentaire . Il décrit ce qu'il faut faire avec l'entrée du joueur et la physique des personnages, mais le principe reste le même pour la "physique pilotée par le serveur".

Ce n'est pas trivial à implémenter mais en quelques mots, pour les objets de jeu qui doivent être synchronisés:

  • Exécutez la physique sur le serveur et le client;
  • Le serveur envoie des mises à jour régulièrement;
  • Le client réajuste continuellement et en douceur son monde physique aux valeurs du serveur.

Alors oui, vous vous dirigez dans la bonne direction avec votre méthode 2. Il ne suffit pas de remplacer les valeurs, vous obtiendrez des sauts sur le client, ce que vous devez faire est d'interpoler en douceur et en continu sur les valeurs du serveur.

Pour votre bug actuel, je ne connais pas Bullet, mais certaines valeurs vous manquent probablement, par exemple, vous avez défini les vitesses linéaires et angulaires, mais avez-vous défini les accélérations?

Laurent Couvidou
la source
Merci! Cela me fait me sentir mieux que je suis sur la bonne voie. Je vais passer en revue mon code avec un peigne à dents fines maintenant. Peut-être que certaines notifications ne sont pas renvoyées ou, comme vous le dites, il me manque une valeur car la méthode 2 devrait (saccadée) fonctionner.
Lucas
3

Ce que je fais personnellement, c'est que celui qui héberge le jeu crée le monde phsyics et synchronise les objets avec les clients. Même si c'est un schéma de réseau p2p, je base toujours le moteur physique sur l'un des clients des joueurs.

Il n'est même pas nécessaire de synchroniser d'autres éléments physiques que j'utilise qui sont uniquement des bonbons pour les yeux.

Dans un prototype que j'ai fabriqué il y a quelque temps, appelé "kettlezerkerker", j'ai exécuté de la physique sur l'hôte et les effets de particules (utilisant également la physique) n'étaient pas synchronisés sur un réseau mais indépendants pour chaque client, car ils étaient agréables pour les yeux.

tsturzl
la source
Merci, c'est une façon de procéder. Cependant, cela n'entraîne pas de belles réponses de collision sur le client pour les choses que le client fait et les choses pour les yeux ne vont pas toujours interagir correctement car elles ne peuvent pas repousser les choses du serveur (au moins dans ce pas de temps). Je pense que cela doit être possible car des moteurs comme Unreal et Source semblent le faire.
Lucas
les bonbons pour les yeux n'ont pas besoin de se synchroniser, ils peuvent être calculés par client. la réponse sur le client est calculée sur le serveur, les coordonnées du client sont juste calculées et renvoyées, vous n'envoyez pas de rappel au client en disant qu'il est entré en collision, cela aurait probablement l'air horrible.
tsturzl
2

Il est impossible de mettre en œuvre des mondes de physique synchrone de réseau. Petite différence à l'étape N, bien plus grande différence à l'étape N + 1 Vous ne pouvez pas appliquer de forces ou d'impulsions pour garder la synchronisation et avoir l'air réaliste.

Solutions:-

  1. Vous pouvez envisager de synchroniser seulement quelques objets comme des personnages ou des voitures de course, surtout s'ils sont cinématiques. Mais la plupart des régions du monde ne seraient pas synchronisées pour paraître réalistes.

  2. Vous pouvez avoir un univers physique sur le serveur et diffuser les positions et les vitesses des objets aux clients.

Max
la source
Vous pouvez essayer de jouer à un jeu en réseau avec la physique pour voir que les mondes ne sont pas synchronisés. Par exemple, Need For Speed ​​World est gratuit et propose des modes multijoueurs et une physique de base. (boîtes sur la route et objets destructibles)
Max
Je ne suis pas sûr de vous suivre exactement. Je suis presque sûr que c'est possible car de nombreux jeux permettent aux joueurs de jeter des caisses (par exemple). Il semble que votre option 2 soit similaire à mon option 2, mais je n'arrive pas à faire en sorte que Bullet accroche proprement les objets à leurs positions de serveur. C'est peut-être mon problème racine?
Lucas
1
Non. Habituellement, c'est une illusion de synchrone. Si vous comparez des écrans, vous verrez que lorsque vous rebondissez dans des boîtes, les boîtes volent dans des directions différentes. ou les boîtes ne sont pas du tout de la physique (juste des animations ed). Le nombre de boîtes est différent. Quand je dis animation, je veux dire qu'il n'y a pas d'animation physique derrière les mouvements. Ils ne font aucune astuce pour que l'image soit quelque peu synchronisée, mais ce ne sont pas des mondes de physique synchrone. Vous devriez regarder et comparer comment ils se déplacent dans différents jeux.
Max