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.)
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.
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).
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?
quelle
Antworten:
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.
quelle
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.
quelle
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.
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.
quelle