Serverseitige Eingabe


9

Derzeit ist der Client in meinem Spiel nichts anderes als ein Renderer. Wenn der Eingabestatus geändert wird, sendet der Client ein Paket an den Server und bewegt den Player so, als würde er die Eingabe verarbeiten, aber der Server hat das letzte Wort über die Position.

Dies funktioniert im Allgemeinen sehr gut, bis auf ein großes Problem: das Herunterfallen von Kanten. Wenn ein Spieler auf eine Kante zugeht, beispielsweise eine Klippe, und kurz vor dem Verlassen der Kante anhält, manchmal eine Sekunde später, wird er von der Kante teleportiert. Dies liegt daran, dass das Paket "Ich habe aufgehört, W zu drücken" gesendet wird, nachdem der Server die Informationen verarbeitet hat.

Hier ist ein Verzögerungsdiagramm, damit Sie verstehen, was ich meine: http://i.imgur.com/Prr8K.png

Ich könnte einfach ein "W Pressed" -Paket pro Frame senden, damit der Server es verarbeiten kann, aber das scheint eine bandbreitenintensive Lösung zu sein.

Jede Hilfe wird geschätzt!

Antworten:


5

Während der Server das letzte Wort über die Position hat, sollte er dies tun, indem er überprüft und überprüft, was der Client als Eingaben und Position sendet. Ich sage das, weil Sie den Player sofort bewegen und die Erwartung, die in Ihrem Code entsteht, ist, dass der Client die reale Position ist.

Sie denken, es funktioniert im Allgemeinen gut, aber es ist nicht. Randnotiz: Sie sagen, dass Ihr Client nichts anderes als ein Renderer ist, und geben ihm dann umgehend die lokale Kontrolle, um sich ohne Servernachrichten zu bewegen. Sie können es nicht in beide Richtungen haben. Warten Sie entweder, bis der Server Sie auffordert, sich zu bewegen, oder übernehmen Sie die Kontrolle über Ihre Position und verwenden Sie den Server, um Cheats zu überprüfen.

Ich stelle fest, dass Ihre Antworten eine ganze Sekunde erreichen? Das ist eine Latenz von 500 ms, die für jede Art von Actionspiel lächerlich groß ist. Versuchen Sie herauszufinden, warum dieser Turnaround so lange dauert. Dies kann alles sein, von der Sicherung von Befehlswarteschlangen über die nicht sofortige Bearbeitung bis hin zu überfluteter Bandbreite oder sogar Dämonen, die viele verlorene Pakete verursachen.

Was ich denke, sollte passieren

client sends a move + position update
server gets it t+latency time later
server verifies and sends out info to all clients
client receives this at (t+latency + latency)

Der schwierige Teil hier ist, dass ein Client, der eine Nachricht über sich selbst erhält, diese meistens ignorieren sollte, es sei denn, diese Nachricht ist so etwas wie "ungültiger Zug, gehe stattdessen zu XYZ". Wenn diese Nachricht für den Client eines anderen bestimmt ist, über den Sie Informationen erhalten, müssen Sie diese rechtzeitig vorwärts extrapolieren, damit sie so aussieht, wie sie sein wird.


Der Kunde sendet seine Position überhaupt nicht. es sagt einfach voraus / interpoliert. Deshalb fällt es von den Kanten, wenn es denkt, dass es am Rand ist. Außerdem sehe ich nicht, wo ich sagte, dass die Verzögerung 1 Sekunde betrug, sondern eher 8 ms (lokale Tests) bis 100 ms (über das Internet). Ich sagte, dass der Spieler später zurückgesetzt wurde, weil ich regelmäßig vollständige Positionsaktualisierungen verschicke. Habe ich Recht, wenn ich verstehe, dass ich die Position, die der Client für richtig hält, zusammen mit den gedrückten Tasten senden und der Server überprüfen sollte, ob dies möglich ist?
Thomas

"Manchmal wird er eine Sekunde später teleportiert" implizierte die großen Verzögerungen, von denen ich die Zeit bekam. Bei einem reaktionsschnellen Actionspiel spielt der Client und der Server in der Zeit zurück und teilt dem Client mit, ob etwas Illegales getan wurde. Sie werden feststellen, dass in Online-Multiplayer-Spielen meistens andere Personen ihre Positionen verschieben (diese stammen vom Server), während sich Ihre eigene Position nur sehr selten aufgrund direkter Serverkorrekturen ändert. Andere Leute sehen Sie Position wechseln, etc ...
Patrick Hughes

Könnte dies nicht dazu führen, dass der Player auf dem Server vom Rand fällt? Wenn ich nicht jedes Bild ein Paket sende, könnte der Server immer noch denken, dass sich der Player etwa 32 ms lang bewegt. (Ich sende nur alle drei Frames Pakete). Oder schlagen Sie vor, dass ich überhaupt keine Eingabe auf dem Server simuliere, sondern nur überprüfe, ob die Position innerhalb der Grenzen der gedrückten Eingabe liegt?
Thomas

Da der Server nur ungültige Bewegungen korrigiert, die vom Client gemeldet wurden, würde er niemals ein "Sie sind von der Klippe gefallen" senden, es sei denn, der Client selbst ist direkt über den Rand gefahren. In dieser Rückkopplungsschleife korrigiert sich der Server an der Sicht des Kunden auf die Welt und seinem Platz darin. Die Bewegung fühlt sich knackig an und reagiert auf den Spieler. Andere Aktionen wie die Interaktion mit Weltobjekten umfassen das Warten, bis der Server dem Client mitteilt, was gerade passiert ist, ein Kästchen anklicken und auf eine Antwort warten, aber wir sprechen hier nur von Bewegung.
Patrick Hughes

Das klingt sehr nach dem, was ich gerade mache. Senden einer Position an den Server und Überprüfen des Servers, ob der Spieler zu dieser Position hätte wechseln können. Das scheint jedoch ein heuristischerer Ansatz zu sein, und meiner Meinung nach wäre es nicht annähernd effektiv, wenn der Server entscheiden würde, Punkt. Würde das Senden von Zeitstempeln mit jedem Paket funktionieren? Ich denke, das würde das Problem beseitigen. Ich glaube, dass Halo und Spiele, die die Source-Engine verwenden, dies verwenden.
Thomas

0

Ich verstehe Ihre Frage als:

Der Server erhält ein Paket, wenn ich die Weiterleitungstaste drücke, und ein weiteres Paket, wenn ich die Weiterleitungstaste endlich loslasse. Daher beginnt und endet die tatsächliche Bewegung auf dem Server etwa 100 Millisekunden "zu spät" im tatsächlichen Spiel im Vergleich zu dem, was der Spieler auf der Clientseite ausdrückt. Wenn sich der Spieler also 10 Sekunden bewegen möchte, bewegt er sich möglicherweise 10x Sekunden, anstatt x >= 1online zu sein.

Dies ist eine schlechte Designstrategie, da sie nicht den Willen des Spielers in der Spielwelt zum Ausdruck bringt, wie der Spieler beabsichtigt, was zu einer eher schlechten Benutzererfahrung führt.

Die Lösung, die ich empfehlen würde, besteht darin, ein Paket zu senden (so oft Sie können), das angibt, wie viele Schritte der Spieler in welche Richtung unternommen hat. Der Server aktualisiert dann die Spielwelt mit dem neuen Spielerstandort, wenn er eine Korrektheitsprüfung besteht. So kann sich der Spieler mit großer Präzision bewegen und vermeiden, von hohen Leisten zu fallen.

Die Alternative wäre, sich die Positionen des Spielers in der letzten Sekunde zu merken und die Position im Nachhinein zu dem Zeitpunkt zu korrigieren, zu dem der Knopf losgelassen wurde. Klingt so, als würde es den Gummibandeffekt der alten Tage erzeugen (nur aus einem anderen Grund)

Grundsätzlich müssten Sie also ein Paket senden, von dem die Taste gedrückt wird und zu welcher tatsächlichen Spielzeit die Taste gedrückt wurde, und später, welche Taste losgelassen wurde und zu welcher genauen Zeit.


Wie ich zu Patrick sagte, denke ich, dass diese Lösung eher ein heuristischer Ansatz wäre; Anstatt dass der Server "The Man" ist, überprüft der Server die Clientdaten auf Gültigkeit. Dies muss natürlich einen gewissen Spielraum schaffen, damit Verzögerungen oder andere Netzwerkprobleme keine Fehlalarme verursachen.
Thomas
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.