Warum ist Java für Spiele nicht so gut?

7 Antworten

Vom Fragesteller als hilfreich ausgezeichnet

In erster Linie würde ich dieser Aussage erst einmal widersprechen, denn viele Spielideen können mit Java durchaus gut umgesetzt werden und es gibt zahlreiche Tools (wie LWJGL, libGDX oder die jMonkeyEngine), die dich dabei unterstützen. Der Fokus bei der Umsetzung von einem Spiel kann generell auf vielen verschiedenen Punkten liegen (Story, Puzzles, Grafik, ...) und die benötigen auch mal unterschiedliche Ressourcen. Man sollte sich dessen bewusst werden, bevor man mit einer Umsetzung eines Spiels beginnt, denn dies ist enorm wichtig für den späteren Spielspaß.

Es gibt bspw. Schach-Apps, die den Spieler zwar mit verschiedenen visuellen Effekten je Spielzug begeistern können oder das Schachbrett in 3D darstellen. Bei der Spiellogik kommt es jedoch zu Mängeln, weil bspw. ein Zug wie die Rochade unbekannt ist. Dies wäre dann ein Beispiel für ein Projekt, wo der Fokus nicht gut gesetzt wurde.

Oder ein anderes (schlechtes) Beispiel: Ein riesiges Open-World-Game, welches in seinem Aufbau kaum Abwechslung, dafür aber hässliche, matschige Texturen bietet.

Ein weiterer Punkt ist, dass es auch Sinn machen kann, einzelne Aspekte eines Spiels in Module zu unterteilen, die in verschiedenen Sprachen implementiert werden. Dabei denke ich an serverbasierte Spiele, bei denen das Modell rundherum für die Netzwerktechnik durchaus in Java implementiert werden könnte. Die Good Game Studios setzen hier meines Wissens bspw. auf Java, das (ehemals browserbasierte) Spiel Runescape setzt gänzlich auf der Sprache auf.

In dem Fall, dass man nun ein Spiel entwickeln möchte, welches sich aufgrund seines Aufbaus vorausschauend rechenintensiv und speicherfressend verhält, wäre Java aber tatsächlich nicht die optimalste Wahl.

Der Grund liegt darin, das Java (und damit beziehe ich mich folgend auf die gesamte Architektur/Technologie!) in erster Linie für portable Anwendungen entwickelt wurde. Um das zu erreichen, wird das produzierte Programm in einer Virtual Machine ausgeführt. Das heißt, der Zugriff auf das wirkliche System (und damit auf Hardware-Treiber, u.ä.) ist ein weiterer Weg (mehr Ressourcen sind notwendig). Ein systemnäherer Einfluss (bspw. auf das Speichermanagement wie in C, freier Umgang mit Zeigern, u.ä.) ist dir in Java praktisch per se verwehrt. Im Gegensatz dazu lässt sich in einer hardwarenäheren Sprache wie C++ manch eine Implementation eines Algorithmus einfacher optimieren. Wenn du weißt, was du tust(!), kannst du in der Hinsicht also einen Vorteil herausschlagen.

Notwendig erachte ich es an dieser Stelle, trotz des obigen Arguments, gegen ein altes Vorurteil zu steuern: Java ist keinesfalls langsam und die JVM arbeitet ziemlich effizient, gerade was die JIT-Optimierung angeht.

Zwingend notwendig ist es heutzutage auch nicht mehr, selbst auf tiefste Ebenen herunterzukriechen, um Optimierungen vorzunehmen (man hat nur gern diesen Joker im Ärmel). Vor allem natürlich, wenn man eine gute Basis hat. Für diese Aussage kann man eine Engine wie Unity als Beispiel heranziehen. Der Otto-Normal-Nutzer arbeitet keinesfalls auf unterer Ebene mit C oder C++, sondern eine abstrakte Ebene weiter oben (mit C# und da läuft in der Regel sogar noch ein GC). Die Möglichkeiten der Performance-Optimierung, die die Engine bereitstellt, reichen völlig, um gute, auch rechenintensivere Spiele zu entwickeln.

Aber ich schweife ab.

Ein weiterer oft angeführter Grund ist der in Java integrierte GC, dessen Laufzeit nicht einfach beeinflussbar ist. Wenn er zu der Entscheidung kommt, zwischendurch einmal Speicher freiräumen zu müssen, wird für diese Zeit, in der er das tut, dein Programm unterbrochen, was zu einem Lag in deiner draw loop bzw. der Framerate führen kann. Auf der anderen Seite kann es sein, dass schwerer wiegende Speicherstellen, die gelöscht werden könnten, erst spät bearbeitet werden.

Prinzipiell lässt sich gegen solche (u.a. übliche Performance-)Probleme schon mit gewissen Strategien (wie Object Pooling) entgegengehen. Und um auch einmal ein konkreteres, einfaches Beispiel zu benennen: Eine häufige Konkatenation von Strings via Konkatenationsoperator (+) statt StringBuilder (bspw. in einer Schleife) ist schlecht. Auf diese Weise würde man unnötigen Speicher anhäufen, der vom GC wieder freigeräumt werden müsste.

Lösungskonzepte, die die Probleme mit dem GC selbst an der Wurzel packen wollen, könnten eine Neuimplementation eines Systems beschreiben, auf dem Java laufen kann. Insofern wären wir dann schon bei der Implementation eigener Game Engines (wie die NOD Engine), in denen Java als Skriptsprache eingesetzt werden könnte. So etwas ist prinzipiell ein schweres, aufwendiges Unterfangen.

Ein letzter Punkt, der mehr für Tools (wie Unity, Unreal, ...) sprechen würde, welche nicht auf Java basieren, wäre die Auswahl verfügbarer Literatur und Größe der Community. Beides ist für Java durchaus vorhanden (im Fokus ständen hier die bereits oben genannten Java-Tools: libGDX, etc.), jedoch wohl kaum so groß, wie bei benannten Konkurrenzprodukten. Das heißt, wenn du Probleme mit einem bestimmten Tool hast (z.B. JOGL für das Grafik Rendering), ist die Wahrscheinlichkeit etwas geringer, hilfreichen / fachkundigen Support von anderen dafür zu erfahren.

AntworterBasic  28.02.2020, 20:19

Wirklich gut erklärt - dankeschön 😊
Deine Ausdrucksweise kannst du allerdings noch ein wenig verbessern ^^

Achja, und kannst du mir sagen, ob Java - Programme immer Skripte sind, oder auch zu Binärcode kompiliert werden?

0
regex9  28.02.2020, 20:42
@AntworterBasic

Java wird normalerweise zu Bytecode umgewandelt. Den kannst du in den class-Dateien wiederfinden, die der Compiler generiert. Die Umwandlung in Maschinensprache findet dann innerhalb der JVM zur Laufzeit statt.

3
AntworterBasic  28.02.2020, 20:46
@regex9

Achso das heißt es ist kein Quellcode mehr, den man einfach analysieren und verändern kann, aber auch nicht in Binärform, oder?

0
regex9  28.02.2020, 20:51
@AntworterBasic

Der Code besteht dann nur noch aus stark verkürzten Anweisungen für die JVM und ähnelt nicht mehr Java. Nur aus Nullen und Einsen besteht er deswegen aber nicht.

2
regex9  18.06.2020, 14:57

Eine Korrektur zu obiger Aussage:

Eine häufige Konkatenation von Strings via Konkatenationsoperator ( +) statt StringBuilder (bspw. in einer Schleife) ist schlecht.

Hiermit ist gemeint, dass nur ein StringBuilder (vor der Schleife) erstellt werden sollte, dem dann in der Schleife die Strings angehängt werden. Würde man stattdessen nur den Konkatenationsoperator benutzen, könnte das bedeuten, dass in jedem Schleifendurchlauf implizit ein neues StringBuilder-Objekt angelegt wird.

0

Schon darum weil es nicht direkt auf der Hardware ausgeführt wird. Durch die Virtualisierung geht schon Performance verloren.

Woher ich das weiß:eigene Erfahrung – Ich habe selber lange im PC gearbeitet

Ich bin zwar kein Spiele-Entwickler, habe mir aber sagen lassen, dass C++ gerne verwendet wird weil etliche engines damit entwickelt wurden, und man die leicht einbinden kann. Wie angedeutet, das ist Halbwissen.

xtrify  15.11.2019, 17:21

C++ für Spiele? Fuuu da würde ich mir lieber die Kugel geben xDDD. C# hingegen wird häufig verwendet. Und wird auch von vielen Engines zb Unity Standardmäßig verwendet.

0
wiiha  15.11.2019, 17:24
@xtrify

Wie gesagt, halbwissen. Kann durchaus sein, dass mir C# dazu empfohlen wurde. Danke für die Aufklärung.

0
xtrify  15.11.2019, 17:26
@wiiha

Mit C++ kannst du halt super effizienten code schreiben. Deswegen wird damit häufig auf großen HLRZ gearbeitet. Aber der Nachteil ist du musst halt jeden scheiß den du machen köntest auch machen. Und die Doppelbelegung von so ziemlich allem ist auch nicht gerade schön.

2
SirNik  15.11.2019, 17:32
@xtrify

Unity Core ist in C++, UR auch und viele andere auch.

Der geliebte objektorientierte Ansatz und Hardwarenähe machen C++ gut geeignet.

C# wird in Unity zum Skripten verwendet; Richtige Softwareentwicklung und somit das Spiel ist dadurch nicht abgedeckt;

Tatsächlich sind also viele bekannte Gameengines im Hintergrund mit C++ entwickelt worden. In modernen Gameengines sind oft Skriptingsysteme integriert, die es einem erlauben bestimmtes Verhalten zu Skripten (verschiedene Sprachen gehen da: C# bei Unity bekannt, UnityScript [abgewandeltes JavaScript] gabs mal bei Unity; Andere Engines bieten andere Skriptingschnittstellen mit anderen Sprachen an) [Unity hat einen erheblichen Marktanteil, weshalb viele C# empfehlen].

Je nachdem was du entwickeln willst (Backend, also die Engine) ist C++ weit verbreitet. Wenn du mehr Gameplay und Co, dann C# (wegen Unity) oder anderes.

1
regex9  15.11.2019, 17:36
@xtrify

Wieso empfiehlst du in deiner Antwort dann C?

0
xtrify  15.11.2019, 17:37
@SirNik

Ich bin durch die Formuliereung der Frage einfach mal davon ausgegangen das OP nicht Backend entwickeln will sondern überhaupt erstmal irgendein kleines Projekt machen will. Du empfiehlst einem Parkwanderer auch keine Eispickel weil er damit besser Gletscherwände hochkommt.

2
xtrify  15.11.2019, 17:38
@regex9

Erstmal generellC ist gut für eig alles. und für einfache Spiele programmierung habe ich doch C# hervorgehoben.

0
Ifm001  15.11.2019, 17:29

Dann sage demjenigen, er möge C, C++, C# usw. besser auseinanderhalten.

0
wiiha  15.11.2019, 17:32
@Ifm001

Keine Sorge, der Typ hat einen Dipl. Ing in Informatik (und arbeitet hauptsächlich mit C++). Es ist wahrscheinlicher, dass ich mich vertan habe, weil mich Spiele zu entwickeln wenig interessiert. Ich programmiere ganz andere Sachen.

0

Java ist in erster Linie relativ langsam, da der Bytecode interpretiert wird. Außerdem gibt es zB Unity, welches mit dem in der Hinsicht besseren C# arbeitet. Ist ziemlich ähnlich zu Java, guck dir das mal an.

Java ist halt eher, wie die anderen schon sagten, für universelle Anwendungen gedacht.

Gegenbeispiel wäre aber zB Minecraft, das ist auch mit Java gemacht.

Woher ich das weiß:Hobby

Weil Java von der Konzeption her nicht besonders für Ansteuerenungen von schneller Graphik festgelegt wurde.

Die Stärken sind in der Datenverarbeitung und Universellität von anderen Anwendungen, auch ohne Oberfläche. Beispielsweise nur Netzwerk oder Dateiverarbeitung.