- Add app/games: GameProfile base, registry, ReaderHooks and renpy/naninovel/ tomie profiles. pipeline, preflight, detect and mods dispatch via the registry - Move tomie_* converter modules to app/games/tomie and split out reader hooks, import, mod validation and known defects - Tolerate the 31 authoring defects of the pinned Tomie build as report warnings (exact list, per-script counts); any new defect still blocks import - Frontend: runtime registry (runtimes.ts) with lazy Tomie launcher - Add profile/registry tests and docs/GAME_PROFILES.md; update IMPORT.md Full media export of the original Tomie build is not yet verified. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
60 lines
4.6 KiB
Markdown
60 lines
4.6 KiB
Markdown
# Профили игр
|
|
|
|
Общий конвейер (загрузка, очередь, хранилище блобов, моды, оболочка плеера) не знает
|
|
подробностей конкретных игр. Всё, что относится к движку или к одной сборке игры,
|
|
живёт в профиле — модуле в `backend/app/games/`.
|
|
|
|
## Что такое профиль
|
|
|
|
Класс `GameProfile` (`app/games/base.py`):
|
|
|
|
| Член | Назначение |
|
|
| --- | --- |
|
|
| `id` | Стабильный идентификатор в отчётах, например `tomie/expansion-1.3801` |
|
|
| `engine` | Семейство движка из `compatibility.detect` (`renpy`, `naninovel`, …) |
|
|
| `specific` | `True` для профиля, привязанного к одной сборке: он выбирается раньше общего профиля движка |
|
|
| `runtime` | Значение `game.runtime`, если игре нужен отдельный плеер |
|
|
| `claims(root)` | Дешёвая проверка, что профиль подходит (например, SHA-256 сборки) |
|
|
| `inspect(root, work)` | Проверка совместимости без записи блобов; при отказе — `CompatibilityError` |
|
|
| `convert(root, work, progress)` | Полный импорт в PGVN |
|
|
| `validate_mod(game, scripts, manifest)` | Дополнительные проверки изменённого мода |
|
|
| `unity_hooks()` | Расширение общего читателя Unity/Naninovel (`app/games/hooks.py`) |
|
|
|
|
`app/games/registry.py` выбирает профиль: `select(engine, root)` — сначала
|
|
`specific`-профили, затем общий профиль движка; `for_runtime(runtime)` — для
|
|
валидации модов. Остальной код обращается только к реестру: `pipeline`,
|
|
`preflight`, `compatibility.detect`, `mods`.
|
|
|
|
## Как добавить игру со своим конвейером
|
|
|
|
1. Создайте `backend/app/games/<имя>/` с классом профиля. Задайте `engine`,
|
|
`specific = True`, `claims()` (хэш сборки, а не имя папки) и `inspect`/`convert`.
|
|
2. Особенности чтения Unity-данных вынесите в наследника `ReaderHooks`
|
|
(`begin`, `accept_duplicate_script`, `scan_object`) и передайте его в
|
|
`read_package(..., hooks=...)`.
|
|
3. Зарегистрируйте профиль в `app/games/__init__.py`.
|
|
4. Если игре нужен свой плеер, добавьте `runtime` и запись в
|
|
`frontend/src/player/runtimes.ts` (загрузчик подгружается лениво).
|
|
5. Проверки: профиль закрывается по принципу «закрыто по умолчанию» — неизвестное
|
|
отклоняется. Добавьте тесты по образцу `tests/test_tomie_*.py` и
|
|
`tests/test_game_profiles.py`.
|
|
|
|
## Профили сейчас
|
|
|
|
* `renpy` — `app/games/renpy.py`; конвертация остаётся в `converter/pipeline.py`,
|
|
потому что объединяет распаковку архива, RPA и медиа.
|
|
* `naninovel` — общий импорт Naninovel (`converter/naninovel.py`).
|
|
* `tomie/expansion-1.3801` — `app/games/tomie/`: хэш сборки (`profile.py`),
|
|
формат и нативный интерпретатор команд (`format.py`, `validation.py`), медиа
|
|
(`assets.py`), хуки читателя (`reader.py`), известные дефекты оригинала
|
|
(`defects.py`), проверка модов (`mod.py`), импорт (`convert.py`).
|
|
|
|
## Известные дефекты оригинала
|
|
|
|
Профиль может перечислить ошибки самой игры (переход на несуществующую метку,
|
|
ветка без `EndIf`), которые оригинал тоже не обрабатывает. Они не блокируют
|
|
импорт, а попадают в отчёт как предупреждения; плеер на таком месте останавливается
|
|
с явной ошибкой. Список точный: ключ — (код, сообщение, сценарий), значение —
|
|
максимальное число. Новые или лишние случаи, в том числе в моде, по-прежнему
|
|
отклоняются. Добавлять записи ради прохождения импорта нельзя.
|