Senden von Zustandsdifferenzen (Deltas) und unzuverlässigen Verbindungen

8

Wir erstellen ein Echtzeit-Multiplayer-Spiel, bei dem jeder Spieler dafür verantwortlich ist, seinen Status bei jeder Iteration der Spielschleife zu melden.

Die Statusaktualisierungen werden mit unzuverlässigem UDP gesendet .

Um das Senden von Statusdaten zu minimieren, haben wir ein System entwickelt, das nur Deltas sendet (unabhängig davon, welche Statusdaten geändert wurden).

Diese Methode ist jedoch fehlerhaft, da ein verlorenes Paket bedeutet, dass andere Spieler das Delta nicht erhalten, wodurch sich das Spiel auf unerwartete Weise verhält.

Zum Beispiel:

Angenommen, dieser Status besteht aus: {positionX, positionY, health}

Frame 1  - positionX changed --> send a packet with positionX only.
Frame 2 - health changed // lost !
Frame 3 - positionY changed --> send a packet with positionY only.

// Andere Spieler wissen nichts über Gesundheitsveränderungen.

Wie kann man dieses Problem dann überwinden? Das Senden der gesamten Daten ist nicht immer möglich.

spaceOwl
quelle

Antworten:

7

Auch wenn Sie Daten mit UDP senden, müssen Sie Ihre eigene Zuverlässigkeit hinzufügen, um solche Situationen zu bewältigen. UDP bietet Ihnen nur die Flexibilität, das zu tun, was Sie wollen, anstatt sich mit dem zuverlässigen, aber weniger flexiblen Format der TCP-Kommunikation zu befassen. Bestätigungsnachrichten oder Bestätigungspakete einer Art sollten verwendet werden, wenn der Empfang von Informationen erforderlich ist. Andernfalls kann Ihr Client nicht wissen, ob die von ihm gesendeten Daten erneut gesendet werden müssen. Wenn Sie beispielsweise wichtige Informationen senden und innerhalb eines festgelegten Zeitraums keine Antwort erhalten, die den Empfang dieser Daten bestätigt, senden Sie sie erneut.

Evan
quelle
2
Schlage mich dazu. Es sollte jedoch beachtet werden, dass ziemlich flüchtige Werte wie Positions- und andere physikalische Daten nicht garantiert werden müssen. Selbst wenn die Möglichkeit besteht, dass es bei einem bestimmten Frame falsch ist, wird es im nächsten Frame trotzdem behoben.
Jmegaffin
1
Guter Punkt, dies wird am häufigsten in Spielen gesehen, wenn sich ein Charakter plötzlich sehr schnell an einen neuen Ort bewegt (oder sich dort alle zusammen teleportiert). Die meisten Spiele gehen auf verschiedene Arten damit um, aber das Ziel ist das gleiche. Der Server hat einfach die Entitätsposition aktualisiert, und Ihr Client aktualisiert sie entweder sofort oder mit einer sehr hohen Deltazeit über einige Frames.
Evan
3

Sie können das Problem auch umgehen, indem Sie beispielsweise jede Sekunde eine vollständige Statusaktualisierung vom Server an die Clients senden. Wenn ein Client kein Paket empfangen hat, verhält er sich falsch, bis er die vollständige Statusaktualisierung erhält. Dann wird es wieder synchronisiert.

Matthias
quelle
3

Viele Spiele verwenden sowohl UDP als auch TCP / IP zum Senden / Empfangen von Daten. Je nachdem, wie oft die Daten gesendet werden, wird ein anderes Protokoll verwendet.

Zum Beispiel:

UDP: Positionsaktualisierungen und alles andere, was möglicherweise mehrmals pro Sekunde gesendet / empfangen werden könnte.

TCP / IP: Inventaraktionen, Zauber- / Fähigkeitsaktionen (die meisten vom Benutzer durchgeführten Aktionen)

Es hängt wirklich von der Menge des Verkehrs jedes Artikels ab. Wenn Sie feststellen, dass Sie häufig HP Updates senden, müssen diese möglicherweise auf UDP sein.

UnderscoreZero
quelle
1
TCP wird im Allgemeinen nicht für Dinge verwendet, die Echtzeitgenauigkeit erfordern, da es große Verzögerungsspitzen verursachen kann.
TheNickmaster21
Es ist gut, wenn Sie sicherstellen möchten, dass Ihr Paket dort ankommt. Dinge wie Positionsaktualisierungen sind dafür nicht gut, aber wenn Sie sicherstellen möchten, dass Ihr Benutzer zu einem bestimmten Zeitpunkt eine Taste gedrückt hat, übernimmt TCP alle Fehlerprüfungen und andere Dinge, die Sie für UDP implementieren müssten, um Paketverlust zu vermeiden.
UnderscoreZero
Gutes Argument; Ich würde nur lieber UDP ändern.
TheNickmaster21
1

Wenn Sie die Überprüfung des Quake 3-Quellcodes lesen , erklärt er das Netzwerkmodell, das Ihrem Design sehr ähnlich ist, jedoch eine Lösung für die verworfenen Pakete enthält.

Im Wesentlichen senden Sie in Ihrem Modell Deltas gegen den direkt vorherigen Status. Im quake3-Modell senden Sie Deltas gegen den letzten bestätigten Status vom Peer.

Minismus
quelle