Ich arbeite an einem 2D-Top-Down-Shooter und gebe mein Bestes, um Konzepte zu kopieren, die in vernetzten Spielen wie Quake 3 verwendet werden.
- Ich habe einen autorisierenden Server.
- Der Server sendet Snapshots an Clients.
- Schnappschüsse enthalten einen Zeitstempel und Entitätspositionen.
- Objekte werden zwischen Schnappschusspositionen interpoliert, damit die Bewegung reibungslos aussieht.
- Die Interpolation von Entitäten erfolgt zwangsläufig geringfügig "in der Vergangenheit", sodass wir mehrere Schnappschüsse haben, zwischen denen interpoliert werden kann.
Das Problem, dem ich gegenüberstehe, ist "Uhrzeitsynchronisation".
- Nehmen wir der Einfachheit halber einmal an, dass es beim Übertragen von Paketen zum und vom Server keine Latenz gibt.
- Wenn die Serveruhr 60 Sekunden vor der Clientuhr liegt, liegt ein Snapshot-Zeitstempel 60000 ms vor dem lokalen Client-Zeitstempel.
- Daher werden Entitäts-Snapshots gesammelt und etwa 60 Sekunden lang gespeichert, bevor der Client erkennt, dass eine bestimmte Entität seine Züge ausführt, da es so lange dauert, bis die Client-Uhr aufholt.
Ich habe es geschafft, dies zu überwinden, indem ich bei jedem Empfang eines Snapshots die Differenz zwischen Server- und Client-Uhr berechnet habe.
// For simplicity, don't worry about latency for now...
client_server_clock_delta = snapshot.server_timestamp - client_timestamp;
Wenn ich feststelle, wie weit die Entität in der Interpolation ist, addiere ich einfach die Differenz zur aktuellen Zeit des Kunden. Das Problem dabei ist jedoch, dass es zu Ruckeln kommt, da die Differenz zwischen den beiden Uhren abrupt schwankt, da Schnappschüsse schneller / langsamer als andere ankommen.
Wie kann ich die Uhren genau genug synchronisieren, dass die einzige wahrnehmbare Verzögerung die ist, die für die Interpolation fest codiert ist, und die, die durch gewöhnliche Netzwerklatenz verursacht wird?
Mit anderen Worten, wie kann ich verhindern, dass die Interpolation zu spät oder zu früh startet, wenn die Uhren erheblich desynchronisiert sind, ohne dass es zu Ruckeln kommt?
Bearbeiten: Laut Wikipedia kann NTP verwendet werden, um Uhren über das Internet innerhalb weniger Millisekunden zu synchronisieren. Allerdings scheint das Protokoll kompliziert und vielleicht übertrieben für den Einsatz in Spielen?