Checked against six real games (Ren'Py 7.5 and 8.x): - nested labels and named menus become jump anchors inside label bodies - call with arguments and labels with parameters (dynamically scoped) - frame-by-frame ATL images, Movie frames, layeredimage, camera, Shake, custom audio channels via register_channel, show text with expressions - generator expressions in Python, no SyntaxWarning noise from decompiled code Also: - app.import_dir converts an unpacked game folder without changing it - app.converter.analyze dry-runs the script part of the converter - imports use their own "importing" status so a worker restart can't hijack them Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
PGames — локальная библиотека визуальных новелл
Загружаете архив с игрой на Ren'Py — сервер распаковывает его, переводит скрипты и ассеты в собственный формат PGVN (JSON-скрипты, WebP, Opus, WebM) и удаляет исходники. Играете в браузере во встроенном плеере. У каждой игры может быть несколько версий (форков) от разных пользователей; версии делят общие ассеты, поэтому форк почти не занимает места.
Подробности устройства — в docs/ARCHITECTURE.md.
Установка на VM
git clone <repo> pgames && cd pgames
cp .env.example .env
# обязательно поменяйте SECRET_KEY (openssl rand -hex 32) и пароли
docker compose up -d --build
Приложение слушает http://<IP VM>:8080 (порт — HTTP_PORT в .env).
Caddy на хосте Proxmox:
games.example.lan {
reverse_proxy 192.168.1.50:8080
}
Если в браузере сайт открывается по HTTPS через Caddy, оставьте
COOKIE_SECURE=true; при доступе напрямую по HTTP поставьте false, иначе
браузер не сохранит сессию.
Первый вход
Логин admin / пароль из ADMIN_PASSWORD (по умолчанию admin). Сразу после
входа нужно задать свой логин и пароль.
Регистрации нет: пользователей создаёт админ в разделе «Пользователи».
Сервер генерирует пароль и показывает его один раз — передайте его человеку,
при первом входе он задаст свой. Права настраиваются через роли
(«Роли»): admin, moderator, player плюс свои.
Импорт уже распакованных игр
Если игры уже лежат на VM распакованными, архивировать их не нужно. Подключите папку к контейнеру (только чтение) и запустите импорт:
docker compose run --rm -v /srv/games:/games:ro backend \
python -m app.import_dir "/games/Some-Game" --title "Some Game"
Папка не изменяется, сконвертированная копия попадает в библиотеку как обычная загрузка. Проверить, насколько хорошо конвертер понимает игру, не трогая медиа (минуты вместо часов), можно сухим прогоном:
docker compose run --rm -v /srv/games:/games:ro backend \
python -W ignore -m app.converter.analyze "/games/Some-Game"
Данные и бэкап
./data/blobs— сконвертированные игры (неизменяемые файлы по sha256);- том
db— PostgreSQL (пользователи, игры, версии, сохранения).
Для бэкапа достаточно pg_dump и копии data/blobs.
Разработка
На Windows тестовый стенд поднимается одной командой: start-test.bat.
Он запускает отдельный compose-проект pgames-test на http://localhost:8090
(свой .env.test, данные в data-test\), генерирует тестовую игру
data-test\sample.zip и открывает браузер. start-test.bat stop — остановить,
reset — удалить стенд вместе с данными, logs — логи бэкенда и воркера.
cd backend && pip install -r requirements.txt pytest && python -m pytest
cd frontend && npm install && npm run dev # проксирует /api на :8000
python -m tests.make_sample sample.zip # тестовая игра (из backend/)
Что поддерживает конвертер Ren'Py
label, реплики (в т.ч. атрибуты, extend, centered, NVL), scene/show/hide
с at/as/behind/zorder/with, переходы (dissolve, fade,
Fade(...), vpunch, wipe/slide…), menu с условиями и set, if/elif/else,
while, jump/call/return (включая expression), $/python:/init python:
(подмножество Python: переменные, выражения, списки/словари, циклы),
define/default, Character(...), image (файлы, цвета, Transform, im.*,
Composite, ConditionSwitch, Movie, покадровые ATL-анимации с pause/repeat),
layeredimage (always/attribute/group/if), transform со статическими
свойствами, Shake, camera, вложенные метки и именованные menu,
call label(args) и метки с параметрами, play/queue/stop/voice и свои
каналы (register_channel), pause, .rpa, .rpyc (через unrpyc),
автоопределение картинок из images/, GUI-текстбокс и шрифты игры.
Пока не поддерживается: screen-язык (кастомные экраны, карты,
мини-игры), движение и твины в ATL, функции/классы в python и картинки,
которые игра вычисляет своими функциями. Такие места перечислены в отчёте
конвертации у версии. Игры-«песочницы», где навигация построена на экранах,
пока не играбельны.