[Java] Multiplayer Networking

Dieses Thema im Forum "Programmierung & Entwicklung" wurde erstellt von Blackb!rd, 15. März 2013 .

  1. 15. März 2013
    Multiplayer Networking

    Hallo Zusammen,

    ich bin gerade dabei etwas Java zu lernen und habe mich hierzu für ein kleines Spielchen entschieden. ( Ich bau den ganzen Tag Anwendungen in PHP, da brauch man Abwechslung )

    Die Basic's kommen auch Stück für Stück - Iwo sind ja alle Sprachen Ähnlich.

    Nun stehe ich aber vor dem Problem, das ich eine Verbindung zwischen den Client's und einem Server herstellen möchte. Hierfür verwendet ich derzeit Socket's. Das klappt auch soweit sehr gut, allerdings kommt mir das irgendwie etwas uneffizient vor.

    Folgende Schritte führe ich derzeit aus:

    1) Socket öffnen, warte auf neuen Client
    2) Wenn ein Client connected, erstelle ich einen neuen Thread der sich um die Verbindung kümmert und der Listener ist wieder frei für neue Client's
    3) Der Thread der sich um den Client kümmert kann nun String's mit dem Client austauschen.

    Um nun Aktionen zu übergeben wäre das einfachste natürlich einfach irgendwelche Command-Strings zu schicken ( login,move_up,move_down,jump ... ) Aber mach das wirklich Sinn?

    Vielleicht hat irgendjemand ein paar Anregeungen für mich wie man sowas am besten realisiert.


    Bitte Rücksicht nehmen, ich bin Java Anfänger


    Grüße

    Blackb!rd
     
  2. 15. März 2013
    Zuletzt bearbeitet: 15. März 2013
    AW: Multiplayer Networking

    Hey!

    Sieht doch schon garnicht schlecht aus, von der Theorie.

    Am sinnvollsten dürfte es sein 2 Typen von Paketen zu versenden: Das Hauptpaket, das einen abstrakten Event darstellt und mit einer eindeutigen ID identifizierbar ist, sodass der Server ganz genau weiß, worum es sich hier handelt (Sprich: Idle = 0, Bewegung = 1, ..) und das Datenpaket, welches die relevanten Daten des Events enthält. Du kannst also hier für Event-Typ 1 (Bewegung) die Koordinaten/Vektoren übermitteln und was sonst noch alles wichtig für die Bewegung innerhalb deines Spiels ist.

    Um Overhead zu vermeiden würde ich die Daten serialisiert als Byte-Array versenden. Natürlich bieten sich auch Klartext-Modelle ala XML oder JSON an, hierbei hättest du allerdings einen minimalen Overhead. Eventuell wäre es nicht verkehrt beides (Byte-Array und JSON/XML) zu implementieren, damit ließe es sich auf jedenfall einfacher debuggen.

    Die Events würde ich zuallererst einmal in einer abstrakten Klasse verarbeiten: EventHandler::handle(Event) und dann bei validem Event weiterleiten (EventHandler: nXYZ(Data)).
    Jetzt müsstest Du lediglich die Empfangsobjekte bei einem EventListener registrieren lassen, welcher die Events dann weiterschickt.

    So würde ich das wohl handhaben.

    Das war recht generell und informativ gedacht, mit Java hab ich nicht viel am Hut, daher kann es durchaus sein, dass man es in Java eventuell sogar noch anders handhaben könnte (Ich verweise da mal an alex²).
     
    1 Person gefällt das.
  3. 15. März 2013
    AW: Multiplayer Networking

    Multiplayer ist recht komplex, aber für den Anfang sollte dein Konzept schon passen.

    Idr. handhabt man Bewegungen aber anders um Latenzen zu vermeiden. Und zwar erstellt man einen Puffer für Bewegungen der letzten ~500ms (je nach dem wie hoch der Ping zum Server ist / ein wenig mehr). Damit kannst du ruckelfrei durch die Gegend laufen und nur wenn irgendwann etwas nicht passt (z.b. du stehst in einer Wand) dann greift der Server ein und positioniert dich entsprechend um.

    Sprich: Man synchronisiert die Spielstände einfach in regelmäßigen Abständen anstatt alles vom Server absegnen zu lassen.

    Soweit ich weiß arbeitet man da auch mit "Vorhersagen".
    Da gibt es aber sicherlich auch Lektüre dazu, schau dich mal ein wenig um.
     
    1 Person gefällt das.
  4. 15. März 2013
    AW: Multiplayer Networking

    Danke schon mal für die ersten Feedbacks.

    Gerade beim umsetzen fällt mir aber noch etwas auf: Sollte man Lesen/Schreiben immer in einem Thread lösen oder macht es Sinn das zu verteilen?

    Folgendes Ausgangslage:
    1) Socket wird geöffnet, wenn die Verbindung steht, fragt der Client an ob er Connecten darf. ( Server voll? etc.. )
    2) Wenn ich vorher bereits einen Thread erzeugt habe, der alle Input's abfängt, kann ich ja an dieser Stelle gar nicht mehr wissen OB ich nun connecten Darf oder nicht.

    terraNova hat ja etwas von Event's angesprechen, die helfen mir ab in dem Augenblick doch auch nicht oder? In meiner "Login"-Methode würde ich ( Von meiner Logik her ) prüfen ob man drauf darf, anschließend Daten abgleichen, ggf Levels übertragen, etc...und dann das eigentliche Spiel joinen. Ab dann macht es Sinn, dass Eingaben und Ausgaben getrennt voneinander bearbeitet werden. ( MOVE_TO_X_Y oder PLAYER_B_MOVED_TO_X_Y benötigt nicht unbedingt eine Antwort darauf, dadurch kann man Leistung sparen.. )


    Gruß Blackb!rd
     
  5. 15. März 2013
    AW: Multiplayer Networking

    Die Events sollten auch nicht unbedingt direkt verteilt werden. Leg einen Container an und jeder Thread, bzw. EventHandler, holt sich einen Event bei Bedarf ab.

    Der Loginvorgang kann doch auch in Events stattfinden.

    Benutzer X verbindet sich:
    Event - Anlegen eines Spielers, Login steht aus (Attribut, evtl. eigener Container für ungesetzte Spieler). Optional: Anlegen eines neuen Events, welcher nach Logindaten fordert (Ist nicht erforderlich, wäre nur ne Möglichkeit).​
    Benutzer X sendet Logindaten:
    Event - Login. Datenabgleich und ein Event anlegen ("Login fehlerhaft" und ggf. "Verbindung zum Spieler trennen" oder "Login erfolgreich" und "Spieler in die Welt setzen", wobei letzterer Event dann dazu da ist, den anderen Spielern bzw. Clients mitzuteilen, dass ein neuer Mitspieler dem Spiel beigetreten ist). ​

    Wie Du siehst ist das ganze recht aktiv und kann den Server, jenachdem wie gut er besucht wird, belasten. Allerdings hat der aktive Modus den Vorteil, dass alles wichtige über den Server abläuft und nicht andersrum beim Spieler und dieser dadurch weniger die Chance bekommt zu mogeln.

    Die Map usw. brauchst Du ja garnicht zu senden, wäre ja auch schwachsinnig, die sollte dem Clienten bereits bekannt sein. Wichtig sind die Zustände bzw. die Abweichungen und auch da ist es nicht unbedingt nötig alles auf einmal zu senden.

    Ein Beispiel anhand des Spieles Counter-Strike wäre (Auch wenn es nicht so läuft): Spieler X ist Terrorist und startet an die davor vorgesehene Basis. Spieler Y ist Counter-Terrorist und startet an seiner Basis. Spieler X legt die Bombe, Spieler Z tritt dem Spiel bei und kann noch den Terroristen beitreten. Wichtig ist hier, dass dieser Spieler mitbekommt, dass die Bombe bereits gelegt wurde und ggf. die Position des eigenen Mitspielers um diese auf der Minimap anzuzeigen. Von Spieler Y benötigt er bisher noch keine Positionsdaten, da dieser sich nicht in der Reichweite befindet.

    Die Logik solltest Du so gut wie es geht dem Server überlassen um Missbrauch zu vermeiden.
     
  6. 19. März 2013
    Zuletzt bearbeitet: 19. März 2013
    AW: Multiplayer Networking

    Was schwebt dir denn genau vor bei deinem Spielchen?

    Man sollte hier unterscheiden zwischen rundenbasierten Spielen oder ich sag jetzt mal "Echtzeitspielen" (def.: alle Spieler interagieren zur selben Zeit und die Spieler sollten stets informiert werden - einfaches Beispiel: das Spiel Pong).

    Dein Ansatz mit dem Verbindungsaufbau etc. pass soweit denke ich auch.

    Du hast auf deinem Server ja den Thread, der auf die Verbindungen wartet. Du kannst es so machen, dass dieser Thread weiß wie viele Spieler auf dem Server sind und wie viele drauf dürfen. Wenn eine Anfrage kommt und der Server voll ist, schickt du eine dementsprechende Antwort zurück. Das kannst du theoretisch im gleichen Thread machen. Auf der Clientseite musst du dann natürlich zwischen einem erfolgreichen Verbindungsaufbau und einer "Servervoll"-Nachricht unterscheiden.

    Hoffe du hast das gemeint.
     
  7. Video Script

    Videos zum Themenbereich

    * gefundene Videos auf YouTube, anhand der Überschrift.