Ich weiß, dass mein supereinfaches Multiplayer-Setup wahrscheinlich keine gute Idee ist, aber warum?


11

Ich mache ein einfaches kleines MOBA nur zum Spaß. Ich habe alles im Einzelspielermodus gemacht, dann wurde mir klar: "Oh Mist, ich sollte wahrscheinlich Multiplayer hinzufügen, oder?"

Ich habe noch nie etwas mit Networking gemacht, also war es lustig und großartig zu lernen, wie man Lidgren in mein Spiel integriert . Die Sache ist, ich weiß ziemlich genau, wie ich Dinge mache, ist falsch, weil es meines Wissens nicht robust genug für Mainstream-Spiele ist, aber was ist daran falsch?

Was ich tue, ist im Grunde, wenn ein Spieler eine Aktion ausführt, sendet er eine Nachricht an den Server, die besagt: "Hey, ich habe gerade dieses Ding gemacht." Der Server und der Client führen beide dieselbe Simulation aus. Der Server sendet dann eine Nachricht an alle anderen Clients, in der er ihnen mitteilt, dass dieser Typ das getan hat.

Zum größten Teil, außer in einigen Fällen, wenn ein Spieler etwas tut, geht der Kunde davon aus, dass es cool ist, und macht es alleine weiter. Wenn Sie also mit der rechten Maustaste auf eine Stelle klicken, um dorthin zu gelangen, beginnt der Client dieses Spielers, seinen Mann dorthin zu bewegen, und sendet dann eine Nachricht an den Server, in der er darüber informiert wird.

Also im Grunde genommen:

  • Spieler 1 wirkt einen Zauber, der ihn sechs Sekunden lang 100% schneller bewegen lässt
  • Der lokale Client von Spieler 1 fügt diesen Buff seinem Einheitenobjekt hinzu
  • Der Client von Spieler 1 sendet eine Nachricht an den Server mit der Aufschrift "Hey, ich habe gerade diesen Zauber gesprochen".
  • Der Server stellt sicher, dass er wirklich genug Mana hat, um diesen Zauber zu wirken, und fügt diesen Buff in diesem Fall der Serverkopie dieses Einheitenobjekts hinzu
  • Der Server sendet eine Nachricht an alle anderen Clients mit der Aufschrift "Hey, dieser Typ hat gerade diesen Zauber gesprochen."
  • Jeder andere Client erhält die Nachricht und sagt "ah okay cool" und fügt diesen Buff seinem lokalen Einheitenobjekt für diesen Spieler hinzu

Ich habe Dinge durchgesehen, um zu sehen, wie große Spiele im Mehrspielermodus funktionieren, und es ist etwas verwirrend für jemanden, der gerade erst anfängt, sich mit diesen Dingen zu beschäftigen, aber es sieht so aus, als ob die Source-Engine ein Paket sendet, das alle Änderungen an allem im enthält Welt jede Zecke? Wiederum völlig neu in diesem Bereich, aber können Sie wirklich so viele Daten so häufig pushen?

Tut mir leid, wenn das ein bisschen wild ist, aber im Grunde habe ich mich gefragt, warum mein einfacheres System nicht der richtige Weg ist, denn wenn es so wäre, würden andere Spiele es verwenden, oder?


6
Ein Schritt, den Sie vermissen, besteht darin, dass der Server diese Nachricht auch an den ursprünglichen Client (nicht nur an alle anderen) sendet, um das Ergebnis der Simulation zu bestätigen oder abzulehnen. Der ursprüngliche Client fährt dann entweder fort oder passt sich an die neue Realität an. Abgesehen davon ist diese Methode in Ordnung und die anderen Antworten unten helfen Ihnen dabei, andere Aspekte besser zu verstehen.
Patrick Hughes

1
Was großartig ist, ist, dass der Rest von uns vernünftige Hoffnung hat, dass das Netzwerk nicht so schwer ist. Es ist machbar.
Asche999

Antworten:


12

Zusätzlich zur Antwort von Byte56 gibt es noch einige weitere Dinge zu beachten:

Wie werden Sie zwischen den Kunden über Spielerbewegungen kommunizieren? Im Gegensatz zu den meisten anderen Spieleraktionen, bei denen es sich in der Regel um isolierte Ereignisse handelt und die wahrscheinlich etwas selten sind, ist die Bewegung kontinuierlich. Die Rate, mit der Sie Updates senden und empfangen können (und möchten), ist begrenzt. Die von Byte56 erwähnte clientseitige Vorhersage beinhaltet typischerweise regelmäßige Aktualisierungen der Clientposition und -geschwindigkeit. Der Client interpoliert dann lokal zwischen ihnen und verwendet so etwas wie a kubischen Spline .

Ein zweites Problem, das mit den vorherigen verbunden ist, ist, dass UDP keine garantierte Zustellung hat. Sie können nicht sicher sein, dass jede von Ihnen gesendete Nachricht oder sogar in der richtigen Reihenfolge eintrifft. Sie können die Pakete 1, 2 und 3 senden, und der Server empfängt 3, dann 1 und nicht 2. Oft sind sie in der richtigen Reihenfolge und kommen oft an, aber nicht immer. Sie benötigen also ein System, das robust gegen Paketverlust ist. Ein einfaches Bestätigungssystem ist ausreichend. In der Regel wird ein Bitfeld verwendet, das dem anderen Knoten mitteilt, ob er die letzten 32 Nachrichten (für einen 32-Bit-Int) empfangen hat und welche Nachricht zuletzt empfangen wurde. Auf diese Weise können Sie Nachrichten als kritisch oder nicht kritisch kennzeichnen und erneut senden, wenn sie keine kritischen Nachrichten erhalten. Es gibt hier eine ziemlich anständige Diskussion darüber .

Beachten Sie dabei auch, dass Ihre Kunden nicht mehr miteinander synchronisiert sind. Jeder zeigt die anderen Spieler, die zwischen ihren beiden vorherigen Netzwerkrahmen interpolieren, während Sie im besten Fall am nächsten arbeiten. Sie benötigen also ein System, das (ziemlich) berücksichtigt, dass das, was ein Spieler sah, als er eine Aktion ausführte, nicht der tatsächliche Status des Spiels war, als er diese Aktion ausführte. Er reagierte auf einen alten, nicht synchronen Spielzustand.

Wenn dieses Spiel wettbewerbsfähig sein soll, müssen Sie sich auch Gedanken über Betrug machen. Daher müssen Sie, soweit möglich (und angemessen), den Kunden misstrauen und überprüfen, ob ihre Handlungen möglich waren. "Nein, du kannst nicht durch diese Wand gehen. Nein, du kannst nicht schneller als deine Laufgeschwindigkeit gehen. Nein, du kannst nicht behaupten, dieses Ziel getroffen zu haben." etc.

Für weitere Ideen empfehle ich, die anderen Artikel in diesem zweiten Link zu durchsuchen.

Viel Glück!


6

Was Sie beschreiben, ist im Wesentlichen eine clientseitige Vorhersage , aber Sie sagen nicht, was passiert, wenn Server und Client nicht übereinstimmen.

Es entwickelte sich aus den Tagen, als der Client nur ein dummes Terminal war und seine Eingaben an den Server sendete und der Server dem Client das Ergebnis mitteilte. Sobald sich die Spiele jedoch über das LAN hinaus bewegten (und häufig zuvor), war die Latenz in dieser Situation spürbar. Was Sie beschreiben, wurde eine clientseitige Vorhersage eingeführt, um dies zu beheben. Jetzt simuliert der Client auch die Bewegung, während er darauf wartet, dass der Server antwortet. Dann einigen sie sich auf das Ergebnis. Mit dem Server als Autorität.

In den nächsten Schritten reagieren Sie auf Meinungsverschiedenheiten. Wenn Sie dafür nichts eingerichtet haben, wird der Client mit Gummibändern oder Teleportierungen versehen, wenn Client und Server nicht übereinstimmen.


5

Zeitliche Koordinierung. In den anderen Antworten wird das Timing der Ereignisse auf dem Server und den verschiedenen Clients nicht erwähnt. Je nach Spiel kann dies etwas sein, auf das Sie achten müssen. Die Latenz (auch bekannt als Lag) führt eine variable Verzögerung zwischen dem Senden und dem Empfangen eines Pakets ein. Die Zeit kann schwierig sein, aber ich werde versuchen, die potenziellen Probleme so gut wie möglich zu erklären. Es gibt einige Spiele, die ohne Bedenken auskommen können, aber hier ist ein einfaches Beispiel dafür, wo es Probleme verursachen kann.

Angenommen, jeder handelt auf Pakete, sobald sie ankommen.

@ Time 0 (wall time), Player 1 puts up a shield   (Message has been sent, but not received by anyone)
@ Time 1, Player 2 shoots player 1   (Message has been sent, but not received by anyone)

Angenommen, Zeit 0 (T0) und T1 liegen nahe beieinander.

Was als nächstes passiert, hängt davon ab, wer dies betrachtet und in welcher Reihenfolge die Pakete auf dem Server ankommen. Der Server sollte immer das letzte Wort haben. Wenn der Server die Pakete in der oben angegebenen Reihenfolge empfängt, wendet der Server den Schild an, bevor der Schuss und Spieler 1 (P1) überleben. Aus der Perspektive von P1 wird er, nachdem er den Schild selbst aufgestellt hat, den Schild vor dem Schuss sehen und überleben. Aber was ist mit P2? Sie werden den Schuss sofort sehen, weil sie ihn geschossen haben, aber werden sie zuerst den Schild sehen? Wenn(T0 + latency between P1 and the server + the latency between the server and P2) > T1 , wird der Schild nach dem Schuss hochgehen und P2 wird denken, dass ihr Schuss P1 getötet hat. Der Server muss diese Situation irgendwie korrigieren.

Wenn der Server die Pakete jedoch in umgekehrter Reihenfolge empfängt (was durchaus möglich ist, auch wenn T0 <T1 ist), tritt das Gegenteil auf. P1 ist falsch (und tot), während P2 richtig (und siegreich) ist.

Es gibt einige Möglichkeiten, mit solchen Situationen umzugehen. Am einfachsten ist es jedoch, den Server alles tun zu lassen. Sie können versuchen, dies auf dem Client zu simulieren, aber keine dauerhaften Aktionen wie den Tod zulassen. Die Spieler müssen auf wichtige bahnbrechende Bestätigungen vom Server warten.

Das Senden eines Zeitstempels mit Aktionen kann von Vorteil sein. Wenn Sie den Kunden größtenteils vertrauen, können Sie diese Zeitstempel verwenden, um zu bestimmen, welche Aktion zuerst ausgeführt wurde, anstatt unserer ersten Annahme zu folgen. Dies kann schwierig sein, da das Empfangen von Nachrichten aus der Vergangenheit normalerweise bedeutet, dass Sie in der Lage sein müssen, die Zeit umzukehren.

Zeit macht Spaß, oder? Egal, was Sie am Ende tun, es ist hilfreich, sich dieser Zeitprobleme bewusst zu sein.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.