Der Dungeon Crawler in 3D: Neuumsetzung mit Rust, Bevy und Claude Code (Opus 5.5)
Veröffentlicht: 26. Oktober 2026
Im Juni 2026 entstand mit Claude Code aus einem einzigen, bewusst vagen Prompt in rund 20 Minuten ein spielbarer Dungeon-Crawler für den Browser: Held des Drachenkerkers, umgesetzt in Vanilla-JavaScript auf einem HTML5-Canvas, mit Emoji als Grafik. Daran schloss sich die Frage an, ob sich dasselbe Spiel auch in 3D umsetzen lässt: in Rust, mit einer Game-Engine und weiterhin direkt im Browser spielbar.
Das Ergebnis ist Held des Drachenkerkers 3D: dieselben Spielwerte, dieselben Labyrinthe und bis auf wenige begründete Abweichungen dieselben Regeln, ergänzt um animierte 3D-Modelle, Fackellicht, Partikel und Soundeffekte. Umgesetzt hat es Claude Code mit dem Modell Opus 5.5 in der Engine Bevy 0.20; ausgeliefert wird das Spiel als WebAssembly mit WebGL2. Die Entwicklung erfolgte am 25. Oktober 2026 in sieben Meilensteinen zwischen 7 Uhr morgens und kurz nach Mitternacht, bei rund acht Stunden reiner Sitzungszeit.

Die beiden Fassungen im Überblick:
| 2D (Juni 2026) | 3D (Oktober 2026) | |
|---|---|---|
| Technik | Vanilla-JavaScript, HTML5 Canvas | Rust, Bevy 0.20, WebAssembly, WebGL2 |
| Grafik | Emoji-Glyphen | 3D-Modelle aus CC0-Paketen, Licht, Partikel |
| Modell | Opus 4.8 | Opus 5.5 |
| Vorgabe | ein bewusst vager Prompt | Spezifikation mit zehn Abschnitten |
| Entwicklungszeit | rund 20 Minuten für die erste Fassung | rund acht Stunden in sieben Meilensteinen |
| Code | rund 1.400 Zeilen | knapp 14.000 Zeilen samt Tests |
| Automatische Tests | keine | 153 |
| Download | rund 100 KB | rund 27 MB, mit gzip rund 9 MB |
Eine Spezifikation als Ausgangspunkt
Beim 2D-Spiel war der knappe Prompt Teil des Experiments: Klassenbalance, Labyrinth-Verfahren und Drop-Tabellen legte Claude Code selbst fest. Für die 3D-Fassung war dieses Vorgehen aus zwei Gründen nicht geeignet.
Erstens sollte kein beliebiger Dungeon-Crawler entstehen, sondern eine Umsetzung des bestehenden Spiels. Klassenwerte, Gegner, Drop-Tabellen, Erfahrungskurve und Labyrinthgrößen wurden unverändert aus der 2D-Version übernommen, deren Quellcode als Referenz im Repository liegt.
Zweitens erschien Bevy 0.20 erst am 8. Oktober 2026, gut zwei Wochen vor Projektbeginn und damit nach dem Trainingsstand des Modells. Was ein Sprachmodell über Bevy weiß, stammt daher aus älteren Versionen, und Bevy ändert seine Schnittstellen von Version zu Version teils erheblich.
Am Anfang stand deshalb eine Spezifikation mit zehn Abschnitten: Modellwahl, Projektziel, technische Vorgaben, Spielregeln, 3D-Umsetzung (feste Kamera mit 55° Neigung, 2 m je Kachel, niedrige Wände, Fackellicht am Helden), Assets, Modulstruktur, Meilensteine, verbindliche Regeln für Claude Code und Abnahmekriterien. Sie liegt als docs/SPEC.md im Repository. Der Kern des Startprompts ist dagegen kurz:
Lies docs/SPEC.md und CLAUDE.md vollständig. Der Quellcode der 2D-Version
liegt unter reference/2d/; lies dort zuerst die Daten- und Systemmodule.
Arbeite Meilenstein M0 ab. Erstelle zuerst im Plan-Modus einen Plan mit den
Schritten und den Bevy-APIs, die du in 0.20 nachschlagen musst.
Lege docs/bevy-0.20-notes.md an, bevor du Spielcode schreibst.
Schließe mit scripts/check.sh, einem Eintrag in docs/PROGRESS.md und einem
Commit ab. Danach anhalten und berichten.
Der Auftrag für M1 war ähnlich aufgebaut: Spezifikation, Fortschrittsprotokoll, Entscheidungsprotokoll und Bevy-Notizen lesen, dann planen und umsetzen. Für die weiteren Meilensteine genügte meist ein einzelner Satz wie „Bitte fahre mit M4 fort.“ Alle übrigen Vorgaben standen in den Projektdokumenten.
Arbeiten mit einer unbekannten Engine-Version
Die zentralen Regeln dafür stehen in der Datei CLAUDE.md, die Claude Code zu Beginn jeder Sitzung lädt:
- Bevy 0.20.x ist gepinnt. Kein Upgrade, keine andere Version.
- Dein Trainingswissen zu Bevy ist veraltet und mischt 0.12 bis 0.19.
Bei jeder Bevy-API, deren Signatur du nicht sicher kennst: im Quelltext
unter ~/.cargo/registry/src/*/bevy*-0.20.*/ oder in vendor/bevy-examples/
nachsehen. Nicht raten.
- docs/bevy-0.20-notes.md vor jeder Session lesen und neue Erkenntnisse
dort ergänzen.
Meilenstein 0 diente deshalb noch nicht der Spielentwicklung, sondern der Recherche: Claude Code las die Migration Guides von 0.18 bis 0.20, klonte die offiziellen Beispiele des Release-Tags und schlug die benötigten Schnittstellen im Quelltext nach, meist mit Angabe der Fundstelle. Daraus entstand docs/bevy-0.20-notes.md, ein von Claude Code selbst verfasstes Nachschlagewerk, das mit jedem Meilenstein erweitert wurde und am Ende knapp 900 Zeilen umfasst. Allein die Tabelle der Stellen, an denen älteres Wissen zu falschen Annahmen führt, enthält 34 Einträge. Eine Auswahl:
| Annahme aus älterem Wissen | Bevy 0.20 |
|---|---|
EventWriter / EventReader | MessageWriter / MessageReader |
StateScoped | DespawnOnExit |
NextState::set_if_neq | set_if_different; der alte Name existiert nicht mehr |
| fester Takt mit 60 Hz | Standard sind 64 Hz; 60 Hz müssen explizit gesetzt werden |
| Standardschrift für alle Texte | enthält nur ASCII-Zeichen, also keine Umlaute |
Die letzten beiden Zeilen zeigen, warum sich das Nachschlagen lohnt: Mit 64 statt 60 Ticks pro Sekunde liefe die Spiellogik nicht mehr im Takt des Originals, und in einem deutschsprachigen Spiel wären fehlende Umlaute sofort sichtbar. Das Spiel bringt deshalb zwei eigene Schriften mit: Drybrush für Überschriften und Open Sans für alle übrigen Texte.
Portierung statt Neuentwicklung
Die 2D-Version liegt unter reference/2d/ im Repository und ist die verbindliche Quelle für alle Zahlenwerte. Die Spielregeln sind als reine Funktionen umgesetzt, die ohne das Entity-Component-System (ECS) der Engine auskommen und sich mit festem Seed testen lassen.
Zufallsgenerator und Labyrinth-Algorithmus sind bitgenau portiert: mulberry32 und der Recursive Backtracker liefern für denselben Seed exakt dieselben Werte wie das JavaScript-Original. Die Referenzwerte für die Tests wurden mit Node.js direkt aus dem 2D-Code erzeugt. Der Kern von mulberry32 sieht in Rust so aus:
/// Nächster Rohwert. `| 0`, `Math.imul` und `>>>` rechnen in JS modulo 2³²,
/// hier entsprechen ihnen die `wrapping_*`-Operationen auf `u32`.
pub fn next_u32(&mut self) -> u32 {
self.state = self.state.wrapping_add(0x6d2b_79f5);
let a = self.state;
let mut t = (a ^ (a >> 15)).wrapping_mul(1 | a);
t = t.wrapping_add((t ^ (t >> 7)).wrapping_mul(61 | t)) ^ t;
t ^ (t >> 14)
}
Damit erzeugt derselbe Seed in beiden Versionen dasselbe Labyrinth, platziert dieselben Gegner an denselben Positionen und liefert dieselben Zufallszahlen für die Beute.

Jede Abweichung von der 2D-Version, ob von der Spezifikation vorgegeben oder durch die 3D-Umsetzung bedingt, ist mit Begründung in docs/DECISIONS.md dokumentiert, ebenso alle wesentlichen Festlegungen; insgesamt sind es 35 Einträge. Zwei Beispiele, beide von der Spezifikation vorgegeben: Der Nahkampf trifft in einem Kreissektor von ±60° vor dem Helden statt in einem quadratischen Bereich. Außerdem prüfen die Gegner die Sichtlinie und finden ihren Weg per Breitensuche durch die Gänge, statt wie in 2D direkt auf den Helden zuzulaufen und an der nächsten Wand hängen zu bleiben.
Sieben Meilensteine
Die Umsetzung war in sieben Meilensteine mit jeweils eigenen Abnahmekriterien gegliedert:
| Meilenstein | Inhalt | abgeschlossen um |
|---|---|---|
| M0 | Projektgerüst, Bevy-Notizen, rotierender Würfel nativ und im Browser | 8:45 Uhr |
| M1 | Labyrinth, Bewegung, Kollision, Treppe | 9:30 Uhr |
| M2 | Klassen, Kampf, Gegner-KI, Game Over | 10:44 Uhr |
| M3 | Beute, Inventar, Erfahrung, vollständiges HUD | 18:11 Uhr |
| M4 | Roter Drache, Sieg, Touch-Steuerung, Hochformat | 19:36 Uhr |
| M5 | 3D-Modelle, Animationen, Effekte, Soundeffekte | 21:14 Uhr |
| M6 | Bundle-Größe, Ladeanzeige, Renderauflösung, README | 0:08 Uhr |
Zwischen dem ersten Prompt um 7 Uhr und dem Abschluss von M6 kurz nach Mitternacht lagen längere Pausen; die Sitzungen selbst dauerten zusammen rund acht Stunden. Alle Sitzungen liefen mit Opus 5.5. Die vorgesehene Eskalation auf Fable 5.1, das leistungsfähigere und teurere Modell für besonders anspruchsvolle Aufgaben, war nicht erforderlich.
Bis einschließlich M4 bestand die Grafik nur aus Platzhaltern: Kapseln für die Helden, Quader als Wände, Kegel und Kugeln als Gegner. Das Spiel war damit von der Klassenwahl bis zum Sieg über den Drachen vollständig spielbar, bevor das erste 3D-Modell eingebunden wurde. Welches Spielobjekt wie dargestellt wird, legt ein einzelnes Modul fest. Der Austausch gegen die endgültigen Modelle in M5 blieb dadurch ein lokaler Eingriff, nach demselben Prinzip wie die austauschbaren Emoji-Glyphen der 2D-Version.
Jeder Meilenstein endete mit denselben Schritten: Formatierung, Clippy (der Linter für Rust) ohne Warnungen, Durchlauf aller Tests, ein Probelauf ohne Absturz, Web-Build, Eintrag in docs/PROGRESS.md und Commit. Insgesamt entstanden 50 Commits.
Wie Claude Code das Spiel testet
Claude Code kann am Linux-Desktop weder Tasten drücken noch das laufende Spiel sehen. Um das Spiel dennoch prüfen zu können, hat es die erforderlichen Werkzeuge selbst entwickelt:
- Entwickleroptionen im Spiel: Screenshot nach einer festgelegten Zahl von Sekunden, fester Seed, Sprung auf eine bestimmte Ebene, Unverwundbarkeit sowie das Versetzen des Helden direkt vor den nächsten Gegner oder den Drachen. Die Screenshots wertet Claude Code anschließend selbst aus.
- Headless-Durchläufe: Die echten Plugins des Spiels laufen ohne Fenster. Für jede Klasse wählt der Test per Klick die Klassenkarte aus und besiegt mit der Leertaste einen Geist; anschließend fällt der Held, der Game-Over-Bildschirm erscheint und das Spiel startet neu. Weitere Tests lassen Archer und Krieger den Roten Drachen besiegen.
- Smoke-Test im Browser: Ein Headless-Firefox lädt das Web-Bundle und wird per WebDriver BiDi gesteuert: Klicks, gehaltene Tasten, Touch-Gesten (Tippen und Ziehen), Screenshots und das Sammeln von Konsolenfehlern. Das Smartphone-Format wird dabei emuliert; Chrome, Safari und echte Smartphones standen in dieser Umgebung nicht zur Verfügung.
Insgesamt umfasst das Projekt 153 automatische Tests.
Nach M4 und nach M6 hat zusätzlich jeweils ein neu gestarteter Subagent die Commits geprüft, also eine zweite Claude-Instanz ohne Kontext aus der Umsetzung. Die Befunde waren nicht nur kosmetischer Natur. Bei niedriger Bildrate laufen mehrere Spiel-Ticks pro Frame, und nach dem Sieg wurden die verbleibenden Ticks noch ausgeführt: Eine verspätete Flamme hätte den Sieg nachträglich in ein Game Over verwandeln können. Außerdem fingen die schwebenden Schadenszahlen Touch-Eingaben ab, sodass ein Tipp auf eine Zahl den Helden nicht bewegte. Beide Fehler sind behoben und durch Tests abgesichert.
Auch die Regel „nach zwei gescheiterten Anläufen anhalten und nachfragen“ kam zur Anwendung: In der Sandbox von Claude Code erhielt Firefox keinen WebGL-Kontext. Claude Code hielt nach zwei Anläufen an und beschrieb Ursache und bisherige Lösungsversuche. Gelöst wurde das Problem durch eine Freigabe, mit der das Testskript außerhalb der Sandbox läuft.
Vom Emoji zum 3D-Modell
In der 2D-Version waren alle Figuren Emoji. In der 3D-Fassung stammen alle Modelle und Soundeffekte aus kostenlosen Asset-Paketen unter der Lizenz CC0: Helden, Skelette, Dungeon-Kacheln und Beute von KayKit, Geist und Drachen aus dem Paket „Ultimate Monsters“ von Quaternius sowie 17 Soundeffekte von Kenney. Kostenpflichtige Assets wurden nicht verwendet.
Die Modelle werden reproduzierbar mit Python-Skripten aufbereitet, die Blender ohne Benutzeroberfläche ausführt: Animationen auswählen, Figuren auf dem Boden ausrichten, Hauptfarben an die Farben der 2D-Version anpassen und als GLB exportieren. So bleibt der Geist hellblau und der Rote Drache rot. Das Ergebnis sind 21 Modelle mit zusammen 3,5 MB. Die Waffen befestigt das Spiel zur Laufzeit an den Handknochen der Helden. Soweit die Pakete sie enthalten, verfügen die Figuren über Animationen für Stehen, Laufen, Angriff, Treffer und Tod. Bei den Helden wird das Tempo der Laufanimation an die Bewegungsgeschwindigkeit angepasst, damit die Füße nicht über den Boden gleiten.

Nicht alle Anforderungen ließen sich mit den Paketen abdecken. Das Skelett ist im Paket ohne Rig enthalten, also ohne die Knochenstruktur, die für Animationen benötigt wird. Skelett und Mumie werden deshalb als Ganzes bewegt: Sie wippen beim Laufen, stoßen beim Angriff nach vorn und kippen beim Tod um. Keines der Pakete enthält eine Mumie; sie ist ein umgefärbtes Skelett. Im Icon-Paket von Kenney fanden sich außerdem keine Symbole für Gold, Waffe und Rüstung, weshalb das HUD an diesen Stellen Text statt der Emoji aus der 2D-Version zeigt.
Aufgrund einer Rückmeldung aus dem Spieltest wurden am Morgen nach M6 die Effekte überarbeitet: Magiekugel und Feueratem waren bis dahin einfarbige Kugeln. Da die CLAUDE.md eigene Shader ausschließt, entstanden die neuen Effekte mit den Standardmitteln der Engine: Flächen mit additiver Farbmischung und einer beim Start erzeugten Verlaufstextur, höchstens 240 auf der CPU berechnete Partikel und wenige Punktlichter ohne Schattenwurf. Die Magiekugel zieht nun einen violetten Schweif mit Funken hinter sich her, die Flammen des Drachen flackern und versprühen Glut, die von Gelb zu Dunkelrot verglüht. Die WebAssembly-Datei wurde dadurch um 52 KB größer.

Im Browser: 27 MB statt 100 KB
Die 2D-Version kommt ohne Build-Schritt aus und umfasst insgesamt rund 100 KB. In der 3D-Fassung sind Spiel und Engine in einer gemeinsamen WebAssembly-Datei enthalten. Bereits der rotierende Würfel aus M0 ergab eine Datei von 35,5 MB; mit allen Modellen erreichte das Bundle in M5 41 MB. In Meilenstein 6 wurde Bevy auf die tatsächlich genutzten Features reduziert und das Web-Profil auf Dateigröße optimiert (opt-level = "z", volles LTO, anschließend wasm-opt -Oz):
| Stand | WebAssembly | Bundle gesamt |
|---|---|---|
| M5, alle Bevy-Features | 36,7 MB | 41,0 MB |
| M6, nur genutzte Features, auf Größe optimiert | 23,0 MB | 27,3 MB |
Mit gzip-Komprimierung werden rund 9 MB übertragen. Eine Ladeanzeige zeigt den Fortschritt, bis das Menü erscheint. Außer Bevy selbst bindet das Projekt kein weiteres Crate ein. Das Ende des Ladevorgangs meldet das Spiel der Webseite deshalb indirekt: über den Fenstertitel, den Bevys Fensterschicht im Browser in das alt-Attribut des Canvas-Elements schreibt. Das Bundle besteht ausschließlich aus statischen Dateien und benötigt keine Serverlogik.
Die Touch-Steuerung der 2D-Version wurde ebenfalls übernommen: Ziehen führt den Helden zum Bodenpunkt unter dem Finger, ein Doppel-Tipp löst einen Angriff aus, jeweils mit denselben Schwellenwerten wie in 2D. Im Hochformat erscheint das HUD als Leiste am oberen Rand, und die Kamera rückt ein Stück zurück, damit Gegner nicht erst kurz vor dem Kontakt ins Bild kommen. Auf Smartphones mit hoher Pixeldichte begrenzt das Spiel die Auflösung der 3D-Szene auf zwei Bildpunkte je logischem Pixel und reduziert sie automatisch weiter, wenn die Bildrate unter 27 fps fällt. Schrift und Bedienelemente bleiben dabei scharf.

Die Input-Fassade, die sich in der 2D-Version bei der nachträglichen Touch-Steuerung bewährt hatte, war diesmal von Beginn an vorgegeben: Tastatur und Touch schreiben in eine Ressource PlayerIntent, und die Spielsysteme lesen Eingaben ausschließlich dort. Nur Klicks im Inventar wirken direkt, da die Spiellogik pausiert, solange das Inventar geöffnet ist.
Fazit
Die 20 Minuten im Juni und die rund acht Stunden im Oktober messen zwei verschiedene Dinge. Das 2D-Spiel war ein Test, wie weit ein vager Prompt bei vertrauter Technik führt. Die 3D-Fassung zeigt, wie weit ein Agent mit einer ihm unbekannten Engine-Version kommt, wenn die Rahmenbedingungen stimmen: eine Spezifikation mit Abnahmekriterien, klare Regeln in der CLAUDE.md, fortlaufend ergänzte Notizen, kleine Meilensteine, automatisierte Tests und zwei unabhängige Reviews.
Bemerkenswert ist vor allem, dass das Modell Bevy 0.20 nicht aus dem Training kennen musste. Es genügten die Anweisung, nicht zu raten, und der Quelltext zum Nachschlagen. Die 2D-Version war dabei ein zweites Mal von Nutzen: als ausführbare Spezifikation, an der sich jede Zahl und jede Regel überprüfen ließ.
Wie die 2D-Version läuft auch die 3D-Fassung ohne Installation im Browser. Nach der Klassenwahl führt der Weg durch fünf Labyrinth-Ebenen; auf der letzten wartet der Rote Drache.
👉 Held des Drachenkerkers 3D jetzt im Browser spielen
Zum Vergleich: die 2D-Version und der Artikel zu ihrer Entstehung.
Weitere Posts