Files
pgames-manager/README.md
T
mrleo1nidandClaude Sonnet 5.5 ff82d882c0 feat: add ATL animation timelines and try/raise to the Ren'Py player
Python sandbox
- try/except/else/finally, raise (incl. re-raise), assert, for/while ... else
- Multi-generator and dict comprehensions
- Builtin exception hierarchy; user exceptions subclass it
- Inside try, missing keys/indexes, division by zero, attribute access on None
  and unknown names raise Python exceptions; lookups stay lenient elsewhere
- int()/float() raise ValueError on non-numeric strings

ATL
- converter/atl.py: set/move (linear, ease, easein, easeout), pause, repeat,
  parallel, choice, block, on show/hide and named transforms become a timeline
  shipped as game.json "atl"; Move() becomes a linear slide
- player/atl.ts: timeline runner wired into the renderer; `on hide` plays
  before the picture is removed
- function, time, contains, matrixcolor and expressions still block the import

Tests: exceptions/ATL fixtures and runtime tests, converter ATL tests; README
and ARCHITECTURE updated.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-25 12:11:07 +03:00

135 lines
8.3 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# PGames — локальная библиотека визуальных новелл
Загружаете архив с игрой на Ren'Py или Unity-игру на Naninovel (включая
отдельный адаптер Tomie) — сервер распаковывает его, переводит
скрипты и ассеты в собственный формат **PGVN** (JSON-скрипты, WebP, Opus, WebM)
и удаляет исходники. Игры других движков отклоняются на входе. Играете в браузере во встроенном плеере. У каждой игры
может быть несколько версий (форков) от разных пользователей; версии делят
общие ассеты, поэтому форк почти не занимает места.
Подробности устройства — в [docs/ARCHITECTURE.md](docs/ARCHITECTURE.md).
Пакетный импорт коллекции, строгая проверка совместимости и текущие ограничения
Naninovel описаны в [docs/IMPORT.md](docs/IMPORT.md).
Профили игр (отдельный конвейер для игр с особенностями) —
в [docs/GAME_PROFILES.md](docs/GAME_PROFILES.md).
Редактор модов, слияние, перенос на новую версию, ревизии и сборщик мусора —
в [docs/MODDING.md](docs/MODDING.md).
## Установка на VM
```bash
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 распакованными, архивировать их не нужно.
Подключите папку к контейнеру (только чтение) и запустите импорт:
```bash
docker compose run --rm -v /srv/games:/games:ro backend \
python -m app.import_dir "/games/Some-Game" --title "Some Game"
```
Папка не изменяется, сконвертированная копия попадает в библиотеку как
обычная загрузка. Проверить, насколько хорошо конвертер понимает игру,
не трогая медиа (минуты вместо часов), можно сухим прогоном:
```bash
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` — логи бэкенда и воркера.
```bash
cd backend && pip install -r requirements-dev.txt ruff && ruff check . && python -m pytest
cd frontend && npm install && npm run dev # проксирует /api на :8000
cd frontend && npm run typecheck && npm test
python -m tests.make_sample sample.zip # тестовая игра (из backend/)
```
Тесты конвертера требуют `ffmpeg` в `PATH`. Те же проверки (ruff, pytest,
`tsc`, тесты и сборка фронтенда) выполняет GitHub Actions
(`.github/workflows/ci.yml`); `mypy` запускается там как справочная проверка.
Каталоги `data/` и `data-test/` содержат библиотеку и тестовый стенд (гигабайты),
они в `.gitignore` — не добавляйте их в коммиты и в образы Docker.
Вход ограничен по числу неудачных попыток: 8 ошибок за 15 минут по IP или по
логину блокируют вход на оставшееся время (ответ 429 с `Retry-After`). Счётчик
хранится в памяти процесса и сбрасывается при перезапуске 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-текстбокс и шрифты игры.
Для Naninovel/Tomie см. [docs/IMPORT.md](docs/IMPORT.md).
Python игры выполняется в песочнице плеера: свои `def` и `class` (наследование,
`super()`, свойства, замыкания, `lambda`, `*args`/`**kwargs`), `try`/`except`/
`finally`, `raise`, `assert`, `for`/`while … else`, comprehension. ATL: движение
(`linear`/`ease`/`easein`/`easeout`), `pause`, `repeat`, `parallel`, `choice`,
`block`, `on show`/`on hide`, вызов других transform.
Пока **не** поддерживается: `screen`-язык (кастомные экраны, карты,
мини-игры), в ATL — `function`, `time`, `contains`, `matrixcolor` и шейдеры,
в Python — специальные методы кроме `__init__`/`__str__`/`__repr__`, генераторы,
`with`, системные модули (`os`, `socket`, …) и картинки, которые игра вычисляет
своими функциями. Такие места перечислены в отчёте конвертации у версии и
останавливают импорт. Игры-«песочницы», где навигация построена на экранах,
пока не играбельны.