Entwicklertagebuch – Der Weg zum eigenen Switch-Spiel


BadToxic Discord-Server | GameMaster Discord-Server | BadToxic auf Twitter
BadToxic auf Instagram | BadToxics Entwickler-Instagram | BadToxic auf YouTube
##navigation## ##header## ##abschnitt:2016##
##titel:Teil 1: Willkommen in der Welt der Videospielentwicklung!## Teil 1: Willkommen in der Welt der Videospielentwicklung!
Heute starten wir eine neue Rubrik, die für etwas Abwechslung sorgen dürfte – ein Entwicklungstagebuch zu einem Spiel. Ich (BadToxic) habe seit kurzem einen Nintendo-Entwickler-Rang und damit begonnen, ein Spiel zu entwickeln, welches ich für Nintendos neue Heimkonsole Nintendo Switch veröffentlichen möchte. Tatsächlich habe ich sogar auf der Basis einer 3DS-Anwendung begonnen, sodass auch eine Version für den 3DS denkbar wäre. Da so ein Entwicklungsprozess allerdings sehr viel Zeit kostet und es somit noch lange bis zum fertigen Spiel dauern wird, peile ich mit der Nintendo Switch die neuere Generation als primäres Ziel an.

In diesem Tagebuch möchte ich euch regelmäßig über den Fortschritt berichten und auch mal etwas zeigen. Hier dürft ihr die andere Seite etwas kennenlernen – für alle die gerne mehr darüber wissen möchten, wie so ein Videospiel überhaupt entsteht. Ich werde auch auf Prozesse neben der Entwicklung eingehen: Wie wird man überhaupt Nintendo Entwickler? Was muss man können? Vielleicht strebt der eine oder andere unter euch ebenfalls ein Entwickler-Dasein an. Ich habe vor, das Ganze interaktiv zu gestalten. Kommentare, Fragen und Feedback eurerseits sind ausdrücklich erwünscht! Ab und zu werde ich euch nach eurer Meinung fragen, sodass ihr in Form von kleinen Umfragen die Entwicklungsrichtung mitgestalten könnt, wenn ihr Lust dazu habt.

Vorweg möchte ich dazu sagen, dass ich dies nebenberuflich tue und daher nicht regelmäßig an diesem Projekt arbeiten kann. Außerdem gehe ich dieses gewaltige Vorhaben alleine an. Wer die teilweise endlos lang erscheinenden Namenslisten aus den Credits mancher Spiele kennt, kann sich sicher vorstellen, dass dies eine große Herausforderung ist, sehr zeitintensiv ausfällt und Erfahrungen auf den verschiedensten medialen Feldern voraussetzt.

Das soll es auch schon für die Eröffnung gewesen sein. Jetzt würde mich interessieren: Was haltet ihr von dieser neuen Rubrik? Seid ihr gespannt was daraus wird und würdet gerne mitwirken? Oder lässt euch das kalt und ihr interessiert euch höchstens für das Ergebnis? Übrigens: Auch wenn diese Rubrik sich „Tagebuch“ nennt, dürft ihr leider nicht jeden Tag Neuigkeiten erwarten. Informationen wird es in unregelmäßigen Abständen geben und all das hängt von dem Interesse ab, das ihr hier zeigt. Ich freue mich auf eure Unterstützung und hoffe, dass ich euch damit ein wenig unterhalten kann.

PS: Das Tagebuch wird ebenfalls auf Englisch geführt, um einen größeren Personenkreis ansprechen zu können. ##neue_seite## ##abschnitt:2017##
##titel:Teil 2: Am Anfang stand die Idee## Teil 2: Am Anfang stand die Idee
Heute möchte ich euch erzählen, um was für ein Spiel es sich bei meinem Projekt überhaupt handeln soll. Aber bitte nicht alles weiter verraten, es soll ja niemand alle Ideen stehlen. 😉

Ich selbst glaube, dass die Idee großes Potenzial hat und viele Gamer ansprechen dürfte. Als Arbeitstitel nutze ich Namen „Game Master“, der durchaus passend sein dürfte. Denn wie der Name bereits vermuten lässt, wird es Ziel sein, Spiele zu meistern oder besser gesagt Meister der Spiele zu werden. Stellt euch ein Spiel vor, welches sich mit Pokémon vergleichen lässt, bei dem ihr über eine Overworld Map lauft und in verschiedenen Gebieten verschiedene… naja, nicht Pokémon, sondern Minispiele finden könnt! Ja, richtig gelesen, ihr werdet von einem Spiel „angegriffen“ und ihr kämpft gegen dieses, indem ihr es spielt. Je nachdem wie gut ihr dies tut, habt ihr die Chance es „einzufangen“. Ein erstes Ziel ist also: Gotta catch’em all!

Diese Spiele könnt ihr natürlich auch weiterentwickeln. Anfangs sind sie womöglich nur schwarz-weiß oder in Game Boy-Qualität – langsam, träge, „schwer“. Doch je weiter ihr in diesem Spiel voranschreitet, umso mehr Statuspunkte bekommt ihr bzw. das Spiel, um diese auf die verschiedenen „Fähigkeiten“ des Spiels zu verteilen. Diese Fähigkeiten sind dann zum Beispiel Grafik, Audio, Schwierigkeit, KI, usw. So entwickelt ihr vielleicht ein 80er Jahre Pong zu einem 3D-Pong mit Powerups und Partikel-Effekten.

Statt Pokébällen könnte es verschiedene Cartridges (Datenträger) geben – von klobigen Modulen über Kassetten und CDs bis zu kleinen Mikrochips. Vielleicht brauchen gewisse Spiele-Level einen bestimmten Datenträger als Minimum. Vorstellbar wäre auch, dass man man für jeden Datenträger-Typ eine geeignete Konsole braucht, um diese auch nutzen zu können. Verschiedene Kombinationen von Konsolen-Eigenschaften sind denkbar. Etwa eine portable Konsole, die nur kleine Module abspielen kann, welche es aber auch als eine stationäre Variante gibt, die dafür schon zusätzlich Medien einer neueren Generation nutzen kann. Konsolen kann man dann finden, gewinnen oder kaufen. Es gibt wohl viele denkbare Möglichkeiten.

Um dem ganzen noch eins oben drauf zu setzen und es ein bisschen in die Realität zurückzuholen, würde ich die Welt dieser Geschehnisse in die virtuelle Realität versetzen. Man bewegt sich also bereits in einer digitalen Welt: Ein Forschungsprojekt für eine künstlichen Intelligenz, welche auf neuronalen Netzen basiert und kreiert wurde, um eigenständig das perfekte Spiel zu schaffen, ist schiefgelaufen. Die erschaffene KI hat alle Ergebnisse und Daten des Forschungstraktes verschlüsselt und somit „entführt“. Sie will diese erst wieder frei geben, wenn jemand die von ihr erschaffene Spiele-Welt bezwingt. Dadurch hat sie einen, ihrer Ansicht nach, angemessenen Ansporn geschaffen, um ihr Spiel zu spielen, und möchte die Gelegenheit nutzen durch den Spieler noch mehr zu lernen und das Spiel weiter zu verbessern. Die Story greift also viele gesellschaftskritische Themen der aktuellen Generation auf (VR, „Daten-Geiselnahme“ durch Verschlüsselung, selbständig denkende und handelnde KIs, etc.).

Das lässt zwar noch viel offen, dürfte aber einen guten Eindruck vom Konzept vermitteln. Jetzt bin ich sehr gespannt, was ihr davon haltet.

Ihr möchtet die Auszüge aus dem Leben eines Entwicklers lieber in englischer Sprache lesen? Unter diesem Link findet ihr die englische Version dieses Tagebucheintrags! ##neue_seite##
##titel:Teil 3: Die Voraussetzungen## Teil 3: Die Voraussetzungen
Was ist eigentlich nötig, um ein Videospiel zu erschaffen? Wie kann ich eins für eine Nintendo-Konsole entwickeln? Wer darf das? Wenn ihr euch solche Fragen stellt, ist der heutige Tagebucheintrag für euch genau richtig, denn dieses Mal möchte ich auf diese ersten Hürden und Schritte eines Spieleentwicklers eingehen.

Die Zeiten ändern sich – früher war es noch deutlich schwerer ein Spiel zu erschaffen. Die verfügbaren Werkzeuge waren rar und forderten jede Menge Grundwissen in der Programmierung. Heute gibt es jede Menge Programme zum Erstellen von Spielen, die damit beworben werden, dass keine Programmierkenntnisse nötig seien und alles kinderleicht ist. Und das ist auch wirklich so! Schnell hat man als Neuling nach Anleitung via Drag ’n’ Drop ein eigenes kleines Minispiel gebastelt, doch kommt man hier eventuell schnell an seine Grenzen beziehungsweise an die der Software. Eine solche Software ist der GameMaker von yoyogames, den ich euch an dieser Stelle nicht vorenthalten möchte, da ich selbst lange damit gearbeitet habe und der Meinung bin, dass sich diese IDE (Integrierte Entwicklungsumgebung) prima zum Lernen anbietet und man damit auch schon ordentliche plattformübergreifende Anwendungen produzieren kann.


Über den GameMaker könnte ich sehr viel berichten und lehren, aber so plattformübergreifend er auch ist, den 3DS oder die Switch unterstützt er (noch) nicht. Deswegen möchte ich an dieser Stelle lieber auf die IDE eingehen, die ich jetzt verwende und euch optional einen Link zu einem älteren Artikel von mir zum Thema GameMaker verlinken.

Jetzt arbeite ich mit Unity, ebenfalls eine Sofware zum Entwickeln plattformübergreifender Spiele. Lange Zeit haben mich die Kosten für Unity abgeschreckt, doch mittlerweile hat sich das Preismodell geändert, so dass man erst zahlen muss, wenn man mit dieser Software einen gewissen Ertrag im Jahr erzielt hat. Auch die Unterstützung für den 3DS ist noch ganz frisch. Vielleicht habt ihr mal die Sammlung an Logos von Firmen gesehen, die an einer Nintendo Switch-Entwicklung beteiligt sind – auch hier ist das Logo von Unity zu sehen. Tatsächlich entwickle ich nun also gezielt für den 3DS, möchte aber später die Switch als primäres Ziel ansehen. Es ist vorteilhaft, das Spiel für die schwächere Plattform und kleinere Auflösung zu optimieren, da eine Anpassung in die andere Richtung durchaus einfacher ist. Wenn alles gut läuft, findet das Spiel seinen Weg auf beide Konsolen.


Unity ist ein Programm, das jede Menge Funktionen und Tools anbietet, um das Erstellen eines Spiels stark zu vereinfachen. Es gibt einen 2D- und 3D-Editor, in dem zum Beispiel Level und Welten gebastelt werden können. Außerdem bietet es eine eigene leistungsfähige Engine und hoch entwickelte Bibliotheken zum Programmieren. Zum Programmieren stehen dem Entwickler die Programmiersprachen C# und Javascript zur Auswahl. Ich möchte gar nicht erst darüber spekulieren, welche Sprachen sich am besten für die Spieleentwicklung eignen. Es gibt sogar Sprachen, die eigens für Spiele erfunden wurden. Man sollte auf jeden Fall keine Angst vor höheren Sprachen haben und nicht anhand der Sprache die IDE wählen, sondern höchstens andersherum. Ein guter Programmierer muss eine Sprache nicht beherrschen, um sie zu benutzen. Im Internet kann heute jeder genügend Dokumentationen und Tutorials finden, mit denen er etwas zusammenschustern kann. Wenn man das eine Weile macht, lernt man auch die Sprache besser kennen. Ein Tipp für diejenigen, die schon etwas können: Versteift euch nicht darauf und seid bereit, etwas neues zu erlernen! Die, die ganz neu auf dem Gebiet sind sollten sich auch nicht abschrecken lassen. Auch für Unity gibt es viele gute Tutorials. Ich empfehle auf jeden Fall, nicht gleich das große Traumprojekt anzufangen, sondern erst ein paar andere kleine Projekte – simple Spiele nachprogrammieren zum Beispiel.

Doch wer sich nun freudig die kostenlose Version von Unity herunterlädt, sollte wissen, dass man damit nicht einfach was für Nintendo-Konsolen programmieren kann. Nein, man bekommt von Nintendo jeweils eine spezielle Version von Unity inklusive der benötigten SDK (Software Development Kit). Tatsächlich ist es inzwischen sehr leicht geworden, dies zu bekommen, während es bis vor kurzem noch etliche Anforderungen gab, die nicht jeder einfach so erfüllen konnte. Dazu gehörte beispielsweise der Nachweis eines bereits „erfolgreich“ publizierten Videospiels, bevor man sich überhaupt als Entwickler bewerben durfte. Heute darf sich jeder einen Entwickler-Account bei Nintendo zulegen, der bestimmten AGBs usw. zustimmt. Bestimmt braucht man für einige Angelegenheiten einen gesetzlichen Vormund, wenn man selbst noch nicht alt genug ist, aber das trifft theoretisch auf alles zu, mit dem man Geld verdienen kann. Als wirkliche harte Voraussetzung muss ich aber folgendes nennen: Man muss der englischen Sprache mächtig sein. Alternativ kommt man sicher auch mit Japanisch aus, aber man kann leider nicht für alle Verträge, Anleitungen und Dokumentationen deutsche Versionen erwarten. Wer sich das ganze etwas genauer anschauen möchte, kann dies hier tun.

Sicher fragen sich schon einige von euch: Wie bekommt man so ein Spiel dann überhaupt auf das Gerät? Klar, einfach auf die SD Karte ziehen und loslegen kann nicht sein. Dann gäbe es ja Unmengen an Raubkopien im Internet, die jeder mit Leichtigkeit nutzen könnte. Nein, es ist dazu Hardware nötig, die ihr ebenfalls auf obiger Seite finden und bestellen könnt. Hier gibt es sehr viel Auswahl an verschiedenen Teilen, die auch nicht ganz günstig sind. Hier überlegt sich der Hobby-Programmierer erst noch mal genauer, was er da eigentlich vorhat. Auch wenn euch diese Modelle und Preise jetzt vielleicht ganz besonders interessieren, darüber werde ich außerhalb des Nintendo-Entwicklerportals nicht zu viel verraten. Man sollte sich allerdings für eine vernünftige Lösung nicht von einem vierstelligen Betrag abschrecken lassen. Vielleicht kennt ihr aber auch jemanden, der bereits ein wichtiges Gerät besitzt und ihr kommt mit weniger aus. Natürlich ist es rein technisch auch komplett ohne zusätzliche Gerätschaften möglich, einen bereits vorhandenen 3DS so zu manipulieren, dass er direkt zum Abspielen der Eigenkreationen taugt. Darüber möchte ich aber ebenfalls nicht viel sagen, da diese Vorgänge, wie ihr euch vielleicht denken könnt, mit Aktionen verbunden sind, die auch das illegale Verwenden von Fremdsoftware ermöglichen würden. Es sei außerdem noch anzumerken, dass man als offizieller Entwickler jeglicher Art von „Homebrew“ entsagt, also nichts mehr in der Hobby-Entwickler-Szene für die jeweilige Konsole entwickeln oder veröffentlichen darf und schon gar nicht mit dem Material, das man von Nintendo bekommen hat.

Damit möchte ich mich für heute Verabschieden. Ich hoffe ihr konntet ein paar neue Einblicke erhaschen und lasst euch von den wenigen bereits genannten Hürden nicht abschrecken! 😉

Ihr möchtet die Auszüge aus dem Leben eines Entwicklers lieber in englischer Sprache lesen? Unter diesem Link findet ihr die englische Version dieses Tagebucheintrags! ##neue_seite##
##titel:Teil 4: Die letzten Vorbereitungen## Teil 4: Die letzten Vorbereitungen
Wir haben eine Spielidee, wissen, dass wir diese mit Unity umsetzen möchten und woher wir alles Nötige bekommen. Doch bevor wir nun richtig loslegen, sollten wir noch ein paar Vorbereitungen treffen. Heute möchte ich auf ein paar Dinge eingehen, die man vor dem Durchstarten abklären sollte oder könnte. Zunächst können wir auf jeden Fall die IDE Unity und das 3DS-SDK installieren, falls noch nicht geschehen. Nintendo bietet im Entwicklerportal eine Software an, mit der alle benötigten Pakete heruntergeladen und aktualisiert werden können. Nicht-Nintendo-Entwickler können Unity direkt von dieser Homepage beziehen. So, was brauchen wir noch?

Versionsverwaltung – git
Wie teilt man eigentlich ein Projekt auf mehrere Leute auf, wenn diese teilweise an den gleichen Dingen und zudem möglichst unabhängig voneinander arbeiten müssen? Diese und etliche weitere Fragen beantwortet ein Werkzeug zur (verteilten) Versionsverwaltung wie git. Dank git können mehrere Personen sogar Text in ein und derselben Datei gleichzeitig bearbeiten, ohne dass es dann zu Problemen kommt, wenn die verschiedenen Versionen wieder zusammengeführt werden. Solange es keine Konflikte gibt, wie etwa das Ändern ein und derselben Zeile, übernimmt git dies völlig automatisch. Dieses Werkzeug ermöglicht es außerdem, dass man seinen Code oder sein komplettes Projekt jederzeit auf einen beliebigen Zustand zurück (und auch wieder vor) setzen kann. Dazu sendet man nach einer Änderung einen Commit, sozusagen ein Checkpoint des Projekts, an den Server, auf dem git läuft.


Bildquelle: Smashing Magazine
Alleine über dieses Werkzeug kann man ganze Bücher schreiben – das Thema ist sehr komplex. Vielleicht wundert ihr euch nun, warum ich dies nutze, wenn ich doch alleine an diesem Projekt arbeite. Dafür habe ich natürlich ein paar Gründe und deswegen möchte ich euch diese im Falle eines eigenen Projektes erläutern. Die Commits, die man durchführt, werden kommentiert. So kann man später durch die History blättern und sehen, wann man was getan hat. Man kann sagen, git fungiert auch gleich noch als eine Art Tagebuch. Außerdem sichert man so regelmäßig und effizient sein Projekt auf einem anderem Rechner. Es werden nur so viele Daten gesichert, wie sich wirklich geändert haben und man muss diese nicht selbst heraussuchen oder das ganze Projekt kopieren. Sollte die Festplatte, der PC oder auch das Projekt selbst defekt sein, kann man jederzeit einen beliebigen Zustand wiederherstellen.

Zeiterfassung – TrackingTime
Eine weitere sinnvolle Hilfe ist ein Werkzeug zur Erfassung der Zeit, die man für verschiedene Teilaufgaben benötigt hat. Ich wurde schon oft gefragt, wie lange ich denn für ein bestimmtes Projekt benötigt habe und konnte nicht exakt darauf antworten. „Knapp über ein Jahr“ – und was bedeutet das nun? Vielleicht hätte ich das auch in einem Monat geschafft. Man müsste schon die Stunden wissen oder die Arbeitstage mit fester Arbeitsstunden-Zahl, um eine sinnvolle Auskunft geben zu können. Durch eine präzise Arbeitszeiterfassung habt ihr auch die Chance, den tatsächlichen Wert eures Projektes abzuschätzen. Hier hilft ein Zeiterfassungs-Werkzeug (Time-Tracker) wie TrackingTime. Bei diesem erstellt man zuerst einzelne Aufgaben, wie z.B. „Einlernen in Unity“, „Inventar“, „Titelbildschirm“, „Charakterdesign“, „Minispiel XY“. Danach kann man bequem per Tastendruck einen Timer der jeweiligen Aufgabe starten und nachdem man fertig ist oder man eine Pause macht, wieder stoppen. Die Ergebnisse werden als nach Aufgaben geordnete Liste oder in einem Kalender dargestellt. Diese Erfassung könnte man als Einzelperson auch mit einer einfachen Textdatei oder einem Blatt Papier bewältigen. Aber wieso sollte man einen kostenlosen Service, der alles leichter macht, nicht nutzen?


Werbung / Community
Wenn man bei professionellen Spieleentwicklern nachfragt oder diese von sich aus berichten, wieviel Aufwand und Kosten in den jeweiligen Bereichen der Spieleentwicklung stecken, könnte man überrascht werden. Oft hört man, dass das Programmieren den kleinsten Teil, vielleicht ca. 20% eines Projektes ausmacht. Die Verteilung variiert natürlich enorm zwischen den Spielen, denn manche legen nunmal den meisten Wert auf ihre Grafiken, Sounds und die Story. Doch fand ich es besonders verblüffend, wie enorm der Werbeanteil sein kann. Manche Entwickler – vor allem für Mobile Games – erzählen oft, dass der Aufwand für Werbemaßnahmen über 50% des Gesamtprojektes ausmacht. Damit sind nicht nur Werbespots und Anzeigen gemeint, sondern vielmehr soziale Netzwerke wie Facebook und Twitter. Dieser Anteil scheint hauptsächlich kurz vor und nach dem Release eines Spiels stattzufinden. Aber man sagt auch, man könne niemals früh genug damit anfangen.

Es gibt ebenfalls Projekte, bei denen bereits vor Entwicklungsstart damit begonnen wird. Aus diesem Grund gehe ich auch in diesem Kapitel darauf ein und zähle es zu den Vorbereitungen. Zumindest sollte man von Anfang an darüber nachdenken. Doch spätestens in der Endphase ist es unerlässlich, Werbemaßnahmen zu treffen – gerade im Angesicht der großen Mengen an Spielen, die heutzutage täglich neu in Umlauf kommen. In meinem Fall könnte man dieses Tagebuch als eine Werbemaßnahme interpretieren. Natürlich ist das nicht der Grund für die Entstehung dieser Texte, aber sicher wünsche ich mir auch, dass bereits dadurch eine kleine Interessen-Community entsteht.

Das soll es mit den Vorbereitungen fürs Erste gewesen sein, obwohl man wohl noch etliches auflisten könnte. In meinem nächsten Tagebucheintrag möchte ich endlich mit der Entwicklung beginnen!

Ihr möchtet die Auszüge aus dem Leben eines Entwicklers lieber in englischer Sprache lesen? Unter diesem Link findet ihr die englische Version dieses Tagebucheintrags! ##neue_seite##
##titel:Teil 5: Es kann losgehen## Teil 5: Es kann losgehen
Nun da alle Vorbereitungen getroffen sind, können wir endlich loslegen. Unser Vorhaben ist sehr komplex und es gibt noch unzählige offene Fragen. Menschen mit Erfahrung in umfangreichen Projekten können bestimmt bestätigen, dass eine gute Planung das A und O einer effektiven Herangehensweise ist. Auf Grundlage meiner Spielidee könnte man bereits Wochen vorher planen, wie alles genau umgesetzt werden soll. Dazu müsste man unzählige Male über alles erneut iterieren. Ich habe allerdings für mich festgestellt, dass es effizienter ist, Teile zu isolieren und sofort umzusetzen, die von einer weiteren Planung nicht abhängen. Das Problem dabei ist vor allem, solche Teile ausfindig zu machen. Erschwerend kommt noch dazu, dass Unity und C# noch immer sehr neu für mich sind und ich von den Möglichkeiten nicht viel Ahnung habe. Gerade deswegen bietet es sich an, erst mit simplen Aufgaben zu beginnen und dabei zu lernen.

Die Welt und der Spieler
Ich habe mich also entschlossen, zunächst eine Welt zu basteln, in der ich umherlaufen und durch bestimmte Aktionen ein erstes Spiel starten kann, welches ich ebenfalls zeitig skizziere. Alles soll zunächst so simpel wie möglich gehalten werden, damit nichts unnötig mehrfach gemacht werden muss.

Die Welt ist einfach nur eine Ebene (Plane). Auf dieser wird ein Charakter platziert, der gesteuert werden können soll. Dazu genügt zunächst ein Quader. Dazu noch ein Objekt, mit dem interagiert werden soll, um ein Spiel zu starten – z.B. noch ein Quader. Ich werde nicht darauf eingehen, wie die einzelnen Schritte in Unity genau funktionieren, dafür gibt es bereits genügend Tutorials im Internet und das meiste lässt sich auch so herausfinden. Nun wollen wir unseren Spieler steuern können, also weisen wir ihm ein neues Skript zu, welches sich allgemein um den Spieler kümmern soll. Spätestens jetzt kommt bereits die erste plattformabhängige Frage auf – woher weiß ich, welche Taste gerade gedrückt wird? Hier kommt unser Nintendo 3DS SDK ins Spiel. Diese bietet Funktionen an, mit denen abgefragt werden kann, ob eine Taste aktuell gedrückt ist, oder nicht.

Unity erlaubt, einzelne Code-Abschnitte so zu markieren, dass sie nur auf bestimmten Plattformen ausgeführt werden. So kann ich also festlegen, dass auf dem 3DS über Variante A nach den Tastendrücken gefragt werden soll und auf einem anderen Gerät über Variante B. Für jede Richtung, in die wir laufen können wollen, ordnen wir der entsprechenden Taste eine Geschwindigkeit für unseren Charakter in diese Richtung zu. Mit wenigen einfachen Einstellungen übernimmt Unitys Engine dann selbstständig Aufgaben wie die Kollisionsbehandlung und die Reibung. Unser Würfel fällt so nicht mehr durch den Boden und wird beim Laufen abgebremst.

Mit diesem Charakter kann ich mich identifizieren
Das Charakterdesign ist eine sehr knifflige Aufgabe. Es gehört sicher zu den Herausforderungen, die man lange zurück stellen könnte. Aber irgendwie habe ich keine Lust, beim Testen neuer Funktionalitäten ewig einen Würfel durch die Gegend zu schieben und ich bin neugierig, wie das eine oder andere in Unity funktioniert. Doch kann ich mich jetzt schon entscheiden, was für eine Art von Figur ich am Ende haben möchte?

Benutze ich eine voll in 3D modellierte Person oder lieber nostalgische Pixel-Sprites? Steuere ich überhaupt einen Menschen oder kann mein Avatar auch ein Tier, ein Fantasiewesen oder gar ein Gegenstand sein? Das Szenario meiner Spielidee lässt hier sehr viel Freiraum. In meinem Fall sollte aber vor allem der Aufwand eine wichtige Rolle spielen, mal abgesehen von meiner fehlenden Erfahrung in der 3D-Modellierung. Mit Zeichnen und der Erstellung von Sprites kenne ich mich schon deutlich besser aus. Nichtsdestotrotz möchte ich mich nicht deswegen alleine auf etwas festlegen, sondern wollte erst einmal mit der für mich simpler erscheinenden Technik experimentieren. Also habe ich mich für eine pixelige 2D Variante in Form eines kleinen Männchens entschieden, welches ich bereits für ein anderes Projekt vor vielen Jahren erstellt hatte. Es galt somit herauszufinden, wie man eine zweidimensionale Figur im dreidimensionalen Raum darstellen und animieren kann – Stichwort „Billboard“. Selbst wenn ich diese Variante später komplett ersetzen sollte, wäre der Aufwand nicht umsonst, denn diese Technik lässt sich in vielen Fällen gebrauchen. Jetzt wirkt das simple Szenario viel angenehmer, mit einer Grafik, die leicht an Paper Mario erinnert.

Die erste Interaktion
Jetzt, da wir durch unsere Welt stolzieren, möchten wir auch mit ihr interagieren können. Der Spieler soll also zu dem vorhin erwähnten zweiten Quader laufen und ihn „benutzen“ können. Über die bereits vorhandene Kollisionsbehandlung können Quader und Spieler so aufeinander abgestimmt werden, dass beim Spieler in jedem Schritt eine bestimmte Methode aufgerufen wird. „Schritt“ nenne ich vereinfacht den Abschnitt zwischen zwei Code-Durchläufen. Dies kann dem Wechsel von einem Frame (gerendertem Bild) zum nächsten entsprechen oder nach Wahl auch unabhängig davon. Im Allgemeinen sollten wir nicht davon ausgehen, dass jeder dieser Schritte gleich viel Zeit benötigt. Bei einer Bildwiederholrate von 60 FPS würde ein Schritt alle 1/60 Sekunden auftreten, bei 30FPS nur noch alle 1/30 Sekunden. Solange der Spieler neben dem Quader steht, überprüft diese Methode dann, ob eine bestimmte Taste gedrückt wird. Wird diese „Aktionstaste“ gedrückt, soll schließlich unser erstes Minispiel aufgerufen werden. Die Implementierung dieses Spiels heben wir uns allerdings für den nächsten Tagebucheintrag auf.


Der aktuelle Fortschritt: Eine Figur kann durch die Welt laufen.
An dieser Stelle wäre Feedback zu dem Informationsgehalt meiner Tagebucheinträge hilfreich. Gehe ich eurer Meinung nach zu sehr ins Detail, oder wollt ihr sogar Genaueres wissen, etwa unterstützt mit Code-Beispielen? Gerne passe ich meinen Stil euren Wünschen an, wenn diese eindeutig in eine bestimmte Richtung gehen. Bis zum nächsten Mal!

Ihr möchtet die Auszüge aus dem Leben eines Entwicklers lieber in englischer Sprache lesen? Unter diesem Link findet ihr die englische Version dieses Tagebucheintrags! ##neue_seite##
##titel:Teil 6: GONG! Das erste Minispiel## Teil 6: GONG! Das erste Minispiel
Unser Charakter ist bereit, ein erstes Minispiel zu starten. Höchste Zeit eines zu erstellen! Ziel soll es sein, ein simples Spiel zu erstellen, damit man ein funktionierendes Exemplar hat, um andere Dinge implementieren und testen zu können. Dazu gehören beispielsweise die Verbindung und der Wechsel zwischen der Welt und den Spielen. Das Minispiel selbst soll zunächst gar nicht so wichtig sein. Wenn ich überlege, welches Spiel am einfachsten umzusetzen ist, kommt mir Pong als erstes in den Sinn. Zwei Rechtecke, die sich vertikal bewegen können, und ein Ball, der zwischen diesen hin und her geschlagen wird. Es wäre natürlich nett, wenn das Spiel etwas mehr zu bieten hätte, aber dazu kommen ja später die Entwicklungsmöglichkeiten, die mein Projekt ausmachen sollen. Also ist es beschlossene Sache: Wir programmieren ein Pong! Zwar gibt es rechtlich gesehen keine Probleme damit, einen Pong-Klon zu erstellen, aber einen eigenen Namen wollen wir uns doch leisten. Wie wäre es, wenn es statt einem „Ping“ und „Pong“ richtig scheppert? Nennen wir es fürs Erste doch einfach „GONG!“.

Das Spiel selbst ist relativ leicht implementiert: Am linken und rechten Rand des Bildschirms jeweils ein Quader, der vertikal in die Länge gezogen wird, und in der Mitte ein weiterer Quader, welcher einen schön kantigen Ball repräsentiert. Starten wir eine Runde, wird der Ball in die Richtung eines Spielers beschleunigt. Welcher der beiden das ist, wird ausgelost. Der Spieler kann durch seine eigene Bewegung den Abprallwinkel des Balls bestimmen und so versuchen, dem Gegner möglichst schwere Bälle zu schicken. Gelangt der Ball hinter einen Spieler, gibt dies einen Punkt für den anderen. Wurde eine bestimmte Punktzahl erreicht, gewinnt der Spieler. Der Gegner könnte ein zweiter menschlicher Spieler sein. Dabei denke ich gleich an den Vorteil der Joy-Cons der Nintendo Switch – diese können auf zwei Spieler aufgeteilt werden. Es wäre sogar möglich, zu zweit an einem 3DS zu spielen, auch wenn das deutlich weniger bequem wäre. Mein Projekt wäre nicht das erste, welches diese Option anbietet. Da wir aber auch alleine spielen und testen wollen, erstellen wir noch eine KI (Künstliche Intelligenz), gegen die wir antreten können.

Es lebt!
Um dem Gegner Leben einzuhauchen, braucht es nicht viel. Wir erstellen eine Methode, die in jedem Frame ausgeführt wird und den CPU(Computer-gesteuert)-Schläger in die Richtung des Balls bewegt. Dabei achten wir darauf, dass diese Bewegung nicht zu unrealistisch wirkt, indem sie auch nicht schneller vonstatten geht, als würde sie ein Mensch kontrollieren. Die CPU soll ja den gleichen Regeln unterworfen sein wie ein menschlicher Spieler. Da der Ball auf der Y-Achse (also vertikal) schneller als ein Schläger bewegt werden kann, kommt diese KI schnell an ihre Grenzen und kann leicht ausgetrickst werden. Sie sollte also vorausschauend denken lernen. Um dies zu erreichen, kann die KI berechnen, wo der Ball mit seiner aktuellen Geschwindigkeit auf der Y-Achse ankommen wird. Dadurch könnte die KI allerdings optimal spielen, würde also nie verlieren. Es gilt einen Zwischenweg zu finden, so dass man gewinnen kann, aber nicht mit Leichtigkeit.

Ich habe das gelöst, indem ich die KI nur ein paar Frames vorausschauen lasse, anstatt den Aufschlagpunkt des Balles zu berechnen. Je nachdem, wie weit die CPU in die Zukunft schauen kann, spielt sie besser. Die Voraussicht bietet sich somit an, um später für verschiedene auswählbare Schwierigkeitsgrade variierbar zu sein.


Das erste Minispiel: GONG!
Mögen die Spiele beginnen!
Schon ist unser GONG! bereit für den ersten Spielspaß! Natürlich gehört noch jede Menge Logik dazu, die im Hintergrund abläuft. Nach einem erzielten Punkt wird die nächste Runde gestartet. Dazu werden Ball und Spieler auf ihre Startpositionen zurückgesetzt. Der Spieler, gegen den der Punkt gemacht wurde, bekommt in der nächsten Runde die Ball-Angabe. Zwischen den Vorgängen sollte jeweils genug Zeit sein, damit sich ein menschlicher Spieler darauf einstellen kann. Eine Taste erlaubt es, das Spiel zu pausieren. Während einer Pause werden die Bewegungen von Ball und Spielern unterbrochen. Die Bewegungsvektoren (Richtung und Geschwindigkeit) werden gesichert und den Objekten nach Beenden der Pause wieder zugeordnet. Ein Ende nach bestimmter Punktzahl oder dergleichen gibt es noch nicht.

Entwicklungspotential
GONG! bietet noch viel Potential für Features. Wie wäre es beispielsweise mit vier statt nur zwei Spielern? Statt der Wände am oberen und unteren Bildschirmrand könnte jeweils ein weiterer Spieler mitmachen. Oder wie wäre es mit einem Doppel? Auf jeder Seite zwei Spieler, die sich entweder das Spielfeld in zwei Hälften teilen oder leicht nebeneinander versetzt die komplette Vertikale ablaufen können. Dazu sollte man eventuell auch den Schwierigkeitsgrad anheben, indem wir zwei Bälle gleichzeitig nutzen oder die Geschwindigkeit des einen Balles erhöhen. Die Spieleranzahl und Schwierigkeitsstufen sollen zu den entwickelbaren Fähigkeiten gehören. Dazu kommt dann noch die Grafik. Die simplen Quader könnten durch hübsche detailreiche und farbige Formen ersetzt werden.

Ich möchte nun zunächst wieder in die „Overworld“ zurückwechseln und eine weitere sehr wichtige Grundlage des Projekts angehen – das Inventar. In dieses Inventar möchte ich dann etwas legen, womit wir GONG! starten können, statt zu dem Start-Würfel laufen zu müssen. Das Inventar wird allerdings Gegenstand meines nächsten Tagebucheintrags.

Ihr möchtet die Auszüge aus dem Leben eines Entwicklers lieber in englischer Sprache lesen? Unter diesem Link findet ihr die englische Version dieses Tagebucheintrags! ##neue_seite##
##titel:Teil 7: Das Inventar## Teil 7: Das Inventar
Eine grundlegende Mechanik in unserem Projekt ist das Mitführen und Nutzen verschiedenster Gegenstände. Um das bewerkstelligen zu können, beschäftigen wir uns im heutigen Tagebucheintrag mit einem Inventar. Wir möchten auf unserem Bildschirm eine Reihe von Ablageplätzen (Slots) sehen, in die wir unsere Gegenstände (Items) legen können. Die Items sollen via Drag’n’Drop beliebig umplatziert werden können. Außerdem soll man die Möglichkeit haben, Items miteinander zu kombinieren bzw. sie ineinander zu schachteln. Manche Items sollen durch Antippen direkt verwendet werden können.

Passend zum derzeitigen Entwicklungsstand des Projektes sollen die ersten Items darauf ausgelegt werden, unser erstes Minispiel GONG! starten zu können, welches im letzten Tagebucheintrag behandelt wurde. Dazu soll unser Spieler eine tragbare Konsole mit sich führen, auf der dann das Spiel gestartet wird. Neben der Konsole benötigen wir das Minispiel selbst, in Form eines Spielmoduls, sowie eine passende Energieversorgung in Form von Batterien. Ich stelle mir also eine Art GameBoy als die erste Konsole vor, in die man ein Spiel und zwei Batterien einlegen muss, um sie zu nutzen. Aufgrund des Copyrights nenne ich diesen Handheld „GameGuy“. Wird dieser GameGuy angetippt, soll sich ein Fenster öffnen, welches weitere Slots anbietet und ausschließlich ein Spielmodul und zwei Batterien erlaubt.

Man soll das Rad nicht neu erfinden
Nun ist es so, dass bereits viele Spiele eine Art von Inventar benutzen und dies nichts Außergewöhnliches ist. Aus diesem Grund bietet es sich an, zunächst nach einer fertigen Implementierung Ausschau zu halten, die man übernehmen kann, statt alles von Grund auf neu zu erfinden. Auch wenn man alles selbst machen möchte, ist es nicht verkehrt, sich andere Varianten anzuschauen und sich inspirieren zu lassen.

Unity bietet den sogenannten AssetStore an, in dem verschiedenste Ressourcen für die eigene Spielentwicklung erworben werden können. Hier finden wir Grafiken, Audio-Dateien, 3D-Modelle, aber auch ganze Engines und Systeme, wie beispielsweise Inventarsysteme. Zum Glück muss man nicht gleich tief in die Tasche greifen – es gibt auch eine Vielzahl kostenloser Angebote. Nach etwas Suchen und Vergleichen bin ich dann auf das Paket „Inventory Master – uGUI“ gestoßen. Dieses erlaubt, verschiedene typische Inventar-Bestandteile zu nutzen. Vorhanden sind beispielsweise ein Hauptinventar, eine Art Schnellzugriffs-Leiste und ein Crafting-System. Dazu kommt eine Datenbank, in der man neue Items anlegen kann. Auch eine Drag’n’Drop-Funktionalität ist bereits vorhanden. Dieses Paket habe ich in mein Projekt importiert und etwas genauer inspiziert. Das Inventarsystem entspricht zwar nicht ganz dem, was ich mir vorstelle, aber es konnte eine solide Grundlage bilden. Im Endeffekt habe ich zwar so viel daran verändert, dass es vielleicht leichter gegangen wäre, wenn ich es von Grund auf selbst implementiert hätte, aber so konnte ich eine Menge lernen und etliche Mechanismen abkupfern.

Die Umsetzung des Inventars hat mich vor viele Herausforderungen gestellt und war ein langatmiger Prozess. Trotzdem möchte ich nicht tiefer in die Materie gehen und lieber von den Resultaten berichten. Im Endeffekt fasst meine Item-Datenbank zum aktuellen Zeitpunkt folgende Gegenstände: Eine GameGuy-Konsole in zwei Variationen, ein Spielmodul mit GONG! und eine 1,5V Batterie des Typs AA. Jede Art Item hat ein kleines Bild der Größe 64×64 Pixel. Sie unterliegen einer gewissen Typen-Hierarchie, um später verschiedene logische Prozesse zu vereinfachen und zu abstrahieren. Man spricht hier von Vererbung. So ist der GameGuy beispielsweise eine Konsole oder gar ein Handheld, und eine AA-Batterie ein spezieller Typ von „Batterie“. Dies erleichtert bestimmte Überprüfungen. Es ist z.B. nur möglich, Batterien und Datenträger in eine (tragbare) Konsole einzulegen. Probiert man dann dies, wird weiterführend getestet, ob genau diese Art von Batterie in diese Art von Konsole passt. So kann ich logische Abfragen ebenso hierarchisch und effektiv behandeln, anstatt am Ende große unübersichtliche Listen an Möglichkeiten zu prüfen.

Danach habe ich eine GUI (ein Fenster) programmiert, welche – wie oben beschrieben – drei Slots anbietet. In einen kann man ausschließlich GameGuy-Module legen und in die beiden anderen jeweils eine AA-Batterie. Erst wenn diese Slots gefüllt sind, wird ein Start-Knopf aktiviert, mit dem das Minispiel ausgeführt werden kann.


Inventarleiste mit geöffneter GameGuy-Oberfläche samt Spiel und Batterien.
Das Spielmodul kann also eine Referenz zu einem der Minispiele bekommen und dementsprechend trägt es ein passendes Cover – siehe Bild. Die Batterien brauchen außerdem eine Ladung. Diese wird durch kleine Balken neben dem Item dargestellt. Während man die Konsole nutzt, wird diese Ladung langsam aufgebraucht. Ist mindestens eine der Batterien leer, schaltet sich die Konsole von alleine wieder ab. Eine kleine Batterieanzeige verhindert während des Spielens, dass dies unbemerkt geschieht.

Die Batterien und das Spielmodul können entweder in die Slots des Konsolen-Fensters oder direkt auf die Konsole gezogen werden. In beiden Fällen ist es natürlich Voraussetzung, dass einer der entsprechenden Slots noch frei ist. Zieht man ein Item in einen bereits belegten Slot, tauschen die beiden Items ihre Plätze. Eine Ausnahme bilden stapelbare Gegenstände, die dann in einem Slot zusammengefasst werden können, aber solche habe ich noch nicht vorgesehen. Batterien bieten sich zumindest nicht zum Stapeln an, denn dann würden ihre verschiedenen Ladungen unübersichtlich.

Damit wäre ein solides Inventarsystem geschaffen, welches uns während des gesamten Projekts als wichtiger Bestandteil begleiten wird. Im folgenden Tagebucheintrag beschäftigen wir uns mit dem Speichern und Laden unseres Fortschritts, da wir nun erste Zustandsänderungen durchführen können, die behalten werden wollen.

Ihr möchtet die Auszüge aus dem Leben eines Entwicklers lieber in englischer Sprache lesen? Unter diesem Link findet ihr die englische Version dieses Tagebucheintrags! ##neue_seite##
##titel:Teil 8: Speichern & Laden## Teil 8: Speichern & Laden
Nun, da wir erste Zustände im Spiel verändern können, wie z.B. die Positionen von Gegenständen in unserem Inventar, wird es Zeit, sich mit einem Speichersystem zu beschäftigen. Auch hier gibt es einige Aspekte, die vorher gut geplant werden sollten und andere, die man theoretisch sofort angehen kann. Man kennt verschiedenste Varianten von anderen Spielen. In manchen Spielen ist man darauf beschränkt, nur an bestimmten Orten oder nach gewissen Ereignissen speichern zu dürfen. In anderen kann man das Spiel nahezu jederzeit unterbrechen und speichern. Manche Spiele speichern ausschließlich automatisch, während man in anderen zusätzlich und in wieder anderen nur manuell speichern kann. Oft gibt es eine feste Anzahl an nutzbaren Speicherplätzen, wohingegen andere Spiele theoretisch unendlich viele Spielstände erlauben, soweit der verfügbare Speicherplatz dies zulässt. Für diese Unterschiede gibt es mehrere Gründe. Zum Einen sollte es in das Gesamtbild des Spiels passen und nicht etwa durch lange Wartezeiten die Stimmung verfälschen oder durch zu häufig mögliches Speichern den Schwierigkeitsgrad beeinflussen. Vor allem bei älterer Hardware sind es auch die technischen Aspekte, wie eine geringe Speicherkapazität, die solche Entscheidungen stark beeinflussen.

Integration in das Spiel
Ich möchte zunächst auf jeden Fall die Möglichkeit haben, auf Knopfdruck speichern zu können und sei es nur zu Testzwecken. Ob das Spiel später immer nur selbstständig speichern soll, würde ich davon abhängig machen, wie lange solch ein Prozess auf der jeweiligen Plattform benötigt. Bräuchte das Spiel nach jeder Aktion, die einen Zustand verändert, eine Sekunde oder länger, um dies zu speichern, würde es den Spielfluss zu stark beeinträchtigen. Aber vielleicht möchte ich auch, dass der Spieler sich nicht nach Belieben absichern und Fehlentscheidungen rückgängig machen kann. Das würde dafür sprechen, ihm gar keine Kontrolle über das System zu überlassen. Aber das möchte ich erst später entscheiden, um es besser auf den Rest abstimmen zu können. Alternativ habe ich die Idee, eine Art Tagebuch als Item im Inventar mit sich zu führen, mit dem man jederzeit speichern kann. Dabei sollte der Spieler so viel Freiheit haben, sich selbst dieses Gegenstandes entledigen zu können, wenn er das denn möchte.

Ich beginne also mit zwei kleinen Buttons, beschriftet mit „S“ und „L“, mit denen ich zu jeder Zeit, in der ich mich auf der Overworld-Map befinde, speichern und laden können soll. Fürs Erste möchte ich nur die Position meines Charakters und die Item-Verteilung in meinem Inventar sichern können. Als nächstes habe ich mir Gedanken über das Dateiformat gemacht, in dem ich den Spielstand speichern möchte. Es stehen sich leicht lesbare Formate wie XML oder JSON und für Menschen unlesbare, binäre Varianten gegenüber. Ersteres ist leicht zu verstehen und zu verändern – das lädt zum Cheaten ein. Zweiteres sind unlesbare Aneinanderreihungen von Einsen und Nullen, die deutlich weniger Platz beanspruchen, als ausgeschriebene Worte. Gerade auf Konsolen, bei denen der Platz eine größere Rolle spielt und man nur schwer an Speicherdateien kommt, um sie mit einem Texteditor zu durchsuchen, würde ich der Lesbarkeit keinen Gewinn anrechnen, aber dem Sparen von Speicherplatz um so mehr.

Was und wie speichern?
In bisherigen Projekten, habe ich die Spielstände immer manuell angelegt, also die Dateien mit eigenem Code beschrieben und von ihnen gelesen. Dabei muss darauf geachtet werden, dass alle Reihenfolgen immer gleich bleiben und alles vollständig ist oder damit umgegangen werden kann, wenn mal etwas fehlt. Mit Unity kann man sich das Leben einfacher machen, indem man serialisierbare Daten-Objekte erstellt, die dann automatisch gespeichert und geladen werden können (siehe Serialisierbarkeit auf Wikipedia). Zwar lassen sich diese nicht so einfach optimieren wie bei manuell angelegten Verfahren, aber sie vereinfachen und beschleunigen den Prozess erheblich. Während ich einem solchen serialisierbaren Objekt einfach eine neue Variable geben kann, die dann mitgespeichert wird, müsste ich bei einer manuellen Variante jede Variable einzeln in die Datei schreiben.

Also lege ich ein serialisierbares Objekt an, welches für jeden Wert, den ich speichern können möchte, eine Variable bekommt. So z.B. die X- und Y-Koordinaten meines Charakters, aber nicht Z, denn momentan können wir uns nur auf einer Ebene bewegen. Dies eignet sich auch bereits als Beispiel für den Optimierungs-Spielraum:

1. Ich lasse nicht benötigte Informationen wie die Z-Koordinate weg.

2. Wertebereich: Je nachdem, wie groß meine Welt werden kann, könnte man die Koordinaten begrenzen. So reichen ggf. kleinere Datentypen aus, für die dann auch weniger Platz reserviert werden muss. z.B. reicht ein sbyte für Zahlen von -128 bis +127 und short für -32,768 bis +32,767.

3. Genauigkeit: Eben genannte Datentypen können nur ganze Zahlen behalten. Ich werfe also Stellen nach dem Komma weg. Ich könnte den Wertebereich auch dehnen oder stauchen und anders „codieren“ – etwa vor dem Speichern einen Wert durch acht teilen und nach dem Laden wieder mit acht multiplizieren.

4. Alternativen suchen: Statt der Koordinaten könnte ich feste Orte nutzen, also vorgegebene Speicherpunkte, um mir so die großen Zahlen zu sparen. Ich müsste mir also nur noch den Ort merken, etwa in Form einer viel kleineren Zahl.

Zu den Koordinaten kommen noch die Items. Bei diesen ist es etwas komplizierter, da es theoretisch beliebig viele, auch mehrfach vorhandene Gegenstände und sogar Inventare geben können soll. Beispiele für weitere Inventare wären Truhen oder Items, die weitere Objekte aufnehmen können – etwa unser GameGuy. Fürs Erste beschränke ich mich auf das Inventar meines Charakters selbst, welches eine Liste von Items beliebiger Länge sein kann, und einer weiteren Ebene an Items – wie gesagt, für unseren GameGuy.

Abstraktionsebenen
Auch beim Speichern hat es Vorteile, Vererbung zu nutzen und zu abstrahieren. Zum einen gibt es Speicherdaten für das Hauptspiel selbst, wie die oben genannten. Daneben gibt es Daten für die Minispiele und darunter welche, die alle gemeinsam haben. Beispielsweise sollen alle Spiele über einen Level verfügen und folglich müssen auch Erfahrungspunkte behalten werden können. Die Haupt-Speicherdaten können dann eine Liste an Minispiele-Daten halten, so könnte man komplett alles in eine einzige Datei packen. Alternativ können die Daten der Minispiele auch in separaten Dateien gehalten werden.

Bei diesen Überlegungen kamen jedoch Fragen auf: Kann man ein Spiel mehrfach besitzen? Und wenn ja, haben diese dann ihre eigenen Spielstände? Hieße das, man könnte unendlich große Spielstände erzeugen? Diese Fragen werde ich jetzt noch nicht beantworten. Es wird schließlich davon abhängen, wie viel Speicherplatz man auf der jeweiligen Plattform zur Verfügung haben wird.

Das sollte zunächst für einen kleinen Einblick in das Speichern und Laden genügen. Im nächsten Tagebucheintrag würde ich gerne die Schnittstelle zwischen den Minispielen und der Welt ausbauen – hier fehlen noch Menüs für alle möglichen Optionen. Im Speziellen würde ich auf das Fähigkeiten-System eingehen, welches ich hier unterbringe. Damit werden unsere Minispiele sich weiterentwickeln können.

Ihr möchtet die Auszüge aus dem Leben eines Entwicklers lieber in englischer Sprache lesen? Unter diesem Link findet ihr die englische Version dieses Tagebucheintrags! ##neue_seite##
##titel:Teil 9: Fähigkeitenbaum & Menüs## Teil 9: Fähigkeitenbaum & Menüs
Heute ist es an der Zeit, die Kopplung zwischen den Minispielen und der Overworld etwas auszubauen. Es gibt wenige Spiele, die einfach schlagartig beginnen, sobald man das Gerät eingeschaltet hat – so wie es bei unserem „Gong“ aktuell der Fall ist. Für gewöhnlich wird man von einem Titelildschirm begrüßt, der den Namen oder das Logo des Spiels präsentiert und gegebenenfalls erste Optionen zur Auswahl stellt. Eventuell kommen davor noch die Logos der beteiligten Firmen oder ein kurzes Intro zum Spiel. Ich möchte nun mit dem Part beginnen, der auf dem Titeildschirm beginnt oder darauf folgt – den verschiedenen Menüs. Jedes Spiel soll zunächst die folgenden Menüpunkte bekommen können:

1. Start-Menü: Hier werden spezifische Einstellungen für das Spiel getroffen, wie die Anzahl der Spieler und der Schwierigkeitsgrad.
2. Optionen: Allgemeine Einstellungen in den Bereichen Grafik, Audio, Steuerung usw. können vorgenommen werden.
3. Entwicklung: Hier können die Fähigkeiten des Spiels weiterentwickelt werden, wie der Schwierigkeitsgrad, Grafiken und vieles mehr.
4. Errungenschaften: Unter dieser Option verbirgt sich eine Liste von freigeschalteten Achievements der Art „xxxx Punkte erreicht“ oder „Level Y bezwungen“.
5. Spiel beenden

Diese Menüs passen sich dann an das jeweilige Spiel und dessen Entwicklungsfortschritt an, während so viel wie möglich wiederverwendet werden soll. Ich erläutere das an dem Start-Menü für unser erstes Minispiel „Gong“:


Start-Menü von „Gong“ vor der Entwicklung
Ein Start-Menü erlaubt, die Anzahl der Spieler einzustellen und festzulegen, wer welchen Spieler steuert. Zu Beginn kann bei „Gong“ die Spieleranzahl noch nicht geändert werden, da mindestens zwei Spieler teilnehmen müssen und die Möglichkeit für mehr Teilnehmer noch nicht entwickelt wurde. Für beide Spieler kann jeweils festgelegt werden, ob er durch einen Menschen oder eine simple KI gesteuert werden soll. Es können also auch zwei Menschen (selbst an einem einzelnen 3DS) oder zwei KIs gegeneinander antreten. Natürlich bekommt man in beiden Fällen keine Erfahrungspunkte, da man sonst mogeln könnte oder es unfair wäre. Hat man die Fähigkeit, weitere Spieler antreten zu lassen, erlernt, taucht eine neue Option zur Einstellung der Spielerzahl auf. Für jeden weiteren hinzugeschalteten Spieler tauchen wiederum neue Optionen für deren Belegung durch Mensch oder KI auf.


Start-Menü von „Gong“ nach der Entwicklung
Fähigkeiten, die Früchte der Erfahrung
Der aktuell wichtigste Menüpunkt ist die „Entwicklung“. Hier finden wir einen Fähigkeitenbaum durch den wir Neues lernen können. Das Erlernen einer Fähigkeit kostet Fähigkeitspunkte, welche wir bei einem Levelanstieg erhalten. Sie sind hierarchisch angeordnet, da für manche Fertigkeiten zuvor andere erlernt werden müssen. Beispielsweise kann man den Vier-Spieler-Modus erst freischalten, nachdem der Drei-Spieler-Modus erlernt wurde. Wenn man eine Fähigkeit auswählt, werden unten links Informationen angezeigt. Es können beliebig viele Fertigkeiten ausgewählt werden, sofern alle Vorbedingungen erfüllt sind. Diese Vorbedingungen beschränken sich aktuell auf das Freischalten aller vorhergehenden Baumknoten. Sofern dann genügend Fähigkeitenpunkte zum Erlernen aller selektierten Fähigkeiten verfügbar sind, ist ein Übernehmen-Button aktiv. Wird dieser angeklickt, werden alle ausgewählten Fähigkeiten unwiderruflich freigeschaltet und die Fähigkeitenpunkte abgezogen. Danach könnten Fähigkeiten der nächsten Ebene(n) im Baum erlernt werden.


Fähigkeitenbaum von „Gong“
Die erlernten Fertigkeiten wirken sich umgehend aus und wir können die neuen Optionen wie oben beschrieben nutzen. Nun muss nur noch dafür gesorgt werden, dass wir das Erlernte nicht wieder vergessen – es muss gespeichert werden. Hierfür genügt pro Fähigkeit ein Bit, also eine „1“ für erlernt und eine „0“ für noch nicht erlernt. Da wir das Thema Speichern und Laden bereits im vorherigen Tagebucheintrag behandelt haben, werde ich hier nicht genau darauf eingehen.

Die verbleibenden Menüpunkte sind die Optionen – noch existieren keine – und die Errungenschaften. Letzteres werde ich dann im nächsten Tagebucheintrag behandeln. Also bis zum nächsten Mal, ich freue mich auf euch. 😉

Ihr möchtet die Auszüge aus dem Leben eines Entwicklers lieber in englischer Sprache lesen? Unter diesem Link findet ihr die englische Version dieses Tagebucheintrags! ##neue_seite##
##titel:Teil 10: Errungenschaften & Benachrichtigungen## Teil 10: Errungenschaften & Benachrichtigungen
Das letzte Mal haben wir uns mit den wichtigsten Menüs und dem Erfahrungs-System vertraut gemacht. Heute wollen wir uns Errungenschaften bzw. Achievements anschauen. Jedes unserer Minispiele soll einige Achievements anbieten, die sich freischalten lassen. Wird eines aktiviert, soll eine kleine Pop-up-Benachrichtigung am Bildschirmrand auftauchen und dies anzeigen. Ab diesem Zeitpunkt soll die Errungenschaft in einem Extra-Menü des jeweiligen Minispiels angezeigt werden.

Diese Pop-ups wollen wir nicht blocken
Gehen wir zunächst auf die Pop-up-Nachrichten ein. Je nach Kontext spricht man auch von „Growl“- oder „Toast“-Nachrichten. Wenn sie aktiviert werden, sollen sie für ein paar Sekunden am rechten Bildschirmrand eingeblendet werden. Es gibt eine maximale Anzahl der gleichzeitig möglichen Nachrichten – auch wenn es eher selten sein sollte, dass überhaupt mehrere gleichzeitig aktiviert werden. Sie werden von unten nach oben eingeblendet, d.h. die neueren stehen weiter unten. Wird die maximale Anzahl überschritten, wird die älteste Nachricht sofort entfernt. Jede hat ihren eigenen Countdown, nach dessen Ablaufen die Nachricht ebenfalls wieder ausgeblendet wird. Eine weitere Möglichkeit, eine Nachricht verfrüht verschwinden zu lassen, für die Ungeduldigen unter uns, ist das Anklicken bzw. Antippen der Nachricht. Alternativ denkbar wäre es, durch das Anklicken etwas auszulösen, wie im Falle eines Achievements das Öffnen der Achievement-Liste des Spiels.


Eine Pop-up-Benachrichtigung zeigt das freigeschaltete Achievement
Für die Umsetzung der Nachrichten benötigen wir zunächst eine Art Container, direkt über dem User-Interface. Ich habe also in Unity einen weiteren Canvas angelegt, eine Art UI-Folie, die über alles drüber gelegt wird, so wie es beispielsweise bereits für das Inventar gemacht wurde. Es gilt dabei die Zeichen-Reihenfolge zu beachten – es muss festgelegt werden, welche Folie sich vor welcher anderen befindet. Dieser Canvas bekommt dann einen Bereich zugeordnet, in dem die Nachrichten vertikal gestapelt werden. Das Erstellen neuer Nachrichten wollte ich möglichst leicht machen. Das Ergebnis ist der Aufruf einer Methode, welche ein Bild und einen Text erwartet und den Rest völlig automatisch erledigt. Und schon können wir unseren Spieler über alle möglichen Ereignisse informieren.

Tooooor! Was für eine Errungenschaft!
Wie bereits auf obigem Bild zu erkennen, habe ich mich für ein recht simples erstes Achievement entschieden. Sobald man in unserem ersten Minispiel Gong einen ersten Punkt macht, wird die Errungenschaft „First Goal“ (bzw. „Erstes Tor“ im Deutschen) freigeschaltet. Man sieht, dass der Text der Benachrichtigung eigentlich aus verschiedenen Teilen besteht. Zum einen ein fester Text „Unlocked achievement“ (bzw. „Errungenschaft freigeschaltet“), welcher bei jedem Achievement gleich bleiben kann, und ein spezifischer Part mit dem Namen des Achievements. Tatsächlich übergebe ich aber nicht nur den übersetzten Text an unser neu zu erstellendes Pop-up, sondern die Schlüssel-Worte, die verwendet werden, um den Text je nach Sprache zuzuordnen. Der Vorteil: Das Pop-up kann sich selbst übersetzen, wenn man die Sprache des Spiels wechselt, während es angezeigt wird. Sicher kann man sich darüber streiten, ob dies nötig ist bei einem Text, der nur wenige Sekunden angezeigt wird, aber ich möchte ja alles perfekt machen. 😉 Und da es sich wie gesagt um zwei Textabschnitte handelt, musste sogar eine spezielle Art von Pop-up erstellt werden, welche gleich zwei Texte beinhaltet. Dennoch sagen Bilder mehr als tausend Worte und deshalb wollen wir zugleich aussagekräftige Bilder erstellen, welche das Achievement repräsentieren. Als erstes kam mir hierfür ein Fußball-Tor mit einer „1“ in den Sinn. Ich habe mich dann aber doch für etwas entschieden, das direkt das aktuelle Spiel widerspiegelt, auch wenn es nicht genauso intuitiv scheint. Das Resultat seht ihr ja selbst.

Die Errungenschaften gehören genauso zum Spielfortschritt wie der Level und wollen auch gespeichert werden. Aber auch hier werde ich nicht genauer auf das Speichern und Laden eingehen, da wir dazu bereits einen separaten Tagebucheintrag hatten. Beim Einbauen des Achievements ist noch auf ein paar Feinheiten zu achten, beispielsweise dass es nur aktiviert wird, wenn wirklich ein Mensch diesen Punkt gemacht hat und nicht etwa der Computer-Gegner oder ein Spieler bei einem Spiel mit KI gegen KI. Und auch hier soll alles so einfach wie möglich verwendet werden können: Ein Aufruf von enableAchievement("firstGoal"); genügt und schon ist unser Achievement aktiviert und im Spielstand untergebracht. Zu guter Letzt möchte ich meine Leistungen jederzeit einsehen können und dies ermöglicht uns der Menüpunkt „Achievements“ („Errungenschaften“) eines jeden Minispiels. Hier finden wir eine Liste aller verfügbaren Achievements des Spiels, auch solche, die noch nicht freigeschaltet wurden. Allerdings werden die Bilder nur bei den bereits erlangten angezeigt. An dieser Stelle gibt es noch Optimierungsmöglichkeiten. Beispielsweise kann man statt der Namen Hinweistexte anzeigen, welche Tipps zum Finden der Achievements liefern.


Achievement-Liste vom ersten Minispiel „Gong“
Soviel zum Thema Achievements. Das nächste Mal wollen wir uns mit Uhrzeiten, Tageswechsel und Wetter im Spiel beschäftigen, um etwas Abwechslung in unsere Overworld zu bringen.

Ihr möchtet die Auszüge aus dem Leben eines Entwicklers lieber in englischer Sprache lesen? Unter diesem Link findet ihr die englische Version dieses Tagebucheintrags! ##neue_seite## ##abschnitt:2018##
##titel: Teil 11: Tag- und Wetterwechsel## Teil 11: Tag- und Wetterwechsel
Dieses Mal wollen wir etwas Abwechslung in den tristen digitalen Alltag unserer Overworld- Landschaft bringen. Im Gegensatz zu den meisten Dingen, die bisher implementiert wurden, birgt es zwar keinen strategischen Vorteil, damit so früh in der Entwicklung zu beginnen, aber ein Entwickler möchte auch nicht immer dieselbe monotone Landschaft beim Testen vor sich haben. Deshalb habe ich mich entschlossen, dem Ganzen durch einen Tag- und Wetterwechsel etwas Würze zu verleihen. Dies beinhaltet Änderungen der Wetterlage wie Sonnenschein, Regenwetter und Schneegestöber, passende Lichtverhältnisse sowie einen Tag- und Nachtwechsel.

Man muss das Rad der Zeit nicht neu erfinden
Wie auch schon beim Inventarsystem habe ich zunächst recherchiert, ob es bereits kostenlose Angebote für Wetter- und Zeitsysteme im Assetstore von Unity gibt. Tatsächlich bin ich auch fündig geworden, habe mir Time of Day & Weather System heruntergeladen und in mein Projekt importiert. Dieses enthält genau das oben Gewünschte und noch etwas mehr. Es besteht hauptsächlich aus zwei Kontrollobjekten – eines für das Wetter und eines für die Tageszeit. Gehen wir zunächst auf die zeitlichen Aspekte ein. Der Zeitkontroller hat einen Timer, der in einer vorgegebenen Geschwindigkeit stets von 0 bis 24 Uhr zählt und wieder von vorne beginnt. Dazu gehören zwei Lichtquellen, welche den Mond und die Sonne repräsentieren. Beide Lichtquellen sind direktional, erzeugen also Lichtstrahlen in eine vorgegebene Richtung und nicht etwa in alle Richtungen wie es eine „Punktquelle“ tun würde. Sie drehen sich beide um etwa 180° versetzt um sich selbst, um so die verschiedenen Lichteinfallswinkel über den Tag hinweg zu simulieren und dadurch Objekte immer von einer anderen Seite zu beleuchten und entsprechende Schatten zu werfen. Das Ganze stellt natürlich ein stark vereinfachtes Modell unseres Tag- und Nachtwechsels dar. In Wirklichkeit scheinen Sonne und Mond aus unserer Sicht keine gleichmäßige Kreisbahn zu beschreiten, sondern bewegen sich dank der Erdrotation auf einer Kurvenbahn. Auch ist die Versetzung zwischen Sonne und Mond nicht immer gleich. Im echten Leben sind Sonne und Mond manchmal gleichzeitig zu sehen und manchmal nicht. Ebenso werden die Entfernung der Sonne, also die Jahreszeiten, sowie die Lichtintensität vom Mond, der nicht stets gleich stark von der Sonne angestrahlt wird, hier außer Acht gelassen. Was unser System aber bereits beachtet, sind Unterschiede in den Farben unserer Lichtquellen, die sich je nach Tageszeit ändern. Beispielsweise wird das Sonnenlicht bei Sonnenauf- und untergang leicht rötlich.

Da wir nun auch gerne wüssten, wie spät es in unserem Spiel ist, wollte ich eine Möglichkeit finden, die etwas mehr hermacht als eine simple Anzeige auf dem Bildschirm. Immerhin wissen wir in der Realität auch nicht die genaue Uhrzeit, nur weil sich das Licht verändert. Deshalb habe ich zwei neue Items erstellt – eine analoge und eine Digitaluhr. Führt man diese im Inventar mit sich, kann man die Zeit direkt im Item-Slot ablesen. Natürlich wäre es nützlich, wenn man solch eine Uhr später nicht stets in der immer sichtbaren „Hotbar“ tragen muss, um die Zeit sehen zu können. Denkbar wäre ein „Ausrüsten“ wodurch die Zeit bzw. die Uhr zusätzlich am Bildschirmrand eingeblendet wird.


Zwei Uhren im Inventar bei Nacht
Wetter wechsle dich!
Das importierte Wettersystem bietet bereits die wichtigsten Wetterzustände an: Sonne, Regen, Schnee, Gewitter und Bewölkung. Im Falle von Regen und Schnee gibt es Partikelsysteme die Regentropfen oder Schneeflocken erzeugen. Partikel sind so zu sagen sehr minimalistische Objekte, die gewissen physikalischen Gesetzen gehorchen und eine begrenzte Lebensdauer haben. Sie sollen so möglichst effizient in großen Mengen genutzt werden können, ohne zu viel Rechenleistung zu benötigen. Regen kann beispielsweise als zweidimensionale kurze Striche dargestellt werden, um so den Eindruck schnell fallender Tropfen zu schaffen. Sie müssen also keine 3D-Modelle nutzen und können durch andere Objekte durch fallen, also keine Kollisionen behandeln, da man dieses Detail eh kaum sehen könnte.


Düster und Regen – das drückt die Stimmung
Die Schneeflocken hingegen sind als kleine weiße Quader umgesetzt. Nur wenige davon haben bei einem Test ein altes 3DS-Modell bereits zum Ruckeln gebracht. Alternativ wären hier vielleicht 2D-Sprites, also Bilder statt Modelle, von Schneeflocken denkbar.


Die kantigen Schneeflocken reflektieren das Sonnenlicht leicht
Ausgehend davon, dass es ohne Wolken auch keinen Niederschlag geben kann, wird die Umgebung bei schlechtem Wetter automatisch mit abgedunkelt. Das Wettersystem beeinflusst also ebenfalls die Lichtquellen, zusammen mit der Tageszeit. Ein Gewitter erweitert das Regenwetter um Blitze. Diese werden nicht direkt durch sichtbare Blitz-Zeichnungen umgesetzt, sondern durch ein kurz und hell aufleuchtendes Bild.

Nun muss das Wetter nur noch bestimmt und in angemessenen Zeitabständen gewechselt werden. Dafür wird ebenfalls unsere Spiel-Uhrzeit verwendet und ein bisschen Zufall. Ich kann beispielsweise bestimmen, dass eine Wetterphase jeweils eine bestimmte Zeit andauert – ein paar Stunden bis ganze Tage. Danach wird das nächste Wetter per Zufall ausgewählt und wieder eine Dauer festgelegt. Dieser Prozess könnte stark optimiert werden um die Realität möglichst genau widerzuspiegeln. Je nach Lokalisation der Spielwelt (eingestellte Sprache, etc. als Hinweis) könnte man niederschlagsarme Wüsten bis regnerische Subtropen abbilden. Da wir uns aber in einer virtuellen Welt befinden, welche sich momentan an keinem bestimmten realen Vorbild orientieren soll, habe ich hierfür keine Zeit investiert und es bei einem relativ willkürlichen Zufallsalgorithmus belassen.

Ein Unterschied wie Tag und Nacht
Momentan ist das neue Zeit- und Wettersystem nur ein Schönheits-Detail unserer Welt und hat keinen tieferen Sinn. Das wird auch eine Weile so bleiben, da andere Dinge eine höhere Priorität haben, dennoch möchte ich bereits jetzt ein paar der neuen Möglichkeiten ansprechen. Wetter und Tageszeit können eine Menge Einfluss auf das Spielgeschehen haben. In vielen Spielen steht die Nacht für Gefahr – denkt an Minecraft oder an Don’t Starve. Nachts kann es beispielsweise mehr oder gefährlichere Monster geben. Vielleicht muss man sich sogar in eine sichere Unterkunft zurückziehen oder in der Nähe eines Lagerfeuers bleiben. Für unseren Fall denke ich mal wieder eher an einen Vergleich zu Pokémon: Vielleicht gibt es düstere Minispiele, die nachtaktiv sind und andere, die sich nur bei Tag heraus trauen. Oder manche Spiele unterscheiden sich leicht, je nachdem ob man sie bei Tag oder bei Nacht spielt. Sie könnten sich rein grafisch an die jeweilige Situation anpassen oder bei Nacht schwerer sein und mehr Erfahrung geben. Außerdem sind somit zeitbasierte Events denkbar. Solar-Akkus, welche sich nach einer bestimmten Zeit in der Sonne aufladen und Pflanzen die eine bestimmte Zeit benötigen, um nachzuwachsen. Man könnte beispielsweise Batterie-Büsche anbauen, an denen man Batterie-Beeren ernten kann. Bei solchen Dingen stellt sich allerdings die Frage, ob diese Dinge wirklich von der Zeit im Spiel oder der realen Systemzeit abhängen sollen. Man könnte Pflanzen auch wachsen lassen, während das Spiel nicht läuft, wie die Beeren-Sträucher bei Pokémon oder alle Pflanzen bei FarmVille. Oder im Spiel muss die Zeit wirklich abgewartet werden, wie etwa bei Harvest Moon und Stardew Valley.

Auch das Wetter darf direkten Einfluss nehmen. Wieder vergleichbar mit Pokémon, die sich nur bei Regen hervor trauen, können Minispiele ein solches Verhalten aufweisen. Wetter und Uhrzeit wirken sich auf die Temperatur aus, ein weiterer wichtiger Aspekt, der noch völlig außer Acht gelassen wurde. Temperaturen könnten die Minispiele ebenfalls beeinflussen. Nicht zuletzt aber auch die Welt an sich. Gewässer könnten austrocknen oder zufrieren und so neue Wege freigeben. Der Spieler muss sich gegebenenfalls gegen zu hohe oder zu niedrige Temperaturen schützen, damit er keinen Schaden nimmt oder schwächer wird. Ein Musterbeispiel für das Zusammenspielen all dieser Aspekte ist The Legend of Zelda: Breath of the Wild. Hier sollte man sich mit passenden Nahrungsmitteln und Kleidung auf die verschiedenen Temperaturen vorbereiten, die an verschiedenen Orten und zu verschiedenen Tageszeiten herrschen können.

Dies war mein heutiger Beitrag zum aktuellen Entwicklungsstand von Game Master. Im nächsten Part gehe ich auf ein sehr umfangreiches Thema ein: Netzwerk-Spiele! Online Multiplayer und lokale Mehrspieler-Partien über WiFi sollen verwirklicht werden. Bis zum nächsten Mal – und scheut euch nicht vor Feedback, Fragen und Vorschlägen!

Ihr möchtet die Auszüge aus dem Leben eines Entwicklers lieber in englischer Sprache lesen? Unter diesem Link findet ihr die englische Version dieses Tagebucheintrags! ##neue_seite##
##titel:Teil 12: Netzwerk-Spiele## Teil 12: Netzwerk-Spiele
Heute wagen wir uns an ein gewaltiges Thema: Multiplayer via Netzwerkverbindung. Dies betrifft Spiele lokal über WiFi mit dem 3DS, im LAN (am PC) und über das Internet (am PC). Dank meiner Erfahrung in der Spieleentwicklung ist mir bewusst, dass man mit der Implementierung eines Multiplayer-Modus niemals früh genug beginnen kann, da sehr viele Vorgänge darauf vorbereitet sein müssen. Ich möchte an dieser Stelle auch nicht festlegen, dass das Spiel bei Release wirklich einen Multiplayer-Modus haben oder wie umfangreich dieser sein wird, da ich schon viele Entwickler daran scheitern sehen habe, was Verschiebungen des Erscheinungsdatums nach sich ziehen kann oder gar ein kurzfristiges Streichen oder Einschränken des Modus. Durch meine folgenden Erläuterungen wird es vielleicht auch etwas verständlicher, woran dies liegt.

Nichtsdestotrotz brauche ich zunächst einen Plan, in welche Richtung der Multiplayer gehen soll, den es später zu erproben gilt. Und da möchte ich zunächst keine Aufwände und Risiken scheuen und das Beste versuchen, das ich mir vorstellen kann. Optimal wäre ein Coop-Modus über das komplette Spiel mit allen denkbaren Freiheiten. Ein Spieler soll jederzeit das Spiel und die damit verbundene Welt eines anderen betreten können und dort nur wenigen Einschränkungen unterliegen – etwa vergleichbar mit Minecraft. Wenn ein Spieler gerade mit einem Minispiel beschäftigt ist, soll ein anderer dazu kommen können, um zuschauen und sogar mitzuspielen. Außerdem sollten Spieler miteinander kommunizieren können.

Unity vs. 3DS
Unsere Entwicklungsumgebung Unity bietet auch zum Thema Netzwerk-Multiplayer eine passende Lösung an. Es werden Tutorials und Muster-Projekte angeboten, anhand derer man diese Lösung besser kennen lernen kann. Es handelt sich um ein recht umfangreiches Paket zum Erstellen und Verwalten von Netzwerk-Spielen mit nützlichen Werkzeugen, die man häufig gebrauchen kann. Dazu gehört beispielsweise eine Lobby, in der sich die Spieler vor oder eventuell sogar während des Spiels treffen können. Auf dieser Ebene muss man sich weniger mit der darunter liegenden Technik auseinandersetzen, wie die Verwendung der Protokolle TCP und UDP. Leider lässt sich genanntes System nicht auf dem 3DS verwenden, da hier gewisse Richtlinien eingehalten werden müssen. Unsere Lösung erlaubt Direktverbindungen zu anderen Teilnehmern aufzubauen oder einen kostenpflichtigen Service von Unity in Anspruch zu nehmen, welcher die Spiele-Findung verwaltet. Beim 3DS hingegen sind wir dazu verpflichtet, zunächst eine Verbindung zu Nintendos Servern herzustellen, welche vor einem Spiel Sicherheitsprüfungen durchführen und somit unserer Lösung einen Strich durch die Rechnung machen. Tatsächlich lernen wir aus Beispielcode für Verbindungen zwischen 3DS-Systemen, dass alles auf deutlich niedrigerer Ebene behandelt werden muss. Hier müssen wir uns selbst um das Erstellen und Versenden von Datenpaketen kümmern.

Ich werde diese Problematik an dieser Stelle nicht genauer erläutern. Aber ich habe für mich hiermit festgelegt, dass ich eine 3DS-Konnektivität zwar parallel zur höheren Unity-Variante mit implementieren werde, aber diese zunächst nur für lokale WiFi-Spiele umsetzen werde, anstatt über Internet. Einigen von euch mag es schon oft komisch vorgekommen sein, dass relativ viele 3DS-Spiele zwar einen lokalen Multiplayer anbieten, aber auf Onlinespiele verzichten. Wie ihr euch jetzt denken könnt, dürfte das deutlich mehr Gründe haben, als „nur“ weitere Netzwerk-Infrastruktur zahlen zu müssen oder die Spiele auf höhere Latenzen auslegen zu müssen.

Ein Spiel starten
Betrachten wir zunächst die Nicht-3DS-Variante. In diesem Fall nutzen wir die Lobby, die uns Unity zur Verfügung stellt, damit sich Spieler dort treffen und vorbereiten können. Der Spieler, der das Spiel hostet, also erstellt und anderen zur Verfügung stellt, landet als erstes in der Lobby. Andere Spieler, die sich via IP-Adresse mit ihm verbinden, landen ebenfalls in der Lobby. Bis der Host das Spiel startet, können alle Teilnehmer einen Namen und eine Farbe festlegen. Fertige Spieler können sich als „bereit“ markieren, wenn sie so weit sind. Dann kann der Host das Spiel starten. Ich habe das alles ein wenig abgewandelt, so dass Spieler nun auch noch beitreten können, nachdem das Spiel bereits gestartet wurde.


Multiplayer-Lobby auf dem PC
Da es heutzutage nicht mehr üblich ist, IP-Adressen manuell einzugeben, möchte man dem Benutzer eine automatisierte Spielefindung anbieten. Damit meine ich, dass man seinem Spiel bzw. Lobby-Raum einen Namen gibt, und der Benutzer dann aus einer Liste an Spielen auswählt, oder nach diesem Namen suchen kann. Um dies zu verwirklichen ist aber ein weiterer Rechner nötig, ein Server der irgendwo steht und diese Liste verwaltet. Mit anderen Worten: weiterer Aufwand und weitere Kosten. Wie bereits erwähnt, bietet Unity hierfür einen kostenpflichtigen Service an. Dieser nimmt einem dann die Arbeit und Kosten für ein eigenes Serversystem ab. Auf dem 3DS beschränken wir uns wie gesagt zunächst auf lokalen Multiplayer via WiFi. Hier kann man es theoretisch etwa genauso umsetzen, denn der große Unterschied spielt sich erst auf niedrigerer Ebene ab. Aktuell existieren hierfür allerdings nur sehr minimalistische GUI-Buttons ohne tolles Design oder Komfort, daher ist es noch nicht der Rede wert.

Die Kommunikation zwischen den Geräten
Nachdem sich Teilnehmer gegenseitig gefunden haben, müssen sie stetig miteinander kommunizieren. Dabei agiert der Host als Vermittler zwischen allen anderen Spielern, welche untereinander keinen direkten Kontakt haben. Dies beginnt bereits in der Lobby – wenn ein dritter Spieler beitritt, berichtet der Host diesem über den zweiten Spieler und den zweiten über den Neuankömmling. Sobald das Spiel begonnen und jeder Teilnehmer seinen eigenen Charakter hat, den er steuern kann, wird die Kommunikation auf die Zustände dieser Charaktere ausgedehnt. Jeder Spieler muss also dem Host seine aktuelle Position schicken und dieser verteilt diese an die anderen Teilnehmer, sofern vorhanden. Dazu kommt, dass man auch sehen möchte, in welche Richtung ein Spieler blickt und ob er gerade läuft oder steht. Besonders wichtig ist, dass man bedenken muss, dass das Versenden dieser Informationen eine gewisse Zeit benötigt, im Speziellen weil nicht alle Spieler direkt miteinander kommunizieren. Diese Versanddauer (Latenz = Verzögerungszeit, siehe auch Ping) hängt von sehr vielen Faktoren ab und kann stark variieren. Dies und die zeitliche Dichte der Informationen haben zur Folge, dass Spieler scheinbar von einem Punkt zum nächsten springen. Deshalb müssen die Spieler-Bewegungen interpoliert werden. Das bedeutet, dass jeder Rechner versuchen sollte, die Bewegung aller nicht lokalen Teilnehmer vorherzusagen, um so ein Ruckeln zu vermeiden. In unserem Fall geht dies sogar relativ einfach, da es bereits genügt, Bewegungsrichtung und -geschwindigkeit mit zu übermitteln. Die Abweichungen sind dann so minimal, dass ein Spieler dies gar nicht wahrnehmen kann, sofern der Ping nicht zu hoch ist. Aus den Bewegungsinformationen können wir dann auch die Blickrichtung und die Laufanimation ableiten.

Mit der Unity-Variante lässt sich dies sehr einfach verwirklichen. Objekte, für welche diese Funktionalität umgesetzt werden soll – wie die Charaktere der Spieler – benötigen lediglich entsprechende vorgefertigte Komponenten. Unser Spieler bekommt also eine „Network Identity“, welche aussagt, dass es sich um ein Objekt handelt, welches mit anderen Netzwerkteilnehmern synchronisiert werden muss. Diese Identität wird einer Netzwerkverbindung zugeordnet, sodass entsprechende Spieler sie kontrollieren können. Dazu kommt noch ein „Network Transform“-Skript, welches Transformationen dieses Objektes mit synchronisiert. In diesem Skript lässt sich dann einstellen, wie häufig und wie genau welche Informationen abgeglichen werden sollen. In unserem Fall also die Bewegung, bestehend aus Richtung und Geschwindigkeit, sowie die Rotation des Objektes.

Für die 3DS-Variante müssen wir dies manuell verwalten. Dazu lesen wir in bestimmten Zeitabschnitten genannte Werte aus und codieren sie in Bytes. Das bedeutet, dass wir mit mathematischen Funktionen die Werte unserer Bewegungen und Rotationen auf ganze Zahlen größer Null abbilden, welche ein gewisses Maximum nicht übersteigen. Dabei geht natürlich etwas an Genauigkeit verloren, da wir nicht beliebig komplexe Zahlen abbilden können. Diese Bytes schicken wir dann in Paketen über die entsprechenden Verbindungen weiter. Auf der anderen Seite werden diese wieder decodiert und zurück auf die gewünschten Zahlenbereiche abgebildet.


Ein alter 3DS XL und ein New 3DS XL sind zum Spielen miteinander verbunden.
Aussicht
Aus diesem Artikel lässt sich der benötigte Aufwand und die Komplexität, zu lösender Probleme und Schwierigkeiten nicht annähernd erahnen. Aber genau so soll es ja auch im Rahmen dieses Entwicklertagebuchs bleiben. Für diese Aufgaben habe ich jedenfalls einige Zeit benötigt und ich kann mich nicht zu lange damit aufhalten, ohne am eigentlichen Inhalt weiter zu arbeiten. Aktuell ist bereits etwas mehr möglich als bisher beschrieben. Auf obigem Screenshot lässt sich bereits erkennen – es gibt ein Chat-System, über welches man Texte und sogar Smileys austauschen kann. Ein versandter Smiley erscheint auch kurzzeitig in etwas größer über dem Kopf des Senders. Er soll die aktuelle Emotion des Benutzers widerspiegeln. Ein weiteres Feature ist, dass man sehen kann, in welchem Minispiel ein anderer Spieler sich gerade befindet. Ist jemand mit einem Spiel beschäftigt, sehen alle anderen das Icon des Spiels über seinem Kopf. Währenddessen können andere, wenn sie neben diesem Spieler stehen, mit der Aktionstaste genauere Infos erfragen. An dieser Stelle soll es dann möglich sein, diesem Minispiel beizutreten, falls dieses solch eine Funktion anbietet. Damit dies möglich ist, muss aber noch Einiges getan werden. Unser erstes Minispiel „Gong“ bietet sich natürlich prima dafür an, dass bis zu drei weitere Spieler einsteigen. Dazu benötigen Minispiele aber ebenfalls eine Art von kleiner Lobby und etliche Anpassungen. Bei „Gong“ müssen die Pads den Teilnehmern zugeordnet werden. Im Multiplayer müssen auch das Erfahrungssystem und die Achievements anders gehandhabt werden. Man kann nicht einfach leichtfertig Erfahrung für jemanden verteilen, der gegen einen anderen Menschen spielt, denn so könnte man leicht schummeln.

Das soll es zunächst zum Netzwerk-Multiplayer gewesen sein. Im nächsten Tagebucheintrag kümmern wir uns um etwas künstliche Gesellschaft, doch mehr möchte ich noch nicht verraten. Bis zum nächsten Mal!

Ihr möchtet die Auszüge aus dem Leben eines Entwicklers lieber in englischer Sprache lesen? Unter diesem Link findet ihr die englische Version dieses Tagebucheintrags! ##neue_seite##
##titel: Teil 13: Begleiter-Haustier## Teil 13: Begleiter-Haustier
Heute wollen wir dafür sorgen, dass sich unser Spieler nicht so einsam fühlt. Um dies zu bewerkstelligen, schaffen wir etwas Retro-Gesellschaft. Der Jugend von heute mag es vielleicht gar kein Begriff mehr sein, aber wir implementieren eine Variante des virtuellen Haustieres Tamagotchi, welches 1996 von Bandai auf den Markt gebracht wurde.

Umsetzung eines „Tamagotchis“
Zunächst brauchen wir ein neues Item für unser Inventar. Wenn man dieses Tamagotchi-Item anklickt, soll eine größere Variante davon erscheinen. Der besondere Clou: Solange die große Ansicht des Tamagotchis nicht geöffnet ist, ist das Display des virtuellen Gerätes sogar komplett im Inventar einsehbar – die geringe Pixelanzahl reicht hierfür tatsächlich aus. Um es besser einsehen und vor allem bedienen zu können, ist die größere Ansicht allerdings unerlässlich.


Die Tamagotchi-GUI
Wie das Original verfügt unsere Variante über drei Knöpfe. Diese können direkt auf dem Bildschirm, je nach Plattform mit dem Finger, Stylus oder der Maus, angeklickt werden. Wie auf obigem Screenshot zu sehen, sind den Knöpfen ebenfalls Gamepad-Buttons zugeordnet. In diesem Fall sind es X, A und B, wie sie der Anordnung auf einem Xbox Controller entsprechen würden, welcher der am häufigsten genutzte Controller am PC ist. Wird das Spiel auf einem 3DS oder der Nintendo Switch ausgeführt, würden hier die Buchstaben Y, B und A angezeigt werden. Die Funktionen der Knöpfe entsprechen ebenfalls denen des Originals – der linke zum Auswählen der verschiedenen Optionen, der mittlere zum Bestätigen der Auswahl und der rechte zum Abbrechen eines Vorgangs, bzw. um einen Menüpunkt zurück zu springen.

Die Bedürfnisse eines Haustieres
Wie ein echtes Haustier, hat so ein virtueller Begleiter Bedürfnisse. Er benötigt Nahrung, Schlaf und Fürsorge in Form von gemeinsamen Spielen, ab und zu medizinische Hilfe und es muss hinter ihm sauber gemacht werden. Auf dem folgenden Screenshot sind die verfügbaren Menüpunkte und die verschiedenen Interaktionen zu sehen.


Die unterschiedlichen Interaktionen
Von links nach rechts und von oben nach unten ist folgendes zu sehen: Das Statusmenü, in dem das Alter, die Hungrigkeit und Fröhlichkeit abgelesen werden können. Das Nahrungsmenü über welches das Tamagotchi gefüttert werden kann. Das Reinigungssymbol, mit dem ein Häufchen beseitigt werden kann. Ein Gamepad-Symbol, mit dem ein Minispiel gestartet werden kann. Ein Lichtschalter, mit dem das Licht an- und ausgeschaltet werden kann. Medizin, mit der man ein erkranktes Tamagotchi wieder fit bekommt. Ein glückliches Tamagotchi, nachdem es ein Spiel gewonnen hat. Ein trauriges Tamagotchi, nachdem es ein Spiel verloren hat. Ein verstorbenes Tamagotchi.

Sie werden so schnell erwachsen
Ganz im Sinne des Entwicklungsprinzips von GameMaster, entwickeln sich auch virtuelle Haustiere weiter. So bietet das Original eine Art Stamm- oder Entscheidungsbaum – je nachdem wie man sein Haustier behandelt, entwickelt es sich in eine bestimmte Richtung weiter. Füttert man es zu viel, wird es vielleicht dick und träge. Manche Tamagotchi-Umsetzungen bieten auch das Disziplinieren an. Dies sollte genutzt werden, wenn sich der Kleine nicht angemessen verhält, etwa gesundes Essen verweigert. Lässt man ihm zu viel durchgehen, wirkt sich das negativ auf seine „Persönlichkeit“ aus – auch wenn diese hauptsächlich oder nur im Aussehen zu erkennen ist. So kann es beispielsweise so weit kommen, dass unser Schützling eine Teufelsgestalt annimmt.

Eine solche Haustier-Entwicklung habe ich trotzdem zunächst zurückgestellt und noch nicht umgesetzt. Theoretisch wäre der Aufwand im Vergleich zur restlichen Implementierung relativ gering, wenn es fast nur darum geht neue Grafiken einzufügen. Es müssten außerdem die entsprechenden Entscheidungswege umgesetzt werden, wodurch, wann und wie es sich weiterentwickelt. Ich halte es für besser, diese Entscheidung später zu treffen, denn je nach Voranschreiten des gesamten Spiels bieten sich vielleicht abweichende Konzepte besser an. Beispielsweise könnte man auch das Tamagotchi-Gerät upgraden müssen um es weiterzuentwickeln. Oder man kann es so weit treiben, dass es das Gehäuse verlassen kann und seinem Herrchen zu Fuß folgt.

Das genügt fürs erste, um der Einsamkeit in dieser virtuellen Welt entgegen zu wirken. Das nächste Mal widmen wir uns neuen Steuerungsmöglichkeiten. Wir wollen beispielsweise dafür sorgen, dass unser Spiel auch auf Geräten bedient werden kann, die nur eine Touch-Steuerung anbieten. Bis die Tage!

Ihr möchtet die Auszüge aus dem Leben eines Entwicklers lieber in englischer Sprache lesen? Unter diesem Link findet ihr die englische Version dieses Tagebucheintrags! ##neue_seite##
##titel:Teil 14: Unterstützung für Android und iOS## Teil 14: Unterstützung für Android und iOS
Heute wollen wir uns darum kümmern, dass unser Spiel auch auf mobilen Geräten funktionsfähig wird. Genauer gesagt geht es zunächst mal um Geräte, welche nur eine Touch-Steuerung anbieten. Die meisten denken nun sicher an ihr Handy oder Tablet, unter denen zum größten Teil Android und iOS vertreten sind, daher habe ich auch den heutigen Titel so gewählt. Im Allgemeinen gilt dies aber auch für Windows Phone oder für Geräte, die zumindest wahlweise ohne Tasten und Controller bedient werden können, wie Laptops mit Touchscreen oder gar die Nintendo Switch.

Das Steuern ohne Tasten
Die meisten Handys, Smartphones und Tablets haben keine Tasten, mit denen man unseren Charakter steuern könnte, also benötigen wir eine Lösung, mit der sich alles via Touchscreen steuern lässt. In erster Linie wird die Steuerung für den 3DS und die Nintendo Switch optimiert, welche beide über analoge Sticks (Joysticks) und Tasten verfügen. Ausnahmen sind bisher nur ein paar Menüs, wie z.B. das der Netzwerk-Lobby – für welche später auch eine mögliche Tastensteuerung folgen wird. Für den 3DS wäre theoretisch auch eine reine Touchscreen-Steuerung denkbar, aber spätestens für die Switch wäre es im TV-Modus nicht sinnvoll.

Der wichtigste Punkt ist die Bewegung unseres Charakters durch die Landschaft. Für diese wären verschiedene Ansätze denkbar: Zum Beispiel könnte man an eine Stelle tippen, zu der der Spieler dann automatisch läuft und man könnte mit Objekten interagieren, indem man diese antippt. Hierfür wäre aber eine Wegfindung nötig, damit man nicht an jedem noch so kleinen Hindernis hängen bleibt, was den Spielfluss sonst stark beeinträchtigen würde. Und auch alle Minispiele müssten jeweils für eine weitere Steuerung angepasst werden. Unser „Gong“ (Pong-Klon) könnte beispielsweise den Schläger zum Finger bewegen. Solch eine Umsetzung könnte die Bedienung für einen Benutzer angenehmer gestalten, würde aber einen stark erhöhten Aufwand bedeuten. Außerdem kann dies das Spielerlebnis stark verändern und manche Dinge einfacher oder schwerer machen. Man stelle sich einen Online-Shooter vor, bei dem ein Spieler mit Maus gegen einen mit Touchscreen antritt – vermutlich nicht unbedingt fair. Aus diesen Gründen habe ich mich, zumindest zunächst, für ein „Touch-Gamepad“ entschieden – das Abbilden von Analogstick und Buttons auf dem Bildschirm.


„Touch-Gamepad“ simuliert Tasten eines Gamepads auf dem Touchscreen (iPhone X)
Wir stellen auf der linken Seite einen Analogstick dar, mit dem wir unseren Charakter bewegen wollen. Wie sein physikalisches Vorbild, kann man ihn wahlweise viel oder nur wenig in eine Richtung bewegen um die Geschwindigkeit zu regulieren. Auf der rechten Seite haben wir bisher einen A- und einen B-Button. Die simulieren das Drücken, Gedrückthalten und Loslassen der realen Buttons.

Anfangs habe ich mit ein paar Besonderheiten experimentiert, die solch ein simulierter Analogstick als Vorteil gegenüber dem Original haben kann. Beispielsweise muss er nicht an der Stelle bleiben, sondern könnte ein Stück verschoben werden, um sich an die bequemste Daumen-Position anzupassen. Oder er kann sogar beim Auflegen des Fingers direkt an diese Stelle springen, so dass man an beliebiger Stelle mit der Bewegung beginnen kann. Dabei muss natürlich beachtet werden, dass der Analogstick nicht an Positionen bewegt werden kann, an denen er andere UI-Elemente verdeckt, mit denen man interagieren können möchte – also weder zu den A- und B-Buttons, noch so, dass es die Hotbar unseres Inventars überdeckt. Leider war ich mit den Ergebnissen dieser Experimente auf unterschiedlichen Bildschirmgrößen nicht zufrieden und habe es eher als unangenehm empfunden, sich nicht auf eine fixe Position verlassen zu können, so dass ich diese Ansätze fürs Erste verworfen habe.

Inventar-Navigation via Gamepad
Während bisher die Steuerung des Spielers ohne Tasten nicht möglich war, verhielt es sich mit den Inventar-Menüs genau umgekehrt. Ohne Maus, Stylus oder Touch war es nicht möglich, die Items zu benutzen oder zu bewegen. Dies soll nun ebenso nur mit Tasten bzw. einem Gamepad möglich sein, was im Speziellen wichtig für die Nintendo Switch im TV-Modus ist. Auch hierfür galt es zunächst ein Konzept auszuarbeiten, um die Interaktionen möglichst einfach und intuitiv zu gestalten. Ich wollte, dass möglichst viel machbar ist, ohne den Spielfluss zu unterbrechen. Das heißt ich möchte nicht das Spiel pausieren, eine Extra-UI öffnen und alle Items manuell durchlaufen müssen, wenn es sich vermeiden lässt. Wie sollte man beispielsweise ein Item von einem Inventar, also z.B. dem GameGuy-Fenster in die Hotbar verschieben können und umgekehrt? Man findet zuhauf Spiele bei denen man jedes Item einzeln über ein weiteres Untermenü an ein anderes Inventar senden kann – „Rüstung anlegen”, „Schwert ausrüsten”, „Trank in Schnell-Menü verschieben”, „Apfel in Rucksack legen”…


Schnelles Benutzen und Verschieben von Items via Gamepad
Auf diesem Screenshot kann man sehen, wie ich solche Prozesse vereinfacht habe. Mit den L- und R-Schultertasten kann man die Selektion der Itemslots unten in der Hotbar nach links oder rechts bewegen. Wird ein benutzbarer Gegenstand markiert, wird der „Benutzen“-Button angezeigt, hier Y wie es im Falle eines Xbox-Controllers ist. Wird dieser gedrückt, öffnet sich bei markiertem GameGuy-Item beispielsweise das entsprechende Fenster. Nun da ein Fenster die Spielwelt verdeckt, ist es auch nicht sinnvoll, den Spieler weiterhin im Hintergrund bewegen zu können. Deshalb können jetzt die Bewegungstasten (Analogstick oder D-Pad) genutzt werden, um parallel im Inventar des Fensters zu navigieren. Auf der rechten Seite sieht man was passiert, wenn in der Hotbar eine Batterie markiert ist, während im Fenster ein Slot markiert ist, in den eine Batterie hinein gehört. Sobald zwei Slots markiert sind, deren Inhalt miteinander getauscht werden kann, erscheint der „Tauschen“-Button, hier das X. Ohne alle Details zu veranschaulichen, sollte dies klar machen, wie viel einfacher die Navigation somit wird. Natürlich ist dafür auch wieder eine Menge Logik nötig, die prüft welche Items wann genutzt oder getauscht werden können.

Dies dürften die wichtigsten Neuerungen in Sachen Steuerung sein, die grundliegend verändert wurden, womit das heutige Thema auch schon abgehandelt wäre. Im nächsten Tagebucheintrag werden wir uns endlich um ein zweites Minispiel kümmern und dieses Mal dürft ihr gerne auch selbst etwas ausprobieren.

Ihr möchtet die Auszüge aus dem Leben eines Entwicklers lieber in englischer Sprache lesen? Unter diesem Link findet ihr die englische Version dieses Tagebucheintrags! ##neue_seite##
##titel:Teil 15: Pairs – Finde Kartenpaare## Teil 15: Pairs – Finde Kartenpaare
Heute machen wir eine Ausnahme und implementieren ein neues kleines Spiel, unabhängig von GameMaster, welches wir später in unser Hauptspiel einbauen. Es handelt sich dabei um eine „Pairs“-Variante, bei der man versuchen muss, Kartenpaare zu finden. Hierzulande ist das Spielprinzip hauptsächlich unter dem Namen Memory bekannt, welcher allerdings der deutschen Firma Ravensburger gehört. Der Spieler hat eine Menge von verdeckten Karten vor sich, von denen jede zweimal vorhanden ist. Pro Zug dreht er zwei Karten um und hofft so, ein Paar mit gleichem Motiv zu finden. Handelt es sich um ein Paar, bekommt der Spieler einen Punkt und die Karten können entfernt oder aufgedeckt liegen gelassen werden und der Spieler darf ein weiteres Mal zwei Karten aufdecken. Handelt es sich aber um verschiedene Karten, werden diese wieder umgedreht und der Zug ist vorbei. Nun kann der nächste Spieler zwei Karten wählen – es ist also eine beliebige Anzahl an Spielern denkbar. Wurden alle Paare gefunden, ist das Spiel vorbei und der Spieler mit den meisten Funden hat gewonnen. Die Herausforderung in diesem Spiel ist es also, sich die Karten und ihre Positionen einzuprägen, um sie später wieder zu finden.


Titelbildschirm des Spiels
Motivation für eigenständiges Spiel
Da GameMaster ein enorm umfangreiches Projekt ist, welches noch sehr viel Zeit in Anspruch nehmen wird, wäre es auch mal schön, zwischenzeitlich etwas schnell Fertigstellbares zu produzieren und vorzuzeigen. Doch ich hatte noch zwei weitere Gründe: Zum einen wollte ich einem Freund anhand eines einfachen Beispiels eine kleine Einführung in Unity geben und zum anderen hat sich dieses Spiel zusammen mit den Bildern auf den Karten perfekt als Geschenk angeboten. Für diese eigenständige Version nutze ich eigene Bilder aus meinem letzten Urlaub in Indonesien und Singapur über Weihnachten 2017 und Silvester 2018. Für die GameMaster-Version dieses Spiels dürften später aber nur andere Motive in Frage kommen, da diese Fotos selbst im stark komprimierten Zustand sehr viel Platz einnehmen und nicht ganz in den Kontext passen würden.


Ein paar gefundene Paare
Die Implementierung
Im Mittelpunkt stehen die Karten. Diese haben zwei unterschiedliche Seiten und können durch Anklicken bzw. Antippen umgedreht werden. Hierfür bietet Unity zweidimensionale Flächen wie „Plains“ oder „Quads“ an, welche mit einer Textur belegt werden können. Ein Anklicken löst eine Animation aus, welche die Karte in einem bestimmten Zeitraum um 180° dreht, anstatt sie etwa schlagartig umzudrehen. Zusätzlich brauchen wir ein Controller-Objekt, welches alles verwaltet. Es kümmert sich darum, dass immer nur zwei Karten umgedreht werden können, für gefundene Paare Punkte vergeben und andere Karten wieder zurück gedreht werden. Der Controller muss natürlich auch weit mehr verwalten. Er erstellt initial die Kartenpaare und legt sie gemischt in einem quadratischen Raster aus. Außerdem visualisiert er den Spielerwechsel und zeigt die Punkte an. Ein kleines Extra-Feature ist das Sammeln von Karten. Insgesamt gibt es ungefähr 150 verschiedene Karten, die per Zufall ausgewählt werden. Jede Karte, die einmal als Paar gefunden wurde, wird in einer Liste unter dem Menüpunkt „Collection“ aufgeführt, zusammen mit der Anzahl der bisher gefundenen und zu findenden Karten. Hier können die Bilder in Ruhe betrachtet werden. Auch nach einem Fund eines Paares, wird das Bild der Karten rangezoomt, bis der Benutzer dies beendet.


Die Collection mit allen gefundenen Bildern
Die Bilder
Auch die Bilder benötigen Vorbereitung für das Spiel. Zunächst sollten sie quadratisch sein, aber auch die Größe und Qualität spielen eine wichtige Rolle. Tatsächlich habe ich anfangs einiges an Zeit investiert um bewegte Bilder in Form von gifs oder Videos zu erproben. Hierbei bin ich aber auf etliche Probleme gestoßen, die ich hier nicht genauer im Detail erläutern möchte, vor allem wenn man möchte, dass dies auf sämtlichen Plattformen funktioniert. Daher habe ich beschlossen, mich auf normale Fotos zu beschränken. Diese Fotos habe ich alle manuell zugeschnitten, da ich sicherstellen wollte, dass der jeweilige Ausschnitt auch optimal gewählt ist. Da ich zu Beginn nicht wusste, wie viele Bilder es insgesamt werden würden und wie viel Speicherplatz diese komprimiert belegen würden, habe ich beschlossen jedes Foto gleich in zwei Auflösungen (256×256 und 512×512) abzulegen, anstatt die Arbeit notfalls zweimal machen zu müssen. Ich hatte es sogar in Betracht gezogen, zwei verschiedene Varianten mit diesen unterschiedlichen Auflösungen zu bauen, mich aber letztendlich auf die 512×512 Pixel festgelegt.

Mit all den Bildern stand ich aber vor einem neuen Problem: Das Spiel würde sehr lange laden, um die Texturen vorzubereiten. Um diesem Problem entgegen zu wirken, lagern die Fotos in einem separaten Ressourcen-Ordner und werden erst zur Laufzeit nebenläufig geladen. Mit anderen Worten kann das Spiel bereits begonnen werden, bevor die Bilder überhaupt bereit sind, angezeigt zu werden. Dementsprechend haben die Karten und die Elemente in der Collection nur eine weiße Fläche, bis das jeweilige Foto fertig geladen wurde. In der Praxis geht dies allerdings so schnell, dass die Texturen bereits fertig sind, bevor die Karten ausgelegt oder die Collection geöffnet wurde, doch auf die gesamte Ladezeit des Spiels wirkt sich dies stark positiv aus.


Rangezoomtes Bild aus Singapur
Mehrspieler
Wie bereits erwähnt, kann man „Pairs“ mit theoretisch beliebig vielen Personen spielen. Für diese Version biete ich neben dem Singleplayer auch einen Zwei-Spieler-Modus an. Dabei kann man zwischen drei KI-Stufen und einem lokalen menschlichen Mitspieler wählen. Für die GameMaster-Version habe ich allerding vier Spieler geplant, entsprechend dem Vorreiter Minispiel „Gong“. Die KIs funktionieren relativ simpel. Die schwächste von ihnen wählt stets zwei absolut zufällig gewählte Karten aus. Die beiden anderen merken sich, welche Karten bereits aufgedeckt wurden und versuchen gezielt, Paare aufzudecken. Kommt eine dieser KIs an die Reihe, checkt sie zunächst ob sich bereits ein Paar unter den bisher sichtbar gewesenen befindet und deckt diese auf. Wenn nicht, wählen sie eine zufällige Karte unter denen, die noch nicht sichtbar waren und decken sie auf. War deren Partner-Karte schon zu sehen, wird diese genommen, ansonsten eine weitere zufällige noch nicht sichtbar gewesene. Dies bedeutet, dass sie nach menschlichem Ermessen perfekt spielen, aber auch nicht über Informationen verfügen, die dem Menschen vorbehalten wurden. Um nun eine der beiden KIs abzuschwächen, lasse ich sie mit einer gewissen Wahrscheinlichkeit eine falsche Karte wählen, selbst wenn sie die richtige bereits kennt – etwa so wie ein Mensch, der die genaue Position einer der bereits sichtbar gewesenen Karten vergessen hat.

Das Ergebnis könnt ihr nun selbst betrachten wenn ihr wollt. Das Spiel steht kostenlos und werbefrei zur Verfügung: Für iOS im App Store. Und für Android im Google Play Store und auf Amazon. Bis zum nächsten Mal!

Ihr möchtet die Auszüge aus dem Leben eines Entwicklers lieber in englischer Sprache lesen? Unter diesem Link findet ihr die englische Version dieses Tagebucheintrags!##neue_seite##
##titel:Teil 16: Einbauen von Pairs in GameMaster## Teil 16: Einbauen von Pairs in GameMaster
Letztes Mal haben wir ein neues Spiel implementiert, bei dem es Aufgabe ist, Kartenpaare zu finden. Dieses haben wir in einem unabhängigen Projekt umgesetzt und als eigenständiges Spiel veröffentlicht. Jetzt wollen wir dieses als zweites Minispiel in unser GameMaster Projekt einbauen. Leider ist es nicht damit getan, alle Dateien in das Zielprojekt zu kopieren – es sind etliche Anpassungen nötig und natürlich wünschen wir auch weitere neue Funktionen.


Lokales Spiel mit vier Spielern und 20 Karten
Die nötigen Anpassungen
Zum Glück haben wir von Anfang an eingeplant, das neue Spiel in unser Projekt einbauen zu können und es entsprechend aufgebaut. Es gibt ein Controller-Objekt, welches für alle Logik benötigt wird, und Spieler-Objekt. Diese beiden können von den entsprechenden Äquivalenten in GameMaster erben und dadurch automatisch etliche benötigte Eigenschaften übernehmen, so dass es beispielsweise von außen möglich ist, das Spiel zu starten und zu beenden. Weitere Objekte wie die Spielkarte können nahezu ohne Änderung übernommen werden, während die erbenden noch einige Anpassungen benötigen.

Wie auch unser bisheriges Minispiel „Gong“ wollen wir bis zu vier Spieler erlauben, lokal wie auch im Netzwerkspiel, statt der bisher vorgesehenen zwei Spieler. Dazu kommt ganz neu die Möglichkeit, das Spiel aufzuleveln und weiter zu entwickeln, was die grundlegende Eigenschaft eines Minispiels in unserem Projekt ist. Es muss also festgelegt werden, für welche Aktionen wie viele Erfahrungspunkte verteilt werden sollen und welche Neuerungen man damit freischalten können möchte. Nur ein lokaler menschlicher Spieler soll Erfahrung erhalten, während er gegen CPU Spieler antritt. Je höher der Schwierigkeitsgrad eingestellt ist, um so mehr Punkte soll man erhalten. Jedes gefundene Paar soll eine kleine Menge geben und ein Sieg deutlich mehr. Es wäre auch schön, wenn man im Spiel gegen Menschen Erfahrung erhalten könnte, doch wäre Mogeln so zu einfach. Damit ein Spieler nicht absichtlich verliert, um dem anderen mehr Erfahrung zu bescheren, müsste dieser im Gegenzug an Erfahrung einbüßen. Doch selbst dann könnte der Gegenüber einfach seinen Spielstand neu laden, nachdem seine Erfahrung gesunken ist. Um dem entgegenzuwirken, müsste man den Spielstand in einem Onlinespiel auf dem Server verwalten, was ich aktuell leider nicht bieten kann. Außerdem wäre dies dann wieder in lokalen Offlinespielen unmöglich.

Entwickeln neuer Optionen
Damit die errungene Erfahrung in Verbesserungen umgesetzt werden kann, benötigt auch „Pairs“ einen Fähigkeitenbaum. Dieser wird ähnlich zu dem von „Gong“ umgesetzt. Man hat die Möglichkeit, die Schwierigkeitsgrade und eine höhere Anzahl an Spielern zu „erlernen“. Angemessen für dieses Spiel ist das Entwickeln der Fähigkeiten schönere Karten zu haben – etwa Bilder statt Muster – und eine höhere Anzahl an Karten, die es aufzudecken gilt, was wiederum zu mehr Erfahrung führen soll. Daraus folgt, dass verschiedene Kartenarten gezeichnet bzw. erstellt werden müssen und dass die Anzahl an Karten verändert werden können muss. Ich war mir lange nicht sicher, ob solche erlernbaren Optionen verstellbar sein sollen, oder ob beispielsweise die höhere Kartenanzahl Pflicht ist, nachdem sie einmal erlernt wurde. Schließlich habe ich für solche Dinge ein zusätzliches Optionenmenü umgesetzt, welches im Hauptmenü eines Minispiels zu finden ist, sobald man auf mindestens eine Option Zugriff hat. Allerdings ist dies nicht sehr benutzerfreundlich und ich habe mit dem Gedanken gespielt, dies mit in dem Menü unterzubringen, in dem man die Spieleranzahl auswählen kann. Dieses Spielermenü nimmt aber auf einem 3DS bereits den gesamten Platz auf dem Bildschirm ein, weswegen wieder eine weitere Lösung nötig wäre – mehrere Tabs oder Scrolling. Eine andere Alternative wäre, die Fähigkeit direkt im Fähigkeitenbaum aktivieren und deaktivieren zu können. Dies wäre zwar intuitiv und platzsparend, würde aber trotzdem eine eventuell sonst unnötige Navigation zu diesem weiteren Menü erfordern. Letzten Endes habe ich – wie gesagt – die Variante mit dem Optionsmenü umgesetzt, in welchem bereits zwei Einstellungen zu finden sind, sofern man sie erlernt hat. Neben der Möglichkeit, ein Kartenset aus den anfangs verfügbaren Mustern und Fotos auszuwählen, kann man die Anzahl der Karten von 12 auf 20 erhöhen.


Entwickle Optionen, um weitere Grafiken und mehr Karten auf einmal nutzen zu können
„Pairs“ bietet eine Kartensammlung an – einen Menüpunkt unter dem man sehen kann, welche Karten man bereits als Paar aufgedeckt hat. Dieses musste neu in die Menüstruktur unserer Minispiele eingearbeitet werden und dies so allgemein, dass es problemlos von anderen Spielen wiederverwendet werden kann. Zuvor wurden diese gesammelten Karten in Form ihrer Dateinamen als Liste in einer Textdatei gespeichert und von dort geladen. Um unserem GameMaster Speicher-Prinzip zu entsprechen, wurde dies komplett ersetzt. Es wird nur noch eine Bitmap gespeichert, sprich eine einzige Zahl, die in Binärschreibweise jeder vorhandenen Karte eine Eins und ansonsten eine Null zuordnet. Die Bilddateien der Karten enden alle mit einer Nummer (etwa card0.png bis card42.png) welche eindeutig den Positionen dieser Bits zugeordnet werden kann. Anstatt einer Textdatei mit bis zu 42 Zeilen Text, ergibt sich also eine Zahl mit maximal 42 Stellen (binär). Dies spart natürlich Platz und ist auch schneller gespeichert und geladen.


Ein paar der Muster und Fotos, die gesammelt werden können
Immer das größte Problem – Netzwerkspiele
Die größte Herausforderung sind mal wieder die Netzwerkspiele. Bisher konnten wir Positionen und Ausrichtungen von Spielern synchronisieren, etwas das uns bei einem Kartenspiel gar nichts bringt. Stattdessen gibt es völlig neue Kommandos, die sich vermutlich nicht zur Wiederverwendung in anderen Spielen eignen. Der Ersteller des Netzwerkspiels sendet allen Teilnehmern eindeutige Identifikationsnummern der verdeckten Karten in der Reihenfolge wie sie auch erstellt werden. So kann man sicherstellen, dass alle Spieler auch mit denselben Karten spielen. Außerdem muss sichergestellt werden, dass auch nur der Spieler Karten umdrehen kann, der gerade an der Reihe ist. Von Gong kann übernommen werden wie die Punkte gezählt werden. Ob es sich um „geschossene Tore“ oder aufgedeckte zueinander passende Karten handelt, kann den vorhandenen Funktionen egal sein.

Sicher hat dieser Tagebucheintrag wieder nur die Oberfläche der Aufgaben und Probleme angekratzt, doch dies sollte für einen Eindruck genügen. Das nächste Mal beschäftigen wir uns mit „Statistiken“ – das sich Merken von verschiedenen Daten wie der Spieldauer oder Anzahl der gewonnen Spiele, warum dies nötig ist und wozu es nützlich sein kann. Bis zum nächsten Mal!

Ihr möchtet die Auszüge aus dem Leben eines Entwicklers lieber in englischer Sprache lesen? Unter diesem Link findet ihr die englische Version dieses Tagebucheintrags! ##neue_seite## ##abschnitt:2019##
##titel:Teil 17: Statistiken## Teil 17: Statistiken
Heute widmen wir uns den Zahlen. Doch keine Sorge, es wird nicht sonderlich mathematisch. Es wird Zeit, sich allerlei Daten zu merken, um sie später für verschiedene Dinge auswerten zu können. Im Mittelpunkt stehen hier die Achievements, denn diese hängen häufig nicht von nur einem speziellen Event ab, sondern brauchen oft eine gewisse Anzahl von einem oder mehreren Ereignissen. Außerdem können Zahlen den erbrachten Leistungen mehr Ausdruck verleihen, deswegen wollen wir die gesammelten Statistiken dem Spieler auch direkt anzeigen.

Leistung gehört belohnt
Achievements sollen als Ansporn dienen, Spiele häufiger oder länger zu spielen und nicht nur das Hauptziel vor Augen zu haben. Wie bei einer Trophäensammlung haben hier Stolz auf erbrachte Leistungen, mit denen man auch mal angeben kann und der Sammeldrang eine wichtige Rolle. Doch wenn ich eine Auszeichnung dafür bekommen soll 100 Punkte erzielt zu haben, müssen diese natürlich auch mitgezählt werden. Und wenn ich das Spiel neu starte, soll nicht von vorne gezählt werden müssen, also gehören diese Zahlen mit in den zu speichernden Spielstand.

Wie immer wollen wir von Wiederverwendbarkeit profitieren. Deswegen legen wir anfangs ein paar Aktionen fest, die wir in jedem Minispiel zählen möchten:
1. Wie oft wurde das Minispiel geöffnet (z.B. der GameGuy eingeschaltet)? (n)
2. Wie lange war das Spiel insgesamt offen? (t)
3.Wie lange wurde das Spiel effektiv gespielt (nicht pausiert, nicht in den Menüs)? (t)
4. Wie viele Spiele wurden gemacht? (n)
5. Wie viele Spiele wurden gewonnen? (n)
6. Erzielte Punkte (spielübergreifend)? (n)

Dazu habe ich sogleich notiert, um was für eine Art von Zahl es sich jeweils handelt, damit wir wissen, in welchem Datentyp wir sie speichern können. (n) für eine ganze natürliche Zahl und (t) für eine Zeit in Sekunden oder Millisekunden. Wir legen also eine Liste von Zahlen an, die bei den entsprechenden Aktionen jeweils erhöht werden. Diese müssen dann regelmäßig in den Spielstand geschrieben und beim nächsten Start wieder ausgelesen werden. Aktuell kann unser Spielstand nur manuell per Klick auf einen Button gespeichert oder geladen werden. Wenn GameMaster später ein automatisches Speichern unterstützen soll, bleibt noch abzuwägen wie oft diese Daten wirklich geschrieben werden sollen. Da solche Prozesse etwas Zeit benötigen, steht es nicht zur Debatte, diese bei jeder Änderung sofort zu schreiben, sondern immer in gewissen Intervallen oder bei bestimmten Aktionen.

Zu diesen allgemeinen Statistiken gesellen sich noch solche, die vom jeweiligen Minispiel abhängen. Für unser Kartenspiel Pairs aus dem letzten Tagebucheintrag bietet sich beispielsweise noch die Anzahl aufgedeckter Kartenpaare an. Die oben erwähnten „Punkte“ können je nach Spiel für etwas anderes eingesetzt werden. In diesem Fall die Anzahl der zusammenpassenden aufgedeckten Kartenpaare und bei Gong die „geschossenen Tore“. Danach können wir die neuen Achievements anlegen, inklusive Bildern und Kurzbeschreibungen. Bei Pairs können wir nun beispielsweise ein Achievement für das erste gefundene Paar verleihen, aber auch mitzählen und ein weiteres für die ersten 100 gefundenen Paare.


Zwei der Achievements von Pairs wurden freigeschaltet
Das Auge spielt mit
Wie angekündigt, wollen wir dem Spieler anbieten, die gesammelten Statistiken auch selbst einsehen zu können. Dazu wurde abermals ein neuer Menü-Unterpunkt angelegt. Dieses Mal handelt es sich aber um einen kleinen Button mit Diagrammicon rechts neben den bisherigen Buttons, um nicht alles zu überladen. Außerdem schaut man hier vermutlich seltener rein, als in die anderen Untermenüs. Auf der Statistikseite finden wir dann die Zahlen mit Kurzbeschreibungen. So kann man immer prüfen, wie viel man noch von etwas benötigt, um an bestimmte Achievements zu kommen, sofern man weiß was dazu nötig ist, was sich meist an den noch nicht freigeschalteten Achievements ablesen lässt. Damit das Ganze etwas beeindruckender aussieht, wollte ich Diagramme anbieten. So habe ich es mir erlaubt zunächst ein Tortendiagramm zu implementieren. Für solche Grafiken bieten sich natürlich nur zusammenhängende Werte an, etwa die Anzahl der gemachten Spiele, der Anzahl der gewonnen Spiele gegenübergestellt. An dieser Stelle sei erwähnt, dass ich bewusst entschieden habe, die Anzahl der verlorenen Spiele nicht aufzuzeichnen. Wir wollen einen Spieler nicht daran erinnern, wie schlecht er einmal war. 😉 Es sei also angemerkt, dass nicht gewonnene Spiele nicht automatisch verlorene Spiele sind. Es kann auch ein Unentschieden geben oder man kann ein Spiel vorzeitig abgebrochen haben. Außerdem verleitet ein solcher negativer Zähler manche Leute dazu, absichtlich ein Spiel abzubrechen, wenn ein Gewinnen nicht mehr in Aussicht ist, um schlechte Statistiken zu vermeiden. Dies wäre vor allem in Mehrspielerpartien unangebracht.


Beschriftetes Tortendiagramm
Der Kuchen lügt nicht
Das Tortendiagramm war eigentlich die einzige, wenn auch nur kleine, mathematische Herausforderung bei dieser Thematik. Aber ich hatte auch Lust auszuprobieren, ob ich das einfach so hinbekomme. Glücklicherweise bietet unsere Entwicklungsumgebung Unity 3D bereits die Möglichkeit, angezeigte Bilder „kreisförmig aufzufüllen“. Es gibt verschiedene Füll-Funktionen, die für Dinge wie Lebens- oder Fortschrittsbalken gedacht sind. Dazu gehört auch diese Kreisausschnittvariante. Es muss lediglich eine Prozentzahl (0 bis 1) angegeben werden. Es bleibt also nur noch auszurechnen, wie viel Prozent die Anteile jeweils einnehmen und die Kreisausschnitte so zu drehen, dass sie einen vollen Kreis bilden. Um das mal am Beispiel des obigen Screenshots zu verdeutlichen: wir haben zwei von drei Spielen gewonnen. Es gibt also einen Ausschnitt mit 33,3% und einen mit 66,6%. Der zweite Ausschnitt muss dann um den prozentualen Anteil von 360° des ersten gedreht werden. Wenn der rote mit 33,3% der erste ist, muss der zweite um 33,3% (ein Drittel) von 360°, also 120° gedreht werden. Ein dritter Ausschnitt müsste dann um die Anteile der beiden ersten gedreht werden und so weiter. Durchaus etwas komplizierter ist dann die Berechnung der Positionen und Ausrichtungen der kleinen Beschriftungen, welche ebenfalls im Screenshot zu sehen sind. Doch ich möchte euch nicht mit weiteren Rechnungen langweilen.

Das soll es für heute gewesen sein. Nächstes Mal wird es etwas fischig – das dritte Minispiel steht an. Bis die Tage!

Ihr möchtet die Auszüge aus dem Leben eines Entwicklers lieber in englischer Sprache lesen? Unter diesem Link findet ihr die englische Version dieses Tagebucheintrags! ##neue_seite##
##titel:Teil 18: Fizhy## Teil 18: Fizhy
Es wird Zeit für etwas Spiele-Nachwuchs! Das dritte Minispiel steht auf der Matte! Es handelt sich um ein Remake des ersten Spieles, welches ich für die Öffentlichkeit in den App Stores von Apple und Google publiziert habe: Fizhy. Es ist ein Puzzlespiel welches dem Prinzip des Nintendo Klassikers Dr. Mario folgt. Ihr könnt die alte Version auch gerne selbst ausprobieren, bevor ihr mehr darüber lest und sie kostenlos und werbefrei für iOS und Android beziehen.

Beschreibung
Anstatt die genaue Funktionsweise des Spiels zu erklären, erlaube ich mir, die Beschreibung aus den App Stores zu zitieren:

Fange alle Fische im Teich dieser idyllischen Berglandschaft, indem du Ketten von mindestens vier gleichfarbigen Fischen bzw. Köderteilen horizontal oder vertikal anordnest.

Die Köder werden in die Mitte des Teiches geworfen und sinken langsam herab.
Sie können nach rechts, links oder nach unten bewegt und um 90° gedreht werden.
Sobald sich eine Kette von mindestens vier bildet, beißen alle beteiligten Fische an und werden an Land gezogen.

Messe dich mit anderen indem du versuchst, einen höheren Highscore zu erreichen. Kombinationen von mehreren Fischen in einem Zug geben mehr Punkte.
Spiele weitere und schwerere Level frei und besuche drei verschiedene Welten mit unterschiedlichen Schwierigkeitsstufen.
Jede Welt bietet eine einzigartige Umgebung mit jeweils 20 Stufen. (Oder sind es sogar noch mehr?)

Schaffst du es alle Errungenschaften (Achievements) freizuspielen?
Oder landest du sogar an der Spitze der Highscore Liste (Leaderboard) einer jeden Welt?

Wische mit deinen Fingern über den Bildschirm, um die Köder zu bewegen. Alternativ kannst du auch ein Gamepad verwenden, welches mit deinem Gerät kompatibel ist.
Ein besonderes Feature dieses Spiels ist die optionale stereoskopische Ansicht, durch die das Geschehen in 3D betrachtet werden kann.
Hierfür kann ein 3D Fernseher angeschlossen werden, eine VR-Brillen-Halterung für dein Gerät verwendet werden, oder du schielst einfach.

Das Spiel erlaubt dir eine Vielzahl an Einstellungen vorzunehmen, sei es um grafische Qualität gegen Geschwindigkeit abzuwägen, die fetzige Hintergrundmusik zu deaktivieren, eine andere Sprache zu nutzen oder den Farbenblindheitsmodus zu aktivieren, welcher durch größtmögliche Helligkeitsunterschiede in den Farben bei Sehschwächen helfen soll.

Die Neuauflage
Wie bereits bei unserem zweiten Minispiel, entwickeln wir auch dieses als eigenständiges Projekt, bevor wir es in GameMaster integrieren. Da wir mit der Entwicklungsumgebung Unity 3D arbeiten und das alte Spiel mit dem GameMaker implementiert wurde, müssen wir leider alles von Grund auf neu erarbeiten. Auch die im GameMaker verwendete Skriptsprache „Game Maker Language“ (gml) unterscheidet sich von C# stark, so dass sich einzelne Codes nur schwierig wiederverwenden ließen. Vor allem soll aber auch die Grafik stark verbessert werden und zu echtem 3D angehoben werden. Dafür habe ich ein Setting ganz nach meinem Geschmack ausgewählt: Ein japanischer Zen-Garten. Tatsächlich wird die Grafik zur größten Herausforderung in diesem Miniprojekt und soll mir ermöglichen, Neues auf diesem Gebiet zu lernen, was mir später im Hauptprojekt helfen wird.

Die Implementierung ist nahezu trivial im Vergleich zum Aufwand, den ich für die Welt-Gestaltung betreibe, vor allem wenn man alles schon mal programmiert hat. Es werden nach und nach Köder ins Wasser geworfen, welche in immer gleichen Zeitschritten ein Feld nach unten fallen. Wir benötigen also einen Timer, der dafür sorgt, dass gewisser Code immer nach einer fest definierten Millisekundenzahl ausgeführt wird. Hier ist es besonders wichtig, dass man die echte verstrichene Zeit verwendet und nicht etwa die Anzahl an Durchläufen des Haupt-Codes zählt. Ein Beispiel: Wir stellen die Bilder pro Sekunde (FPS) auf 60 ein und könnten somit davon ausgehen, dass nach einem Durchlauf, bzw. nach einem Frame, 1/60 Sekunden vergangen sind. Jedoch ist dies der Idealfall, der nur selten der Realität entspricht. Während der Köder fällt, kann er nach links, rechts und nach unten bewegt werden, oder um 90° im oder gegen den Uhrzeigersinn gedreht werden. Das Drehen ist etwas problematisch, da wir das Köderobjekt nicht um einen bestimmten Punkt drehen können, ohne dass es aus dem Raster herausragen würde. Mit jeder Drehung ist also auch eine Verschiebung (Translation) nötig.


Es wird nicht um einen bestimmten Punkt gedreht.
Genau genommen habe ich es so gemacht, dass er sich nur zwischen 90° hin und her drehen kann und die restlichen Ausrichtungen (180° und 270°) durch Tauschen der beiden Köderteile verwirklicht wird. Das erleichtert mir später das Verwalten der Referenzen zwischen den ganzen Köder-Teilobjekten. Wenn ein Köder schließlich nicht mehr weiter fallen kann, weil er auf dem Boden, einem anderen Köder oder auf einem Fisch gelandet ist, werden alle Köderteile und Fische auf dem Spielfeld durchlaufen und auf Ketten gleichfarbiger Objekte geprüft. Es müssen mindestens vier Objekte horizontal oder vertikal ohne Unterbrechung miteinander verbunden sein, damit diese „aufgelöst“ werden können. Die betroffenen Objekte werden dann vorgemerkt und in weiteren Zeitschritten nacheinander aufgelöst, bzw. Fische an Land gezogen. Es muss beachtet werden, dass ein Objekt Teil einer horizontalen und vertikalen Verbindung sein kann, also theoretisch zweimal aufgelöst würde. Durch mehrere nacheinander gefangene Fische, ohne dass ein neuer Köder eingeworfen wurde, entstehen Combos die mehr Punkte geben. Nach jedem Fang verdoppelt sich die Punktzahl. Des weiteren muss beachtet werden, dass nach einem Auflösen oder Fangen, andere Köderteile eventuell nirgends mehr aufliegen und ebenfalls wieder fallen können. Somit können abermals neue Kombos erzeugt werden, bevor ein weiterer Köder eingeworfen werden kann. Ist diese Kettenreaktion abgeschlossen, wird geprüft ob alle Fische gefangen wurden – falls ja ist der Level geschafft. Sollte hingegen kein Platz mehr sein, wo der Köder eingeworfen wird, ist das Spiel verloren.


Der Titelbildschirm
Die räumliche Welt
Die Gestaltung einer dreidimensionalen Umgebung ist deutlich aufwändiger als das Zeichnen der Hintergründe für die alte Version von Fizhy. Alleine über das Modellieren von Objekten könnte man zahlreiche Tagebucheinträge füllen. Tatsächlich nehme ich auch mal die Modellierungssoftware Blender zur Hilfe, um etwas auszubessern. Jedoch habe ich weder die Zeit noch die Erfahrung, alles selbst zu erstellen, damit es in einem für mich akzeptablen Zeitrahmen und einer passenden Qualität fertig würde. Deswegen suche ich nach unterschiedlichsten Ressourcen, für kostenlos kommerziell nutzbare 3D-Objekte und Texturen. So kann ich nach und nach alle relevanten Bestandteile zusammensuchen, wie sie im Ergebnis zu sehen sind. Glücklicherweise finde ich bereits einen japanischen Garten, der schon gut gelungen war: Japanese teahouse with garden free 3D model. Allerdings sind hier keine Texturen enthalten und es herrscht enorme Unordnung in der Hierarchie der vielen tausend Objekte. Ich investiere also viel Zeit, um die Objekte sinnvoll zu sortieren, damit sie auch hierarchisch beeinflusst werden können. Z.B. sollten Blätter ihren Ästen und diese ihrem Baumstamm untergeordnet sein. Ich lege die Objektgruppen so an, dass sie sich eignen, um für verschiedene Grafik-Detail-Stufen aktiviert und deaktiviert zu werden. Diese Stufen können in den Optionen des Spiels eingestellt werden.


Grafik-Details können in den Optionen verstellt werden
Bei vielen Objekten verzichte ich komplett auf Texturen und ordne ihnen nur einfarbige Materialien zu. Das spart natürlich Speicherplatz, ist leichter zu rendern und verleiht dem Spiel einen speziellen comicartigen Touch. Auch wenn der Garten so langsam nach etwas aussieht, wirkt er noch immer statisch und somit unrealistisch. Deswegen entscheide ich mich dazu etwas Wind in die Sache zu bringen und beschäftige mich erstmalig mit dieser Thematik. Schließlich läuft es darauf hinaus, dass ich alle Bäume und Büsche komplett neu als „Unity Trees“ erstelle, welche effizient von Wind beeinflusst werden können. Für dieses Thema habe ich erstmals ein bisschen Entwicklung auf Twitch gestreamt (siehe in der Unity3D Collection von meinem Twitch Account xybadtoxic). Nicht wundern, falls das Video zum Zeitpunkt des Erscheinens dieses Tagebucheintrags nicht mehr verfügbar sein sollte, Videos werden dort nach einer Weile automatisch entfernt. Sollte jedoch Interesse daran bestehen, könnte ich so etwas auch öfter machen. In dem Video sind die verschiedenen Arbeitsschritte zu sehen, die nötig sind um Bäume zu erstellen. Deswegen werde ich textuell nicht im Detail darauf eingehen. Mehr Bewegung bringe ich durch eine Skybox in die Welt – einen Himmel im Hintergrund, der sich langsam bewegt.

Es gibt noch viel mehr…
In dem fertigen Spiel steckt noch deutlich mehr verborgene Arbeit, doch dies sollten die wichtigsten Themen gewesen sein. Dazu kommt noch die Touch-Steuerung mit ihren Swipe-Gesten, welche perfekt ausbalanciert werden müssen. Relevant sind die Strecke, die ein Finger zurücklegen muss, bevor sich ein Köder bewegt und vor allem die Zeitabstände, zwischen den einzelnen Bewegungen. Es muss eine UI (User Interface) gestaltet, die Punkte gezählt und zusammen mit anderen Daten, wie etwa dem Levelfortschritt, gespeichert werden. Eine weitere Herausforderung war es, Spielfeld und Kamera so aufeinander abzustimmen, dass der Platz auf einem beliebig großen Bildschirm perfekt genutzt werden kann. Vor allem die Formate der Bildschirme unterscheiden sich heute stark. So sind Tablets nahezu quadratisch während aktuelle Smartphones wie das iPhone X ein extra breites Bild haben. Die UI muss sich entsprechend skalieren, da bei neuen Geräten die Pixeldichte so hoch ist, dass einzelne Buttons sonst winzig klein wären. Dann kommt noch das Erstellen der Store-Einträge für Google Play und iTunes mit etlichen Texten und Informationen auf eventuell mehreren Sprachen und dem Anfertigen vieler Screenshots und anderer Bilder in sämtlichen Größen und Formaten. Auch ist immer mit plattformspezifischen Komplikationen zu rechnen, die es zu bewältigen gilt. Alles in allem habe ich für dieses Spiel über 100 Stunden Arbeit investiert, wie ich von meiner Zeiterfassungs-Anwendung ablesen kann. Ein Aufwand, den ich nicht für jedes Minispiel betreiben werde. Aber ich konnte so auch einiges Neues lernen und für gewisse „Fans“ meines Fizhy-Spiels habe ich gerne etwas mehr Zeit investiert.

Damit möchte ich mich für dieses Mal verabschieden. Das neue Spiel Fizhy Zen könnt ihr euch ebenfalls auf Android und iOS selbst anschauen. Der Aufwand um dieses Spiel in GameMaster einzubauen, wird auch nicht ohne sein. Bis die Tage!

Ihr möchtet die Auszüge aus dem Leben eines Entwicklers lieber in englischer Sprache lesen? Unter diesem Link findet ihr die englische Version dieses Tagebucheintrags! ##neue_seite##
##titel:Teil 19: Fizhy in GameMaster einbauen & KI## Teil 19: Fizhy in GameMaster einbauen & KI
Das letzte Mal haben wir mit Fizhy Zen ein neues Minispiel fertiggestellt, welches alleinstehend im Google Play Store für Android und Apple App Store für iOS verfügbar ist. Heute wollen wir dieses Spiel als drittes Minispiel in unser Hauptprojekt GameMaster portieren.

Die üblichen Aufgaben beim Portieren
Dieses Mal habe mir eine Art Anleitung erstellt, für die einzelnen Schritte, die immer nötig sind, wenn ich ein neues Spiel einbauen möchte. Ich hoffe damit den Prozess weiter optimieren zu können, damit es in Zukunft noch schneller geht. Nachdem die Dateien aus dem Fizhy-Projekt in das GameMaster-Projekt kopiert wurden, gibt es nämlich vieles zu tun. Ich führe ein neues Spiel-Modul ein, damit man Fizhy via GameGuy starten kann, aber auch eine Schnellstart-Referenz, um den Prozess zum Testen des Minispiels abzukürzen. Vorher hart kodierte Texte müssen nun in die Übersetzungsdateien ausgelagert und von dort ausgelesen werden. Es müssen Referenzen an verschiedene Objekte verteilt werden, damit diese dann entsprechende Infos finden. Beispielsweise muss die GameGuy-Konsole wissen, welches Objekt es zu instanziieren hat, um das Spiel zu starten. Alles in Allem sehr viele kleine Aufgaben die einem keinen Spaß bereiten können. Ein großer Anteil davon ist nötig, bevor das neue Spiel überhaupt erst gestartet werden kann. Weitere Aufgaben wie das Anlegen eines Skilltrees, Achievements und Optionen, oder das Ermöglichen von Spielständen und (Online-) Multiplayer bieten sich erst an, nachdem das Spiel erfolgreich eingebunden wurde.

Leider habe ich einen Punkt im Voraus nicht gut durchdacht. Fizhy Zen ist nicht auf die Art Multiplayer ausgelegt, wie ich ihn umsetzen würde. Das Problem ist die Struktur der Objekte: Spielfeld, Fische, Köder, Angel usw. sind nicht dem Spieler untergeordnet, sondern dem Spiel selbst. Mit anderen Worten, es ist ohne eine große Umstrukturierung im Code nicht möglich, ein Spielfeld pro Spieler zu haben. Denkbar problemlos wäre stattdessen eine Art Koop-Spiel umzusetzen, bei dem zwei Spieler gleichzeitig an einem Spielfeld angeln, doch so habe ich mir das nicht vorgestellt und somit muss ich in den sauren Apfel beißen und vieles umbauen.

Eine künstliche Intelligenz
Im Vergleich zu den beiden bereits vorhandenen Minispielen ist eine KI bei diesem Spiel eine gewaltige Herausforderung. Selten greife ich direkt auf theoretisches Wissen zurück, welches ich mir im Studium angeeignet habe, doch hier fehlt es mir an praktischer Erfahrung. Begriffe wie „Backtracking“, „Breiten-“ und „Tiefensuche“ sowie damit verbundene Vorgänge werden sofort in Erinnerung gerufen. Vielleicht das spannendste Thema, dem ich in diesem Projekt bisher gegenüber stehe. Allerdings muss sehr viel geplant und durchdacht werden, bevor man zu viele Schritte in die falsche Richtung unternimmt. Eine ideale Lösung gibt es hier nicht, solange man den üblichen natürlichen Einschränkungen unterliegt, wie begrenztem Speicherplatz und begrenzter Laufzeit. Perfekt spielen könnte eine KI mit einer Datenbank, mit optimalen Spielzügen für jede mögliche Situation. Diese Option fällt weg, selbst wenn der benötigte Speicherplatz dafür heutzutage weniger das Problem wäre, bräuchte ich dafür womöglich Jahre, sofern ich so etwas überhaupt manuell anlegen könnte. Man kennt das vom Schach – man kann nicht immer alle folgende Züge ausprobieren, um den besten Ablauf zu bestimmen. Hier wird meist eine Kombination aus einem Suchalgorithmus und einer Datenbank wichtiger Züge verwendet.

Ich beginne zunächst damit einen rekursiven Suchalgorithmus vorzubereiten: Eine Funktion, die für jeden eingeworfenen Köder alle erreichbaren Felder auf dem Spielfeld testen soll. In einer vorgegebenen Reihenfolge testet er jede mögliche Köder-Bewegung nacheinander durch. Man kann unterscheiden, ob er zunächst nach links oder rechts geht, also in die Breite (Breitensuche), oder nach unten in die Tiefe (Tiefensuche). Die KI läuft also „Pfade“ im Spielfeld ab. Dies tut sie allerdings nicht im sichtbaren Spielfeld, sondern in einer internen Datenstruktur, welche eine Kopie davon darstellt. Bei jedem Feld, auf dem ein Köder liegen bleiben kann, weil sich unter ihm ein Fisch, ein anderer Köder, oder der Boden befindet, wird eine Testfunktion ausgeführt. Dieser Test soll bestimmen wie gut oder schlecht die Position ist und bewertet sie mit einer Punktzahl. Immer wenn der Köder in eine Sackgasse läuft, also keine weitere Richtung zur Verfügung hat, geht man zum vorherigen Feld zurück und nutzt von dort aus die nächste freie verbliebene Richtung. Dieses Vorgehen nennt man dann Backtracking, in diesem Fall ein rekursives. Jedes Feld welches bereits durchlaufen wurde, wird zudem markiert, damit man es nicht erneut besucht, von einem anderen Feld ausgehend. Am Ende wird der Pfad gewählt, welcher zur Position mit der höchsten Punktzahl führt. Dazu wird bei jedem Test der aktuelle Pfad gespeichert, wenn er die bisher höchste Punktzahl überboten hat.


Zur Veranschaulichung kann ich mir beim Testen die Pfade der Suche ausgeben lassen.
Die Bewertungsfunktion
Unser Suchalgorithmus versucht also verschiedene Lösungen zu bewerten, ohne die Folgen ihres Handelns zu beachten. Ein übliches Vorgehen wäre es, die Punkte zur Bewertung zu nutzen, welche auch der Spieler bekäme. Bei Fizhy wäre das also die Punktzahl für das Einfangen von Fischen. Dass dies hier nicht genügen kann, ist offensichtlich – es sind meist einige Züge im Voraus nötig, um Fische fangen zu können. Außerdem ist es nicht stets die beste Strategie, möglichst schnell viele Fische zu fangen, da man sich so andere Fische verbauen könnte. Zudem habe ich beschlossen, immer nur den aktuellen Zug zu beachten und keine Folgezüge durchzurechnen. Immerhin kann man die nächsten drei Köder sehen, es wäre also fair. Aber ich möchte zunächst vermeiden, dass zu lange Rechenprozesse Probleme verursachen könnten, vor allem auf schwächeren Geräten.

Da ist sie also, die größte Herausforderung in diesem Projekt bisher – die Bewertungsfunktion zum Testen der Positionen. Ausgehend von der zu testenden Position schauen wir für beide Köderteile in jeweils alle vier Richtungen, um zu sehen was für Köder und Fische sich dort befinden. Einfach gesagt möchten wir zählen wie viele gleichfarbige und andersfarbige Objekte sich neben uns befinden und bei gleicher Farbe mehr Punkte geben und bei anderer Farbe weniger oder gar negative. Das ist aber leichter gesagt als getan. Zum einen sollten leere Felder zwischen dem Köder und den umliegenden Objekten eine Rolle spielen. Sie sollten die Wertung insoweit beeinflussen, dass der Köder näher an die relevanten Objekte gelegt werden. Also gewichten wir die Punkte in einem Verhältnis zur Entfernung der Objekte zum aktuellen Feld. Zum anderen sollten gleichfarbige Objekte hinter einem andersfarbigen Objekt nicht mehr, oder nicht viel, zur Bewertung beitragen, da sie mit dem Köder keine direkte Linie bilden können. Außerdem müssen wir auch nicht endlos weit in alle Richtungen schauen, sondern natürlich nur bis zum Rand des Spielfeldes oder einer gewissen Entfernung. Beispielsweise würden sich vier oder mehr gleichfarbige Objekte sofort auflösen, also muss man nur bis zu einer Entfernung von drei oder vier in alle Richtungen schauen. Ein Sonderfall sind Objekte über dem aktuellen Feld: Eventuell würden sich die Köder beim Aufstapeln bereits auflösen, bevor das Objekt erreicht wird. Außerdem muss darauf geachtet werden, dass es überhaupt genügend Platz gibt, um weitere Köderteile unterzubringen mit denen die Kette abgeschlossen werden kann. Demnach müsste man zudem nochmals in die gegenüberliegende Richtung schauen, ob dort bereits gleichfarbige liegen oder noch Platz ist. Dabei muss natürlich auch jeweils das andere Köderteil beachtet werden, welches zum Zeitpunkt des Tests noch kein Teil des Spielfelds ist. Dazu kommt noch die Tatsache, dass man sich so leicht den Einwurfbereich, oben in der Mitte des Spielfelds, verbauen kann. Deshalb sollte man wiederum eine negative Bewertung in Abhängigkeit der Entfernung zum Einwurfpunkt geben.

Wie ihr seht, kommen unzählige kleine Sonderfälle auf, welche das Implementieren schwierig gestalten. Und selbst wenn alles beachtet wird, muss lange mit den Punkten experimentiert und beobachtet werden, um gute Werte zu finden. Im folgenden ein paar Basis-Beispielswerte:

Punkte für gleichfarbigen Fisch: 200
Punkte für gleichfarbigen Köder: 30
Punkte für andersfarbigen Fisch: -150
Punkte für andersfarbigen Köder: -40
Etwas kann aufgelöst werden: 350
Nicht genug Platz um die Kette abzuschließen: -50

Sind alle diese Dinge umgesetzt, finden sich noch weitere Sonderfälle. Etwa ein Fisch, der weit oben liegt und von oben nicht genug Platz bietet, um gefangen zu werden. Wie bereits erwähnt kann dies zur Folge haben, dass dieser von unten nicht erreicht werden kann, da sich ein gleichfarbiger Stapel bereits vorher auflösen würde. Deshalb wird hier die Regel benötigt, andere Farben zu bevorzugen. Außerdem folgt daraus, dass man nach oben mehr Felder kontrollieren muss, als nach unten oder zur Seite. Eine weitere Beobachtung zeigt, dass es schwierig für die KI ist, an verbaute Fische zu kommen, wenn das Auflösen anderer Köderteile an einem anderen Ort, ebenfalls so viele Punkte gibt, wie den Fisch freizuräumen. Also brauchen wir hier wieder eine Regel, welche besagt dass Teile in der Nähe von Fischen bevorzugt aufgelöst werden sollen. Dieses Thema für sich ist bereits ein komplexes Problem. Genau genommen muss für jedes Feld bekannt sein, wie viele Fische in ihrer Umgebung liegen, gewichtet mit deren Entfernungen. Ein so gewonnener Wert kann dann auf die bisherige Bewertung addiert werden. Es ist allerdings nicht einfach, ein gutes Mittelmaß zu finden, so dass der gewünschte Bereich zwar bevorzugt wird, aber nicht ausschließlich bespielt wird.


Hier sieht man die Gewichtungen der Felder in Abhängigkeit zu ihrer Fisch-Nähe.
Die KI ist noch weit davon entfernt perfekt zu spielen – muss sie aber auch nicht, man möchte ja noch gewinnen können. Allerdings befürchte ich, dass sie auch nicht gut genug spielt, um eine Herausforderung für einen fortgeschrittenen Spieler zu sein. Trotzdem muss ich voranschreiten und darf mich nicht zu lange an einer Sache festbeißen, auch wenn ich ungern Dinge unfertig liegen lasse.

Multiplayer
Da die KI-Entwicklung bereits so viel Zeit eingenommen hat, verschiebe ich die Implementierung des Online-Multiplayer fürs Erste. Einen lokalen Multiplayer möchte ich aber gleich umsetzen. Wie zu Beginn dieses Tagebucheintrag erwähnt, ist hierfür eine umfangreiche Umstrukturierung des Codes nötig. Alle Instanzen, die zu einem bestimmten Spieler gehören, müssen diesem untergeordnet werden, anstatt dem Spiel selbst. Selbstredend muss auch die Mechanik angepasst werden. Beispielsweise ist zu entscheiden, wann ein Spiel zuende ist. Wenn wir vier Spieler haben und einer hat seinen Level beendet, ist das Spiel dann für alle vorbei oder können die restlichen noch um den zweiten, dritten und vierten Platz kämpfen? Eine weitere große Neuerung ist, dass die Spieler verschiedene Level spielen können. Also benötigen wir vor dem Start ein weiteres Menü, in dem für alle Spieler dieser festgelegt werden kann.


Jeder Spieler kann in einem anderen Level starten.
Außerdem müssen je nach Spieleranzahl die Positionen der Spielfelder und der UI-Texte angepasst werden. Vor allem wenn wir verschiedene Bildschirmgrößen und Seitenverhältnisse unterstützen wollen, kann dies zu einer Herausforderung werden. Nicht zu vergessen, dass ich noch immer die 3DS-Auflösung unterstütze und auf solch einem kleinen Bildschirm nicht viel Platz ist.


Vier Spieler auf einem 3DS-Bildschirm – es bleibt noch viel zu optimieren.
Skills und Achievements
Zu guter Letzt möchte ich noch kurz auf die anderen oben erwähnten Themen eingehen. Auch Fizhy bekommt einen Fähigkeiten-Baum. Wie gewohnt bieten wir das Erlernen verschiedener KI-Schwierigkeitsgrade an. Dazu kommt die grafische Aufwertung von 2D-Sprites zu dreidimensionalen Modellen und der bereits gezeigte lokale Multiplayer für bis zu vier Spieler.


Diese Fähigkeiten werden bisher angeboten.
Sobald die 3D-Fische erlernt sind, können diese in den Optionen jederzeit aktiviert und deaktiviert werden. Achievements setze ich gleich mehrere um. Teilweise kann ich hier Grafiken aus der alten Fizhy-Version wiederverwerten. Man kann diese Errungenschaften freischalten, indem man Fische fängt, Köder auflöst, Kombos macht, Spiele gewinnt und schließlich alle Achievements gesammelt hat.


Ein paar simple Grafiken für die Fizhy-Achievements
Damit möchte ich den heutigen Tagebucheintrag abschließen – da ist ganz schön was zusammengekommen. Und das obwohl ich die Themen nur ankratze und vieles gar nicht behandle. Das nächste Mal möchte ich auf die Community eingehen, welche hinter solch einem Projekt stehen sollte. Sie ist in vielerlei Hinsicht unerlässlich. Neben der Gesellschaft gleichgesinnter stehen weitere Aspekte im Vordergrund, von reiner Informationsfindung über Support bis Marketing.

Ihr möchtet die Auszüge aus dem Leben eines Entwicklers lieber in englischer Sprache lesen? Unter diesem Link findet ihr die englische Version dieses Tagebucheintrags! ##neue_seite##
##titel:Teil 20: Erschaffen einer Community## Teil 20: Erschaffen einer Community
Nachdem wir in den letzten beiden Tagebucheinträgen vorerst mit Fizhy abgeschlossen haben, kommen wir nun zu einem ganz anderen Thema. Hinter jedem bekannten Spiel steckt eine Community. Sei es auf Facebook, Reddit, Fan-Wikis oder anderen sozialen Plattformen. Sobald sich ein Spiel einen Namen macht, entstehen solche wie von ganz alleine. Manchmal gibt es auch Communitys innerhalb der Spiele selbst oder auf speziellen Internetseiten, die von den Entwicklern zur Verfügung gestellt werden. Liest man über den Prozess der Spieleentwicklung, findet man häufig das Aufbauen einer Community bereits ganz am Anfang. Es heißt, man könne nie früh genug damit beginnen. Wir wollen uns heute anschauen, wozu eine solche Community gut ist und die ersten Schritte tun eine solche zu erschaffen.

Zweck einer Community
Hinter einer Community-Gründung können etliche Gründe stehen. Die Basis ist die Gesellschaft unter Gleichgesinnten, die sich für die gleiche Sache interessieren und darüber reden können wollen. Am vielleicht häufigsten liegen Fragen vor, zu denen man eine Antwort sucht, wenn man einer einer Spiel-Community beitritt – „Wie schaffe ich diesen Level?“ So bilden sich oft ganze Fan-Wikis (Enzyklopädien), welche sich darauf spezialisiert haben Fragen zu beantworten, die noch nicht einmal gestellt wurden. Ein anderer Grund kann das Prahlen oder Suchen nach Kritik und Meinungen anderer sein – „Was haltet ihr von meiner neuen Ausrüstung und meinen Statuswerten?“ Man sucht also eventuell nach Anerkennung und möchte zeigen was man erreicht hat. Oder man möchte sich verbessern, mit anderen vergleichen und daraus lernen. Im Prinzip kann man hier Gründe für jede Art von zwischenmenschlicher Konversation zugrunde legen. Natürlich kann es auch praktische Nutzen geben, welche sich speziell aus Features des Spiels ergeben. Beispielsweise kann man sich zu einem Gilden-Raid verabreden oder einen Handels- oder Tauschpartner für Items finden.

Aus Sicht der Publisher und Entwickler ergeben sich ebenfalls Vorteile aus einer Community. Oft bietet sich so ein einfacherer Weg, um kostengünstig und effizient Support leisten zu können. Anstatt auf E-Mails und Anrufe antworten zu müssen, können sie dies an einem Ort regeln, an dem sie bereits auf ein gesammeltes Wissen verweisen und zurückgreifen können. Häufig können Hilfe-Anfragen bereits von anderen Benutzern beantwortet werden, ohne dass das eigene Team einschreiten muss. Des Weiteren liefert eine Community umfangreiches Feedback. So können die Entwickler frühzeitig reagieren und etwas ändern oder erfahren was gut ankommt und in welche Richtung sie weitermachen sollten. Am wichtigsten jedoch, ist womöglich der kostenlose Werbeeffekt. So verbreitet sich Kenntnis und Eindrücke über das Spiel ohne hohe Kosten.

Die Qual der Wahl
Doch wo soll man anfangen? Welche sozialen Plattformen sind gut, was sind die Vor- und Nachteile? Sollte man möglichst überall vertreten sein oder sich besser auf ein Netzwerk konzentrieren? Diese Fragen sind nicht einfach zu beantworten und hängen zum einen vom Spiel ab, welches repräsentiert werden soll, und zum anderen davon, ob man genügend Kapazitäten aufbringen kann all diese zu moderieren. Man kann zunächst Schwerpunkte auf die oben genannten Vorteile legen, um eine bessere Entscheidung zu treffen. Ich möchte als erstes eine zentrale Anlaufstelle schaffen, bei der Leute mich kontaktieren und sich in den Entwicklungsprozess einbringen können, wenn sie möchten. Facebook, Twitter und Co. eignen sich besser um Neuigkeiten zu verbreiten und stetiges Feedback in der Entwicklung zu geben. Solche Plattformen leben vor allem von einer Regelmäßigkeit und Benutzer springen schnell ab, wenn sie nicht genügend Material vorgelegt bekommen. Stattdessen möchte ich lieber einen Ort, an dem ich alle Infos persistent ablegen kann und eine gewisse Übersichtlichkeit gewährleistet wird. So habe ich mich nach vielen Recherchen und Versuchen entschieden Discord in den Mittelpunkt zu stellen. „Discord ist ein kostenloses Programm für Instant Messaging, Chat, Sprachkonferenzen und Videokonferenzen, das für Computer und Mobilgeräte entwickelt wurde, ‚um Gamer zusammenzubringen‘. Der Dienst kann als Webanwendung im Browser oder mit proprietärer Client-Software auf allen gängigen Betriebssystemen genutzt werden. Im Mai 2018 verzeichnete der Dienst 130 Millionen Nutzer.“ [Wikipedia]

Man sollte unterscheiden, ob die Webpräsenz, die man schaffen möchte, das Spiel, die Firma oder den Entwickler selbst präsentiert. So habe ich einen Discord-Server für mein Spiel GameMaster sowie einen für meine Person und Firma angelegt. Vertreten bin ich als Person, Entwickler oder Ein-Personen-Gewerbe dennoch auf etlichen weiteren Plattformen. Besonders viel Arbeit stecke ich zur Zeit in meinen Instagram-Account, auf dem ich hauptsächlich News über meine Entwicklung, aber auch privates poste. Mehr auf die Entwicklung konzentriert, poste ich auf Twitter, aber deutlich zurückhaltender. Als reines Entwickler-Gewerbe bin ich ebenfalls auf Facebook vertreten. Damit sind ein paar der größten sozialen Netze abgedeckt und die Inhalte unterschiedlich priorisiert, nach meinem persönlichen Ermessen für typische Zielgruppen auf den jeweiligen Plattformen. Ich bin auch auf deutlich mehr Plattformen zu finden, die ich nicht alle auflisten werde. Die meisten dienen hauptsächlich zur Auffindbarkeit und verweisen dann wiederum auf andere, wie etwa Discord. Ich würde mich natürlich sehr freuen, wenn der eine oder andere Leser seinen Weg in meine Communitys findet und mich unterstützt.

Discord einrichten
Zunächst benötigen wir natürlich einen Account, welchen wir auf discordapp.com erstellen können, sofern noch nicht passiert. Wie die Wikipedia-Beschreibung bereits verraten hat, können wir dies direkt im Browser, aber auch in Anwendungen bzw. Apps, für verschiedene Plattformen tun. Sobald man eingeloggt ist, kann sicher jeder eigene Server anlegen, indem er links auf das Plus in seiner Server-Liste klickt.


Der Button zum Hinzufügen eines neuen Servers, direkt unter den GameMaster und BadToxic-Servern
Danach könnt ihr nach belieben eigene Text- und Voice-Channels (Kanäle) anlegen und die ersten Benutzer einladen. Aber ich würde wohl kaum im Stil einer Anleitung schreiben, wäre alles so trivial wie diese ersten Schritte. 😉 Am besten gehe ich gleich auf ein kritisches Thema ein – Spam und Schutz dagegen. Wenn man einen Server öffentlich zugänglich macht, läuft man immer Gefahr, dass Leute mit schlechten Absichten reinkommen und Unfug treiben. Dies kann sich in verschiedenen Formen äußern. Benutzer können in allen Channels Spam, Werbung oder unsittliche Kommentare verbreiten. Sie können Links zu schädlichen Dingen oder Phishing-Versuchen posten. Sie können außerdem alle anderen Benutzer sehen, welche sich auf dem Server befinden und diese ebenfalls privat anschreiben und mit gleichem nerven. Man kann ebenso Bots benutzen um diese Angriffe zu automatisieren. So kann es vorkommen, dass ganze Benutzergruppen sich den Spaß machen, einen Server nach dem anderen zu besuchen, um diese mit vielen Nachrichten pro Sekunde vollzuspammen und somit unerträglich zu machen. Natürlich kann man als Admin solche Benutzer blockieren und kicken, aber das schützt nicht davor, dass sich diese Angreifer neue Accounts anlegen und von vorne beginnen oder andere kommen und gleiches tun. Es ist schwierig, etwas gegen solche Dinge zu unternehmen ohne den guten Benutzern all ihre Freiheiten zu nehmen. Doch es gibt Mittel und die werde ich euch kurz erklären.

Discord-Türsteher und -Rollen
Ich habe verschiedene Bots und Rollen verwendet, um eine Art „Türsteher“ (Gatekeeper) zu schaffen, der möglichst nur friedliche Leute auf den Server lassen sollte. Dies funktioniert folgendermaßen: es gibt einen Kanal namens „Welcome“, welcher anfangs der einzige für jeden sichtbare ist. Dort muss man erst eine bestimmte Handlung durchführen, bevor man Zugriff auf die anderen Kanäle bekommt. In meinem Fall muss man mit einem bestimmten Emoji auf einen Text „reagieren“. Diese sogenannten „Reaktionen“, sind eine Discord-Funktion, die es erlaubt Symbole direkt unter einen Beitrag zu setzen. Dies kennt man gegebenenfalls bereits von Facebook, wenn man neu bei Discord ist. Ich habe also eine kleine Liste an Regeln aufgeschrieben, denen man mit einem Häkchen-Symbol zustimmen muss, damit der restliche Server freigeschaltet wird.


Der Willkommen-Kanal auf dem BadToxic-Server agiert als „Türsteher“
Der Weg über dieses Symbol hat den Vorteil, dass man in diesem Willkommens-Kanal das Schreiben komplett verbieten kann. Also kann auch niemand hier spammen. Alternativ hätte man es auch so umsetzen können, dass der Benutzer einen bestimmten Text schreiben müsste, wie z.B. „agree“ (ich stimme zu). Dann könnte man dort alle Nachrichten sofort automatisch wieder löschen lassen, um Spam zu vermeiden. Ich habe mich aber für die erste Variante entschieden, weil sie meiner Meinung nach schöner und einfacher ist.

Um dies nun technisch umzusetzen benötigen wir zunächst Rollen. Jeder Benutzer kann verschiedenen Rollen angehören und für jeden Kanal kann man für jede Rolle bestimmte Regeln festlegen. So verbieten wir jedem („@everyone“) im Willkommens-Kanal das Schreiben von Nachrichten, erstellen aber eine weitere Rolle „@Member“, welche in allen vorgesehenen Kanälen schreiben können soll.


Der Willkommen-Kanal erlaubt Neulingen nur das Lesen und „Reagieren“ via Emojis
Damit eine Rolle automatisch verteilt wird, wenn man beispielsweise wie oben beschrieben zustimmt, benötigen wir einen Bot. Ich verwende dazu Zira, der genau zu diesem Zweck existiert. Wenn man dies alles umgesetzt hat, ist man vor automatisierten Angriffen schon fast sicher – bisher habe ich noch keinen Bot gesehen, der sämtliche Reaktionen ausprobiert, um eventuell an Rollen zu kommen. Natürlich können Menschen weiterhin den Text lesen, zustimmen und selbst spammen, oder sogar einem Bot beibringen genau dies zu tun. Aber die Hürde und der Aufwand dafür ist bereits viel höher und macht dies deutlich unwahrscheinlicher. Man sollte es aber auch nicht dabei belassen, sondern noch weitere Sicherungsvorkehrungen treffen. Manches bietet Discord von Haus aus an, unter der Server-Einstellung „Moderation“. Hier kann man einen Verifizierungs-Level einstellen – wie lange ein Benutzer bereits auf einem Server sein muss, bevor er schreiben darf. Dazu noch einen Nachrichten-Filter, welcher unangebrachte Inhalte finden soll. Und zu guter Letzt eine 2-Faktor-Authentifizierung, um sich beispielsweise nur über einen Code einloggen zu können, den man auf sein Handy erhält.


Moderations-Hilfe von Discord
Inhaltsgestaltung
Nun kommen wir zum Inhalt unserer Discord-Server. Wir wollen Neuigkeiten zur Verfügung stellen, einen Ort zum Diskutieren über verschiedene relevante Themen anbieten und Support leisten können. Da unser Spiel noch in der frühen Entwicklung steckt, wiegen Neuigkeiten am meisten, da man noch nicht über viel diskutieren oder Hilfe brauchen kann. Es liegt also nahe einen „News“-Kanal anzulegen, in dem wir regelmäßig über Neuerungen berichten.


Die ersten Kanäle auf dem GameMaster-Server
Wäre es nicht toll, wenn solche Dinge von alleine gingen? Wir posten unsere News eventuell bereits (oder zusätzlich) an anderen Orten, wie Twitter, Instagram oder Facebook. Können wir diesen Prozess nicht so automatisieren, dass wir nur noch an einem Ort posten müssen und es überall landet? Es gibt vermutlich keine perfekte All-In-One-Lösung, doch einige Widgets, die einem diese Arbeit teilweise abnehmen. Hierzu möchte ich euch IFTTT („If This Then That“ = „Wenn Dies Dann Das“) und zapier vorstellen, zwei Plattformen, die es ermöglichen sämtliche Arten von Diensten miteinander zu verknüpfen. zapier ist kostenlos leider nur eingeschränkt nutzbar. Ich habe diese verwendet um verschiedene soziale Netze mit Discord zu verbinden. Beispielsweise landen meine neuen Twitter-, Instagram- oder Facebook-Posts automatisch in verschiedenen Kanälen meines BadToxic-Servers.


Meine „Applets“ auf IFTTT
In Discord werden sogenannte „Webhooks“ verwendet, um die Daten entgegen zu nehmen. Manche Dienste bieten bereits von Haus aus an, sich mit solchen Webhooks zu verbinden. Die Versionsverwaltung von GameMaster findet auf GitLab statt, welches bereits solch eine Integration anbietet. Da ich aber in diesem Projekt meinen Quellcode nicht für alle öffentlich zugänglich machen möchte, ist das „Repository“ auf privat eingestellt. Würde ich nun die native Integration nutzen, bekäme ich zwar Nachrichten an Discord gesandt, diese wären jedoch ohne Inhalt. Die Benutzer auf meinem Server würden also nur sehen, dass es ein Update am Spiel gab, jedoch nicht was aktualisiert wurde. Um dieses Problem zu lösen, nutze ich zapier, welches sich in meinem Namen bei GitLab einloggen und die Updates somit auslesen und an Discord senden kann.


Links:GitLab „Zap“ in zapier; Rechts: der Empfänger-Kanal in Discord
Die Instandhaltung
Zu guter Letzt möchte ich kurz auf die Wartung des Servers eingehen. Große Communitys haben für gewöhnlich mehrere Moderatoren, die sich um Recht und Ordnung kümmern und den Leuten helfen. Auch diesen Job müsste ich anfangs alleine übernehmen, gäbe es keine digitalen Freunde – Bots. Bei dieser Aufgabe unterstützt mich Dyno ein kostenloser Bot für automatische Moderation, das Loggen von Aktionen, Streamen von Musik im Voice-Chat und vieles mehr. Er kann beispielsweise auf vordefinierte verbotene Worte reagieren, die betreffende Nachricht löschen und den User verwarnen oder sogar bannen. Oder man kann „Cooldowns“ für bestimmte Aktionen setzen – ein Benutzer wird verwarnt, wenn er innerhalb von ein paar Sekunden mehrmals Links sendet.


Einstellungen der automatische Moderation in Dyno
Besonders nützlich finde ich bisher die Logging-Funktionen. Verschiedene Aktionen können in verschiedene Kanäle geloggt werden. So kann ich mir zum Beispiel dort anzeigen lassen, wenn jemand meinen Server verlassen hat, was ohne extra Hilfsmittel oder einer manuellen Beobachtung, nicht möglich wäre.

Damit dürften wir das Thema Communitys fürs Erste zu genüge besprochen haben. Das nächste Mal behandeln wir Shader, mit denen wir unsere Grafik aufpolieren wollen und spezielle Effekte erzielen möchten. Tatsächlich werden diese sogar wichtiger Bestandteil der Spielmechanik selbst.

Ihr möchtet die Auszüge aus dem Leben eines Entwicklers lieber in englischer Sprache lesen? Unter diesem Link findet ihr die englische Version dieses Tagebucheintrags! ##neue_seite##
##titel:Teil 21: Shader und Partikel## Teil 21: Shader und Partikel
Heute beschäftigen wir uns mit Shadern (von englisch shade für „Schattierer“). Shader sind Hardware- oder Software-Module, die bestimmte Rendering-Effekte implementieren. In unserem Fall sind Shader kleine Programme, welche effizient auf direkt dafür vorgesehenen Einheiten der Grafikkarte laufen können. Sie werden in speziellen Sprachen verfasst, wie GLSL (OpenGL Shading Language) oder HLSL (High Level Shading Language). Fehlen einem Gerät bzw. der Grafikkarte die Shadereinheiten, müssen die Shader mit der CPU – wesentlich langsamer – berechnet oder komplett weggelassen werden. Doch keine Sorge, auch dieses Mal soll es nicht zu technisch werden. Viel mehr schauen wir uns die Ergebnisse an, die wir mit Shadern erreichen wollen, als ihre konkrete Umsetzung.

Ziele: Generationen-Wechsel
Wir wollen die Minispiele in GameMaster weiterentwickeln können. Begonnen mit simplen Pixel-Grafiken, wie wir sie vom Game Boy gewohnt sind, bis hin zu hübschen 3D-Grafiken. Das würde theoretisch bedeuten, dass wir für jede Variante eigene Grafiken anfertigen müssten – ein enormer Aufwand. Doch es gibt Tricks um unsere Grafiken älter und pixeliger aussehen zu lassen, ohne viel Arbeit aufzubringen. „Post Processing“ (Nachbearbeitungs-) Shader erlauben uns einzelne Pixel und ihre Farben so zu manipulieren, dass das Resultat aussieht, als liefe es auf einem schwächeren Gerät mit eingeschränkter Technik. Man kann es sich so vorstellen, dass beispielsweise immer vier oder mehr Pixel zu einem zusammengefasst werden, welcher den Mittelwert aller Pixelfarben hat. Im Falle unseres GameGuys, welcher einem Game Boy gleichen soll, sind wir auf vier Farben, bzw. Graustufen eingeschränkt. Unsere Pixel bekommen also die Farbe, welche von diesen vier am nächsten dran ist.


Eine monochromatische 8Bit-Version mit vier Graustufen
Ich kann die Fisch- und Köder-Grafiken aus meiner älteren Fizhy-Version wiederverwenden, muss aber für die 8Bit Variante trotzdem die Fische nochmals überarbeiten. Natürlich muss auch noch einiges Weiteres für die 2D-Versionen getan werden, wie das Wasser und das Becken anzulegen, oder Kameraeinstellungen zu machen, aber da der heutige Tagebucheintrag von den Shadern handeln soll, beschränke ich mich nur auf die grafischen Ergebnisse.

Ähnlich geht es mit der nächsten Entwicklungsstufe weiter, welche einem NES (Nintendo Entertainment System) ähneln soll. Ein NES kann bereits 16 bis 25 von 52 Farben gleichzeitig darstellen. Ganz so streng muss es der Shader nicht nehmen, es soll ja nur so aussehen und das gelingt auch einfacher.


Die farbige 8Bit-Version
In dieser Version pflege ich ein paar Landschaftsdetails vom japanischen Zen-Garten ein. Doch irgendwas fehlt noch für das richtige Retro-Feeling. Das Bild gleicht einer typischen NES-Ausgabe, doch haben auch damalige Fernsehgeräte stark zum Aussehen beigetragen. Auch dies lässt sich mit einem Shader nachempfinden. Dazu verwende ich einen CRT (englisch „Cathode Ray Tube“)-Shader, der einen sogenannten „Kathodenstrahlröhrenbildschirm“ simuliert. Grob gesagt lässt dieser es so aussehen, als wären die Pixel eines Röhrenmonitors in ihren einzelnen Farben rot, grün und blau erkennbar. Dazu kommt noch die typische Wölbung der Bildfläche.


Nochmal die farbige 8Bit-Version, aber mit CRT-Effekt
Als nächstes biete ich eine 16Bit-Version an, welche in etwa einem SNES (Super Nintendo Entertainment System) gleicht. Mit ihrer 15-Bit-Farbpalette sorgt diese Konsole bereits für eine gewaltige Aufwertung. Für diese modelliere ich eine Extra-Variante des japanischen Zen-Gartens, welche ich auch für die 8Bit-Ausgabe nutze. Auch hier ist der CRT-Effekt passend.


Die 16Bit-Version, links mit CRT-Effekt, rechts ohne
Die danach folgende 32Bit-Version kennt ihr bereits aus vorherigen Tagebucheinträgen. Doch auch für diese erstelle ich aus Experimentierfreude zwei spezielle Shader-Varianten.


Die Welt sieht mit dem Bleistift-Shader aus wie gezeichnet
Zum einen haben wir hier eine Variante, die aussehen soll, als wäre sie mit Bleistift gezeichnet worden. Und zum anderen, mein persönlicher Favorit, eine Neon-Version. Ob und wie ich diese sinnvoll begründet in das Spiel einfließen lassen werde, weiß ich noch nicht mit Sicherheit. Vielleicht biete ich sie nur aus Spaß an.


Ein Neon-Shader – ich liebe diese Variante
Grafikeffekte
Shader eignen sich nicht nur zur Nachbearbeitung des Bildes, sondern können auch gezielte Grafikeffekte erzeugen. Davon habe ich bereits ein paar für Fizhy umgesetzt. Die meisten dieser Effekte sind allerdings mittels Partikeleffekten realisiert, was wieder eine ganz andere Technik ist. Mit ihr lässt sich eine große Anzahl von Objekten animieren. Partikelsysteme werden beispielsweise eingesetzt, um Feuer-, Rauch- oder Explosionseffekte zu simulieren. Wenn ihr den folgenden Fizhy Screenshot mit einer älteren Version vergleicht, seht ihr, dass sich eine Menge getan hat. Eigentlich realisiert man die Unterschiede erst richtig im bewegten Bild.


Die gewohnte 3D(32Bit)-Version
Zunächst erkennt ihr einige Wölbungen auf dem Boden. Diese werden via Shader realisiert und bewegen sich in einem konstanten Tempo. Tatsächlich sieht dies aber wie Wasserspiegelungen auf dem Boden aus. Für gewöhnlich realisiert man dies mittels Projektion von Texturen über die gewünschte Fläche. Diese Alternative habe ich beim Experimentieren mit Shadern entdeckt und schätze sie als recht effizient ein. Als nächstes könnt ihr eine Art blauen Nebel im Wasser erkennen, welcher das Sichtfeld in die Entfernung zunehmend einschränken soll. Dieser ist mittels Partikeln realisiert, obwohl Nebel normalerweise gut per Shader umgesetzt werden kann. Ich habe mich für diese weniger effiziente Methode entschieden, weil es in meinen Shader-Experimenten problematisch war, durch das Wasser blickend die nebelfreie Oberfläche sehen zu können. Bestimmt ließe sich auch dieses Problem anderweitig lösen, aber das Gebiet ist für mich neu und ich möchte vorankommen. Des Weiteren erkennt ihr kleine Blasen, welche zufällig und bevorzugt bei Bewegung eines Köders, bis zur Wasseroberfläche aufsteigen. Auch das sind Partikel, welche kleine Bilder nutzen. Zuletzt gibt es noch einen Partikeleffekt, welcher auftritt, wenn ein Köder ins Wasser geworfen wird, zu sehen im nächsten Screenshot.


Partikel-Platscher-Effekt, wenn ein Köder ins Wasser fällt
Unmögliche Objekte
Jetzt kommen wir zu etwas ganz Speziellem. Mit Shadern lassen sich auch Effekte darstellen, die in der Realität gar nicht möglich sind. Stellt euch beispielsweise ein Portal vor. Wie ein Fenster zu einem anderen Ort, einer anderen Zeit oder Realität. Oder man läuft drei Mal um dieselbe Säule um plötzlich woanders herauszukommen. Ein absolutes Musterexemplar, welches jede Menge solcher Effekte bis an die Spitze treibt, ist das Spiel Antichamber.

Diese Techniken habe ich zunächst nur aus Interesse daran untersucht und nicht weil ich ihre Verwendung direkt geplant hatte. Doch einen Grundpfeiler dieser Techniken möchte ich hier vorstellen, welcher es bereits ins Spiel schafft. Ich erstelle eine Art Spielkarte, welche eine eigene dreidimensionale Welt in sich trägt. Diese Welt ist nur durch das „Fenster“ der Karte sichtbar, man kann nicht etwa drumherum schauen. Also gewissermaßen ähnlich einem holografischen Effekt, welcher manche Sammelkarten ziert, aber nicht auf wenige Blickwinkel beschränkt. In folgendem Video sieht man ein fertiges Beispiel solch einer Karte.

Diese Karten möchte ich für alle Minispiele erstellen und sie sollen eine Art Trophäe dafür darstellen, dass man das jeweilige Minispiel „besiegt“ hat. Was genau das bedeutet, lege ich erst später fest. Ob man beispielsweise alle oder einen bestimmten Anteil der Achievements gefunden haben muss.

Um grob die Funktionsweise zu erklären: Alle Objekte innerhalb der Karten-Welt haben bestimmte Materialien, welche alle den selben Index als eine Shader-Variable haben. Das Karten-Fenster hat eine Art Shader-Maske mit demselben Index und fungiert als Gegenstück. Die Shader sind angewiesen, die Pixel der Objekte nur zu zeichnen, wenn sie von einer Maske mit identischem Index überlagert sind. Diese Karte stelle ich in einer simplen Fassung kostenlos zum Download zur Verfügung. Zum einen auf GitLab, wo ihr euch auch eine WebGL-Vorschau anschauen könnt und zum anderen, als mein allererstes Produkt dort, im Unity Asset Store. Für letzteres war etwas mehr Aufwand in Form von aufpolierten Bildern in verschiedenen Größen, erklärende Texte und das Einhalten etlicher Richtlinien nötig. Tatsächlich musste meine Karte ganze drei Mal durch einen mehrwöchigen Verifikationsprozess, bis es endlich geklappt hat. Theoretisch könnte dieser Store natürlich auch als Einnahmequelle dienen, doch aktuell plane ich dies nicht. Hier hättet ihr den Vorteil, die Karte direkt und ohne Aufwand in euer eigenes Projekt importieren zu können.

Nun habt ihr bereits einige Beispiele dafür gesehen, was mit Shadern und Partikeln möglich ist. Damit möchte ich für heute zum Ende kommen. Das nächste Mal machen wir einen kleinen Abstecher in die Landschaftsgestaltung unserer „Overworld“ und beschäftigen uns mit Gras, welches sich sogar biegt, wenn man hindurch läuft.

Ihr möchtet die Auszüge aus dem Leben eines Entwicklers lieber in englischer Sprache lesen? Unter diesem Link findet ihr die englische Version dieses Tagebucheintrags! ##neue_seite## ##abschnitt:2020##
##titel:Teil 22: Overworld-Landschaftsgestaltung## Teil 22: Overworld-Landschaftsgestaltung
Direkt anschließend an unseren vorherigen Tagebucheintrag, geht es mit Grafikeffekten weiter. Wir wollen unsere bisher triste Landschaft außerhalb der Minispiele etwas aufwerten. Diesbezüglich beschäftigen wir uns heute mit zwei Themen. Zum einen mit einem etwas speziellen Baum und zum anderen mit Gras, welches sich im Wind bewegt aber auch auf die Spieler reagiert.

Pythagoras-Baum
Das besondere an einem Pythagoras-Baum ist, dass es sich hierbei gar nicht um eine Pflanze handelt, sondern um ein Fraktal. Das heißt, geometrische Figuren, welche sich nach mathematischen Vorgaben rekursiv wiederholen. In diesem Fall handelt es sich um den Satz des Pythagoras, welchen vermutlich jeder aus der Schulmathematik kennen dürfte. Er besagt, dass in allen ebenen rechtwinkligen Dreiecken die Summe der Flächeninhalte der Kathetenquadrate gleich dem Flächeninhalt des Hypotenusenquadrates ist. Oder ausgedrückt in einer Formel, die vermutlich leichter hängen geblieben sein dürfte: a²+b²=c².


Veranschaulichung des Satz des Pythagoras auf Wikipedia
Besagter Baum nutzt nun diese Formen rekursiv und setzt auf Quadrate weitere Dreiecke und Quadrate mit identischen Seitenverhältnissen auf. Das ganze wird schnell verständlich, wenn man sich folgendes Video anschaut, in dem ich meine ältere (2013) Implementierung eines solchen Baumes mit der Spieleentwicklungssoftware Game Maker: Studio umgesetzt habe.

Eine HTML5-Version davon könnt ihr direkt in eurem Browser ausprobieren oder auf meiner Homepage herunterladen. Die Kanten des Grund-Quadrats sowie die obere Ecke des aufliegenden Dreiecks lassen sich frei festlegen. Dadurch können bereits viele verschiedene Fraktale erzeugt werden. Mit ein paar Farben und Texturen lässt sich das ganze interessanter gestalten und der optionale Wind bringt Leben in die Sache.

Nun war mir danach, das Ganze in Unity in 3D nachzubauen. Da bei den Berechnungen die dritte Dimension eigentlich keine Rolle spielt, sollte dies nicht schwieriger sein. Allerdings weichen die verwendeten Sprachen und Techniken stark voneinander ab, so war es dennoch eine erneute Herausforderung. Ich erspare euch die mathematischen Details, für interessierte biete allerdings den Quellcode auf GitLab an.

Solche Rekursionen können selbst einen aktuellen PC schnell an seine Grenzen bringen. Es bleibt also zunächst fragwürdig, in welcher Form ich diesen Baum schließlich im Spiel verwenden werde. Es dürfte aber sicher sein, dass es keinen Pythagoras-Wald geben wird, sondern solche Ressourcen-hungrigen Bäume eine Seltenheit sein werden.

Interaktives Gras
Jetzt zu etwas das die fast trostlose Landschaft flächendeckend verbessern soll: eine Wiese. Um Gräser, Sträucher, Blumen und ähnliches in Unity umzusetzen gibt es viele unterschiedliche Ansätze. Ich entscheide mich allerdings für gewisse Anforderungen, die diese Auswahl stark einschränken. Ich möchte, dass unsere Spieler (und eventuell auch andere Dinge) mit dem Gras interagieren können sowie dass das Gras sich im Wind bewegt. Die Grashalme sollten sich also beispielsweise zur Seite biegen, wenn ein Spieler auf die tritt, und sich danach wieder aufrichten.

Ich suche gezielt und umfangreich nach Anleitungen und Beispiel-Code zu diesem Thema und werde fündig. Im Endeffekt versuche ich aus verschiedenen Beispielen eine Kombination zu schaffen. Ich möchte euch die vermutlich wichtigsten Funde nicht vorenthalten: Linden Reids „Waving Grass Shader in Unity“ und Minions Arts „Quick Game Art Tips – Interactive Grass Shader“. Die effiziente Variante dies mit Shadern umzusetzen, bringt den Nachteil mit sich, dass ich mir auf diesem Gebiet noch schwer tue alles auf anhieb nachvollziehen zu können, aber das ist etwas womit man zurechtkommen muss. Theoretisch ist in den genannten Tutorials alles ausführlich erläutert und kann zum größten Teil übernommen werden. In der Praxis funktioniert leider nicht immer alles so einfach und zudem kann es widersprüchliche Voraussetzungen geben, wenn man zwei verschiedene Shader miteinander kombinieren möchte.


Wellenförmiger Wind aus Linden Reids Tutorial
Die verlinkten Tutorials beschreiben das meiste bereits (wenn auch nur auf Englisch), weshalb ich nicht alles im Detail wiederkauen möchte, aber ich gebe euch Zusammenfassungen. Der Wind, welcher sich wellenförmig ausbreiten zu scheint, wird so zu sagen durch ein scrollenden Gradienten verwirklicht.


Gradienten Textur von Linden Reids Tutorial
Grashalme werden etwa entsprechend der Helligkeit im Gradienten an ihrer Position gebogen. Beispielsweise kann man hell für rechts und dunkel für links festlegen. Zudem wird die verstreichende Zeit auf diese Koordinaten addiert, wodurch sich die Wellen in stetiger Form bewegen (als würde der Gradient endlos wiederholend scrollen).


Grashalme biegen sich interaktiv in Minions Arts Tutorial
Die Interaktion mit dem Gras ist simpler nachzuvollziehen und man kommt leicht auf die Idee, wie es umgesetzt werden kann. Doch ohne Erfahrung mit Shadern kann jede Kleinigkeit zur Herausforderung werden. Beispielsweise: Wie bekomme ich die Position eines Objektes im Spiel in den Shader hinein? Da wir hier keine stark technischen Tagebucheinträge verfassen, bleibt euch zum Glück erspart durchzukauen, was alles noch schief gehen kann, selbst wenn man bereits Anleitungen mit Beispiel-Code vorliegen hat. Zusammengefasst: Grashalme biegen sich in die entgegengesetzte Richtung zu einem Objekt, mit dem sie interagieren sollen, sobald dieses eine gewisse Entfernung unterschritten hat. Das klingt doch einfach, oder? Da die obige Grafik und das verlinkte Tutorial die Thematik bereits gut veranschaulicht und erklärt, werde ich es auch schon hierbei belassen.

Und so sieht das ganze dann in der Praxis in GameMaster aus. Im Video sehen wir ebenfalls blaue Pilze, welche im Dunkeln leuchten, sowie Blumen. Die verwendeten 3D-Modelle haben verschiedene LOD (Level of Detail) -Varianten. Das bedeutet je nachdem wie weit die Kamera von ihnen entfernt ist, haben die Modelle entweder mehr oder weniger Details. Dies soll dafür sorgen, dass einzelne Objekte weniger rechenintensiv sind, wenn sie in größerer Zahl gleichzeitig im Bild sind. Dadurch entsteht allerdings der Nachteil, dass sich die verschiedenen Modell-Varianten, in Bezug auf unsere Gras-Shader, auch unterschiedlich Verhalten, da sie verschieden viele Punkte (bzw. Vertices) nutzen. Man müsste die Werte der Shader somit pro Modell und Detaillevel konfigurieren, um möglichst gute Ergebnisse zu erzielen. Ein großer Teil meiner Zeit für dieses Thema, wurde durch die Optimierung dieser Werte in Anspruch genommen.

Damit beende ich den heutigen Eintrag. Das nächste Mal heben wir unseren Spiele-Charakter in eine neue Dimension und damit auch den Gesamteindruck unseres Spiels – Wir nutzen dreidimensionale Manga-Stil Figuren aus VRoid Studio. Bis bald!

Ihr möchtet die Auszüge aus dem Leben eines Entwicklers lieber in englischer Sprache lesen? Unter diesem Link findet ihr die englische Version dieses Tagebucheintrags! ##neue_seite##
##titel:Teil 23: Charaktere im 3D-Manga-Style## Teil 23: Charaktere im 3D-Manga-Style
Es wird Zeit, etwas an unseren Spiele-Charakteren zu ändern. Zwar hat dieser flache Paper Mario-Style auch ein gewisses Etwas, doch möchte ich etwas deutlich besseres anstreben. Bisher wurden sehr simple 2D-Grafiken verwendet, welche ich vor über zehn Jahren für meine ersten Spiele angefertigt habe. Sprites im niedrig auflösenden Pixel-Stil – flache Bilder in einer dreidimensionalen Welt. Das kann natürlich Geschmackssache sein, aber betrachten wir das ganze aus der technischen Sicht, wird die Entscheidung leicht: Angenommen wir wollen verschiedene Charaktere, verschiedene Geschlechter, Alter und Größen. Dazu wollen wir diese vielleicht verschieden kleiden. Pro Kombination dieser (und ggf. weiterer) Werte, müsste man mehrere Bilder für jede Art Bewegung bzw. Animation des Charakters anfertigen – ein Aufwand den ich nicht alleine Tragen könnte. Wir brauchen also ein generisches Vorgehen, bei dem möglichst viel wiederverwendet werden kann.

Welche Möglichkeiten gibt es?
OK, ich möchte die Sprite-Variante nicht schlechter reden als sie ist. Natürlich könnte man auch hier Tricks anwenden und mehrere Bilder kombinieren um sich etliche Zeichnungen sparen zu können. Beispielsweise verschiedene Frisuren und Klamotten könnten über den Körper gelegt werden. Oder man setzt den Körper ebenfalls aus Einzelteilen zusammen, etwa Torsos in verschiedenen Formen. Dann könnte man die Körperteil-Bilder einzeln dynamisch skalieren, um kein verschiedene Varianten zu benötigen. Dazu könnte man mit Blend-Effekten Haut- und Kleidungsfarben ändern. Wie ihr schon bemerkt haben dürftet, kann man das ganze immer weiter generalisieren, automatisieren und vereinfachen, doch zu welchem Preis? Natürlich steigt der Rechenaufwand drastisch, wenn man statt einer Grafik plötzlich zehn mit unterschiedlichen Skalierungen und Blend-Modi zeichnen muss. Und natürlich sehen die Verzerrungen, welche eventuell durch das Skalieren entstehen, nicht so schön aus.

Es gibt Animationsprogramme, welche diese Dinge in Perfektion kombinieren und professionelle Ergebnisse erzeugen können. Davon möchte ich euch eines vorstellen, welches es bei meinen Überlegungen bis in die Endauswahl geschafft hatte – Spine. Spine ist eine 2D-Animations-Software welche Einzelbilder mit Knochen verbindet welche dann bewegt werden können. Zudem können einzelne Bereiche eines Bildes verschieden stark skaliert werden, wodurch verblüffende Effekte geschaffen werden können. Man kann das ganze so gut umsetzen, dass 2D-Bilder sogar dreidimensional wirken. Doch seht selbst in einem Beispiel auf YouTube:

Mit dieser Lösung müsste man also deutlich weniger zeichnen, dafür aber umso besser. Denn kantige Pixelgrafiken passen nicht zu solchen flüssigen Bewegungen – wenn man das Potenzial von Spine nutzen möchte.

Eine weitere Möglichkeit welche ich in Betracht gezogen habe, ist das Modellieren und Verwenden von Voxel-Objekten. Im Endeffekt auch kantige Pixelgrafiken, aber in 3D statt 2D. Diese wiederum könnte ich auch flüssig animieren, ohne dass es unpassend aussieht. Wir kennen Voxel beispielsweise von Minecraft, oder was das Animieren von kantigen und ungelenkigen Körpern betrifft – Lego-Spiele und -Filme. Das Zusammensetzen von kleinen Bauklötzchen traue ich mir deutlich eher zu, als das modellieren hochauflösender 3D-Figuren. In einem anderen Kontext habe ich dies auch mal ausprobiert, mit der kostenfreien Software MagicaVoxel. Wie das abläuft könnt ihr in meinem Zeitraffer-Video anschauen, in dem ich die Monas in Jakarta (Indonesien) nachbaue:

Um erwähnte Voxel-Figuren oder 3D-Charaktere allgemein zu animieren gibt es beispielsweise Mixamo von dem man kostenlose Animationen für humanoide Figuren herunterladen kann. Es ist also nicht nötig, alles selbst zu animieren. Auch wenn diese Variante mit Voxeln und vorgefertigten Animationen sehr einladend wirkt, schaue ich mich weiter nach etwas besserem um. Da ich oft Spiele sehe, in denen Manga-Figuren vorkommen, welche besser und professioneller wirken als der Rest des Spiels, recherchiere ich gezielt danach. Zudem würden mir Manga-Figuren in meinem Spiel ganz gut passen. Und tatsächlich werde ich fündig: VRoid Studio zum Anfertigen von dreidimensionalen Figuren im Manga-Stil. Zu dieser Software habe ich ebenfalls ein Video angefertigt, in dem ich mit verschiedenen Werten experimentiere:

Man wählt zunächst das Geschlecht oder direkt aus einer Vorlage aus. Alle möglichen Dinge wie Längen und Dicken der Gliedmaßen und etliche Details im Gesicht können verstellt werden, wodurch sich viele verschiedene Emotionen darstellen lassen. Es gibt Webportale, in denen Benutzer ihre Werke (Charaktere und auch Kleidungen) unter verschiedenen Lizenzen anbieten können. Hier habe ich auch das schwarze Kleid gefunden, kostenfrei und kommerziell nutzbar, welches im Video zu sehen ist. Auch zeige ich, wie relativ einfach Frisuren erstellt werden können.

Meine Wahl ist getroffen
So beeindruckt ich von diesen Manga-Figuren bin, und wie einfach sie zu erstellen sind, fällt mir die Entscheidung leicht. Natürlich mit dem Hintergrundgedanken, dass die erwähnten Mixamo-Animationen auch mit diesen Figuren funktionieren. So weit so gut, doch wie bekomme ich solch eine Figur nun in mein Spiel? Das von VRoid Studio angebotene Format .vrm wird nicht von Unity unterstützt. Die Schritte, die ich durchgeführt habe um dies zu bewerkstelligen, sind gegebenenfalls zum Entstehungszeitpunkt dieses Tagebucheintrags bereits veraltet, daher werde ich nicht genau darauf eingehen. Neben zwei Unity-Plugins (UniVRM und VRMtoPMXExporter) waren auch Nachbearbeitungen in Blender nötig. Es gibt auch einfachere Wege, je nachdem wie viel Kontrolle man über die einzelnen Bestandteile haben möchte. Beispielsweise kann man am Ende eine einzige Textur für den gesamten Charakter haben, oder aber einzelne Textur-Bilder für sämtliche Bestandteile von Kleidung und Körper. Wenn ihr euch die verfügbaren Methoden anschauen wollt, sucht einfach auf YouTube nach „Vroid Studio To Unity“.

Nun gilt es den Charakter zu bewegen und zu animieren. Die Bewegungen sind bereits bei unserem flachen Sprite-Charakter vorhanden. Doch anstatt ihn je nach Richtung vertikal zu spiegeln, damit er zumindest nach links und rechts sehen kann, werden wir den Charakter ab jetzt um die Y-Achse rotieren, so dass er stets genau in die Laufrichtung schauen kann. Und statt die Bilder für eine Animation laufend auszutauschen, müssen die einzelnen Körperteile flüssig bewegt werden. Hierzu verwenden wir wie angekündigt fertige Animationen von Mixamo. Fündig werden wir mit dem Suchbegriff „walking“.


Lauf-Animationen in Mixamo
Hier wählen wir aus was uns gefällt und ein Format, welches von Unity unterstützt wird. Zur Auswahl steht direkt ein „FBX for Unity(.fbx)“, welches wir ohne Skin („Without Skin“) nutzen möchten. Wir können zudem einstellen wie viele Bilder pro Sekunde („Frames per Second“) wir haben möchten und ob wir eine „Keyframe Reduction“ wünschen.


Mit diesen Einstellungen laden wir eine Animation herunter
In Unity müssen wir dann noch ein paar Einstellungen anpassen, wie z.B. den „Animation Type“ auf „Humanoid“ stellen. Das meiste können wir unverändert lassen. Doch manches müssen wir durch Ausprobieren abschätzen. Beispielsweise kann es vorkommen, dass wir im Tab „Animations“ Anpassungen vornehmen müssen, wie etwa „Root Transform“ Positionen auf bestimmten Achsen in die Posen „einbrennen“ („Bake Into Pose“). Dazu muss gesagt werden, dass die Animationen unseren Charakter direkt bewegen, unsere Walk-Animation den Spieler also wirklich vorwärts laufen lässt und nicht nur die Beine bewegt. Mit genau diesen Einstellungen können wir solche Effekte beeinflussen.


Ein paar Optionen müssen wir in Unity anpassen
Und dann können entsprechende Animations-Abläufe und -Übergänge modelliert werden. Dazu legen wir im „Animator“-Tab von Unity verschiedene Zustände an, welche jeweils für eine Animation stehen und verbinden diese miteinander über Transitionen. Die Transitionen brauchen jeweils Bedingungen die erfüllt sein müssen, damit sie ausgelöst werden, wie etwa dass eine Variable einen bestimmten Wert annimmt.


Zustände und Übergänge im Animator
In obigem Screenshot sieht man bereits weitere Animationen mit ihren Übergängen. Interagiert der Spieler beispielsweise mit einer Bank, geht er in den Zustand „Sitting Idle“ über. Nach ein paar Sekunden wird per Zufall gesteuert eine weitere Sitz-Animation gestartet, die den Charakter etwas anders sitzen lassen soll, um so etwas realistische Abwechslung zu erzeugen.


Runtergebeugt oder kerzengerade – verschiedene Sitz-Animationen
Eine wichtige Sache möchte ich noch genannt haben: In fast allen heruntergeladenen Animationen bemerke ich Probleme mit der Ausrichtung bzw. Rotation der Füße. Diese sind teilweise um unrealistische 180° verdreht. Google zeigt auf, dass dies ein geläufiges Problem ist. Um es zu beseitigen, müssen „IK“(„Inverse Kinematics“)-Checkboxen angehakt werden. Diese finden sich an verschiedenen Stellen im Animator-Tab. Wenn ihr euch über Gründe für die Notwendigkeit dieser Einstellungen erkundigen wollt, folgt am besten der Google-Suche. Leider muss ich sagen, dass sich die Probleme nicht bei allen Animationen auf diese Weise lösen lassen, soweit ich das bisher in Erfahrung gebracht habe.


Wichtige Option zum Korrigieren der Fuß-Ausrichtung
Ich denke damit sollte ich zunächst genug zum Thema berichtet haben – verschiedene Möglichkeiten zur Charaktergestaltung erwähnt und meine erste Wahl leicht vertieft. Ich verabschiede mich mit einem Video von meinem ersten Manga-Stil Charakter in Bewegung.

Das nächste Mal werden wir Gewissermaßen ein weiteres Minispiel zu Implementieren beginnen. Diesmal wird es allerdings (zunächst) direkt auf der „Weltkarte“ stattfinden, statt in einer virtuellen Konsole. Und es soll Hunger stillen… Bis bald!

Ihr möchtet die Auszüge aus dem Leben eines Entwicklers lieber in englischer Sprache lesen? Unter diesem Link findet ihr die englische Version dieses Tagebucheintrags! ##neue_seite##
##titel:Teil 24: Gemeinsam Hamburger „kochen“## Teil 24: Gemeinsam Hamburger „kochen“
Heute beginnen wir ein weiteres Minispiel. Geplant ist allerdings zunächst nur die Grundlagen davon zu implementieren und es erst zu einem späteren Zeitpunkt fertigzustellen. Außerdem gehen wir diesmal ganz anders vor: Anstatt das Spiel als eigenständiges Projekt zu beginnen, wie wir es bei Fizhy gemacht haben, wird es direkt in unser Haupt-Spiel eingebaut. Zudem wird es (zunächst) direkt auf unserer „Overworld“ stattfinden, anstatt in einer Konsole. Der Grund hierfür ist, dass wir unseren Spiel-Charakter direkt dafür verwenden und keinen weiteren als Konsolen-Version entwerfen wollen. Zudem seid vorgewarnt – das folgende Kapitel könnte den Appetit anregen!

Ein Kochspiel planen
Farm- oder Kochspiele gibt es enorm viele. Trotzdem können sie sich stark im Gameplay unterscheiden. Ich möchte mich an dem Spiel Delicious World orientieren, welches ich überraschend gut fand. Allerdings musste ich feststellen, dass ein Vorgänger dieses Spiels (der gleichen Firma) deutlich weniger Spaß macht, obwohl die Spielmechanik fast identisch ist. Es sind Kleinigkeiten, wie beispielsweise dass in einem Spiel eine Aktion automatisch abläuft, während in dem anderen ein weiterer Klick hierfür notwendig ist. Aus diesem Grund ist eine gute Planung bei solchen Spielen deutlich wichtiger als bei vielen anderen Genres.

Das Grundprinzip ist leicht erklärt: Wir wollen Essen zubereiten und es an Kunden verkaufen. Die Kunden geben Bestellungen auf und wir kochen was sie wünschen. Dazu sammeln wir entsprechende Zutaten in unserer Küche zusammen und nutzen verschiedene Küchengeräte. Fertig zubereitetes Essen servieren wir dann dem Kunden welcher uns dafür bezahlt. Wenn ein Kunde aufgegessen hat, müssen wir noch den Tisch für die nächsten Personen aufbereiten.

Nun kommen wir zu den weiteren Details, welche bereits große Auswirkungen haben. Je nachdem wie lange wir für die Nahrungszubereitung gebraucht haben, bekommen wir mehr oder weniger Trinkgeld dafür. Brauchen wir zu lange, verlässt der Kunde verärgert unsere Gaststätte. Eine Bestellung kann aus mehreren Dingen bestehen. Es spielt also auch eine Rolle, ob wir alles auf einmal servieren können, oder ob wir alles einzeln bringen. Das können wir durch Kombo-Boni umsetzen – mehr Punkte, wenn man alles auf einmal serviert. Andererseits kann man die Zeit verlängern, die ein Kunde dazu bereit ist auf sein Essen zu warten, wenn man bereits Teile davon serviert hat. Dies wirft erste Fragen auf: Wartet der Kunde mit dem Verzehr bis alles serviert wurde? Oder isst er einen Teil und geht dann trotzdem nach zu langer Wartezeit? Bezahlt er dann hoffentlich zumindest diesen Teil? Auch für die Tische gibt es eine Wartezeit. Neue Kunden warten eine Weile, wenn alles belegt ist, bevor sie weiter ziehen. Also auch hier ein Grund dafür, alles zügig zu machen. Küchengeräte brauchen auch ihre Zeit. Manche können eigenständig funktionieren, wie beispielsweise das Kochen von Wasser, welches nur aufgesetzt werden muss. Anderes benötigt die Anwesenheit des Spielers, wie das Schneiden von Gemüse. Eigenständige Geräte müssen gegebenenfalls rechtzeitig gestoppt werden, wie dass etwas aus einem Topf oder einer Pfanne genommen werden muss. Andere sind einfach fertig und können keinen Küchenbrand veranlassen, wie eine Kaffeemaschine.

Die Speisekarte
In unseren konkreten Variante bieten wir zunächst Hamburger an. Diese bestehen aus Fleisch-Patties welche gebraten werden und dann auf einem Brötchen serviert werden. Alles weitere, wie Salat und Käse, sind optional und werden später implementiert. Erst kümmern wir uns darum, dass wir mit nur diesem Angebot den kompletten Prozess ausarbeiten.


Überblick über unser Restaurant
Wie auf obigen Bild zu sehen, haben wir eine Kücheneinrichtung (oben) mit zwei Tellern, von denen wir die Patties und Brötchen nehmen können. Links daneben befinden sich zwei Herdplatten mit Pfannen, in denen wir das Fleisch braten können. Über unserer Item-Hotbar (unten) sehen wir ein Tablet mit zwei Tellern, auf denen wir das zubereitete Essen an die Tische der Kunden transportieren können. Von diesen Tischen sind drei zu sehen, über denen die „verschiedenen“ Bestellungen eingeblendet werden. Direkt unter den Bestellungen sind Fortschrittsbalken zu sehen, welche anzeigen wie lange die Kunden noch bereit sind zu warten. Sichtbare Kunden selbst sind zunächst nicht nötig.


Burger-Braten macht Spaß!
Drücken wir die Aktionstaste während wir vor dem Teller mit den Fleisch-Patties stehen, wird eines in eine freie Pfanne gelegt, sofern verfügbar, und das Braten beginnt. Auch hier wird jetzt ein Fortschrittsbalken eingeblendet. Dieser hat allerdings zwei Ebenen, so zu sagen: Zunächst füllt sich ein grüner Balken. Ist dieser voll, kann das Fleisch herausgenommen werden. Sobald er voll ist, beginnt aber auch ein roter Balken diesen zu überblenden. Wenn dieser voll wird ist das Fleisch verbrannt und kann nur noch entsorgt werden. Es sollte also rechtzeitig aus der Pfanne entfernt werden. Dies geht aber nur, wenn wir bereits ein Brötchen auf einem unserer beiden Teller haben, auf dem noch kein anderes Patty liegt. Wir können fertig gebratenes also nicht irgendwo zwischenlagern.


Hier wird genau das bestellt, was wir auf dem Tablet haben
Mit den fertigen Burgern auf unserem Tablet gehen wir dann an einen Tisch und servieren sie. Diese werden dann verzehrt und hinterlassen einen schmutzigen Tisch. Zu guter Letzt müssen wir den Tisch noch reinigen, was ebenfalls durch einen Fortschrittsbalken angezeigt wird, und das ganze kann von vorn beginnen.


Der Tisch muss abgeräumt und geputzt werden.
Aussicht
Ich denke damit bekommt ihr bereits einen recht guten Eindruck davon, wie das ganze ablaufen soll. Natürlich brauchen wir noch weitere Zutaten, wie der bereits genannte Salat und Käse, weitere Angebote wie beispielsweise Pommes und Getränke. Auch möchte ich verschiedene Dinge upgradebar machen – mehr Teller auf meinem Tablet, weitere Tische bzw. ein größeres Restaurant, neue Essensangebote. Da es in GameMaster eh um das Entwickeln von Spielen geht, bietet sich dies an. Es können auch weitere Elemente einfließen, wie Dekorationen, die sich darauf auswirken, wie lange Kunden bereit sind zu warten, oder wie viel Trinkgeld sie geben.

Ein Multiplayer-Modus, welcher auch online funktioniert, wurde ebenfalls bereits implementiert. Andere Spieler können mitmischen und sehen auch die Aktionen anderer. Allerdings halte ich mich in Zukunft etwas damit zurück, Multiplayer-Dinge zu programmieren – Unity hat bereits des längeren erklärt, dass ihre unterliegende Netzwerk-Implementierungen bald abgelöst werden. Skripte, von denen mein Multiplayer abhängen, wurden als „deprecated“ (Engl. für „veraltet“) markiert und werden mit den aktuellen Unity-Versionen nicht einmal mehr ausgeliefert. Daher sollte ich davon ausgehen, dass ich in Zukunft das gesamte Multiplayer-System neu schreiben muss um der Zeit gerecht zu werden.

Am Ende des heutigen Tagebucheintrag möchte ich euch noch mitteilen, dass ich den 3DS-Support fallen lasse. Es war natürlich zu erwarten, dass mein Projekt noch sehr viel Zeit benötigen würde und es unrealistisch ist, so spät noch eine 3DS-Variante umzusetzen. Da mich die 3DS-Kompatibilität stark ausbremst und davon abhält, auf neuere Unity-Versionen zu upgraden, habe ich jetzt entgültig entschlossen darauf zu verzichten.

Nächstes Mal wollen wir unseren Spiel-Charakter individualisieren. Also ohne mit VRoid Studio einen neuen zu erstellen, wie wir es in Tagebucheintrag 23 getan haben, werden wir erforschen inwieweit wir diesen innerhalb von Unity verändern können. Bis bald!

Ihr möchtet die Auszüge aus dem Leben eines Entwicklers lieber in englischer Sprache lesen? Unter diesem Link findet ihr die englische Version dieses Tagebucheintrags! ##neue_seite##
##titel:Teil 25: Charakter-Individualisierung## Teil 25: Charakter-Individualisierung
Wir sind es gewohnt, in RPGs und anderen Spielen eigene Charaktere zusammenstellen zu können. Wir wählen das Geschlecht, regulieren Körpergröße und Statur und können alle möglichen Details anpassen. Im Tagebucheintrag 23 haben wir einen 3D-Charakter im Manga-Style erstellt, doch dieser bleibt bisher so wie wir ihn mit dem Programm VRoid Studio gebastelt haben. Heute wollen wir erforschen, inwieweit wir das Aussehen dieses Charakters noch innerhalb von Unity und unserem Spiel beeinflussen können.

Auf was können wir Einfluss nehmen?
Um das herauszufinden untersuchen wir, wie das Spieler-Objekt welches wir nach dem Konvertierungsprozess aus VRoid Studio erhalten haben. Im folgenden Screenshot seht ihr eine bereits leicht verfeinerte Version der Objekt-Hierarchie, die wir dann mit unserem Spieler verschmolzen haben.


Struktur unseres Spieler-Objektes
Unter „Armature“ finden wir jede Menge Knotenpunkte, die für verschiedene Körperteile und Gelenke stehen. Von der Hüfte gehen etwa die Beine und der Torso bzw. die Wirbelsäule aus. Von dort wiederum die Brust und von dieser die Schultern und der Hals. Der Grundgedanke ist nun, dass wir diese Einzelteile unterschiedlich skalieren, also dehnen oder stauchen, um neue Proportionen zu erhalten. Doch ist das wirklich so einfach? Nein, natürlich ist es das nicht. Zunächst muss man beachten, dass auch alle darunter liegenden Teile mit verzerrt werden. Wollen wir beispielsweise breitere Schultern, bekommen auch die Arme einen größeren Durchmesser. Aber natürlich nur auf der Achse die wir verändern – breitere Schultern verursachen also sogar einen ovalen Armdurchschnitt, was wir nicht wollen. Außerdem gibt es zwischen den Knotenpunkten Rotationen, wodurch das ganze etwas komplizierter wird. So kann das Ändern der X-Achse eines Objektes auch die Y-Achse der Kindobjekte beeinflussen, statt deren X-Achsen. Wahrscheinlich sogar Anteilig – also etwa zu 20% die X-Achse und zu 80% die Y-Achse.

Wollen wir also einzelne Körperteile verändern, müssen wir die Änderungen bei deren Kind-Objekten wieder kompensieren. Machen wir beispielsweise die Arme um 10% länger, müssen wir die darunterliegenden Hände um 10% kürzer machen. Dazu muss uns bekannt sein welche Achsen des Kindes wir um wie viel anpassen müssen, um insgesamt die 10% zu erreichen. Um bei diesem Beispiel zu bleiben – die Hände vielleicht um 6% auf der X-Achse verkürzen, und jeweils 2% auf den Y- und Z-Achsen. Hier zu berechnen was wie geändert werden muss, scheint mir aufwändiger als es auszuprobieren, auch wenn das etwas grob ausfällt.

Wie können wir das umsetzen?
Noch schwieriger ist die Planung der Umsetzung. Wir wollen eine UI, bei der wir mit Schiebereglern verschiedene Körperteile verändern können. Der darunter liegende Code braucht Referenzen auf die einzelnen Körperteile, die er verändern soll. Also erstellen wir einen „CharacterCustomizationController“, wie ich die C#-Klasse genannt habe, welcher einen „Player“ bekommt, ihn eigenständig durchläuft und anhand der Knoten-Namen die Referenzen sammelt um später direkt darauf zugreifen zu können. Jeder Slider eines veränderbaren Körperteils bekommt einen Wertebereich nach Augenmaß – eine minimale und maximale Dehnung bzw. Stauchung. Und nun das Trickreiche: Zudem bekommt jeder Slider eine Liste von Referenzen auf weitere Körperteile, die zur Kompensation genau gegenteilig skaliert werden sollen. Zu jeder dieser Referenzen benötigt er einen 3D-Vektor, welcher angibt, zu welchen Anteilen diese referenzierten Körperteile auf welchen Achsen skaliert werden sollen.


Code-Beispiel: Nötige Referenzen und Skalierungs-Vektoren um die Armlängen zu verändern.
Um alles hierfür nötige herauszufinden muss jede Menge ausprobiert werden – man sagt „Trial & Error“ (Versuch und Irrtum). Und dabei sammeln sich etliche Werte an, die auch verwaltet werden wollen. Immerhin brauchen wir mittelmäßige Standardwerte, die am besten der Ausgangssituation entsprechen. Dazu kommen die Minima und Maxima und ein Faktor, um wie viel sich eine Skalierung verändert, wenn man den Slider um eine gewisse Strecke bewegt. Das Minimum und Maximum kann sich natürlich aus dem Faktor ergeben (oder andersherum), da die Slider einen festen Wertebereich von null bis eins haben.


Code-Beispiel: Nötige Faktoren und Standardwerte für zehn veränderbare Körperteile
Diese Werte müssen gespeichert und geladen werden und im Multiplayer außerdem über Netzwerk übertragen werden können, damit man auch die Einstellungen anderer Spieler sehen kann. Auf diesen Aufwand werde ich hier aber nicht genauer eingehen, da es sich hauptsächlich um Schreibarbeit handelt und das Speicher-System und Kommunikation über das Netzwerk bereits in früheren Tagebucheinträgen angesprochen wurde.

Die grafische Umsetzung
Per Tastendruck lassen wir jederzeit mitten im Spiel die Kamera zu unserem Character fahren und zoomen. Wir haben eine zweigeteilte Benutzeroberfläche: Links lassen sich die Kategorien von Körperteilen auswählen und rechts werden dann entsprechende Schieberegler angezeigt. In obigem Video sieht man eine sehr simple und frühe Umsetzung. Hier werden nur Standard-Unity-UI-Grafiken verwendet und Schlüsselwörter beschreiben die Funktionen. Da ich solche Texte nicht so schön finde und man dadurch erhöhten Aufwand hat, das Spiel in mehrere Sprachen zu übersetzen, überlege ich mir, wie man mit Grafiken die gleiche Aussagekraft erzielen kann. In folgendem Video sieht man, wie ich es schließlich umgesetzt habe – einfache Figuren, bei denen jeweils eingezeichnet ist, was sich verändert. Für die Körper-Kategorien links sind ganze Körperbereiche blau markiert. Auf der rechten Seite sind die konkreten Achsen an den betroffenen Stellen eingezeichnet. Außerdem ist die Benutzeroberfläche nun kompakter, hält sich nur am Bildschirmrand und ist vom Design minimal ansehnlicher.

Es ist vollbracht
Somit haben wir unser Ziel erreicht. Tatsächlich habe ich nur Einstellungen für die Körperteile implementiert, für die es mit vertretbarem Aufwand möglich war. Ich habe auch mit Körperteilen experimentiert, bei denen die Verzerrungen der Kindknoten so heftig waren, dass ich sie nicht ohne weiteres ausgleichen konnte. Man kann sich aber auch einige andere Optionen überlegen. Beispielsweise dass wir die Haut-, Augen- und Haarfarben ändern können. Auch andere Kleidung ist wünschenswert, aber vermutlich nicht so ohne weiteres austauschbar, da sie aktuell fester Bestandteil unseres Spieler-Körpers ist. Doch fürs Erste soll uns das zum Thema Charakter Individualisierung genügen.

Und damit möchte ich mich für heute verabschieden. Bis zum nächsten Mal – dann wollen wir einen flüssigen Übergang zwischen der Overworld und den Minispielen schaffen, indem wir unseren „GameGuy“-Handheld aus der Tasche holen und auf ihm ein Spiel starten.

Ihr möchtet die Auszüge aus dem Leben eines Entwicklers lieber in englischer Sprache lesen? Unter diesem Link findet ihr die englische Version dieses Tagebucheintrags!

To top