Serverseitige Leistung mit Mehrspieler-FPS


12

Dies hängt mit der MMO-Leistung zusammen, mit der Ausnahme, dass es um die Bandbreite geht. Hier geht es um die CPU-Auslastung.

Ich habe ein einfaches FPS mit node.js und webGL zusammengestellt. Es ist extrem einfach, ähnlich wie der BuddyMaze-Klon von MIDI Maze. Es ist sehr wenig los, jeder bewegt sich in zwei Dimensionen (keine Höhe), schießt auf einfache Projektile und rennt gegen Wände.

Wenn ich jetzt mehrere Verbindungen zum Server herstelle, auf denen jeder Spieler schnell schießt, während er sich im Kreis dreht, kann ich ungefähr 15 bis 20 Spieler im Spiel haben, bevor der Server einen Kern ausschöpft und sich verlangsamt. Und das ist, wenn auf dem Server mit 30 fps ausgeführt wird. Bei 10 fps bekomme ich ca. 25 - 30 Verbindungen. Das ist ziemlich schlimm, da das Spiel bald viel mehr zu tun haben wird und ich mehr Spieler ausrüsten muss, damit dies ein praktikables Unterfangen ist.

Mein Bruder hat gerade auf einige Statistiken zum TF2-Server seines Kollegen hingewiesen. Sein Server hat niedrigere Spezifikationen als unser, und dennoch läuft TF2, offensichtlich ein viel komplexeres Spiel, mit satten 500 Ticks pro Sekunde und 36 Benutzern pro Kern. Außerdem verbrauchen wir derzeit viel mehr Bandbreite als sie, aber wir haben noch nicht versucht, diese zu verringern.

Wie ist das möglich? Welche Tricks gibt es, um die Serverleistung auf diese Größenordnung zu steigern? Einige Dinge, die ich kenne, sind:

  • Verringern der Framerate auf dem Server und Interpolieren der Positionen auf dem Client. Ich habe einige Vorteile, aber der TF2-Server kümmert sich offensichtlich nicht einmal darum.
  • Erledigen Sie teure Aufgaben wie die Kollisionserkennung auf dem Client und überprüfen Sie sie selten auf dem Server. Ich bin noch nicht darüber hinweggekommen, das werde ich heute Abend tun. Trotzdem erwarte ich keinen so enormen Gewinn.
  • Teilen Sie das Spielfeld in Regionen (Quad-Bäume) auf, um Berechnungen zu minimieren. Hatte noch keine Gelegenheit dazu.
  • Ich habe die unglückliche Möglichkeit in Betracht gezogen, dass node.js viel langsamer ist als alles, was TF2 verwendet, und möglicherweise nicht für diese Art von hochintensiven Aufgaben geeignet ist.
  • Ist alles in der Serverkonfiguration Magie?

Also, was sind die anderen Tricks der Branche, um nur das erforderliche Minimum auf dem Server zu tun und dennoch ein fehlerfreies Spielerlebnis zu haben? Es gibt einen großen Konflikt zwischen "Defer to Client, um CPU-Zeit zu sparen" und "Don't Trust the Client". Vielleicht hilft es also zu wissen, wo die Grenze in verschiedenen Situationen gezogen wird.

Aktualisieren

Profiling ist wirklich das einzige Mantra, das ich jemals für absolut unfehlbar befunden habe. Ich habe schnell einige Timing-Funktionen um meinen Code gewickelt (danke, FP!) Und festgestellt, was ich nie erwartet hatte: Die Übertragung der Daten an die Clients macht fast die gesamte Ausführungszeit aus. Insbesondere rund 90% davon. Weitere Tests ergaben, dass diese Zeit sowohl von der Anzahl der Clients als auch von der Größe der Daten abhängt. Bei einer Auslastung von 20 Benutzern reduzierte ich meine Sendezeit um 90% von 24 ms auf etwas mehr als 2 ms, indem ich statt der vollständigen Daten nur "{}" sendete. Bei nur 5 Benutzern dauert die Übertragung ca. 0,5 ms. Ich muss hier also unbedingt etwas optimieren.

Die erste offensichtliche Verbesserung ist die Sichtprüfung. Dies würde sowohl die Anzahl der Personen, die sich für Daten interessieren, als auch die Menge der an interessierte Parteien gesendeten Daten verringern. Gibt es andere Tricks in diesem Bereich, die ich ausprobieren kann, um die Kosten meines Sendebetriebs zu minimieren?


5
Profil der Code ist wirklich alles, was ich vorschlagen könnte. Ich vermute, dass es nicht so fein abgestimmt ist, wie Sie denken, und deshalb läuft bei TF2 eine höhere Tick-Rate mit weniger Hardware. Ich denke auch, dass TF2 all die Dinge tut, die Sie vorgeschlagen haben, und als Ergebnis dazu beiträgt, warum ihre Leistung höher ist.
Nate

1
Ich bin gespannt auf Ihre neuesten Ergebnisse. Konnten Sie die Leistung von node.js verbessern?
iddqd

Antworten:


5

Ihr Server sollte nicht bei jedem Tick den Status aller Spieler an alle Spieler senden. Stattdessen sollte alle 500 ms eine speziell gestaltete Nachricht an jeden Client gesendet werden, die besagt, dass sich diese x Spieler in Ihrem Ansichtsfenster in 500 ms an diesen Koordinaten befinden sollten. Meistens funktioniert dies einwandfrei, aber wenn der Server feststellt, dass er falsche Informationen angegeben hat, sendet er nur eine zusätzliche Nachricht.

Dadurch wird der Netzwerkverkehr drastisch reduziert.

Eine andere zu berücksichtigende Sache ist, dass der Client keine Spiel-Ticks auf dem Server hat, sondern nur dann Nachrichten sendet, wenn eine Aktion stattfindet (Richtung geändert, Schuss abgefeuert) und dann auf dem Server vorausrechnet, wenn eine Aktion empfangen wird.


Ja, ich füge gerade eine Blickrichtungsprüfung hinzu. Tatsächlich waren die Gewinne minimal, von 45 ms für 25 Spieler bis hinunter zu 35 ms. Es kann jedoch einen zusätzlichen Aufwand für die Verwendung einzelner Sendebefehle anstelle von Broadcast geben. Und ich sende nur Nachrichten bei der Eingabe. Aber Sie haben Recht, es kann eine Möglichkeit geben, überhaupt nicht ankreuzen zu müssen, nur wenn Eingaben eingehen.
Tesserex

1

Ich habe die unglückliche Möglichkeit in Betracht gezogen, dass node.js viel langsamer ist als alles, was TF2 verwendet, und möglicherweise nicht für diese Art von hochintensiven Aufgaben geeignet ist.

Es ist wahrscheinlich das. Der Server von TF2 wird mit C / C ++ geschrieben und ist daher schneller als node.js (wenn ich mich richtig erinnere, wird Javascript verwendet, das in Java interpretiert wird).

Googles WebGL-basiertes Quake verwendet Java für den Server. Den Quellcode finden Sie hier: http://code.google.com/p/quake2-gwt-port/ . Es könnte sich lohnen, sich das anzuschauen, um zu sehen, wie es gemacht wird. Ich frage mich auch, was Sie meinen, wenn Sie über eine Framerate auf dem Server sprechen. Es gibt keinen Grund, etwas auf dem Server zu rendern. Es sollte nur für die Verarbeitung der vom Client gesendeten Befehle vorhanden sein.

Schließlich ist die Regel "Dem Client nicht vertrauen" wichtiger als das Auslagern teurer Berechnungen auf den Client in der Hoffnung, die Leistung zu verbessern. Besonders wichtig wie die Kollisionserkennung. Zweifelsohne, wenn Ihr Spiel auf Javascript basiert und daher ziemlich einfach zu hacken ist (im Vergleich zu etwas wie TF2, das kompiliert wurde).

Ich weiß, dass dies keine gute Antwort ist, aber ich hoffe, dass es Ihnen ein paar Hinweise gibt, die zur Verbesserung der Leistung beitragen können.


7
Ich hätte die Tick-Rate anstelle der Framerate sagen sollen. Natürlich rendert nichts auf dem Server. Ich meine das Intervall, in dem die Befehle in der Spielschleife verarbeitet werden. Einige Antworten lassen auch vermuten, dass Sie dem Client beispielsweise eine Kollisionserkennung zuweisen können, sofern Sie alle paar Sekunden zufällige Überprüfungen durchführen. Jemand sagte, dass es Betrüger ziemlich schnell aussortiert.
Tesserex
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.