# Netzwerkspiel



## flashray (13. März 2007)

Hallo,

ich brauche eine Strategie um ein Netzwerkspiel zu programmieren.

Unzwar ist mir unklar, wie die Synchronisation von Server und den Clienten erfolgt. Also eine asynchrone Kommunikation in dem der Client eine Nachricht schickt, daraufhin der Server antwort und ähnliches ist kein Problem.

Aber?

Folgendes simples mini Beispiel Szenario:
Ein Server und ein Client haben beide das gleiche JFrame vor sich. Darin befinden sich zwei Komponenten beispielsweise JLabels mit dem Benutzernamen, stellvertretend für je einen der Mitspieler. Jeder soll einen dieser, das eigene per Maus beliebig verschieben können.

Wie geht man hier vor? Sollte es nur ein JFrame und zwei JLabels auf dem Server geben. Und bei jeder Änderung wird diese komplett auf den Clienten geschickt und angezeigt? Oder gibt es von der selben Applikation mehrere Instanzen, und nur die Positionen der Labels werden jeweils ausgetauscht?

Kann mir da jemand eine grobe Strategie geben wie ich das hier bei dem einfachen Beispiel machen sollte, und wie es bei komplexen Spielen besser wäre?


Vg Erdal


----------



## tobias_petry (13. März 2007)

generell verschickt man bei netzwerkprogrammierung so wenig daten wie möglich, damit es auch genauso gut für online-zwecke nutzen könnte 
Bei deinem Beispiel ist schwer zu erkennen was passiert, wird die neue Position des JLabels schon dargestellt wenn man es beim verschieben noch nicht losgelassen hat oder erst beim Loslassen?
Generell würde ich aber sagen, dass Positionsdaten übergeben werden und jedes neue Datenpaket sollte eine Nummer bekommen, damit du beim Client alte Datenpakete rausfiltern kannst, die schon überholt sind.


----------



## flashray (13. März 2007)

Hallo,

wäre es dann besser die Positionsinformationen per Thread in gewissen Zeitabständen zu schicken, oder immer nur dann wenn der User per Mouse oder Tastatur die eigene "Spielfigur" bewegt?


Vg Erdal


----------



## MeinerEiner_80 (13. März 2007)

Moin!
Auch das hängt meiner Meinung nach davon ab, was genau du tun willst.
Wenn die Bewegungen sofort sichtbar sein bzw. die Änderungen sofort angezeigt werden sollen, müsstest du auch bei jeder Änderung durch den Nutzer die Informationen senden.
Wenn die Änderungen nicht sofort angezeigt werden müssen, würde ich wahrscheinlich eine intervall artige Aktualisierung bevorzugen..

*grüssle*
MeinerEiner


----------



## flashray (13. März 2007)

Hallo,

in ca. 2 Monaten soll es ein 3D Multiplayer Bomberman werden, so jedenfalls die Aufgabenstellung.

Aus euren Antworten interpretiere ich dann, das bei jeder Interaktion der Mitspieler die Teilnehmer synchronisiert werden sollten. Bei einem Brettspiel, wie Schach würde es vielleicht auf die halbe Sekunde nicht ankommen, hier jedoch schon gedenke ich.

Eine weitere Frage in diesem Zusammenhang:
Unzwar soll ein Teilnehmer ein Netzwerkspiel beginnen, und andere können mit daran teilnehmen. D.h. der initierende startet/ist den/der Server, die anderen sind die Clienten.

Wäre es von der Software-Architektur her besser, wenn der Initierende, der zuerst ein Netzwerkspiel startet auch ein interner/der erste und zunächst einzige Client neben dem Server auf dem gleichen System ist, oder nicht?

Ist mir eben so eingefallen, weiss aber nicht ob das Sinn macht!

Vg Erdal


----------



## flashray (13. März 2007)

Hallo,

ich glaube ich habe gefunden, welche Client Server Architektur man hier als Basis nehmen könnte: Einen Chatserver und -Clienten.

Bei einem Chat können, alle Clienten zu jeder Zeit Eingaben machen, die dann sofort bei allen sichtbar sind.

Werde mal in der Richtung recherchieren, wie ein einfacher Java-Chat aufgebaut ist.


Vg Erdal


----------



## MeinerEiner_80 (13. März 2007)

Moin again!
Bin mir nicht sicher, ob ich dich da richtig verstanden habe, aber ich versuchs mal.
Prinzipiell denke ich mal das es egal ist, fände es aber schöner, wenn bei der Spielinitinierung nur erstmal der Server gestartet wird. Jeder Nutzer hat dann auch die Möglichkeit, sich mit einem Client zum Server zu verbinden.
Warum? Vielleicht möchte man garnicht als Client dem Spiel beitreten, sondern nur den Serverdienst zur Verfügung stellen.
Allerdings hat das wenig mit der Software-Architektur zu tun, sondern nur das Startverhalten der Software, von daher bin ich mir wie gesagt nicht sicher, ob darauf deine Frage rauslief. Architekturtechnisch sollte es aber auf jeden Fall so sein, das Client- und Servermodul strikt getrennt sind.

*grüssle*
MeinerEiner


----------



## flashray (13. März 2007)

Hallo MeinerEiner,

der Initierer wird auch auf jedenfall mitspielen. Natürlich wird er zunächst einen Server starten, damit sich andere Teilnehmer nach Wunsch verbinden können.

Für den Initierer habe ich aber die Alternative dessen Spiel Logik mit in den Server zu packen, oder für ihn wird ebenfalls ein Client gestartet, so dass es nur Spieler gibt die Clienten sind, wobei auf dem Rechner der das Spiel gestartet hat sowohl der Server als auch der eigene Client läuft.

Meine Frage zielte darauf ab, ob das so vielleicht programmiertechnisch einfacher zu realisieren ist, und die Informationsverteilung leichter wäre, weil die Informationen einfach an alle Clienten geschickt wird, und die Rollenverteilung strikter ist.


Vg Erdal


----------



## tobias_petry (13. März 2007)

es sollte4 auf jedenfall so sein, denn wenn du von dem Prinzip abweichst, dass es einen broadcast-server und nur clienten gibt wird das entwickeln schwieriger und unnötig komplex wenn es vllt nacher auch einfach nur eine server-software geben soll


----------



## MeinerEiner_80 (13. März 2007)

flashray hat gesagt.:


> Für den Initierer habe ich aber die Alternative dessen Spiel Logik mit in den Server zu packen, oder für ihn wird ebenfalls ein Client gestartet, so dass es nur Spieler gibt die Clienten sind, wobei auf dem Rechner der das Spiel gestartet hat sowohl der Server als auch der eigene Client läuft.


Wie ich schon sagte,  Client und Sermodul, bzw. Spieler und Server strikt trennen.
Der Initierer sollte sich ebenfalls als Spieler extra zum Server verbinden.
Aber, die Logik die für die Verwaltung und Initierung des Spiels nötig ist, solltest du auch in den Server packen...  

*grüssle*
MeinerEiner


----------



## flashray (13. März 2007)

Hallo,

danke an beide. Da bin ich schon mal einen Schritt weiter. Strikte Trennung von Server und Client.

Da ich bisher, bis auf eine einzige Vorlesung keine Berührung mit Verteilter Programmierung hatte, ist bzw. war das keine Offensichtlichkeit für mich.

Diese eine Vorlesung, war eine Einführung in CORBA. Die scheidet von vornherein aus.

Java bietet nach meinem eher dürftigen Wissen in diesem Bereich noch folgende Alternativen an:
Sockets über UDP
Sockets über TCP/IP
RMI

Und natürlich viele Abwandlungen, Umsetzungen dieser. Könnte man für meine Zwecke eines dieser favorisieren? Oder anders gefragt, mit welchem dieser würdet ihr den Netzwerkmodus realisieren?


Vg Erdal


----------



## tobias_petry (14. März 2007)

da ist dann wieder die Frage wie genau das Spiel abläuft, aber bei Multiplayer-Live-Spielen die in Echtzeit laufen sollen, nutzt man in der Regel UDP auf Grund der Möglichkeit von Verlust von Datenpaketen (positiv gemeint)


----------



## flashray (14. März 2007)

Hallo tobias,

das musst du mir nochmals erläutern? Bin aus der knappen Erklärung nicht schlau geworden!


Vg Erdal


----------



## Thomas Darimont (14. März 2007)

Hallo,

also Prinzipiell gibt es da mal wieder mehrere Möglichkeiten...
wie teilweise schon erwähnt sind bei der Netzwerkprogrammierung die maßgebenden Faktoren Verzögerung
(Lag / Latency), (Garantierte) Übertragung wichtiger Daten und Bandbreite. Diese Faktoren gilt es zu beachten, 
um ein perfomante und responsive Multiplayer Anwendung zu erstellen. 

Weiterhin gibt es mehrere Architekturen die potentiell in Frage kommen:
Client / Server und P2P (Peer to Peer).

Bei C/S Anwendungen findet die gesamte Systemkommunikation nur über 
den Server statt.

Für eine Client/Server basierte Lösung bieten sich normale (Server)Sockets auf TCP / UDP Basis an.
Bei TCP ist die Übertragung garantiert, bei UDP nicht.Das bedeutet das wichtige nicht zeitkritische Daten
per TCP versendet werden sollten. Nicht wichtige nicht Zeitkritische Daten können per UDP versendet werden.
Bei wichtigen und zeitkritischen Daten bietet sich die Verwendung von UDP mit einer eigenen Übertragungskontrolllogik
an die bei Fehlübertragung die geforderte Sequenz erneut sendet (quasi das gleiche wie das was TCP schon von Haus aus macht
nur speziell angepasst an den jeweiligen Bedarf). Natürlich bietet sich hier auch noch die Variante an, pro Client 
zwei Verbindungen zum Server aufzumachen. Eine UDP Verbindung für die zeitktischen Daten und eine TCP Verbindung für
die wichtigen aber nicht zeitkritischen Daten.

Weiterhin bietet sich für einfache C/S Anwendungungen auch die Verwendung von RMI an. Das hat den Vorteil,
dass man sich nicht mit Low Level Socket Programmierung quälen muss was jedoch den Nachteil eines erheblichen 
Protokoll / ObjektSerialisierungs Overheads mit sich bringt, der für Zeit / Bandbreitenkritische Multiplayer Anwendungen IMHO 
nicht hinnehmbar ist.

Beim typischen Client / Server Szenario verbinden sich mehrere Clients zu einem Server welcher für die Verteilung
der Spieldaten eines Clients an alle anderen zuständig ist. Dabei ist dann zu klären, wie die einzelnen Berechnungsaufgaben
zwischen Client / Server verteilt sind. Bei Spielen wie etwa 3D Multiplayer Weltraumsimulationen werden für die Darstellung
einer Spielszene sehr viele Daten benötigt (Position der Spieler, aktuelle Flugrichtung, Energie, Geschwindigkeit, etc.)
Da die Daten potentiell verzögert beim Client ankommen muss der Client gewisse Werte interpolieren um so die Spielszene
halbwegs realistisch darstellen zu können. Kommen die Werte vom Server dann irgendwann an wird die Spielsituation entsprechend
der neuen Daten "smooth" angeglichen so das man möglichst wenig davon mitbekommt. (Na ja, das mal als exkurs ;-)

P2P ist eine Weitere Variante für Multiplayer Anwendungen bei der alle beteiligten Systeme erst einmal gleichberechtigt sind.
D.h. jeder Teilnehmer kann mit jedem anderen Teilnehmer kommunizieren. Hier bietet es sich nun an einen Teilnehmer als
"Server" auszuwählen, der dann die Koordination des eigentlichen Spiels übernimmt und die zentralen Spieldaten (Spielzustand) verwaltet.

Für P2P gibt es für Java zahlreiche Implementierungen:
Beispielsweise:
http://www.jxta.org/
http://www.jgroups.org/javagroupsnew/docs/index.html
( Natürlich kann man über MulticastSockets sowas auch relativ einfach selber bauen:
http://www.tutorials.de/forum/java/241551-netzwerk-udp-multicast-socket-pakete-empfangen.html )

Gruß Tom


----------



## tobias_petry (14. März 2007)

also das schöne an UDP ist, dass verlorene Datenpakete nicht erneut gesendet werden, nehmen wir an, du läufst auf dem Feld mit deiner Bombermanfigur 2 Kästchen vor, würde bei TCP beim ersten Schritt ein Übertragungsfehler auftreten, würde er das Paket solange senden bis es ankommt, das nächste Paket (Schritt Nr. 2) müsste nun solange warten bis Paket 1 (Schritt 1) empfangen wurde, ist die Anwendung zeitkritisch, ist das natürlich nicht sehr schön, nun könnte man UDP verwenden und wenn das erste Paket verloren geht, ist es weg und das 2. Paket muss nicht warten, in dem Falle wäre es auch gut, da der erste Schritt dann sowieso eine veraltete Positionsangabe ist und man gut darauf verzichten könnte.
Wann man UDP und TCP verwendet ist zT schwer zu entscheiden, denn es ist von dem dahinterliegenden System (Spiel) abhängig, ob Datenpakete immer ankommen müssen, oder auch mal fehlen können, bei einem periodischen Senden von Daten könnte man UDP verwenden, bei einem Event-basierten Senden würde ich jedoch zu TCP raten


----------



## flashray (14. März 2007)

Hallo Tom,

danke für die ausführlichen Erläuterungen.

Bei CS möchte ich bleiben. P2P ist mir noch zu fremd von der Implementierung her.

Über JGroups habe ich keine einstufende/einordnende/wertende Aussage so jetzt auf die Schnelle im Web gefunden und kann es nicht einschätzen.

Aus der JGroups Homepage werde ich nicht unbedingt schlau, weil es noch Neugebiet für mich ist.

Kannst du bitte in kurzen Worten, die Vorteile von JGroups sagen. Damit ich abwägen kann, ob es sich lohnt sich darin einzuarbeiten, und ob es überhaupt das richtige für mich ist.

Vg Erdal


----------



## flashray (14. März 2007)

Hallo Tobias,

ich bleib dann doch bei TCP, denn es müssen auch die Punkte gezählt werden, diese dürften dann nicht verloren gehen.

Zwei Verbindungen pro Client eine TCP eine UDP wäre mir dann zu kompliziert!


Vg Erdal


----------

