# Продвинутое руководство
# Переменные
Если вы хотите, чтобы игра запоминала каждый выбор игрока, то без переменных нам не обойтись.
Объявление переменных происходит в специальном блоке init. Имена и значения у переменных могут быть любые, но рекомендуется использовать короткие английские слова или цифры (цифры только в значении).
init:
$ choice = False # Переменная будет объявлена со значением False
$ count = 0 # А у этой переменной будет значение 0
2
3
Изменение значения переменных будет выглядеть так:
init:
$ choice = False # Переменная будет объявлена со значением False
$ count = 0 # А у этой переменной будет значение 0
label my_mod:
$ choice = True # Переменная `choice` становится равна `True`
$ count += 1 # К переменной `count` добавляется одно очко
2
3
4
5
6
7
# Выборы
Если вы хотите дать игроку выбор, то вам необходимо использовать специальный блок menu:
mt "Возьми-ка этот мешок с сахаром."
menu:
"И куда мне его девать?":
$ good += 1
jump good_label
"Да идите вы со своим сахаром на ...":
jump bad_label
2
3
4
5
6
7
8
В приведенном примере Ольга Дмитриевна попросит нас взять мешок с сахаром, мы же можем как подчиниться и увеличить переменную "good" на 1, так и отказаться, причем в зависимости от нашего выбора события в игре могут измениться.
Будьте осторожны
Варианты ответа тоже открывают блок, и если мы не поставим после каждого двоеточие, мод может не запуститься.
# Проверка условий
Что нам делать если мы хотим чтобы какие-то из возможностей были у игрока в зависимости от его выборов? Для этого то мы и использовали переменные! Сейчас же мы воспользуемся специальной конструкцией:
label my_mod:
if good > 0: # Если очков `good` больше 0, то прыгаем на лейбл хорошей концовки
jump good_end
else: # Иначе прыгаем на лейбл плохой концовки
jump bad_end
2
3
4
5
Если значение переменной good
больше нуля, то игра продолжится на метке good_end
, если нет, то мы переходим на метку bad_end
.
Теперь же мы постараемся реализовать выборы, в которых, в зависимости от прошлых выборов персонажа, будут добавляться или убираться различные варианты ответов:
label my_mod:
mt "Семен, сегодня после обеда ты будешь убираться в столовой."
menu:
"Почему именно я?":
jump why_me
"Я же уже помог вам сегодня" if good > 0:
jump helped_today
"Не намерен я вам тут прислуживать!" if good == 0:
jump angry
2
3
4
5
6
7
8
9
10
В данном случае мы можем:
- возмутиться сложившейся ситуации;
- мы можем попросить ее отсрочить дежурство, если мы уже заслужили доверие вожатой;
- отправить ее куда подальше, если не помогали. И в каждом случае нам, как создателям мода необходимо будет прописать что произойдет в каждом из этих случаев.
Проверка на значение True
или False
значения переменной происходит схоже:
label my_mod:
if Otnes_saxar == True: # Если помог отнести сахар, то Ольга хвалит нас.
mt "Молодец, Семён, помог отнести сахар!"
else: # Если же не помогли отнести, то Ольга нас ругает. Стерва.
mt "Бездарность, не пионер, а размазня!"
2
3
4
5
Проверка условия
Обратите своё внимание, что проверка на значение переменной проходит с двумя знаками 'равно'. Напомним, один знак равно — присваивание значения переменной, а два — проверка на значение переменной
Также, переменным можно присваивать не только очки и состояния True
или False
— а всё, что вашей душе заблагорассудится. Приведём пример:
init:
$ Ya_molodec = None # Оставляем переменную без значения. Равна `None`.
label my_mod:
$ Ya_molodec = "Krasavec" # Присваиваем переменной значение "Krasavec"
if Ya_molodec == "Krasavec": # Если переменная равна "Krasavec", то мы хвалим себя.
th "А я хорош!"
else: # Иначе негодуем.
th "Не получилось, не фортануло."
2
3
4
5
6
7
8
9
Разница в присвоенных значениях
Обратим внимание, что в примере выше проверка на значение переменной была с кавычками. Если бы мы сделали проверку без кавычек, то игра бы просто пропустила проверку.
Также советую запомнить, что True
и "True"
при проверке переменной — это два разных значения.
# Использование карты
Чтобы дать игре понять, когда развернуть перед игроком карту, необходимо всего несколько простых команд.
- Перед выводом карты нужно сбросить все прошлые зоны на ней:
disable_all_zones() # Отключает все старые маркеры карты.
- Заполняем конструкцию
set_zone()
.
Первым значением будет выделенная на карте зона, а вторым - лейбл, куда прыгать, при клике на неё.
Вот список всех зон и как они обозначены в игре:
me_mt_house
- Домик Семёна и Ольги Дмитриевныestrade
- Сценаmusic_club
- Музклубsquare
- Площадьdining_hall
- Столоваяsport_area
- Спорткомплексbeach
- Пляжboat_station
- Лодочный причалclubs
- Клубыlibrary
- Библиотекаmedic_house
- Медпунктcamp_entrance
- Ворота в лагерьforest
- Лес
Например, чтобы при нажатии на клубы мы прыгали на лейбл day1_gone_to_clubs
(название лишь для примера) нужно реализовать такую конструкцию:
set_zone("clubs", "day1_gone_to_clubs")
И в конце выводим саму карту командой:
show_map()
Полный пример:
label my_mod:
$ disable_all_zones()
$ set_zone("clubs", "day1_gone_to_clubs")
$ show_map()
2
3
4
Вариант кода со всеми позициями на карте:
label my_mod:
$ disable_all_zones()
$ set_zone("me_mt_house", "day1_gone_to_mt_house") # Домик Семёна и Ольги Дмитриевны
$ set_zone("estrade", "day1_gone_to_estrade") # Сцена
$ set_zone("music_club", "day1_gone_to_music_club") # Музклуб
$ set_zone("square", "day1_gone_to_square") # Площадь
$ set_zone("dining_hall", "day1_gone_to_dining_hall") # Столовая
$ set_zone("sport_area", "day1_gone_to_sport_area") # Спорткомплекс
$ set_zone("beach", "day1_gone_to_beach") # Пляж
$ set_zone("boat_station", "day1_gone_to_boat_station") # Лодочный причал
$ set_zone("clubs", "day1_gone_to_clubs") # Клубы
$ set_zone("library", "day1_gone_to_library") # Библиотека
$ set_zone("medic_house", "day1_gone_to_medic_house") # Медпункт
$ set_zone("camp_entrance", "day1_gone_to_camp_entrance") # Ворота в лагерь
$ set_zone("forest", "day1_gone_to_forest") # Лес
$ show_map()
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# Добавление персонажа
Любой персонаж игры - простая переменная. Переменные создаются двумя способами, методом движка - с помощью команды define
и методом Python - с помощью символа - $
.
define ivan = Character(u"Иван")
TIP
Символ u
используется для отображения русского текста у людей, у которых он не установлен в системе.
Теперь персонажа можно использовать в моде:
define ivan = Character(u"Иван")
label my_mod:
ivan "Привет"
2
3
4
Цвет имени персонажа указывается с помощью параметра color
, также рекомендую использовать неизменный параметр what_color
для изменения цвета речи персонажа. В самой игре все персонажи говорят цветом #f1d076
, так не будем выделяться: назначим нашему персонажу в качестве цвета имени, скажем, зелёный цвет (#008000
) и установим в качестве цвета речи - #f1d076
:
define ivan = Character(u"Иван", color="#008000", what_color="#f1d076")
label my_mod:
ivan "Привет"
2
3
4
# Монитор с номером дня
Для выведения на экран монитора, необходимо прописать две команды:
backdrop = "days"
new_chapter(1, u"Мой мод. День первый.")
2
backdrop
- фон с монитором.1
- номер дня, который будет показан на мониторе.- текст (в примере - Мой мод. День первый.) - то, как будет называться сохранение.
Фонов (backdrop
) в игре 5:
backdrop = "days" # Просто монитор.
backdrop = "un" # Монитор с проплывающей Леной.
backdrop = "us" # Монитор с проплывающей Ульяной.
backdrop = "sl" # Монитор с проплывающей Славей.
backdrop = "dv" # Монитор с проплывающей Алисой.
2
3
4
5
TIP
Обратим внимание, что при использовании команды new_chapter
сбрасываются плавные переходы для изображений, следующими после неё. Проверено на опыте. Советуем прописать pause
в n
-ное количество секунд, чтобы сначала проигрались плавные анимации перехода, а затем сработала команда new_chapter
# Достижения
Для вывода достижения в нужном вам месте, вставьте следующие команды:
define myachiv = "mods/my_mod/images/myachiv.png"
label my_mod:
play sound sfx_achievement
show myachiv at achievement_trans
with dspr
$ renpy.pause(3, hard=True)
hide myachiv
2
3
4
5
6
7
8
myachiv
- Ваше изображение с достижением.
# Аудиоканалы
Всего внутри "Бесконечного Лета" 8 аудиоканалов:
ambience
, music
, sound
, sound2
, sound3
, sound_loop
, sound_loop2
, sound_loop3
.
Если вам необходимо добавить новый аудиоканал, то в init-блоке вашего мода пропишите следующее:
renpy.music.register_channel("<название_канала>", "<название_микшера>", True)
Пример:
init:
$ renpy.music.register_channel("voices", "voice", True)
2
Есть три возможных микшера громкости: music
, sfx
и voice
. Подбирайте необходимый вам микшер в соответствии с предназначением дорожки.
Если вам необходимо создать свой микшер для звука или музыки, пропишите следующее:
renpy.sound.set_mixer("название_канала", "номер_микшера")
.
Это задает имя микшера, связанного с данным каналом. "sfx" находится на каналах от 0 до 3, а "music" - от 3 до 7.
Пример:
init:
$ renpy.sound.set_mixer(voices_mixer, 10)
2
# Экраны
# Предисловие
Экраны имеют две основные функции:
- Отображение информации. С помощью различных панелей, изображений, или вовсе текста. Например, экран диалогов (
say
(opens new window)) используется для отображения диалога с пользователем, отображая имя говорящего. - Взаимодействие. Различные кнопки и панели, показанные экраном, позволяют игроку совершать различные действия или менять какие-либо значения.
Экраны могут отображаться четырьмя способами:
- Неявно, как, например, экран
say
. - Явно, используя операторы, вызывающие отображения других экранов.
- Автоматически. Например, экран с именем
main_menu
(opens new window) будет автоматически вызываться, когда игрок вернётся в главное меню игры или модификации, если она, конечно, заменяет этот экран на свой. - Как действие, связанное с любой кнопкой. Например, можно привязать появление какого-либа скрина на нажатие правой/левой кнопки мыши или при нажатии на клавишу.
# Язык экрана
Он состоит из оператора, объявляющего новый экран (screen
(opens new window)), операторов, добавляющих отображаемые объекты на этот экран (например, add
(opens new window) или imagebutton
(opens new window)), и операторов управления (opens new window) (xalign
, yalign
, spacing
).
Пример экрана:
screen test_screen:
tag test
modal True
add "test bg"
2
3
4
5
В этом примере, первая строка — оператор screen, что используется для объявления экрана. Не забываем про то, что необходимо дать экрану имя. Оператор tag
выступает в выдаче "тэга" для этого окна, заменяя другие экраны с таким же тегом, если вызывается ещё один экран с таким же тегом. Оператор modal
при значении True
не позволяет игроку взаимодействивать с отображаемыми объектами "под" экраном, давая взаимодействие игроку лишь с кнопками или объектами внутри самого экрана. Оператор add
добавляет изображение или любой отображаемый объект на экран. Возможно расположение по указанным координатам, благодаря стандартным командам из трансформов (align
, pos
и прочее).
# Синтаксис языка экрана
У операторов экрана в большинстве своём общий синтаксис. Если оператор заканчивается двоеточием, то он создаёт блок, в котором может быть одно из следующих составляющих:
- Список свойств (
modal True
,tag menu
,sensitive
). - Операторы языка экрана (
imagebutton
,textbutton
,text
и прочее).
# Операторы-кнопки
button
(opens new window), imagebutton
, textbutton
(opens new window) — все эти операторы позволяют создать внутри экрана кнопку, которой можно задать свойства (hover
, idle
, action
и т.д). Как понятно из названия, imagebutton
создаёт кнопку-изображение, textbutton
— текстовую кнопку, а button
— просто область экрана, при нажатии на которую будет выполнено какое-либо действие, указанное для такой кнопки.
Пример экрана с кнопками:
screen my_screen:
tag menu
modal True
add "black"
textbutton "Текстовая кнопка":
align(0.5, 0.5) # Располагаем кнопку по центру экрана
imagebutton:
align(0.1, 0.1) # Располагаем кнопку в левом верхнем углу экрана
idle "Путь до изображения-кнопки в состоянии 'не наведена мышка'"
hover "Путь до изображения-кнопки в состоянии 'наведена мышка'"
action NullAction() # Даём кнопке "нулевое действие" — при нажатии ничего не происходит.
2
3
4
5
6
7
8
9
10
11
12
13
14
Оператор "auto"
Также, если вы не хотите прописывать idle и hover версию в две строчки, можно воспользоваться оператором auto
, который автоматически находит idle и hover версию кнопки в зависимости от названия.
Учтите, что в названиях кнопки должны присутствовать слова idle
и hover
.
Пример:
screen my_screen:
tag menu
modal True
imagebutton:
auto "mymod/buttons/my_button_%s.png" # Слово, на которое опирается оператор `auto` находится в конце. То бишь, названия кнопок с `idle` и `hover` версией — my_button_idle и my_button_hover.
2
3
4
5
6
Полный список действий (action
), которые можно дать кнопкам, можно найти здесь (opens new window).
# Операторы экрана
В дополнение к оператору screen, есть три оператора, которые включают экраны. Это show screen
(opens new window), call screen
(opens new window) и hide screen
(opens new window).
Оператор show screen
вызывает отображение экрана. Возможно использование with
. Также, их можно вызывать с какими-либо параметрами. Например, show screen my_screen(_layer = "screens")
.
screen my_screen:
add "black"
label my_mod:
show my_screen with dissolve # Показываем экран с растворением в 0.5 секунды.
2
3
4
5
TIP
Учтите, что screen прописываются за блоком лейбла. Можно прописать вне всяких блоков, а также внутри блока init
.
Показанные таким образом экраны отображаются до тех пор, пока они не будут скрыты командой hide screen
.
Оператор hide screen
используется для скрытия экрана, который отображается в данный момент. Возможно использование with
.
screen my_screen:
add "black"
label my_mod:
show screen my_screen with dissolve # Показываем экран с растворением в 0.5 секунды.
pause(2) # Пауза 2 секунды
hide screen my_screen with dissolve # Убираем экран с растворением в 0.5 секунды.
2
3
4
5
6
7
Оператор call screen
показывает экран, а затем снова скрывает его, как только с ним закончится взаимодействие (Скажем, когда будет произведён прыжок на другой лейбл). Убрать экран можно также с помощью действия return
(opens new window) (или Return()
, если мы говорим о действии для кнопки. При нажатии на неё, экран будет скрыт. Если же экран был показан с помощью show screen
— нас выбросит в главное меню игры). Возможно использование with
.
screen my_screen:
add "black"
textbutton "Нажми!":
action Return() # Закрываем экран при нажатии на кнопку.
label my_mod:
call screen my_screen with dissolve # Показываем экран с растворением в 0.5 секунды. Как только будет нажата кнопка, экран будет закрыт.
2
3
4
5
6
7
8
Различие между Show и ShowMenu при задавании действии для кнопки.
Если внутри экрана мы откроем ещё один экран, который при нажатии на кнопку был вызван действием Show
(Show("my_screen")
) и затем нажмём на кнопку с действием Return()
, то нас выбросит в главное меню. Но! Если мы также вызовем экран, но с действием ShowMenu
(ShowMenu("my_screen")
), то при нажатии на кнопку с Return()
внутри второго экрана, нас возвратит обратно на предыдущий экран. Удобно!
screen my_screen:
add "black"
textbutton "Нажми!":
action Show("my_screen2") # Открываем экран "my_screen2"
screen my_screen2:
add "black"
textbutton "Нажми!":
action Return() # Нас выбрасывает в главное меню игры.
2
3
4
5
6
7
8
9
10
11
и
screen my_screen:
add "black"
textbutton "Нажми!":
action ShowMenu("my_screen2") # Открываем экран "my_screen2"
screen my_screen2:
add "black"
textbutton "Нажми!":
action Return() # Нас возвращает обратно на экран "my_screen"
2
3
4
5
6
7
8
9
10
11
# Портирование мода на Android с помощью ESTool
WARNING
Необходимо наличие установленного Python (opens new window) и, для использования полного функционала, установленный модуль Pillow (PIL) (opens new window)
Благодаря утилите ESTool можно облегчить портирование своего мода в несколько раз, т.к она позволяет автоматически урезать размеры изображений/кнопок/стилей и т.п до тех, что поддерживает мобильная версия Бесконечного Лета, сохраняя огромное количество времени. Создано группой "Загрузчик модов для Бесконечного Лета" (opens new window), за что им большое спасибо. Программа всё ещё в разработке, так что ошибки не исключены.
В нашем примере используется версия 1.001
.
# Установка
Выбираем версию, скачиваем, распаковываем архив в любую папку.
# Настройка
Открываем config.py
, смотрим.
dry_run
— делает прогон кода, если значение переменной равноTrue
. Ничего не меняет и не создает никаких файлов (кроме лога), но выявляет большую часть ошибок. Настоятельно рекомендуется сначала запустить сTrue
, посмотреть лог, а уже затем ставить наFalse
и запускать скриптin_place
— еслиFalse
, то портированный мод кладется в отдельную папку рядом. ЕслиTrue
, то он кладется вместо исходных файлов.backup_style
— создание бэкапа скриптов. Еслиin_place
равноTrue
, то создаются резервные копии rpy-скриптов (и только скриптов!)- При значении
separate
бэкапы создаются в отдельной папке. - Если
nearby
, то бэкап кладётся рядом с исходными файлами (с расширением._rpy
). - Если
None
, то бэкапы не создаются. Еслиin_place
равноFalse
, то настройка игнорируется (в бэкапах нет необходимости, поскольку исходные файлы остаются в целости и сохранности)
- При значении
backup_location
— приbackup_style
со значениемseparate
задаёт путь к папке с бэкапами.src_path
— путь к папке с модом, который требуется портировать.dest_path
— путь, куда класть результат. Приin_place
со значениемTrue
заменяет путь вsrc_path
наdest_path
rename_non_ascii
— при значенииTrue
переименовывает файлы в латиницу, транслитерируя кириллицу при наличии.rescale_coordinates
— при значенииTrue
умножает координаты в коде на 2/3, подгоняя под размеры для Android.comments_style
— дописывание комментария к изменённым строкам в коде.- Если равно
long
, то в комментарий пишется исходная строка целиком. - Если равно
short
, то делается пометка, что строка была изменена. - Если равно
none
, то комментарий не пишется.WARNING
Если при
in_place
со значениемTrue
запустить скрипт дважды сcomments_style
со значениемnone
, то координаты будут изменены дважды!
- Если равно
resize_images
— еслиTrue
, сжимает изображения в полтора раза.WARNING
Требуется наличие модуля
Pillow
WARNING
Если при
in_place
со значениемTrue
запустить скрипт дважды, то картинки будут сжаты дважды!old_virtual_root
— если в коде скриптов для доступа к файлам используется какой-то префикс, не отраженный в структуре каталогов (например,"mods/"
), следует вписать его сюда. Иначе не будет работать замена путей.new_virtual_root
— если в ходе портирования требуется добавить постфикс, он указывается здесь.exclude_patterns
— шаблоны файлов, которые следует исключить из мода.?
— любой одиночный символ.*
— любое количество любых символов.**
— любые подпапки
Примеры исключений:
**.rpyc
— скомпилированные в байт-код скрипты."**/Thumbs.db
— свойства папки (Windows)**/.DS_Store
— свойства папки (macOS)**._rpy
, # Наши бэкапы приbackup_style
равнымnearby
(старые удаляются, новые создаются).
path_rewrite_rules
— правила по перемещению файлов. Синтаксис:префикс, шаблон, новый_префикс
.Если путь к файлу начинается с указанного префикса и удовлетворяет шаблону, то этот префикс срезается и заменяется новым. Файл копируется/перемещается (в зависимости от
in_place
) в новое место; также переписываются пути в скриптах.WARNING
Правила применяются последовательно, так что порядок объявления важен.
WARNING
Обязательно наличие одного правила:
("/мод/", "**", "/мод/")
. Под это правило попадают все загружаемые в скриптах файлы, но оно ничего не меняет. Необходимо для корректного переписывания путей в коде.extra_files
— дополнительные файлы, которые требуется добавить в мод.WARNING
Обязательно наличие одного правила:
("sprites_lol.rpy", "/")
. Добавляетrpy
с мобильными версиями оригинальных спрайтов.
# Запуск
Запускаем командную строку, перемещаемся в папку с ESTool с помощью cd
, запускаем скрипт: python estool-1.001.py
. Прогресс портирования также отображается. По окончанию нажмите Enter
и закройте ком. строку.
# Заключение
Как уже упоминалось ранее, скрипт неполноценен и некоторые места в коде может не обработать, потому, на всякий случай открываем и внимательно просматриваем свои rpy
на наличие изменений, правим.
# Работа с RPYC и RPA файлами
# "Обфускация" исходного кода
Обфускация или запутывание кода — приведение исходного кода программы к виду, сохраняющему её функциональность, но затрудняющему анализ, понимание алгоритмов работы и модификацию при декомпиляции.
Рассмотрим самый из простых методов обфускации кода. Для удаления исходного кода, но сохранения функциональности достаточно удалить .rpy
файлы, оставив лишь их .rpyc
версии.
# Создание RPA архива
Для создания rpa
архива можно воспользоваться:
# RPATool
WARNING
Необходимо установить Python
(opens new window) версии не младше 3.1
, при установке выберите опцию Добавить Python в PATH
.
- Скачайте файл
rpatool
и положите в удобное для Вас место. - Нажмите ПКМ с зажатым Shift, выберите
Открыть окно PowerShell здесь
. - Введите в консоль (путь без кавычек):
python rpatool -c название_архива.rpa путь_до_папки_с_файлами_без_кавычек
WARNING
Если папок несколько, то разделяйте пробелами, если нужно заархивировать лишь один файл, то не забудьте указать его расширение.
По окончании архивации появится соответствующий RPA архив рядом с файлом rpatool
.
# RenPy
- Установите RenPy удобным для Вас способом, запустите
renpy.exe
. - Создайте новый проект в RenPy, дайте любое имя, любые настройки.
- Перейдите в папку проекта, создайте новый
rpy
файл и откройте его. - Пропишите:
init python:
build.archive("archive", "all") # Создаём новый архив с названием 'archive'
build.classify('game/**', 'archive') # Помещаем все файлы из папки 'game' в 'archive'
2
3
При необходимости можем вместо того, чтобы указывать все файлы, указать конкретные расширения файлов:
init python:
# Изображения
build.classify('game/**.jpg', 'archive')
build.classify('game/**.png', 'archive')
# Музыка
build.classify('game/**.ogg', 'archive')
build.classify('game/**.mp3', 'archive')
# Не добавляем в архив все файлы с расширением .txt в папке и подпапках 'game'.
build.classify("**.txt", None)
2
3
4
5
6
7
8
9
Также можем положить файлы в разные архивы:
init python:
# Создаём архивы
build.classify("images", "all")
build.classify("music", "all")
# Изображения в 'images'
build.classify('game/**.jpg', 'images')
build.classify('game/**.png', 'images')
# Музыка в 'music'
build.classify('game/**.ogg', 'music')
build.classify('game/**.mp3', 'music')
2
3
4
5
6
7
8
9
10
11
Подробнее о параметрах при создании архива здесь (opens new window).
- Переходим обратно в
renpy.exe
, выбираем проект, нажимаемBuild Distributions
. - Выбираем
PC: Windows and Linux
, нажимаемBuild
. - После окончания разархивируем архив с билдом проекта и находим
rpa
архивы.
# Интеграция RPA в БЛ
Создаём rpy
в папке мода с любым названием, прописываем
init -9999 python:
config.archives.append("Путь до rpa архива без расширения")
2
Благодаря этому, наш архив был добавлен в список других архивов, для исключения конфликта с другими возможными rpa архивами из других модов. Пути к файлам после архивации остаются прежними, если Вы сохраняли ту же иерархию папок при архивации.
# Декодирование RPYC
Для декодирования rpyc
файлов Вы можете воспользоваться:
# UnRen
- Скачайте архив и распакуйте bat-ник в директорию
game
. - Запустите bat файл и выберите
Decompile rpyc files
. - По окончанию нажмите любую клавишу для выхода или введите
1
в командную строку, чтобы вернуться.
Будут декодированы все rpyc
в директории game
, включая подпапки.
# UnRpyc
Перейдите в 'releases' и скачайте файл в зависимости от варианта декодирования:
bytecode.rpyb
un.rpy/un.rpyc
Скачайте rpyb
файл, положите в game\cache
(с заменой, если необходимо) и запустите игру.
Или
Скачайте un.rpy
или un.rpyc
, положите в game
и запустите игру.
После загрузки игры и запуска главного меню, все rpyc
файлы, включая rpyc
из модов Мастерской будут декодированы.
# Декодирование RPA
Для декодирования rpa
файлов Вы можете воспользоваться:
- UnRen (opens new window)
- UnRpa (opens new window)
- RPATool (opens new window)
- Game Resources Viewer (opens new window)
# UnRen
- Скачайте архив и распакуйте bat-ник в директорию
game
. - Запустите bat файл и выберите
Extract RPA packages
. - По окончанию нажмите любую клавишу для выхода или введите
1
в командную строку, чтобы вернуться.
Будут декодированы все rpa
архивы в директории game
, включая подпапки.
# UnRpa
WARNING
- Необходимо установить
Python
(opens new window) версии не младше3.1
, при установке выберите опциюДобавить Python в PATH
. - Поддерживается версия Windows не младше Windows 8.
- Установите и разархивируйте в удобное для вас место.
- Запустите
UnRPA Commander.exe
. - Нажмите
Install UnRPA
. - В первом поле укажите полный путь до
rpa
архива. - Во втором поле укажите путь распаковки
rpa
архива. - Нажмите
Extract All
.
# RPATool
WARNING
Необходимо установить Python
(opens new window) версии не младше 3.1
, при установке выберите опцию Добавить Python в PATH
.
- Скачайте файл
rpatool
и положите в удобное для Вас место. - Нажмите ПКМ с зажатым Shift, выберите
Открыть окно PowerShell здесь
. - Введите в консоль (пути без кавычек):
python rpatool -x путь_до_архива.расширение -o путь_до_папки_с_разархивированными_ресурсами`