Ich mache ein schnelles Physikspiel, das ein Tischhockey ist. Mit zwei Schlägern und einem Puck. Das Spiel läuft auf dem iPhone / iPad und ich mache den Multiplayer-Teil über GameCenter.
So funktioniert das Netzwerksystem. Der Client, der die Übereinstimmung markiert, wird als Server abgerechnet, und derjenige, der die Übereinstimmungsanforderung akzeptiert, ist der Client.
Auf dem 'Server' läuft die Physik und die Antwort erfolgt sofort, und auf dem Client läuft auch die Physik, sodass sie zwischen dem Nachrichtenaustausch reibungslos aussieht. Was ich als Server mache, ist, dass ich dem Client meine Puckgeschwindigkeit und meine Position sende und der Client seine Puckgeschwindigkeit / Position in Bezug auf den Server anpasst, um ihn synchron zu halten. Andernfalls desynchronisiert die Physik und es vermasselt es.
Wenn die Netzwerklatenz gut ist, unter 100 ms sind die Ergebnisse ziemlich gut, ich habe ein reibungslos spielbares Spiel auf der Clientseite und das seltsame Verhalten ist minimal. Das Problem tritt auf, wenn die Verzögerung zwischen 150 und 200 ms liegt. In diesem Fall kommt es vor, dass mein Client-Puck bereits eine Kante und eine umgekehrte Richtung getroffen hat, aber eine Verzögerungsnachricht vom Server empfängt und sich etwas zurückzieht, was ein seltsames Gefühl für das Ballverhalten verursacht.
Ich habe ein paar Dinge darüber gelesen:
Beispiel für ein Pong-Netzwerk
Klicken Sie auf Synchronisierungsbeispiel
Wie kann ich das lösen? Soweit ich gelesen habe, ist die beste Option, die ich habe, eine Uhrensynchronisation auf dem Server / Client mit einem Zeitstempel durchzuführen, so dass ich, wenn ich Verzögerungsmeldungen zu meiner Uhr erhalte, diese einfach ignoriere und die Client-Simulation das machen lasse Job. Seid ihr damit einverstanden? Und da ich unzuverlässige Daten (UDP) sende, kann es sein, dass ich verspätete oder nicht ordnungsgemäße Nachrichten erhalte.
Wenn das der beste Ansatz ist, wie implementiere ich die Uhrensynchronisation? Ich habe die Schritte gelesen, aber ich habe es nicht ganz verstanden.
Es steht dass:
- Der Client stempelt die aktuelle Ortszeit auf ein "Zeitanforderungs" -Paket und sendet sie an den Server.
- Nach dem Empfang beim Server stempelt der Server die Serverzeit und kehrt zurück
- Beim Empfang beim Client subtrahiert der Client die aktuelle Zeit von der gesendeten Zeit und dividiert durch zwei, um die Latenz zu berechnen. Es subtrahiert die aktuelle Zeit von der Serverzeit, um das Client-Server-Zeitdelta zu bestimmen, und addiert die halbe Latenz, um das richtige Taktdelta zu erhalten. (Bisher ist dieser Algothim SNTP sehr ähnlich)
- Der Client wiederholt die Schritte 1 bis 3 fünfmal oder öfter und hält jedes Mal einige Sekunden an. In der Zwischenzeit kann anderer Datenverkehr zulässig sein, sollte jedoch für beste Ergebnisse minimiert werden. Die Ergebnisse der Paketempfänge werden akkumuliert und in der Reihenfolge der niedrigsten Latenz bis zur höchsten Latenz sortiert. Die mittlere Latenz wird bestimmt, indem die Mittelpunktstichprobe aus dieser geordneten Liste ausgewählt wird.
- Alle Stichproben über ungefähr 1 Standardabweichung vom Median werden verworfen und die verbleibenden Stichproben werden unter Verwendung eines arithmetischen Mittels gemittelt.
Nach diesem Beispiel hätte ich folgendes:
Stellen wir uns vor, das Spiel wurde geladen und meine Client-Zeit ist jetzt 0, also sende ich an den Server, dass meine Zeit 0 ist.
Es dauert 150 ms, bis die Nachrichten zum Server gelangen, aber die Uhr des Servers wurde bereits gestartet und liegt 1 Sekunde vor dem Client. Wenn der Server die Nachricht erhält, lautet die Zeit: 1.15 und sendet diese Zeit an den Client. Sind wir gut? Stellen wir uns vor, unsere Verzögerung ist konstant bei 150 ms.
Jetzt empfängt der Client die Zeit 1.15 und subtrahiert die aktuelle Zeit von der gesendeten Zeit und dividiert durch zwei, um die Latenz zu berechnen. Was ist: 0,3 - 0 = 0,3 / 2 -> 150 ms.
Es subtrahiert die aktuelle Zeit von der Serverzeit, um das Client-Server-Zeitdelta zu bestimmen, und addiert die halbe Latenz, um das richtige Taktdelta zu erhalten:
Client-Zeit: 0,3 Serverzeit 1,15
0,3 - 1,15 = 0,85 + Latenz (0,15) = 1
Wie ist das synchronisiert? Was vermisse ich?
Es ist mein erstes Mal im Multiplayer- und Netzwerkerlebnis, daher bin ich etwas verwirrt.
Vielen Dank.
Antworten:
Der veröffentlichte Algorithmus war korrekt, aber in Ihrem Beispiel vergessen Sie die Zeit, die das Serverpaket benötigt, um zum Client zu gelangen.
Wie Sie sehen können, würde der Client, wenn er seine Uhr auf 1,15 ändern würde, 0,15 hinter dem Server liegen. Aus diesem Grund müssen Sie den Ping (auch bekannt als Round Trip Time [RTT]) anpassen. Hier ist die vollständige Deltazeitberechnung, die in vielen Schritten durchgeführt wird:
Dies gibt uns die korrekte Deltazeit von 1,00 Sekunden
quelle