39dll Online Shooter Performance-Einbruch über Hamachi

  • GM 8

    39dll Online Shooter Performance-Einbruch über Hamachi

    Wie manche vielleicht schon wissen oder auch nicht, arbeite ich an einem Multiplayer und zwar mit der 39dll.

    Die TCP-Verbindung läuft so, dass der Server automatisch einen Client erstellt, damit der Host nicht unötig ein zweites mal das Game starten muss.

    Ich bin soweit, dass ich einen Topdownshooter im Deathmatch programmiert hab, der HP abzieht, kills, deaths zählt, sowie jeden einzelnen Client einer ID zuweist. Also Probleme scheint es in einer Selbstverbindung absolut nicht zu geben.

    Das ganze sieht aber dann schon extrem anders aus, wenn mein Kumpel mit seiner sehr schnellen Leitung einen Server hostet und ich mit unseren Unkonstanten Internet, das nur selten die Maximalität von 2,3k erreicht. Ja die Telekom müssen wir noch bis Januar ertragen. Jedenfalls ruckelt es bei mir sehr ungemein. Lag vielleicht auch am schlechten Internet, aber es gingen schon andere Spiele, die mit Game Maker waren. Als Beispiel SectorX oder das Battle Tanks Online² von MasterXY.

    Eine kleine Entscheidung von mir war, dass ich mich für 90 FPS entschied, weil das für eine flüssige Bewegung in der Selbstbewegung sorgte. Allerdings muss ich gestehn, dass ich von Multiplayer im Bezug auf Game Maker nicht viel Erfahrung aufweise, jedoch die 39dll ziemlich gut verstanden habe. Ich weiß auch wie Sachen umsetzte die ich machen will, allerdings weiß ich nicht ob es eben besser gehen würde. Die 90FPS schraube ich warscheinlich noch runter, gab bei 8-9 clients einen Einbruch, als ich mich selbst über hamachi verbindete(falls das was ändert?).

    Codes will ich aber jetzt nicht unbedingt zeigen, wäre zu viel und eine .gmk will ich auch nicht öffentlich hochladen. Wäre nett wenn Experten micht anschreiben würden, deren ich mich anvertrauen könnte. Für Tipps in diesem Forum bin ich aber trotzdem offen.

    Danke schon mal in Voraus, MFG Xable
    Mono C# / SFML.Net <3
    Dass Rendering und Spiellogik mit der gleichen fps laufen ist ein Fluch des GMs. Ich persönlich bevorzuge 60fps, würde dir bei einem Onlinespiel aber zu eher 30 raten.
    Auch wäre UDP die bessere Wahl. Das ist wesentlich schneller, aber es können natürlich Informationen verloren gehen. Deshalb musst du die Clients z.B. raten lassen, was die Bewegungen der anderen Spieler angeht und nachkorrigieren, sobald Fakten vorliegen.
    Manche Infos müssen natürlich zweifelsfrei ankommen (z.B. das Signal für Spielende). Ich weiß nicht, ob du TCP und UDP mischen kannst. Wenn nicht, musst du dir eine Quittierung selber bauen. Dann wiederholt der Server einfach die Nachricht, bis er eine Quittung vom Client bekommt.

    Zu guter Letzt bedeutet das natürlich, dass du den Clients mehr Vertrauen entgegenbringen musst, damit sie nicht immer erst auf ein OK des Servers warten müssen. Um dich gegen plumpes Cheaten zu schützen, könnte der Server ein paar Dinge (Schussfrequenz, zurückgelegte Distanz, etc.) auf ihre Plausibilität hin überprüfen.
    Ich muss ehrlich sagen, dass man langsam merkt was wirklich schwer dran ist, ein Multiplayer-Spiel zu machen. Allerdings soll das ganze nicht direkt Online spielbar sein, bzw. meine ich damit, dass man seine eigenen Server hosten muss. Hierbei handelt es sich aber nur um ein, sozusagen Lernprojekt, um mich noch fester der 39dll zu vertrauen.

    Mit der UDP-Verbindung muss ich mich noch mit außereinander setzten. Das hört sich jetzt nach Monatelanger Arbeit an. Na ja, ich werde morgen ja noch nicht Rentner, also laufen mir meine Projekte nicht davon. Jetzt heißt es erstmal wieder lesen, lernen, probieren, verbessern, überlegen, verbessern bis der Kopf abfällt.

    Zu Blöd, dass der Game Maker nicht mehr Leistung dafür bietet. Also ich werde in meinem zukünftigen Projekt maximal 10 Spieler einbringen. Wenn ich 30 FPS wähle, ruckelt es bei der Selbstverbindung. Vielleicht gibt es ja sonst noch Tipps hier im Forum oder im Internet.

    Was würde deiner Meinung nach in einer UDP-Verbindung gesendet werden? Dinge die man durchgehend sendet oder, wie Positionen? Und wichtige Aspekte wie die Client ID oder der Name des Clients in der TCP-Verbindung schicken.

    Wie siehts aus mit C++ Server? Den Server vom Game aus starten und automatisch(Nur als Host) verbinden?

    Es gibt es vielleicht noch performantere Tipps, dann gibt bescheid. Auch noch vielen Dank MewX. Ich weiß dieses Thema ist eine Heiße Angelegenheit.
    Mono C# / SFML.Net <3
    Um direkt mit einem Irrtum aufzuräumen: Der GM ist eher nicht der Flaschenhals. Klar, nachdem so ein Paket angekommen ist, muss es erstmal verarbeitet werden. Bei "normalen" Anwendungen würde man dies in einen eigenen Thread auslagern, der kann dann fast sofort reagieren. Beim GM musst du da schonmal mit einer Verzögerung von 1/fps Sekunden rechnen. Quittierst du deine Pakete selber, tritt diese Verzögerung direkt auf beiden Seiten auf. Das Quittieren also auf Netzwerkebene passieren zu lassen ist eine gute Idee - vorausgesetzt, man kann nicht darauf verzichten.

    Der wahre Bottleneck liegt aber meist im Netzwerk selbst. Je nach Leitung und Serverstandort ist heutzutage wohl alles zw. 15 und 400ms drin. Bei 30 fps dauert ein Frame ~30ms. Wlan fügt angeblich mal eben rund 200ms hinzu (hab grad keins, aber so unrealistisch klingt das nicht). Dabei ist es egal, ob Maschinencode oder der GM die Pakete verschickt.

    Aber Kopf hoch: UDP braucht keine Monate Einarbeitungszeit. Es ist, einfach ausgedrückt, TCP ohne Quittung. Das Warten auf eine Quittung dauert ungefähr eine Roundtriptime - also meist Ping * 2. Wenn die DLL wirklich erst nach einer Quittung weitermacht (diese Info wäre sehr hilfreich, damit man dir bessere Tipps geben kann), läuft dein Spiel bei 2 Paketen pro Step ganz schnell unter 30 fps. Sparst du dir das Warten, kannst du die fps auch wieder höher schrauben, denn damit verringerst du die durch das Stepsystem bedingte Reaktionszeit.


    Zu deiner Frage: Unabhängig davon, was du verwendest, willst du die Informationen auf das nötigste beschränken. Dabei solltest du aber im Hinterkopf behalten, dass diese umfassend genug sind, um zukünftiges Verhalten vorauszusehen. Überträgst du z.B. x, y, image und sprite, lässt sich nur schwer rekonstruieren, in was für einer Bewegung sich der Spieler gerade befindet. Was, wenn image verlorengeht? Besser also, du sendest x, y, direction, speed, Zustand (stehend/laufend). Der Client setzt die Grafiken dann selbst und bis zum nächsten Update sind speed und direction wortwörtlich Selbstläufer. WoW z.B. korrigiert Spielerpositionen beim Laufen nur jede Sekunde oder so, und korrigiert oft erst beim Stehenbleiben.

    Auf die Gefahr hin, dass ich damit noch ein größeres Fass aufmache: Pakete kommen nicht immer in der gleichen Reihenfolge an. Vielleicht biete die DLL da schon Mechanismen, aber zumindest bei UDP könnte das bedeuten, dass eine alte Information nach einet neuen ankommt. Ups. Dann bräuchten deine Nachrichten noch fortlaufende IDs... besser aber, dein Spiel verkraftet kurzzeitige Fehlinfos.
    Also in der Selbstverbindung läuft es noch konstant bis zu 7-8 Spieler auf 90 FPS. Bei Internetverbindung ändert sich auch nichts, außer das der Ping so hoch schreitet, dass das Spiel unspielbar ist.

    Da ich sowieso schon C++ Kenntnisse habe, sehe ich es als vorteilhaft, einen Server darunter laufen zu lassen. Das würde mir schon mal etwas mehr hergeben. Da mein daraufolgendes Größeres Projekt, ein Endlos-Projekt wird, kann ich darauf wenigstens etwas Performance einsparen.

    Die UDP Verbindung scheint doch schon ihre Vorteile zu haben, doch mich schrecken ein wenig ihre Nachteile und Risiken ab. Mich würde mal Meinung von Ausstehende interessieren, die diese beführworten können, bzw. bereits in ihren Spielen verwendet haben.
    Allgemein also schon viel Erfahrung damit gemacht haben.

    Die Strategie mit dem Direction und Speed, scheint auf jeden Fall interessant zu sein. Auch das prüfen ob er läuft.
    Wenn es aber darum geht bestimmte Instanzen zu erstellen und dass mitzuteilen, dann sollte das schon in einer TCP Verbindung geschickt werden, oder?

    Desto mehr man versteh, desto komplizierte wird das darauf folgende :o
    Mono C# / SFML.Net <3