image: teaser.webp image_alt: "Der Saal wie ein verlassenes Büro, schräg aus einer Ecke: gelbe Tapete, tapezierte Säulen, Teppichfliesen, ein Schreibtisch mit einem Schulstuhl und ein leeres Regal; hinten durch einen runden Bogen der grüne Salon" kind: projekt duration: 2 Doppelstunden curriculum: "Sek I: Digitale Bilder und Visualisierung (Figuren, Farbmodelle); Oberstufe: Vertiefung Computergrafik (prozedurale Texturen, Shader)" topics: [computergrafik, digitale-bilder] reference: [workspace, kartografie] template: https://github.com/specht/backrooms-starter.git template_name: der Backrooms-Vorlage

Die Backrooms

Du bist durch eine Wand gefallen. Dahinter liegen die Backrooms: gelbe Tapete, feuchter Teppich, das Summen der Leuchten, Räume ohne Ende. Du kartierst sie in Textdateien und baust eigene Räume dazu, einen Saal wie ein verlassenes Büro, mit Säulen, Teppichfliesen und einem Schreibtisch, und einen Salon mit Holz an den Wänden. Dein Browser macht daraus ein Bauwerk in 3D und berechnet das Licht, das zwischen den Wänden hin- und herfällt, am Rechner, auf dem Handy, mit Rot-Cyan-Brille oder mit einer VR-Brille. Zum Schluss schaust du nach, wie das Programm aus ein paar Zeilen Text Wände macht und Holz und Marmor, ohne ein einziges Bild.

Wenn du das hier liest, bist du durchgefallen. Nicht durch eine Prüfung. Durch die Wirklichkeit. Irgendwo hat eine Wand nicht gehalten, was sie versprochen hat, und jetzt bist du hier.

Keine Panik. Der Teppich ist feucht, aber er trägt. Die Leuchten summen, aber sie leuchten. Und du bist nicht der erste Mensch hier: Wir haben angefangen, alles aufzuschreiben.

Erste Seite des Feldhandbuchs der Kartografen
Level 0, »Die Lobby«
Überlebensschwierigkeit Klasse 1: sicher, stabil, keine Entitäten gesichtet
Ausdehnung so groß, wie du es baust
Ausgänge einer, sagen die Kartografen, ganz am Ende dieser Seite. Den Tab zu schließen, soll auch helfen (unbestätigt).

Die Backrooms sind eine Legende aus dem Internet. 2019 stellte jemand in einem Forum das Foto eines leeren Büroraums mit gelber Tapete ein, und jemand anderes schrieb dazu: Wer an der falschen Stelle aus der Wirklichkeit »noclippt«, landet hier, in endlosen leeren Räumen. Noclip heißt ein Cheat aus alten Ego-Shootern wie Quake: Mit ihm läuft man durch Wände. Seitdem haben unzählige Leute weitere Levels erfunden, Geschichten geschrieben und Videos gedreht.

Kane Parsons 2026 bei einem Interview: ein junger Mann mit dunklen Locken in einem grau melierten Pullover vor einer gelben Wand, mit einem leichten Lächeln.

Kane Parsons (geboren 2005), amerikanischer Filmemacher, auf YouTube »Kane Pixels«. Im Januar 2022, mit 16, stellte er »The Backrooms (Found Footage)« online: neun Minuten, die aussehen wie eine alte Videokassette. 1991 tritt ein Kameramann einen Schritt zurück, fällt durch den Boden und flieht durch gelbe Gänge vor etwas Dunklem. Die Kamera, sagt das Video, tauchte erst fünf Jahre später wieder auf.

Gefilmt ist daran nichts. Du baust deine Gänge aus Text, er baute seine im freien 3D-Programm Blender und rechnete das Wackeln der Kamera und das Rauschen der Kassette dazu. Mit diesem Video und rund zwei Dutzend weiteren wurden die Backrooms weltbekannt. Im Mai 2026 kam sein Kinofilm »Backrooms« heraus; mit 20 war er der jüngste Regisseur, dessen Film in Nordamerika am ersten Wochenende auf Platz 1 stand.

Foto: Lachlan und Austin Macfarlane, 2026, CC BY 4.0, zugeschnitten (Wikimedia Commons)

Hier baust du deine eigenen Backrooms. Du beschreibst Räume in Textdateien: wo die Wände stehen, wo die Leuchten hängen, wo eine Tür in den nächsten Raum führt. Ein Programm im Browser liest sie, baut daraus ein Bauwerk in 3D und berechnet das Licht: wohin es fällt, wo Schatten liegen und wie es von Wänden, Boden und Decke zurückgeworfen wird. Programmieren musst du dafür nicht. Wer will, findet das ganze Programm im Ordner engine/ und kann darin herumschrauben.

1. Ausrüstung

Was du brauchst: eine Karte (du hast keine), eine Lampe (es gibt hier genug) und einen Ordner, in den du alles schreibst, was du findest. Den Ordner gibt es schon. Er lag hier, als wir ankamen.

Feldhandbuch, Seite 2

Die Vorlage klonen

Alles, was du brauchst, steckt in der Backrooms-Vorlage:

Stelle zuerst sicher, dass du keinen Ordner geöffnet hast. Um sicherzugehen, drücke einfach den Shortcut für »Ordner schließen«: StrgK und dann F. Dein Workspace sollte jetzt ungefähr so aussehen:

Ein leerer Workspace ohne geöffneten Ordner.

Klicke auf »Clone Repository« und füge die Adresse der Vorlage ein:

https://github.com/specht/backrooms-starter.git

Das Eingabefeld für die Adresse des Repositorys.

Bestätige mit Enter. Danach wählst du das Verzeichnis, in dem das Repository gespeichert werden soll: den Ordner /workspace.

Die Auswahl des Zielordners /workspace.

Das Repository wird jetzt in einen Unterordner von /workspace geklont, der so heißt wie das Repository. Beantworte die Frage, ob es jetzt geöffnet werden soll, mit »Open«:

Die Frage, ob das geklonte Repository geöffnet werden soll.

Danach liegt die Vorlage in /workspace/backrooms-starter:

Die geklonte Vorlage im Explorer: die Ordner engine, models, rooms und vendor, dazu .gitignore, export.sh, index.html, level.ini, README.md und textures.html; im Editor ist level.ini geöffnet.

Darin liegt dein Level. Es beginnt klein, in level.ini und im Ordner rooms: ein Zimmer, ein Gang und zwei farbige Räume. Ein fertiges Level zum Durchlaufen wartet am Ende der Reihe.

Aufgabe 1Die Vorlage ist da

Die Backrooms-Vorlage liegt in /workspace/backrooms-starter.

Eintreten

Der Eintrag »Go Live« unten rechts in der Statusleiste; der Tooltip sagt »Click to run live server«.

Im Workspace ist die Erweiterung »Live Server« installiert. Unten rechts findest du den Eintrag »Go Live«. Klicke darauf, um die Vorschau zu starten. Sie öffnet sich in einem neuen Browsertab.

Der Live Server ist ein kleiner Webserver in deinem Workspace. Er liefert die Dateien aus deinem geöffneten Ordner aus, und die Adresse in der Vorschau zeigt, welche Datei du gerade siehst.

Statt »Go Live« steht unten rechts »Port : 5500«; der Tooltip sagt »Click to close server«.

Solange der Live Server läuft, steht an derselben Stelle die Nummer seines Ports, zum Beispiel »Port : 5500«. Ein Klick darauf hält ihn wieder an. Das brauchst du, wenn du einen anderen Ordner öffnest: Der Live Server liefert immer den Ordner aus, in dem er gestartet wurde.

Falls sich die Vorschau einmal nicht mehr aktualisiert, lade die Seite neu: StrgR oder F5.

Die Vorschau zeigt index.html. Zuerst ist es dunkel, nur feine hellblaue Linien zeigen die Kanten der Räume, wie in der Automap. Dann gehen die Leuchten an, eine nach der anderen, die nächsten zuerst, und oben links wächst ein Balken: Das Licht wird berechnet.

Das Zimmer, noch unfertig beleuchtet; oben links der Name des Levels, »Baking light« mit einem Fortschrittsbalken und darunter die Schalter.

Wie lange das dauert, hängt von der Grafikkarte deines Rechners ab. Ist es fertig, steht dort »Light baked in …«:

Das Zimmer im warmen Licht seiner Leuchte, gelbe Tapete, dunkle Sockelleiste, durch die offene Tür sieht man in den Gang.

Klick ins Bild, dann siehst du dich mit der Maus um. Esc gibt die Maus wieder frei.

Taste Was passiert
W A S D laufen, mit Shift rennen
↑ ↓ ← → vor und zurück laufen, nach links und rechts drehen
M oder Tab die Automap: das ganze Bauwerk als Drahtgitter
Shift R zurück zum Anfang
P den Kasten oben links aus- und wieder einblenden

Wo du stehst, merkt sich die Adresse der Seite, eine offene Automap auch, so gedreht und gezoomt, wie sie ist. Lädst du neu, stehst du wieder dort, solange sich der Grundriss nicht geändert hat: Ändere einen Raum, lade neu und sieh dir dieselbe Stelle noch einmal an.

Auf dem Handy oder Tablet läufst du mit dem linken Daumen: Wo er das Bild berührt, erscheint ein Ring, und schiebst du ihn aus dessen Mitte, läufst du in diese Richtung, ganz hinaus geschoben rennst du. Der rechte Daumen wischt, um dich umzusehen. In der Automap dreht ein Finger die Karte, zwei Finger zoomen und verschieben sie. Dort ist der Kasten oben links zuerst zu: an seiner Stelle öffnet ihn, − darin schließt ihn wieder, »More« zeigt alle Schalter.

Ausprobieren: Drück M. Die Automap zeigt das Bauwerk als Drahtgitter, jeden Raum mit seinem Namen, die Leuchten als gelbe Punkte; der rote Pfeil bist du. Zieh mit der Maus, um die Karte zu drehen, mit Shift, um sie zu verschieben, und zoom mit dem Mausrad. Lauf ein paar Schritte, während sie offen ist, und schau nach unten: Was macht die Karte? V zeigt statt des Drahtgitters die Räume selbst von oben, ohne Decken, mit ihrem Licht. Esc schließt die Karte.

So sieht die Automap aus, wenn du am Start nach Nordosten und etwas nach unten schaust und mit dem Mausrad ein Stück herauszoomst:

Die Automap über dem ganzen Level: Zimmer, Gang, Blau und Rot als hellblaues Drahtgitter von schräg oben, jeder Raum mit seinem Namen, gelbe Punkte für die Leuchten, ein roter Pfeil mit Ring und Strahl im Zimmer; Linien hinter Wänden sind blass.

Und mit V, die Räume selbst:

Dieselbe Automap mit den Räumen von oben, ohne Decken: gelbe Tapete und Teppich im Zimmer und im Gang, der blaue Raum blau, der rote rot, darüber das hellblaue Drahtgitter und die Namen.

2. Kartografie

Wir kartieren in Feldern. Ein Feld ist ein Meter. Eine Raute ist eine Wand, ein Punkt ist Teppich. Was nicht auf der Karte steht, gibt es nicht. Das ist die einzige Regel, auf die man sich hier verlassen kann.

Notiz, mit Kugelschreiber auf die Tapete geschrieben

Ein Raum

Öffne rooms/zimmer.room. Das ist der Raum, in dem du aufgewacht bist:

# Ein kleines Zimmer. Du weißt nicht, wie du hierhergekommen bist.

[room]
baseboard = 0.08, #86763c
name = Zimmer
height = 2.6
look = east              # am @ schaust du zur Tür

[map]
#######
#.....#
#.@.L.1
#.....#
#.....#
#######

[L]
light = #ffe7b8
power = 0.9

[1]
door = gang 1

Eine Raumdatei besteht aus Abschnitten in eckigen Klammern. In [room] steht, wie der Raum aussieht: sein Name, wie hoch die Decke ist (2,6 m), eine dunkle Sockelleiste unten an den Wänden, 8 cm hoch, und wohin du am Anfang schaust. Eine Zeile, die mit # beginnt, ist ein Kommentar, ebenso alles ab einem # mit Leerzeichen davor und danach; eine Farbe wie #86763c hat kein Leerzeichen dahinter.

In [map] steht der Grundriss, von oben gesehen, oben ist Norden. Hier zählt jedes Zeichen, Kommentare gibt es darin nicht:

Zeichen Bedeutung
# Wand
. Boden
@ hier fängst du an, nur einmal im ganzen Level
Leerzeichen nichts, außerhalb des Raums
ein Buchstabe eine Leuchte, ein Block oder ein Modell; was es ist, steht im Abschnitt mit diesem Buchstaben
eine Ziffer eine Tür in einen anderen Raum, beschrieben im Abschnitt mit dieser Ziffer; dieselbe Ziffer mehrmals in einer Reihe, nebeneinander oder untereinander, ist eine breite Tür

[L] sagt, dass das L eine Leuchte ist, mit warmem, gelblichem Licht. [1] macht aus der 1 am rechten Rand eine Tür.

Türen

Eine Tür ist ein Feld, das zwei Räumen gehört. door = gang 1 heißt: Diese 1 ist dasselbe Feld wie die 1 in rooms/gang.room. Das Programm legt die beiden Räume so nebeneinander, dass die Türen aufeinanderliegen. Ihre Wände dürfen sich dabei überdecken, ihre Böden nicht.

Zwei Räume dürfen sich auch mehrere Türen teilen, jede mit ihrer eigenen Ziffer. So entsteht aus vielen kleinen Dateien ein Bauwerk. level.ini nennt nur den ersten Raum (start = zimmer). Das Programm liest ihn, dann jeden Raum, zu dem eine seiner Türen führt, dann deren Nachbarn, bis es keine neuen Türen mehr gibt.

Aufgabe 2Eine Tür ins Nichts

Du legst rooms/keller.room an. In seinem Grundriss steht eine 1, und darunter [1] mit door = gang 6. Im Gang gibt es aber keine 6, und keine andere Datei nennt den Keller. Was passiert, wenn du die Vorschau neu lädst?

Eine Tür ins Nichts

Hier geht es weiter, sobald du deine Antwort oben abgegeben hast.

Eine Datei, zu der keine Tür führt, liest das Programm also gar nicht.

3. Ein Raum mehr

Gestern war im Gang neben dem Zimmer eine Wand. Heute ist dort eine Öffnung. Ich habe nachgezählt: Das Feld ist dasselbe. Die Wand ist weg. Dahinter ist eine Kammer, die es gestern nicht gab.

Seite aus einem durchnässten Notizbuch

Eine Kammer anbauen

Leg im Ordner rooms eine neue Datei kammer.room an:

# Eine Kammer, die gestern noch nicht da war.

[room]
name = Kammer
height = 2.2
wallpaper = #9a8a4c

[map]
#####
5...#
#.L.#
#...#
#####

[L]
light = #ffb070
power = 0.9
flicker = 1

Die Leuchte ist orange, und mit flicker = 1 flackert sie ab und zu. Die Farbe der Tapete steht als Hexadezimalzahl da, wie in CSS: Rot, Grün und Blau, je zwei Ziffern.

Noch führt keine Tür in die Kammer, also gibt es sie nicht. Öffne rooms/gang.room. Weit unten im Grundriss ist links die 1, die Tür zum Zimmer. Ersetze in dieser Zeile das # am rechten Rand durch eine 5:

#...#1...5#...#

und schreib ganz unten in die Datei, wohin sie führt:

[5]
door = kammer 5

Speichere beide Dateien und lade die Vorschau neu. Die Kammer liegt östlich vom Gang, gegenüber der Tür zum Zimmer. In kammer.room steht kein Abschnitt [5]: Es genügt, wenn einer der beiden Räume die Tür beschreibt.

Die Kammer: niedrig, mit dunklerer Tapete im orangefarbenen Licht ihrer Leuchte; durch die Tür in der Ecke fällt Licht aus dem Gang.

Stimmt etwas nicht, steht oben links in Rot, in welcher Datei (und, wenn es eine Zeile ist, in welcher) das Programm hängen geblieben ist, auf Englisch, zum Beispiel rooms/kammer.room: room kammer and room rot lie in the same place at the same height. Das heißt: Der Raum läge auf dem Boden eines anderen; dahinter steht auch, an welchem Feld. Schieb die Tür an eine andere Stelle oder mach den Raum kleiner.

4. Ein Saal, Schritt für Schritt

Hinter der Kammer ist noch eine Tür. Dahinter: ein Saal, leer, mit einer Decke aus Platten wie in einem Büro. Jedes Mal, wenn ich zurückkomme, steht etwas mehr darin.

Seite aus einem durchnässten Notizbuch, andere Handschrift

Hinter der Kammer baust du einen Saal, Schritt für Schritt: erst den Grundriss, dann Säulen, farbiges Licht, Möbel und einen Boden wie im Büro; unterwegs siehst du, wie eine schräge Decke aussähe. Nach jedem Schritt speicherst du und lädst die Vorschau neu.

Der Grundriss

Gib der Kammer in rooms/kammer.room eine zweite Tür, an der rechten Wand, in der Zeile der ersten:

#####5...6#.L.#

und schreib unten dazu, wohin sie führt:

[6]
door = saal 1

Dann leg rooms/saal.room an:

# Ein Saal hinter der Kammer.

[room]
name = Saal
height = 3

[map]
#############
#...........#
#...L...L...#
1...........#
#...........#
#...........#
#...L...L...#
#...........#
#############

[L]
light = #fff3cf

Ein Saal, 11 m lang und 7 m breit, mit vier Leuchten in zwei Reihen. Weil [L] nur einmal beschrieben ist, sind alle vier gleich.

Der leere Saal von seiner Tür aus: gelbe Wände, eine flache Decke mit vier Leuchten in zwei Reihen, Teppich.

Schräge Decken

Die Decke des Saals ist flach und 3 m hoch, wie in einem Büro, und so bleibt sie. Sie kann aber auch schräg sein: Zwei Höhen machen die Decke schräg, slope sagt, wie. gable ist ein Satteldach: an den Wänden 3 m, in der Mitte 7 m hoch, der First läuft an der längeren Seite entlang. Die Leuchten liegen dann so schräg wie die Decke über ihnen. Weil sie höher hängen, bekommen sie mit power mehr Kraft:

[room]name = Saalheight = 3, 7slope = gable
[L]light = #fff3cfpower = 1.6

Derselbe Saal unter einem Satteldach: Die Decke steigt von beiden Wänden zur Mitte hin an, die Leuchten liegen schräg in den Dachflächen, die Stirnwand ist fünfeckig.

Eine Decke kann auch nur in eine Richtung ansteigen, wie ein Pultdach. Mit slope = east statt gable wird die Decke des Saals nach Osten immer höher, also nach rechts im Grundriss:

height = 3, 7slope = east

An der Westwand ist sie dann 3 m hoch, an der Ostwand 7 m. Statt east geht auch north, south oder west. Auch hier liegen die Leuchten so schräg wie die Decke. So sähe der Saal damit aus, von der Seite:

Der leere Saal von der Seite: Die Decke steigt von rechts nach links gleichmäßig an, die Leuchten liegen schräg in ihr.

Hast du eine der beiden ausprobiert, stell danach wieder height = 3 ein und nimm die Zeile mit slope heraus: Für die nächsten Schritte bleibt die Decke flach.

Säulen

Ein Buchstabe im Grundriss kann auch ein Block sein. Vier Säulen, je zwei an den langen Seiten, zwischen den Leuchten:

#...........##...L.S.L.S.#1...........##...........##...........##...L.S.L.S.##...........#
[S]
block = 0.7, 4, 0.7      # höher als die Decke: Die Säule verschwindet in ihr

block = 0.7, 4, 0.7 ist 0,7 m breit, 4 m hoch und 0,7 m tief, mitten auf seinem Feld. Ist ein Block höher als die Decke, verschwindet er in ihr. block = 1 füllt das ganze Feld einen Meter hoch, eine Kiste. Mit base = 2 schwebt ein Block zwei Meter über dem Boden, mit color = #6a5a3a bekommt er eine eigene Farbe; ohne sieht er aus wie die Wände seines Raums. Mit material = marble ist er aus Marmor, auch in einem Raum mit Tapete; es gehen alle Arten, die es für Wände gibt (in »Andere Wände und Böden«). Durch Blöcke läuft man nicht hindurch, und sie werfen Schatten.

Der Saal mit vier tapezierten Säulen, die bis an die Decke reichen; an Boden und Wänden ihre weichen Schatten.

Mit shape = round wird ein Block rund, eine Säule wie in einem alten Bad, so breit und tief wie der Block. So sähe der Saal damit aus; für die nächsten Schritte bleiben die Säulen eckig:

[S]block = 0.7, 4, 0.7      # höher als die Decke: Die Säule verschwindet in ihrshape = round

Derselbe Saal mit vier runden Säulen bis an die Decke; das Licht der Leuchten läuft weich um sie herum.

Farbiges Licht

Die Leuchte hinten rechts soll grün leuchten, wie das Schild über einem Notausgang. Sie bekommt einen eigenen Buchstaben:

#...........##...L.S.G.S.##...........#
[G]
light = #30e060
power = 2
size = 1.2, 1.2

light ist die Farbe, size die Größe in Metern: Eine größere Leuchte wirft weichere Schatten. Das grüne Licht fällt auf Wände, Boden und Säulen und wird von ihnen zurückgeworfen, grün gefärbt. So sähe der Saal mit der grünen Leuchte aus; für die nächsten Schritte bleiben alle vier weiß.

Der Saal mit einer grünen Leuchte hinten rechts: Die Wand hinten, die rechte Wand und die Säulen dort leuchten grün, nach vorn wird es wieder gelb.

Möbel

Mitten im Saal steht ein Schreibtisch, davor ein Stuhl, als wäre gerade jemand aufgestanden. Ich habe mich nicht hingesetzt. Als ich wiederkam, stand der Stuhl ein Stück weiter vom Tisch weg.

Letzter Eintrag einer Kartografin, Saal

In die Mitte des Saals kommt ein Schreibtisch mit einem Stuhl davor, an die Südwand ein Regal:

1...........##....CM.....##...........##...L.S.L.S.##...R.......#
[M]
model = models/metal_office_desk/metal_office_desk_1k.gltf   # Poly Haven, CC0
height = 0.76
rotation = 270

[C]
model = models/SchoolChair_01/SchoolChair_01_1k.gltf   # Poly Haven, CC0
height = 0.82
rotation = 90

[R]
model = models/worn_metal_rack/worn_metal_rack_1k.gltf   # Poly Haven, CC0
height = 1.8
offset = 0, 0, 0.25      # an die Südwand

Die Möbel sind 3D-Modelle aus dem Ordner models, im Format glTF: eine Datei .gltf, die das Modell beschreibt, daneben seine Daten und Texturen. height macht ein Modell so hoch wie angegeben, rotation dreht es in Grad um seine senkrechte Achse, hier den Schreibtisch mit den Schubladen zum Stuhl und den Stuhl zum Schreibtisch. offset verschiebt es auf seinem Feld, in Metern nach Osten, nach oben und nach Süden: Das Regal rückt 25 cm an die Wand. Auch Modelle werfen Schatten und bekommen Licht, das Wände und Boden zurückwerfen, und wo ein Modell sich selbst verdeckt, ist es auf ihm dunkler.

Der Saal mit einem grauen Schreibtisch aus Metall zwischen den Säulen, davor ein blauer Schulstuhl; rechts an der Wand ein leeres Regal aus Metall.

Weitere Möbel liegen im selben Ordner; zwei davon stehen gleich im Salon. Was ein Modell sonst noch kann, etwa auf einem Sockel stehen oder aus einem anderen Material sein, steht in der Kartografie.

Ein Boden wie im Büro

Zum Schluss bekommt der Saal einen Boden aus Teppichfliesen wie in einem Büro, in einem schmutzigen Gelbgrau:

[room]name = Saalheight = 3floor = carpet_tilescarpet = #7a7050

Der fertige Saal: gelbe Tapete, eine Decke aus Platten mit vier Leuchten, tapezierte Säulen, ein Boden aus gelbgrauen Teppichfliesen, in der Mitte der Schreibtisch mit dem Stuhl, rechts das Regal.

Andere Wände und Böden

Teppichfliesen sind nur eine Möglichkeit. walls kennt neun Arten, floor elf, jede in der Farbe aus wallpaper (Wände) und carpet (Boden), Marmor in seiner eigenen:

Wert Wände (walls) Boden (floor)
wallpaper, carpet Tapete mit Rautenmuster Teppich
marble Marmor Marmor
wood senkrechte Bretter Dielen
tiles Fliesen Fliesen
velvet Samt in senkrechten Streifen, wie im Kino
plain einfarbig einfarbig
concrete Sichtbeton: Fugen der Schaltafeln und die Löcher ihrer Anker Beton mit Fugen
brick Ziegel im Läuferverband Ziegelpflaster
terrazzo Terrazzo: Steinchen in Zement Terrazzo
carpet_tiles Teppichfliesen wie im Büro, jede gegen ihre Nachbarn gedreht
checker Schachbrett, schwarz und in der Farbe aus carpet
parquet Fischgrätparkett: kurze Stäbe, abwechselnd längs und quer

Für Fliesen wie in einem Schwimmbad zum Beispiel walls = tiles, floor = tiles, wallpaper = #e6ecef und carpet = #c4ced3, dazu eine helle Decke mit ceiling = #e8ecee. So sieht der leere Saal vom Anfang mit jeder Art aus, Holz mit Wandlampen und Samt mit Kerzenleuchtern statt Leuchten an der Decke; Lampen, die selbst leuchten, kommen in einem tieferen Level (ein Klick zeigt ein Bild groß):

5. Ein Salon

In der Südwand des Saals ist ein Bogen, der gestern nicht da war. Dahinter: Holz an den Wänden, ein Sofa, ein Tisch. Auf dem Tisch nichts. Das Sofa ist warm.

Seite aus einem durchnässten Notizbuch, wieder die erste Handschrift

Der Saal ist fertig. Hinter seiner Südwand baust du einen zweiten Raum, und diesmal geht es um die Wände selbst: was unten an ihnen ist, was oben, und wie eine Tür aussieht.

Eine breite Tür

Gib dem Saal in der Mitte seiner Südwand eine Tür, drei Felder breit:

#...L.S.L.S.##...R.......######444#####
[4]
door = salon 1

Dieselbe Ziffer mehrmals in einer Reihe, nebeneinander wie hier oder untereinander, ist eine breite Tür. Die Tür auf der anderen Seite muss genauso breit sein; ist sie es nicht, steht oben links, wie breit jede ist. Leg dahinter rooms/salon.room an:

# Ein Salon hinter dem Saal. Jemand hat ihn eingerichtet und ist nie zurückgekommen.

[room]
name = Salon
height = 3.2
wallpaper = #66784f
floor = wood
carpet = #8a6646
ceiling = #ece4cc
baseboard = 0.1, #3a281a

[map]
#####111#####
#...........#
#..L.....L..#
#...........#
#.....T.....#
#.....S.....#
#..L.....L..#
#...........#
#############

[L]
light = #ffe7b8
power = 1.4

[S]
model = models/sofa_03/sofa_03_1k.gltf   # Poly Haven, CC0
height = 0.93
rotation = 180          # mit Blick zur Tür

[T]
model = models/small_wooden_table_01/small_wooden_table_01_1k.gltf   # Poly Haven, CC0
height = 0.53

Grüne Tapete, ein Boden aus Dielen, eine helle Decke und eine Sockelleiste aus dunklem Holz, 10 cm hoch. Sofa und Tisch sind Modelle wie der Schreibtisch, aus dem Ordner models; rotation = 180 dreht das Sofa, bis es zur Tür schaut.

Ein Salon mit grüner Tapete und Dielenboden, links ein Sofa und ein kleiner Tisch; in der Wand gegenüber eine breite, rechteckige Öffnung in den gelben Saal.

Ein runder Bogen

Eckig sieht die Öffnung nach einem Lager aus. arch macht aus einer Tür einen Bogen:

[4]door = salon 1arch = 2.9              # oben rund, in der Mitte 2,9 m hochcasing = on             # mit Rahmen: Putz, Bekleidung und Schwelle

Über die ganze Breite der Tür spannt sich ein Halbkreis, in der Mitte so hoch wie die Zahl. Hier ist die Tür 3 m breit, der Halbkreis hat also 1,5 m Radius und beginnt 1,4 m über dem Boden. Es genügt, wenn einer der beiden Räume arch nennt, so wie bei door.

Eine Tür ist so tief wie die Wand, ein ganzes Feld, und sieht aus wie der Raum, dem dieses Feld gehört. Zwischen zwei gelben Räumen fällt das nicht auf; hier wäre der Bogen innen gelb tapeziert wie der Saal, und vom Salon aus sähe die grüne Wand dünn wie Papier aus. casing = on gibt der Tür einen Rahmen: innen heller Putz, unten eine Schwelle aus Stein und auf beiden Seiten der Wand eine Leiste um die Öffnung, in der Farbe der Sockelleiste des Raums, hier also dunkles Holz.

Derselbe Salon; die Öffnung zum Saal ist jetzt ein runder Bogen, durch den man in den gelben Saal sieht.

Ausprobieren: Mit einer zweiten Zahl wird der Bogen schmaler als die Tür, und daneben bleibt Wand: arch = 2.9, 1.2 ist nur 1,2 m breit. Wie sieht arch = 2.4, 0.9 aus, ein schmaler, hoher Durchgang? Stell danach arch = 2.9 wieder her.

Ein Lambris

Die Wand soll unten aus Holz sein und oben Tapete bleiben:

baseboard = 0.1, #3a281adado = 1, #553a27       # unten Holz, bis 1 m über dem Bodendado_material = wood

dado = 1, #553a27 macht die Wände bis 1 m über dem Boden anders, in dieser Farbe, und dado_material = wood macht diesen Teil aus Holz; ohne ist er aus demselben wie der Rest der Wand. Das Wort kommt aus der Baukunst: Im Englischen heißt der untere Teil einer Wand, der anders aussieht als der Rest, dado, nach dem italienischen Wort für Würfel, dem würfelförmigen Mittelstück im Sockel einer Säule. Auf Deutsch sagt man Lambris.

Der Salon mit dunklem Holz an den Wänden bis auf Hüfthöhe, darüber grüne Tapete; der Bogen und das Sofa wie vorher.

Eine Stuhlleiste

Wo Holz und Tapete sich treffen, kommt eine helle Leiste:

dado_material = wooddado_rail = 0.06, #d9cdae

dado_rail ist eine Leiste auf der Kante des Lambris, hier 6 cm hoch. Auf Englisch heißt sie auch chair rail, Stuhlleiste: Sie hielt die Lehnen der Stühle von der Wand fern und schützte so die Tapete.

Der Salon mit einer hellen Leiste auf der Oberkante des Holzes, die ringsum an allen Wänden entlangläuft und am Bogen endet.

Ein Gesims

Dann die Kante, an der die Wand die Decke trifft:

dado_rail = 0.06, #d9cdaecornice = 0.14, #f6f3ec

cornice ist eine Leiste oben, wo Wand und Decke sich treffen, schräg wie eine Hohlkehle, hier 14 cm hoch. Auf Deutsch heißt sie Kranzgesims oder, aus Gips, Stuckleiste. Jedes dieser Stücke liegt an einer Kante: die Sockelleiste, wo die Wand auf den Boden trifft, die Stuhlleiste, wo das Holz endet, das Gesims, wo die Decke beginnt.

Der fertige Salon: oben an allen Wänden eine helle, schräge Leiste zur Decke, darunter grüne Tapete, eine helle Stuhlleiste, dunkles Holz und eine dunkle Sockelleiste; durch den Bogen der gelbe Saal.

Runde Ecken

Zuletzt verlieren die Ecken des Salons ihre Kanten. Setz in die vier Ecken des Grundrisses statt # einen Buchstaben und beschreib ihn:

[map]r####111####r#...........#
#...........#r###########r[r]round = 2               # die Ecken des Raums rund, 2 m Radius

Ein Buchstabe statt eines #, dessen Abschnitt round nennt, ist eine Wand mit runden Ecken. Treffen an seinem Feld zwei Wände aufeinander wie hier, wird die Ecke des Raums ein Viertelkreis mit diesem Radius. Boden und Decke folgen ihm, und alle Leisten laufen um die Rundung herum. Ragt eine Wand in den Raum, wird mit round ihre Kante rund: Das Ende einer Wand, die ein Feld dick ist, wird mit round = 0.5 ein Halbkreis.

Der Salon mit runden Ecken: Die grüne Wand biegt in einem Viertelkreis um die Ecke, Sockelleiste, Holz, Stuhlleiste und Gesims laufen ohne Kante mit.

Ausprobieren: Wie groß darf der Radius hier werden? Probier round = 4: Oben links steht dann, an welchem Feld er nicht mehr passt und warum. Öffne danach die Automap: Auch dort sind die Ecken rund.

6. Dein eigener Raum

Jetzt bist du dran: Bau einen Raum nach deiner Idee und schließ ihn mit einer Tür an. Was du in [room] einstellen kannst:

Eintrag Bedeutung
name der Name, den die Automap zeigt
height Deckenhöhe in Metern; zwei Zahlen für eine schräge Decke
slope wie die Decke schräg ist: north, east, south, west (sie steigt in diese Richtung an) oder gable (ein Satteldach)
walls wallpaper (Tapete), marble (Marmor), wood (Holz), tiles (Fliesen), velvet (Samt), plain (einfarbig), concrete (Beton), brick (Ziegel) oder terrazzo
floor carpet (Teppich), marble, wood, tiles, plain, concrete, brick, terrazzo, carpet_tiles (Teppichfliesen), checker (Schachbrett) oder parquet (Fischgrätparkett)
wallpaper, carpet, ceiling die Farben von Wänden, Boden und Decke
baseboard die Sockelleiste: Höhe und Farbe; ohne Angabe 8 cm und etwas dunkler als die Tapete, none: keine
dado die Wände unten anders: Höhe und Farbe, dado_material sagt, woraus
dado_rail eine Leiste auf der Kante von dado: Höhe und Farbe
cornice eine Leiste oben, wo Wand und Decke sich treffen: Höhe und Farbe
look wohin du am @ schaust: north, east, south, west oder Grad, im Uhrzeigersinn von Norden aus (look = 30: etwas rechts von Norden)

Für die Buchstaben im Grundriss:

Eintrag Bedeutung
light eine Leuchte unter der Decke, in dieser Farbe; dazu power (wie hell), size (wie groß, in Metern) und flicker = 1 (sie flackert)
block ein Block: Breite, Höhe, Tiefe; eine Zahl: ein ganzes Feld so hoch. Dazu base (wie hoch er schwebt), color, material (auch cardboard, ein Karton), shape = round und rotation (in Grad um die senkrechte Achse gedreht)
model ein Modell aus models/: height (wie hoch), rotation (in Grad gedreht), material = marble, pedestal (ein Sockel: Breite, Höhe, Tiefe)
round statt eines #: eine Wand mit runden Ecken, so viele Meter Radius

Und für eine Tür, im Abschnitt ihrer Ziffer:

Eintrag Bedeutung
door = gang 2 diese Ziffer ist dasselbe Feld wie die 2 im Gang
arch = 2.4 oben rund, ein Halbkreis, in der Mitte 2,4 m hoch; arch = 2.4, 0.8: nur 0,8 m breit, daneben Wand
casing = on ein Rahmen: innen Putz, eine Schwelle, auf beiden Seiten eine Leiste um die Öffnung

Es gibt noch mehr: Böden, die ansteigen, Treppen, Räume übereinander, Wasser. Das kommt in den tieferen Levels. Alle Einträge stehen zum Nachschlagen im Handbuch unter Kartografie und in der README.md der Vorlage. Der Dateiname ist der Name des Raums, den eine Tür nennt: nur Kleinbuchstaben, Ziffern, - und _.

Aufgabe 3Ein Raum nach deiner Idee

In rooms liegt außer den Räumen der Vorlage und denen, die du auf dieser Seite gebaut hast (Kammer, Saal und Salon), ein Raum, den du selbst entworfen hast. Sein Name besteht aus Kleinbuchstaben, Ziffern, - und _, und er endet auf .room. Damit es ihn im Level gibt, braucht er eine Tür zu einem anderen Raum.

Tipp

Schreib zuerst den Grundriss in [map], mit einer Ziffer in einer Wand, und dann in einem Raum, den es schon gibt, die passende Tür mit door = name ziffer.

7. Mit Brille

Mit der Brille sind die Gänge tiefer. Ich weiß nicht, ob die Brille sie tiefer zeigt oder ob sie tiefer werden, wenn man sie aufsetzt.

Zettel, an eine Rot-Cyan-Brille geklebt

3 schaltet auf ein Bild für eine Rot-Cyan-Brille um: Jedes Auge sieht die Räume von seinem eigenen Platz aus, und dein Gehirn macht daraus Tiefe. Wie das funktioniert, steht in der Aktivität 3D-Grafik mit Anaglyphen. Auch die Automap ist dann räumlich, wie ein Modell auf dem Tisch.

Öffnest du die Seite im Browser einer VR-Brille, steht unten »ENTER VR«. Dann gehst du mit dem linken Stick, und hältst du dazu den linken Abzug unter dem Zeigefinger oder drückst den Stick ein, läufst du; mit dem rechten Stick drehst du dich. Statt der Automap zeigt der rechte Abzug über deinem rechten Handgelenk eine kleine Karte der Umgebung, so gedreht wie das Bauwerk: Ein Gang, der auf ihr nach links führt, führt auch wirklich nach links. Du bist der Ring in ihrer Mitte. Damit das geht, muss die Brille die Adresse deiner Vorschau öffnen können.

8. Im Maschinenraum

Hinter einer Tür, die auf keiner Karte steht, haben wir einen Raum voller Kabel gefunden. Es summt dort lauter als anderswo. Wir glauben, dass hier alles gemacht wird.

Feldhandbuch, letzte beschriebene Seite

Bis hierher hast du gebaut. Jetzt schauen wir hinter die Wände: Das Programm steht im Ordner engine/, in JavaScript, und benutzt die 3D-Bibliothek three.js. Die liegt in vendor/: Die Seite lädt nichts aus dem Internet. Jedes Level sieht sich ein Stück davon genauer an, hier zwei: wie aus Textdateien ein Bauwerk wird, und woher Tapete, Holz und Marmor kommen.

Datei Was sie tut
level.js liest level.ini und die Räume und legt sie an ihren Türen aneinander
geometry.js baut daraus Böden, Decken, Wände, Leisten und Blöcke
bake.js berechnet das Licht auf der Grafikkarte
textures.js malt Tapete, Teppich, Decke und Samt, ohne ein einziges Bild
main.js lädt alles, schaltet die Leuchten an und zeichnet jedes Bild; seine Shader rechnen Holz, Fliesen und Marmor
controls.js, automap.js Laufen und Umsehen (auch mit den Daumen) und die Automap

Vom Text zum Bauwerk

level.js macht aus den Dateien in vier Schritten ein Bauwerk:

  1. Lesen. Es fängt mit dem Raum aus start = an und merkt sich jeden Raum, zu dem eine seiner Türen führt, in einer Queue. Dann liest es den vordersten aus der Queue und so weiter, bis sie leer ist; jeden Raum nur einmal. In der Informatik heißt das Breitensuche: erst alle Nachbarn des Anfangs, dann deren Nachbarn. Darum liest es eine Datei, zu der keine Tür führt, nie.
  2. Legen. Der erste Raum liegt, wo er liegt. Jede Tür zu einem Raum, der noch nirgends liegt, schiebt diesen so, dass die beiden Türfelder aufeinanderliegen. Führen mehrere Türen zu einem Raum, muss jede passen; sonst steht oben links this door doesn't fit.
  3. Ein Gitter. Alle Räume kommen in ein großes Gitter aus Feldern, ein Meter je Feld. Für jedes Feld steht fest, ob dort Boden ist, Wand oder nichts, und zu welchem Raum es gehört. Zwei Räume auf demselben Feld meldet das Programm: lie in the same place.
  4. Flächen. geometry.js setzt ein Stück Wand überall dort, wo ein Feld mit Boden an eines ohne grenzt, von Boden bis Decke, und über jedes Feld mit Boden ein Stück Decke. Ein # im Grundriss ist im Bauwerk also keine dicke Mauer, sondern eine dünne Fläche an der Kante des Felds davor. Darum dürfen sich die Wände zweier Räume überdecken. Stücke nebeneinander legt es zu großen Flächen zusammen, solange sie nicht knicken.

Mit E siehst du das Gerüst des Bauwerks: jede Kante, an der zwei Flächen im Winkel aneinanderstoßen, an Ecken, an Leisten, an Möbeln und am Bogen. Am Anfang, solange das Licht noch fehlt, zeigt die Vorschau genau diese Linien. In den runden Ecken ist keine Linie: Dort knickt nichts. Im Salon, mit T ohne Texturen, damit man sie besser sieht:

Der Salon mit hellblauen Linien auf allen Kanten: wo die Wände auf Boden und Decke treffen, an den Leisten, um den Bogen, an Sofa und Tisch; über die runden Ecken laufen nur die Linien unten und oben, keine senkrechte.

Texturen ohne ein einziges Bild

Tapete, Teppich, Marmor, Holz, Fliesen und Samt sind keine Fotos: textures.js malt sie beim Laden, auf eine Leinwand des Browsers (ein canvas), mit Formen oder Punkt für Punkt. Man nennt das prozedurale Texturen: Gespeichert ist nicht das Bild, sondern das Rezept dafür. Die Vorlage braucht so keine Bilddateien, und jede Farbe in wallpaper oder carpet bekommt ihre eigene Textur.

Die Tapete entsteht in drei Schritten: eine Farbe, darauf feine senkrechte Streifen, abwechselnd etwas heller und dunkler, dann ein blasses Rautenmuster:

Und die vergilbten, feuchten Flecken? Malte die Textur sie, kämen sie mit ihr jeden Meter wieder, und auf einer großen Wand sähe man ihr Muster. Darum kommen sie erst beim Zeichnen dazu, im Shader jeder Fläche: aus Rauschen, nicht über die Textur, sondern über die ganze Welt, in drei Größen. Es wiederholt sich nirgends, keine zwei Wände sehen gleich aus, und eine große Wand kostet nicht mehr als eine kleine. Dasselbe gilt für Holz, Fliesen und Marmor, wie weiter unten steht: Kein Brett kommt zweimal vor, und eine Wand von 100 m kostet nicht mehr als eine von einem Meter.

Wo die Textur selbst Zufall braucht, die Fasern im Teppich oder die Töne der Bretter, kommt er aus einer Formel (random in textures.js): Jede Zahl wird aus der vorigen berechnet, und mit derselben ersten Zahl kommt immer dieselbe Folge. So sieht alles bei jedem Laden gleich aus.

Marmor ist schwieriger: Seine Adern sind keine Form, die man malen könnte. Für jeden Punkt der Textur rechnet das Programm aus, wie hell er ist, so, wie Ken Perlin 1985 Marmor beschrieben hat:

  1. Rauschen (englisch Noise): Auf einem Gitter von 4 × 4 Punkten liegt je eine Zufallszahl, dazwischen wird weich gemischt.
  2. Turbulenz: dasselbe Rauschen in vier Größen, jede doppelt so fein und schwächer als die vorige, zusammengezählt.
  3. Ein Sinus quer über die Textur gibt gerade Streifen; eine Ader ist dort, wo er nahe null ist.
  4. Zählt man die Turbulenz zum Sinus dazu, verbiegen sich die Streifen zu Adern.

Holz geht ähnlich: Bretter in je eigenem Ton, eine Maserung aus einem Sinus quer über jedes Brett, von zwei weiteren Sinuswellen sanft hin und her gebogen, zuletzt die Fugen zwischen den Brettern und quer, wo eines endet:

Im Level rechnet der Shader Holz, Fliesen und Marmor auf Wänden und Böden selbst aus, für jeden Bildpunkt aus seiner Stelle in der Welt, nach demselben Rezept. Der Zufall kommt dort nicht aus einer Folge, sondern aus der Stelle selbst: Aus der Nummer eines Bretts wird eine Zahl gerechnet, immer dieselbe für dasselbe Brett, und daraus sein Ton, seine Länge und seine Maserung. So ist jedes Brett anders, keine Fliese hat den Ton ihrer Nachbarin, und die Adern des Marmors, aus Rauschen im Raum, laufen über die Ecke von der Wand auf den Boden weiter. textures.html zeigt das Rezept auf einem Quadrat.

So sieht das Rezept für Fliesen aus, in engine/main.js, in GLSL, der Sprache der Shader. Die Funktion läuft für jeden Bildpunkt einer gefliesten Fläche, jedes Mal, wenn ein Bild gezeichnet wird; uv ist die Stelle auf der Fläche in Metern, baseColor die Farbe aus wallpaper oder carpet:

vec3 tiles(vec2 uv) {
    vec2 cell = floor(uv * 10.0), inside = fract(uv * 10.0);
    float tone = 0.95 + 0.08 * hash2(cell + vec2(floor(vWorld.y * 10.0) * 0.37, 0.0));
    float aa = max(fwidth(uv.x), fwidth(uv.y)) + 1e-5;
    vec2 edge = min(inside, 1.0 - inside) / 10.0;
    float grout = max(line(edge.x, 0.003, aa), line(edge.y, 0.003, aa));
    return pow(min(baseColor * mix(tone, 0.7, grout), vec3(1.0)), vec3(2.2));
}
  • floor(uv * 10.0) ist die Nummer der Fliese, zehn auf einem Meter, fract(uv * 10.0) die Stelle in ihr, von 0 bis 1.
  • hash2 macht aus der Nummer eine Zahl zwischen 0 und 1, die zufällig aussieht, für dieselbe Fliese aber immer gleich ist. Daraus kommt ihr Ton: Keine Fliese gleicht ihrer Nachbarin, und nichts wiederholt sich, auch auf einer Wand von 100 m nicht.
  • edge ist der Abstand zum nächsten Rand der Fliese, in Metern. Wo er kleiner als 3 mm ist, liegt die Fuge.
  • fwidth(uv.x) sagt, wie viel Fläche ein Bildpunkt hier misst. Weit weg ist ein Bildpunkt breiter als eine Fuge; dann zeichnet line sie weich und blasser, statt dass sie flimmert.
  • pow(…, 2.2) rechnet die Farbe vom Bildschirm in Licht um, mit dem das Programm danach rechnet.

Tapete, Teppich, Decke und Samt bleiben Texturen. Jede ist ein Quadrat von einem Meter, auf der Wand liegt es nebeneinander, immer wieder. Am rechten Rand muss die Textur darum genau so weitergehen, wie sie am linken anfängt, und unten wie oben, sonst sähe man an jeder Wiederholung eine Naht. Die Streifen und Rauten der Tapete gehen deshalb glatt in einen Meter auf, und das Rauschen des Marmors auf einer Statue wiederholt sich genau über die Breite seiner Textur. Neunmal nebeneinander, die roten Linien zeigen, wo eine Wiederholung endet:

Ein großes Quadrat aus Marmor, durch feine rote Linien in drei mal drei Felder geteilt; die grauen Adern laufen über die roten Linien hinweg, ohne abzubrechen.

Ausprobieren: Öffne in der Vorschau statt index.html die Seite textures.html?show=marble. Ändere in engine/textures.js beim Marmor die Zahl in vein / 0.08, etwa auf 0.25, und lade neu: Wie ändern sich die Adern? Und was passiert mit turbulence * 5, wenn du 5 durch 12 ersetzt? Im Level ändert das nur den Marmor der Statuen: Wände und Böden aus Marmor rechnet marble in engine/main.js, dort steht dasselbe Rezept. Ersetze in tiles in engine/main.js jede 10.0 durch 5.0, gib dem Saal walls = tiles und lade neu: Wie groß sind die Fliesen jetzt? Mit git checkout engine/ ist alles wieder wie vorher.

Was ein Shader ist, steht im Handbuch zu GLSL. Wenn du am Programm etwas änderst und nichts mehr geht: Die Konsole des Browsers (F12) sagt, in welcher Zeile es hakt, und git diff zeigt, was du geändert hast.

9. Ein Ausgang

Hinter dem Saal geht es weiter, sagt eine Karte, die wir in einer Sofaritze gefunden haben. Nach Osten steigt der Boden, nach Norden führt eine Treppe, und ganz am Rand der Karte hat jemand einen Pfeil nach unten gezeichnet und nichts dazugeschrieben.

Feldhandbuch, eingelegtes Blatt, an den Rändern verbrannt

Weiter geht es in Level 1: Böden, die ansteigen, eine Treppe ein Stockwerk hinauf, ein Dachboden und ein Loch im Boden.