Tagebuch: r-process

Mal schauen, was daraus wird…

r-process ist ein 2D rundenbasiertes rogue-like Space-Exploration-Game, das ein Kumpel und ich entwickeln. Sehr früher Entwicklungsstand (~25h Arbeitszeit), wie man am Screenshot sehen kann (natürlich gibt es da noch ordentliche Grafik). Konzeptionell könnte man es als eine Mischung von FTL, Out There und Everspace beschreiben, minus die Kämpfe. Die Idee ist, aus einer Galaxie zu entkommen, die bald durch eine Supernova zerstört wird - wobei es für das Entkommen verschiedene Wege gibt. Viel Resourcen-Management, Crafting, Blaupausen, Forschung, wenig Micro-Management und Grinding.

Wie ich mich kenne, werde ich hier nicht allzuoft schreiben, bin aber jederzeit für Anregungen offen. Der seltsame Name “r-process” ist ein Arbeitstitel, es ist schwer, irgend einen Namen zu finden, der mit Supernovas zu tun hat und noch nicht vergeben ist (der “r-process” einer Supernova erzeugt schwere Elemente, die es sonst in der Galaxis nicht gäbe).

1 „Gefällt mir“

Konkurrenz :face_with_raised_eyebrow: Muss ich schon wieder Leuten anfangen Steine in den Weg zu legen :smiley:
Also interessant wäre natürlich immer etwas über die Technik zu hören, für die ihr euch entschieden habt.

libGDX (mit lautem Zähneknirschen), und da keine HTML5-Version vorgesehen ist, Kotlin. Da das Spiel wenig grafiklastig ist, müssen wir auch nicht viel in die Optimierung stecken.

In dem hässlichen Screenshot steckt schon eine Menge Arbeit (etwa die Schrift, die als Distance Field Font ordentlich skalierbar ist). Da sonst alles ziemlich statisch ist, habe ich wenigstens die Monde animert. Natürlich wird jedes System zufällig generiert, und auch die Planetenpositionen sind zufällig.

Das Raumschiff sieht zumindest schon mal sehr cool aus.

Du knirscht die Zähne, aber fürs Font Rendering hab ich ein paar Wochen in Raw OpenGL gebraucht um es annähernd gut (und performant) zu machen :smiley:

Ja - das liebe OpenGL… damit hatte ich mich auch mal auseinander setzen wollen. Hab sogar ein klein wenig was hinbekommen - aber das war mir dann doch zu low-level. Bei so manchen Posts von euch lerne ich Unity3D halt erst richtig zu schätzen.

Aber es heißt doch Tagebuch :wink: . Und gerade zu Anfang kann man doch auch super gut fortschritte schreiben.

Anregungen können halt dann kommen, wenn wir mehr wissen und natürlich wenns mal einen Spielbaren Zustand gibt (Du hast über ostern doch eh nix vor. Also bis Montag wollen wir was sehen :nerd_face:).

Landnova, iNova, The Universums End

Ein sehr bescheiden wirkender Screenshot, aber ein wichtiger. Nach viel herumprobieren mit verschiedenen Dialog-Optionen, inklusive VisUI, sind wir zum Schluss gekommen, es doch lieber selbst zu machen (was nicht ganz einfach ist, weil Modalität für “normale” Komponenten nicht vorgesehen ist).

Alle vorgefertigten Lösungen waren zu starr, weil bei der weiteren Entwicklung viel kompliziertere, formularartige Dialoge erforderlich sein werden. Die aktuelle Lösung ist im Prinzip unbeschränkt, sie erlaubt beliebige Unterkomponenten, und völlige Freiheit bezüglich Grafik und Listenern. Das heißt natürlich auch, dass man häufiger benötigte Dialogtypen erst einmal selber stricken muss, und das hier war Nummer eins.

Das Projekt wird komplett in Kotlin geschrieben, und ich kann jedem nur raten, der mit einer ähnlich verkorksten API wie libGDX arbeiten muss, das auch in Erwägung zu ziehen. Allein die Möglichkeit, durch Extension-Methoden Hässlichkeiten bestehender Klassen zu korrigieren, und bequeme DSLs für das Loan-Pattern schreiben zu können, sind einfach Gold wert.

Ach ja, ist schon jemand über den Bug gestolpert, dass wenn man libGDX Desktop mit Konfiguration startet, das resizable-Flag ignoriert wird? Als Workaround kann ich die App auch “manuell” konfigurieren, aber das sollte doch eigentlich auch so gehen.

Sieht doch schonmal gut aus :wink: .

An der Stelle aber ein kleiner Tipp von mir: ich würde mich am Anfang noch gar nicht so sehr aufs Hauptmenü setzen. Hatte ich bei Industry City gemacht. Damit hatte ich Wochen zugebracht - hatte Zeug implementiert, dass nicht notwendig war und irgendwann das Gefühl gehabt nicht vorwärts zu kommen und in die Wasserfall-Methodik zu verfallen.

Danach hatte ich angefangen einen Kurs zu schauen, der für fortgeschrittenere Entwickler war und wie die Ihre Spiele planen. Was ich da extrem gut fand waren die Punkte: Wirkliche Prototype und das Onion-Konzept.

Letzteres ist im Prinzip folgendes: Zuerst entwickelst du den Kern deines Spiel. Und dann baust du Schicht für Schicht um diesen Kern Features in dein Spiel ein. Jede Schicht sollte den Kern verbessern und darauf ausgerichtet sein. Letztendlich imho eine super Möglichkeit den Fokus zu wahren.

Da stimme ich dir voll und ganz zu, es war nur so, dass sich der Exit-Dialog als kleinstes Beispiel einfach angeboten hat. Also nächstes stehen die Dialoge zur Rohstoffgewinnung an, also im Spiel.

Ganz nebenbei und auf unterster Priorität: Ich weiß nicht mal, ob der Dialog hier in seiner jetzigen Form überhaupt überlebt. Ich überlege, ob ich stattdessen eine Linie weiter von “Exit” ziehe, aufteile, und die “Buttons” dann direkt in der Oberfläche zeichne. Wäre grafisch sicher reizvoll, die Frage ist nur, wie das dann mit den anderen Einträgen ist.

Also das Menu sieht wirklich sehr gut aus!
Bin echt gespannt wie es hier weiter geht.

Ich (nur ich persönlich) bin nur immer verwirrt, wenn cancel auf der linken Seite steht und das eigentliche ok (bzw hier leave) auf das rechten Seite. Bei zwei Buttons, erwarte ich immer Abbrechen auf der rechten Seite. Aber habe dieses Design schon häufiger nun gesehen. Dran gewöhnen muss man sich ja aber nicht. :smiley:

Sieht echt gut aus :+1:

Das Spiel sichern zu können hat länger gedauert als gedacht. Aktuell ist es einfach JSON, später kann ich das ja noch passwortgeschützt zippen. Außerdem werde ich noch ein zweites JSON sichern, für permanent freigeschaltete Goodies, Statistiken und Achievements, aber das ist aktuell noch nicht nötig.

uuuh, Savegames. Das ist etwas - was ich mittlerweile so weit wie möglich hinaus zögern würde ^^. Schon bei Feature Runner durfte ich das immer wieder anpassen, ändern und neu schreiben.

Wie schon TMII würde ich auch euch den Rat geben: Lasst die Finger weg von Migrationscode. Wenn sich das Save-Game ändert, dann einfach brechen lassen (zumindest solange das Spiel noch alpha, beta, early-access — also alles vor Version 1 ist).

Ich weiß nicht wie das bei Unity ist, oder LibGDX, aber es schadet im allgemeinen nicht, so früh wie möglich ein erstes Savegamesystem umzusetzen. Immerhin ist das OO betrachtet ein ziemlicher Eingriff in die Systemarchitektur. Man muss sich überlegen wie man Zugriff auf praktisch alle relevanten Zustands-abhängigen Teile bekommt, ihn abspeichert und am Ende den Zustand wieder herstellt.
Zudem ist ein Savegamesystem sehr praktisch zum automatisierten und manuellen Testen.

Möglichst keine Änderungen des bestehende Konzepts mehr im Anschluss durchzuführen, das habe ich nach deinem Tipp aber beherzigt, und das war ein guter Tipp :). Dann lieber erstmal ein einfaches stabiles erweiterbares Klartextformat (JSON oder XML), und zum Schluss kann man sich dann nochmal überlegen Arbeit hinein zu stecken. :slight_smile:
Da Spiele meist auf irgendeinem Scene Graph aufbauen funktioniert das auch ganz gut, den Graph im Speicher abzubilden.

jup - kann ich nachvollziehen - ich hatte das Problem immer in Fantasya wenn ich komplett neue Dinge implementiert hatte und die DB angepasst werden musste…

Sollte eigentlich imho keine Auswirkungen haben. Zumindest so wie ich meine Spiele baue. Da sind die relevanten Daten in einfache Model-Klassen abgebildet (welche ich aber nicht unbedingt 1:1 serialisiert haben möchte).

Dementsprechend brauchst musst du beim laden „nur“ die Daten im Model anpassen und das Spiel sollte im richtigen Zustand sein.

#Theorie :stuck_out_tongue: .

Die generelle Spiel-Struktur wird schon so bleiben, ich sehe da keine grundsätzlichen Änderungen auf mich zukommen: Es gibt eine Galaxie, ein Schiff…

Über das Sichern nachzudenken hat mir geholfen, einige goldene Henkel wieder abzuschrauben. Anstatt mich mit Adaptern rumzuschlagen, habe ich mir serialisierungsfreundliche Wrapperklassen geschrieben, die das Konvertieren übernehmen - sehr bequem. Außerdem bietet sich bei JSON immer an, Roundtrip-Tests zu schreiben, so dass man sofort merkt, wenn etwas nicht funktioniert.

Die Sicherung einzubauen hatte auch Einfluss auf die Spiel-Architektur (z.B. muss ich das Spiel jetzt zentral halten, weil ich nur in der Hauptklasse den Listener für’s Ausschalten verfügbar habe). Später wäre das u.U. ziemliche Arbeit gewesen.

Habe noch einmal mein Modell ein bisschen gestrafft, und Linsen für die data Klassen eingebaut (sehr einfach selbst gestrickt, weil ich nicht mehr Abhängigkeiten wollte - Bibliotheken kann ich später immer noch verwenden).

Auch wenn ich jetzt rein “optisch” nicht viel weiter gekommen bin, bin ich mir trotzdem über einige Dinge klarer geworden. Ich denke, es ist wirklich wichtig, nicht zu viele Konzepte in die erste Version zu packen.

Ja, dem kann ich nur zustimmen. Was nicht zwingend notwendig ist würde ich in hacknplan ins backlog packen. Dann wird es auch nicht vergessen. (Für eine bessere Visualisierung kann man noch sowas wie Mindmeister nutzen - hat mir auf jeden Fall geholfen gerade am Anfang nicht zu viel zu wollen).

Zumal gerade am Anfang immer Mal wieder Umbauten anstehen. Und dann passen so manche nice-2-haves nicht mehr und man ist froh, damit keine Zeit verschwendet zu haben.

Babysteps. Das Zeichnen der Ressourcen werde ich wohl nochmal überarbeiten müssen. Rechts daneben kommen dann die Buttons zum “Abbauen” in der jeweiligen Ebene (bzw. “Erforschen” für die “Oberfläche”, falls es eine gibt). Neben “Cancel” kommt dann ein “Scannen”-Button, der Rohstoffe (mit vom Equipment abhängiger Wahrscheinlichkeit) aufdecken kann.

Ja, es ist etwas zäh, aber ich denke, beim nächsten Dialog wird es einfacher. Ich habe jetzt ein sehr einfaches “Scannen” eingebaut, das für ein paar Energiezellen zufällig Rohstoffe aufdeckt. Die “extract”-Buttons sollen dann von der gewählten Ebene etwas abbauen, aber das muss ich noch implementieren.