# Realisierung eines Netzwerkcodes für ein Strategiespiel



## Shrek (16. Feb 2008)

Hallo,

Ich habe vor mal ein ganz simples Strategiespiel (in Java) zu programmieren. Die grösste Schwierigkeit dabei ist wohl, dass das Spiel online gegen andere spielbar sein soll. Ich habe mir vorgenommen klein anzufangen. In meinem ersten Versuch soll man ein Spiel starten können (hosten, joinen und alles was dazugehört) und jeder hat z.b. 5 Einheiten, die dann auf weissem Hintergrund bewegt werden können und bei allen Spielern sollen alle Einheiten sichtbar sein. (später sollen die dann auch kämpfen können, aber eben erst später).

Aber wie realisiert man diesen Netzwerkteil? Ich habe schon simple Socket-Anwendungen gemacht, wo der Server dem Client ein Wort geschickt hat und dieser es dann ausgegeben hat. Doch hier handelt es sich um mehrere X,Y Koordinaten, die dauerhaft geschickt werden müssen und später müssen die sich auch noch bekämpfen können...

Was macht der Server, was der Client? Meine Überlegung wäre die: Der Server übergibt beim Spielstart alle Sockets den Clienten, so dass diese sich während dem Spiel direkt Daten schicken können. Macht dies Sinn? Wenn nein, wie könnte man es sonst sinnvoll machen?

Angenommen ein Spiel wäre gestartet. Was soll man sich dann jeweils schicken lassen? Irgendwie ein spezielles Byte, dass man weiss, dass jetzt die X und Y Koordinaten kommen und dann eben die Koordinaten, oder soll mein gleich das ganze Object via ObjectOutputStream schicken?

Das waren jetzt einige Überlegungsfragen. Ich hoffe ihr könnt mir ein paar Tipps zur Realisierung meines ersten Versuches geben. Evt. kennt ja jemand einen source code oder ein tutorial über ein multiplayerspiel, wo ich den Netzwerkcode studieren könnte.

Ich bin dankbar für Antworten 
Gruss Chrigi


----------



## Thief (16. Feb 2008)

Oehm, also wenn ich das jetzt richtig überflogen habe musst du nur ein eigenes Protokoll entwerfen ?!

Ich weiss jetzt nicht was da alles rein muss (also spieltechnisch welche Informationen da gesendet werden müssen), und die Frage die sich bei mir immer stellt ist : Besser Strings schicken, oder Objekte *g*

Aber sagen wir mal du schickst nen String, dann stell dir einfach folgendes vor:

du bist auf x=1, y=1 und willst nach x1=2, y1=3 und heisst P, dann könnte es aussehen:

P,1,1,2,3,XY  also Name, x,y,x1,y1,checksum

Da du das Protokoll entworfen hast, weiss der Server natürlich wie er damit umzugehen hat.


----------



## Shrek (17. Feb 2008)

Danke vielmal für die Anwort. Jetzt würde mich gerne noch interessieren wie man folgendes am besten realisiert:
Die Funktionen in.read(), in.readInt() usw. warten ja jeweils solange bis etwas eintrifft. Macht man da am besten einen zusätzlichen Thread, der auf Inputs wartet und diese verarbeitet, oder soll man ohne Threads arbeiten und einfach jeweils ein timeout setzen, so dass es nicht allzulange wartet?

Und mich würde immernoch interessieren was am besten zu realisieren wäre: 
1) Ein zentraler GameServer, der alle laufenden Spiele verwaltet, und für diese jeweils x,y Koordinaten usw. an alle weterleitet etc.
2) Oder ein zentraler GameServer, der einfach nur das Spiel hosten und joinen übernimmt und sobald ein Spiel gestartet ist, die Sockets den Clienten übergibt, so dass das Spiel danach direkt unter den verschiedenen Spielern abläuft.
3) Dritte Möglichkeit ist, dass der Host quasi der Server des Spieles ist. Also die Koordinaten usw. laufen alle über ihn und werden von dort an alle anderen gesendet und evt. auch auf Cheats überprüft. Nachteil ist halt, dass das Spiel abbricht wenn der Host rausgeht.
4) evt andere Vorschläge?

Ich bin dankbar für eure Hilfe 

Gruss
Shrek


----------



## tuxedo (18. Feb 2008)

Wenn du sowieso was "ganz simples" machen willst, warum nimmst du dann nicht RMI, oder falls es über ROuter hinweg noch prima funktionieren soll nicht meine RMI-Alternative SIMON (siehe links von diesem Beitrag) ?! Wenn du nicht gerade 1000 Clients gleichzeitig in einem Echtuzeitspiel bedienen willst dürfte das übrig ausreichen...

Ein Protokoll auf Strings basieren lassen ist nicht so das gelbe vom Ei. 

- Alex


----------



## Shrek (18. Feb 2008)

Danke vielmals für den Tipp. Bin gestern schon auf RMI gestossen, aufgrund meinem Router hatte ich allerdings kein wirklich kluges Netzwerkdesign hingebracht. Deshalb ist das SIMON wohl genau wonach ich suche 
Ich werde mal hinaunschauen und nochmals danke für den Tipp 

Gruss Shrek


----------



## tuxedo (18. Feb 2008)

Bedenke: Simon ist noch im Teststadium. Freue mich über jeden gefundenen Bug. 
Nichts desto trotz kannst du mit Simon schon prima Sachen machen...

- Alex


----------



## Shrek (18. Feb 2008)

Ich bin gerade daran mit SIMON meinen ersten Versuch zu realisieren. Dabei haben sich kleine Fragen gestellt. Ich habe im main mit folgender Zeile den Zugriff auf dieses ServerInterface vom Server freigemacht.

```
ServerInterface server = (ServerInterface) Simon.lookup("127.0.0.1", 2000, "server");
```
Jetzt hat es in diesem ServerInterface eine Methode _Player getPlayer(int id) _die mir das Player-Objekt dieser ID zurückgibt.
1. Frage: Ich hätte jetzt mit _Player enemy_1 = server.gePlayer(1);_ den Spieler mit der ID 1. Würde ich nun an diesem Player Object eine Methode ausführen z.B. _enemy_1.move(...);_, ist dies dann hier eine Referenz zum wirklichen Player Object auf dem Server, so dass es auch dort im Speicher geändert wird, oder wird das nur beim lokalen Clienten geändert werden?

2. Frage: Ist dies überhaupt möglich, via getMethoden vom ServerInterface Objekte/Variabeln abzurufen, denn die Variabeln sind ja eigentlich (jedenfalls im Code) nur in der ServerInterfaceImplementation vorhanden.

3. Frage: Ist es evt. einfacher wenn man die Player-Klassen vom Server aus gleich einzeln in eine Registry tut, was dann von der Seite des Clienten so aussehen würde:

```
Player p1 = Simon.lookup("127.0.0.1", 2000, "p1");
Player p2 =  Simon.lookup("127.0.0.1", 2000, "p2");
Player p3 =  Simon.lookup("127.0.0.1", 2000, "p3");
```

Ich hoffe ihr könnt mir helfen und freue mich sehr auf Antworten 

Gruss Chrigi


----------



## tuxedo (19. Feb 2008)

Zu 1):

Wenn du dir vom Server objekte holst, die Methoden haben, welche auf dem Server weitere Aktionen nach sich ziehen, dann sollten diese Objekte auch Remote-Objekte (also welche die SimonRemote implementieren) sein. Allerdings halte ich das in deinem Fall für kein gutes Design. Ich würde viel eher am Server eine Methode machen wie z.B.


```
Server#moveMe(clientCallback, x,y,z);
```

Der Client ruft die Methode auf, übergibt dem Server das Callback-Objekt (damit der Server auch wirklich weiß dass das der richtige Client ist) und zusätzlich noch Koordinaten oder sonst was. Der Server sollte das dann alles prüfen und ggf. Rückmeldung geben ob's auch zulässig war (Stichwort Cheaten).

Zu 2)
Ja, genau das ist ja der Trick an RMI bzw. Simon. Du bekommst kein wirkliches Serverobjekt. Du bekommst ein Proxy-Objekt das sich von den Methoden her exakt so verhält wie das Objekt direkt auf dem Server. Der Client ruft also die Server-Methoden in dem Proxy-Objekt auf, welche dann "abgefangen", zum Server geschickt und dort ausgeführt werden. Das Ergebnis (return-wert) wird dann wieder zurück zum Client übermittelt. Und der Client denkt: Prima, hab ich lokal ausgeführt ... Dabei wurde alles zum Server übermittelt.

Zu 3)
Ach herrje. Ne, so eine Struktur würde ich nicht wählen. Ein grund dafür ist, dass der Client dann pro Player-Objekt eine Socketverbindung zum Server aufrecht halten würde... 

Erkärt doch mal wie und warum der Client Objekte am Server bewegt. In der Regel sollte der Client nur seine eigene Player-Figur bewegen können. Alles andere sollte, oder viel eher muss im Server ablaufen. 

Von daher würde ich das eher so machen:

Server bietet login-Methode an "login(ClientCallback)" und liefert als Ergebnis ein ServerSessionObjekt.

Dieses ServerSessionObjekt enthält dann alles notwendige in form von Methoden damit der Client seine Interaktionen mit dem Server abwicklen kann. ALso eine Methode für's bewegen, eine Methode für Interaktion A, eine Methode für Interaktion B, usw usw.

Das alles ist jetzt aber mehr eine Frage des Spiel-Design als eine Frage des Protokolls oder zu RMI/Simon ...

- Alex


----------

