Everlasting Summer

Everlasting Summer

903 ratings
Уроки моддинга
By HencoDesu and 1 collaborators
Будем учиться создавать свои моды на "Бесконечное Лето"
10
2
   
Award
Favorite
Favorited
Unfavorite
Предисловие
Сразу же оговорюсь, никаких модов в общий доступ я не выкладывал пока, по причине того что сценарист из меня так себе (ИМХО). Я лишь делал небольшие мини моды, которые выкидывались в корзину спустя 1-2 дня после их завершения. В моем руководстве будет лишь теория для Steam версии (совместимость с другими версиями возможна но не гарантированна)
Начинаем творить
Что нам понадобится для создания мода?
Для создания мода нам понадобится:
  • Сама игра, в нашем случае Everlasting Summer
  • Текстовый редактор, я советую использовать Notepad++

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

Начинаем создавать мод
Создаем текстовый файл, с любым названиме и расширением .rpy (Надеюсь вы знаете, как создавать файлы с другими расширениями)
А теперь открываем его нашим текстовым редактором (У меня это Notepad++) и продолжаем вникать в это руководство
Где мой мод? Почему передо мной пустой файл?
Весь моддинг "Бесконечного Лета" заключается в писании магических фраз в файлах .rpy, которые игра будет читать и делать то что мы захотим (но конечно же есть ограничения)

Что за магические фразы? Где их найти?
Подожди, писать заклинания еще рано, сначала нужно понять, как правильно расставлять слова для эффекта

Структура файла выглядит примерно так:
<Блок> <Команды в блоке> <Другой блок>

Команды в блоке ВСЕГДА имеют отступ в 4 пробела относительно команды говорящей нам о начале блока.

Как мне начать блок?
Есть несколько команд начинающих блок, пока стоит лишь запомнить то, что после команды, начинающей блок всегда ставится двоеточие (:)

На данном этапе создания мода нам понадобится лишь одна блоковая команда

label <Название метки>: - Обычно используется для разделения мода на части, для удобной навигации между ними

label vasya_mod_d1: <Что-то происходит> label vasya_mod_d2: <Происходит что-то другое>

Переходы между блоками
Существует 2 варианта перейти от одного блока к другому

Вариант 1 - "Прыжок"

В этом варианте сначала выполняется первый блок, а затем второй. При этом используется команда

jump <Название блока>

Вот уже знакомый нам пример:

label vasya_mod_d1: <Что-то происходит> jump vasya_mod_d2 label vasya_mod_d2: <Происходит что-то другое>

В этом случае если написать в блоке vasya_mod_d1 что либо после jump'a, то игра просто пропустит это

Вариант 2 - "Вызов"

В отличии от прыжка, при использовании этого варианта после полного выполнения блока на который переходит игра, она вернется в первоначальный и продолжит его выполнение после команды. Команда для этого:

call <Название блока>

Ну и как же без примера:

label vasya_mod_d1: <Что-то происходит> call vasya_mod_d2 <Eще что нибудь> label vasya_mod_d2: <Происходит что-то другое>

Окончание блоков, переход к которым осуществляется именно этим методом имеет некоторые особенности, о которых можно узнать дальше

Как закончить блок?

Если к этому блоку ведут jump'ы, то конец блока можно ничем не выделять, если только это не последний блок в вашем моде (Последний блок 1/x концовки). В ином же случае последней командой блока должна быть команда return. Зачем? В случае если это последний блок, чтобы игра могла закончить обработку мода и вернуться в главное меню. Если же на блок привела команда call, то игре просто необходимо знать, когда вернуться в предыдущий блок.

Получается что наш пример call не будет работать и нам придется привести его к такому виду:

label vasya_mod_d1: <Что-то происходит> call vasya_mod_d2 <Eще что нибудь> return label vasya_mod_d2: <Происходит что-то другое> return

Из всего этого можно понять то, что ваш мод запускается именно методом вызова, где блок из которого вызывают - главное меню игры.
Пора бы уже и поговорить
Как мы все знаем "Бесконечное Лето" - это визуальная новелла и весь сюжет в ней разворачивается посредством диалогов персонажей и выборами Главного Героя,

Как же заставить персонажей говорить?
Благодаря движку игры, это было реализовано донельзя просто.
Просто в виде команды пишем следующий текст

<ID говорящего> "<Что он(а) сказал(а)>"

Ковычки обязательны!

Что за ID говорящего?
Все просто, этот ID говорит нам о том, с кем же сейчас ГГ разговаривает

Вот их список:
Имя персонажа в игре
ID персонажа
Мысли ГГ
th
Семен (ГГ)
me

Для текста от автора ID не нужен

Остальных говорящих вы можете увидеть на прикрепленной картинке да, картинка копипаст

Как же это должно выглядеть в файле?
Для примера мы попросим поздороваться каждого из основных говорящих

Кто говорит
Как это писать
ГГ думает
th "Привет"
Семен
me "Привет"
Лена
un "Привет"
Алиса
dv "Привет"
Ульяна
us "Привет"
Славя
sl "Привет"
Мику
mi "Привет"
Юля
uv "Привет"
Электроник
el "Привет"
Шурик
sh "Привет"
Женя
mz "Привет"
Ольга Дмитревна
mt "Привет"
Виола
cs "Привет"
Пионер
pi "Привет"
Маша
ma "Привет"

ID персонажей без определенного имени (Для использования пока имена персонажей не известны):
Кто говорит
Как это писать
Парень
mep "Привет"
Пионерка (Лена)
unp "Привет"
Пионерка (Алиса)
dvp "Привет"
Пионерка (Ульяна)
usp "Привет"
Пионерка (Славя)
slp "Привет"
Пионерка (Мику)
mi "Привет"
Странная девочка (Юля)
uvp "Привет"
Пионер (Электроник)
elp "Привет"
Пионер (Шурик)
shp "Привет"
Пионерка (Женя)
mzp "Привет"
Вожатая (Ольга Дмитревна)
mtp "Привет"
Медсестра (Виола)
csp "Привет"
Как украсить речь персонажей?
В игре вы встречались с тем, что некоторые слова во фразах персонажей были как-то выделены или вовсе были в ковычках. Для этого используются специальные теги.

Код
Результат
Одно из слов будет написано {i}курсивом{/i}
Одно из слов будет написано курсивом
А здесь будет {b}жирный{/b} шрифт
А здесь будет жирный шрифт
Этот текст {w}Будет написан {w}По частям
Стим не позволяет продемонстрировать подобное
{s}Это мы не должны видеть{/s}
Это мы не должны видеть

Как мы уже знаем, ковычки ограничивают реплики персонажей, так как же нам использовать их внутри этих реплик?

Чтобы ковычки не учитывались игрой, перед ними нужно поставить \
Как мне показать где происходят действия героев?
В самой игре при смене местоположения нашего ГГ меняется и картинка на фоне (bg)
Так как же нам показать где сейчас наш герой?

А делается это при помощи команды scene bg <Название фона>

Например:
scene bg bus_stop #Покажет нам автобусную остановку из времени Семена scene bg int_bus #Внутри автобуса, привезшего нас в "Совенок" scene bg ext_bus_night #Снаружи этого же автобуса, но уже ночью

Все bg из игры -> Ссылка[drive.google.com]

Так же в архиве приложен текстовый файл из которого сразу можно скопировать нужную строку

А как мне показать персонажей?
Персонажи в игре - не что иное, как тоже картинки, только именуются они спрайты.
Перечислять их все на буду, но скажу, что их более 350

Вызываются все спрайты командой show <Имя спрайта>

Имя спрайта обычно состоит из нескольких слов, разделенных пробелами

<имя персонажа> <эмоция> <одежда>

В оригинальной игре имя персонажа совпадает с ID говорящего из предыдущего раздела этого руководства

Например:
show dv angry pioneer #Злая Алиса shov un cry sport #Смущенная Лена в спортивной форме

И так далее

Список всех спрайтов -> Ссылка[drive.google.com]

Если персонаж уже на экране, то повторное использование show будет менять эмоцию и/или одежду

Что можно сделать со спрайтами?
При простом использовании show <Спрайт> он будет появляться просто по центру, это можно исправить добавив в конец at <Позиция>

show <Спрайт> at <Позиция>

Всего в игре 7 позиций где может находиться спрайт:
fleft, left, cleft, center, cright, right, fright

На приведенном скриншоте были использованы команды:
scene bg ext_bus_night show dv angry pioneer2 at left show un smile pioneer at right show mi cry_smile pioneer at cleft show sl serious pioneer at cright show mt rage panama pioneer at center

Так же можно показать персонажа ближе\дальше. Для этого можно воспользоваться атрибутом close/far

На втором скриншоте как раз были использованны эти атрибуты. Команды:

scene bg ext_bus_night show dv angry pioneer2 far at left show un smile pioneer far at right show mi cry_smile pioneer at cleft show sl serious pioneer at cright show mt rage panama pioneer close at center

Как убрать персонажей с экрана?
Для того, чтобы убрать персонажа воспользуйтесь

hide <Имя персонажа>

Если вы хотите вслед за этим сменить декорации, то прописывать hide для каждого персонажа не обязательно, команда scene сама их уберет

А что делать, если я хочу картинку с уже нарисованным на ней персонажем?
Тут принцип как и с bg, только надо использовать scene cg

Все cg со списком -> Ссылка[drive.google.com]

Примеры думаю не нужны.
Как можно украсить спрайты, bg и cg
Мы можем показать спрайты, bg и cg с некоторым замедлением, плавно

Так же есть еще несколько эффектов, о которых речь пойдет далее, некоторые из эффектов можно применить не только к изображениям, но и даже друг к другу!

Плавность
Чтобы показать наши картиночки более красиво для человеческого глаза, мы можем использовать специальный атрибут. Это будет выглядеть примерно так:

scene bg <Название bg> with <Атрибут>

Атрибутов для плавности 6, они отличаются лишь своей скоростью.
dspr - 0,2 сек - Самый быстрый, на практике не особо заметен
dissolve - 1 сек - Средняя скорость, считаю оптимальной для смены cg на bg и наоборот и для эмоций спрайтов
dissolve2 - 2 сек - Самая плавная картинка, считаю хорошим вариантом для переходов между локациями лагеря
dissolve_fast - 0.5 сек.
hell_dissolve - 50 секунд - на практике не особо применим, но вдруг пригодится.
dissolve_long - 100 секунд.

Так же можно группировать несколько обьектов для одновременного начала эффекта

scene bg ext_bus_night show sl smile pioner far with dissolve2

В приведенном примере мы попадем в ночной автобус и перед нами предстанет улыбающаяся Славя, и все это с задержкой в 2 секунды.

Так же атрибут плавности может применяться к другим эффектам.

Если все вышеприведённые примеры Вас не устраивают, можно добавить свой атрибут плавности. Для этого, пропишите его в блоке init.

init: $ trisekundi = Dissolve(3.0)

После этого мы можем использовать наш переход, так-же, как и все остальные.

scene bg ext_bus_night show sl smile pioner far with trisekundi

Моргание
Я более чем уверен, что вы видели эффект того, как иногда ГГ моргает или вовсе закрывает глаза. Мы можем реализовать подобную возможность!

show blink - Закрыть глаза
show unblink - Открыть глаза
show blinking - Моргание

Будьте осторожны: blink и unblink это разные эффекты, они не могут отменить друг друга

Как открыть глаза:
show blink <Ваши события> hide blink show unblink

Так же к эффектам моргания можно применить атрибут плавности.
Больше о изображениях и их появлениях.
Свои изображения.

Вполне может быть, что по сюжету Вашего мода, может не хватить имеющихся БГ, ЦГ и спрайтов. В таком случае, мы добавим свои. Где искать картинки, спрайты и т.д. - разбирайтесь сами, но вот что с ними делать дальше...
Для начала нам надо объявить изображение в блоке init. Делается это, с помощью объявления переменной image. Покажем на примере. Допустим, мы нашли изображение с видом города и называется оно у нас gorod.jpg Для его объявления, пропишем такую команду:
image gorod = "gorod.jpg"
(Прим.: При условии, что изображение лежит в папке game. Если оно лежит в другом месте, например в папке вашего мода, который в свою очередь находится в папке mods, объявление изображения будет выглядеть так:
image gorod = "mods/nazvanie_moda/gorod.jpg" )
Теперь мы можем использовать имеющееся изображение так-же, как и остальные:
scene gorod with dissolve
или
show gorod with dissolve


Свои положения на экране.

Если Вам не хватает стандартных вышеперечисленных команд (cleft, center, fright и т.д.) на положение изображения на экране - не беда. Здесь поможет встроенный в РенПи язык - ATL. Для его использования надо сделать следующее:
Вместо команды at, мы пишем после изображения двоеточие и параметризируем его по следующим командам:
anchor(a, b) - якорь, от которого будут отсчитываться прочие коодинаты. Задаётся десятичными долями.
pos(a, b) - Положение на экране, относительно якоря. Задаётся, как десятичными долями, так и координатами в пикселях.
xpos a - координата горизонтальной оси, так-же задаётся, как десятичными долями, так и координатами в пикселях. Не используется вместе с pos.
ypos a - координата вертикальной оси. Свойства, как и у xpos.
align(a, b) - Положение на экане, относительно якоря и собственного размера изображения.
xalign и yalign - аналогично предыдущему примеру.
Для начала этих трёх команд нам хватит, с их помощью мы сможем разместить изображение в любом месте экрана.
Покажем на примере.
Разместим изображение нашего города ровно по центру экрана. Для этого мы поставим якорь на середине экрана, и укажем позицию.
show gorod: anchor (0.5, 0.5) pos(0.5, 0.5)
Что за странные циферки? Ничего не понятно!
Сейчас объясним.
Возьмём наши координаты pos(0.5, 0.5), где первая цифра - xpos (положение по горизонтали), а вторая ypos (положение по вертикали).
Весь экран условно делится на части, где 0.0 - крайняя левая часть, а 1.0 - крайняя правая (по аналогии верхняя и нижняя). Соответственно, наше 0.5 - это середина. Назревает вопрос. Можно ли использовать отрицательные числа, и числа больше одного? Да. Но в этом случае изображение будет вылезать за пределы экрана.

У align назначение похожее, но немного отличается. Этот элемент, помимо указанных координат, использует собственный размер изображения. Для примера:
Если при якоре (0.5, 0.5) мы зададим позицию pos(1.0, 0.5) - у нас пропадёт половина изображения, ибо точкой его появления будет указан край экрана. С align ситуация обстоит иначе. При использовании align(1.0, 0.5) изображение прижмётся к краю экрана, но не исчезнет.

При назначении позиции координаты pos и align можно комбинировать.
Давайте, для примера выведем спрайт улыбающейся Мику слева экрана.
show mi smile pioneer far: anchor (0.5, 0.5) xpos 0.33 yalign 1.0

Так-же мы можем заранее назначать позиции. Давайте повторим предыдущий пример, но назначим всё заранее. Для этого реализуем переменную transform в блоке init:
transform sleva_na_ekrane: anchor (0.5, 0.5) xpos 0.33 yalign 1.0
После этого мы можем использовать её, так-же, как и остальные.
show mi smile pioneer far at sleva_na_ekrane

Что ещё может ATL?

Очень и очень многое. Допустим, анимации.
Вот стоит у нас слева на экране Мику, объявленная в прошлом блоке, но вдруг появилась Ульяна, и Мику из вежливости решила подвинуться чуть правее. Как мы это сделаем? Можно просто задать координаты положения, и Мику "телепортируется" туда, но разве это красиво? Не. У нас другие методы.

Смена положения.
Для смены положния существует 4 метода: linear, ease, easein, easeout. Для начала нам понадобится только linear. Как он работает? Очень просто. После linear мы пишем время в секундах, а после новые координаты в системе ATL.
Пример. Созданим перемещение к правому краю экрана:
transform peremeshenie: linear 1.2 xpos 0.7
Теперь добавим это в наш код.

show mi smile pioneer far at sleva_na_ekrane with dissolve mi "Привет, как дела?" show mi smile pioneer far at peremeshenie mi "Ой, Ульяна, я тебя не заметила. Давай я подвинусь."

В одной трансформации можно создавать несколько анимаций, а так-же зацикливать их. Для зацикливания используется команда repeat и после неё пишется количество повторов. Если число не указано, повторы будут бесконечно.
Например. Добавим такую трансформацию:
transform tuda_syda: linear 1.0 xpos 0.3 linear 1.0 xpos 0.7 repeat

И импортируем её в код:

show mi smile pioneer far at sleva_na_ekrane with dissolve mi "Привет, как дела?" show mi smile pioneer far at peremeshenie mi "Ой, Ульяна, я тебя не заметила. Давай я подвинусь." show mi smile pioneer far at tuda_syda mi "А теперь мне что-то побегать захотелось."
Как добавить звук?
Наверное вы и сами слышали, что в "Совенке" никогда не бывает тихо, где-то играет приятная музыка, иногда мы слышим стуки в двери, три раза в день, звук горна собирает всех обитателей у столовой.

Добавление фоновой музыки
Для того чтобы проигрывания музыки используется всего две команды

play music music_list["<Название>"] - Начинает проигрывать указанную музыку
и
stop music - Завершает проигрывание музыки

Список всей фоновой музыки в игре -> Ссылка[drive.google.com]

Послушать эту музыку можно прямо в игре, зайдя в раздел Галерея

Прочие звуки
Для проигрывания прочих звуков нам понадобится все та же команда play, только немного в другом виде

play ambience ambience_<Название> - Игра включает нам выбранный звук
и
stop ambience - Выключает его

Список этих звуков -> Ссылка[drive.google.com]

Увы, подобрать нужный звук вам поможет лишь базовое знание Английского языка и "метод научного тыка"
Время усложнять мод!
Все что мы узнали раньше позволяет нам писать лишь статичные моды, в которых от игрока ничего не зависит. Теперь же нам пора добавить игроку возможность выбора

Переменные
Если вы хотите, чтобы игра запоминала каждый выбор игрока, то без переменных нам не обойтись.

Объявление переменных происходит в специальном блоке init. Имена и значения у переменных могут быть любые, но рекомендуется использовать короткие английские слова или цифры (цифры только в значении)

init: $ choise = False # Переменная будет объявлена со значением False $ Count = 0 # А у этой переменной будет значение 0
Изменение значения переменных будет выглядеть так:

... $ shoice = True $ Count += 1 ...

После выполнения данных команд переменная "choice" будет иметь значение "True", а переменная "Count" увеличит свое значение на единицу.

Выборы
Если вы хотите дать игроку выбор, то вам необходимо использовать специальный блок menu:

mt "Возьми-ка этот мешок с сахаром" menu: "И куда мне его девать?": $ good += 1 jump good_label "Да идите вы со своим сахаром на ...": jump bad_label

В приведенном примере Ольга Дмитриевна попросит нас взять мешок с сахаром, мы же можем как подчиниться и увеличить переменную "good" на 1, так и отказаться, причем в зависимости от нашего выбора события в игре могут измениться

Будьте осторожны: Варианты ответа тоже открывают блок, и если мы не поставим после каждого двоеточие, мод может не запуститься

Проверка условий
Что нам делать если мы хотим чтобы какие то из возможностей были у игрока в зависимости от его выборов? Для этого то мы и использовали переменные! Сейчас же мы воспользуемся специальной конструкцией
if good > 0: jump good else: jump bad
Поясню данный отрезок. Если значение переменной "good" больше нуля, то игра продолжится на метке "good", если же нет, то мы переходим на метку "bad"

Теперь же мы постараемся реализовать выборы, в которых в зависимости от прошлых выборов персонажа будут добавляться или убираться различные варианты ответов

... mt "Семен, сегодня после обеда ты будешь убираться в столовой" menu: "Почему именно я?": jump why_me? "Я же уже помог вам сегодня" if good > 0: jump help "Не намерен я вам тут прислуживать!" if good == 0: jump angry

В данном случае мы можем либо возмущаться сложившейся ситуации, если мы уже заслужили доверие вожатой, мы можем попросить ее отсрочить дежурство или если не помогали отправить ее куда подальше. И в каждом случае нам, как создателям мода необходимо будет прописать что произойдет в каждом из этих случаев
Использование карты
Иногда по нуждам сюжета необходимо дать игроку выбор куда ему пойти, использование для этого обычного меню выбора выглядит несколько не эстетично, так давайте же научимся ориентироваться в "Совенке" при помощи карты!

Чтобы дать игре понять. когда развернуть перед игроком карту необходимо всего несколько простых команд.

Во первых:

$ 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" - "о. Лес"



т.е. чтобы при нажатии на клубы мы прыгали на лейбл mymodlabel2 (название, примера ради) нужно реализовать такую конструкцию:

$ set_zone("clubs", "mymodlabel2")

И в конце, выводим саму карту командой:

$ show_map()

Показываю пример полностью. Допустим нам нужны три зоны. Сцена, Муз. клуб и Пляж, и каждая ведёт к совим лейблам label1, label2 и label3, для этого мы делаем всё то, что я уже описал выше:

$ disable_all_zones() $ set_zone("estrade", "label1") $ set_zone("music_club", "label2") $ set_zone("beach", "label3") $ show_map()

Как-то так.
Заселяем лагерь
Вполне возможно, что вашем моде вам понадобится персонаж, которого по какой-то причины разработчики не стали заселять в лагерь, что же делать в этом случае? Правильно создать его!

Любой персонаж игры - простая переменная, с которой мы вольны делать что захотим (*зловещий смех*)

Переменные создаются двумя способами, методом движка - с помощью команды define и методом "Питона" - с помощью символа - $.

Далее мы присваиваем переменной свойство Character().
Для примера создадим Вашего покорного слугу:

define vladya = Character(u"Владя")
(прим.: Символ u используется, для отображения русского текста у людей, у которых он не установлен в системе.)

Теперь мы можем использовать переменную vladya в своём моде. Давайте, я поздороваюсь с Вами:
vladya "Привет"

Но стоп! Что же мы видим? У всех персонажей игры есть свой цвет, а наш персонаж белый. Некрасиво! Надо исправить. Но как-же это сделать? С помощью параметризации свойства Character у нашей переменной.
Так давайте же это сделаем! Цвет имени персонажа указывается с помощью параметра color, так-же рекомендую использовать неизменный параметр what_color, для изменения цвета речи персонажа. В самой игре, все персонажи говорят цветом f1d076, так не будем выделяться. Назначим нашему персонажу в качестве цвета имени, скажем, зелёный цвет (008000) и установим в качестве цвета речи - f1d076:

define vladya = Character(u"Владя", color="#008000", what_color="#f1d076")

И давайте я вновь поздороваюсь с Вами:
vladya "Привет"

Намного лучше, не правда ли?

Ух ты. Столько крутых штук с именем. Хочу ещё!
Окей, окей. Без проблем.

Допустим наш персонаж пересмотрел Ваномаса и теперь после каждого предложения говорит "ёпты блин" (пардоньте, в Стиме цензура, оригинал не работает), можно конечно прописывать после каждой строчки это замечательное словосочетание, а можно использовать команду what_suffix. Давайте дополним переменную:
define vladya = Character(u"Владя", color="#008000", what_color="#f1d076", what_suffix=u", ёпты блин.")
Что мы напишем
Что увидим в игре
vladya "Привет"
Привет, ёпты блин.

Одинаковая фраза, после каждой реплики - это не круто. Хочу больше!
Окей. Организуем.

Для начала реализуем перед именем вот такую конструкцию:
init: # Ваши переменные и пр. python: vano = "" vano2 = [", ёпты блин.", ", мазафака бич!", "... Воооооот!"] def vanomas(): global vano vano = renpy.random.choice(vano2) vanofun = renpy.curry(vanomas) vanomas()
Эта функция создаёт переменную vano, которая содержит случайно выбранную из списка фразу. Далее используем, уже известную нам команду what_suffix и дополняем переменную имени:
define vladya = Character(u"Владя", color="#008000", what_color="#f1d076", what_suffix=u"[vano]")
Используя эти настройки, РенПи выберет случайную фразу из списка, после реплики персонажа. Но! На данном этапе случайная фраза будет одна. Как нам это побороть и заставить движок менять фразы, после текста? Очень просто. После блока init мы реализуем следующую конструкцию:
screen scr123: on "show" action vanofun() timer 0.1 action [Hide("scr123"), Show("scr123")]
И после начала нашего мода прописываем:
show screen scr123
Этой командой мы будем обновлять значение переменной vano, каждую 0.1 секунду.

И что-же будет теперь:

Что мы напишем
Что увидим в игре
vladya "Привет"
Привет, ёпты блин
vladya "Как дела"
Как дела, мазафака бич!
Монитор с номером дня.
И вот уже весь лагерь, включая нашего подопечного уснул. Несомненно вы видели, как в оригинальной игре о начале нового дня нас оповещали даже. не будящие нашего протагониста лучи солнца, а простой монитор компьютера, показывающий нам сколько времени мы провели в этом дивном месте. Чем же мы хуже, давайте сделаем себе такой же монитор!

Для выведения на экран монитора, необходимо прописать две команды:

$ backdrop = "days" $ new_chapter(1, u"Мой мод. День первый.")

Где:
backdrop - фон с монитором.
1 - номер дня, который будет показан на мониторе,
Текст - то, как будет называться сохранение.
Фонов (backdrop) в игре 5:

$ backdrop = "days" # Просто монитор. $ backdrop = "un" # Монитор с проплывающей Леной. $ backdrop = "us" # Монитор с проплывающей Ульяной. $ backdrop = "sl" # Монитор с проплывающей Славей. $ backdrop = "dv" # Монитор с проплывающей Алисой.
А как-же ачивки?
Вы 100% видели, как в оригинальной игре да и некоторых модах, при прохождении концовок появляется картинка а-ля "Achivement Complted" И хотели бы в свой мод такую же.

Для этого в нужном вам месте вставьте следующие команды

play sound sfx_achievement show myachiv at achievement_trans with dspr $ renpy.pause(3, hard=True) hide myachiv
Где "myachiv" - Ваша картинка с ачивкой.
Ну, вот и всё. Ачивка выведена.

А если ачивок слишком много?

Нет. У меня есть моё личное правило: если какой-то код периодически повторяется - я пишу под него функцию. Ибо удобно.

К слову, в БЛ вывод ачивок реализован именно так, но оригинальная функция нам не подойдёт, ибо она подогнана только под уже заложенные ачивки "Лета", так что нам нужно немного её переделать, под более универсальные нужды.

Для этого, реализуем следующую конструкцию в блоке питона.

init python: def achiv_for_my_mod(pic): renpy.play(sfx_achievement) renpy.show(pic, [achievement_trans], layer="overlay") renpy.pause(3.5) renpy.hide(pic)

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

$ achiv_for_my_mod("myachiv")

Где, опять же, "myachiv" - Ваша картинка с ачивкой.

P.S.: Название функции "achiv_for_my_mod" дано, для примера, и его можно и нужно менять. т.к. если функция, с одним и тем же названием, дважды (или больше) встретится в разных модах - будут конфликты.
Полезные советы
1. Используйте уникальные имена
Старайтесь в своем моде задавать уникальные имена блоков и функций, иначе игра не будет знать куда же ей переходить и что выполнять, что зачастую черевато вылетом

2. Старайтесь продумать сценарий раньше написания самого мода
Большинство модов, сценарий которых пишется одним человеком-разработчиком мода, да еще и в процессе написания самого мода, забрасываются на очень ранних этапах. Не советую вам начинать писать мод, не имея сценария, иначе это может ударить по вашей самооценке.

Если вам прямо не терпится создать мод, а сценария нет, загляните на "Книгу Фанфиков[ficbook.net]", там вы вполне сможете найти себе сюжет по душе, только свяжитесь с автором фанфика и узнайте, согласен ли он на создание мода по его творчеству или нет
Исправляем ошибки в моде
Вполне возможно, что во время написания мода вы могли что-то где-то не так сделать и теперь у вас выдает ошибку, давайте разберемся в самых частых ошибках.

Tab characters are not allowed in Ren'Py Scripts
Решение: Проверьте свой мод на то что везде у вас отступ не Tab, а 4 пробела

is not terminated with a new line (Check strings and parenthesis)
Решение: Обычно при этой ошибке еще и указан номер строки, проверьте, закрыли ли вы ковычки на этой строке

identation mismatch
Решение: Проверьте, везде ли отступ по 4 пробела

expected statement
Решение: Проверьте команду в указанной строке

could not find label '<Название блока>'
Решение: Проверьте label и jump/call на наличие опечаток

Пишите возникающие у вас ошибки и решения будут добавлены сюда
Прочее
Как заставить игру видеть мой мод?
Писать мод. не имея возможности самому его запустить и протестировать - по меньшей мере глупо.

Для того чтобы игра увидела ваш мод просто обьявите в init: блоке следующую переменную

$ mods["<Mod ID>"] = u"<Название мода>"

Где:
MOD ID - Любое английское слово
Название мода - То, какое вы хотите видеть в меню игры

Проверьте, что ваш мод начнется с метки с тем же названием, что и Mod ID

Теперь, положив ваш .rpy файл в Everlasting Summer/game вы сможете запустить ваш мод, так же как и любой другой
Полезные вещи для написания мода
1. Быстрое объявление большого числа картинок
У вас в моде много картинок и вам не охота тратить 100500ч времени на прописывание их в файле мода? Вам поможет данное видео:
(Автор видео - Владя)

Преимущества:
  • Вам не нужно отдельно прописывать все файлы
  • Потенциально может сработать не только с изображениями, но и с музыкой

Недостатки:
  • Имя файла задается по строго определенному алгоритму и если изображения предварительно были названы "как попало" то в получившихся именах "без бутылки и не разберешься"

2. Телефон в игре
Хотели использовать в своем моде возможность самостоятельно выбирать игроком музыку? Пришли к тому выводу, что лучший выбор - телефон / mp3 плеер , а делать его реализацию на Ren'Py весьма муторно? Обрадую вас, такая возможность уже реализована самым "прошаренным" в вопросах Ren'Py человеком в этом гайде - Владей

Скачать и посмотреть этот телефон можно по ссылке - Телефон[drive.google.com]

Весь код снабжен комментариями и должен быть понятен
Телефон выполнен в виде отдельного мода, но при желании его можно вытащить из .rpy файла и использовать у себя (Не забывайте про Полезный совет №1)

Преимущества:
  • Готовая реализация переключения музыки прямо в игре.
  • Возможность настроить внешний вид телефона

Недостатки:
  • На мой взгляд несколько "не эстетичная" кнопка "Достать телефон" (Можно допилить до ума)
  • При открытии телефона плейлист автоматически будет прокручен до самого низа


Раздел был написан Автором руководства, с использованием контента от Владя, с его личного разрешения.
Послесловие
Данное руководство еще не завершено, на данный момент в нем есть все необходимое для создания небольшого мода. Руководство будет дополняться.

Благодарности:
Команде Sovet Games - За создание столь прекрасной визуальной новеллы
Владя - Автору нескольких интересных модов, за помощь в дополнениии данного руководства
🔰 Лена 🔰 - за помошь в коментариях всем, кто столкнулся с затруднениями

Полезные ссылки:
Все используемые в руководстве ссылки -> Ссылка[drive.google.com]

Задавайте в комментариях свои вопросы, в процессе ответов на них, руководство будет дополняться
1,486 Comments
Kuzm1ch 8 Dec @ 7:40am 
Всем КУ! Я Kuzm1ch - юный мододел, пока что я пишу мод про Алису Двачевскую.
Мод готов на 50%, можете накинуть в профиль идеи и предложения, а так же поддержать.
Буду рад любой поддержке и идее!
Спасибо за просмотр.
Дядя Серёжа 1 Sep @ 2:44am 
А что за ошибку пишет? По идее, правильно всё.
hYsteria 1 Sep @ 1:31am 
ошибку выдает конкертно на $ disable_current_zone() строку
hYsteria 1 Sep @ 1:29am 
как сделать обход зон единоразовым? т.е. у меня в коде попытка это реализовать такая:
<оформление карты задача зон и тд>
label HELP:
if x == 3:
jump HELP_2
else:
$ show_map

label HELP_MUSIC_CLUB:
"Музыкальный клуб"
$ x += 1
$ disable_current_zone()
jump HELP
и аналогичный код на каждую зону. но выдает KeyError: u'error'. Прошу помощи,закину очков,или игру дешевую
михалыч 7 Jul @ 9:14am 
а как заблокировать изменение размеров окна и установить принудительно разрешение 800х600?
КЛЮЧ НА 9 31 Oct, 2023 @ 2:47pm 
Как работать с приближением фона? Я хочу приблизить фон в центр, дабы мой персонаж приблизился к центру комнаты, но я не знаю вычислений координат в системе БЛ. Я не знаю что делать.
Lefinser 30 Aug, 2023 @ 1:53pm 
Отличное руководство!
Dark Light 22 Aug, 2023 @ 9:47am 
ID персонажа mep не работает. Выдаёт ошибку. К примеру ID персонажа unp (Лена) работает. Что делать?
Carovorax 2 Jul, 2023 @ 8:23pm 
Не подскажете как свой звук в игру вставить? Подсмотрел в моде на русскую озвучку, но никак не работает звук, если заменить. Переписывал в файле самого дня, переписывал в папке с озвучкой, не знаю уже что делать.
AkkuChan 25 Jun, 2023 @ 6:50am 
RomanWerki, использовать zoom из ATL.
Пример на анимации объятия.

show sl smile pioneer:
____subpixel True # чтобы не было дёрганным
____align(0.5, 0.5) # зумим из центра спрайта
____ease 1.0 zoom 1.2 # в течение 1 секунды приблизится
____pause(0.5) # ждём полсекунды
____ease 1.0 zoom 1.0 # в течение 1 секунды возвращаемся в исходное положение