Everything so far lived in code comments and CLI help, which works while writing the thing and not at all when coming back to it after a month. Covers what the catalogue is, where its knowledge of the Aidem formats comes from (:core through a composite build, never a fork), how the data is shaped, and how to run it — pipeline, browsing, transcription, Docker, and moving the database between machines. Written against the actual state rather than memory: the command list is what the binary prints, the table list is what the schema holds, and the submodule URL is the one in .gitmodules. Volatile figures are left out, with a pointer to `rex-catalog stats` instead, so the file does not rot on the next ingest. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
7.2 KiB
rex-catalog
Katalog kolekcji gier Aidem Media — serii Reksio i Poznaj Mity. Indeksuje obrazy płyt, zagląda do środka i pozwala je przeglądać: odszyfrowane skrypty, odtwarzalne kwestie mówione, podgląd grafiki i animacji oraz powiązania między nimi.
Powstał do celów archiwizacyjnych i testów emulatora. Niczego nie modyfikuje w kolekcji —
obrazy płyt otwiera wyłącznie do odczytu, a wszystko, co wytworzy, ląduje w osobnym
katalogu data/.
Skąd bierze wiedzę o formatach
Formaty Aidem — zaszyfrowane skrypty CNV, obrazy PIK\0, animacje NVP\0, kompresje
CLZW i CRLE — czyta przez :core z Rex-EMoolatora,
podpiętego jako composite build, a nie fork. Emulator jest przypięty submodułem na
konkretnym tagu (gradle.properties → coreVersion), a zadanie verifyCoreVersion
pilnuje, żeby tag i submoduł się nie rozjechały.
Dzięki temu wiedza o formatach ma jedno źródło. Tam, gdzie katalog musiał napisać własny
parser, jest to powiedziane wprost w komentarzu razem z powodem — najczęściej dlatego,
że loader z :core buduje tekstury OpenGL-a i w procesie bez okna nie da się go użyć.
Jak to jest poukładane
Trzy poziomy tożsamości. title (dzieło) → edition (wydanie) → copy (konkretny
plik na dysku). Między wydaniem a kopią stoi jeszcze game_root, bo jedna płyta bywa
dwupackiem z dwiema grami, każdą z własnym silnikiem.
Plik osobno, treść osobno. file mówi, gdzie coś leży, blob — czym jest. Porównanie
dwóch wydań jest więc operacją na zbiorach odcisków, a wszystko, co wytworzone
(odszyfrowany skrypt, miniatura), kluczuje się treścią: ten sam plik na trzech płytach
przerabiamy raz.
Fakty z dowodem. Detektory nie nadpisują pól, tylko dopisują wiersze do detection
z wartością, pewnością i dowodem. Poprawki człowieka siedzą osobno, w polach *_override,
i nigdy nie są nadpisywane przez kolejny przebieg.
Nic nie wypakowujemy. Dźwięk i klatki animacji czytamy z obrazu płyty na żądanie,
sięgając od razu na właściwą pozycję. W data/ zostaje tylko to, co drogo policzyć:
odszyfrowane skrypty i miniatury.
Uruchomienie
Potrzebne: JDK 21 i submoduł z emulatorem.
git submodule update --init --recursive
./gradlew installDist
Dalej wygodnie przez launcher (build/install/rex-catalog/bin/rex-catalog) albo
./gradlew run --args="...". Katalog bazy wskazuje -Dcatalog.data (domyślnie ./data).
Potok
rex-catalog ingest /ścieżka/do/kolekcji # indeksuje obrazy, katalogi gier i całe kolekcje
rex-catalog decode # odszyfrowuje skrypty do cache'u i indeksu FTS5
rex-catalog probe # dźwięk, grafika, dialogi, powiązania
rex-catalog analyze # metadane z application.def i install.ini
rex-catalog promote # tworzy tytuły i wydania z wykrytych faktów
Każdy krok jest przyrostowy — dołożenie nowej płyty przerabia tylko ją. Ponowne
uruchomienie bez --force nie robi nic, jeśli nic się nie zmieniło.
ingest przyjmuje obraz .iso (ISO 9660, Joliet i UDF), archiwum .zip, katalog
rozpakowanej gry albo katalog z całą kolekcją.
Przeglądanie
rex-catalog serve # front i MCP na http://127.0.0.1:8765
rex-catalog find CANVAS_OBSERVER # przeszukanie skryptów (składnia FTS5)
rex-catalog cat arcade.cnv # odszyfrowany skrypt na wyjście
rex-catalog titles # lista wydań z metadanymi
Front ma cztery widoki: Katalog (tytuły, wydania, kopie, pliki), Skrypty (wyszukiwanie pełnotekstowe i podgląd z listą użytych zasobów), Dźwięk (wyszukiwanie nagrań, odtwarzacz, transkrypcja) i Formaty (rozkład zawartości kolekcji).
Pod /mcp stoi serwer MCP (Streamable HTTP, tylko do odczytu) z dziewięcioma narzędziami —
od list_titles i search_scripts po get_script_assets, które pokazuje, co dany skrypt
odtwarza, kto to mówi i jak długo trwa.
Metadane ręczne
Tego, czego nie da się wykryć, nie zgadujemy:
rex-catalog set copy "Wojna Troj" source_kind=wlasny_zgraj rip_tool=dd
rex-catalog set edition 3 distributor="Aidem Media" release_date_override=2003-11-18
rex-catalog lang add 3 cs audio
Transkrypcja mowy
Opcjonalna i uruchamiana świadomie — wymaga whisper.cpp i modelu, których repozytorium nie dostarcza.
brew install whisper-cpp # albo dowolna inna instalacja
rex-catalog transcribe --limit 100 # -Dcatalog.whisper.model=ścieżka/do/ggml-medium.bin
Da się też wyklikać z zakładki Dźwięk — z paskiem postępu i zatrzymaniem, które nie gubi tego, co już policzone.
Kwestie są sklejane po kilka w trzydziestosekundowe okna z sekundą ciszy między nimi, a wynik rozcinany z powrotem po znacznikach czasu. Whisper koduje zawsze pełne okno, więc podawanie mu czterosekundowych kwestii po jednej marnuje większość pracy.
Transkrypt jest wygenerowany, nie odczytany z płyty. Siedzi w osobnej tabeli razem z nazwą modelu i narzędzia, a interfejs oznacza go jako maszynowy. Zdania, które model dopisuje z siebie na ciszy — podpisy ekip od napisów — są odsiewane.
Docker
COLLECTION=/ścieżka/do/kolekcji docker compose up -d
docker compose exec katalog /app/entrypoint.sh ingest /media
Kolekcja montuje się tylko do odczytu, baza i cache lądują w wolumenie. Obraz niesie
whisper.cpp i ffmpeg, ale nie model — ten podmontuj pod /models i wskaż zmienną
WHISPER_MODEL.
Dockerfile.cuda buduje wariant z akceleracją NVIDII (domyślnie pod compute capability
8.6, czyli GeForce RTX 30). Na macOS akceleracja w kontenerze nie działa — tam transkrypcję
uruchamiaj na hoście, gdzie whisper.cpp sam korzysta z Metala.
Przenoszenie między maszynami
Baza zapisuje bezwzględne ścieżki do obrazów płyt, bo czyta z nich dźwięk i grafikę.
Po skopiowaniu data/ na inną maszynę trzeba ją przypiąć do kolekcji:
rex-catalog relocate D:\Reksio --dry-run # najpierw pokaż, co zrobisz
rex-catalog relocate D:\Reksio
Dopasowuje po nazwie i sprawdza rozmiar (--verify dokłada SHA-256), a nazwy porównuje po
normalizacji Unicode — bez tego kolekcja z macOS nie dogaduje się z tą samą kolekcją na
Windowsie, bo ń jest tam zapisane inaczej.
Co siedzi w bazie
SQLite, jeden plik obok cache'u, więc przeniesienie katalogu to skopiowanie data/.
| tabela | co trzyma |
|---|---|
title, edition, copy, game_root |
tożsamość: dzieło, wydanie, nośnik, korzeń gry |
file, blob |
gdzie plik leży i czym jest |
detection |
fakty detektorów z dowodem i pewnością |
artifact |
wytworzone: odszyfrowane skrypty, miniatury |
media |
fakty o zasobie: długość, wymiary, klatki, kodek |
archive_entry |
zawartość archiwów .snd — kwestie spakowane w jeden plik |
script_ref |
odwołania skryptów do zasobów |
dialogue_line, anim_event |
mówca i zdarzenie kwestii, nazwane sekwencje animacji |
transcript |
rozpoznana mowa, osobno od reszty |
script_fts, transcript_fts |
indeksy pełnotekstowe |
rex-catalog stats pokazuje, co w danej chwili jest w środku.