Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

RmbRT

Treue Seele

  • »RmbRT« ist der Autor dieses Themas

Beiträge: 169

Wohnort: Darmstadt

Beruf: Student

  • Private Nachricht senden

1

09.06.2014, 23:52

[Gelöst] Zählerwert zwischen Client und Server synchron halten?

Hallo Community,
Ich arbeite gerade an einem (M)MORPG. Die Logik soll natürlich auch auf den Clienten simuliert werden, um unschöne Lags zu vertuschen.
Dafür haben wir einen eigenen Zahlengenerator (Pseudo-Zufall), damit wir einen deterministischen Zufall auf Server und Client haben.

Die ganzen Klassen, die mit dem RNG zu tun haben, haben alle einen Member

C-/C++-Quelltext

1
int RNGcounter, id;
Die id ist so wie ein Primärschlüssel bei Datenbanken, d.h., einzigartig. Der RNGCounter wird nach jeder Zufallsberechnung, die dieses Objekt betraf, erhöht.
Dann wird, wenn zum Beispiel ein Spieler einen anderen angreift, um zu errechnen, ob der Spieler getroffen hat, folgendes gemacht:

C-/C++-Quelltext

1
2
float chance = RNG::fNum(0.f,1.f, Player1.id, Player1.RNGCounter++, Player2.Id, Player2.RNGCounter++);
if(chance>=hittreshold) //usw.

fNum nimmt dabei Unter- und Oberwert an, gefolgt von mehreren "seeds". Damit jedes mal ein anderer Zufallswert rauskommt, wird der RNG-Zähler beider Spieler erhöt.
Aber wie mache ich es nun am geschicktesten, dass diese RNGCounter-Werte bei allen Synchron bleiben?
Wenn jetzt zum Beispiel der Spieler eigentlich außerhalb einer Schusslinie wäre, sich aber auf dem Clienten auf einmal zum Schuss hinbewegt, also so, dass der Server noch nichts davon weis, und dann auf dem Clienten der Spieler mit dem Pfeil kollidiert, wird ja der RNGCounter des Clienten benutzt, um zu berechnen, ob er doch ausweicht, oder ob es ein kritischer Treffer war o.ä.. Diese Berechnung findet aber auf dem Server nicht statt, da dieser noch nicht weis, dass der Spieler in den Schuss gelaufen ist. Dadurch hätte man ja zwei verschiedene RNG-Counter-Werte.
Das beeinflusst ja alle zufallsgesteuerten Ereignisse, z.B. Drops eines besiegten gegners etc.
Wisst ihr, wie man das Problem am besten löst?
Wie geht man am besten damit um, wenn der Client widersprüchliche Daten zu denen des Servers hat (z.B. wenn es laggt, und man wegrennen will vor den Gegnern,
so wäre es doch am fairsten, wenn der Server die in verzug geratenen Daten vom Clienten noch annimmt, statt ihn stehen und sterben zu lassen.)?

MfG, RmbRT
"Dumm ist, wer dummes tut."

Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »RmbRT« (10.06.2014, 16:22)


BlueCobold

Community-Fossil

Beiträge: 10 738

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

2

10.06.2014, 06:43

Versuch nicht die Logik auf beiden Seiten abzubilden. Entscheide Dich für eine. Mein Vorschlag wäre rein auf dem Server.
Teamleiter von Rickety Racquet (ehemals das "Foren-Projekt") und von Marble Theory

Willkommen auf SPPRO, auch dir wird man zu Unity oder zur Unreal-Engine raten, ganz bestimmt.[/Sarkasmus]

RmbRT

Treue Seele

  • »RmbRT« ist der Autor dieses Themas

Beiträge: 169

Wohnort: Darmstadt

Beruf: Student

  • Private Nachricht senden

3

10.06.2014, 14:36

Ich habe aber gehört, dass es besser ist, die Logik auch auf dem Clienten zu simulieren, da man dann bei schlechteren Latenzen keine "Standbilder" hat.
Zum Beispiel soll ja ein Monster, was einen Laufbefehl nach Punkt x hat, nicht ruckeln, sondern der Pfad auch auf dem Client berechnet werden.
MfG
"Dumm ist, wer dummes tut."

BlueCobold

Community-Fossil

Beiträge: 10 738

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

4

10.06.2014, 15:47

Das nennt sich dann Client-side-prediction. Du lässt z.B. die Spielfigur schon mal dorthin laufen, wohin der Spieler will, validierst die tatsächliche Position aber auf dem Server und schickst bei zu viel Differenz zwischen Client und Server vom Server aus eine Korrektur an den Client.
Generell gilt aber: All incoming data is evil. Daher sollte der Server so viel wie möglich validieren und selbst vorgeben. Du willst ja nicht, dass Spieler durch Wände laufen, auf Türme springen oder sich durch ganze Welten teleportieren, Drops einsammeln wo keine sind, etc..
Das heißt aber nicht, dass Du ALLE Ereignisse auf dem Client simulieren solltest. Das führt erstens zu Redundanz und doppelten Code (was schwierig bei Änderungen ist) und viel schlimmer führt es zweitens zu inkonsistenten Zuständen, wo sich Server und Client nicht einig sind. Daher versuche solche Zustände zu vermeiden und nur ganz gewisse Dinge durch den Client auch ohne Server-Rückmeldung schon auszuführen (laufen, drehen, Magie ausführen, ein Ziel anwählen, etc). Der Server muss dennoch alle diese Aktionen verifizieren oder verwerfen.

Mein Vorschlag:
Lass ALLES den Server machen. ALLES. Sende vom Client nur ein Request, der Server verarbeitet es und gibt dem Client den echten Befehl etwas zu tun. Einige MMORPGs arbeiten so und das funktioniert reibungslos. Das allein ist schon kompliziert und aufwendig genug um es als hohes Projektrisiko einzustufen. Client-side-prediction kannst Du immer noch nachrüsten, wenn der Rest funktioniert. Und zwar an den Stellen, die für den Spieler am meisten auffällig sind. Aber nicht generell bei allem von Anfang an. Da scheiterst Du an Problemen, die mit dem eigentlichen Ziel überhaupt nichts zu tun haben - wie man jetzt ja schon sieht.
Teamleiter von Rickety Racquet (ehemals das "Foren-Projekt") und von Marble Theory

Willkommen auf SPPRO, auch dir wird man zu Unity oder zur Unreal-Engine raten, ganz bestimmt.[/Sarkasmus]

RmbRT

Treue Seele

  • »RmbRT« ist der Autor dieses Themas

Beiträge: 169

Wohnort: Darmstadt

Beruf: Student

  • Private Nachricht senden

5

10.06.2014, 16:22

Danke für die Antwort.
Ich werde es dann wirklich so machen wie du es vorgeschlagen hast, ich dachte nur, dass es schlechter Stil wäre, alles nur auf dem Server laufen zu lassen.
MfG
"Dumm ist, wer dummes tut."

BlueCobold

Community-Fossil

Beiträge: 10 738

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

6

10.06.2014, 16:31

Für die Top-10-Spiele der Welt ganz sicher. Für alle anderen keineswegs. :)
Teamleiter von Rickety Racquet (ehemals das "Foren-Projekt") und von Marble Theory

Willkommen auf SPPRO, auch dir wird man zu Unity oder zur Unreal-Engine raten, ganz bestimmt.[/Sarkasmus]

Werbeanzeige