2009-09-11 14 views
31

Ich habe eine Server/Client-Architektur implementiert, wo alle Statusänderungen an die Funktion gesendet, validiert und an alle verbundenen Clients übertragen werden. Dies funktioniert ziemlich gut, aber das System behält die Synchronisierung zwischen den Client-Instanzen des Spiels ab sofort nicht bei.Multiplayer-Spiel-Synchronisation

Wenn es zwischen dem Server und einem bestimmten Client zu einer Verzögerung von 5 Sekunden kam, würde er die Statusänderung 5 Sekunden nach dem Rest der Clients erhalten, wodurch der Spielstatus nicht mehr synchron war. Ich habe nach verschiedenen Möglichkeiten gesucht, ein Synchronisationssystem zwischen den Clients zu implementieren, habe aber bisher nicht viel gefunden.

Ich bin neu in der Netzwerkprogrammierung, und nicht so naiv zu denken, dass ich ein funktionierendes System selbst erfinden kann, ohne dass ich dafür viel Zeit aufwenden muss. Die Idee, die ich habe, ist jedoch, ein Zeitsystem zu haben, so dass jede Zustandsänderung mit einem bestimmten Zeitstempel im Spiel verbunden ist. Auf diese Weise würde ein Kunde, wenn er eine Statusänderung erhalten würde, genau wissen, in welcher Spielperiode die Änderung stattgefunden hat, und würde dann in der Lage sein, für die Verzögerung zu korrelieren. Das Problem mit dieser Methode ist, dass in diesen Sekunden Verzögerung das Spiel auf der Client-Seite fortgesetzt hätte, und somit der Client müsste Rollback rechtzeitig für die Zustandsänderung aktualisieren, die definitiv unordentlich werden würde.

Also ich bin auf der Suche nach Papieren Diskussion die Themen oder Algorithmen, die es löst. Vielleicht ist mein gesamtes Design, wie das Multiplayer-System funktioniert, fehlerhaft, in dem Sinne, dass die Spielinstanz eines Clients nicht aktualisiert werden sollte, wenn nicht vom Server eine Idee empfangen wird? Im Moment aktualisieren sich die Clients nur selbst in ihrer Spielschleife, vorausgesetzt, dass sich keine Zustände geändert haben.

+3

Interessante Frage. – Ian

+0

Ich glaube, du solltest die akzeptierte Antwort noch einmal überdenken. Havenard sagte nichts über Totzeitrechnungen oder andere Lag-Versteck-Techniken, die heute benutzt werden. Es ist nicht so, dass Spiele einfach "verzögerte Spieler sollten ihre Bedingung akzeptieren"; Sie bemühen sich, den Lag zu verstecken, um das Spiel spielbarer zu machen. Wenn ich schließlich ein Spiel spielte, in dem die Leute überall herumspringen und ich kaum spielen könnte, würde ich das Spiel verdammt schnell verlassen. – Ricket

Antwort

16

Der grundlegende Ansatz dazu ist etwas genannt Dead Reckoning und ein ganz netter Artikel darüber finden Sie hier. Im Grunde handelt es sich um einen Vorhersagealgorithmus dafür, wo Entitätenpositionen für die Zeiten zwischen Serveraktualisierungen geschätzt werden.

Es gibt fortschrittlichere Methoden, die auf diesem Konzept aufbauen, aber es ist ein guter Ausgangspunkt.


auch eine Beschreibung, wie dies in der Source-Engine (Valves Motor zum ersten Half Life Spiel) kann here behandelt wird gefunden werden, ist das Prinzip im Grunde das gleiche - bis der Server verwenden Sie sonst eine Vorhersage erzählt Algorithmus, um die Entity entlang eines erwarteten Pfades zu bewegen - aber dieser Artikel behandelt den Effekt, den dies hat, wenn man versucht etwas tiefer zu schießen.

2

Ihre beste Option ist es, die Änderungen von der Zukunft an den Client zurückzusenden und damit zum gleichen Zeitpunkt beim Client zu sein, wie für andere Clients, die keine Lag-Probleme haben.

+0

THat ist eine offensichtliche Antwort, aber sicherlich öffnet sich ein potenzieller Fehler von Menschen Engpässen ihre Maschine zielgerichtet, bevor sie es nach einer Aktualisierung zu beschleunigen? Die Möglichkeit haben, Aktionen vor allen anderen durchzuführen ..? – Ian

+3

Das Paket in der Zeit zurücksenden ist die offensichtliche Antwort? wow ... – Martin

+0

Downvoted, Antwort macht keinen Sinn. – CiscoIPPhone

2

Wenn Client-Ereignisse mit der Rate ist der Server geschieht sehen ihn füttern, was der normale Weg ist (ich habe mit Protokollen von Ultima Online, KalOnline und ein bisschen World of Warcraft gearbeitet), dann würde diese momentane Verzögerung von 5 Sekunden dazu führen, dass er diese 5 Sekunden von Ereignissen erhält Ich sehe sofort, dass diese Ereignisse sehr schnell oder fast augenblicklich vorübergehen, da andere Spieler sehen würden, dass er sehr schnell für eine kurze Strecke "läuft", wenn seine Ausgaben sich ebenfalls verzögern. Danach fließt alles wieder normal.Abgesehen von der Normalisierung von Grafik und Physik kann ich keine speziellen Anforderungen sehen, um eine korrekte Synchronisation zu erreichen, sondern nur die Synchronisation.

Wenn Sie jemals Valve Spiele in zwei nahen Computern gespielt haben, würden Sie bemerken, dass sie sich nicht um kleine Details kümmern, wie "der genaue Ort, an dem Sie gestorben sind" oder "wo Sie tote Körpergeister angeflogen sind". Es liegt alles an der Client-Seite und ist vollständig von der Latenz betroffen, aber das ist irrelevant.

Immerhin müssen verzögerte Spieler ihren Zustand akzeptieren oder ihr verdammtes eMule schließen.

+0

Du sagst also, dass ich auf meinen Client zurückgehen und den Stand des Spiels neu updaten soll? Sagen wir, ich habe einen Spieler, der nach Süden zieht. Er wird dies weiterhin auf allen Client-Rechnern ohne ein Wort vom Server tun. Wenn er sich irgendwann nach Norden bewegt, werden ihn alle Klienten immer noch als nach Süden ziehen sehen, bis er sie benachrichtigt, und wenn sie es einmal getan haben, müssen sie rechtzeitig zurückgehen und seine Position neu updaten, da er es tatsächlich nicht war die ganze Zeit nach Süden ziehen. Da zurück in der Zeit und Neubeurteilung ist nicht machbar, ich denke, ich konnte Spieler absolute Positionierung bei bestimmten Intervall senden –

+0

Das ist jetzt, wie es getan werden sollte. Diese Bewegungsinterpolation muss ein Limit haben, er wird einige wenige Schritte voraus hängen, es sei denn, der Server interveniert mit neuen Informationen über seine Bewegungen. – Havenard

+0

In KalOnline ist es durch Coordenate Korrektur gemacht, jeder Schritt er aktualisiert den Player xyz Punkt in der Welt mit 3 signierten Bytes für X, Y und Z. Andere Clients interpolieren nur die Modellposition bis zum endgültigen xyz Punkt. Die Interpolation wird nicht einmal übersprungen, wenn neue Änderungen kommen, sondern nur das neue finale xyz von diesem Moment an. – Havenard

5

Es wird niemals eine Möglichkeit geben, eine perfekte Synchronisation über mehrere Blickwinkel hinweg in Echtzeit zu garantieren - die physikalischen Gesetze machen es unmöglich. Wenn die Sonne jetzt explodierte, wie konntest du garantieren, dass Beobachter auf Alpha Centauri die Supernova gleichzeitig mit der Erde sehen? Informationen brauchen Zeit zum Reisen.

Daher haben Sie die Wahl, entweder alles genau mit Latenz zu modellieren, die sich von Betrachter zu Betrachter unterscheiden kann (was Sie gerade haben), oder sie ungenau ohne Latenz zu modellieren und weitgehend über alle Zuschauer hinweg zu synchronisieren Rechnen/Extrapolation kommen). Langsamere Spiele wie Echtzeitstrategie neigen dazu, die erste Route zu gehen, schnellere Spiele gehen die zweite Route.

Insbesondere sollten Sie niemals davon ausgehen, dass die Reisezeit konstant ist. Dies bedeutet, dass das Senden von Start- und Stoppnachrichten zum Verschieben von Entitäten in beiden Modellen niemals ausreicht. Sie müssen regelmäßige Aktualisierungen des tatsächlichen Status (in der Regel mehrere Male pro Sekunde für schnellere Spiele) senden, damit der Empfänger Fehler in seinen Vorhersagen und Interpolationen korrigieren kann.