translated the remaining german notes, python comments, help and messages to english (in-game strings, parsed report lines and cli values stay german)
This commit is contained in:
1 parent
86fe26d786
commit
526f6072f6
36 files changed
+1553
-1544
No files matched your search
+110
-110
@@ -1,146 +1,146 @@
|
||||
# Test-Harness `tools/lamatest.py`
|
||||
# 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.
|
||||
Starts "Ein Königreich für ein Lama" unattended and invisibly (Xvfb :5,
|
||||
sound into a null sink), loads TestLevel chapter 1 (T1L9M001.wad) and takes screenshots.
|
||||
Tested on 2026-11-06 with Wine 6.0.3, llvmpipe.
|
||||
|
||||
## Befehle
|
||||
## Commands
|
||||
|
||||
```
|
||||
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 run <wad> <outdir> [n] # all in one: install, start, tolevel, tour, stop
|
||||
lamatest.py start # Xvfb :5 + null sink lama_stumm + groove.exe
|
||||
lamatest.py tolevel # menu -> slot with TestLevel -> chapter 1 -> gameplay
|
||||
lamatest.py tour <outdir> [n] # n camera shots (look around) + n walking shots + llama view
|
||||
lamatest.py shot out.png # full screen 1920x1080
|
||||
lamatest.py key <xdotool-key> [s] # hold key for s seconds (default 0.12)
|
||||
lamatest.py keys Up:1.5 a:0.5 x # sequence, name[:hold time], also sleep=2
|
||||
lamatest.py seq <outdir> "TOKENS" # --seq tokens (shot:, run:, rj: …) in the running game
|
||||
lamatest.py status | stop | restore-wad
|
||||
```
|
||||
|
||||
### `run`-Optionen (2026-11-06 ergänzt)
|
||||
### `run` options (added 2026-11-06)
|
||||
```
|
||||
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).
|
||||
* **WAD restore**: `run` remembers the *previously installed*
|
||||
`T1L9M001.wad` (`$LAMATEST_DIR/vorher_T1L9M001.wad`) and restores it after the run –
|
||||
i.e. not `.orig`. With `--keep` the tested WAD stays installed.
|
||||
(`restore-wad` still explicitly restores `.orig`.)
|
||||
* `--seq` replaces the default tour with a key sequence (with `--tour` the tour runs as well):
|
||||
* `Up:1.5`, `a:0.5`, `x` … key[:hold time] as with `keys`; `sleep=1`
|
||||
* `shot:NAME` → `seq_NN_NAME.jpg`, `fp:NAME` → shot in llama view (Return held)
|
||||
* `dialog` → click away dialog/letterbox
|
||||
* `Up+x:0.8` → hold keys simultaneously
|
||||
* `rj:T1:T2` → running jump (hold Up, X after T1 s, Up for another T2 s)
|
||||
* `dj:T` → double X with run-up, `hop:N:T` → hold Up, jump N× every T s
|
||||
* `run:T:x@1.3,x@2.9,shot@5.0,Left@3.0-3.4` → hold Up for T s, following a schedule (s from start)
|
||||
tap X / take a shot (`seq_NN_runT.jpg`) / hold a key from–to; `run/Left:T:…` holds
|
||||
another key instead of Up. Real time: a shot blocks ~0.4 s (delays subsequent events
|
||||
and slows the game down) → no shots shortly before jumps.
|
||||
* Controls are **camera-relative** (Up = in the camera's view direction, Left/Right sideways).
|
||||
A/S rotate the camera, S:0.45 ≈ look 90° to the left.
|
||||
* Measurements (llama): ~1.1 units/s walking, jump 0.35 high, ~1.3 far with run-up – see
|
||||
levelbau.md. Timed runs scatter by ~0.3 units (start delay, frame rate);
|
||||
longer distances need "stops" (a wall/step where the llama comes to a halt).
|
||||
* Camera: after running into a wall or a fall the camera rotates unpredictably →
|
||||
Up then walks in a different direction. A/S rotation (S:0.45) is only roughly 90°.
|
||||
* Complete test world parkour as a script: `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.
|
||||
* `LAMATEST_SHOT=1280` (environment): `shot:`/`fp:` shots at 1280×720, quality 85 instead of 960×540 (preview images).
|
||||
* "EINGEFROREN?" (frozen?) for a `--seq` without movement (e.g. only `sleep=3 shot:x`) is a false alarm –
|
||||
the standing llama does not change the image; with camera rotation/walking you get "OK".
|
||||
* Good viewing angles in the game are hard: the camera hangs low behind the llama; elevated
|
||||
start points (pedestal, parkour checkpoint `pk2` + `A:0.6`) show several areas.
|
||||
|
||||
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.
|
||||
Helper script for series: `$CLAUDE_JOB_DIR/tmp/lb_run.sh WAD NAME "SEQ"` (montage `lb_mNAME.jpg`,
|
||||
WAD path absolute!), `rs.sh NAME "SEQ"` (restart with installed WAD + `seq`, montage `i/NAME.jpg`).
|
||||
**Caution**: no `pgrep -f groove.exe` in wait loops – it matches your own shell
|
||||
(the command line contains "groove.exe") and lamatest takes it for a foreign instance.
|
||||
|
||||
Zustand/PIDs/wine.log: `$LAMATEST_DIR` (Default `/tmp/lamatest-$USER`).
|
||||
State/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.
|
||||
`run` exit codes: 0 OK, 3 crash, 4 timeout/hang, 5 image frozen.
|
||||
Output in `<outdir>`: `report.txt`, `wine.log` (stderr, truncated to 2 MB),
|
||||
`00_geladen.png` (full) + `.jpg`, `tour_*.jpg` (960x540, ~30 KB), on failure
|
||||
`zz_absturz.jpg` / `zz_timeout.jpg`. One run ≈ 75 s, ≈ 1.2 MB.
|
||||
|
||||
## Sicherheitsregeln (im Skript umgesetzt)
|
||||
## Safety rules (implemented in the script)
|
||||
|
||||
- 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.
|
||||
- Aborts if a groove.exe with a different DISPLAY is running (Elias' instance).
|
||||
- xdotool only with DISPLAY=:5.
|
||||
- Sound: own null sink, the app is never muted; `stop` unloads the sink.
|
||||
- Save games (`*.ksv` in the game folder) are backed up on `start` and restored
|
||||
on `stop` if changed (newly created ones are deleted).
|
||||
- `stop`: `wineserver -k` only if no foreign groove.exe is running, otherwise only own PIDs.
|
||||
- The test world exit saves progress (chapter 2 unlocked) – restored on `stop` together with the
|
||||
save games.
|
||||
- WAD: the first `run` backs up the original as `mods/testlevel/wads/T1L9M001.wad.orig`;
|
||||
`restore-wad` restores it. The overlay (`lama-mod an`) consists of
|
||||
**symlinks** to the mod files → overwriting
|
||||
`~/.wine-lama/mods/testlevel/wads/T1L9M001.wad` takes effect immediately; `lama-mod an` is
|
||||
only called if the overlay link is missing.
|
||||
|
||||
## Ablauf `tolevel` (gemessen)
|
||||
## `tolevel` sequence (measured)
|
||||
|
||||
| Schritt | Taste | Erkennung | t (ab Start) |
|
||||
| Step | Key | Detection | t (from 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 |
|
||||
| Logo → main menu | – | OCR crop 700x300+1150+650, threshold 75 % → only the highlighted item "Spiel starten" is readable | ~6 s |
|
||||
| "Spiel starten" (start game) | Return | – | |
|
||||
| Save slot selection (carousel, starts at slot 2, **no** wrap) | Left ×3, then Right until "TestLevel" | OCR crop 1600x280+160+740 (fuzzy, 2 thresholds) | ~20 s |
|
||||
| Load slot 3 | Return | selection map = >75 % beige pixels | ~25 s |
|
||||
| Activate chapter 1 (cursor from KSV +4/+5) | Return | | |
|
||||
| Camera fly-through (letterbox: top+bottom row black) | Return skips | | +1.5 s |
|
||||
| Gameplay | – | bright, no letterbox, golden HUD top left (or >25 s) 3× in a row | ~29 s total, loading ~4 s |
|
||||
|
||||
Ohne Überspringen dauert der Kamera-Flug im Dorf ~20 s.
|
||||
Ladebild = T191.COR ("TestLevel Kapitel 1 … LADEVORGANG").
|
||||
Without skipping, the camera fly-through in the village takes ~20 s.
|
||||
Loading screen = 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.
|
||||
Fallback: if no menu is detected, Return after 40 s (skips the demo). Caution:
|
||||
Return on a misdetected screen can start a different game –
|
||||
but save games are restored at the end.
|
||||
|
||||
## Steuerung PC (Tastatur, aus "Optionen → Tastatur konfigurieren", verifiziert)
|
||||
## PC controls (keyboard, from "Optionen → Tastatur konfigurieren", verified)
|
||||
|
||||
| Aktion | Taste |
|
||||
| Action | Key |
|
||||
|---|---|
|
||||
| Auf / Ab (vorwärts / rückwärts laufen) | Up / Down |
|
||||
| Links / Rechts (drehen) | Left / Right |
|
||||
| Sprung (auch Dialog weiter) | X |
|
||||
| Up / Down (walk forward / backward) | Up / Down |
|
||||
| Left / Right (turn) | Left / Right |
|
||||
| Jump (also advances dialog) | 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 |
|
||||
| Llama view (first person, hold) | Return |
|
||||
| Rotate camera left / right | A / S (hold 0.5 s ≈ 90°) |
|
||||
| Pause menu | Escape |
|
||||
|
||||
Registry `HKCU\Software\Disney Interactive\Emperors New Groove\1.0`,
|
||||
`"InputDevice Wine Keyboard"` = 14 DIK-Codes (je 4 Hex):
|
||||
`"InputDevice Wine Keyboard"` = 14 DIK codes (4 hex digits each):
|
||||
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:\.
|
||||
19 P, C9 PgUp, D1 PgDn, 2C Z, 18 O. The registry order ≠ menu order;
|
||||
P/PgUp/PgDn/O probably pause/inventory (according to exe strings: PAUSE GAME, CYCLE
|
||||
INVENTORY UP/DOWN, USE AN ITEM, TURN 180, SELECT) – not verified.
|
||||
Other values there: 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.
|
||||
Pause menu (Escape): graphics/sound options, configure keyboard/joystick,
|
||||
more options, continue, "Beenden und zur Auswahlkarte wechseln" (quit to selection map; confirmation
|
||||
Ja/Nein, default Nein → Up, Return), quit game. Main menu submenus: Escape = back.
|
||||
|
||||
## Beobachtungen Dorf-1-Kopie
|
||||
## Observations on the village 1 copy
|
||||
|
||||
- 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.
|
||||
- Walking forward in the village immediately starts the Pacha dialog (letterbox with
|
||||
subtitles, ~9× X to click through). `tour` detects this, photographs the
|
||||
dialog once and clicks it away.
|
||||
- The llama can fall off the cliff during the tour (respawn) – irrelevant for visual checks.
|
||||
|
||||
## Absturzerkennung
|
||||
## Crash detection
|
||||
|
||||
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.
|
||||
Per poll: groove.exe process on :5 gone / window "Groove" gone / window with
|
||||
"Programmfehler", "error", "exception" … (Wine crash dialog). The report contains the
|
||||
line `wine: Unhandled page fault … at address XXXXXXXX` (look up the address in Ghidra).
|
||||
Tested: WAD truncated to 300 KB and WAD with 2000 random
|
||||
bytes → both crash during the loading screen, detected after ~5 s (exit 3).
|
||||
Harmless log noise (gstreamer/MPEG-1 missing, ole, ChangeDisplaySettings,
|
||||
MIDIMAP) is filtered out of the report.
|
||||
|
||||
## Abhängigkeiten
|
||||
## Dependencies
|
||||
|
||||
Xvfb, xdotool, ImageMagick (import/convert), tesseract mit `deu`, pactl, wine.
|
||||
Xvfb, xdotool, ImageMagick (import/convert), tesseract with `deu`, pactl, wine.
|
||||
Reference in new issue
Block a user