Vernetzung und Bewegung in der Einheit des MMORPG


8

Ich programmiere einen dedizierten Server in C # mit BeamServer2-DLLs. Zuerst wollte ich sehen können, wie sich andere Spieler auf unserer bereits erstellten Omuni-Karte bewegen. Dazu habe ich einfach Ihre Position in jedem Frame an den Server gesendet. Das hat geklappt und ich konnte mit ein paar Freunden spielen, aber die Bewegung war nicht nachlässig. Also habe ich versucht, Bewegungsglättung und Sicherheit hinzuzufügen, damit sie nicht einfach eine falsche Position an den Server senden können, ohne dass der Server sie daran hindert, die anderen Clients zu erreichen.

Was ich dann getan habe, habe ich einen MasterClient erstellt, der einen MovementController auf dem RemotePlayer hat. Wenn ein Client umziehen möchte, bewegt er sich lokal und sendet eine Nachricht an den Server mit der Anweisung, sich zu bewegen. Der Server nimmt dann seine Geschwindigkeit und sendet sie an den masterClient. Der masterClient bewegt dann den remotePlayer genauso wie der remotePlayer sich selbst. Wenn er aufhört sich zu bewegen, sendet er eine Nachricht mit seiner Position. Der Masterclient prüft dann, ob die Position, zu der er gekommen ist, so nahe ist wie die Position, die er vom Client hat, wenn dies gemäß dem Ping des Clients realistisch ist, setzt der Server ihn auf die Position des Clients.

Dies funktioniert, aber ich habe immer noch ein Verzögerungsproblem und bin mir nicht sicher, wie ich das beheben soll. Ich muss die Bewegung auf dem Client glätten, aber ich habe selbst herausgefunden, dass ich einfach (x / 2, y / 2, z / 2) zur Position lerp und ihn auf die reale Position im nächsten Frame bringen kann werde es bald wieder versuchen. Selbst wenn das hinzugefügt wird, bin ich mir nicht sicher, ob der Lagg behoben ist.

Irgendwelche anderen Techniken, Vorschläge, Fragen, ...? Danke, Diede.

Antworten:


8

Es gibt viele Probleme / Aufgaben beim Programmieren von Echtzeit-Netzwerkspielen ohne Verzögerung.

  • Hardwaregeschwindigkeit (benötigte CPU-Leistung pro Player, Client und Server)
  • Netzwerkentfernung und Ausrüstung (Verbindungs-LAN oder WAN?)
  • Serverbandbreite (wie viele Spieler)

Zweitens haben Sie die "bösen Jungs", die immer versuchen, in Spielen zu betrügen. Wenn Ihr Spiel an die Öffentlichkeit geht, überlegen Sie, was passieren würde, wenn ich mich hinsetze und "falsche" Netzwerkpakete injiziere. Überlegen Sie, ob jemand "nicht erreichbare Positionen" oder "volle Gesundheit / Munition" gepostet hat.

Mein Vorschlag für Ihre Architektur wäre zunächst etwa so:

  • Server, steuert alle wichtigen Daten, berechnet UND validiert die Bewegung.
  • Der Client erhält Daten darüber, was auf dem Bildschirm angezeigt werden soll, sowie einige Vorausdenkdaten zu sich bewegenden Objekten.

Wie ich weiß, machen die meisten Echtzeit-FPS eine Art "Wir wissen, dass Sie diese Richtung mit dieser Geschwindigkeit bewegen, also simulieren wir das nur, bis wir andere Details vom Server erhalten".

Ihr Client sollte also "was er anfordert" posten und möglicherweise sogar beginnen, sich in diese Richtung zu bewegen, aber er wird möglicherweise vom Server "zurückgedrängt", wenn der Server die Bewegung ablehnt. Hier muss man sich überlegen, was passiert, wenn der Client "falsche Koordinaten" außerhalb der Karte veröffentlicht oder plötzlich "springt". Der Server muss verfolgen, ob die neue Position von seinem vorherigen Punkt aus möglich ist, ODER der Server erhält nur die Meldung "CLIENT MOVE FORWARD 200" und der Server verarbeitet dann, was dies gemäß Karten- und Spieldaten tun wird.

Dies führt zu einer gewissen Verzögerung. Wenn Sie jedoch zulassen, dass der Client diese Daten empfängt und selbst einige Berechnungen durchführt, muss er nicht alle ms / Frame aktualisiert werden. Er kann ohne merkliche Verzögerung auf dem Bildschirm etwas verzögern.

Vielleicht können Sie die Karte sogar in "virtuelle Kacheln" unterteilen (wenn es sich um ein Vektorspiel handelt), damit Sie schnell berechnen können, wo sich die Objekte als nächstes befinden sollen.

World of Warcraft / Schlachtfeld / Gegenschlag

Ich glaube, WOW macht das auch so. Sie drücken eine Taste, der Server empfängt Ihre Bewegung "Wunsch" und antwortet mit "Sie bewegen sich jetzt" und dann zeigt der Client dies + der Server simuliert die neue Position auf dem Server in einer Art "Sitzung pr. Client". Dies ist der Punkt, an dem die "maximale Anzahl an Spielern pro Spiel" unangenehm wird, da Ihr Server alle im Auge behalten und dies im Grunde genommen als "rundenbasiert" tun muss - aber so schnell, dass es in Echtzeit aussieht.

Damit...

Foreach (Client in GameSessionList)
{
   ParseInput();
   ParseMovement(); // including collission test
   ResponseSend(); // new positions+movement data for client and objects/other players
}

3
Gibt es einen Grund, unhöflich zu sein, unabhängig von den Vorzügen seiner Antwort?
Konrad

Ich hatte den Eindruck, dass in den meisten FPS-Spielen die Clients und der Server unabhängig voneinander kollidieren und der Server die Clients korrigiert, wenn sie zu stark variieren, anstatt dass die Clients nur simulieren.
Magus

Mir ist nicht bewusst, wie jeder FPS das macht. Aber ja, zB. Die BF-Serie hat etwas, das sie Netcode nennen, was bedeutet, dass sie die Berechnungen lokal durchführen und die Ergebnisse an den Server senden, der die Ergebnisse dann überprüft und verteilt (wie mir gesagt wurde). Dies hat möglicherweise mit der großen Menge an "Partikeln" / Details zu tun, die andernfalls übertragen werden müssen. Wo WOW eine statischere Welt ist und Sie keine Kollision zwischen Zeichen haben (im normalen Modus), ist es in Ordnung, Sie durch jemand anderen "gleiten" zu lassen.
BerggreenDK

2

Der herausfordernde Teil der Verzögerungskompensation besteht darin, dass Sie Updates von Kunden erhalten, die nicht in Ordnung sind. Der zum Zeitpunkt T gesendete Befehl eines verzögerten Clients kann sehr wohl nach einem Befehl des nicht verzögerten Clients eintreffen, der bei T + 40 ms gesendet wird. Das Anwenden der Befehle in der Reihenfolge, in der Sie sie erhalten, führt zu allerlei Gemeinheit. Um dies richtig zu machen, müssen Sie die Zeit zurückdrehen und alle seitdem ausgegebenen Befehle wiedergeben.

Es gibt keinen einfachen Weg, dies zu umgehen, aber es gibt mehrere gültige Lösungen. Eine relativ einfache finden Sie hier .

Es gibt viel Forschung auf diesem Gebiet, schauen Sie sich um!


1

Ich würde den Client so erstellen, als wäre er ein Spiel ohne Netzwerk. Das heißt, alles, was Sie tun, tun Sie sofort auf dem Client. Fügen Sie dann parallel dazu Ihren Netzwerkcode hinzu. Dieser Code erhält die Bewegungsdaten. Einfach wie von Koordinaten, Richtung und Geschwindigkeit. Es sendet dies nur an den Server, der validiert. Der Server sendet Ihnen ein OK oder eine neue Position.

Sie haben also Ihren gesamten Client-Code so, als ob er alleine auf der Welt wäre. Dann erhält es einfach neue Korrekturdaten vom Server oder ein OK. Wenn Sie vorwärts drücken und zehn Sekunden lang gedrückt halten, empfängt der Server nur diese einen Daten. Sie können das Senden / Empfangen von Daten jede Sekunde in Betracht ziehen, obwohl Sie nur die Vorwärts-Taste gedrückt halten, oder wenn Sie auf eine Verzögerungsspitze stoßen, werden Sie möglicherweise für immer ausgeführt.

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.