paint-brush
Unity Realtime Multiplayer, Teil 1: Netzwerkgrundlagenby@dmitrii
1,058
1,058

Unity Realtime Multiplayer, Teil 1: Netzwerkgrundlagen

Im ersten Beitrag dieser Serie, die sich mit der gesamten Unity Realtime Multiplayer-Landschaft befasst, befassen wir uns mit Netzwerkgrundlagen und wichtigen Überlegungen für akzeptable Spielerlebnisse. Insbesondere werden wir über Netzwerkgeschwindigkeiten, die dahinter stehende Infrastruktur, mögliche Verzögerungen und Methoden zur Behebung dieser Probleme sprechen.
featured image - Unity Realtime Multiplayer, Teil 1: Netzwerkgrundlagen
Dmitrii Ivashchenko HackerNoon profile picture
0-item

Im ersten Beitrag dieser Serie, die sich mit der gesamten Unity-Echtzeit-Multiplayer-Landschaft befasst, befassen wir uns mit Netzwerkgrundlagen und wichtigen Überlegungen für akzeptable Spielerlebnisse. Insbesondere werden wir über Netzwerkgeschwindigkeiten, die dahinter stehende Infrastruktur, mögliche Verzögerungen und Methoden zur Behebung dieser Probleme sprechen.


Die Netzwerkinteraktion ist für die meisten modernen Spiele von entscheidender Bedeutung, egal ob auf Mobilgeräten, Konsolen, PCs oder VR. Es spielt keine Rolle, ob Sie ein einfaches Multiplayer-Spiel oder ein ambitioniertes MMO erstellen – Netzwerkprogrammierkenntnisse sind der Schlüssel.


Hallo zusammen, ich bin Dmitrii Ivashchenko, ein leitender Softwareentwickler bei MY.GAMES. Diese Artikelserie zum Thema „Unity-Netzwerklandschaft im Jahr 2023“ behandelt kritische Aspekte und Einschränkungen von Netzwerkumgebungen, befasst sich mit verschiedenen Protokollen (einschließlich TCP, UDP und WebSocket) und beleuchtet die Bedeutung des Reliable UDP-Protokolls. Wir untersuchen die Auswirkungen von NAT auf Echtzeit-Multiplayer-Spiele und unterstützen Sie bei der Vorbereitung von Spieldaten für die Netzwerkübertragung.


Wir werden uns mit Themen befassen, die von den Grundlagen bis hin zu fortgeschritteneren Konzepten wie Transportprotokollen, Netzwerkarchitekturmustern, vorgefertigten Lösungen für Unity und mehr reichen. Wir analysieren sowohl offizielle Unity-Lösungen als auch Tools von Drittanbietern, um Ihnen dabei zu helfen, die optimale Wahl für Ihre Projekte zu finden.


In diesem ersten Beitrag werden wir die kritischen Elemente der Netzwerkprogrammierung behandeln und uns mit den Hindernissen und Problemen befassen, mit denen Entwickler häufig konfrontiert sind, wenn sie Spiele mit Netzwerkfunktion erstellen.

Die Infrastruktur verstehen

Das Internet ist ein komplexes System aus verschiedenen Geräten mit jeweils einzigartigen Funktionen. Lassen Sie uns über einige davon sprechen. Typischerweise beginnt die Verbindung einer Person mit dem Internet mit einem Gerät wie einem Computer oder einem Smartphone. Diese stellen über Router oder Modems eine Verbindung zu einem lokalen Netzwerk her, die die Kommunikation zwischen dem lokalen Netzwerk und dem ISP ermöglichen.


Der ISP verfügt über größere Router und Switches, die den Datenverkehr aus mehreren lokalen Netzwerken verwalten. Diese Geräte bilden das Rückgrat des Internets, zu dem ein kompliziertes Netzwerk aus Routern und Glasfaserkabeln mit hoher Kapazität gehört, das Kontinente und Ozeane umspannt. Für die Aufrechterhaltung dieses Backbones sind separate Unternehmen, sogenannte Backbone-Provider, verantwortlich.


Darüber hinaus beherbergen Rechenzentren leistungsstarke Server, auf denen sich Websites, Anwendungen und Onlinedienste befinden. Wenn Sie Zugriff auf eine Website oder einen Online-Dienst anfordern, wird Ihre Anfrage über dieses umfangreiche Netzwerk zum entsprechenden Server weitergeleitet und anschließend werden die Daten auf demselben Weg zurückgesendet.

Netzwerkbeschränkungen

Bevor Sie in die Welt von TCP, UDP, Relay-Servern und der Entwicklung von Echtzeit-Multiplayer-Spielen eintauchen, ist es wichtig, ein solides Verständnis der Netzwerksysteme als Ganzes zu haben. Dazu gehört das Verständnis der Rollen und Funktionen von Geräten wie Hubs und Routern sowie ein Bewusstsein für mögliche Probleme, die sich aus dem Betrieb dieser Geräte und Medien ergeben können.


Netzwerktechnologien sind nicht von der physischen Welt isoliert und unterliegen mehreren physischen Einschränkungen: Bandbreite, Latenz, Verbindungszuverlässigkeit – all diese Faktoren müssen bei der Entwicklung vernetzter Spiele berücksichtigt werden.


Wenn Sie diese Grundprinzipien und Einschränkungen verstehen, können Sie die möglichen Lösungen und Strategien, die für die erfolgreiche Netzwerkintegration Ihrer Spiele erforderlich sind, besser beurteilen.

Bandbreite

Unter Bandbreite versteht man die maximale Datenmenge, die in einem bestimmten Zeitraum über ein Netzwerk übertragen werden kann. Die Geschwindigkeit der Datenübertragung hängt direkt von der verfügbaren Bandbreite ab: Je mehr Bandbreite, desto mehr Daten können gleichzeitig hochgeladen werden.


Die Bandbreite wird in Bits pro Sekunde gemessen und kann zwei Arten haben: symmetrisch (mit gleichen Upload- und Download-Geschwindigkeiten) und asymmetrisch (mit unterschiedlichen Upload- und Download-Geschwindigkeiten).


Symmetrische Verbindungen werden normalerweise für kabelgebundene Netzwerke verwendet, wie bei Glasfasernetzen, während asymmetrische Verbindungen in drahtlosen Netzwerken verwendet werden, wie es bei mobilen Daten der Fall ist.


Die Bandbreite wird normalerweise in Bits pro Sekunde (bps) oder Vielfachen, wie beispielsweise Megabits pro Sekunde (Mbps), gemessen. Durch eine hohe Bandbreite können mehr Daten in kürzerer Zeit übertragen werden, was für Echtzeit-Multiplayer-Spiele unbedingt erforderlich ist.

Zeit für eine Rundreise

RTT (Round-Trip Time) misst die Zeit, die ein Datenpaket benötigt, um vom Sender zum Empfänger und wieder zurück zu gelangen. Dies ist eine wesentliche Kennzahl bei vernetzten Spielen, da sie sich auf die Latenz auswirkt, die Spieler während des Spiels erleben können.



Wenn die RTT hoch ist, kann es bei den Spielern zu Verzögerungen kommen, die sich negativ auf das Gameplay auswirken können. Daher sollten Spieleentwickler danach streben, die RTT zu minimieren, um ein flüssigeres und reaktionsschnelleres Spielerlebnis zu ermöglichen.

Netzwerkverzögerungen

Eine Netzwerkverzögerung (oft als „Lag“ bezeichnet) ist die Zeit, die benötigt wird, um ein Datenpaket vom Sender zum Empfänger zu übertragen. Selbst kleine Netzwerkverzögerungen können das Gameplay in Spielen mit hohen Anforderungen an die Reaktionsfähigkeit, wie zum Beispiel Ego-Shooter, erheblich beeinträchtigen.


Obwohl Daten mit Geschwindigkeiten nahe der Lichtgeschwindigkeit übertragen werden, kann die Entfernung dennoch Auswirkungen auf das System haben und zu Verzögerungen führen. Aufgrund der für das Funktionieren des Internets erforderlichen Infrastruktur kommt es häufig zu Verzögerungen, die nicht beseitigt werden können. Dies kann aus Gründen im Zusammenhang mit der Übertragung über physische Kabel, Verzögerungen bei Netzwerkgeräten wie Routern und Switches sowie Verarbeitungsverzögerungen bei Sende- und Empfangsgeräten auftreten. Dennoch kann diese Infrastruktur noch optimiert werden, um Verzögerungen zu reduzieren.

Die Lichtgeschwindigkeit und Netzwerklatenz

Lassen Sie uns darüber sprechen, wie sich die Art der Datenübertragung auf die Netzwerklatenz auswirkt. Mit Licht über Glasfasern übertragene Daten werden nicht genau mit Lichtgeschwindigkeit übertragen. In Wirklichkeit wird das Licht in optischen Fasern langsamer übertragen als im Vakuum, da das Material der Faser einen Einfluss auf die Geschwindigkeit hat.


(Die maximale Lichtgeschwindigkeit beträgt ungefähr 299 Millionen Meter pro Sekunde oder 186.000 Meilen pro Stunde, aber auch dies ist nur unter idealen Vakuumbedingungen möglich.)


Bei Glasfasern wird das Licht relativ gesehen langsamer übertragen. Beachten Sie auch, dass die über Kupferkabel übertragenen Daten im Vergleich zu Glasfaserkabeln deutlich geringer ausfallen, da Glasfaserkabel eine größere Bandbreite haben und weniger anfällig für Störungen sind als Kupferkabel.

Route

Distanz

Zeit (Lichtgeschwindigkeit)

Zeit (Glasfaser)

RTT

Amsterdam - London

360 km

1 ms

2 ms

4 ms

Amsterdam - New York

5850 km

20 ms

29 ms

58 ms

Amsterdam - Peking

7800 km

26 ms

39 ms

78 ms

Amsterdam - Sydney

16700 km

56 ms

83 ms

166 ms


In der obigen Tabelle wird davon ausgegangen, dass Datenpakete über Glasfaser in einem großen Kreis zwischen Städten übertragen werden, was in der Realität selten der Fall ist. Die Weiterleitung von Datenpaketen erfolgt meist über viele Zwischenpunkte („Hops“), was die Datenübermittlungszeit erheblich verlängern kann; Jeder Zwischenpunkt führt zu einer Verzögerung und die tatsächliche Reisezeit kann erheblich verlängert werden. Ein über Glasfaser übertragenes Datenpaket (mit nahezu Lichtgeschwindigkeit) benötigt für den Hin- und Rückweg von Amsterdam nach Sydney und zurück mehr als 150 Millisekunden.


Während Menschen nicht besonders empfindlich auf Verzögerungen im Millisekundenbereich reagieren, haben Untersuchungen gezeigt, dass sich die Verzögerung bereits im menschlichen Gehirn bemerkbar macht, wenn wir 100–200 ms erreichen. Wenn sie 300 ms überschreitet, nimmt das menschliche Gehirn dies als langsame Reaktion wahr.


Um die Netzwerklatenz so zu reduzieren, dass sie 100 ms nicht überschreitet, müssen Inhalte den Benutzern möglichst nahe an der geografischen Lage zur Verfügung gestellt werden. Wir müssen den Durchgang von Datenpaketen sorgfältig kontrollieren und einen klaren Weg mit möglichst wenig Staus bereitstellen.

Nervosität

Jitter ist eine Variation oder „Fluktuation“ der Netzwerkverzögerungen; es beschreibt eine Änderung der Verzögerungszeit zwischen aufeinanderfolgenden Datenpaketen. Wenn Datenpakete in unregelmäßigen Abständen eintreffen, deutet dies auf eine Instabilität der Netzwerkübertragung hin. Dies kann durch verschiedene Faktoren verursacht werden, darunter Netzwerküberlastung, Verkehrsänderungen und Gerätemängel.


Selbst wenn eine durchschnittliche Verzögerung als akzeptabel erachtet wird, kann ein hoher Jitter Probleme verursachen, insbesondere bei Echtzeitanwendungen wie Online-Gaming oder solchen mit Internettelefonie, bei denen es auf die Konsistenz der Verzögerung ankommt.


Wenn der Jitter zu groß ist, kann es beim Bewegen von Spielfiguren oder Objekten zu Verzögerungen oder „Rucklern“ kommen. Dies kann auch zu Paketverlusten führen, wenn Datenpakete ihr Ziel nicht erreichen oder zu spät ankommen, um noch nützlich zu sein.


Jitter kann sich auch auf die allgemeine Fairness des Spiels auswirken. Wenn beispielsweise ein Spieler einen hohen Jitter hat und ein anderer nicht, ist dieser im Vorteil, weil seine Aktionen schneller registriert und angezeigt werden.

Paketverlust

Ein Paketverlust liegt vor, wenn ein oder mehrere Datenpakete ihr Ziel nicht erreichen. Dies kann verschiedene Gründe haben, beispielsweise Netzwerkprobleme, Verkehrsüberlastung oder Geräteprobleme.

In Echtzeitspielen, in denen solche Informationen relevant sind, kann der Paketverlust spürbare Probleme verursachen, darunter das „Einfrieren“ von Charakteren, das Verschwinden von Objekten oder Inkonsistenzen des Spielstatus zwischen den Spielern.


Ein Paketverlust kann zu einer völligen Unterbrechung des Spiels führen, da notwendige Informationen während der Übertragung verloren gehen können.


Daher ist es wichtig, Mechanismen zu entwickeln, um mit Paketverlusten umzugehen oder deren Auswirkungen auf das Gameplay zu minimieren.

Tick rate

Die Tick-Rate oder Simulationsrate bezieht sich auf die Häufigkeit, mit der das Spiel jede Sekunde Daten generiert und verwaltet. Während eines Ticks verarbeitet der Server die empfangenen Daten und führt Simulationen durch, bevor er die Ergebnisse an die Clients sendet. Der Server ruht dann bis zum nächsten Tick. Eine schnellere Tick-Rate bedeutet, dass Clients schneller neue Daten vom Server erhalten, wodurch die Verzögerung zwischen Player und Server verringert und die Reaktionsfähigkeit bei der Trefferregistrierung verbessert wird.


Eine Tick-Rate von 60 Hz ist effizienter als 30 Hz, da sie die Zeit zwischen den Simulationsschritten verkürzt, was zu einer geringeren Verzögerung führt. Darüber hinaus ermöglicht diese Rate dem Server die Übertragung von 60 Aktualisierungen pro Sekunde, was die Roundtrip-Verzögerung zwischen Client und Server um etwa 33 ms reduziert (-16 ms von Client zu Server und weitere -16 ms von Server zu Client).


Es kann jedoch zu Gameplay-Problemen wie Gummibändern, teleportierenden Spielern, abgelehnten Treffern und physikalischen Fehlern kommen, wenn der Server Schwierigkeiten hat, Ticks innerhalb des für jede Tick-Rate zugewiesenen Intervalls zu verarbeiten. Wenn ein Server beispielsweise auf eine Tick-Rate von 60 Hz eingestellt ist, die erforderlichen Simulationen und Datenübertragungen jedoch nicht innerhalb der für jeden Tick verfügbaren ca. 16,67 Millisekunden (1 Sekunde / 60) abschließen kann, können diese Probleme auftreten.

Umgang mit Einschränkungen

Wie wir in den Abschnitten über Verzögerung und Paketverlust besprochen haben, ist Verzögerung ein Problem, das wir angehen müssen, und Jitter macht die Schaffung eines nahtlosen Spielerlebnisses noch schwieriger.


Wenn wir Verzögerungen ignorieren und keine Maßnahmen ergreifen, um sie abzumildern, erhalten wir am Ende ein „dummes Terminal“. Dumme Terminals müssen die Simulation, die sie dem Client zeigen, nicht verstehen; Stattdessen senden sie nur Eingabedaten von Clients an den Server und empfangen den resultierenden Status vom Server zur Anzeige.


Bei diesem Ansatz steht die Genauigkeit im Vordergrund und stellt sicher, dass immer der richtige Benutzerstatus angezeigt wird. Es hat jedoch mehrere Nachteile:


  1. Wenn die Aktualisierungsfrequenz des Servers nicht ausreichend ist, kann es zu Verzögerungen und einem instabilen Spielerlebnis kommen. Das Spiel läuft im Tempo des Servers, unabhängig von der potenziellen Bildrate des Clients. Dies kann dazu führen, dass ein Spiel mit hoher Frequenz zu einem minderwertigen Erlebnis mit spürbarer Eingabeverzögerung wird.
  2. Verzögerungen in der Reaktionsfähigkeit können bei einigen Spielgenres akzeptabel sein, aber nicht bei allen. Eine veraltete Visualisierung der Spielwelt kann das genaue Zielen auf andere Spieler erschweren. Die Spieler müssen ihre Aktionen vorhersehen und früher zielen, um die Verzögerung auszugleichen.
  3. Im schlimmsten Fall kann es passieren, dass Spieler ihr Ziel völlig verfehlen. Der Feind scheint im Vergleich zur Anzeige zeitlich um 100–150 ms voraus zu sein, selbst wenn er sich nicht unregelmäßig bewegt. Diese Diskrepanz kann dazu führen, dass Spieler ihr Ziel verfehlen, selbst wenn sie laut Bildschirm genau zielen.


Obwohl der Ansatz des „dummen Terminals“ eine genaue Zustandsdarstellung gewährleistet, kann er aufgrund seiner inhärenten Einschränkungen möglicherweise die Qualität des Spielerlebnisses beeinträchtigen.

Clientseitige Interpolation

Wenn wir das Chaos aus RTT-Oszillationen und Jitter kombinieren, entsteht ein unerwünschtes Spielerlebnis. Seltene Aktualisierungen vom Server sowie schlechte Netzwerkbedingungen können zu visueller Instabilität führen. Es gibt jedoch Möglichkeiten, die Auswirkungen von Verzögerungen und Jitter zu minimieren, beispielsweise durch clientseitige Interpolation.


Bei der clientseitigen Interpolation interpoliert der Client den Zustand von Objekten im Laufe der Zeit reibungslos, anstatt sich einfach auf ihre vom Server gesendeten Positionen zu verlassen. Diese Methode ist vorsichtig, da sie nur den Übergang zwischen den tatsächlichen, vom Server gesendeten Zuständen glättet.


In einer Topologie mit einem vertrauenswürdigen Server kann der Client normalerweise einen Status anzeigen, der etwa die Hälfte der RTT hinter dem tatsächlichen Modellierungsstatus auf dem Server liegt. Damit die clientseitige Interpolation jedoch ordnungsgemäß funktioniert, muss sie hinter dem letzten vom Server übertragenen Status zurückbleiben. Dies führt zu einer Verzögerungserhöhung während der Interpolationsperiode. Dieser Zeitraum sollte kürzer sein als der Paketversandzeitraum, um Stottern zu vermeiden. Sobald der Client die Interpolation zum vorherigen Status abgeschlossen hat, erhält er einen neuen Status und wiederholt den Vorgang.

Dead Reckoning

Um die Auswirkungen nicht periodischer Statusaktualisierungen zu minimieren, verwenden einige Entwickler die Extrapolationsmethode, auch bekannt als Dead Reckoning (DR). Bei dieser Technik wird die zukünftige Position, Rotation und Geschwindigkeit eines Spielobjekts auf der Grundlage seiner letzten bekannten Werte vorhergesagt. Wenn der Player beispielsweise alle dritten Frames ein Paket mit der aktuellen Position, Rotation und Geschwindigkeit des Objekts sendet, kann der Extrapolationsalgorithmus von Bolt abschätzen, wo sich das Objekt in den nächsten drei Frames befinden wird, bis neue Daten eintreffen.


In diesem Fall ist es wichtig zu beachten, dass wir immer noch dieselbe Schätzmethode verwenden können, wenn ein neues Paket nicht wie vorhergesagt ankommt. Aber je länger wir in die Zukunft raten, desto höher ist die Wahrscheinlichkeit, einen Fehler zu machen. Um dieses Problem zu beheben, nutzt der DR-Algorithmus „Projected Velocity Blending“, um Korrekturen vorzunehmen, sobald tatsächliche Daten empfangen werden.


Durch die Extrapolation wird die Notwendigkeit künstlicher Paketverzögerungen beim Spielen verringert, was zu einer schnelleren Anzeige von Echtzeitaktionen für Spieler führt. Es geht auch effektiver mit verlorenen oder fehlenden Paketen um, wenn Sie mit Spielen mit vielen Spielern arbeiten. Das bedeutet, dass fehlende Positions-, Rotations- und Geschwindigkeitsinformationen keine Verzögerungen im Spielverlauf verursachen.


Obwohl DR hilfreich sein kann, ist es nicht so präzise wie die Interpolation. Darüber hinaus kann die Verwendung von DR eine Herausforderung sein, wenn Sie ein FPS-Spiel spielen und zuverlässige Aufnahmen mit Verzögerungsausgleich machen möchten. Dies liegt daran, dass die Extrapolation, bei der Werte geschätzt werden, zu Abweichungen bei dem führen kann, was jeder Spieler auf seinem Bildschirm sieht. Wenn Sie interpolierte Werte verwenden, könnten Sie direkt auf einen Spieler zielen, der sich senkrecht zu Ihnen bewegt, und trotzdem einen Schuss verfehlen.

Clientseitige Vorhersage

Interpolation und Extrapolation auf der Clientseite reduzieren Verzögerungen, aber das Spiel kann sich trotzdem „träge“ anfühlen. Hier kommt „Client-Side Prediction“ ins Spiel: Unmittelbar nach dem Drücken einer Taste beginnt die Spielerfigur, sich zu bewegen, wodurch das Gefühl der Trägheit beseitigt wird. Bei korrekter Durchführung ist diese Vorhersage nahezu identisch mit den Berechnungen des Servers.


Die clientseitige Vorhersage führt zu Unterschieden zwischen dem, was der Server und der Client sehen. Dies kann zu „unerwarteten“ visuellen Effekten führen. Es ist wichtig, unverarbeitete Spieleraktionen zu berücksichtigen und nach jedem Server-Update erneut anzuwenden.


Trotz Verbesserungen gibt es immer noch eine erhebliche Verzögerung zwischen einem Server-Update und dem Moment, in dem der Spieler es sieht. Dies führt zu Szenarien, in denen der Spieler beispielsweise einen perfekten Schuss macht, ihn aber verfehlt, weil er auf eine veraltete Position eines anderen Spielers zielt. Hier beginnt der Diskussionsbereich namens Lag Compensation.

Verzögerungskompensation

Die Verzögerungskompensation ist eine umstrittene Technik, die darauf abzielt, das Problem zu lösen, bei dem beispielsweise ein Spieler einen perfekten Schlag macht, dieser ihn aber verfehlt, weil er auf die „veraltete“ Position eines anderen Spielers zielte.


Das Prinzip der Verzögerungskompensation besteht darin, dass der Server den Weltzustand jederzeit wiederherstellen kann. Wenn der Server Ihr Datenpaket mit Informationen zum Schuss erhält, stellt er die Welt im Moment des Schusses wieder her und entscheidet, ob der Schuss getroffen oder verfehlt wurde.


Leider ist die Verzögerungskompensation anfällig für Betrug. Wenn der Server den vom Spieler gesendeten Zeitstempeln vertraut, kann ein Spieler den Server „austricksen“, indem er später einen Schuss sendet, aber vortäuscht, dass dieser einige Zeit vorher ausgeführt wurde.


Aus diesem Grund sollte eine Verzögerungskompensation vermieden werden. Die drei oben beschriebenen Techniken auf der Client-Seite implizieren kein Vertrauen vom Server zum Client und sind nicht anfällig für solche Missbräuche.


In dieser Serie werden wir alle diese Techniken genauer untersuchen und lernen, wie wir Daten am schnellsten, kompaktesten und zuverlässigsten übertragen.

Abschlussteil 1

Ihre Spieler spielen auf verschiedenen Geräten, hinter verschiedenen Router-Modellen und werden von einer vielfältigen Auswahl an Anbietern betreut. Manchmal sind sie über ein Glasfaserkabel für Hochgeschwindigkeitsinternet verbunden, manchmal nutzen sie möglicherweise eine Wi-Fi-Verbindung oder sogar mobiles 3G-Internet. Dies bedeutet, dass die Netzwerkbedingungen stark variieren können, was sich auf Latenz, Paketverlust und allgemeine Verbindungsstabilität auswirkt. Als Spieleentwickler ist es wichtig, diese unterschiedlichen Umgebungen zu verstehen und die Handhabung Ihres Netzwerks so zu gestalten, dass das bestmögliche Spielerlebnis gewährleistet ist. Zweifellos eine herausfordernde Aufgabe, aber richtig gemacht, ist die Umsetzung dieser Praktiken auf hohem Niveau das, was erfolgreiche Multiplayer-Spiele von den anderen unterscheidet.


Im nächsten Abschnitt besprechen wir die wichtigsten Datenübertragungsprotokolle wie TCP, UDP und WebSockets.