Tagebuch: r-process

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.

Ich habe jetzt endgültig die Nase voll gehabt, und mir einen extra Layer für das Rendern in LibGDX gebastelt. Da Performance bei mir nicht so sehr das Problem ist, kann ich es auch ziemlich einfach halten. Beispiel der alten Schreibweise (schon mit einigen Hilfsfunktionen):

override fun drawBackground(batch: Batch, parentAlpha: Float) {
    batch.draw(Assets.dialog, bounds.x, bounds.y, bounds.width, bounds.height)
    batch.useFont(Assets.russelSquare, 0.5F, Color.GOLD) {
        draw(batch, title, bounds.x + bounds.width / 2F - titleWidth / 2F, bounds.y + bounds.height - titleHeight)
    }
    batch.end()
    withLineSR(sr) {
        color = Color.GOLD
        rect(bounds)
        val lineHeight = bounds.y + bounds.height - titleHeight - 40F
        line(bounds.x, lineHeight, bounds.x + bounds.width, lineHeight)
    }
    batch.begin()
}

Das kann nur jemand gut finden, dessen Lieblingsfach im Studium Buchhaltung war. Und hier die neue Version:

override fun render() = arrayOf(
       Picture(Assets.dialog, bounds),
       Text(title, at(bounds.x + w2 - titleWidth / 2F, bounds.y + bounds.height - titleHeight), 0.5F, Color.GOLD),
       Rect(bounds, Color.GOLD),
       Line(at(bounds.x, lineHeight), at(bounds.x + bounds.width, lineHeight), Color.GOLD)
)

Ich hoffe, ihr erkennt eine gewisse Verbesserung. Im Hintergrund arbeitet eine Klasse die ganzen Zeichenobjekte ab, und macht dabei das Batch und den ShapeRenderer automatisch auf und zu u.s.w.

Es hat sich so viel geändert, und es gibt trotzdem so wenig zu zeigen. Die Planeten und so sind jetzt 3D, aber noch deutlich zu hässlich für einen Screenshot.

Ein Video vom Macher von “Return of the Obra Dinn” hat mir ein bisschen Angst gemacht bezüglich der Internationalisierung. Und tatsächlich musste ich z.B. meine Font neu generieren, weil ich keine Umlaute hatte. Ich werde jetzt erst mal alles zweisprachig durchziehen:

Damit hätte ich auch die erste Sache, die ins Options-Menü gehört…

Allerdings muss ich mich andauernd am Riemen reißen, um kein Bikeshedding zu betreiben, und mich auf die zentralen Aspekte zu fokussieren.

Nebenbei bemerkt kam gerade ein Spiel raus, dass in eine recht ähnliche Richtung wie r-process geht, nämlich “Void Bastards” - auch wenn es bei mir keinen eingebauten 3D-Shooter geben wird…

Crafting nimmt langsam Gestalt an. Wenn man jetzt auf ein Resource-Icon klickt, werden alle “Rezepte” herausgesucht, die diesen Stoff als Input benötigen. Die Zahl am Ende zeigt, wie oft das Rezept mit den aktuell vorhandenen Resourcen angewandt werden könnte. Nächster Schritt ist natürlich, ein einzelnes Rezept anzeigen und ausführen zu können.

Edit: Neuer Screenshot. Als ich den ersten hochgeladen habe, habe ich mir gesagt, dass es sicher mit transparenten Hintergrund viel besser aussieht…

Das Crafting funktioniert, natürlich mit ein paar Ecken und Kanten.

Das Fragezeichen steht für ein Blueprint (hier: “Elektrolyse”), was ich noch nicht gezeichnet habe.

Mal sehen, wo ich weitermache…

Warte, warte, du hast das Männchen auch selbst gezeichnet? Was für ein Zeichenprogramm verwendest du? :slight_smile:
(Das Menü sieht immer noch schick aus mit dem Dunkelblau/Dunkelrot-Gradient.)

Wann kommt die erste Demo? :smiley:

Viele der Icons sind einfach Unicode-Emoticons. Das Männchen :walking_man: ist U+1F6B6 - “Pedestrian”. Als Zeichenprogramm reicht Paint NET aus.

Bis zu einem Demo wird es noch lange dauern: Das Spiel wird drei Ansichten (Karte, Sternsystem, Erforschung von Strukturen) haben, und ich habe jetzt gerade mal die Grundlagen einer dieser Ansichten fertig. Im Hintergrund muss auch noch die Spielwelt einigermaßen balanciert generiert werden, und ein Ereignissystem fehlt auch noch.

Wobei ich auch sagen muss, dass ich relativ wenig an r-process arbeite. Meine Projekt-Stoppuhr zeigt aktuell 72h, dazu vielleicht noch 15h sonstige Arbeiten.

So, ich habe alle 3D-Elemente rausgeworfen, und bin damit einige Probleme losgeworden. Die erste Version mit 2D ist nicht toll, aber ausbaufähig. Vor allen an den Schatten muss ich noch arbeiten, aber wenigstens sind sie schonmal richtig gegenüber dem Stern ausgerichtet.

Um weiteres Bikeshedding zu vermeiden, starte ich erst mal mit der Sternkarte.

Ich habe noch das Problem, dass das Spiel unter Windows am Ende crasht, habe noch keine tolle Idee…

Die erste Karte, die man auch als solche bezeichnen kann, wenn auch mit vielen Problemchen:

Wahrscheinlich werde ich eine zweite Kamera benutzen müssen, um Zoom und Verschiebung zu erlauben. Vielleicht geht es aber auch etwas extravaganter, ich dachte an sowas wie einen Fisheye-Effekt

3 Likes

super :sunglasses:

Ich finds klasse. Unter deiner Beschreibung konnte ich mir nichts vorstellen. :+1:

Wirkt nur ein bisschen stark im Video. Aber es muss sich ja vorallem gut anfühlen wenn man es bedient. :slight_smile:

Ehrlich gesagt ist das einfacher zu implementieren als Zoom + Verschiebung, sind nur ein paar Zeilen Code:

    fun distort(v: Vector2, mx: Float, my: Float): Vector2 {
        val dist = v.dst(mx, my)
        if (dist < 10) return v
        val drag = 100 / (1 + sqr(sqr(2 - dist / 100)))
        return Vector2(v.x + drag * (v.x - mx) / dist, v.y + drag * (v.y - my) / dist)
    }

v ist der Ausgangspunkt, mx und my die Mauskoordinaten. Zuerst berechne ich aus dem Abstand zum Mauszeiger den Betrag der Verschiebung (“drag”) und dann verschiebe ich den Punkt um diesen Betrag weg vom Mauszeiger.

Die verwendete Funktion hat diesen Verlauf: https://www.wolframalpha.com/input/?i=y+%3D+1%2F(1+%2B+(x-2)^4)

Ja, man kann jetzt reisen. Die nötigen Resourcen hängen natürlich von der Länge des Sprungs, von der Ausstattung des Schiffs, sowie Anzahl und Spezies der Crew ab. Das braucht sicher noch einiges Finetuning.

Währenddessen füllt sich mein Backlog mit den vielen kleinen Dingen, die ich erst mal in den Skat gedrückt habe.

Der weitere Plan sieht vor:

  • mehr Resourcen, Blueprints und Rezepte
  • realistischer Generator mit Seed
  • Forschungsbaum
  • Ereignisse, inklusive rudimentärer Story-Line
  • Strukturen innerhalb von Systemen (Ruinen, Handelsstationen, Schiffswracks u.s.w)
  • Erkundung dieser Strukturen
  • Stats / History, Hilfe
  • Sound

Fisheye und Zoom mit Mausrad schließen sich ja nicht gegenseitig aus (siehe Beispiel das ich vor 5 Jahren mal gedengelt hatte) ;-). Aber leichter bedienbar ist es sicher ohne, wenn man ohne auskommt…