Ich habe schon ein wenig Spielnetzwerkcodierung durchgeführt, aber hauptsächlich mit TCP für Spiele ohne Echtzeitbedarf. Ich arbeite an einem 2D-Java-Spiel mit vernetztem Multiplayer. Zum Lernen möchte ich dies selbst tun, ohne eine vorhandene Netzwerk-API.
Wie kann ich den Spielstatus, der von einem Server an Clients gesendet wird, effizient darstellen? Es gibt die naheliegendste, aber wahrscheinlich am wenigsten effiziente Möglichkeit, eine Art Spielstatus-Kontextobjekt mit dem Standort, dem Animationsstatus usw. jedes Spielers zu erstellen und dieses bei jedem Update an jeden Spieler zu senden . Das scheint nicht besonders schwierig zu implementieren, wäre aber wahrscheinlich zu groß, um etwas in der Nähe der Echtzeitinteraktion zu erreichen (natürlich sind meine Erfahrungen damit begrenzt, so dass ich möglicherweise falsch liege).
Gibt es eine solide Methode, die einer von Ihnen zuvor verwendet hat, um nur Zustandsänderungen zu übertragen, und gibt es sogar eine ausreichend große Leistungsunterschiede, die die zusätzliche Arbeit wert ist?
Antworten:
Das regelmäßige Übertragen des vollständigen Spielstatus ist normalerweise nicht möglich, hängt jedoch stark von der Komplexität Ihres Spiels ab. Für ein einfaches Spiel mit einem kleinen Weltmodell kann es funktionieren.
Ich persönlich habe mit folgendem Modell viel mehr Erfolg gehabt:
Dies hat mir auch bei recht großen Spielwelten eine gute Leistung gebracht.
Ein weiterer Tipp: Lassen Sie den Client sich ohne Bezugnahme auf den Server um Animation, Partikeleffekte usw. kümmern. Es macht keinen Sinn, diese zu übertragen - sie müssen nur durch die entsprechenden Spielereignisse "ausgelöst" werden.
quelle
Die Synchronisation ist normalerweise in zwei Teile unterteilt: inkrementell und absolut.
Manchmal müssen Sie alles übertragen, es ist groß, aber wenn Sie es richtig verpacken, können Sie dies alle paar Sekunden tun. Es ist gut, alles einzurichten und die Fehler inkrementeller Aktualisierungen zu korrigieren.
Um eine Echtzeiterfahrung zu erzielen, müssen Sie einige Änderungen schnell übertragen, aber nur die Attribute, die sich ändern können. Wenn beispielsweise eine Rakete in einer geraden Linie fliegt, müssen Sie die Position nicht aktualisieren. Jeder Kunde kann sie vom Startpunkt aus berechnen. Wenn es jedoch trifft, können Sie eine Nachricht darüber generieren, sodass jeder Client die Rakete an der richtigen Stelle explodieren lassen kann. Kleinere Störungen können ignoriert werden.
Natürlich aktualisieren Sie Sachen nur, wenn sie den Client beeinflussen können! Etwas weit weg vom Bildschirm ist es nicht wert. Einige Werte können weniger häufig aktualisiert werden. Zum Beispiel sind die Positionen wichtig, um mehr oder weniger genau zu sein. Ereignisse (Tod, Schuss, Explosion usw.) müssen sofort gesendet werden, während nicht direkt wichtige Werte niedrigere Aktualisierungsperioden haben können, z. B. Anzeigetafel, Chat.
Das Packen von Daten ist ebenfalls wichtig. Sie können ungefähr 1400 Bytes (konfigurationsabhängig, dies ist die Standardeinstellung) in einem UDP-Paket übertragen. In der Regel sind einige Bytes Header vorhanden. So können Sie problemlos 50-100 Einheitenpositionen in einem Paket aktualisieren.
quelle
Abhängig von Ihrem Spiel können Sie ein "synchronisiertes Ausführungsmodell" in Betracht ziehen, bei dem jeder Client zufällig dasselbe Spiel spielt, indem er einfach nicht deterministische Eingaben wie Tastatur- / Joystick-Eingaben und Timer-Ereignisse teilt. (Im Vergleich zu einem Modell, bei dem jeder Client lokale Simulationen ausführt und erwartet, dass Ergebnisse aus Remote-Simulationen integriert werden). Ihre Spiel-Engine muss im Allgemeinen vollständig deterministisch sein, damit dies funktioniert. Dies kann je nach Spiel eine schwere Belastung sein. Wenn das Spiel jedoch bereits deterministisch ist, kann dies ein einfacherer Ansatz sein.
Dieser # AltDevBlogADay-Beitrag behandelt einige Aspekte dieses Ansatzes in einem modernen RTS (insbesondere, wie Sie erkennen, wann Ihre Kunden "verschiedene" Spiele ausführen ).
Denken Sie jedoch daran, es einfach zu halten, bis das Gegenteil bewiesen ist. :) :)
quelle