Add a README
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>
This commit is contained in:
co-authored by
Claude Opus 5
parent
20ce26364c
commit
c2036e1f72
@@ -0,0 +1,164 @@
|
||||
# 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](https://github.com/patryk025/Rex-EMoolator),
|
||||
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.
|
||||
|
||||
```bash
|
||||
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
|
||||
|
||||
```bash
|
||||
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
|
||||
|
||||
```bash
|
||||
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:
|
||||
|
||||
```bash
|
||||
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](https://github.com/ggerganov/whisper.cpp)
|
||||
i modelu, których repozytorium nie dostarcza.
|
||||
|
||||
```bash
|
||||
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
|
||||
|
||||
```bash
|
||||
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:
|
||||
|
||||
```bash
|
||||
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.
|
||||
Reference in New Issue
Block a user