Umgang mit schnelleren Computern in einem Client / Server-Echtzeit-Videospiel


15

Ich erstelle mein erstes Online-Spiel mit socket.io und möchte, dass es ein Echtzeit-Multiplayer-Spiel wie agar.io oder diep.io ist.

Aber ich habe versucht herauszufinden, wie alle Computer mit der gleichen Geschwindigkeit arbeiten können.

Ich habe drei Ideen für Models, aber keine davon scheint richtig zu sein, und ich frage mich, wie normale Videospiele das machen. (Sie können das Lesen meiner Ideen überspringen. Sie geben Ihnen nur einen Weg, die Probleme zu erkennen, die ich habe.)

  1. Auf dem Server können die Clients selbstständig ausgeführt und Aktualisierungen an den Server übergeben werden, der sie dann an die übrigen Clients sendet. Dies hat das Problem, dass einige Computer schneller laufen als andere, sodass sie schneller aktualisiert werden und sich schneller über den Bildschirm bewegen können.

  2. Bitten Sie den Server, den Clients mitzuteilen, wann sie aktualisieren sollen. Ich kann dann warten, bis der letzte Client antwortet (eine schreckliche Idee für den Fall, dass eine Person einen langsamen Computer hat), warten, bis der erste Client antwortet (erneut auf die Kommunikation vor jedem Frame wartet) oder sie einfach so schnell wie möglich senden (welche) scheint auf dasselbe Problem zu stoßen wie Nummer 1).

  3. Lassen Sie den Server zu Beginn des Spiels den Clients mitteilen, wie schnell die Aktualisierung erfolgen soll. Dies würde bedeuten, dass der Kunde dafür verantwortlich ist, die Bewegung zwischen diesen Zeiträumen einzuschränken. Wenn es beispielsweise jemandem in diesem Zeitraum irgendwie gelungen ist, einen Knopf zweimal zu drücken, wird nur ein Knopfdruckereignis gesendet. Dies hat das Problem, dass einige Aktionen ignoriert werden (z. B. das Drücken von zwei Tasten) und dass die Interaktion von der Uhr des Clients abhängt, die möglicherweise nicht mit der Uhr des Servers übereinstimmt. Der Server muss dann den Überblick über jeden Client behalten und sicherstellen, dass die Aktualisierungen zum richtigen Zeitpunkt übermittelt werden.

Ich habe einige Nachforschungen angestellt , aber die Artikel, die ich lese, scheinen nicht speziell zu behandeln, was zu tun ist, wenn ein Client Updates schneller als andere Clients sendet.

In meinem speziellen Fall habe ich es mit Leuten zu tun, die schnellere Tastaturgeschwindigkeiten haben (ihr Computer würde mehr Tastaturaktualisierungen senden als andere Computer).

Wie gehen Programmierer normalerweise damit um?


1
Nach meiner Erfahrung tun sie das nicht. Aus diesem Grund gibt es Spielautomaten. Diejenigen, die 5 Riesen für einen hochmodernen Flammenwerfer bezahlen, haben automatisch den Vorteil, dass sie immer noch einen Commodore 64 verwenden.
Robert Harvey

1
Also wird mein Spielverlauf langsam aussehen, weil wir auf den kleinsten gemeinsamen Nenner spielen müssen? Scheint, als sollte der Spieleserver das Tempo bestimmen und es liegt an den Kunden, mitzuhalten, sonst müssen Sie einfach zurückbleiben.
JeffO

3
Ich verstehe die Frage vielleicht falsch, aber Sie sind wahrscheinlich auf der Suche nach einem tickbasierten Client- und Servermodell. gamedev.stackexchange.com/questions/81608/… Grundsätzlich verarbeiten Sie Eingaben und Logik nur alle x-mal (normalerweise 1 / N Sekunden, z. B. 1/60 für 60-Hz-Logik)
Christopher Wirt

4
Nachdem Sie die Frage etwas genauer gelesen haben, scheinen Sie sich zu sehr auf die Client-Aspekte des Spiels zu konzentrieren. Wenn Sie ein "faires" Multiplayer-Spiel wollen, muss Ihr Server autorisierend sein. Dies bedeutet, dass alles, was mit den Clients geschieht, vom Server überprüft oder ausgeführt wird. Dann schränken Sie die Dinge von hier aus ein, wahrscheinlich durch ein Tick-basiertes System wie oben.
Christopher Wirt

1
Ah, Echtzeit-Netcode. Der tiefste, dunkelste Ort der Spieleentwicklung. Willkommen auf dem Schiff, Kumpel!
T. Sar - Reinstate Monica

Antworten:


8

Ihre dritte Idee scheint der meiner Meinung nach branchenweit besten Lösung für diese Art von Problem am nächsten zu kommen.

Was Sie beschreiben, wird allgemein als Ticks bezeichnet . In jedem Tick würde eine feste Anzahl von Aktionen für jeden Client in Serie verarbeitet. Häufig werden auf Spieleservern parallele Aktionen ausgeführt, wenn dies möglich ist. Dies ist jedoch ein viel komplizierteres Problem.

Ein Tick hat wahrscheinlich die Form von 1 / N Sekunden, wobei N die Anzahl der Ticks pro Sekunde oder die Tickrate ist. Diese Tickrate kann je nach Anwendungsfall sehr, sehr häufig oder sehr selten sein. Mein persönlicher Vorschlag wäre, eine Tickrate über 60 Ticks / Sekunde zu vermeiden, es sei denn, Sie sind sicher, dass Sie mehr benötigen. Sie wahrscheinlich nicht :)

Aktionen sollten atomar sein. Zum Beispiel sollte in slither.io eine Aktion wie das Bewegen nicht sofort so etwas wie das Brechen Ihrer Kette verarbeiten, es sei denn, der Spieler, den Sie getroffen haben, hat bereits seinen Zug ausgeführt. Dies mag für etwas auf der Ebene der Pixel trivial erscheinen, aber wenn Sie sich mit fliesenbasierten Bewegungen befassen, wird dies viel offensichtlicher und sorgt für Fairness. Wenn Spieler A zu Kachel X, Y wechselt und Spieler B sich gerade auf dieser Kachel befindet, müssen Sie sicherstellen, dass sich Spieler B am Ende des Ticks noch auf dieser Kachel befindet, damit zwischen ihnen Aktionen stattfinden können.

Außerdem würde ich sagen, dass Sie keine Ihrer Berechnungen auf der Clientseite durchführen lassen sollten, es sei denn, diese werden unabhängig auf der Serverseite durchgeführt. Dies wird mit der Physik kompliziert und teuer (viele Spiele entscheiden sich aus diesem Grund für eine niedrigere Tick-Rate für die Physik als viele andere Aktionen und Ereignisse).

Als Referenz finden Sie hier einen guten Link , um Ihr eigenes Verständnis von Spieleservern und Multiplayer-Netzwerken zu ergänzen.

Zuletzt würde ich sagen, dass Fairness Ihren Server nicht ruinieren darf. Wenn es Exploits gibt, die Ihr Spiel unfair machen, beheben Sie diese. Wenn es darum geht, dass ein besserer Computer einen kleinen Vorteil hat, würde ich sagen, dass dies möglicherweise keine so große Sache ist.


3
@ProQ Es ist erwähnenswert, dass das Schreiben eines guten Netcodes nicht trivial ist! Wenn Ihre App von Anfang an nicht gut funktioniert und Ihr Netcode zu scheißen scheint, geben Sie nicht auf. Sogar Leute, die das für ihren Alltag tun, haben Probleme damit. es ist einfach so schwer!
T. Sar - Reinstate Monica

0

Das folgende System stellt sicher, dass alle Clients und der Server zu jeder Zeit fast den gleichen Spielstatus haben.

Haben Sie den Status des Spiels auf Client und Server.

Wenn ein Client versucht, einen Befehl (Maus, Tastatur usw.) zu verwenden, überprüfen Sie den Status des Spiels, sofern er gültig ist.

Wenn dies der Fall ist, senden Sie den Befehl an den Server, ohne ihn auf dem sendenden Client auszuführen.

Wenn der Server den Befehl erhält, prüfen Sie, ob der Status des Spiels gültig ist.

Wenn dies der Fall ist, senden Sie den Befehl mit dem genauen zukünftigen Datum an ALLE Clients zurück, nachdem die Ausführung auf dem Server abgeschlossen sein soll. Führen Sie dann die vom Befehl angeforderten Aktionen nach einer Verzögerung aus, die der Mindestzeit zum Senden des Befehls an Clients entspricht . Zeichnen Sie dann das Datum auf, um zukünftige Vorhersagen zu treffen. Wenn die Zeit zu stark variiert, sollten Sie Ihr Spielsystem zeitdeterministischer gestalten.

Wenn ein Client einen Befehl vom Server erhält, überprüfen Sie den Status des Spiels. Wenn der Befehl gültig ist, führen Sie sofort die vom Befehl angeforderten Aktionen aus. Überprüfen Sie dann das aktuelle Datum und vergleichen Sie es mit der empfangenen Datumsprognose. Wenn es nicht gültig ist, ist der Client nicht synchron. (Alle Clients mit einer ähnlichen Verbindung empfangen gleichzeitig)

Wenn das Datum vor dem angegebenen Datum liegt, haben Sie im vorherigen Schritt ein Problem. Beheben Sie dieses Problem. Wenn das Datum etwas später ist, machen Sie nichts. Wenn das Datum lange danach ist, ist der Client nicht synchron, dh der Client bleibt zu weit zurück.

Wenn ein Client nicht synchron ist, fordern Sie eine Kopie des gesamten Spielstatus des Servers an und verwenden Sie diesen. Wenn dies zu oft vorkommt, beheben Sie dies, da dies teurer ist als das Senden von Befehlen.

Rendern Sie auf den Clients Inhalte NUR dann auf dem Bildschirm, wenn nichts mehr zu tun ist. In einfachen Szenarien übernimmt die Renderfunktion nur den aktuellen Spielstatus als Eingabe.

Darüber hinaus können Sie eine Menge optimieren, indem Sie Predictive-Systeme verwenden, Befehle gruppieren, nur Diffs rendern usw.

Die Validierung sollte sich unterscheiden, zum Beispiel obliegt es dem Server, die Befehlsanforderungen / Zeiteinheit zu begrenzen.


0

Ich weiß nicht, ob dies ein Problem der von Ihnen verwendeten Bibliotheken oder Umgebungen ist, aber ich denke, Sie nähern sich dem völlig falsch an.

In der überwiegenden Mehrheit der Multiplayer-Spiele führt nur der Server echte Berechnungen durch. Clients sind nur dumme IO-Maschinen, bei denen das Zeichnen von 3D-Grafiken nur ein echtes Leistungsproblem darstellt. In diesem Fall spielt es keine Rolle, ob der Client mit 20 oder 200 FPS ausgeführt werden kann, da dies nur die visuelle Darstellung betrifft. Das heißt "Client Update" hat absolut keine Bedeutung. Der Client versucht möglicherweise, "vorherzusagen", was der Server berechnet. Dies dient jedoch nur dazu, das Spielgefühl zu mildern, und hat keine tatsächlichen Auswirkungen auf das Spiel selbst.

schnellere Tastaturgeschwindigkeiten

Ich weiß nicht einmal, was das bedeutet. Die meisten Leute können nicht einmal mit der Geschwindigkeit von Low-End-Tastaturen mithalten. Wie würde sich das auf die Leistung von Spielern auswirken?

Andernfalls scheint die Frage zu weit zu gehen, und Sie sollten sich stattdessen auf ein einzelnes tatsächliches Problem konzentrieren, anstatt zu versuchen, ein "allgemeines" Problem zu finden, das Sie möglicherweise gar nicht haben.


Bei höheren Tastaturgeschwindigkeiten geht es nicht um das Tippen, sondern darum, wie viele Befehle gesendet werden können, wenn Sie die Taste "Vorwärts" oder "Schießen" gedrückt halten.
gbjbaanb

@ gbjbaanb Und wie ist das ein Problem? Sie sollten sich nur um gedrückte und freigegebene Befehle kümmern. Sie sollten sich nicht darum kümmern, wie schnell das Update erfolgt.
Euphoric

Es ist Ihnen egal, ob Sie alle Ereignisse wie vom OP erwartet abwickeln - auf dem Client. Wenn Sie also w drücken, gehen Sie ein Stück vorwärts, und Ihre Tastatur war schneller als die einer anderen Person. Das letzte, was Sie wollen, ist ein Rennspiel zu machen, bei dem Sie eine Taste gedrückt halten müssen, um vorwärts zu kommen!
gbjbaanb

@ gbjbaanb Nein. Das ist falsch. Der Server weiß, dass der Spieler vorwärts geht und aktualisiert dann alle 1/60 der Sekunde die Positionen ALLER Spieler, basierend darauf, ob sie vorwärts gehen. So funktionieren ALLE Spiele. Die Aktualisierungsschleife ist für alle Entitäten im Spiel gleich und Aktualisierungen basieren NICHT auf Ereignissen von der Benutzeroberfläche.
Euphoric

1
Nein, das war nicht das Verständnis des OP, weshalb er es fragte, und weshalb Sie sagten: "Ich weiß nicht einmal, was das bedeutet." Wenn Sie die Position des OP verstehen, dann ist seine Frage sinnvoll. Wenn das OP sein Spiel so programmiert hat, dass es mit einer Spieleschleife funktioniert, die ausschließlich davon abhängt, wie schnell Ereignisse vom Client übermittelt werden, fragt er danach. unabhängig davon, ob sein Design nach den meisten Maßstäben falsch ist.
gbjbaanb
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.