Frage zu Netzwerkprotokoll



  • Aha ok.

    Ja mein ich doch, dass die Berechnungen vom Server gemacht werden. Mit der zweiten Möglichkeit meinte ich wohl dasselbe wie du, @krabbels.

    Also der Client sendet: "Möchte attackieren"
    Der Server erhält dies, und beginnt mit dem serverseitigen attackieren. Dabei werden die Spielerdaten (Angriffspunkte, Lebenspunkte, ...) aus der Datenbank geholt um den Kampf durchführen zu können.
    Weiters sendet der Server gleichzeitig solange an den Clienten "Attackiere", bis dieser antwortet, damit auch am Clienten attackiert wird. Dies könnte doch mit UDP geschehen? (Schneller, besser??) Oder reicht nur TCP?

    So in etwa hab ich das gemeint.

    Und... wegen der Lebenspunkte zum Beispiel. Wäre es besser, wenn der Server ständig die verbleibenden Lebenspunkte an den Clienten sendet, oder nur den Wert, der abgezogen wird? Ist doch eigentlich egal, oder?

    MfG



  • ceplusplus schrieb:

    Weiters sendet der Server gleichzeitig solange an den Clienten "Attackiere", bis dieser antwortet, damit auch am Clienten attackiert wird.

    Wenn der Client an den Server "Möchte attackieren" sendet, kann er doch das Ereignis senden und sofort mit dem Attackieren beginnen. Warum willst du da noch mal eine Rückbestätigung vom Server senden lassen? Immerhin wird das vermutlich zu einem enormen Mehraufwand beim Server führen, was, gerade bei einem MMORPG nicht wirklich wünschenswert ist.

    - Client sendet an Server, "Möchte attackieren"
    - Client spielt "Möchte attackieren"-Musik/Animation was auch immer ab
    - Server erhält Nachricht und berechnet den Kampf
    - Nebenbei schickt der Server immer mal wieder die Daten, die beim Client zum    
      synchronisieren des Spiels mit dem Server notwendig sind, z.B. die   
      verbleibenden Lebenspunkte(optimal wäre es natürlich, wenn diese nur bei   
      einer tatsächlich stattgefundenen Veränderung geschickt werden(Spieler   
      nimmt Heiltrank))
    


  • Mhm, aber was, wenn eine enorme Verbindungsverzögerung existiert, und der Client schon auf den Gegner einhaut, während der Server erst 20 Sekunden später damit beginnt? Oder MUSS man da mit timestamps arbeiten?

    Und ist es nun egal, ob der Server die verbleibenden Lebenspunkte oder nur den Wert der von den Lebenspunkten abgezogen wird sendet? Letzteres würde ja wieder traffic einsparen, kommt mir aber irgendwie unsicherer vor...

    MfG



  • ceplusplus schrieb:

    Und ist es nun egal, ob der Server die verbleibenden Lebenspunkte oder nur den Wert der von den Lebenspunkten abgezogen wird sendet? Letzteres würde ja wieder traffic einsparen, kommt mir aber irgendwie unsicherer vor...

    Warum sollte es Traffic einsparen, wenn man "12 Lebenspunkte weniger" anstatt "noch 51 Lebenspunkte übrig" sendet?



  • ceplusplus schrieb:

    Mhm, aber was, wenn eine enorme Verbindungsverzögerung existiert, und der Client schon auf den Gegner einhaut, während der Server erst 20 Sekunden später damit beginnt?

    Lags wirst du auch so nicht vermeiden können, im Gegenteil. Deine Variante halte ich sogar für noch gefährlicher, da auf dem Server bereits gekämpft wird während der Spieler gar nichts davon mitbekommt.

    ceplusplus schrieb:

    Oder MUSS man da mit timestamps arbeiten?

    Nein, ist doch sinnlos. Wie gesagt, Lags kannst du nicht vermeiden.

    mad_martin schrieb:

    ceplusplus schrieb:

    Und ist es nun egal, ob der Server die verbleibenden Lebenspunkte oder nur den Wert der von den Lebenspunkten abgezogen wird sendet? Letzteres würde ja wieder traffic einsparen, kommt mir aber irgendwie unsicherer vor...

    Warum sollte es Traffic einsparen, wenn man "12 Lebenspunkte weniger" anstatt "noch 51 Lebenspunkte übrig" sendet?

    Es macht keinen Unterschied. Ich würde mich für erstere Variante entscheiden, da sie weniger abstrakt und mit dem Wert auf dem Server tatsächlich synchron ist.



  • ceplusplus schrieb:

    Mhm, aber was, wenn eine enorme Verbindungsverzögerung existiert, und der Client schon auf den Gegner einhaut, während der Server erst 20 Sekunden später damit beginnt?

    IMHO wird die Kampflogik etc. vom Server verwaltet. Soll heissen falls so eine extrem hohe Verbindungsverzögerung existiert wird sich das nur auf der Clientseite bemerkbar machen, auf dem Server sollte alles normal ablaufen. D.h. wiederum, nicht du haust auf einen nichtreagierenden Computergegner, sondern der Computergegner haut auf deinen nicht reagierenden Avatar ein. Falls zwei menschliche Spieler gegeneinander spielen, wird wohl der gewinnen der die wenigsten Lags hat. 😉

    tt



  • Hmm, bezüglich deinem Schema, @krabbels:

    Wäre es nicht besser am Clienten erst mit dem Attackieren zu beginnen, wenn die erste Antwort vom Server kommt?

    Also in etwa so:

    - Client sendet an Server, "Möchte attackieren"
    - Server erhält Nachricht und berechnet den Kampf, beginnt gleichzeitig mit dem ständigen senden von zB. "A31", "A95", .. 
    was für ATTACK + abgezogenes Leben steht.
    

    Dabei weiß dann der Client ganz sicher, dass die Attacke stattfindet.
    Mir fällt keine einfachere, gleichsichere Möglichkeit ein.

    Und es macht doch einen Unterschied, ob man 11592 oder 62 sendet?!

    MfG



  • Am "einfachsten und sichersten" machst du das mit TCP - solange die Verbindung steht brauchst du dir da keine Sorgen machen dass irgendwas nicht angekommen ist.

    Am "besten" macht man sowas aber mit UDP, da die Fehlerkorrektur-Mechanismen in TCP leider dafür sorgen dass deutliche Lags auftreten, wenn mal ein Paket nicht oder verändert angekommen ist.



  • Wobei ja Fehlerkorrektur nicht unbedingt nötig wäre. Man könnte ja Bestätigungen einbauen, und falls was nicht ankommt, einfach nochmal senden oder so.



  • ceplusplus schrieb:

    Wäre es nicht besser am Clienten erst mit dem Attackieren zu beginnen, wenn die erste Antwort vom Server kommt?

    Warum? Was erhoffst du dir davon?

    krabbels schrieb:

    Lags wirst du auch so nicht vermeiden können, im Gegenteil. Deine Variante halte ich sogar für noch gefährlicher, da auf dem Server bereits gekämpft wird während der Spieler gar nichts davon mitbekommt.

    Bei Verbindungsstörungen würde der Client mit meiner Variante bereits kämpfen. Bei deiner Variante würde u.U. lediglich auf dem Server gekämpft werden. Der Spieler selber würde also gar nicht merken, dass schon lange gekämpf wird. Außerdem ist mit deiner Variante, durch die Rückbestätigungen, ein höheres Maß an Leistung bei Server und Bandbreite notwenig.



  • ceplusplus schrieb:

    Und es macht doch einen Unterschied, ob man 11592 oder 62 sendet?!

    MfG

    Ich wage einfach mal die Behauptung, dass das nicht interessiert. Ob man jetzt ein Byte oder 2 oder 3 schickt, der Overhead durch UDP und IP ist auf jeden Fall da.



  • @krabbels:
    Stimmt sorry, da hatte ich nen Denkfehler.

    @mad_martin:
    Und bei 100.000 Spielern, die gleichzeitig auf einem Server online sind? (Lässt WinSock überhaupt so viele connects zu?)



  • ceplusplus schrieb:

    Und es macht doch einen Unterschied, ob man 11592 oder 62 sendet?!

    Es macht sicher einen Unterschied, wieviel Daten du am Ende sendest. Nur ist es unrealistisch, dass man zum Speichern der Lebenspunkte mehr als 1 oder 2 Byte braucht und dass Veränderungen in einem wesentlich kleineren Rahmen liegen.



  • Deinen letzten Satz verstehe ich nicht.

    Naja jedenfalls wären es wohl immer 2 Byte, egal ob man nun das abzuziehende Leben oder den Lebenstand sendet. Das meintest du wohl?



  • @mad_martin:
    Und bei 100.000 Spielern, die gleichzeitig auf einem Server online sind? (Lässt WinSock überhaupt so viele connects zu?)

    Man müsste wahrscheinlich auf ein anderes System umsteigen, wenn man mehr als 65000 Clienten bedienen müsste!
    Ich hab auch schon nachgeschaut und überlegt wie man das Problem lösen könnte! Letztendlich bin ich zu der Erkenntnis gekommen, dass es garnicht zu lösen ist!
    Wer Lösungen hat, bitte sofort nennen! 🙂

    -Mehrere Server laufen lassen!



  • ceplusplus schrieb:

    Naja jedenfalls wären es wohl immer 2 Byte, egal ob man nun das abzuziehende Leben oder den Lebenstand sendet. Das meintest du wohl?

    Du kannst auch anfangen bei einer maximal möglichen Energie von 200 Punkten(mind. 1 Byte) bei einem Ereignis, was dem Spieler 25 Punkte abzieht nur 5 Bit zu schicken. Mir wäre das zu frickelig. Und ob du da nun wirklich ein Leistungszuwachs rausholst, ist fragwürdig.



  • Jo, schon klar.

    Aber ich hätte halt gerne optimalste Optimalität 🤡
    Also so trafficsparend und sicher wie nur möglich.



  • ich finde schon, dass es sinn macht für den client erst den server zu fragen, ob er einen mob angreifen darf oder nicht.

    was wenn z.b. der client versucht einen befreundeten spieler/NPC/mob anzugreifen? der client würde dann einfach drauf loshämmern und die animation abspielen und dann (vielleicht) irgendwann merken dass er es nicht darf, oder auch nicht. ziemlich unsinnig.

    bsp:

    client -> server: [attack-request] auf mob id 338
    server -> client: [attack-reply] accept
    client -> server: [attack-action] skill id 228 (irgendein skill halt)
    (animation abspielen für skill id 228)
    ...
    
    client -> server: [attack-request] auf mob id 339
    server -> client: [attack-reply] denied (ist ein befreundeter spieler)
    

    um vollständige sicherheit zu garantieren müsste der server natürlich so schlau sein, und ein [attack-action] packet auch nur akzeptieren, wenn vorher ein [attack-request] abgeschickt und mit accept beantwortet wurde.



  • Jo stimmt.
    Geht aber noch einfacher, attack-action braucht man doch nicht mehr zu senden.

    client -> server: [attack-request] auf mob id 338 
    server -> client: [attack-reply] accepted
    

    Accepted am server bedeutet: Berechnung beginnen
    Accepted am clienten bedeutet: Animation beginnen

    client -> server: [attack-request] auf player id 594
    server -> client: [attack-reply] denied
    

    ...

    MfG



  • ceplusplus schrieb:

    Jo stimmt.
    Geht aber noch einfacher, attack-action braucht man doch nicht mehr zu senden.

    client -> server: [attack-request] auf mob id 338 
    server -> client: [attack-reply] accepted
    

    Accepted am server bedeutet: Berechnung beginnen
    Accepted am clienten bedeutet: Animation beginnen

    client -> server: [attack-request] auf player id 594
    server -> client: [attack-reply] denied
    

    ...

    MfG

    Hatte ich mir auch überlegt.
    Das hätte aber den Nachteil, dass du nach jedem Angriff neu serverseitig prüfst, ob der Mob angegriffen werden kann.
    Ich dachte es mir also so, dass die [attack-action]-Packete nicht mit accept beantwortet werden müssen um Overhead zu vermeiden, sondern nur einmalig mittels des [attack-request]-Packets geprüft wird, ob man den Mob angreifen darf.

    Bsp:

    client -> server: [attack-request] auf mob id 338
    server -> client: [attack-reply] accept
    client -> server: [attack-action] skill id 228 (irgendein skill halt)
    (animation abspielen für skill id 228) 
    client -> server: [attack-action] skill id 228 (irgendein skill halt)
    (animation abspielen für skill id 228) 
    client -> server: [attack-action] skill id 228 (irgendein skill halt)
    (animation abspielen für skill id 228) 
    ...
    

    Wahrscheinlich ist deine Variante aber doch sicherer/besserer.
    Soll auch vorkommen, dass Mobs die Seiten wechseln, außer Reichweite geraten oder Ähnliches - also lieber jedesmal neu auf Bestätigung warten.


Anmelden zum Antworten