Mutliplayer Performance -> Geht das so? (39dll)

  • GM 8
  • Mutliplayer Performance -> Geht das so? (39dll)

    Hallo liebe Community,

    ich bin gerade an meinem größten und kompliziertesten Projekt und muss euch folgendes Fragen bezüglich Multiplayerperformance. Dazu muss ich aber erst kurz erläutern, um was es sich im Spiel handelt, damit ihr eine Vorstellung habt, was ich meine!

    Das Spiel ist ein Topdownshooter der anderen Art. Maximal 5 Spieler spawnen am Spawnpoint und einer von diesen Spielern wird nach Zufall zum "Master" gemacht.

    Dieser Master kann dann über die gesamte Map wie bei einen Strategiespiel, verschiedenes Zeug spawnen, wie z.B. Wände die zerstört werden müssen, Fallgruben und und und. Außerdem muss er 3 Schlüssel platzieren, welche die Spieler finden müssen. Haben die Spieler die Schlüssel gefunden und sind ans Ziel gekommen, haben sie gewonnen. Wenn die Spieler aber durch den Master es nicht schaffen, gewinnt logischer Weise der Master.

    Das Spiel besteht aus einem C++ Server (weil das schneller sein soll) und eben aus den Clients mit GM.

    Nun zu meiner Frage:
    Der Master kann auch Zombies spawnen.. sollten schon mehrere sein vielleicht um die 50 rum!
    Die Netzwerkkommunikation bezüglich Zombiepositionen verläuft nun so:


    Der Spawn
    1. Master spawnt Zombie per Mausklick an die gewünschte Position
    2. Master Sendet an Server die X,Y Position des gespawnten Zombies sowie die Zombie_id
    3. Server sendet diese Position an alle restlichen Clients und die erstellen dann den Zombie an dieser Position mit der jeweiligen zombie_id

    Positionsberechnung

    Die Zombies sind so eingestellt, dass sie permanent per mp_potential_step zu NextX, NextY laufen (Wie ein Wegpunkt).

    1. Der Master kontrolliert das gesamte Verhalten der Zombies.. sie sind als Clientside
    2. Masterclient prüft, ob Zombie einen Spieler sieht
    3. Wenn Zombie einen Spieler sieht wird dem jeweiligen Zombie ein Wegpunkt zu den Spieler gesetzt (NextX = player.x NextY = player.y)
    4. Der Master sendet dann im Sekundentackt die Wegpunkt koordinate (NextX,NextY) sowie die x,y Zombieposition und die Zombie_id an den Server.
    5. Server empfängt diese Daten und sendet sie an alle Clients (auch dem Master zurück)
    6. Clients (inklusive der Master) setzen dem jeweiligen Zombie mit der empfangenen Zombie_id die Variablen NextX,NextY und x & y position des Zombies
    --------------------
    Der Master schickt praktisch die Info an den Server und der Server schickt sie an alle Clients und auch dem Client, welcher der Master ist. Damit sollten die Zombies ja bei jeden etwa gleichzeitig anfangen zu laufen!

    ICH HOFFE IHR HABT DAS VERSTANDEN, WENN NICHT, BITTE NACHFRAGEN WEIL ES WICHTIG IST!

    So:
    Das ganze läuft Lokal nun eimanfrei, aber denkt ihr, das läuft dann auch über das Internet so gut?
    Nehmen wir mal an es gibt 30 Zombies und alle 30 Zombies sehen eben gerade einen Spieler. Dann sendet der Client, welcher der Master ist immerhin 30 Pakete an den Server pro Sekunde! Und der Server dann diese 30 Pakete an 5 Clients!

    Das Problem wird wohl sein, dass die Zombies auch lagen werden, wenn der Master ne schlechte Verbindung hat, da er sie ja praktisch steuert.

    Komplett Serverseitige Kontrolle der Zombies wäre wohl das beste, aber gleichzeit auch sehr sehr schwer, da der Server ja in C++ geschrieben ist und man dann mit den Server herausfinden muss, ob der Zombie den Player überhaupt sieht und keine Kollision besteht..



    Ich bedanke mich dafür, dass ihr euch Zeit genommen habt das zu lesen und hoffe nun auf Ratschläge!

    Liebe Grüße!
  • Ein kleiner Hinweis: Wieso im Sekundentakt die Position übertragen. Sag den Clients doch, welchen Spieler der Zombie verfolgen soll, bzw sende die Koordinaten nur wenn sie sich ändern. Die Bewegung zu diesen Koordinaten kann dann jeder Client selbst übernehmen. Eventuell zwischndurch mal die x und y Koordinaten zum Ausgleichen senden. In meinem aktuellsten Spiel hab ich es ähnlich gelöst: Die KI bewegt sich anhand eines Grids, über welches Pfade berechnet werden. Die KI sucht sich nun serverseitig einen Punkt, zu dem sie gehen will, dieser Punkt wird an alle Clients übertragen, jeder Client berechnet selbst den Pfad und führt ihn aus. Gibt es irgendwelche vorkommnisse (KI muss Granate ausweichen, etc) sendet der Server den jeweiligen Befehl wieder an alle Clients. Das Bewegungs-/Blickrichtungsmuster sowie Angriffe sind in den Clients implementiert, der Server sagt nur wohin's geht bzw sorgt für den tatsächlichen Angriff (der auf Clientseite nur visuell erfolgt)

    © 2008 by Teamgrill Productions
  • Hallo und danke für die Antwort!
    Dass die Zombies auf einen generierten Wegpunkt laufen anstatt zum player, habe ich aus dem Grund gemacht, dass der Master später auch noch ausgewählt Zombies per Mausklick an eine bestimmte Position laufen lassen kann.

    Deshalb läuft der Zombie immer zu einem Wegpunkt, der im Falle, wenn er einen Spieler folgt, im Sekundentakt auf die Playerposition aktualisiert wird.
    Dies hat auch den Vorteil, das der Spieler sich verstecken kann.

    Aber der Gedankenanstoß ist nicht schlecht, vielleicht probiere ich es mal auf diese Art & Weise!



    EDIT:
    Mir ist gerade in den Sinn gekommen, dass die Bewegungsabläufe der Zombies / und auch ob der Zombie gerade einen Spieler sieht alles beim client selber berechnet wird und zum Ausgleich der Master in einem bestimmten, größeren intervall die x/y/NextX/NextY position an die restlichen Clients sendet.
    Denkt ihr das wäre möglich oder eher nicht so toll?

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von funky-destroy ()

  • Also größere Sachen wie das Entdecken eines Spielers würde ich beim Server belassen, bzw. beim Master. Den Bewegungsablauf kannst du in den Clients lassen, der Master muss nur allen clients sagen, dass Zombie1 Spieler4 gesehen hat. Mit dieser Information können die Clients schon genug anfangen, um daraus den Zombie zur Aktion zu bewegen. Es ist nur eine Art der Umsetzung und wenn man es gut macht, braucht man wirklich fast keine Daten übertragen. Aber falls dir das zu kompliziert ist, machs so wie du es jetzt hast, denn jeder fängt mal klein an. Bei meinem ersten Multiplayer habe ich auch jeden Step alle x und y Werte übertragen und es hat trotzdem einigermaßen funktioniert. Je mehr man im Multiplayer programmiert, desto mehr überlegt man sich Möglichkeiten, wie man die Datenübertragung verringern kann.

    © 2008 by Teamgrill Productions
  • Ich sehe das Spiel als Herausforderung an und möchte das so gut wie nur Möglich hinbekommen.
    Ich werde es auf deine Art probieren. Zombie4 sieht Spieler1.. und der rest macht der Client.
    und die x/y position des Zombies wird vom Master alle 3 Sekunden als ausgleich versendet.

    Das mit den x und y im Stept ist in Ordnung, solange man dafür UDP verwendet :)
  • funky-destroy schrieb:

    Das mit den x und y im Stept ist in Ordnung, solange man dafür UDP verwendet :)
    Ja, allerdings muss das auch nicht sein. Bei Spielerbewegungen kann man zum Beispiel nur Übertragen, dass der Spieler eine Taste drückt/loslässt. So kann man die Spielerobjekte auch leichter verwalten indem man z.B. Variablen für die gedrückten Knöpfe benutzt, die eben entweder durch richtiges Drücken gesetzt werden (das entspricht dann dem echten Spieler) oder durch das empfangen der Drück-Nachricht (entspricht einem anderen Mitspieler). Natrülcih braucht man dazu dann verschiedene Absicherungen, aber im Grunde minimiert man so den Datenverkehr und man kann sich auch UDP fast sparen.

    © 2008 by Teamgrill Productions
  • Ich hab das gestern mal probiert mit der Bewegung eines Spielers... es ist schwerer als ich dachte..

    Hab gemacht, wenn man z.B. nach Rechts drückt, wird die hspeed auf 4 gesetzt und dann player_id,x,y,hspeed gesendet (x,y als ausgleich)..

    Und wenn man Rechts loslässt wird hspeed auf 0 gesetzt und die gleichen Daten wieder versendet..
    Sobald der Spieler mit der Wand kollidiert, schickt er auch die Daten.

    Das Problem war, wenn man mehrere Tasten gleichzeitig drückt, dass dann falsche Daten versendet wurden.. (Bei den restlichen Clients lief er beispielsweise nach rechts obwohl er nach links gelaufen ist). Hab das mit keyboard_clear probiert zu verhindern, aber das wollte nicht so ganz klappen.

    Das mit der Wandkollision kann sicher auch Clientside sein, aber das habe ich bis jetzt mit "wenn (place_free(x+player_speed,y)) dann laufe" gelöst..
    Vielleicht kann man das auch im Stepevent machen sodass die restlichen Clients selber testen, ob der Player Kollidiert.. allerdings weiß ich nicht, mit welchen Befehl ich das anstellen sollte. Möchte ja, dass wenn links vom Spieler eine Wand ist, er trotzdem hoch und runter laufen kann und wenn die Blockierung weg ist er normal weiter nach links läuft, ohne das er nochmals die Taste drücken muss.


    Kannst du mir da eine Lösung geben?
  • Grundsätzlich ist es einfacher wenn du einfach nur sagst, dass der Spieler links gedrückt hast. Im Spielerobjekt des anderen Spieler fragst du dann, so wie du für deinen Spieler abfragst nur ab, ob die Taste gedrückt ist. Ab besten legst du dir im Create-Event Variablen an:

    GML-Quellcode

    1. left_pressed = false;
    2. right_pressed = false;
    3. up_pressed = false;
    4. down_pressed = false;


    Bei deinem eigenen Spieler, den du mit der Tastatur steuerst, setzt du diese Variablen im step Event:

    GML-Quellcode

    1. left_pressed = keyboard_check(vk_left)
    2. right_pressed = keyboar_ //... usw


    Bei den anderen Spielern setzt du diese Variablen, sobald der Spieler sendet, dass er die jeweilige Taste drückt. Also wenn die NAchricht fürs drücken daherkommt, wird die jeweilige Variable auf true gesetzt und wenn die NAchricht fürs loslassen kommt, auf false. Damit hast du den Vorteil, dass du nun bei allen Spielern mit den Variablen left_pressed usw arbeiten kannst, egal ob dein Spieler oder Mitspieler. du brauchst also im Step nur mehr abfragen.

    GML-Quellcode

    1. if (left_pressed)
    2. hspeed = -4


    Und kannst das Clientside bei allen Spielern so machen. Ich hoffe das ist verständlich ;)

    © 2008 by Teamgrill Productions