Files
pgames-manager/docs/RENPY_PLAYER.md
T
mrleo1nidandClaude Sonnet 5.5 a8902deaf7
CI / frontend (push) Failing after 19s
CI / backend (push) Failing after 36s
docs: what the Ren'Py player does like Ren'Py (layers, rollback, text tags, preferences)
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-27 04:39:48 +03:00

6.0 KiB
Raw Blame History

Плеер Ren'Py: что он делает так же, как Ren'Py

Плеер (frontend/src/player/) исполняет сценарий Ren'Py из IR в браузере. Здесь — то, что повторяет поведение Ren'Py, а не его упрощение. Принцип: если игра приносит свой код (библиотеку текстовых эффектов, свои displayable, свои настройки), плеер запускает её код, а не заменяет его собственной копией.

Геометрия трансформаций

rendertransform.ts — порт RenderTransform из renpy/display/accelerator.pyx: обрезка (crop), size/fit, zoom и отражения, rotate с rotate_pad, 3D-повороты (xrotate, yrotate, zrotate) вокруг matrixanchor, zpos, zzoom, matrixtransform, якорь по transform_anchor. Матрицы — Ren'Py (Matrix4: векторы-столбцы, ось z от зрителя); в CSS уходит matrix3d с отражённым z. xpan/ypan/xtile/ytile — отдельный элемент с повторяющимся фоном. blend и additive переводятся в mix-blend-mode. Тесты — frontend/tests/rendertransform.test.mjs.

Слои и камера

config.layers задаёт порядок слоёв снизу вверх; слой screens — собственный интерфейс плеера (текстбокс, меню, экраны), слои до него лежат под интерфейсом, после — над ним. Игра управляет слоями так же, как в Ren'Py:

  • show/hide/scene ... onlayer имя, renpy.show/hide/scene(layer=...), renpy.showing, renpy.get_showing_tags, renpy.get_attributes с layer;
  • show screen/hide screen/call screen ... onlayer имя, свойство layer экрана, renpy.show_screen(_layer=...), renpy.get_screen(layer=...);
  • renpy.add_layer(имя, above=, below=) — порядок сохраняется в сохранении;
  • camera имя at ... и renpy.show_layer_at(список, layer=) — трансформация всего слоя (анимируемая, с теми же свойствами, что у картинки);
  • perspective True|число|(near, p, far) на слое: картинки со zpos уходят в глубину с перспективой (CSS perspective на слое).

Смена сцены (with) снимает копию всех слоёв под интерфейсом. preferences.transitions = 0 отключает переходы.

Откат

Плеер хранит снимок состояния на каждом взаимодействии (до 50) и возвращается к предыдущему по колесу вверх, PageUp и действию Rollback. Журнал очищается при новой игре и загрузке.

Текст

  • {font}, {alpha}, {k}, {plain}, {outlinecolor}, {cps} (в том числе {cps=*2} и {/cps}), {a=...} (адреса, show:, hide:, jump:, call_in_new_context: или config.hyperlink_handler), {rb}/{rt} (ruby), {space=N}, {vspace=N}, {alt}, {image=...}.
  • Свои теги игры (config.custom_text_tags[...], config.self_closing_custom_text_tags[...]): плеер вызывает функцию игры с (tag, argument, contents), где contents — пары (renpy.TEXT_TEXT | TEXT_TAG, текст); ответ — тот же список, а renpy.TEXT_DISPLAYABLE вставляет displayable в строку как один символ. Так работают Kinetic Text Tags ({bt}, {fi}, {sc}, {rotat}, {chaos}, {swap}, {move}, {omega}), {glitch}, {gradient}, {explode} и {ruby} в That New Teacher: их библиотеки — обычные скрипты игры.
  • История, сохранения и перевод видят текст без вызова функций тегов (parseText(text, false)).

API отрисовки для своих displayable

render.ts: renpy.Displayable, renpy.Render (blit, subpixel_blit, fill, canvas, subsurface, zoom), renpy.render, renpy.redraw, Text.set_text. Дерево рендера превращается в DOM и перерисовывается, пока элемент на странице.

Настройки игры

preferences — объект настроек плеера: text_cps, afm_time, afm_enable, fullscreen, transitions, language, volumes[...], get_volume/set_volume, get_mute/set_mute, get_all_mixers; default preferences.x = ... добавляет поле. Color(...) — настоящий Color Ren'Py (interpolate, tint, shade, hexcode, replace_*, rgb/hls/hsv). renpy.fetch отправляет запрос из браузера (нужен CORS на сервере); без сети игра получает FetchError, как в Ren'Py.

Шрифты: FontGroup().add(файл, от, до) собирается в одно CSS-семейство с unicode-range. config.mouse_displayable = MouseDisplayable(...) и config.mouse меняют курсор.

Чего пока нет

  • Шейдеры и сетки (renpy.register_shader, ATL shader/mesh, u_*, gl_*), поэтому шейдерные эффекты текста ({wave}) и размытие через blur.rpy в профилях пропускаются; частичное additive (0 < x < 1).
  • Live2D.
  • Снимки экрана в слотах сохранения и импорт .save Ren'Py.
  • Пропуск только прочитанного текста (preferences.skip_unseen сохраняется, но не действует).