Сборка дистрибутивов

Ren'Py включает поддержку для сборки дистрибутивов игры. После выбора «Сборка дистрибутивов» (Build Distributions) в лаунчере, Ren'Py просканирует себя и проект, чтобы определить, какие файлы включить в дистрибутив, создаст все необходимые архивы и соберёт файлы пакетов и обновлений.

Без какой-либо настройки Ren'Py может собирать следующие типы пакетов:

PC: Windows и Linux

Zip-архив для Windows x86_64 и Linux x86_64.

Linux

Файл tar.bz2 для Linux x86_64. Он также будет включать 32-битную и 64-битную ARM-версии Ren'Py, если они присутствуют. (Они находятся в пакете Ren'Py sdkarm.)

Macintosh

Zip-архив, содержащий приложение для Macintosh, предназначенное для macOS на процессорах Intel и Apple Silicon. Данные игры будут включены внутрь приложения, которое для пользователя выглядит как один файл. Система обновлений не работает с этим пакетом.

Windows

Zip-архив для Windows x86_64.

Windows, Mac и Linux для торговых площадок

Дистрибутив, который содержит информацию, необходимую для запуска на таких торговых площадках, как itch.io и Steam. Он не предназначен для прямого запуска (и, вероятно, не будет работать на Mac), а должен использоваться в процессе загрузки в магазин приложений.

Предупреждение

Файлы zip и tar.bz2, которые создаёт Ren'Py, содержат информацию о правах доступа, которая должна присутствовать для запуска Ren'Py на Linux и Macintosh.

Распаковка и повторная упаковка zip-файла в Windows с последующим запуском на Linux или Macintosh не поддерживается.

Базовая конфигурация

Процесс сборки можно настроить, устанавливая переменные и вызывая функции, которые находятся в пространстве имён build. Это должно быть сделано внутри блока init python. Настройки по умолчанию для этих конфигураций установлены в файле options.rpy.

Существует несколько основных переменных и функций, которые используются во многих играх.

build.name = "..."

Используется для автоматической генерации build.directory_name и build.executable_name, если они не заданы. Не должно содержать пробелов, двоеточий или точек с запятой.

build.directory_name = "..."

Используется для создания имён директорий в архивных файлах. Например, если установить значение «mygame-1.0», то Linux-версия проекта будет распаковываться в «mygame-1.0-linux».

Также используется для определения имени директории, в которую помещаются файлы пакетов. Например, если вы установите build.directory_name в mygame-1.0, архивные файлы будут помещены в mygame-1.0-dists в директории выше базовой.

Эта переменная не должна содержать специальных символов, таких как пробелы, двоеточия и точки с запятой. Если не задана, по умолчанию используется build.name, дефис и версия. Версия берётся из build.version, если она установлена, или из config.version.

build.executable_name = "..."

Эта переменная управляет именем исполняемых файлов, которые пользователь запускает для начала игры.

Эта переменная не должна содержать специальных символов, таких как пробелы, двоеточия и точки с запятой. Если не задана, по умолчанию используется build.name.

Например, если установлено значение «mygame», пользователь сможет запустить mygame.exe в Windows, mygame.app в Macintosh и mygame.sh в Linux.

Специальные файлы

Есть два файла, которые можно включить в базовую директорию вашей игры для кастомизации сборки.

icon.ico

Иконка, которая используется в Windows.

icon.icns

Иконка, которая используется в Macintosh.

Эти файлы иконок должны быть в определённых форматах. Для их конвертации вам понадобится использовать программу или веб-сервис (например, https://anyconv.com/png-to-ico-converter/ и https://anyconv.com/png-to-icns-converter/ ).

Классификация и игнорирование файлов

Процесс сборки работает путём предварительной классификации файлов дистрибутива Ren'Py и вашей игры по спискам файлов. Затем эти списки файлов добавляются в файлы пакетов.

Классификация выполняется функцией build.classify. Она принимает шаблоны и разделённый пробелами список имён файлов. Шаблоны сопоставляются от первого к последнему, причём первое совпадение имеет приоритет (даже если за ним следует более конкретный шаблон). Шаблоны сопоставляются как с начальным слешем (/), так и без него. Шаблоны могут включать следующие специальные символы:

/

Разделитель директорий.

*

Соответствует всем символам, кроме разделителя директорий.

**

Соответствует всем символам.

Например:

**.txt

Соответствует всем txt-файлам.

game/*.txt

Соответствует txt-файлам в директории game.

По умолчанию существует семь списков файлов, по которым можно классифицировать файлы. (Ren'Py помещает свои собственные файлы в первые шесть из них.)

all

Эти файлы будут включены во все пакеты и в сборки для Android.

linux

Эти файлы будут включены в пакеты для Linux.

mac

Эти файлы будут включены в пакеты для Macintosh.

windows

Эти файлы будут включены в пакеты для Windows.

renpy

Эти файлы будут включены в пакеты, для которых требуются файлы движка Ren'Py. (Linux, Macintosh и Windows.)

android

Эти файлы будут включены в сборки для Android.

Этот набор допустимых списков файлов можно расширить, передавая функции build.classify() новые имена в качестве её аргумента file_list.

Файлы также могут быть классифицированы в архивы. По умолчанию объявлен архив «archive»:

archive

Эти файлы будут включены в архив archive.rpa.

Набор архивов также можно расширить, используя функцию build.archive().

Файлы, которые не были классифицированы иным образом, помещаются в список файлов «all».

Чтобы исключить файлы из дистрибутива, классифицируйте их как None или пустую строку. В этом случае * и ** в конце шаблона должны соответствовать хотя бы одному символу.

Например:

# Включить README.txt
build.classify("README.txt", "all")

# Но исключить все остальные txt-файлы.
build.classify("**.txt", None)

# Добавить png и jpg файлы из директории игры в архив.
build.classify("game/**.png", "archive")
build.classify("game/**.jpg", "archive")

Документация

Вызов функции build.documentation с шаблонами помечает файлы, соответствующие этим шаблонам, как документацию. Файлы документации включаются в приложение для Macintosh дважды – как внутри, так и снаружи самого приложения.

Например, чтобы пометить все txt и html файлы в базовой директории как документацию, вызовите:

build.documentation("*.txt")
build.documentation("*.html")

Пакеты

Также возможно добавлять новые типы пакетов в процесс сборки Ren'Py. Это делается путём вызова функции build.package с именем пакета, типом и строкой, содержащей списки файлов для включения.

Допустим, мы хотим собрать обычную версию нашей игры и версию с бонусными материалами. Мы могли бы классифицировать бонусные файлы в список «bonus», а затем объявить пакет all-premium с помощью:

# Объявить новый архив, принадлежащий новому списку файлов "bonus".
build.archive("bonus_archive", "bonus")

# Поместить бонусные файлы в новый архив.
build.classify("game/bonus/**", "bonus_archive")

# Объявить пакет.
build.package("all-premium", "zip", "windows mac linux renpy all bonus")

Поддерживаемые типы пакетов: «zip» и «tar.bz2» для генерации файлов в этих форматах и «directory» для создания директории, заполненной файлами.

Архивы

Ren'Py поддерживает объединение файлов в простой архивный формат. Хотя он не очень безопасен, он защищает файлы от случайного копирования.

По умолчанию все файлы, классифицированные в список «archive», будут помещены в архив archive.rpa, который включается в список файлов «all».

Вызывая build.archive, можно объявлять новые архивы и списки файлов, в которые они будут включены. (Однако редко используется что-либо, кроме списка файлов «all».) Чтобы использовать архив, классифицируйте файлы в список с его именем.

Например, следующий код заархивирует изображения в images.rpa, а скрипты игры – в scripts.rpa:

# Объявить два архива.
build.archive("scripts", "all")
build.archive("images", "all")

# Поместить файлы скриптов в архив scripts.
build.classify("game/**.rpy", "scripts")
build.classify("game/**.rpyc", "scripts")

# Поместить изображения в архив images.
build.classify("game/**.jpg", "images")
build.classify("game/**.png", "images")

Если архивный файл пуст, он не будет создан.

Пожалуйста, подумайте дважды, прежде чем архивировать вашу игру. Сохранение файлов в открытом виде поможет другим запускать вашу игру на будущих платформах — платформах, которых может и не существовать, когда вас уже не будет.

Директория old-game

Ren'Py использует скомпилированные файлы скриптов (называемые .rpyc-файлами) для быстрого запуска вашей игры. Эти файлы также хранят важные детали, такие как уникальные идентификаторы (ID) для каждой строки диалога или сцены, на которые полагаются файлы сохранений. Когда игра обновляется и скрипты .rpy изменяются, Ren'Py обновляет или создаёт соответствующие .rpyc-файлы при запуске игры.

Такое поведение .rpyc-файлов может создавать трудности для разработчиков, которые делают несколько релизов, например, при распространении игры через ранний доступ или на платформах вроде Patreon, или которые работают над большими играми с участием нескольких разработчиков. В процессе разработки легко внести серию изменений в файл .rpy, что приведёт к тому, что результирующий .rpyc-файл будет иметь другие ID, чем те, что использовались в вашем текущем стабильном релизе. Для команд это ещё большая проблема, поскольку несколько разработчиков могут редактировать один и тот же .rpy-файл. Как Ren'Py может сохранить свои ID без единого .rpyc-файла в качестве определённого источника?

Чтобы эти изменения не нарушали совместимость сохранений, разработчики могут использовать директорию old-game. Эта специальная папка, которая находится рядом с директорией game в папке вашего проекта, позволяет сохранить копию .rpyc-файлов из вашего предыдущего релиза. Её структура должна соответствовать структуре директории game. Например, переместите game/scripts/day1.rpyc в old-game/scripts/day1.rpyc. Файлы в old-game, не являющиеся .rpyc-файлами, игнорируются.

Когда у вас есть директория old-game с .rpyc-файлами из вашего последнего релиза, Ren'Py использует их для создания новых .rpyc-файлов для изменённых .rpy-скриптов. Он сохраняет те же ID для тех частей вашего скрипта, которые не изменились, так что старые файлы сохранений по-прежнему могут загружаться корректно.

Как извлечь максимальную пользу из директории `old-game`:

  • При запуске игры, если .rpy-файл был изменён и в old-game есть соответствующий .rpyc-файл, Ren'Py использует этот .rpyc-файл для обновления файла в директории game. Это сохраняет согласованность его ID с вашим последним релизом для максимальной совместимости сохранений.

  • Перед сборкой нового релиза, включите опцию «Принудительная перекомпиляция» (Force Recompile) на странице сборки в Ren'Py SDK и нажмите «Обновить old-game» (Update old-game) перед тем, как нажать «Собрать» (Build). Это перекомпилирует все .rpyc-файлы, используя файлы из old-game в качестве отправной точки, а затем обновит old-game этими новыми, стабильными .rpyc-файлами для вашего следующего релиза.

  • Если вы уже выпустили игру, вы всё равно можете извлечь пользу из old-game, скопировав .rpyc-файлы из директории game вашего последнего релиза в директорию old-game вашего проекта, сохраняя ту же структуру папок.

Более подробную информацию о том, как .rpyc-файлы помогают загружать сохранения в изменённых играх, можно найти здесь:

Требования

Некоторые магазины запрашивают системные требования для запуска приложений на Ren'Py. Хотя они варьируются от игры к игре, вот набор минимальных требований для типичной визуальной новеллы.

Windows

  • Версия: Windows 10 или новее.

  • Процессор: 2.0 ГГц 64-битный Intel-совместимый

  • ОЗУ: 2.0 ГБ

  • Видеокарта: OpenGL 3.0 или DirectX 11

macOS

  • Версия: 10.10+

  • Процессор: 2.0 ГГц 64-битный Intel-совместимый или M1+

  • ОЗУ: 2.0 ГБ

  • Видеокарта: OpenGL 3.0

Linux

  • Версия: Ubuntu 20.04+

  • Процессор: 2.0 ГГц 64-битный Intel-совместимый

  • ОЗУ: 2.0 ГБ

  • Видеокарта: OpenGL 3.0

Объём необходимого дискового пространства полностью определяется ассетами вашей игры, а требуемый объём процессора и оперативной памяти также может варьироваться. Ren'Py также будет работать под OpenGL 2 при наличии определённых расширений.

Функции сборки

build.archive(name, file_list='all')

Объявляет о существовании архива, чьё name добавляется в список доступных имён архивов, которые можно передать в build.classify().

Если один или несколько файлов классифицированы с именем name, name.rpa будет собран как архив, а затем распространён в пакетах, включающих указанный здесь file_list.

build.archive("secret", "windows")

Если какой-либо файл включен в архив "secret" с помощью функции build.classify(), он будет включен в архив secret.rpa в сборках для Windows.

Как и в функции build.classify(), если имя, указанное как file_list, не существует как имя списка файлов, оно создаётся и добавляется в набор допустимых списков файлов.

build.classify(pattern, file_list)

Классифицирует файлы, соответствующие pattern, в file_list, который также может быть именем архива.

Если имя, указанное как file_list, не существует как имя архива или списка файлов, оно создаётся и добавляется в набор допустимых списков файлов.

build.clear()

Очищает список шаблонов, используемых для классификации файлов.

build.documentation(pattern)

Объявляет шаблон, соответствующий документации. В сборке mac-приложения файлы, соответствующие шаблону документации, хранятся дважды — один раз внутри пакета приложения и еще раз вне его.

build.executable(pattern)

Добавляет шаблон, помечающий файлы как исполняемые на платформах, которые это поддерживают (Linux и Macintosh).

build.package(name, format, file_lists, description=None, update=True, dlc=False, hidden=False, update_only=False)

Объявляет пакет, который может быть собран инструментом упаковки.

name

Имя пакета.

format

Формат пакета. Строка, содержащая список форматов, разделённых пробелами:

zip

Zip-файл.

tar.bz2

Tar.bz2-файл.

directory

Директория, содержащая файлы.

dmg

Macintosh DMG, содержащий файлы.

app-zip

Zip-файл, содержащий приложение для Macintosh. Этот формат не поддерживает Ren'Py updater.

app-directory

Директория, содержащая mac-приложение. Этот формат не поддерживает Ren'Py updater.

app-dmg

Образ диска Macintosh, содержащий dmg. (Только для Mac.) Этот формат не поддерживает Ren'Py updater.

bare-zip

Zip-файл без добавления build.directory_name в начало.

bare-tar.bz2

tar.bz2-файл без добавления build.directory_name в начало.

null

Используется для создания только обновлений, без основного пакета.

Пустая строка не создаст никаких форматов пакетов (это делает возможным dlc).

file_lists

Список, содержащий списки файлов, которые будут включены в пакет.

description

Необязательное описание пакета, который будет собран.

update

Если True и создаются обновления, для этого пакета будет создано обновление.

dlc

Если True, любой zip или tar.bz2-файл будет создан в автономном режиме DLC, без каталога обновлений.

hidden

Если True, пакет будет скрыт из списка пакетов в лаунчере.

Информация о сборке

Существуют две переменные, которые можно использовать для предоставления информации о сборке. Эта информация используется для генерации файла game/cache/build_info.json, который загружается при запуске Ren'Py.

build.time = None

Эта переменная по умолчанию имеет значение None, но если ваша игра была собрана, ей будет присвоено время сборки игры в секундах с 1 января 1970 года.

build.info = { }

Эта переменная позволяет хранить информацию, которая будет помещена в файл game/cache/build_info.json в собранной игре. При запуске собранной игры game/cache/build_info.json загружается, и его содержимое помещается в эту переменную.

Как правило, вы захотите проверить, что поле не существует, и установить его, используя setdefault.

Например, это сохраняет имя компьютера, который собрал игру, в файл build_info.json:

python hide:
    import socket
    build.info.setdefault("build_host", socket.gethostname())

Информация в этой переменной должна иметь типы, которые можно помещать в JSON-файлы (то есть None, булевы значения, строки, числа, списки и словари).

Расширенная конфигурация

Следующие переменные обеспечивают дополнительный контроль над процессом сборки:

build.allow_integrated_gpu = True

Разрешает Ren'Py работать на встроенной видеокарте на платформах, имеющих как встроенные, так и дискретные видеокарты. В настоящее время это поддерживается только в Mac OS X.

build.destination = "{directory_name}-dists"

Задаёт путь к директории, в которую будут помещены архивные файлы. Это может быть абсолютный или относительный путь. Относительный путь считается относительным к директории проектов.

Следующие значения подставляются с помощью функции Python str.format.

{directory_name}

Значение build.directory_name.

{executable_name}

Значение build.executable_name.

{version}

Значение build.version.

build.change_icon_i686 = True

Если True и icon.ico существует, иконка 32-битного исполняемого файла Windows будет изменена. Если False, иконка не изменится. Установка этого значения в False может предотвратить ложноположительные срабатывания некоторых антивирусных программ для вашей игры.

build.exclude_empty_directories = True

Если true, пустые директории (включая директории, оставшиеся пустыми после архивации файлов) будут удалены из сгенерированных пакетов. Если false, пустые директории будут включены.

build.game_only_update = False

Если true, build.include_update включена, и становится доступен пакет «Обновление только игры для мобильных устройств» (Game-Only Update for Mobile).

build.include_i686 = True

Если true, файлы, необходимые для запуска на 32-битных процессорах x86, будут включены в сборки для Linux и Mac. Если False, эти файлы не будут включены.

build.include_old_themes = True

Если true, файлы, необходимые для поддержки тем, существовавших до Ren'Py 6.99.9, будут включены в сборку. Если false, такие файлы исключаются.

Это значение устанавливается в False при вызове gui.init().

build.include_update = False

Если true, Ren'Py создаст файлы, необходимые для работы системы обновлений.

build.itch_project = None

Установка этого значения позволяет лаунчеру Ren'Py загружать ваш проект на itch.io. Оно должно быть установлено в имя проекта, зарегистрированного на itch (например, «renpytom/the-question»).

После установки этого значения, после сборки дистрибутивов, вы можете нажать «Сборка дистрибутивов» (Build distributions), затем «Загрузить на itch.io» (Upload to itch.io), чтобы инициировать загрузку.

build.itch_channels = { ... }

Это сопоставляет шаблон имени файла (например, «*-win.zip») со строкой, указывающей канал itch, на который следует загрузить файл. По умолчанию это:

{
    "*-all.zip" : "win-osx-linux",
    "*-market.zip" : "win-osx-linux",
    "*-pc.zip" : "win-linux",
    "*-win.zip" : "win",
    "*-mac.zip" : "osx",
    "*-linux.tar.bz2" : "linux",
    "*-release.apk" : "android",
}
build.mac_info_plist = { }

Это словарь, сопоставляющий строки со строками, который можно использовать для добавления или переопределения ключей в файле Info.plist для Mac.

build.update_formats = [ "rpu" ]

Это список форматов, которые будет собирать система обновлений. Формат по умолчанию, «rpu», поддерживается начиная с Ren'Py 7.7 и 8.2. Если вам нужно поддерживать обновления с использованием более ранней системы на основе zsync, добавьте «zsync» в список.

build.version = None

Задаёт версию сборки, используемую в процессе сборки. Если None, по умолчанию используется config.version. Основное предназначение этого — позволить config.version содержать символы, которые не являются допустимыми в именах файлов или директорий.