# [Java Server] Allgemeine Frage zum Thema Networking in Videospielen



## GentleXD (12. Dez 2016)

Hallo lieber Benutzer (der sich Zeit nimmt sich um meine Frage zu kümmern ), 

ich habe mal wieder ein kleines Problem/Frage, naja ich arbeite nun schon seit rund 2 Monaten an einem 2D Side Scrolling Platformer/Sandbox Game.
Dieses Spiel soll neben einem normalen Sandbox Game Mode auch Multiplayer Elemente enthalten, da ich aber bisher her nur kleine Chat Systeme, Datenbank Strukturen etc. verwendet habe wollte ich einmal fragen was ich so benutzten kann wenn ich einen Server für ein 2D Spiel entwickeln will. 

Infos zum Spiel: Ich arbeite wie gesagt an einem 2D Side Scrolling Game welches eine Recht große Menge an Items, Dungeons, Welten etc hat.
Gearbeitet wird mit Java und LibGDX.

Hier nun mein kleiner erster Ansatz:
Ich habe bereits vorher in kleineren Projekten mit den ServerSockets und Sockets von Java gearbeitet aber auch mit anderen kleineren Networking Engines, z.b. die von LibGDX, um Chat Programme zu schreiben. Nun ist ein 2D Spiel nun mal kein Chat(zumindest meistens ).
Meine generelle Frage wäre jetzt kann ich weiterhin die ServerSockets Sockets von Java verwenden und dann Packets versenden etc. mit Informationen und diese dann im Client umsetzten ? Und noch eine Sache ich würde das ganze auch gerne mit einer Art selbstgeschrieben (denn muss ich noch machen) ControlPanel arbeiten um den Server zu starten stoppen etc. Für das Speichern der Welt möchte ich gerne ein Multiples System programmieren was mir ermöglicht die Welt Speicher Dateien auf verschiedenen Servern zu lagern und dann von allen Servern abrufen können. Und sollte ich am besten Datenbanken nehmen um alle Spieler Daten etc abzuspeichern oder sollte ich mir da auch ein eigenes System überlegen?!


PS: Ich bin bereit sehr viele neue Sachen zu lernen und alte zu verbessern. Java Erfahrung circa 3 Jahre. Networking Erfahrung habe bereits gesammelt aber es ist nicht das beste.


----------



## Major_Sauce (19. Dez 2016)

Moin,

ServerSockets/Sockets wären meiner Meinung nach auf jeden Fall der richtige Ansatz, ich muss aber auch dazusagen dass ich gerne mal das Rad neu erfinde.
Du solltest nur auf jeden Fall versuchen die Pakete möglichst klein zu halten (logisch) und vielleicht auch nochmal überlegen wie du die Pakete denn versenden willst. In vielen Fällen ist man an dem Punkt wo man sich zwischen UDP und TCP entscheiden muss, hier solltest du dich vielleicht ein wenig einlesen.
Zum Control-Panel sollte es eigentlich nicht viel zu sagen geben, kannst du so machen, vielleicht noch überlegen ob man den Server (falls win) als Service laufen lässt, auf Linux dann einfach ein Start-Script schreiben...
Daten auf verschiedenen Servern verteilen, da wird es interessant. Was machst du, falls einer der Server mal off ist ect. Da musst du dann eine Sync oder ähnliches einrichten ect. Hierzu würde ich einen "Master" vorschlagen, von dem sich die Anderen Server dann jeden Tag/Stunde,was auch immer die Daten frisch holen und an die Clients verteilen (auch hier darauf achten die Daten möglichst klein zu behalten). 

Mit freundlichen Grüßen
Major


----------



## JuKu (2. Jan 2017)

Wichtig ist, dass es sich um eine asynchrone Verbindung handelt, diese kannst du mit Java NIO erstellen.
Am besten verwendest du aber eine Networking Library wie Netty, die dir genau sowas abnimmt und du dich "nur" noch um das Empfangen & Versenden von Daten kümmern musst.



GentleXD hat gesagt.:


> Für das Speichern der Welt möchte ich gerne ein Multiples System programmieren was mir ermöglicht die Welt Speicher Dateien auf verschiedenen Servern zu lagern und dann von allen Servern abrufen können. Und sollte ich am besten Datenbanken nehmen um alle Spieler Daten etc abzuspeichern oder sollte ich mir da auch ein eigenes System überlegen?



Das ganze nennt man "Skalierbarkeit".
Allerdings ist mir noch nicht ganz klar, ob du das in deinem Fall überhaupt brauchst.
Soll jeder Server das selbe machen oder wird die Spielwelt auf verschiedene Server aufgeteilt?
Eine Datenbank solltest du auf jeden Fall verwenden, wenn du einiges an Daten hast, falls es aber schnell sein soll, dann lieber nicht MySQL / PostGreSQL.


----------



## GentleXD (9. Jan 2017)

Danke für die Antworten (Und srry für die späte Rück Antwort), und noch einmal speziell an Juku, danke für die echt gute Antwort, ich habe mir vorgestellt das mein Spiel auf verschiedene Server aufgeteilt ist die einen übernehmen Spielwelt etc die anderen Spieler, Berechnungen. Nun sollen z.b. zwei Server existieren (nur als Beispiel), der eine und der andere sollen Spieler übernehmen, aber was mache ich wenn auf dem einen die Welt des einen Spielers abgespeichert ist aber dieser auf einem anderen Server sich befindet, soll ich dauernd die beiden Server mit einander synchronisieren lassen oder z.b. in einer Datenbank den Server mit Pfad abspeichern und dann Anfragen versenden?? (Und Pentaquin ist echt nice , und ich weiß das ich noch nicht sonderlich viel Ahnung von dem ganzen habe (bin erst 16), möchte das alles trotzdem lernen)

LG Gentle


----------



## JuKu (9. Jan 2017)

So einfach wie du dir das vorstellst, funktioniert das vermutlich nicht.

Du hast nämlich einen entscheidenten Punkt vergessen:
Große Spiele besitzen nicht umsonst einen Proxy Server. Wenn du keinen hast, muss dein Client zu unzähligen Servern eine Verbindung aufbauen...
Normalerweise gibt es auch nicht nur einen Proxy Server, sondern mehrere. Somit kennt der Client auch nur die Proxy Server und der Proxy Server leitet die entsprechenden Anfragen an die jeweils zuständigen Game Server weiter. Dies hat auch den Vorteil, dass ein Game Server mal crashen kann oder du einen Game Server kurz updatest, ohne dass du dafür Wartungsarbeiten im Spiel ankündigen musst (das ganze nennt sich "rolling updates"). Die Spieler können es nämlich leider gar nicht leiden, wenn ihr Spiel gerade nicht erreichbar ist - und wenn es nur um 30 Minuten geht.


Aber es kommt ganz drauf an, was du erreichen willst und wie du die "Arbeit", also die Last der Server, aufteilen willst.

Bei MMOs unterteilt man meist die Spielwelt in mehrere Sektoren / Regions oder Zonen.
Jeder Game Server ist für einen oder mehrere Sektoren zuständig. Obwohl man normalerweise immer einen sog. Failover Server besitzt (sodass ein normaler Game Server ausfallen kann), wird die Spielwelt sonst auf keinen weiteren Game Server, außer dem Failover gespiegelt. Demzufolge brauchst du auch nur zwischen dem jeweiligem Master & Failover des Regions synchronisieren (per interconnects).
Letzteres löst man angeblich meistens sogar so, dass man einfach alle Anfragen des Clients an beide Server gleichzeitig schickt und diese somit parallel die Spielwelt berechnen - somit brauchst du keine große Synchronisation zwischen den Servern. Allerdings antwortet dann nur der eine Server, der für den Sektor der Master ist, der andere Failover hält quasi immer nur ein Backup.

Ganz wichtig:
Bei MMOs z.B. darf die Datenbank nicht im Zentrum stehen! D.h. du speicherst nicht bei jedem Vorgang die Änderungen ab, sondern erzeugst quasi alle z.B. 100 / 500ms einen Dump und lädst somit die Änderungen zur Datenbank nur alle 500ms hoch. Wenn du zu oft auf die Datenbank zugreifst, wird die Performance deiner Server darunter leiden, da sie auf die Antwort des Datenbank Servers warten müssen.

Wenn es gewünscht ist, könnte ich auf meinem Blog https://jukusoft.com/blog mal nen paar Artikel dazu schreiben.
Auch unser Entwickler Blog bei Pentaquin könnte für dich interessant sein:
https://forum.pentaquin.com/viewforum.php?f=153


----------



## GentleXD (10. Jan 2017)

Hallo Juku danke für die tolle Antwort, ich lerne hier gerade echt viel und finde es sehr interessant, ich hätte noch einmal eine ganz andere Frage die sich nicht auf Networking bezieht, ich arbeite ja an meinem Spiel, und wollte fragen ob sie/du (oder jemand anderes) eine Idee hat zu folgendem Problem/System, ich würde gerne Items wie Rüstung, Schwerter, Essen, Blöcke zum bauen, etc. verwalten momentan läuft es das alle Items eingelesen werden da sie aus verschiedenen Editoren zusammen gebastelt werden und mit Eigenschaften versehen werden, so habe ich zum Beispiel erstellt mein Block Editor mit Texturen für die Welt und das Inventar, und ihm werden bestimmte Werte wie Durabillity, Laufgeschwindigkeit etc. zugewiesen, außerdem kann der Spieler sie im Inventar haben also können sie als Items existieren, nun würde ich diese Systeme gerne alle bündeln und vielleicht vereinfachen, nun habe ich aber nach sehr langen Überlegungen gar keine Idee leider, ich habe überlegt ob man alle Hard coden soll und ins System einbinden soll aber das ist nicht Sinn und Zweck der Sache. 

Nun habe ich mit vorgestellt, da sich viele Eigenschaften überschneiden diese zu verbinden, da zum Beispiel Rüstungen Blöcke Essen etc auch im Inventar vorhanden sein können aber alle unterschiedliche Funktionen haben, zum Beispiel soll man Rüstungen, Schwerter und Essen ja nicht platzieren können und Blöcke nicht essen können. Ich denke glaube einfach viel zu schwer .

Lg Alex


----------



## GentleXD (10. Jan 2017)

Achso und ich würde mich riesig über Beiträge freuen, da ich immer gerne neue Sachen lerne und ich glaube das es sehr interessant ist, und eure Pentaquin Beiträge lese ich sehr gerne und ich verfolge euer Projekt jetzt schon etwas länger.

LG Alex


----------



## InfectedBytes (11. Jan 2017)

Schau dir am besten mal Ashley an, das ist ein Entity Component System, das ist für deinen Anwendungsfall gut geeignet. Anstatt eine basisklasse GameObject zu haben und dann unterklassen Placeable, Weapon, Block, etc. hast du einfach nur eine Entity klasse, welche um Komponenten erweitert wird.
Wenn dein Item essbar ist, bekommt es eben eine Eatable Component, wenn es eine Waffe ist eine Damage Component, etc. Du kannst dann eben beliebige Komponenten kombinieren und damit deine Items zusammenstellen.


----------



## JuKu (12. Jan 2017)

Bleib beim du! 

Zuerst ist es wichtig, dass du deine Anforderungen genau kennst.
In deinem Fall solltest du wissen, was es überhaupt für Eigenschaften für die Items hast, z.B.:

Essbar
Bewegbar
Bewegungsgeschwindigkeit
Ist Item (kann ins Inventar) --> benötigt auch nen Icon
usw.
Dann kannst du dir überlegen, ob nicht eine GameObject Klasse reicht und du in dieser alle Eigenschaften prüfst / nutzt, oder ob ein Entity Component System die bessere Wahl wäre.



InfectedBytes hat gesagt.:


> Schau dir am besten mal Ashley an, das ist ein Entity Component System, das ist für deinen Anwendungsfall gut geeignet. Anstatt eine basisklasse GameObject zu haben und dann unterklassen Placeable, Weapon, Block, etc. hast du einfach nur eine Entity klasse, welche um Komponenten erweitert wird.
> Wenn dein Item essbar ist, bekommt es eben eine Eatable Component, wenn es eine Waffe ist eine Damage Component, etc. Du kannst dann eben beliebige Komponenten kombinieren und damit deine Items zusammenstellen.



Für C++ ist ein ECS richtig geil, unter Java kann man aber schnell Probleme mit dem Garbage Collector bekommen, wenn man es nicht optimiert.
Muss man bedenken, bevor man sich dafür entscheidet.


----------



## JuKu (12. Jan 2017)

Auch ein interessanter Link, den ich gerade gefunden habe:
https://www.gamedev.net/resources/_...-critique-of-the-entity-component-model-r3621


----------



## Viktim (12. Jan 2017)

Du könntest dir ja Enums, mit z.B. den von @JuKu angegebenen Elementen oder dann noch Bestimmten besonderheiten erstellen.
Dann würde dir eine Klasse AufnehmbareObjekt oä. reichen und die Eigenschaften von jedem Item könntest du dann mit den Werten aus den Enums zusammen basteln.

PS: (Ich hab überhaupt keine Ahnung von Spiele-Programmierung, das ist nur was mir dazu eingefallen ist. Kann also auch totaler Quatsch sein )


----------



## GentleXD (14. Jan 2017)

Hey ich melde mich dann noch einmal zurück,

ich habe mir in den letzten Tagen dann das Entity Component System ein bissel auf dem Blatt Papier aufgeschrieben und bin noch auf ein paar Probleme gestoßen. 

Movement System: 

Das erste was ich mir überlegt habe das bewegen meines Speilers, nun habe ich ein Collision Component und ein Move Component, nun welchem soll ich jetzt was übergeben dem Collision System das Move System oder dem Move System das Collision System.

Und noch mein Inventar wie unterscheidet man am besten in einem Entity Component System welches Item jetzt da ist, oder welches ich im Inventar habe wenn ich ein Weapon Component erstelle, haben das ja nicht alle meine Entitys und wie unterscheide ich am besten zwischen den unterschiedlichen Waffen mit einer vorgefertigten Liste z.b. einem Enum ?. Aber das wäre ja auch nicht Sinn der Sache.

Lg Alex


----------



## JuKu (15. Jan 2017)

Du hast bei einem Spiel ja trotzdem immer noch einen Gameloop, der updatet und rendert.
Jetzt besitzt bei einem ECS aber evtl. ein Component eigene update() Methoden.

Es gibt ganz verschiedene Arten, ein ECS zu bauen und nicht jede davon ist für Java oder deinen Use Case geeignet.
Nimm nicht die erste, die du findest, sondern schaue dich gründlich um!

Es gibt Varianten, wo das Entity selbst nur eine ID ist und die Components nur Daten halten dürfen (keine Logik!) und du hast noch zusätzlich Systeme, die bei jedem Durchlauf bestimmte Components abfragen, sich Werte holen und ändern usw.
Unter Java ist diese Variante in meinen Augen aber nicht die beste.

Und dann gibt z.B. auch eine Variante, wo jedes Entity eine Klasse ist, die mehrere Components besitzt.
Components besitzen hier Daten & Logik, d.h. jedes Component besitzt auch eine update() und draw() Methode. Bei dieser Variante hast du zwar keine so gute Daten - Logik Trennung, wie oben, aber du kannst in diesem Fall schneller (performanter) auf eigene Daten zugreifen.


```
interface Component {

    //this is only an example!
    public void update (final float timeDelta);

    public void draw ();

}
```

z.B. für die MovementComponent:

```
class MovementComponent implements Component {

    //player position
    protected float x = 0;
    protected float y = 0;

    //player speed
    protected float speedX = 1;
    protected float speedY = 1;

    public void update (float time) {
        //this is only an example!
    
        this.x += this.speedX;
        this.y += this.speedY;
    }

    public void draw () {
        //MovementComponent doesnt have anything to draw, its an only logically component, drawing is task of another component
    }

    //...

}
```

Wichtig ist, dass jedes Component seine eigene Aufgabe erhält.
Dieses Component z.B. ist nur für die Position & Bewegung des Spielers / Entities zuständig - nicht fürs zeichnen des Spielers!

Auch dies muss nicht die beste Lösung für dein Problem sein! Viele raten sogar eher zu dem "Entity ist ID" System. Finde das System, was zu dir und deiner Anwendung passt!

EDIT:
Bei der update() Methode des MovementComponents könntest du beim Kollisionssystem abfragen, ob er den Spieler überhaupt in diese Richtung bewegen kannst. Und speedX und speedY werden natürlich je nach Tastatureingaben gesetzt.

Evtl. macht es auch Sinn, die Position nochmal in ein extra PositionComponent auszulagern, da nicht jedes Entity bewegbar ist. Das musst du alles selbst entscheiden.


----------



## GentleXD (15. Jan 2017)

Okay danke ich hätte mich persönlich nun auch zu dem ECS entschieden in welcher jedes Entity eine Liste mit Components hat. 

LG Alex


----------



## GentleXD (16. Jan 2017)

Ich habe nocheinmal/immernoch ein Problem was für mich entweder zu umständlich oder nicht lösbar erscheint. Wenn ich ein ECS für Items benutzten werde(was ich vorhabe), stellt sich mit immer noch die Frage wie genau die Implementation aussehen soll, wenn ich z.b. ein Schwert habe das soll beim ausführen mit der Maus einmal kurz den Arm bewegen und dann schaden machen, aber wie definiere ich das ich in der Hand ein Schwert habe aber kein Essen oder Rüstung oder so ?!?


----------



## Jardcore (17. Jan 2017)

Vielleicht solltest du für den ganzen ECS ein eigenen Beitrag eröffnen, es verwirrt nur wenn das alles unter dem Thema Networking postest.

Dann habe ich vielleicht auch ein paar wertvolle Ideen 

Entity {
   Components: {
       NameComponent,
       TransformComponent,
       AnimationComponent,
       WeaponComponent
   }
}

Dein Vorhaben ist übrigens nicht so einfach, eine Implementation mit verschiedenen Animationen für Spieler und Items in Interaktion miteinander kann relativ kompliziert sein.

Besser ist immer ein kleinen Projekt zu suchen, in dem man vielleicht noch kein ECS benötigt und einfach klassisch objektorientiert vorgeht. In diesem Projekt sind die Animationen dann vielleicht auf 4-8 beschränkt.
Schau dir Crawl (http://store.steampowered.com/app/293780/?l=german) an, das Spiel hat wenige Animation, macht aber super viel Spaß und hat eine außergewöhnliche Stimmung. Zudem ein neues und interessantes Spielprinzip.
Ein ECS ist erst dann nötig wenn du wirklich >100 verschiedene Enties hast.

P.S: Für Networking kann ich dir Kryonet empfehlen, ist sehr einfach zu bedienen und gibt dir einen Highlevel Zugriff auf die JavaNetwork API


----------

