Ich habe über ein Multiplayer-RTS-Spiel nachgedacht. Der Teil, den ich nicht umgehen kann, ist die Synchronisation der Einheitenbewegungen. Wenn ich Einheit A auf XY stelle, muss ich dies dem Server mitteilen, der es an den anderen Client weiterleitet.
Ich bin gespannt, wie die Kommunikation aussehen würde. Möchten Sie dem Server nur mitteilen, dass ich die Einheit A von JZ nach XY verschiebe? Vielleicht müssen Sie stattdessen Bewegungskoordinaten kommunizieren? Was ist die effizienteste Methode, um die Bewegung von Einheiten von einem Client zum anderen zu kommunizieren?
BEARBEITEN
Dies ist eine neu gestellte Frage von Stackoverflow . Ich fand, dass diese Seite wahrscheinlich ein besserer Ort für die Frage war.
Eine der besseren Antworten aus diesem Beitrag:
Ich gehe davon aus, dass Sie beabsichtigen, das Client-Server-Netzwerk-Paradigma zu verwenden. In diesem Fall können Sie den Clients nicht vertrauen, dass sie die tatsächliche Positionierung der Einheiten vornehmen. Sie müssen diese Aufgabe an den Server delegieren. Anschließend nehmen Sie die Befehlsliste von jedem Client pro Tick und berechnen die Bewegung jeder Einheit. Sobald dies abgeschlossen ist, geben Sie mit dem nächsten Tick die Position jeder Einheit weiter, die für jeden Client relevant ist (entweder auf der Basis einer ganzen Karte oder Ansichtsbasis), und starten Sie den Vorgang erneut.
Antworten:
Sie möchten nicht die Positionen aller Einheiten vom Server zu jedem Client synchronisieren. Das wird viel mehr Bandbreite in Anspruch nehmen, als Sie benötigen. Sie müssten sich auch mit dem Interpolieren / Extrapolieren von Einheitenpositionen usw. befassen. Fast keine professionellen RTS verwenden Client / Server!
Stattdessen möchten Sie nur die Befehle der Spieler senden. Anstatt die Einheiten sofort zu bewegen, wenn der Spieler darauf klickt, werden Sie den Befehl zum Verschieben, der zu einem späteren Zeitpunkt ausgeführt werden soll, in eine Warteschlange stellen - normalerweise nur ein paar Frames. Jeder sendet seine Befehle an alle. Ein paar Frames später führt jeder alle Befehle aus, und da das Spiel deterministisch ist, sehen alle das gleiche Ergebnis.
Der Nachteil ist, dass jeder Spieler so langsam ist wie der langsamste. Wenn jemand beim Aussenden von Befehlen ins Hintertreffen gerät, muss jeder langsamer werden und warten, bis er aufholt (in Starcraft 2 verlangsamt XXX das Spiel " dialog).
In der Tat gibt es noch eine weitere Sache, die normalerweise erledigt wird: den Server komplett ausschalten . Lassen Sie jeden Client seine Befehle an jeden anderen Client senden. Dies verringert die Verzögerung (anstatt eines Befehls von Ihnen -> Server -> Gegner, geht es nur von Ihnen -> Gegner) und erleichtert das Codieren, da Sie keinen separaten Server mehr codieren müssen. Diese Art von Architektur wird als Peer-to-Peer (P2P) bezeichnet.
Der Nachteil ist, dass Sie jetzt eine Möglichkeit zum Lösen von Konflikten benötigen. Da die Befehle der Spieler in den meisten Echtzeitstrategien jedoch unabhängig voneinander sind, ist dies normalerweise kein großes Problem. Außerdem skaliert es nicht gut - jedes Mal, wenn Sie einen neuen Spieler hinzufügen, muss jeder Spieler ihm seine Befehle senden. Sie werden kein MMO-RTS mit P2P erstellen.
Dieses Setup (nur das Senden von Befehlen über P2P) entspricht der Funktionsweise der meisten RTSs, einschließlich Starcraft, C & C und AoE, und ist die einzige Möglichkeit, mit der AoE möglicherweise 1500 Einheiten bei einer 28,8-kbps-Verbindung unterstützen kann .
Hier einige weitere Tipps zum Schreiben eines P2P-RTS:
rand()
,cos()
etc., aber so ziemlich alle Gleitpunktarithmetik sind aus der Frage (siehe hier , hier und hier ) ! In diesem Fall ist es möglicherweise besser, Client-Server zu verwenden.quelle
Ich habe ein TCP-vernetztes RTS erstellt, bei dem ich die Befehle selbst und nicht die Ergebnisse der Befehle übergeben habe . Zum Beispiel gibt ein Spieler einen Zugbefehl. Wenn der Verschiebungsauftrag für diesen Client gültig ist, wird er an den Server gesendet. Der Server sendet es dann an alle Clients zurück, die es validieren und ausführen.
Damit alle Client-Computer das Spiel selbst ausführen, akzeptiert der Server-Code Nachrichten und sendet sie an alle Clients zurück. Wenn ein Client einen Verschiebungsbefehl erteilt, wird er erst ausgeführt, wenn er vom Server zurückerhalten wird.
Der Server sendet eine 'Tick'-Nummer, an der auch der Befehl ausgeführt werden soll. Dies ist ein paar Ticks vor dem' aktuellen 'Tick. Auf diese Weise können alle Befehle auf allen Rechnern mit demselben Häkchen ausgeführt werden.
Ein Vorteil dieser Methode besteht darin, dass die Überprüfung des Befehls nicht von einem einzelnen Client-Computer abhängig ist. Wenn ich die Ergebnisse des Zuges bestanden habe, kann ich ihn möglicherweise hacken, um meine Einheiten schneller zu bewegen. Alle Clients müssen denselben Befehl ausführen, und wenn ein Computer ihn anders ausführt, ist dies offensichtlich.
Die Überprüfung des Befehls auf der Client-Seite vor dem Senden an den Server ist nicht erforderlich, spart jedoch theoretisch Netzwerkverkehr. Ich habe den gleichen Validierungscode verwendet, um der Benutzeroberfläche mitzuteilen, dass das Verschieben möglich ist, sodass kein zusätzlicher Code erforderlich ist.
Wie die Nachrichten aussehen könnten. Es ging mir nicht um Ultraeffizienz, da es mein erstes vernetztes Spiel war. Ich habe Befehle als Zeichenfolgen übergeben. Die Befehle würden folgendermaßen formatiert sein:
"<player_id>:<command>:<parameters>"
Für ein konstruiertes Beispiel könnte ein Bewegungsbefehl wie folgt aussehen:
"3:move:522:100:200"
. Dies bedeutet, dass der Spieler3
einemove
Einheit bilden möchte522
(100
,200
).Der Server übergibt den Befehl an alle Kunden, einschließlich dem, der es geschickt, mit einem Häkchen Zahl wie folgt angebracht:
"153238:3:move:522:100:200"
.Dann würden alle Clients diesen Befehl ausführen, wenn Tick 153238 ausgeführt wird.
quelle