Files
llamamod/notes/testharness.md
T

8.2 KiB
Raw Blame History

Test-Harness tools/lamatest.py

Startet "Ein Königreich für ein Lama" unbeaufsichtigt und unsichtbar (Xvfb :5, Ton in Null-Sink), lädt TestLevel Kapitel 1 (T1L9M001.wad) und macht Screenshots. Getestet am 2026-11-06 mit Wine 6.0.3, llvmpipe.

Befehle

lamatest.py run <wad> <outdir> [n]   # alles in einem: installieren, start, tolevel, tour, stop
lamatest.py start                    # Xvfb :5 + Null-Sink lama_stumm + groove.exe
lamatest.py tolevel                  # Menü -> Slot mit TestLevel -> Kapitel 1 -> Gameplay
lamatest.py tour <outdir> [n]        # n Kamera-Fotos (Rundumblick) + n Lauf-Fotos + Lama-Sicht
lamatest.py shot out.png             # Vollbild 1920x1080
lamatest.py key <xdotool-key> [s]    # Taste s Sekunden halten (Default 0.12)
lamatest.py keys Up:1.5 a:0.5 x      # Folge, Name[:Haltezeit], auch sleep=2
lamatest.py seq <outdir> "TOKENS"    # --seq-Tokens (shot:, run:, rj: …) im laufenden Spiel
lamatest.py status | stop | restore-wad

run-Optionen (2026-11-06 ergänzt)

lamatest.py run <wad> <outdir> [n] [--seq "TOKENS"] [--tour] [--keep]
  • WAD-Wiederherstellung: run merkt sich die vorher installierte T1L9M001.wad ($LAMATEST_DIR/vorher_T1L9M001.wad) und spielt sie nach dem Lauf zurück – also nicht .orig. Mit --keep bleibt die getestete WAD installiert. (restore-wad stellt weiterhin explizit .orig her.)

  • --seq ersetzt die Standard-Tour durch eine Tastenfolge (mit --tour zusätzlich Tour):

    • Up:1.5, a:0.5, x … Taste[:Haltezeit] wie bei keys; sleep=1
    • shot:NAME → seq_NN_NAME.jpg, fp:NAME → Foto in Lama-Sicht (Return gehalten)
    • dialog → Dialog/Letterbox wegklicken
    • Up+x:0.8 → Tasten gleichzeitig halten
    • rj:T1:T2 → Anlauf-Sprung (Up halten, nach T1 s X, Up noch T2 s)
    • dj:T → Doppel-X mit Anlauf, hop:N:T → Up halten, N× alle T s springen
    • run:T:x@1.3,x@2.9,shot@5.0,Left@3.0-3.4 → Up T s halten, nach Zeitplan (s ab Beginn) X tippen / fotografieren (seq_NN_runT.jpg) / Taste von–bis halten; run/Left:T:… hält statt Up eine andere Taste. Echtzeit: ein Foto blockiert ~0,4 s (verzögert folgende Ereignisse und bremst das Spiel) → keine Fotos kurz vor Sprüngen.
  • Steuerung ist kamerarelativ (Up = in Kamerablickrichtung, Left/Right seitlich). A/S drehen die Kamera, S:0.45 ≈ 90° nach links schauen.

  • Messwerte (Lama): ~1,1 Einheiten/s Laufen, Sprung 0,35 hoch, mit Anlauf ~1,3 weit – siehe levelbau.md. Zeitgesteuerte Läufe streuen um ~0,3 Einheiten (Startverzögerung, Bildrate); längere Strecken brauchen „Anschläge“ (Wand/Stufe, an der das Lama stehen bleibt).

  • Kamera: nach Laufen gegen eine Wand oder einem Sturz dreht sich die Kamera unvorhersehbar → Up läuft danach in eine andere Richtung. A/S-Drehung (S:0.45) ist nur ungefähr 90°.

  • Kompletter Testwelt-Parkour per Skript: levels/testwelt_parkour.seq (levelbau.md).

  • LAMATEST_SHOT=1280 (Umgebung): shot:/fp:-Fotos 1280×720, Qualität 85 statt 960×540 (Vorschaubilder).

  • „EINGEFROREN?“ bei einer --seq ohne Bewegung (z. B. nur sleep=3 shot:x) ist ein Fehlalarm – das stehende Lama ändert das Bild nicht; mit Kameradrehung/Laufen kommt „OK“.

  • Gute Blickwinkel im Spiel sind schwer: die Kamera hängt tief hinter dem Lama; erhöhte Startpunkte (Podest, Parkour-Checkpoint pk2 + A:0.6) zeigen mehrere Bereiche.

Hilfsskript für Serien: $CLAUDE_JOB_DIR/tmp/lb_run.sh WAD NAME "SEQ" (Montage lb_mNAME.jpg, WAD-Pfad absolut!), rs.sh NAME "SEQ" (Neustart mit installierter WAD + seq, Montage i/NAME.jpg). Achtung: kein pgrep -f groove.exe in Warteschleifen – das trifft die eigene Shell (Kommandozeile enthält "groove.exe") und lamatest hält sie für eine fremde Instanz.

Zustand/PIDs/wine.log: $LAMATEST_DIR (Default /tmp/lamatest-$USER).

run Exit-Codes: 0 OK, 3 Absturz, 4 Timeout/hängt, 5 Bild eingefroren. Ausgabe in <outdir>: report.txt, wine.log (stderr, auf 2 MB gekürzt), 00_geladen.png (voll) + .jpg, tour_*.jpg (960x540, ~30 KB), bei Fehler zz_absturz.jpg / zz_timeout.jpg. Ein Lauf ≈ 75 s, ≈ 1,2 MB.

Sicherheitsregeln (im Skript umgesetzt)

  • Bricht ab, wenn eine groove.exe mit anderem DISPLAY läuft (Elias' Instanz).
  • xdotool nur mit DISPLAY=:5.
  • Ton: eigener Null-Sink, App wird nie stummgeschaltet; stop entlädt den Sink.
  • Spielstände (*.ksv im Spielordner) werden bei start gesichert und bei stop bei Änderung zurückgespielt (neu entstandene gelöscht).
  • stop: wineserver -k nur, wenn keine fremde groove.exe läuft, sonst nur eigene PIDs.
  • Der Ausgang der Testwelt speichert Fortschritt (Kapitel 2 frei) – wird bei stop mit den Spielständen zurückgespielt.
  • WAD: erstes run sichert das Original als mods/testlevel/wads/T1L9M001.wad.orig; restore-wad spielt es zurück. Das Overlay (lama-mod an) besteht aus Symlinks auf die Mod-Dateien → Überschreiben von ~/.wine-lama/mods/testlevel/wads/T1L9M001.wad wirkt sofort; lama-mod an wird nur aufgerufen, wenn der Overlay-Link fehlt.

Ablauf tolevel (gemessen)

Schritt Taste Erkennung t (ab Start)
Logo → Hauptmenü – OCR Ausschnitt 700x300+1150+650, Schwelle 75 % → nur markierter Punkt "Spiel starten" lesbar ~6 s
Spiel starten Return –
Spielstandauswahl (Karussell, startet bei Slot 2, kein Wrap) Left ×3, dann Right bis "TestLevel" OCR Ausschnitt 1600x280+160+740 (fuzzy, 2 Schwellen) ~20 s
Slot 3 laden Return Auswahlkarte = >75 % beige Pixel ~25 s
Kapitel 1 aktivieren (Cursor aus KSV +4/+5) Return
Kamera-Flug (Letterbox: oberste+unterste Zeile schwarz) Return überspringt +1,5 s
Gameplay – hell, kein Letterbox, goldenes HUD oben links (oder >25 s) 3× hintereinander ~29 s gesamt, Laden ~4 s

Ohne Überspringen dauert der Kamera-Flug im Dorf ~20 s. Ladebild = T191.COR ("TestLevel Kapitel 1 … LADEVORGANG").

Fallback: wird kein Menü erkannt, nach 40 s Return (überspringt Demo). Achtung: Return auf einem falsch erkannten Bildschirm kann ein anderes Spiel starten – Spielstände werden aber am Ende zurückgespielt.

Steuerung PC (Tastatur, aus "Optionen → Tastatur konfigurieren", verifiziert)

Aktion Taste
Auf / Ab (vorwärts / rückwärts laufen) Up / Down
Links / Rechts (drehen) Left / Right
Sprung (auch Dialog weiter) X
Action Z
Power Space
Lama-Sicht (Ego-Perspektive, halten) Return
Kamera nach links / rechts drehen A / S (0,5 s halten ≈ 90°)
Pausenmenü Escape

Registry HKCU\Software\Disney Interactive\Emperors New Groove\1.0, "InputDevice Wine Keyboard" = 14 DIK-Codes (je 4 Hex): CB Left, CD Right, C8 Up, D0 Down, 1E A, 1F S, 39 Space, 2D X, 1C Return, 19 P, C9 PgUp, D1 PgDn, 2C Z, 18 O. Die Reihenfolge der Registry ≠ Menüreihenfolge; P/PgUp/PgDn/O vermutlich Pause/Inventar (laut exe-Strings: PAUSE GAME, CYCLE INVENTORY UP/DOWN, USE AN ITEM, TURN 180, SELECT) – nicht verifiziert. Weitere Werte dort: CameraMode, ControlType, ScreenW/H (1920x1142), CDPath=L:.

Pausenmenü (Escape): Grafik-/Tonoptionen, Tastatur/Joystick konfigurieren, Weitere Optionen, Weiter, "Beenden und zur Auswahlkarte wechseln" (Bestätigung Ja/Nein, Default Nein → Up, Return), Spiel beenden. Hauptmenü-Untermenüs: Escape = zurück.

Beobachtungen Dorf-1-Kopie

  • Läuft man im Dorf vorwärts, startet sofort der Pacha-Dialog (Letterbox mit Untertiteln, ~9× X zum Durchklicken). tour erkennt das, fotografiert den Dialog einmal und klickt ihn weg.
  • Lama kann in der Tour von der Klippe fallen (Respawn) – egal für Sichtprüfung.

Absturzerkennung

Pro Poll: groove.exe-Prozess auf :5 weg / Fenster "Groove" weg / Fenster mit "Programmfehler", "error", "exception" … (Wine-Crashdialog). Im Report steht die Zeile wine: Unhandled page fault … at address XXXXXXXX (Adresse in Ghidra nachschlagen). Getestet: auf 300 KB gekürzte WAD und WAD mit 2000 zufälligen Bytes → beide Absturz während des Ladebilds, erkannt nach ~5 s (Exit 3). Harmloses Log-Rauschen (gstreamer/MPEG-1 fehlt, ole, ChangeDisplaySettings, MIDIMAP) wird im Report ausgefiltert.

Abhängigkeiten

Xvfb, xdotool, ImageMagick (import/convert), tesseract mit deu, pactl, wine.