Abenteuer Spieleentwicklung – Teil 9: Der steinige Weg auf den Handheld

Bereits vor zwei Jahren habe ich eine Investition getätigt, die sich bis vor kurzem eher als Fehlkauf herausgestellt hat: Ein Devkit für den New Nintendo 3DS. Diese Entwicklungshardware war relativ günstig und ich wollte zumindest einmal versuchen, ob ich Regina & Mac auf dem in die Tage gekommenen Nintendo-Handheld zum Laufen bekommen könnte. Zwar kann man ein Level auch tatsächlich auf dem New Nintendo 3DS spielen, aber nur mit deutlichen Einschränkungen in Sachen Framerate (geht bis auf 30 runter), Schatten (gibt es keine) und 3D Effekt (schaut man mit eingeschaltetem 3D Effekt in die falsche Richtung, stürzt das Spiel ab). So habe ich das Dev Kit nach wenigen Wochen wieder sicher verstaut und mit dem Nintendo 3DS als Zielplattform für mich abgeschlossen. Doch mein Partner in Sachen Keen Dreams, Javier M. Chavez, sah die Sache ein wenig anders…

Commander Keen in Keen Dreams: Definitive Edition basiert bekanntlich auf einem Spiel von Anfang der 90er Jahre und ist somit technisch sicherlich etwas weniger anspruchsvoll, als ein 3D Spiel. Chavez sah in dem Nintendo 3DS eine große Chance und bat mich, Keen Dreams nicht nur für die Wii U, sondern auch für den New Nintendo 3DS umzusetzen. Tatsächlich hat sich Chavez sogar eine Version für den ursprünglichen Nintendo 3DS gewünscht, doch Unity ist nicht ohne Grund nur für den New Nintendo 3DS gedacht: Es sei bereits verraten, dass selbst am Ende des Entwicklungsprozesses und zahlreichen Optimierungen für den New Nintendo 3DS bereits das Anzeigen des Titelbildschirms und das Abspielen der Titelmelodie von Keen Dreams: Definitive Edition die RAM-Kapazitäten, die Unity auf dem alten Nintendo 3DS übrig lässt, übersteigt.

Speicher aufgebraucht: Ein ständiger Begleiter beim Port auf den New Nintendo 3DS (Symbolbild)

Doch selbst für den New Nintendo 3DS sah es zunächst düster aus. Das Spiel in Unity für den Nintendo 3DS zum Laufen und zum Kompilieren zu bringen, war zunächst einmal wesentlich mehr Arbeit, als man annehmen würde und eigentlich notwendig wäre. Hierfür kann aber der Nintendo 3DS nichts, sondern Schuld ist in diesem Fall die Unity-Entwicklungsumgebung, die sich auf dem Rechner, der mir noch blieb, ohne bereits eine Entwicklungsumgebung für eine Konsole laufen zu haben, als äußerst zickig herausgestellt hat. Die Aktivierung von Unity erfolgt über ein spezielles Lizenzfenster, in dem man einen Lizenzcode eingeben muss. Dumm nur, dass dieses Lizenzfenster bei mir schlicht weiß blieb. Nach unzähligen Installationsversuchen und verschiedenen Nutzerkonten habe ich dann doch noch eine Lösung gefunden, um die Entwicklungsumgebung verwenden zu können: Ich habe im Internet nachgeschaut, wo Unity die Lizenzdatei ablegt und diese manuell gelöscht. Dann tauchte beim Start des Programms endlich ein nutzbares Aktivierungsfenster auf. Dass für den reinen Start von Unity ein ganzes Wochenende draufgegangen ist, hat meiner Entwicklungsmotivation nicht gerade Vorschub geleistet.

Als kritisch erwies sich zudem, dass es eine ganze Weile gedauert hat, bis ich überhaupt in der Lage war, ein lauffähiges 3DS-Programm zu erzeugen, denn auch auf dem New Nintendo 3DS war mein Ansatz um Keen Dreams auf die Wii U zu portieren, zu speicherhungrig. Auf der Wii U lade ich beim Spielstart direkt alle Assets, aus denen das Spiel aufgebaut wird, in den Arbeitsspeicher. Dadurch hat das Spiel nur sehr kurze Ladezeiten um die Level vorzubereiten, die dem Spieler kaum auffallen dürften. Auf dem New Nintendo 3DS hingegen musste ich jedes Level als einzelne Szene vorbereiten, die dann nur die Assets lädt, die auch tatsächlich in dem jeweiligen Level verwendet werden. Das war natürlich für sich schon ein kleines Wagnis, denn ich konnte mir bis zum Ende nicht sicher sein, ob es nicht vertane Mühe ist, jedes Level einzeln umzusetzen, denn wenn auch nur ein Level die RAM-Grenzen sprengt, kann das ganze Spiel daran scheitern.

Exakt diese Meldung – wenngleich auf einem Devkit dargestellt, statt wie hier auf einem Retail-3DS – war stets Anlass zu großer „Freude“.

Daher habe ich zunächst die Level nach der Anzahl der verwendeten Tiles und der Anzahl der verwendeten verschiedenen Tiles – das sind zwei verschiedene Kenngrößen – sortiert und zunächst die meiner Einschätzung nach komplexesten Level umgesetzt, bevor ich mich an die vermeintlich einfacheren Level gesetzt habe. Erwartungsgemäß hat schon die Szene für nur ein einziges – allerdings auch das größte – Level mir direkt Kopfzerbrechen bereitet. Ohne hilfreiche Fehlermeldung hat sich das Programm beim Start auf dem New Nintendo 3DS Dev Kit verabschiedet.

Nach mühevoller Fehlereingrenzung habe ich schließlich herausgefunden, dass das grundlegendste Problem die Größe der Levelhintergrundtextur ist. Ist die Textur größer als eine gewisse Kennzahl, dann kann diese Textur überhaupt nicht geladen werden. Da ich die Textur aber in der Szene dynamisch erzeugen ließ, konnte Unity mich hiervor nicht im Kompilationsprozess warnen. Aber auch mein nächster Versuch, die Textur, die im Code erstellt wird, stückweise in klein genügenden Teiltexturen zu erstellen, scheiterte, weil in Levels mit mehr als zwei Teiltexturen – und es gibt Szenen, die bis zu acht Teiltexturen benötigen – der verbrauchte Arbeitsspeicher für die Teiltexturen zu groß ist. Bei im Code erzeugten Texturen kann man erst nach Fertigstellung der Textur eine Komprimierung durchführen und das hat Unity auf dem 3DS an seine Grenzen gebracht, wenn bereits zwei komprimierte Texturen im Arbeitsspeicher lagen.

Beispiel für einen zerschnittenen Hintergrund eines Levels.

Also musste eine neue Lösung her: Die Hintergrundgrafiken ließ ich nun in der PC-Version nach Erstellung als unkomprimierte PNG-Datei abspeichern und dann habe ich von Hand mit Paint die Hintergrundgrafiken in entsprechend große Teiltexturen zerlegt. Wenn ich im Nachhinein darüber nachdenke, hätte ich mir wohl einige Stunden dummer Schneidearbeit sparen können, wenn ich meine zuvor geschriebene Methode zur Erzeugung der Teiltexturen aus der 3DS-Version in die PC-Version kopiert hätte. Nunja, was man nicht im Kopf hat, muss man wohl in den Fingern haben.

Mit dieser Lösung ließ sich dann endlich jedes Level kompilieren und spielen, als ging es als nächstes daran, alle Level durch entsprechende Szenenwechsel zusammenzufügen. Da ich in Regina & Mac unterschiedliche Level ohnehin in verschiedenen Szenen gespeichert hatte, konnte ich hier meine für Regina & Mac geschriebene Klasse zum Szenenmanagement recyceln und hätte doch nun eigentlich fertig sein sollen und ein höchstens noch leicht zu optimierendes 3DS-Projekt vorliegen haben. Doch weit gefehlt, denn in der zusammengebauten Version von Keen Dreams auf dem New Nintendo 3DS kam es zwar nicht mehr zu einem Totalabsturz des Spiels, doch an Durchspielen war noch lange nicht zu denken.

Ungefähr so sah das Spiel aus, wenn die Hintergrundtextur nicht geladen werden konnte.

Das wichtigste Problem ergibt sich schon sehr schnell: Wenn man von der Oberwelt in ein Level ging, war es in den allermeisten Fällen so, dass nicht alle Texturen des Spiels mitgeladen werden konnten und einige Hintergrundtexturen komplett weiß blieben. Da die Hintergrundtexturen quasi die gesamten Informationen über Plattformen im Level beinhalten, heißt das im Wesentlichen: Das Spiel war in dieser Form unspielbar. Doch woher kann ein solches Verhalten kommen? Jede Einzelszene funktioniert sauber, wenn man aber zwischen den Szenen wechseln kann, reicht der Arbeitsspeicher nicht mehr aus um alle Texturen zu laden. Die erste Vermutung lag auf der Hand: Unity lehrt beim Szenenwechsel den Arbeitsspeicher nur sehr unvollständig. Um das zu überprüfen, habe ich eine vorläufige Fassung des Spiels erstellt, in der bei jedem Übergang von der Oberwelt zu einem Level und zurück erst einmal eine leere Szene geladen wird, die anschließend die ursprüngliche Zielszene lädt. Das ist zwar mitnichten eine dauerhafte Lösung – dem Spieler wird beim Laden eines Levels dann plötzlich ein komplett blauer Bildschirm angezeigt – aber immerhin: Mit dieser Modifikation konnte man alle Level spielen.

Als nächstes ging es also an das genauere Speichersparen: Nicht erreichbare Teile der Hintergrundtextur wurden herausgeschnitten, Soundeffekte, die in einem Level nicht auftreten konnten, mussten aus dem Soundmanager fliegen und Gegnertypen und Sammelgegenstände, die in einem Level nicht vorkommen, mussten weichen. Schließlich mussten einige Kleinigkeiten, die bereits in der Szene saßen entfernt und nach dem Szenenwechsel über Code neu erzeugt werden, da so auf einen anderen RAM-Pool zugegriffen wird, der etwas weniger ausgelastet ist. Wie knapp die ganze Geschichte war, zeigt sich daran, dass ein Level erst dann richtig funktioniert hat, als ich die letzte Randreihe der Oberweltentextur entfernt habe – viel knapper konnte das RAM-Budget gar nicht ausfallen.

Dieser schmucke Nintendo 3DS wird leider nicht mit Keen Dreams versorgt werden können.

Leider gab es im Anschluss aber noch eine Menge Framerate-Probleme zu lösen, die mit engem RAM-Budget leider alles andere als einfach zu lösen sind. An dieser Stelle musste ich, um die Framerate zumindest nur in sehr wenigen Stellen und nicht allzu tief fallen zu lassen, auch einige Schönheitsfehler in Kauf nehmen: In einem Level musste ich Sammelgegenstände zusammenfassen zu weniger, aber höherwertigen Sammelgegenständen, in einem Level verdeckt ein Loch im Boden Keen nicht, wenn er an einer Stange durch das Loch klettert und in einem anderen Level musste ich die Wasseranimationen um eine Animationsstufe kürzen. Das ist alles andere als optimal, aber zumindest ist die Spielbarkeit des gesamten Spiels jetzt ohne sonderliche Abstriche gewährleistet.

Chavez hatte nach Fertigstellung der New Nintendo 3DS-Fassung noch Hoffnungen, dass wir das Spiel auch auf den alten Nintendo 3DS bringen könnten, aber leider – oder zum Glück, wenn ich die Tortur, das Spiel auf den New Nintendo 3DS zu bringen beachte – scheitert eine Umsetzung auf den alten Nintendo 3DS bereits bei dem Versuch, nur den Titelbildschirm anzeigen zu lassen. Der Overhead der Unity-Engine ist für den alten Nintendo 3DS einfach zu hoch. Das soll natürlich nicht heißen, dass Keen Dreams auf dem alten Nintendo 3DS generell nicht lauffähig wäre – das wäre es sicherlich, dann müsste man aber nativ für den Nintendo 3DS entwickeln und könnte keinen Gebrauch mehr von Unitys komfortablen Multiplattform-Lösungen machen. Diesen Aufwand wäre ein Port auf den Nintendo 3DS zu diesem Zeitpunkt leider nicht mehr wert.

In der nächsten Ausgabe von Abenteuer Spieleentwicklung sprechen wir über den Versuch, Regina & Mac und Keen Dreams: Definitive Edition auf weiteren Plattformen zu veröffentlichen.