Performances côté serveur FPS multijoueur

12

Ceci est lié aux performances MMO, sauf que la question concerne la bande passante. Il s'agit de la charge du processeur.

J'ai mis en place un simple FPS en utilisant node.js et webGL. C'est extrêmement simple, un peu comme le clone BuddyMaze de MIDI Maze. Il se passe très peu de choses, tout le monde se déplace en deux dimensions (sans hauteur), tire des projectiles simples et court dans les murs.

En ce moment, si je fais plusieurs connexions au serveur où chaque joueur tire rapidement tout en tournant en rond, je peux obtenir environ 15 à 20 joueurs dans le jeu avant que le serveur n'épuise un cœur et ralentisse. Et c'est lors de l'exécution à 30 ips sur le serveur. À 10 ips, j'obtiens environ 25 à 30 connexions. C'est assez mauvais, car le jeu aura beaucoup plus à faire bientôt et je devrai adapter plus de joueurs pour que cela soit faisable.

Mon frère vient de souligner quelques statistiques sur le serveur TF2 de son collègue. Son serveur est moins puissant que le nôtre, mais il exécute TF2, évidemment un jeu beaucoup plus complexe, à 500 ticks par seconde, avec 36 utilisateurs par cœur. De plus, nous consommons actuellement beaucoup plus de bande passante qu'eux, mais nous n'avons pas encore essayé de le réduire.

Comment est-ce possible? Quels types d'astuces sont là pour augmenter les performances du serveur à cette ampleur? Certaines choses que je connais comprennent:

  • Réduire le framerate sur le serveur et interpoler les positions sur le client. J'ai obtenu un certain avantage, mais le serveur TF2 ne s'en soucie clairement pas.
  • Faire des choses coûteuses comme la détection de collision sur le client, et la vérifier rarement sur le serveur. Je ne l'ai pas encore déplacé, je le ferai ce soir. Malgré cela, je ne m'attends pas à un gain aussi énorme.
  • Divisez le terrain de jeu en régions (arbres quadruples) pour minimiser les calculs. Je n'ai pas encore eu l'occasion de le faire.
  • J'ai considéré la malheureuse possibilité que node.js soit juste beaucoup plus lent que ce que TF2 utilise, et peut ne pas convenir à ce type de tâche à haute intensité.
  • Est-ce tout dans la magie de configuration du serveur?

Alors, quelles sont les autres astuces de l'industrie pour ne faire que le minimum requis sur le serveur tout en ayant une expérience de jeu sans faille? Il y a un gros conflit entre «s'en remettre au client pour gagner du temps sur le processeur» et «ne pas faire confiance au client», alors peut-être qu'il est utile de savoir où la ligne est tracée dans diverses situations?

Mise à jour

Le profilage est vraiment le seul mantra que j'ai jamais trouvé qui soit absolument infaillible. J'ai rapidement enroulé certaines fonctions de synchronisation autour de mon code (merci FP!) Et découvert ce à quoi je ne m'attendais pas: l'acte de diffuser les données aux clients représente presque tout le temps d'exécution. Plus précisément, environ 90% de celui-ci. Des tests supplémentaires ont montré que ce temps dépend à la fois du nombre de clients et de la taille des données, mais plus encore de ces derniers. Sur une charge de 20 utilisateurs, j'ai réduit mon temps de diffusion de 90%, de 24 ms à un peu plus de 2 ms en envoyant uniquement "{}" au lieu des données complètes. Mais avec seulement 5 utilisateurs, la diffusion prend environ 0,5 ms. J'ai donc clairement besoin de faire une optimisation ici.

La première amélioration la plus évidente est la vérification de la ligne de visée. Cela diminuerait à la fois le nombre de personnes qui se soucient des données, ainsi que la quantité de données envoyées aux parties intéressées. Y a-t-il d'autres astuces dans ce domaine que je peux essayer, qui visent à minimiser le coût de mon opération de diffusion?

Tesserex
la source
5
Profil le code est vraiment tout ce que je pouvais suggérer. Je suppose que ce n'est pas aussi finement réglé que vous le pensez et c'est pourquoi TF2 affiche un taux de tick plus élevé sur moins de matériel. Je pense également que TF2 peut faire tout ce que vous avez suggéré de faire et, par conséquent, cela explique pourquoi leurs performances sont meilleures.
Nate
1
Je suis intéressé d'entendre vos derniers résultats, avez-vous pu obtenir de meilleures performances de node.js?
iddqd

Réponses:

5

Votre serveur ne doit pas envoyer l'état de tous les joueurs à tous les joueurs à chaque tick. Au lieu de cela, il doit envoyer un message spécialement conçu à chaque client, disant toutes les 500 ms en disant "ces x joueurs dans votre port de vue devraient être à ces coordonnées en 500 ms." La plupart du temps, cela fonctionnera bien, mais si le serveur se rend compte qu'il a donné des informations erronées, il envoie simplement un message supplémentaire.

Cela réduira considérablement le trafic réseau.

Une autre chose à considérer est de ne pas avoir de ticks de jeu sur le serveur, mais de demander au client d'envoyer des messages uniquement lorsqu'une action se produit (changement de direction, tir tiré), puis de calculer à l'avance sur le serveur lorsqu'une action est reçue.

Sorenbs
la source
Oui, j'ajoute une vérification de la ligne de visée en ce moment. En fait, les gains étaient minimes, passant de 45 ms pour 25 joueurs à 35 ms. Mais il peut y avoir des frais supplémentaires pour l'utilisation de commandes d'envoi individuelles au lieu de la diffusion. Et je n'envoie que des messages en entrée. Mais vous avez raison, il peut y avoir un moyen de ne pas avoir à cocher du tout, uniquement lorsque l'entrée est reçue.
Tesserex
1

J'ai considéré la malheureuse possibilité que node.js soit juste plus lent que ce que TF2 utilise, et peut ne pas convenir à ce type de tâche à haute intensité.

C'est probablement ça. Le serveur de TF2 est écrit en C / C ++, et sera donc plus rapide que node.js (qui si je me souviens bien, utilise Javascript interprété en Java)

Quake basé sur WebGL de Google utilise Java pour le serveur, et le code source se trouve ici: http://code.google.com/p/quake2-gwt-port/ . Il vaut peut-être la peine de le parcourir pour voir comment cela se fait. Je me demande aussi ce que vous voulez dire lorsque vous parlez d'avoir une fréquence d'images sur le serveur. Il n'y a aucune raison de rendre quoi que ce soit sur le serveur, il devrait simplement être là pour traiter les commandes envoyées par le client.

Enfin, la règle "ne pas faire confiance au client" est plus importante que le déchargement de calculs coûteux sur le client dans l'espoir d'améliorer les performances. Surtout quelque chose d'aussi important que la détection de collision. Doublement si votre jeu est basé sur Javascript, et donc assez facile à pirater (par rapport à quelque chose comme TF2 qui est compilé).

Je sais que ce n'est pas vraiment une réponse, mais j'espère que cela vous indiquera quelques directions qui pourraient aider à améliorer les performances.

thédaïen
la source
7
J'aurais dû dire tick rate au lieu de frame rate. Bien sûr, rien ne s'affiche sur le serveur. Je veux dire l'intervalle auquel il traite les commandes dans la boucle de jeu. En outre, quelques réponses suggèrent que vous pouvez donner au client des éléments tels que la détection des collisions, à condition d'effectuer des vérifications aléatoires toutes les quelques secondes. Quelqu'un a dit qu'il éliminait les tricheurs assez rapidement.
Tesserex