Réseautage et mouvement dans UNITY MMORPG

8

Je programme un serveur dédié en C # en utilisant les DLL BeamServer2. Au début, je voulais voir d'autres joueurs évoluer sur notre carte Omuni déjà créée. C'est ce que j'ai fait en envoyant simplement votre position au serveur à chaque image. Cela a fonctionné et j'ai pu jouer avec quelques amis mais le mouvement n'était pas sans décalage. J'ai donc commencé à essayer d'ajouter un lissage de mouvement et également une certaine sécurité afin qu'ils ne puissent pas simplement envoyer une fausse position au serveur sans que le serveur ne l'empêche d'atteindre les autres clients.

Ce que j'ai fait, j'ai fait un masterClient qui a un motionController sur le remotePlayer. Lorsqu'un client veut se déplacer, il se déplace localement et envoie un message au serveur en lui indiquant comment se déplacer. Le serveur prend alors sa vitesse et l'envoie au masterClient. Le masterClient déplace le remotePlayer comme le remotePlayer se déplace lui-même. Lorsqu'il arrête de bouger, il envoie un message avec sa position. Le maître client vérifie ensuite si la position à laquelle il est arrivé est aussi proche que celle qu'il a du client, si elle est réaliste selon le ping du client, le serveur le place sur la position du client.

Cela fonctionne, mais j'ai toujours un problème de décalage et je ne sais pas comment résoudre ce problème. Je dois faire un mouvement de lissage sur le client mais je me suis rendu compte que je pouvais juste lerp (x / 2, y / 2, z / 2) à la position et le mettre sur la position réelle image suivante, j'ai échoué et j'ai réessaiera bientôt. Même si cela est ajouté, je ne suis pas sûr que le lagg soit corrigé.

D'autres techniques, suggestions, questions, ...? Merci, Diede.

Diede
la source

Réponses:

8

De nombreux problèmes / tâches sont impliqués lors de la programmation de jeux réseau en temps réel "sans retard".

  • vitesse matérielle (puissance CPU requise par lecteur à la fois client et serveur)
  • distance et équipement du réseau (connexion LAN ou WAN?)
  • bande passante du serveur (combien de joueurs)

Deuxièmement, vous avez les "méchants" qui essaient toujours de tricher dans les jeux. Si votre jeu devient public, réfléchissez à ce qui se passerait si je m'assoyais et injectais de "faux" packages réseau. Demandez-vous si quelqu'un a publié des «positions inaccessibles» ou «santé / munitions complètes».

Ma suggestion pour votre architecture pour commencer, serait quelque chose comme ceci:

  • Serveur, contrôle toutes les données vitales, calcule ET valide le mouvement.
  • Le client reçoit des données sur ce qui doit être affiché à l'écran + quelques données de réflexion sur les objets en mouvement.

La plupart des FPS en temps réel, comme je le sais, font une sorte de "nous savons que vous vous déplacez dans cette direction à cette vitesse, donc nous simulons cela jusqu'à ce que nous obtenions d'autres détails du serveur"

Votre client devrait donc publier "ce qu'il demande" et pourrait même commencer à se déplacer dans cette direction, mais il pourrait être "repoussé" par le serveur si le serveur rejette le mouvement. Ici, vous devez penser, que faire si le client publie des "faux accords" en dehors de la carte, ou soudainement "saute". Le serveur doit suivre si la nouvelle position est possible à partir de son point précédent OU le serveur reçoit juste le message qui dit: "CLIENT MOVE FORWARD 200" puis le serveur traite ce que cela fera en fonction des données de la carte et du jeu.

Cela donnera un certain retard, mais encore une fois, si vous laissez le client recevoir ces données et fait un peu de calcul lui-même, il n'a pas besoin d'une mise à jour toutes les ms / trame, il peut un peu traîner sans décalage notable à l'écran.

Peut-être pouvez-vous même diviser la carte en "tuiles virtuelles" (si c'est un jeu vectoriel) afin d'avoir un moyen rapide de calculer où les objets devraient être ensuite.

World of Warcraft / Battlefield / Counterstrike

Je crois que WOW le fait aussi de cette façon. Vous appuyez sur une touche, le serveur reçoit votre mouvement "Souhaitez" et répondez par "vous vous déplacez maintenant" puis le client le montre + le serveur simule la nouvelle position sur le serveur dans une sorte de "session pr. Client". C'est le "nombre maximum de joueurs par jeu." Qui devient désagréable, car votre serveur doit garder une trace de tout le monde et le faire essentiellement "au tour par tour" - mais si vite qu'il semble en temps réel.

Donc...

Foreach (Client in GameSessionList)
{
   ParseInput();
   ParseMovement(); // including collission test
   ResponseSend(); // new positions+movement data for client and objects/other players
}
BerggreenDK
la source
3
Quel que soit le bien-fondé de sa réponse, y a-t-il une raison d'être impoli?
Konrad
J'avais l'impression que dans la plupart des jeux FPS, les clients et le serveur se heurtent indépendamment, et le serveur corrige les clients s'ils varient trop, plutôt que les clients simulant simplement.
Magus
Je ne sais pas comment chaque FPS le fait. Mais oui, par exemple. la série BF a quelque chose qu'ils appellent Netcode, ce qui signifie qu'ils effectuent les calculs localement et soumettent les résultats au serveur qui vérifie et distribue ensuite les résultats (à partir de ce que l'on m'a dit). Cela pourrait avoir à voir avec une énorme quantité de "particules" / détails qui doivent être transférés autrement. Alors que WOW est un monde plus statique et que vous n'avez pas de collision entre les personnages (en mode normal), il est donc normal de vous laisser «glisser» à travers quelqu'un d'autre.
BerggreenDK
2

La partie difficile de la compensation des retards est que vous obtiendrez des mises à jour de clients qui ne fonctionnent pas. Une commande client retardée envoyée à l'instant T peut très bien arriver après une commande client non retardée envoyée à T + 40 ms. L'application des commandes dans l'ordre où vous les obtenez entraînera toutes sortes de méchancetés. Le faire correctement d'autre part implique de remonter le temps et de rejouer toutes les commandes qui ont été émises depuis.

Il n'y a pas de solution simple, mais il existe plusieurs solutions valides. Vous pouvez en trouver un relativement facile décrit ici .

Il y a beaucoup de recherches dans ce domaine, jetez un œil!

drxzcl
la source
1

Je créerais le client comme s'il s'agissait d'un jeu hors réseau. Autrement dit, tout ce que vous faites, vous le faites immanquablement sur le client. Ajoutez ensuite, parallèlement à cela, votre code réseau. Ce code obtiendra les données de mouvement. Simple à partir des coordonnées, de la direction et de la vitesse. Il envoie simplement cela au serveur qui valide. Le serveur vous envoie un ok ou un nouveau poste.

Vous disposez donc de tout votre code client comme s'il était le seul au monde. Ensuite, il reçoit simplement de nouvelles données de correction du serveur ou un ok. Si vous appuyez sur la touche et la maintenez enfoncée pendant dix secondes, le serveur ne recevra que ces données. Vous pourriez envisager d'envoyer / recevoir des données chaque seconde même si vous maintenez simplement le bouton avant, sinon, si vous frappez un pic de retard, vous pourriez courir pour toujours.

Espen
la source