Zeitschritt im Mehrspielerspiel

8

Ich versuche, mich mit dem Konzept zu beschäftigen, ein Server / Client-Multiplayer-Erlebnis zu schaffen.

Mein Problem hängt hauptsächlich mit dem Zeitschritt zusammen. Stellen Sie sich das folgende Szenario vor:

Ein Client stellt eine Verbindung zu einem Server her. Der Client sendet seine Eingaben an den Server, um anzuzeigen, dass er umziehen möchte. Der Server simuliert die Eingabe und bestimmt die Position dieses Clients in der Spielwelt.

Wie können Sie genau simulieren, dass alle Clients mit dem Server synchron sind, da sowohl der Client als auch der Server in unterschiedlichen Zeitschritten ausgeführt werden? Mein Server ist derzeit auf 30 ms eingestellt. Wenn ich Clientbewegungen verarbeite, warten möglicherweise Hunderte von Anforderungen darauf, verarbeitet zu werden, es kann jedoch nicht angegeben werden, wie lange es zwischen den einzelnen Anforderungen gedauert hat.

Ich verstehe wirklich nicht, wie man auf dem Server basierend auf der Zeit richtig simuliert, um alles synchronisieren zu können.

jgallant
quelle

Antworten:

3

Einfach ausgedrückt, müssen Sie mit jedem Snapshot vom Server und mit jeder Eingabe vom Client einen Zeitstempel senden.

An beiden Enden benötigen Sie einen Prozess, um alle Frames "auszufüllen", in denen keine Pakete empfangen werden.

In meinem Spiel (einem schnellen Action-Spiel - Ihr Spiel kann anders sein) verwerfe ich auf dem Server alle "älteren" (nicht in der richtigen Reihenfolge) Eingaben und vermute einfach, dass dieselben Schaltflächen dieselben Schaltflächen haben, wenn keine neuen Eingabepakete eintreffen Halten Sie einfach weiter gedrückt (es gibt ein bisschen mehr Dinge, um sicherzustellen, dass kurze Tastendrücke / -freigaben ausgeführt werden, aber das ist die Grundvoraussetzung).

Auf dem Client behalte ich einen "Verzögerungspuffer" (beschrieben in diesem Artikel , den Tetrad verlinkt hat). Ich verwende einen gleitenden Durchschnitt der Ankunftszeiten, um sicherzustellen, dass der Verzögerungspuffer die richtige Länge hat - damit das Client-Spiel etwas langsamer oder schneller läuft, um aufzuholen. Wenn Schnappschüsse nicht rechtzeitig eintreffen, extrapoliere ich sie auf dem Client. Ansonsten interpoliere ich zwischen Schnappschüssen im Puffer.

Der Client ist auch dafür verantwortlich, die Umlaufzeit für Eingaben zu verfolgen und diese für die Vorhersage zu verwenden (der Server sendet den Zeitstempel der Eingabe zurück, die er bei der Berechnung eines bestimmten Frames verwendet hat). Es puffert Eingaben für diese Zeitspanne und spielt sie erneut ab, um die Position des Spielers von der "alten" Position (im Schnappschuss vom Server) zur vorhergesagten "aktuellen" Position zu bringen.

Grundsätzlich läuft der Server nur mit einer festen Bildrate weiter. Es liegt an den Clients, mit dem Server synchronisiert zu bleiben.

Dies ist natürlich nur eine allgemeine Übersicht. Es gibt viele Details, die Sie herausfinden müssen, wenn Sie sie implementieren.

Andrew Russell
quelle
Wenn der Server zwischen einem Serverzeitschritt 10 Eingabebefehle von einem Client empfängt. Der Server führt die 10 Eingabebefehle aus. Woher wissen wir, wie lange jeder Eingabebefehl simuliert werden muss? Was passiert, wenn Sie nur einen Eingabebefehl erhalten, simulieren Sie den Befehl über die gesamte Zeitspanne des Zeitschritts?
Jgallant
1
@ Jon Die meisten "Action" -Spiele senden Eingaben als Schaltflächen-Auf- / Ab-Status für jeden Frame. Der Server verwendet dann gerade den neuesten empfangene Zustand als den Zustand für das Update Zecke. Verworfene, verspätete und nicht ordnungsgemäße Pakete werden ignoriert. (Zumindest auf der Basisebene - Sie können beispielsweise zusätzliche Sequenzierungsinformationen hinzufügen, damit ein sehr kurzer Auf- oder Ab-Status nicht ignoriert wird, auch wenn er gelöscht wird.) Dies sollten Sie wahrscheinlich für alle Eingaben tun, denen das Timing zugeordnet ist . Befehlsbasierte Aktionen (z. B. "hierher bewegen" in einem RTS) haben im Allgemeinen keine zugehörige Dauer. Sie würden sie also einfach der Reihe nach ausführen.
Andrew Russell