Technik

Voxel-Spiele in Assembler: Welten ohne Asset-Dateien

Eine Spielwelt braucht Landschaften, Oberflächen und Regeln. Sie braucht dafür aber nicht zwingend einen Ordner voller Grafikdateien. Prozedurale Generierung ersetzt gespeicherte Inhalte durch Rechenvorschriften. Gerade bei Voxel-Welten lässt sich daran gut erklären, wie aus vergleichsweise wenig Programmcode eine begehbare Umgebung entstehen kann.

Assembler macht diesen Ansatz besonders aufwendig, ist aber nicht der eigentliche Platzspartrick. Entscheidend ist, welche Informationen das Programm speichert und welche es erst beim Start oder während des Spielens erzeugt. Wer solche Projekte beurteilen will, muss deshalb drei Dinge auseinanderhalten: Umfang des Quellcodes, Größe der ausführbaren Datei und Ressourcenbedarf während des Betriebs.

Codezeilen sind keine Kilobyte

Eine Angabe in Tausend Codezeilen beschreibt zunächst den Umfang eines Programmtexts. Eine Angabe in Kilobyte beschreibt eine Datenmenge. Daraus lässt sich keine direkte Umrechnung ableiten. Kommentare und Formatierung können den Quelltext verlängern, ohne das fertige Programm entsprechend zu vergrößern.

Auch eine kleine Programmdatei sagt wenig darüber aus, wie viel Arbeitsspeicher die laufende Anwendung benötigt. Werden Landschaften und Texturen erst nach dem Start erzeugt, müssen die Ergebnisse trotzdem irgendwo Platz finden. Die Daten verschwinden also nicht. Ihre Entstehung wird vom Entwicklungsprozess auf den Rechner des Spielers verlagert.

Die Demoszene liefert dafür anschauliche Beispiele. Dort sind Intros mit einer Größenbegrenzung von 64 Kilobyte verbreitet, die komplette audiovisuelle Präsentationen enthalten. Ein Beispiel mit Voxel-Landschaft ist „Airframe“ von Prime aus dem Jahr 2002. Solche Produktionen belegen, wie kompakt sich Erzeugungsregeln speichern lassen. Ein interaktives Sandbox-Spiel stellt allerdings andere Anforderungen als eine vorgegebene Präsentation.

Ohne Asset-Dateien steckt der Inhalt in Regeln

Bei prozeduraler Generierung beschreibt das Programm, wie Inhalte aufgebaut werden. Statt jede Oberfläche als fertiges Bild mitzuliefern, kann es deren Muster berechnen. Statt eine Landschaft vollständig abzulegen, kann es Regeln für ihre Form ausführen. In 64-Kilobyte-Intros werden auf diese Weise Grafiken, Modelle, Texturen und auch Musik zur Laufzeit erzeugt.

„Keine Asset-Dateien“ bedeutet deshalb nicht „keine Inhalte“. Die Inhalte stecken in Algorithmen und Parametern. Das spart mitgelieferte Daten, verlangt aber passende Verfahren für das gewünschte Ergebnis. Eine überzeugende Landschaft entsteht nicht allein dadurch, dass ein Programm viele Blöcke aneinanderreiht.

Für eine veränderbare Spielwelt kommt eine weitere Aufgabe hinzu: Der ursprüngliche Zustand und die Eingriffe des Spielers müssen zusammenpassen. Eine Erzeugungsregel kann den Ausgangszustand beschreiben. Sie beantwortet noch nicht automatisch, wie abgebaute Blöcke oder neu errichtete Bauwerke dauerhaft erhalten bleiben. Prozedurale Generierung ersetzt also einen Teil der Inhaltsdaten, nicht sämtliche Zustandsverwaltung.

Assembler entfernt Abstraktionen, nicht die Arbeit

Direkt geschriebener x86-64-Assembler gibt Entwicklern enge Kontrolle über die ausgeführten Maschinenbefehle. In der Demoszene werden Assembler und stark optimierter C-Code mit speziellen Werkzeugketten eingesetzt, um knappe Größenlimits einzuhalten und Standard-Laufzeitumgebungen zu umgehen.

Der Verzicht auf eine C-Laufzeitbibliothek nimmt dem Programm jedoch keine Aufgaben ab. Alles, was das Spiel benötigt, muss weiterhin erledigt werden. Die Implementierung verschiebt sich in eigenen Code oder in die verwendeten Systemschnittstellen. Auch „ohne Compiler“ bedeutet bei Assembler nicht, dass lesbarer Quelltext unmittelbar vom Prozessor ausgeführt wird: Die Assemblersprache muss in Maschinencode übersetzt werden.

Ebenso wenig folgt aus dem Verzicht auf eine C-Laufzeit, dass ein Spiel ohne Betriebssystem läuft. Bare-Metal-Programmierung ist eine zusätzliche technische Entscheidung. Projekte wie ThumbyCraft zeigen eine Minecraft-ähnliche Voxel-Welt auf einem Mikrocontroller mit einem CPU-Raycaster. Das ist ein eigener Ansatz, kein automatisches Merkmal jedes Assembler-Spiels.

Die Grenze liegt bei der laufenden Welt

Eine kompakte Beschreibung löst zunächst das Problem der Auslieferungsgröße. Beim Spielen zählen weitere Größen: Wie aufwendig ist die Erzeugung? Welche Daten müssen im Speicher bleiben? Wie viel Arbeit verursacht eine Veränderung der Welt? Aus einer kleinen Datei lässt sich keine hohe Bildrate ableiten.

Genau darin liegt der praktische Wert solcher Projekte. Sie trennen sichtbar zwischen gespeicherten Inhalten und berechenbaren Strukturen. Für Entwickler ist das eine nützliche Denkweise, auch ohne ein komplettes Spiel in Assembler zu schreiben. Wo sich große Datenbestände durch überschaubare Regeln ersetzen lassen, kann die Auslieferung schlanker werden. Bezahlt wird mit Berechnungsarbeit und zusätzlichem Entwicklungsaufwand. Ob sich dieser Tausch lohnt, entscheidet die konkrete Anwendung.