Dead Reckoning II

Einstiegsfragen, Mathematik, Physik, künstliche Intelligenz, Engine Design
Antworten
Halan
Beiträge: 73
Registriert: 22.01.2005, 21:47
Benutzertext: programmiersüchtig
Echter Name: Kai Mast
Wohnort: Freak City
Kontaktdaten:

Dead Reckoning II

Beitrag von Halan »

Ahoi,

habe hier schon öfters Fragen zur Synchronisation von Uhren etc gestellt. Woltle mal meinen aktuellen Stand mit euch abgleichen.

Der Client hat zur Interpolation der Bewegungen zwei Hilfsmittel
- Die RoundTripTime und damit auch die Latenz
- Die Serverzeit

Das funktioniert auch sehr gut muss ich sagen. Bewegungen sind flüssig. Ich habe nur ein Problem: Input. Wenn ich zum Beispiel die Richtung meiner Bewegung ändere muss der Client für eine Halbe RTT warten damit kein Unterschied zum Server entsteht. Der Server braucht ja diese Zeit bis er das Signal überhaupt erhalten hat. Wie behebe ich das? Kann ich da überhaupt viel machen? Serverseitiges Dead Reckoning will ich eigentlich vermeiden, das würde glaube ich zu viele Möglichkeiten eröffnen den Server zu manipulieren (durch Angabe einer falschen Latenz zum Beispiel).

Wie machen das denn andere Spiele. Bei manchen Online RPGs gingen die Latenzen ja teilweise gegen 1000ms aber die Bewegung wirkt trotzdem total flüssig...

Any Help?
Halan
Benutzeravatar
Chromanoid
Moderator
Beiträge: 4262
Registriert: 16.10.2002, 19:39
Echter Name: Christian Kulenkampff
Wohnort: Lüneburg

Re: Dead Reckoning II

Beitrag von Chromanoid »

Bei WoW und Co. siehst du im Grunde gar keine Serverpositionen bei deiner eigenen Figur. Das sieht man auch ganz gut, wenn man zwei Clients aufmacht - die eigene Figur zieht auf dem Nachbarbildschirm immer ziemlich nach. Bei den anderen Figuren merkt man ja eh nichts, wenn die Latenzzeit sich im Rahmen hält... Für Physik basierte Spiele ist AFAIK replay basierte Synchronisation best practice (siehe Gaffer on Games).
Hier zwei interessante Links:
http://playerio.com/documentation/tutor ... tipstricks
http://gafferongames.com/game-physics/n ... d-physics/

PS: Wo ist eigentlich "Dead Reckoning I" :) ? Ah http://zfx.info/viewtopic.php?f=7&t=1261 :)
Halan
Beiträge: 73
Registriert: 22.01.2005, 21:47
Benutzertext: programmiersüchtig
Echter Name: Kai Mast
Wohnort: Freak City
Kontaktdaten:

Re: Dead Reckoning II

Beitrag von Halan »

Ja, also einfach Kollision zwischen Spielern sollte schon drin sein.

Das Konzept wie im zweiten Link (Gaffer) beschrieben benutze ich ja. Also Client-Side-Prediction. Was ich hier eben nicht verstehe. Müsste die Client-Side Prediction die Bewegung dann nicht erst nach der halben Rountrip-Zeit starten bzw bis zum ersten Update vom Server langsamer ablaufen? Sonst ist ja ein ganz schöner Abstand zwischen Client und Serverlogik da.

Welche Inputverzögerungen sind denn wahrnehmbar? Hab da mal was von 200ms gelesen.
Benutzeravatar
Chromanoid
Moderator
Beiträge: 4262
Registriert: 16.10.2002, 19:39
Echter Name: Christian Kulenkampff
Wohnort: Lüneburg

Re: Dead Reckoning II

Beitrag von Chromanoid »

Halan hat geschrieben:Welche Inputverzögerungen sind denn wahrnehmbar? Hab da mal was von 200ms gelesen.
Das kommt sehr auf das Spiel an. Bei Autos ist ja sowieso eine Art Verzögerung auch im realen Leben vorhanden. Aber beim FPS sieht man das ziemlich schnell... Du benutzt also diesen replay mechanismus? Wenn du dann noch zwischen dem Zielzustand und dem "falschen" Zustand synchronisierst, sollte das doch eigentlich kaum wahrnehmbar sein? Wieviele Updates pro sekunde schickst du eigentlich? AFAIK ist so 20 bei moderneren Spielen normal.
Halan
Beiträge: 73
Registriert: 22.01.2005, 21:47
Benutzertext: programmiersüchtig
Echter Name: Kai Mast
Wohnort: Freak City
Kontaktdaten:

Re: Dead Reckoning II

Beitrag von Halan »

Chromanoid hat geschrieben:Du benutzt also diesen replay mechanismus? Wenn du dann noch zwischen dem Zielzustand und dem "falschen" Zustand synchronisierst, sollte das doch eigentlich kaum wahrnehmbar sein? Wieviele Updates pro sekunde schickst du eigentlich? AFAIK ist so 20 bei moderneren Spielen normal.
Naja du läufst halt mit deinem Charakter los und dann kommt nach ner kurzen Zeit das erste Server-Update und das ist schon spürbar weil er Client etwas ( eigentlich genau die Latenz) vorne liegt. Danach ist die Bewegung (bis zum nächsten Richtungswechsel) flüssig.
Überlege jetzt ob ich den Charakter auf Clientseite einfach noch eine Latenz lang stehen lass ( bis zu 250 ms müsste das ja einigermaßen ertragbar sein) oder ob er sich einfach bis zum ersten Serverupdate mit reduzierter Geschwindigkeit bewegen soll.

Glaube gerade beim Richtungwechsel wäre es besser immer noch eine Latenz zu warten bis ich auf der Clientseite was ändere. Damit müssten die Bewegungen synchron bleiben. Dann muss ich halt dafür sorgen dass die Latenz annehmbar niedrig bleibt...
Benutzeravatar
Chromanoid
Moderator
Beiträge: 4262
Registriert: 16.10.2002, 19:39
Echter Name: Christian Kulenkampff
Wohnort: Lüneburg

Re: Dead Reckoning II

Beitrag von Chromanoid »

Interpolierst du denn zwischen falschem und richtigen Zustand? Btw: Falls es dich interessierst, kannst du ja mal für uns alle recherchieren :) es gibt soweit ich mich erinnere ein paar Papers über Lag und was für den Spielspaß noch erträglich ist.

Ich hab nur das hier dazu in meinem JabRef gefunden (die Series zeigt der leider nicht an :evil: [ah kann man wenigstens bei jabref anpassen, aber bei word ist das ziemlich gruslig...], das ist mir sogar schon mal bei einer Ausarbeitung passiert :evil: ich glaube alles ist aus den NetGames Konferenzen) - sind jetzt aber alles keine knüller...:
Yasui, T.; Ishibashi, Y. & Ikedo, T. Influences of network latency and packet loss on consistency in networked racing games Proceedings of 4th ACM SIGCOMM workshop on Network and system support for games, ACM, 2005, 1-8
Pinelle, D.; Wong, N.; Stach, T. & Gutwin, C. Usability heuristics for networked multiplayer games Proceedings of the ACM 2009 international conference on Supporting group work, ACM, 2009, 169-178
Chen, K.-T. & Lei, C.-L. Network game design: hints and implications of player interaction Proceedings of 5th ACM SIGCOMM workshop on Network and system support for games, ACM, 2006
Palant, W.; Griwodz, C. & Halvorsen, P. Consistency requirements in multiplayer online games Proceedings of 5th ACM SIGCOMM workshop on Network and system support for games, ACM, 2006
pUnkOuter
Establishment
Beiträge: 303
Registriert: 15.04.2002, 15:59

Re: Dead Reckoning II

Beitrag von pUnkOuter »

Ich kann gerade nur aus persönlicher Erfahrung sprechen, aber was erträglich ist, hängt stark vom Spiel ab. Strategiespiele, oder DOTA, z.B. können so gegen 200ms verkraften, Shooter werden ab 100ms schon mühsam und Twitch-Spiele (wie z.B. M&B Multiplayer) werden schon ab 60ms schwierig zu spielen.

Eine Viertelsekunde Verzögerung, bis sich überhaupt etwas tut halte ich für absolut unzumutbar.
Ein Zeiger ins Blaue ist wie ein Wegweiser nach <SEGFAULT>. Wenn du denkst, mein Name hat was mit abgefuckter Kleidung und bunten Haaren zu tun, dann kehr besser um.
Benutzeravatar
ponx
Establishment
Beiträge: 217
Registriert: 04.05.2008, 12:52
Echter Name: Andy Ponx
Wohnort: Hamburg
Kontaktdaten:

Re: Dead Reckoning II

Beitrag von ponx »

hallo Jungs,
ich hab meine Bachelorarbeit über das Thema gemacht, allerdings für eine Firma und ich darf die Arbeit nicht veröffentlichen. Aber hier mal ein Überblick was es da für Techniken gibt:

1. Client-Side Prediction mit Interpolation
So macht es Counterstrike, deshalb ist es auch so schön präzise. Wenn ein Client losläuft sieht er das sofort bei sich auf dem Rechner, ohne Verzögerung. Gleichzeitig schickt er ein Paket an den Server los, mit einem Zeitstempel wann er die Vorwärts-Taste gedrückt hat.
Der Server sammelt die Pakete von allen Clients und hat so ein paar ms später immer das korrekte Bild vom Spielgeschehen, und verteilt diese Info weiter an alle Spieler. Der Server hat immer Recht: Falls Pakete verloren gegangen sein sollten und er nicht mitbekommen hat, wo du mittlerweile hingelatscht bist, setzt er dich an die jeweilige Position zurück ("Laaaaaag !"). Deshalb heißts "Prediction": Du sagst bei dir lokal voraus, wo der Server dich beim nächsten Positionsupdate hinsetzen wird, basierend auf den gedrückten Tasten und deiner aktuellen Position / Geschwindigkeit. Solange kein Datenverlust auftritt, wird diese Vorhersage immer stimmen.
Der Server sammelt mehrere dieser Positionsupdates, und gibt sie dann verzögert an die Clients raus, die dann zwischen den Positionsangaben interpolieren. Also wie eine Spur von Brotkrümeln, die die Spielobjekte bei dir lokal dann einsammeln. Dass erst mehrere Krümel abgewartet werden, bevor ein Spielerobjekt bei dir überhaupt erst losläuft hat den Sinn, dass auch mal ein Update verloren gehen oder stark verzögert werden kann, und die Darstellung ist immer noch geschmeidig. In der Praxis bei ner soliden Inetverbindung würde ich die Verzögerung auf die 2fache Gesamtlatenz setzen (also 2 x Client->Server->Client) setzen.
Durch die Latenz und diesen Verzögerungspuffer siehst du die Bewegung der anderen Spieler immer verzögert. Wenn du auf einen Spieler ballerst, ist der dementsprechend in Wirklichkeit schon ganz woanders ("schön durch die Kiste erschossen, der hat doch an !!"). Das macht bei Counterstrike aber in Sachen Fairness nichts, weil da jeder Schuss sofort trifft, und es keine Projektil-Objekte gibt, denen der andere noch ausweichen könnte. Wichtig ist nur, dass ihr den anderen in eurer lokalen Ansicht getroffen habt. Der Server rekonstruiert eure Ansicht (er hat ja alle Zeitstempel und Positionen der Vergangenheit) und weiß, wann ihr wen getroffen habt.
Die Position der Spieler spielt also bei CS nur eine Rolle, wenn die Spieler untereinander kollidieren und sich blocken. Die Spieler selbst bewegen sich bei CS aber langsam genug, dass diese Abweichung zu klein ist, um das Spielgeschehen zu beeinflussen. Auch Latenzen von 120 ms und mehr merkt man eigentlich nicht.
Also Fazit: Wenn sich alle relevanten Spielobjekte langsam genug bewegen, kann ich das nur empfehlen. Die meisten Shooter haben allerdings einen Raketenwerfer u.ä., da muss man dann mit anderen Techniken tricksen (siehe Dead Reckoning / Local Lag)

+ sehr präzise in der Darstellung, auch bei hohen Latenzen
- starke Abweichung zur tatsächlichen aktuellen Position der Spielobjekte
- braucht einen konstante, relativ hohe Updaterate (ca alle 50ms), viel Traffic


2. Dead Reckoning 1. Ordnung
Diese Technik ist in der Spielewelt am weitesten verbreitet. Sie berücksichtigt die Positionen der Spieler und deren Geschwindigkeit. Im Gegensatz zur Interpolation braucht man keine konstante Rate an Positionsupdates, sondern man muss im Prinzip nur einmal pro Richtungsänderung eine Nachricht an den Server schicken. Dadurch fällt normalerweise extrem wenig Traffic an im Vergleich zu Client Side Prediction mit Interpolation.
1. Ordnung heißt, dass nur die Geschwindigkeit mit einbezogen wird. Es gibt noch 2. Ordnung, dabei wird dann auch die Beschleunigung berücksichtigt. Alle Multiplayerspiele die wir untersucht haben, beschränken sich allerdings auf 1. Ordnung, weil im Falle von Lag/Paketverlust der Fehler sehr schnell sehr groß werden kann, und 1. Ordnung normalerweise auch präzise genug ist.
Also beim Standardansatz von Dead Reckoning schickst du wieder bei einer Richtungsänderung deiner lokalen Spielfigur ein Update an den Server. Der verteilt das sofort an die anderen Spieler weiter, und die setzen dich auf sofort nach Empfang auf die aktuellste Position, die sie gerade empfangen haben. Weil dabei auch die Geschwindikeit mitgeschickt wird, können sie anhand dieser Info dann ausrechnen, wo du bis zum nächsten Positionsupdate in jedem Frame ungefähr sein wirst. Aufgrund der Latenz wird diese Position zum Zeitpunkt der nächsten Richtungsänderung aber nie genau übereinstimmen. Um das zu kaschieren kann man dann von der lokal (geschätzten) Position zur neuen tatsächlichen Position hin-interpolieren. Das führt dann allerdings ggf zu einem kantigen Bewegungsverlauf, deshalb gibt's noch eine Variante davon: Man errechnet anhand der aktuellen Geschwindigkeit den Schnittpunkt mit der Bewegungsrichtung, um dann dahin zu interpolieren. Dadurch ist die durchschnittliche Abweichung zur tatsächlichen aktuellen Position zwar insgesamt schlechter, aber man vermeidet Sprünge in der Darstellung.

+ wenig Traffic
+ einigermaßen gute Übereinstimmung zur serverseitigen Position
- Gefahr von Sprüngen im Bewegungsverlauf

3. Dead Reckoning mit Time-Compensation
Im einfachen Dead Reckoning wird also jedes Spielobjekt beim Update jeweils ungefähr da angezeigt, wo man die letzte Position empfangen hat. Diese Information ist aber in jedem Fall verzögert um die Latenz von dessen Client zum Server, plus die Latenz vom Server zum lokalen Client. Das kann man ausgleichen, indem man Zeitstempel mitschickt: Wenn man weiß, wie alt die Information ist, kann man in Verbindung mit der Position und der Geschwindigkeit ja hochrechnen, wo sich das Objekt jetzt gerade im Moment befindet. Das funktioniert im Prinzip gut, allerdings kann man bei schnellen Richtungsänderungen bzw hohen Latenzen auch sehr falsch damit liegen. Das führt dann zu extremen Sprüngen in der Darstellung, auch wenn die Position in der lokalen Darstellung dann insgesamt besser übereinstimmt. In der Praxis ist es also gesund, da einen Mittelweg zu finden, und nicht über die volle Latenz hochzurechnen. Das hängt natürlich auch von deinem Bewegungsmodell ab, also wie ruckartig man in deinem Spiel die Bewegungsrichtung ändern kann.

+ wenig Traffic
+ sehr gute Übereinstimmung zur serverseitigen Position
- große Gefahr von Sprüngen im Bewegungsverlauf


4. Local Lag
Noch ein Ansatz, die durchschnittliche Abweichung in der Darstellung klein zu halten ist natürlich, die ganze Aktion schon lokal zu verzögern. Also radikalster Ansatz: Der Spieler bewegt sich auch auf seinem eigenen Rechner nicht, bis man die tatsächliche Antwort vom Server erhalten hat. So wirds z.B. bei Echtzeit-Strategiespielen gemacht, wo die genaue Position der Einheiten sehr wichtig ist, und es umgekehrt relativ wurscht ist, dass die Einheiten dann nach dem Klick nicht sofort loslaufen. Bei Shootern leidet das Spielgefühl aber natürlich extrem. Local Lag empfielt sich da bei einigen Aktionen aber trotzdem: Wenn z.B. ein Raketenwerfer abgefeuert wird, ist es sehr wichtig, dass bei allen Beteiligten die Darstellung möglichst gut übereinstimmt, damit man zielen bzw. ausweichen kann. Da sollte der Fehler also möglichst klein sein, und deshalb arbeitet Unreal Tournament z.B. da auch mit Local Lag: Das Mündungsfeuer wird lokal zwar sofort angezeigt, aber das Projektil fliegt erst los, nachdem der Server die "abgefeuert"-Nachricht bestätigt hat. Die Positionsabweichung der Spieler ist aber nicht so ohne weiteres auszugleichen. Bei UT kann es deshalb trotzdem passieren, dass man lokal das Projektil an sich vorbeifliegen sieht, der Server das aber anders sieht, und kurz danach liegt man tot am Boden. Umgekehrt genauso: Leute werden in der lokalen Darstellung vom eigenen Projektil erwischt, aber in Wirklichkeit hat man knapp verfehlt ("Cheater!"). Wie bei Time Compensation auch kannst du da nur selber ausprobieren, was für welche Aktion in deinem Spiel das beste ist, und mit dem Verzögerungswert rumexperimentieren. Es ist immer ein Tradeoff zwischen 'sieht gut aus' vs. 'spielt sich flüssig' vs. 'ist fair und transparent für alle'.

+ eröht die Übereinstimmung zur serverseitigen Position
- verschlechtert das Spielgefühl


Hinweis für Zeitstempel: Ihr braucht eine gemeinsame Zeitreferenz, z.B. die Serverzeit als vergangnene Millisekunden seit Level-Start. Damit die nicht durch die unterschiedlichen Latenzen der Clients zueinander verfälscht wird, müsst ihr am Anfang einmal ausrechnen, wie um wieviele ms die lokale Uhr von jedem Client zu der des Servers abweicht. Am besten damit: http://de.wikipedia.org/wiki/Algorithmus_von_Cristian


viele Grüße,
ponx
Zuletzt geändert von ponx am 17.09.2011, 01:03, insgesamt 5-mal geändert.
Wollnashorn
Beiträge: 1
Registriert: 31.12.2010, 04:31

Re: Dead Reckoning II

Beitrag von Wollnashorn »

Dankeschön an Ponx, dein Beitrag war sehr informativ und hat mir ziemlich geholfen. :)
Antworten