Files
pgames-manager/docs/IMPORT.md
T
mrleo1nid f9eb5c1212
CI / frontend (push) Failing after 15s
CI / backend (push) Failing after 37s
feat: improve RenPy conversion and support MIST runtime
2026-10-25 23:16:33 +03:00

18 KiB
Raw Blame History

Автоматический импорт и проверка совместимости

PGames исполняет восстановленные сценарии в браузере. Наличие ресурсов игры или распознанного движка само по себе не означает, что игра совместима.

Порядок обработки

После получения архива API читает список файлов. Неизвестный движок, неподдерживаемые Unity, Godot, GameMaker и RPG Maker отклоняются до очереди конвертации. EXE-файлы не запускаются и не принимаются вместо архива игры.

Воркер проверяет сценарии перед конвертацией медиа. Для архивов Ren'Py сначала извлекаются только сценарии и RPA; отдельно лежащие изображения, аудио и видео на этом этапе не распаковываются. RPA со сценариями необходимо прочитать из внешнего архива, но из самого RPA для проверки извлекаются только скрипты. Для уже распакованных игр проверка выполняется до копирования медиа.

Определения неподдерживаемых функций и классов, вызовы отсутствующих функций, переходы к отсутствующим меткам, выполняемые screen-команды, динамические ATL и ошибки декомпиляции останавливают импорт. Объявление неиспользуемого screen само по себе не является выполнением экрана. Кодировки сценариев читаются по объявлению coding: либо как UTF-8; повреждённые символы не заменяются молча.

Ошибка имеет engine, compatible: false и список issues с кодом, причиной, местом и количеством обнаруженных случаев. В интерфейсе версии доступны все причины остановки. Неподдерживаемая игра не получает статус ready.

Проверка сценариев не является доказательством прохождения всех веток игры. Она обнаруживает известные неподдерживаемые конструкции и явные ошибки. Ошибка обработки медиа также останавливает конвертацию. Промежуточные блобы не опубликованы в манифесте; их впоследствии удаляет сборщик мусора.

Коллекция на диске

Команды выполняются из каталога backend в окружении с зависимостями проекта, FFmpeg, 7-Zip и настроенным UNRPYC_PATH.

python -m app.import_library "D:\Torrents\Pgames" --check --output report.json
python -m app.import_library "D:\Torrents\Pgames" --import --owner admin --output report.json

Для одной игры укажите --single: путь должен вести к её папке или архиву. Проверяются сценарии и совместимость тем же способом, что при импорте:

python -m app.import_library "D:\Torrents\Pgames\Renpy\DesertStalker-0.21.4-pc" --single --check --output desert-stalker.json
python -m app.import_library "D:\Games\SomeGame.zip" --single --check --output game.json

Для подробного разбора Ren'Py и сохранения извлечённых/декомпилированных сценариев доступна диагностическая команда (без конвертации медиа):

python -m app.converter.analyze --dump ..\data-test\renpy-dump "D:\Torrents\Pgames\Renpy\DesertStalker-0.21.4-pc"

Приоритет — общая поддержка синтаксиса и поведения Ren'Py в конвертере и плеере. Патчи отдельных сборок находятся в app/games/renpy_builds.py; замены блоков дополнительно проверяют SHA-256 исходного текста. Неизвестные изменения проходят обычную строгую проверку. В DesertStalker 0.21.4 блок восстановления нативных сохранений заменяется вызовом загрузчика PGames; сохранения Ren'Py в формате pickle не переносятся.

Начальный код оригинальной игры можно дополнительно проверить в браузерном интерпретаторе без конвертации медиа. После создания дампа выполните из backend:

python -m tests.export_renpy_runtime "D:\Torrents\Pgames\Renpy\DesertStalker-0.21.4-pc" "..\data-test\renpy-dump\DesertStalker-0.21.4-pc" "..\data-test\desert-runtime.json"

Затем из frontend:

$env:PGAMES_RENPY_RUNTIME = "D:\Github\pgames-manager\data-test\desert-runtime.json"
node --test tests/renpy-original.test.mjs

Это проверка init/default и сохранности загрузчика PGames; прохождение сюжета, визуальные эффекты и все ветки она не подтверждает. Оригинальные сценарии и дампы не включаются в репозиторий.

--check не создаёт карточек или версий и не изменяет исходные игры. --import создаёт версии только для прошедших проверку игр. Обработка коллекции продолжается после отказа отдельной игры. При наличии хотя бы одного отказа команда завершается с кодом 2. Полный JSON-отчёт обновляется после каждой игры. Для одноимённых папки и архива проверяется распакованная папка. Повторный запуск --import создаёт новые карточки: это не синхронизатор каталога.

Нужно подключить каталог коллекции к контейнеру для использования команды на сервере. Путь клиента Windows автоматически не становится доступен серверу. Входные каталоги используются только для чтения; временная распаковка и декомпиляция происходят отдельно.

MIST 1.0.3 и общая поддержка Ren'Py

Оригинальная сборка MIST 1.0.3 проходит проверку сценариев и полную конвертацию: 3527 изображений, 355 аудиофайлов, 778 видео и 5 шрифтов. Общий плеер поддерживает циклы ui.interact() с результатами Return от уже показанных экранов, renpy.movie_cutscene с ожиданием/пропуском, регистрацию изображений через renpy.image/ImageReference, пользовательские микшеры и базовую Gallery. У видео Movie сохраняются маски прозрачности и режим повтора; красный канал маски задаёт прозрачность кадра. Эти возможности применяются ко всем играм.

На исходных сценариях MIST проверены начальный код, победа/поражение QTE, мини-игра поднятия руки и продолжение её цикла после загрузки сохранения. Тесты frontend/tests/mist-runtime.test.mjs включаются переменной PGAMES_MIST_RUNTIME, указывающей на JSON из tests.export_renpy_runtime. PGAMES_MIST_ORIGINAL включает backend-проверку оригинального дистрибутива. Полное прохождение сюжета и визуальная проверка каждой сцены не подтверждены.

В оригинальном scripts.rpa есть четыре перехода на отсутствующие метки (robinspent, breakfastdialog, firstdungeontalk, afterrscene09) и показ отсутствующего newbuildingcontrolscreen. Профиль renpy/mist-1.0.3 распознаёт сборку дополнительно по SHA-256 сценарного архива и допускает только эти пять дефектов с исходным количеством вхождений. Они остаются предупреждениями; при достижении такого места плеер останавливается с явной ошибкой. Замены сюжетных переходов не подставляются. Изменённые сценарии проверяются заново.

В отчёте также перечислены 22 ссылки на отсутствующие медиа оригинала, включая старые объявления анимаций, иконку Roastedfish_Kachel.png и два side-изображения. Они не подменяются другими картинками; это ограничение самого дистрибутива, которое нужно учитывать при проверке конкретных веток.

Текущая поддержка Naninovel

Добавлен импорт скомпилированных сценариев из Unity-ресурсов Mono-сборок Naninovel. Код игры не запускается. Для поддерживаемого старого формата managed references схемы берутся из сохранённых метаданных или DLL игры, результат чтения проверяется побайтным циклом записи. Неизвестная схема или различающиеся копии сценария приводят к отказу.

Поддерживается ограниченное подмножество: реплики и продолжения реплик, переменные, безопасно разобранные выражения, if/else, статические переходы и подпрограммы, выборы с GotoPath, паузы, показ и скрытие текста, статические изображения/персонажи, базовые аудиокоманды и выход в меню. Все параметры команды проверяются; неизвестные параметры также вызывают отказ. Изображения и аудио разрешаются по однозначному имени ресурса. Для иных схем ресурсов, внешних интерфейсов и игровых расширений нужен дополнительный адаптер.

Служебные выражения не исполняются как Python или JavaScript: сервер разбирает их в AST, а браузер вычисляет разрешённые операции. Текст переводится до подстановки переменных. Переменные и накопленные варианты выбора входят в состояние сохранения общего плеера.

Извлекаются адресуемые текстовые записи из DefaultUI, Tips, CharacterNames, Inventory, файлов StreamingAssets/text и соответствующих встроенных TextAsset. Части подсказок и синонимы имеют отдельные записи. Ключи и разделители остаются в метаданных. Редактор переводов использует устойчивые ID записей; изменение выражений, тегов и служебных разделителей отклоняется при сохранении перевода. Имена персонажей используют словарь CharacterNames при его наличии.

Tomie

Добавлен отдельный адаптер tomie/1 для Expansion 1.3801. Он выбирается по SHA-256 оригинальной Assembly-CSharp.dll; переименованная или новая сборка не получает этот профиль автоматически. Таблицы имён, комментариев и видео читаются из констант IL без запуска DLL. Исходные переменные восстанавливаются из CustomVariablesConfiguration, образы — по ключам Unity ResourceManager. Дубли Texture2D/Sprite под одним ключом разрешаются в пользу полной текстуры.

Плеер использует исходный список команд Naninovel. Проверены создание персонажа до поля на извлечённых Unity-сценариях и цепочки дня/ночи на данных Godot-порта. Перенесены игровые функции, динамические обработчики выбора, поле и кубики, инвентарь, сообщения, сцена, видео, эффекты и мини-игра. Сохранение включает стек подпрограмм, очередь команд, варианты выбора, инвентарь, генератор случайных чисел, состояние сцены и мини-игры. Ветвления соответствуют реализации в DLL: BeginIf/Else ищут следующую ветку в списке команд, EndIf — пустая команда.

Исходные команды хранятся в редактируемых модулях PGVN; видимый текст индексируется общим редактором переводов. При запуске VM собирается заново из модулей, поэтому редактирование текста мода не оставляет устаревшую копию сценария в плеере. Адреса меток привязаны к ID команд: вставка команд не смещает переходы; удаление команды, на которую указывает метка, требует исправления адреса. Неизвестные команды, параметры, эффекты и интерфейсы останавливают импорт. Предпросмотр Tomie с отдельной строки пока явно отклоняется; запуск с начала поддерживается.

Оригинальная папка Tomie проходит строгую проверку. В скриптах остаются 31 дефект самой игры: 22 перехода на отсутствующие метки (например, B_Rest.Start и AB_Studio.SkillUp), 6 условных блоков без EndIf и 3 некорректных присваивания в вариантах выбора. Они перечислены в app/games/tomie/defects.py, показываются в отчёте версии как предупреждения, а плеер останавливается с явной ошибкой, если игра доходит до такого места. Любой новый дефект по-прежнему останавливает импорт. Автоматическая подмена сюжета не выполняется. Полное прохождение игры и экспорт всего медиакаталога через конвертер ещё не подтверждены.

Устройство профилей и добавление новых игр описаны в GAME_PROFILES.md.

Проверка браузерного интерфейса находится в frontend/tests/tomie-browser.test.mjs. Она использует уже установленный Playwright через PGAMES_PLAYWRIGHT_PATH; при необходимости путь к Chromium задаётся PGAMES_CHROMIUM_EXECUTABLE. Тесты оригинальных данных включаются переменными PGAMES_TOMIE_ORIGINAL (папка дистрибутива), PGAMES_TOMIE_PORT (папка Godot-порта), PGAMES_TOMIE_FIXTURE (его story/opening.json) и PGAMES_TOMIE_RUNTIME (восстановленный runtime_data в JSON). Эти файлы не включаются в репозиторий.

Каталоги .local-translator, migration-staging и migration-tools не считаются отдельными играми. Импорт читает текущие ресурсы дистрибутива: установленный переводческий патч автоматически не откатывается, резервные копии не подставляются вместо исходников без отдельной обработки профиля.