18 KiB
Debug-Ansicht: Kollision & unsichtbare Objekte im Spiel (tools/debugviz.py)
Stand: 2026-11-06. Zeigt in allen 34 Level-WADs die Kollisionsgeometrie (auch unsichtbare Wände/Böden, Todesebenen) und unsichtbare Logik-Objekte (Kameras, Trigger, Ausgänge, Checkpoints, Kraft-/Box-Zonen, Umgebungszonen …) direkt im Spiel – als farbiges Drahtgitter, unsichtbare Flächen zusätzlich halbtransparent gefüllt. Spielmechanik bleibt unverändert.
Benutzung
lama-mod debug an # Debug-WADs zuschalten (baut das Overlay neu, aktiviert damit auch andere Mods)
lama-mod debug aus # wieder Original-Level (testlevel-Mod bleibt, wie sie war)
lama-mod debug # Status
Wirkt beim nächsten Laden eines Levels (am besten Spiel neu starten). Nicht umschalten,
während ein Level lädt. Mod-Ordner: ~/.wine-lama/mods/debug/wads/*.wad (gleiche Namen wie
auf der CD, z. B. t1l1m001.wad); die Datei ~/.wine-lama/mods/debug/.aus = abgeschaltet.
Reihenfolge im Overlay: alphabetisch, spätere gewinnen → testlevel (T1L9*) bleibt immer,
Debug-WADs ersetzen nur die Original-Level. lama-mod an|aus|status funktionieren wie
vorher (an überspringt Mod-Ordner mit .aus). Sicherung des alten Skripts:
deb-build/lama-mod.bak-vor-debug.
Neu bauen (z. B. nach Änderungen an Farben):
python3 tools/debugviz.py --all ~/.wine-lama/mods/debug/wads --report /tmp/dv.json
python3 tools/debugviz.py IN.wad OUT.wad [--no-fill] [--no-markers] [--no-coll] [--opaque]
[--width 0.007] [--offset 0.012]
Laufzeit ≈ 10–40 s je Level.
Farblegende
Alle Farben sind RGB (0–255). Linien = Drahtgitter (deckend), Füllung = halbtransparent (Alpha 96/255, Blendmodus 1 der Engine).
Kollisionsflächen (Rahmen um jedes Kollisionspolygon der Welt-Kacheln)
Kantenfarbe nach Lage, solange das Material 0 (normal) ist:
| Farbe | RGB | Bedeutung |
|---|---|---|
| Grün (Linien) | 40,255,40 | begehbarer Boden (Normale steil nach oben, ny ≥ 0,7) |
| Gelbgrün (Linien) | 200,255,0 | Schräge (0,2 ≤ ny < 0,7) |
| Blau (Linien) | 0,150,255 | Wand (−0,2 < ny < 0,2) |
| Orange (Linien) | 255,130,0 | Decke / Überhang (ny ≤ −0,2) |
| Rot, halbtransparent gefüllt | 255,0,0 | unsichtbare Kollision: keine Render-Fläche innerhalb ±0,5 Einheiten entlang der Normale (= unsichtbare Wand/Boden/Decke). Die Kantenfarbe zeigt weiterhin Lage bzw. Material. |
Kollision mit Sondermaterial (Byte 1 des Kollisionspolygons ≠ 0): Kanten in Materialfarbe, bei unsichtbaren Polygonen auch die Füllung in Materialfarbe (statt Rot):
| Material | Farbe | RGB | Bedeutung |
|---|---|---|---|
| 30 (0x1e) | Magenta, nur Linien (keine Füllung) | 255,0,255 | kein Boden / Fall- und Todesebene: Spieler fällt hindurch (FUN_004036d0 setzt Boden = keiner). Meist Modell 0 bei y ≈ −2,75 in jeder Rasterzelle unter den Inseln → magentafarbenes Gitter = Absturz-/Todeszone. |
| 16 | Violett, immer gefüllt | 190,60,255 | Ausgangs-Boden: LevelDoor löst nur aus, wenn der Spieler auf Material 16 in der Türzelle steht |
| 17 (0x11) | Gelb | 255,255,0 | selektive Kollision: wirkt nur für Objekte mit Laufzeit-Flag 0x8000000 (Strat+0xe8) |
| 18 (0x12) | Hellorange/Pfirsich | 255,200,120 | selektive Kollision: wirkt NICHT für Objekte mit Flag 0x8000000 |
| 1 | Türkis | 0,200,200 | Sondermaterial, Bedeutung unbekannt (Strat-Skripte werten es aus) |
| 2 | Weiß | 255,255,255 | dto. |
| 3 | Rosa | 255,120,170 | dto. (häufig in Welt 5 Berg) |
| 5 | Mint | 120,255,200 | dto. (Fluss, Achterbahn) |
| 6 | Lavendel | 160,120,255 | dto. |
| 7 | Hellorange | 255,170,80 | dto. |
| 8 | Dunkelgrün | 0,130,60 | dto. |
| 9 | Hellblau | 150,200,255 | dto. |
| 10 | Oliv | 150,150,0 | dto. |
| 11 | Braun | 150,90,40 | dto. |
| 13 | Lachs | 255,130,110 | dto. |
| 15 | Hellgelb | 255,255,150 | dto. |
| 20 | Petrol | 0,120,140 | dto. |
| 26 | Dunkelviolett | 110,40,160 | dto. |
| 27 | Silber | 190,190,190 | dto. (Verfolgungsjagd t1l2m003) |
| 28 | Pink | 255,0,140 | dto. |
| 33 | Dunkelrot | 150,0,0 | dto. |
| 255 | Fast schwarz | 20,20,20 | dto. |
| sonstige | Hellgrau | 230,230,230 | (kommt in den Originalen nicht vor) |
Objekt-Marker (unsichtbare Strats, MAP-Strat-Einträge)
Markerwürfel (10 cm) auf einem dünnen Pfahl 0,35 über dem Objekt-Ursprung; kurzer waagrechter Strich = Blickrichtung (Kameras, Checkpoints).
| Farbe | RGB | Kategorie | Typen |
|---|---|---|---|
| Weiß, Pfeil flach am Boden | 255,255,255 | Spielerstart (Richtung) | Llama, KuscoAndPachaTogetherOnATree (Fluss), RollerCoaster, LlamaChase |
| Violett + Drahtwürfel 1×1×1 um die Rasterzelle | 190,60,255 | Ausgang (Auslösezelle) | LevelDoor, VillageEndDoor, EndGameDoor, TeleportDoor |
| Grüntürkis | 0,255,140 | Checkpoint | CheckPointPost, CheckPointBox |
| Cyan | 0,255,255 | Kamera | Camera* (CameraSide, CameraLift, CameraForceInsideBox …), CutSceneCamera*, RiverWaterfallCamera |
| Gelb | 255,255,0 | Trigger | CutSceneTrigger*, Trigger, Say* (Sprüche), ChangeToBunny/Turtle, RiverStartSign |
| Orange | 255,90,0 | Kraft-/Sonderzonen | Force*, FallOffNoHurt, ObjectDontDropInBox, RiverCurrentBox, RiverRebound, WaterReboundPoints*, SuckingWPs, ObjectSuckPoints, RiverTrackChange, TrackSwitch, RiverWhirlpool, BackgroundRotationChanger |
| Gold | 255,200,0 | Geheimnis-Zone | Secret |
| Grau | 170,170,170 | sonstige unsichtbare Steuer-Objekte | CheatTeleport, Wompy*, Spawner, Helper, Coin-Linien/-Kreise, Rain, DrippingWater, WaterfallMist, MusicBox, FlockOfBirds, Bats, Scorpions*, AppearingPlatforms* … |
| Dunkelgrau, kleiner Punkt (6 cm) | 90,90,90 | alle übrigen Objekte (Ursprung) | Münzen, Gegner, Türen … – damit wirklich nichts fehlt |
| Rosa Drahtwürfel je Rasterzelle | 255,100,180 | Umgebungs-/Musik-/Nebelzone | MAP-Block 4 (90-Byte-Einträge, Zelle x/y/z) |
Zonen-Boxen: hat ein Marker-Objekt genau 2 Wegpunkte und liegt das Objekt im Rechteck dazwischen, ist das ein Box-Bereich (Secret, CameraSide/Lift, ObjectDontDropInBox, FallOffNoHurt, RiverCurrentBox …): Drahtquader in der Kategoriefarbe von min(y) bis max(y)+1,2 (die Höhe ist geschätzt – der Code prüft vermutlich nur x/z), bei Flächen ≤ 64 Einheiten² mit halbtransparentem Boden (Alpha 70). Wegpunkt-Ketten anderer Marker-Objekte: kleine Würfel (5 cm) in abgedunkelter Kategoriefarbe (60 %), bei Kraftzonen mit Verbindungslinien (z. B. WaterReboundPoints-Pfade, CutSceneTrigger-Kamerafahrt nur als Punkte).
Wie es gebaut ist (Entscheidungen)
- Kollisions-Overlay an die TRAK-Modelle angehängt (nicht als eigene Kacheln): pro Kollisionspolygon ein Rahmen aus 2·n Vertices (äußere Ecken + um die Linienbreite nach innen versetzte Ecken, aus den Kantenebenen berechnet), 2·n Dreiecke; Füllung nutzt die inneren Ecken mit. Alles 0,012 entlang der Flächennormale versetzt (kein Z-Fighting). Dadurch stimmen Kachel-Transformation, Zonen-/Sichtbarkeit und Kachel-Wechsel (Alt-Modelle, WFPC 0x10000) automatisch. Kollision wird aus dem Spielraum zurückgerechnet (geomlib.coll_decode/ coll_polygon, z gespiegelt).
- Face-Flags der Overlay-Dreiecke: 0x800 | 0x400 (doppelseitig) | 0x4000 (Vertexfarben ignorieren) | 0x8 bei jedem Texturwechsel und spätestens alle 250 Faces (Render-Batch).
- Farben = angehängte Flachfarb-Texturen (TEXT-Tabelle, Seite −1): deckend Flags 0x105, halbtransparent 0x1105 (Bits 12–14 = 1 → Tabelle 0x573eb8: Blendmodus 1 = SRCALPHA/INVSRCALPHA, Alpha aus dem 4. Byte (v1) des Eintrags; im Spiel geprüft). Halbtransparente Dreiecke laufen über den Sortierpuffer (FUN_0041ed90, 512 KB/Frame ≈ 5000 Dreiecke; ist er voll, fallen sie einfach weg – kein Absturz). Deshalb gibt es Füllungen nur für unsichtbare Kollision, Material 16 und kleine Zonenböden.
- Vertexfarben-Block in MAP: je Kachel (und je Farbsatz/Frame, auch für Alt-Modelle) um nV(Overlay) Einträge 0x00808080 verlängert (Byte 3 = 0, ändert die Frame-Anzahl nicht).
- Unsichtbar-Erkennung: Render-Dreiecke aller Kacheln in Weltkoordinaten, nach Zellen gebuckelt; für Mittelpunkt + 4 Punkte (70 % Richtung Ecken) jedes Kollisionspolygons wird ein Strahl entlang der Normale (±0,5) gegen Dreiecke mit ähnlicher Ausrichtung (|cos| > 0,4) getestet; < 60 % Treffer = unsichtbar. Je Modell Mehrheitsentscheid über bis zu 6 Instanzen. Strat-Modelle (STPC: Türen, Plattformen, Figuren) zählen NICHT als Render-Fläche – Kollision hinter beweglichen Objekten kann daher rot erscheinen. (Erste Version mit 0,06/0,15 Abstand markierte ganze Hauswände und Felswände rot, weil die Kollisionshülle 0,2–0,4 vor der sichtbaren Wand liegt – zu viel Rauschen.)
- Marker als neue Kacheln ohne Kollision, je Rasterzelle ein Modell (Linien in ≤ 1-Stücke zerteilt und in die Zelle ihres Mittelpunkts gelegt) → bekommen automatisch die Zone der Zelle. Neue Kacheln werden hinten angehängt (Indizes der Original-Kacheln bleiben).
- Spielmechanik unverändert: keine Kollisionspolygone hinzugefügt/geändert, Strats, Wegpunkte, Parameterpool, Zonen und Rest von MAP byte-gleich (wird nach dem Schreiben geprüft: Strats/Knoten/Rest/Original-Kacheln identisch).
- Größe: WADs wachsen um 0,1–4 MB (max. 8,9 MB, t1l6m003). Level-Speicher (Arena 16 MB, FUN_0041ef00) hält TRAK+STPC+MAP – reicht für alle (Ladetest).
Grenzen / bekannt
- Kollision der Objekt-Modelle (STPC: bewegliche Plattformen, Türen, Kisten …) wird nicht gezeigt – die bewegen sich; nur ihr Ursprung als dunkelgrauer Punkt.
- Zonen-Höhen der Box-Bereiche sind geschätzt; ob die Engine y prüft, ist offen.
- Bedeutung der meisten Sondermaterialien unbekannt (nur Farbe + Anzahl, s. Tabelle unten); Material 30 = kein Boden, 16 = Ausgang, 17/18 = selektiv sicher aus dem Code.
- Umgebungszonen (MAP-Block 4): Zelle sicher, Bedeutung (Nebel/Musik/Kamera) nur mittel sicher; Vorgabe-Eintrag (Position 1,1,1) wird nicht gezeichnet.
- Liegt die Kamera dicht an einem Marker/einer Linie, zerschneidet der Near-Plane-Clip der Engine die Dreiecke manchmal zu großen Fetzen (nur kurz sichtbar).
- Leistung: unter Wine/llvmpipe (Xvfb) ohne spürbaren Einbruch; auf echter GPU unkritisch (≤ 2000 zusätzliche Vertices je Kachelmodell, Ø ~1–2× so viele Dreiecke wie das Original).
- Testlevel T1L9 (Testwelt) hat keine Debug-Version (testlevel-Mod hat Vorrang).
Statistik je Level (Stand Build 2026-11-06)
| Level | Welt | WAD alt→neu (KB) | Koll.-Polygone | davon unsichtbar | Sondermaterialien (Anzahl Polygone) | Marker |
|---|---|---|---|---|---|---|
| t1l1m001 | Dorf | 6158→8235 | 3474 | 215 | 2:138, 6:4, 8:35, 9:13, 16:8, 17:5, 18:84, 28:19, 30:1 | ausgang 1, checkpoint 6, geheimnis 2, kamera 6, kraft 6, objekt 95, sonst 4, start 1, trigger 1, umgebung 12 |
| t1l1m002 | Dorf | 5471→7573 | 3909 | 130 | 6:4, 8:14, 16:9, 18:65, 28:23, 30:1 | ausgang 1, checkpoint 5, geheimnis 1, kamera 8, kraft 5, objekt 89, sonst 9, start 1, trigger 1, umgebung 15 |
| t1l1m003 | Dorf | 5891→8348 | 3893 | 79 | 2:15, 6:4, 8:8, 16:5, 17:3, 18:458, 20:6, 28:23, 30:1 | ausgang 1, kamera 3, kraft 6, objekt 45, sonst 3, start 1, trigger 2, umgebung 4 |
| t1l1m004 | Dorf | 5866→7006 | 2169 | 60 | 2:15, 8:8, 16:16, 17:3, 18:90, 30:1 | ausgang 2, geheimnis 1, kamera 2, kraft 1, objekt 31, sonst 2, start 1, trigger 1, umgebung 5 |
| t1l2m001 | Dschungelnacht | 5094→7491 | 3933 | 460 | 1:26, 2:111, 6:156, 9:34, 16:22, 17:24, 18:284, 20:80, 28:28, 30:138, 33:1 | ausgang 1, checkpoint 2, geheimnis 1, kamera 3, kraft 6, objekt 39, sonst 8, start 1, trigger 1, umgebung 8 |
| t1l2m002 | Dschungelnacht | 5329→7561 | 3715 | 389 | 1:216, 2:57, 6:154, 9:24, 16:34, 17:23, 18:319, 28:28, 30:50 | ausgang 1, checkpoint 4, geheimnis 1, kamera 3, kraft 7, objekt 105, sonst 2, start 1, trigger 1, umgebung 18 |
| t1l2m003 | Dschungelnacht (Verfolgung) | 2837→5142 | 4844 | 630 | 5:3, 9:6, 10:6, 11:37, 16:26, 27:206, 30:46 | kamera 2, kraft 1, objekt 33, sonst 4, start 1, trigger 1 |
| t1l3m001 | Fluss | 4099→8220 | 8371 | 1000 | 5:26, 16:8, 18:23 | ausgang 2, geheimnis 1, kamera 13, kraft 4, objekt 140, sonst 13, start 1, trigger 5 |
| t1l3m002 | Fluss | 3799→8249 | 8824 | 1097 | 5:40, 16:5, 18:23, 30:1 | ausgang 2, geheimnis 1, kamera 19, kraft 44, objekt 115, sonst 39, start 1, trigger 6 |
| t1l3m003 | Fluss | 4497→8537 | 8387 | 868 | 5:56, 16:5 | ausgang 4, geheimnis 1, kamera 15, kraft 7, objekt 52, sonst 15, start 1, trigger 3 |
| t1l3m004 | Fluss | 2674→3754 | 2201 | 228 | 5:18, 16:5 | ausgang 2, kamera 5, kraft 4, objekt 31, sonst 7, start 1, trigger 2 |
| t1l4m001 | Dschungeltag | 5469→7380 | 3214 | 230 | 1:148, 6:105, 10:33, 16:18, 17:33, 18:158, 20:25, 28:24, 30:10 | ausgang 1, checkpoint 9, geheimnis 1, kamera 5, kraft 12, objekt 120, sonst 3, start 1, trigger 1, umgebung 10 |
| t1l4m002 | Dschungeltag | 5807→8045 | 3820 | 157 | 1:186, 6:123, 10:80, 16:33, 17:55, 18:309, 20:6, 28:98, 30:22 | ausgang 1, checkpoint 7, geheimnis 2, kamera 1, kraft 14, objekt 135, sonst 3, start 1, trigger 1, umgebung 14 |
| t1l4m003 | Dschungeltag | 6320→8886 | 4805 | 135 | 1:174, 2:52, 6:10, 10:33, 16:36, 17:110, 18:890, 20:186, 28:27, 30:33, 255:8 | ausgang 1, checkpoint 3, geheimnis 2, kamera 6, kraft 4, objekt 99, sonst 3, start 1, trigger 1, umgebung 16 |
| t1l5m001 | Berg | 6090→8613 | 4419 | 188 | 3:356, 8:96, 16:24, 17:35, 18:539, 20:66, 28:6, 30:87 | ausgang 1, checkpoint 3, geheimnis 2, kamera 5, kraft 2, objekt 83, sonst 7, start 1, trigger 1, umgebung 15 |
| t1l5m002 | Berg | 5949→8558 | 5242 | 220 | 2:20, 3:396, 8:23, 9:15, 16:19, 17:33, 18:342, 20:57, 30:120 | ausgang 1, checkpoint 3, geheimnis 4, kamera 10, kraft 3, objekt 67, sonst 6, start 1, trigger 1, umgebung 7 |
| t1l5m003 | Berg | 4989→6796 | 3399 | 98 | 3:232, 8:223, 16:17, 18:20, 20:6, 30:78 | ausgang 1, checkpoint 5, geheimnis 1, kamera 4, kraft 1, objekt 71, sonst 6, start 1, trigger 1, umgebung 2 |
| t1l6m001 | Stadt | 6210→8227 | 2857 | 169 | 6:29, 16:18, 17:140, 18:110, 30:38 | ausgang 1, checkpoint 4, geheimnis 1, kamera 5, kraft 3, objekt 83, sonst 3, start 1, trigger 5, umgebung 20 |
| t1l6m002 | Stadt | 5155→7060 | 1771 | 106 | 6:56, 16:9, 17:20, 18:39, 30:17 | ausgang 1, checkpoint 10, geheimnis 1, kamera 7, kraft 9, objekt 127, sonst 16, start 1, trigger 5, umgebung 46 |
| t1l6m003 | Stadt | 6693→8924 | 2462 | 148 | 1:39, 16:13, 17:80, 18:154, 28:3, 30:10 | ausgang 1, checkpoint 11, geheimnis 6, kamera 11, kraft 6, objekt 107, sonst 15, start 1, trigger 3, umgebung 59 |
| t1l7m001 | Katakomben (Achterbahn) | 3054→6705 | 4043 | 20 | 5:54, 11:18, 13:18, 16:9, 30:18 | kamera 1, objekt 2, sonst 36, start 1, trigger 1, umgebung 14 |
| t1l7m002 | Katakomben | 5280→7722 | 1795 | 111 | 2:1, 11:3, 16:44, 30:93 | ausgang 3, checkpoint 12, geheimnis 5, kamera 6, kraft 4, objekt 186, sonst 12, start 1, trigger 1, umgebung 23 |
| t1l7m003 | Katakomben (Achterbahn) | 2496→5140 | 1999 | 11 | 5:54, 11:90, 13:36, 15:18, 16:9, 30:9 | kamera 1, objekt 11, sonst 41, start 1, trigger 1 |
| t1l7m004 | Katakomben | 5299→6978 | 1892 | 61 | 2:7, 16:32, 30:70 | ausgang 1, checkpoint 3, geheimnis 3, kamera 4, kraft 7, objekt 93, sonst 10, start 1, trigger 2, umgebung 15 |
| t1l7m005 | Katakomben (Achterbahn) | 2390→4782 | 1885 | 9 | 5:54, 11:36, 13:36, 16:9, 30:9 | kamera 1, objekt 1, sonst 51, start 1, trigger 1, umgebung 9 |
| t1l8m001 | Labor | 6632→8824 | 3396 | 185 | 1:40, 8:9, 16:16, 17:8, 18:181, 30:56 | ausgang 1, checkpoint 2, geheimnis 2, kamera 8, kraft 2, objekt 99, sonst 3, start 1, trigger 2, umgebung 19 |
| t1l8m002 | Labor | 5427→7112 | 2204 | 76 | 16:1, 17:44, 18:496, 30:42 | ausgang 1, geheimnis 1, kamera 5, kraft 2, objekt 74, sonst 2, start 1, trigger 3, umgebung 1 |
| t1l8m003 | Labor | 4656→5546 | 1398 | 34 | 16:9, 17:10, 18:196, 30:21 | ausgang 1, checkpoint 2, geheimnis 1, kamera 2, kraft 2, objekt 36, sonst 2, start 1, trigger 3, umgebung 6 |
| t1l8m004 | Labor | 5817→8407 | 2993 | 124 | 9:10, 16:66, 17:1, 30:57 | ausgang 1, checkpoint 7, geheimnis 3, kamera 12, kraft 6, objekt 164, sonst 3, start 1, trigger 7, umgebung 46 |
| t1l8m005 | Labor | 5375→8660 | 4041 | 179 | 7:10, 16:78, 17:1, 30:82 | checkpoint 7, geheimnis 1, kamera 14, kraft 5, objekt 113, sonst 15, start 1, trigger 2, umgebung 47 |
| t1l8m006 | Labor | 5423→5948 | 738 | 44 | 2:13, 8:24, 16:3, 17:5, 18:27, 26:4 | ausgang 1, objekt 15, start 1, trigger 17 |
| t6l6m001 | Sonder (Optionen/Karte) | 1331→1482 | 333 | 0 | kamera 1, objekt 3 | |
| t6l6m002 | Sonder (Optionen/Karte) | 3605→3640 | 64 | 0 | kamera 1, objekt 2 |
(Kollisionspolygone je TRAK-Modell gezählt, nicht je Kachel-Instanz.)
Tests (2026-11-06)
Offline (alle 33 Debug-WADs, $JOB/tmp/dv/offcheck.py): TRAK parst und baut byte-gleich
zurück; ≤ 8000 Vertices je Modell (max. 2012, t1l4m003); Render-Batches ≤ 256 Faces; alle
Texturindizes < Tabellengröße; Vertexfarben-Block je Kachel = nV(Modell) (alle Frames);
MAP mit mapchunk vollständig geparst (Rest 0 Byte) und byte-gleich neu gebaut; Strats,
Wegpunkte, Parameterpool, Umgebungszonen, Zonentabelle/-raster, Alt-Block und Original-Kacheln
unverändert; Original-Modelle (Vertices, Faces, Kollision) byte-genau unverändert; neue
Marker-Modelle ohne Kollision; alle anderen Chunks (STPC, Sound, LGPC …) identisch;
Kacheln im Raster. TRAK+STPC+MAP+LGPC ≤ 7,6 MB (Level-Arena 16 MB).
Im Spiel geladen (lamatest, über Slot Welt 9 als T1L9M001.wad, ~40–90 s gespielt/gedreht, kein Absturz, kein Hänger, keine Fehler im Wine-Log): t1l1m001 (mehrfach, Sichtprüfung), t1l1m003, t1l1m004, t1l2m001, t1l2m002, t1l3m001–004 (Fluss läuft auch im Slot 9 normal: Boot fährt), t1l4m001–003, t1l5m001–003, t1l6m001–003 = 19 Level. Getestet wurde der Build direkt vor dem endgültigen: identische Geometrie, nur die Farbwerte der Sondermaterialien wurden danach auf feste Farben je Material umgestellt (+8–16 Byte Texturtabelle). Die Vorschaubilder stammen ebenfalls aus diesem Build – Sondermaterial-Farben darin (z. B. Türkis-Füllung im Berg-Bild) entsprechen noch nicht ganz der Legende oben. Nur offline geprüft: t1l1m002 und t1l2m003 (Ladeversuch scheiterte vorher an der Menü-Erkennung von lamatest, nicht am Level), t1l7m001–005 (Katakomben/Achterbahn), t1l8m001–006 (Labor), t6l6m001/002. Ein Test über den echten Spielstand-Slot wurde nicht gemacht.
lamatest-Änderung nebenbei: Spielstand-Auswahl mit mehr Versuchen und 0,3 s langen Tastendrücken (unter CPU-Last gingen kurze Drücke verloren).
Bilder: notes/img/debug/00_montage.jpg (6 Welten), 01_…06_*.jpg (1280×720).