"Schüsse"/schnelle Bewegungen übers Netzwerk übermitteln - wie am besten realisieren?



  • Der Titel verrät schon meine Frage. Ich bin grade dabei, ein Spiel mithilfe der WinAPI zu programmieren (was aber zweitrangig ist). Es gibt beliebig viele Spieler, die auf einer 2D-Spielfläche rumlaufen und irgendwas machen (ein genaues Konzept hab ich noch net, wird wohl ein chaotisches Spiel werden :D).
    Momentan können die Spieler rumlaufen und es sind Dinge wie "Spezialblöcke" vorhanden, durch deren Einsammeln bestimmte Sachen passieren. So weit, so gut, das Grundgerüst steht also schon.

    Die Bewegungen werden serverseitig ausgewertet und immer die aktuelle Position des bewegenden Spielers an alle Clients übermittelt (um client-seitige Cheatversuche zu verhindern :)).

    Ich hab mir anfangs auch überlegt, dass sich die Spieler auch gegenseitig abschießen können sollen. Momentan hab ichs so gelöst, dass der Client an den Server den Befehl "schießen" schickt und der dann vom Server aus an alle Clients weitergeleitet wird. Auf jedem Client startet ein Thread, der den Schuss bewegt. Da ist auch schon das Problem: bei einem schnellen PC "wandern" die Schüsse schnell, bei einem langsamen eben langsamer.

    Eine andere Möglichkeit wäre, dass ich für die Bewegung auch jeweils einen Positionierungsbefehl des Schusses an die Clients schick, was aber hohe Netzlast verursachen kann, wenn alle gleichzeig und permanent schießen.

    Lange Rede, kurzer Sinn: Wie löse ich das Problemchen? Wie wird sowas denn "normalerweise" gemacht?



  • Max0r schrieb:

    . Da ist auch schon das Problem: bei einem schnellen PC "wandern" die Schüsse schnell, bei einem langsamen eben langsamer.

    Ich gehe mal davon aus, dass der Schuss eine definierte Geschwindigkeit hat.
    Um das Problem mit schnellen und langsam PC's auszugleichen hast du 2 möglichkeiten:
    - fps-begrenzen. Somit wird die bewegung auf allen PC's gleich oft ausgelöst
    - Geschwindigkeit mit Frame-Zeit multiplizieren. Also die zurückgelegte Strecke ist abhängig von der Zeit seit der letzten Bewegung.
    So sollten die Schüsse auf allen Rechnern ca gleich schnell sein



  • Danke! Die zweite Variante hört sich ganz gut an. Bei der ersten seh ich die (theoretische) Gefahr, dass dann ein Rechner so langsam ist, dass er noch weniger FPS hat als die erlaubten. Dadurch wärs da wieder langsamer.



  • Servus,

    Max0r schrieb:

    Die Bewegungen werden serverseitig ausgewertet und immer die aktuelle Position des bewegenden Spielers an alle Clients übermittelt (um client-seitige Cheatversuche zu verhindern :)).

    Werden die Bewegungen & Co. auf dem Server ausgewertet, dann sollte der Server auch die Entscheidung über einen Schuss treffen.

    Als erstes solltest du dir Gedanken über die max. Ping-Dauer eines Spielers machen. Bei vielen Shooter ist dies < 160ms = t0
    So, jetzt kannst du jedem Client erlauben, die Szene im voraus bis max. t0 zu berechnen. Treten unerwartende Ereignise auf (z.B. User-Interaktion), müssen ein paar Daten neu berechnet werden. Aber halt nicht die ganze Szene --> Aufwand für Korrekturen/Neuberechnungen im Zeitintervall ist in der Regel sehr gering.

    Der Server bestimmt nun alles. Positionen der Spieler, Spieler getroffen oder nicht.
    Das würde bedeuten, dass der Spieler max 160ms auf eine Bestätigung warten muss. z.B. ob der Schuss erfolgreich war
    160ms werden beim spielen fast nicht wahrgenommen 🙂



  • Ja klar, der Client schickt den Befehl zum Schießen an den Server. Anschließend schickt der Server an alle Clients den Befehl "Spieler X hat geschossen". Jetz wird auf jedem Client der Schuss ausgeführt, ohne dass der Server dafür Steuerpakete senden muss. Dabei berechne ich auf jedem Client eben die Anzahl an Schritten, die der Schuss weiter wandern darf (siehe Beitrag von BigNeal).

    Dass ich net jedes mal die ganze Szene mitsenden muss, is mir klar 🙂 . Mal schauen, obs was wird. Danke euch schonmal.. 👍



  • BigNeal schrieb:

    - fps-begrenzen. Somit wird die bewegung auf allen PC's gleich oft ausgelöst

    Normalerweise ist der Renderloop vom Updateloop entkoppelt. Das Intervall des Updateloops ist konstant.



  • Siassei schrieb:

    160ms werden beim spielen fast nicht wahrgenommen 🙂

    ähem, dazu mal ne frage

    wenn wir sagen wir mal jetzt counterstrike spielen, da wird im scoreboard ja der ping angezeigt

    und wenn der 160 beträgt (wird ja in ms angegeben) dann merkt man das schon gewaltig und bei noch schnelleren spielen (quake oder unreal tournament z.b.) ists noch gravierender, selbst bei warcraft 3 stört das schon...



  • 160ms lag sind brutalst.
    160ms verzögerung bis eine explosion erscheint sind dagegen gut verkraftbar.

    das dumme ist, dass, wenn man 160ms verzögerung bis eine explosion erscheint hat, man auch 160ms lag hat.

    🙂



  • Die meisten Shooter machen das so:
    Die clients und Server werden syncronisiert.
    (syncroner timer so gut es eben geht).

    Jeder client schickt nicht nur den Befehl, dass er geschossen hat, sondern auch die genaue Zeit mit. Dieser Befehl erreicht den Server, z.B 160 ms später.
    Nun rechnet der Server zurück, wo der Schuß vor 160 millisekunden abgefeuert wurde! Und bestimmt, ob es Treffer gibt oder nicht.
    Dieses schickt er an alle clients. Diese berechnen ihrerseits die Verzögerung dazu und berechnen wo sich das aktuelle Projektiel befindet.

    Das führt dazu, das das Projektiel nicht direkt aus der Waffe zu kommen scheint (bei den anderen Clients), sondern davor entsteht (um die Verzögerung auszugleichen). Das kann man schön mit Mündungsfeuer kaschieren.
    Gefühlt ist die Verzögerung so aber deutlich kürzer weil die Bahn der Kugel so verläuft, wie sie auch der Client der den Abschuß ausgelößt hat berechnen würde.

    Das Problem ist hierbei hauptsächlich, die Timer syncron zu bekommen.



  • Andreas XXL schrieb:

    Die meisten Shooter machen das so:
    Die clients und Server werden syncronisiert.
    (syncroner timer so gut es eben geht).

    (...)

    Das Problem ist hierbei hauptsächlich, die Timer syncron zu bekommen.

    Naja. Ich würde mal behaupten dass bei Online-Games ohne synchrone Timer sowieso ziemlich wenig geht.
    Ist also ein Aufwand um den man schwer herumkommt, bzw. der sich IMO fix lohnt - auch abgesehen von den Schüssen.



  • Hier ist beschrieben wies bei CounterStrike Source gemacht wird: http://developer.valvesoftware.com/wiki/Source_Multiplayer_Networking

    Da solltest du Ideen herbekommen.


Anmelden zum Antworten