Tagebuch: Industry City

Schaut btw mittlerweile so aus:

Ja. Sieht imho aus wie ein gutes Model für Minecraft :stuck_out_tongue:.

Keine Ahnung. Das hab ich noch nicht ausprobiert. Aber Ich würde vermuten, dass es noch im Rahmen sein dürfte. Ob ich den Dino jemals aufm Smartphone in einem Spiel verwende ist auch noch komplett unklar. Wie gesagt: eigentlich ist es eine Spielerei. Ich wollte ja nur mal ausprobieren, was ich im Video-tutorial gesehen hab. Und als ich etwas Tier-ähnliches hatte, wollte ich wissen wie weit ich komme ^^.

Oh mann, auf die Form vom Kopf bin ich gerade irgendwie besonders Stolz:

Als ich das angefangen hab, dachte ich „Das wird eh nix“. Und dann zoom ich weg und sehe das :slight_smile:.

So. Bin schon seit Sonntag dabei das Speichersystem umzuschreiben und hab es soweit auch ganz gut fertig. Wie schon erwähnt, konnte ich einiges raushauen, was die Sachen nur unnötig kompliziert gemacht hat. Zudem hab ich die Services jetzt weiter isoliert. Damit sind die besser zu testen.

Vorher waren meine Services als ScriptableObjects realisiert - was diverse Probleme verursacht hat. Ohne jetzt ins Detail gehen zu wollen hier ein Beispiel: Es lässt sich nicht wirklich gut mit Interfaces arbeiten - die ich aber brauche (wegen dem Mocken).

Von nun an sind die ScriptableObjects keine Services mehr - sondern eher … Provider (Wobei ich glaube, dass Gateway hier vom Namen her besser zutreffen dürfte :-/. Egal). Oder ums mal anders zu beschreiben: ich hab mich von Sprint Boot und Rest-Controller inspierieren lassen.

Wenn ich nun Interfaces nutzen möchte, dann kann ich das wunderbar innerhalb des ScriptableObjects tun - da ich dann auf einer programmatischen Ebene bin (vorher war mir das Unity-Framework im Weg. Was ich somit aber sehr gut gelöst bekommen hab :slight_smile:).

Ich hab gerade auf Udemy einen Kurs gefunden, der sehr interessant zu sein scheint. Endlich mal einer der mit fortgeschrittenen Techniken ein Spiel (RPG) umsetzt. Und dabei wurde mir klar, was mich an Industry City irgendwie schon die ganze Zeit stört:

Das mit Untiy umzusetzen ist irgendwie … unnötig. Es ist konzeptionell mehr geplant wie ein „Durch Menüs klicken“-Spiel. Könnte man so auch relativ einfach in React oder so entwickeln.

Das was ich sehe, wie die gerade das RPG angehen, ließ mich schon etwas über Industry City nachdenken. Unter anderem, ob ich es nochmal von komplett vorne anfange. Es in einer wirklichen 3D-Welt spielen zu lasse. Das würde mir auch viel besser gefallen.

Zudem könnte ich dann vermutlich auch viel früher mal einen Stand veröffentlichen. Momentan baue ich ausschließliche MENÜS!

Ein Menü hier, ein Menü da. Aber ich hab noch nichts programmiert was etwas mit dem Spiel an sich zu tun hätte!

Der finale Punkt ist aber: ich programmiere ein Spiel was ich selber vermutlich nicht spielen bzw. downloaden würde.


Meine weitere Vorgehensweise:
Ich habe alles in Git. Ich werde den master-branch umbenennen und einen neuen basierend auf meinem initialen commit erstellen. Parallel werde ich das Video-tutorial versuchen durchzuarbeiten. Mich interessiert, wie der Profi sein Projekt aufbaut und strukturiert.

Wenn man den aktuellen Stand von Industry City anschaut, dann fliegt immerhin theoretisch nicht sonderlich viel weg. Ich mein, was hab ich denn bisher schon:

  • Hauptmenü
  • Einstellungen
  • Ein Dashboard was dummy-daten
  • Ein paar 3D-Modelle (die ich aber behalten und möglicherweise wiederverwenden könnte :stuck_out_tongue:).

Also Spieltechnisch gesehen, hab ich eigentlich … nichts. Und in das Nichts hab ich schon verdammt viel Zeit investiert und würde noch viel mehr Zeit rein investieren.

Nachdem ich jetzt schon einige Stunden an Videomaterial gesehen hab, bin ich erneut in die Projektplanungsphase von IC (industry city) eingestiegen. Diesmal mit einer etwas anderen Technik.

Die im Video arbeiten mit einem Prototypen was ich so überhaupt gar nicht gemacht hab. Anhand von diesem werden Enstprechend Ideen erstellt und kreiert. Deswegen hab ich auch ein komplett neues Projekt gestartet für Industry City. Neues Repo, neues Kanban-board und neues Design-Dokument.

Da ich Industry City gerne in einer “wirklichen” 3D-Welt spielen lassen möchte (und nicht in verkackten Menüs!!!) musste ich mein Grundkonzept ziemlich stark überdenken und überarbeiten.

Diesmal aber wirklich mit Hinblick auf MVP und das ich möglichst schnell einen ersten spielbaren Stand raushauen kann.

Das was ich euch schonmal zeigen kann ist mein Prototyp - mit dem ich gerade arbeite:

Also das ist schon ganz cool was ich erreicht habe heute. Im Kurs habe ich gelernt, wie man mit Raycasts arbeitet. Kurze Erklärung für die, die es nicht kennen (so wie ich noch vor kurzem): Es ist im Prinzip wie Röntgen. Stellt euch vor das Skelett ist ein definierter Layer und der Röntgenstrahl ist mein Raycast. Da wo er auftritt bekomme ich eine „Reflektion“ - womit ich dann das Objekt habe.

Bei meinem Prototypen wird der Strahl von meinen Gebäuden Reflektiert. Klicke ich jetzt auf eines dann lasse ich mir in der Konsole den Typ des Gebäudes ausgeben. Schön zu sehen, dass das funktioniert :slight_smile:.

Hab gerade in der Mittagspause mal angefangen das UI drüber zu packen:

Soweit ist der Prototyp aktuell

Ich glaube mein neuer Ansatz ist verdammt gut. Im Gegensatz zu Feature Runner hab ich wirklich ein Ziel auf das ich hinarbeiten möchte und mit diesem MVP/Prototyp-Ansatz geht das auch sehr Agil und Straight Forward.

Ich überlege mir halt: was brauche ich als nächstes um mein Ziel zu erreichen, was hilft mir dabei. Was nice-to-have ist kommt ins Backlog. Was ich wirklich brauche kommt in den Milestone. Damit hab ich die Chance mir doch relativ viel Gedanken zu allem zu machen.

Unter anderem z.B. ob das Spiel Rundenbasiert oder Echtzeit sein soll. Am Anfang wird es auf jeden Fall Rundenbasiert sein. Warum?

  1. Ich glaube es ist einfacher einzubauen
    Das Problem mit Echtzeit wäre, dass ich dann sowas wie unterschiedliche Geschwindigkeiten und Pause anbieten müsste. Das habe ich bei Rundenbasiert nicht

  2. Halte ich es für Besser (Gerade als Mobile Game)
    Mobile Games sind für mich immer auch irgendwie Casual Games. Und dieses sollte sich imho jederzeit unterbrechen lassen können. Angenommen ich sitz auf der Couch und werde angesprochen. Dann möchte ich nicht erst auf Pause klicken müssen.

Dadurch, dass ich mittlerweile mal eine Stadt vor mir hab. Etwas mit dem man später spielen können soll ist das ganze viel greifbarer. Das ganze gibt auch nochmal extra Motivation. Was vor allem dafür sorgt, dass ich mir auch über den Tag immer mal wieder Gedanken zum Spiel mache. Zumal ich den (Fast aktuellen) Stand ja auch aufm Handy hab.

Perfekt ist mein Ansatz bestimmt noch nicht - aber ich glaub der Weg ist der richtige(re) :slight_smile:.

So. Und um das mal up-2-date zu halten. Mein aktuellster Stand vom Prototypen schaut bisher so aus:

In der Mittagspause heute hab ich angefangen, das Versions-label einzubauen. Ist soweit auch fertig - ich möchte nur noch einen kleinen Test heute abend dazu schreiben :slight_smile:.

Heute abend bin ich einen guten Schritt weiter gekommen. Die Aktionsleiste (das große Ding unten) zeigt nun Abhängig vom ausgewählten Gebäude auch passende AktionsButtons an. Einen Unterschied gibt es aber im wesentlichen nur zwischen Häusern und allen anderen Gebäude. Denn die Gebäude die der Spieler bauen wird (Shop, Produktion und Fabrik) haben alle die gleichen Aktionen.

Sollte sich das dochmal ändern - kein Problem. Das ganze unterstützt schon jetzt eigene Sets von Aktionen pro Gebäudetyp.

So. Ich würde mein Spiel jetzt aus der „Prototypen-phase“ rauslassen und von jetzt ab in Richtung MVP gehen. Die Phase Prototyp würde ich somit zum rumspielen rumspielen frei geben.

Es geht noch nicht wirklich viel! Eigentlich könnt Ihr nur Gebäude durch andere Gebäude austauschen. Aber möglicherweise habt Ihr schon Ideen wie sich das Spiel weiterentwickeln könnte. Und natürlich auch generell: was denkt über den aktuellen Prototyp?

Auch wenn man vermutlich noch nicht viel dazu sagen kann - so bin ich doch um jedes Feedback froh :slight_smile:. Deswegen wollte ich so früh wie Möglich eine erste Version veröffentlichen.

Also dann wünsche ich viel Spaß mit dem Prototypen:

https://play.google.com/store/apps/details?id=de.jfruit.industrycity

Was mir beim rumspielen mit dem Prototyp aufgefallen ist: man erkennt nicht wirklich was man ausgewählt hat. Deswegen hab ich heute mal eingebaut, dass die Selektion nun gut sichtbar ist. Dabei erhebt sich das Gebäude in die Luft und sinkt bis fast auf den Boden um dann wieder nach oben zu steigen. Das geht solange bis etwas anderes ausgewählt wurde. Für diejenigen unter euch die ein schlechtes Vorstellungsvermögen haben hab ich aber auch ein Video aufgenommen:

Heute hab ich “Geld” umgesetzt. Es ist jetzt ein Teil des Spiels. Und somit kennt das Spiel auch persistierung (da ich den Betrag ja auch irgendwie speichern muss ^^). Gebäude-Upgrades kosten von nun an etwas und das verkaufen von Gebäuden gibt den Original-Betrag zurück … zumindest fürs erste.

Viele haben sich den Prototypen bisher vermutlich nicht angesehen (2 Klicks auf den Link - davon war afair einer ich) - aber vielleicht wirds ja noch.

Für meine nächste Version (welche Geld und Gebäudetokens ins Spiel bringt) fehlt nur noch eine geplante Aufgabe. Dann sollte Version 0.1.1 fertig sein.

Vorab (für alle meine … 1 Tester :smiley:): Mir ist bekannt, dass man sich mit der neuen Version Geld und Gebäude-tokens „ercheaten“ können wird. Das liegt im wesentlichen daran, dass nur das Geld und die Tokens bisher persistiert werden. Dementsprechend hab ich schon einen Task auf meinem Board für 0.1.2 der entsprechend dafür sorgen wird, dass der Spielstand resettet wird :wink: . Und ja: das bedeutet auch, dass Version 0.1.2 eben auch die Persistierung der Stadt als Ziel hat.

Hatte gestern nach Industry City bock mal wieder was mit 3D zu machen und hab das dann heute morgen fort gesetzt. Hat zwar nix direkt mit dem Spiel zu tun - poste es aber dennoch hier:

Ziel der Übung war es diese Waffen zu modellieren - aber so, dass diese in einem Mobile-Game verwendet werden können. Laut Unity3D sollte ein Modell dafür nicht mehr als 1,5K Polygone haben. Beide sind darunter. Der Hammer hat etwas um die 1000 und der Stab 751. Somit bin ich gut innerhalb des empfohlenen Rahmen :slight_smile:.

So. Version 0.1.1 ist im Store eingereicht :slight_smile:. Ich glaube nicht, dass es lange dauern wird, bis man diese auch downloaden kann (denke in 30-60min sollte diese freigeschalten sein).

Hier nochmal der Link zum Play-Store: https://play.google.com/store/apps/details?id=de.jfruit.industrycity

So. Ich hab immerhin heute (und vor ein paar Tagen) etwas weiter am Spiel gearbeitet. Allerdings hauptsächlich erstmal UI-Verbesserungen. Also eher Kleinigkeiten. Aber bietet sich halt an für unter der Woche. Ich spiele schon wieder mit dem Gedanken es auch für heute gut sein zu lassen. Zumindest werde ich vermutlich meine Hauptaufgabe für die nächste Version erst am Wochenende starten - und dabei geht es darum die Stadt zu speichern. Das möchte ich nach Möglichkeit mit einem ausgeruhten Kopf ausarbeiten.

Bin seit dem WE dran, dass die Karte persistiert werden kann. Mir war klar, dass es nicht ganz ohne sein wird - weswegen es auch eine eigene Version ist. Immerhin hab ich mittlerweile schon einiges angepasst:

  • Aufteilung in Assemblies
    Services & Co landen jetzt in einem “Core”-Assemly. Damit ist der Code getrennt von dem, welchen ich direkt in Untiy3D verwende (dabei geht es mehr um so Sachen wie Komponenten, Assets usw.)

  • Die Straße zählt auch als "Gebäude"
    Allerdings werden für diese keine Aktionsbuttons auftauchen. Das hat momentan (noch) mehr interne Gründe warum diese als Gebäude gehandelt wird. Dafür hat es aber den netten Nebeneffekt, dass man die aktuelle Selektion durch einen Klick auf eine Straße aufheben kann. Nebenbei gesagt war das ein offener Task vom Backlog gewesen - der es ohne die Story wohl nicht in das MVP gepackt hätte.

  • Native Persistierung
    Die Map wird auf eine andere Art und Weise persistiert wie die Account-Daten. Da diese nicht direkt in einem ScriptableObject landen funktioniert hier der Mechanismus etwas anders.

  • Service
    Der Service der für die ganze Handhabe zuständig ist ist schon sehr weit. Das Datenformat zum speichern unterscheidet sich von dem, welches das Spiel nutzen wird um die Stadt aufzubauen. Der Service kann das übersetzen, kümmert sich ums Speichern und Laden.

  • Tests
    Natürlich versuche ich vieles mit Tests abzusichern. Alleine der Service zum laden/speichern/“transformieren” der Stadtdaten hat momentan 13 Tests (Tendenz: steigend).

Wie ihr seht: das ist alles erstmal Zeug was im Hintergrund passiert. Die Stadt an sich weiß davon noch überhaupt nichts und ich muss dementsprechend auch noch einiges umbauen/neu bauen. So brauche ich z.B. einen Map-Generator, welcher die Stadt anhand der gegebenen Daten aufbaut.


Desweiteren hab ich noch einen Bug am Wochenende gefunden, welchen ich aber noch nicht angegangen bin. Problem: wenn man ein Gebäude (ver)kaufen möchte, dann erscheint ein Dialog. Wenn man einen Button klicken möchte, sich dahinter aber ein Gebäude befindet, dann wird dieses ausgewählt und der Dialog verschwindet. Der Button hat aber den Klick nicht genommen.

So, ich hab heute mal wieder etwas weiter gemacht und IC schaut nun so aus:

Rückschritt? Neeeein :slight_smile:. Die Map kann jetzt anhand einer Speicherdatei geladen werden (einen Test gibt es dafür auch schon). Nur leider hab ich noch keine speichern-Funktion ^^.

Außerdem gibt es eine schöne Neuerung. Zwar nicht im Spiel aber in meinen Tools. Sowohl Unity3D als auch Rider haben nette Updates erfahren. Was Rider neues hat, hab ich im Freu-Thread verlinkt.

Und Unity3D hat endlich Nested-Prefabs geliefert :slight_smile: + eine bessere Möglichkeit solche zu bearbeiten.

Ein Prefab könnt Ihr euch als „Blaupause“ vorstellen. Wenn ich ein Objekt in der Szene hab, das mir gefällt, dann kann ich davon ein Prefab erstellen (z.b. könnte ein Button). Von diesem Prefab kann ich dann beliebig viele Instanzen erstellen. Oder es an Komponenten geben, die dann Objekte basierend auf dem Prefab erstellen (anderes Beispiel: alle meine Gebäude sind als Prefab hinterlegt. Somit braucht mein Generator nur zu wissen, welches Prefab er instanzieren muss. Möchte ich später den Würfel durch ein 3D-Modell austauschen, dann muss ich nur das Prefab anpassen. Alles andere wird weiter funktionieren wie gehabt).

Ok, ich bin nicht zufrieden mit der Datenstruktur, wie ich die Map ablege. Momentan schaut das ganze so aus, dass es als 2D-Array gespeichert wird und beim auslesen in ein anderes Datenformat konvertiert wird. Dabei wird dann auch die Position im 2D-Array in Welt-Koordinaten umgerechnet.

Für den ersten Wurf fand ich auch, dass es Sinn gemacht hat. Ein 2D-Array lässt sich sehr gut auf 2D-Koordinaten mappen. Zudem sollte der Zugriff auf ein 2D-Array O(1) sein, was natürlich super ist, wenn man einzelne Datensätze updaten möchte.

Nachteil: Ich muss alles doppelt pflegen. Und derzeit ist noch nicht klar, wie groß die Stadt überhaupt mal sein wird. Möglicherweise könnte ich mit O(n) Zugriffen sehr gut leben. Aber ich dachte mir, ich wills richtig machen und hab mal ein paar Überlegungen dazu gemacht. Dabei dachte ich mal daran, wie Datenbanken arbeiten und dann kam mir relativ schnell die SortedList in den Sinn. Nach kurzem überlegen hab ich mich gefragt, wie ich das ernsthaft in betracht ziehen konnte. Es bietet absolut keinen Vorteil gegenüber der List, sondern erhöht nur die Komplexität, da ich ja alles nochmal sortieren kann.

Danach hab ich mir mal angeschaut, wie teuer ein Dictionary wäre. Auch wenn ich mir die Implementierung jetzt nicht angesehen hab - laut Internet ist der Zugriff per key immer O(1) und das einfügen von Elementen am Ende auch O(1). Also meine erwarteten Szenarien würden sich allem im Rahmen O(1) befinden. Somit hätte ich die gleichen Vorteile vom 2D-Array - aber die Implementierung wäre erheblich einfacher!

Dementsprechend werde ich das als nächstes mal anpassen :slight_smile:.