Лето, Советы и (не)много кода
Блог по моддингу Бесконечного Лета Официальный новостной портал мода «Советские будни»
Страницы
Гайды по моддингу
Команда «init:» создаст наш блок.
Пришла пора назвать наш мод и сделать запуск из меню «Моды и пользовательские сценарии».
Чтобы наш мод шёл плавно и без проблем, необходимо, чтобы из каждого блока можно было попасть в следующий. Для кинетических модов (моды, которые не имеют выбора и движутся по одной сюжетной линии) вообще не обязательно иметь более одного блока, но можно использовать несколько для красоты.
После этого урока ты уже сможешь написать кинетический мод со встроенными материалами.
Создаём наш запускаемый блок:
Едем дальше. Теперь ты можешь писать любой текст, включать любую музыку и вставлять любые картинки. Как? Очень просто!
Выглядеть это будет так:
Комментарии в коде можно оставлять с помощью #. Движок игры пропускает всё, что написано после этого символа и сразу переходит на следующую.
Ты уже достаточно потренировался с линейным моддингом, но хочется чего-то большего?
Добро пожаловать во второй урок!
Но до этого надо исправить парочку недочётов: остановим музыку.
После указания персонажа, эмоции и типа одежды указываем, за кем должен стоять персонаж. В данном случае на экране у нас только Славя, поэтому пишем behind sl. Если ты используешь far или close, то команда behind должна стоять после. Но обязательно перед with-командой (или at, если она есть).
Источник
Как писать мод на бесконечное лето
Текстовой редактор нужен для работы с командами которые мы будем прописывать в наш мод.
Есть два блока. init и init python(Питон).
Все диалоги, bg, cg, sprites и music, короче всё что связано с сюжетом, прописывается после команды label
По сути своей это команда используется для разделения мода на части.
$ mods [«это_лэйбл»] = u»ЗДЕСЬ ВПИСЫВАЕМ НАЗВАНИЕ МОДА»
$ style.инициал_txt = Style(style.default)
$ style.инициал_txt.font = «путь к шрифту»
$ style.инициал_txt.color = «цвет»
$ style.инициал_txt.size = размер
$ style.инициал_txt.drop_shadow = []
$ style.инициал_txt.drop_shadow_color = «#000»
$ style.инициал_txt.kerning = 1
jump label_название лэйбла
(jump через 4 пробела)
Он нужен для совершение так сказать прыжков между одним и другим днём, то есть.
Полезной вещью для вас будет файл lists, в котором находиться все названия бг, цг и т.п из оригинальной игры.
Для того чтобы персонажи вели диалог есть ID персонажей.
scene bg название_фона
Также команда scene используется не только на bg, но и на cg.
Также как и бг, спрайты из оригинальной игры находятся в том файлике, который я кинул в один из разделов.
Всего в игре 7 позиций у спрайтов:
fleft, left, cleft, center, cright, right, fright
Прописывается так:
show dv smile pioneer2 at left
Спрайт Алисы появиться слева.
Работает так:
hide имя персонажа
$ persistent.sprite_time = «время суток, которое нам нужно»
$ время суток, которое нам нужно_time ()
Прописывают их около bg, cg и спрайтов так:
scene bg(cg) название бэграунда with один из видов плавности
Если вы будете добавлять что либо в больших количествах советую использовать # он разделяет определённый места в init-блоке:
Также аббревиатура нужна для того чтобы сокращёно вписывать добавленные вами изображения, музыку, персонажей и спрайты.
$ Аббревиатура имени = Character (u’Имя в игре’, color=»Цвет имени», what_color=»Цвет диалога»)
image аббревиатура = «Путь к изображению»
$ аббревиатура = «Путь к музыке»
Со звуками и амбиенсами работает так же.
image аббревиатура = «Путь к спрайту», учтите время на него не влияет.
Дело в том что автоматически при включении команды persistent.time они не будут менять цвет при смене суток, так что для каждых времени суток придётся прописывать спрайт.
Если кто знает способ получше кидайте в комментарии.
Переменные нужны для того, чтобы игра запоминала каждый выбор игрока
Вызов переменных происходит во всем уже известном init-блоке. Имена и значения у переменных могут быть любые, лучше использовать короткие английские слова или цифры (цифры только в значении).
После выполнения данных команд переменная «choice» будет иметь значение «True», а переменная «Count» увеличит свое значение на единицу.
Для того чтобы предоставить игроку выбор мы создаём блок menu.
В данном примере Ульяна называет гг дураком, главный герой, может сказать, как джентельмэн просто сказать нет, не вестись на провокации Ульяны и увеличить «good» на 1, так и сказать ей что она дура и приблизиться к плохой концовке.
Можно задать условии при котором выбор игрока будет влиять на последующие варианты.
Этот отрезок показывает, если значение переменной «good» больше нуля, то игра продолжится на метке «good», если же нет, то мы переходим на метку «bad».
Теперь отталкиваясь от прошлых выборов гг будут добавляться или убираться различные варианты ответов.
В этой ситуации есть три варианта. Первый вариант, если мы ничего не совершили с Алисой. Второй вариант, если мы оказали Алисе помощь. Третий вариант, если мы с Алисой были грубы.
С картой разобрались поехали дальше!
$ backdrop = «days»
$ new_chapter(1, u»Мой мод. День первый.»)
$ renpy.movie_cutscene(«Путь к видео»)
Прописываем сразу в лэйбле
Существует два вида пауз renpy.pause и просто pause
show prologue_dream (показать)
hide prologue_dream (скрыть)
Если вы хотите запретить игроку перематывать игру назад, воспользуйтесь функцией:
$ renpy.block_rollback()
Я брал самые интересные команды для вашего мода, так что пользуйтесь, но если вам их не достаточно можете взять информацию с таких ссылок как:
Уроки моддинга
Как создать свой мод для игры Бесконечное Лето [vk.com]
Если хотите изучить азы и не копаться в моём руководстве то вам подойдёт такая ссылка:
Как сделать и выложить мод для игры «Бесконечное Лето»
Источник
Как писать мод на бесконечное лето
16 лет, имеете хотя бы какие то представления о программировании, умеете отличать целые числа от долей, знаете что такое папки и хотя бы примерно представляете как работает RenPy, тогда можно продолжить, иначе лучше закрыть эту страничку.
Как мы знаем, чтобы портировать мод на андроид, нам нужно запихать все его содержимое в одну папку и поменять все размеры и позиции на 2/3 от данного.
ESTool попробует помочь вам заменить позиции(в почти всех их вариациях), размеры картинок(например спрайтов), координаты представленные 4-мя значениями и аргументы к функциям(достаточно спорно) и изменит размеры всех картинок.
Что (еще) не умеет:
Изменять размеры записанные в переменных
Кучу, но существенно поменьше
Если вы хотите помочь разработке, то можете писать в комментарии строчки где возникла ошибка или где скрипт сделал что-то не так.
. Внимание, вышла новая версия.
Скрипт сейчас на 19.01.19 находится на версии 1.001
За которую бесконечная благодарность Николаю Букрееву
Патчнот:
0.006
Работа с юникодом
Поддержка отрицательных чисел
0.007
Откат юникода
Фиксы выбора чисел
Добавление конфига настроек
Добавление бэкапа (варианты работы в конфиге)
Добавлен выбор в конфиге изменения комментария измененной строки
1.001
• Исправлен баг, из-за которого не менялись координаты, если ключевое слово было написано после числа вплотную к нему, без пробела (например, «zoom 1.05anchor (100, 200)»).
• В лог теперь пишется версия скрипта.
• добавил вывод версии скрипта в лог и перенес объявления классов под константы.
Источник
Как писать мод на бесконечное лето
Как сделать выбор имени игроком.
label инициал_shoosing_name:
call screen инициал_input
if _return:
инициал_check_name(_return, ‘инициал_shoosing_name’)
pname = _return.title()
return
в рандомном месте нужно вписать этот лейбл
screen инициал_input: # инпут имени
modal False
window:
id ‘window’
background None
$ timeofday = persistent.timeofday
if (persistent.font_size == ‘large’):
imagebutton:
action ShowMenu(‘text_history’)
auto (get_image(((‘gui/dialogue_box/’ + timeofday) + ‘/backward_%s.png’)))
xpos 38
ypos 924
add (get_image(((‘gui/dialogue_box/’ + timeofday) + ‘/dialogue_box_large.png’))):
xpos 174
ypos 866
imagebutton:
action HideInterface()
auto (get_image(((‘gui/dialogue_box/’ + timeofday) + ‘/hide_%s.png’)))
xpos 1508
ypos 883
imagebutton:
action ShowMenu(‘save’)
auto (get_image(((‘gui/dialogue_box/’ + timeofday) + ‘/save_%s.png’)))
xpos 1567
ypos 883
imagebutton:
action ShowMenu(‘game_menu_selector’)
auto (get_image(((‘gui/dialogue_box/’ + timeofday) + ‘/menu_%s.png’)))
xpos 1625
ypos 883
imagebutton:
action ShowMenu(‘load’)
auto (get_image(((‘gui/dialogue_box/’ + timeofday) + ‘/load_%s.png’)))
xpos 1682
ypos 883
imagebutton:
action Skip()
auto (get_image(((‘gui/dialogue_box/’ + timeofday) + ‘/forward_%s.png’)))
xpos 1768
ypos 924
input default «»:
xpos 194
line_spacing 1
xmaximum 1541
ypos 914
size 30
color ‘#E2C778’
text «Придумайте имя:»:
xpos 194
line_spacing 1
ypos 877
size 30
color ‘#E2C778’
elif (persistent.font_size == ‘small’):
imagebutton:
action ShowMenu(‘text_history’)
auto (get_image(((‘gui/dialogue_box/’ + timeofday) + ‘/backward_%s.png’)))
xpos 38
ypos 949
add (get_image(((‘gui/dialogue_box/’ + timeofday) + ‘/dialogue_box.png’))):
xpos 174
ypos 916
imagebutton:
action HideInterface()
auto (get_image(((‘gui/dialogue_box/’ + timeofday) + ‘/hide_%s.png’)))
xpos 1508
ypos 933
imagebutton:
action ShowMenu(‘save’)
auto (get_image(((‘gui/dialogue_box/’ + timeofday) + ‘/save_%s.png’)))
xpos 1567
ypos 933
imagebutton:
action ShowMenu(‘game_menu_selector’)
auto (get_image(((‘gui/dialogue_box/’ + timeofday) + ‘/menu_%s.png’)))
xpos 1625
ypos 933
imagebutton:
action ShowMenu(‘load’)
auto (get_image(((‘gui/dialogue_box/’ + timeofday) + ‘/load_%s.png’)))
xpos 1682
ypos 933
imagebutton:
action Skip()
auto (get_image(((‘gui/dialogue_box/’ + timeofday) + ‘/forward_%s.png’)))
xpos 1768
ypos 949
input default «»:
xpos 194
line_spacing 2
xmaximum 1541
ypos 964
size 23
color ‘#E2C778’
text «Придумайте имя:»:
xpos 194
line_spacing 2
ypos 931
size 23
color ‘#E2C778’
так же в рандомное место вписываешь
init python:
def инициал_check_name(name, s):
global инициал_namesake
if name.lower() in [‘павлыч’, ‘павлик’, ‘павлуня’, ‘павлюня’, ‘павлуся’, ‘павлюся’, ‘павлуха’, ‘павлуша’, ‘павля’, ‘павлюка’, ‘павлюкаша’, ‘павша’, ‘пава’, ‘паха’, ‘паша’, ‘пашата’, ‘пашуня’, ‘пашута’, ‘пашуха’, ‘паня’, ‘пана’, ‘панюта’, ‘панюха’, ‘панюша’, ‘паняша’, ‘паля’, ‘палюня’, ‘палуня’]:
инициал_namesake = True
elif name.capitalize() in инициал_women_names:
renpy.say(th,’Это же женское имя.
renpy.jump(s)
elif name.lower() in [‘электроник91’, ‘электроник92’, ‘электроник93’, ‘электроник94’, ‘электроник95’, ‘электроник96’, ‘электроник97’, ‘электроник98’, ‘mr.электроник’, ‘xxxэлектроникxxx’, ‘шурик91’, ‘шурик92’, ‘шурик93’, ‘шурик94’, ‘шурик95’, ‘шурик96’, ‘шурик97’, ‘шурик98’, ‘супершурик’, ‘шурик_бл’]:
renpy.say(инициал_server, ‘Ты ведь сейчас шутишь, да?
renpy.jump(s)
elif ‘электроник’ in name.lower():
инициал_temp_rand = str(renpy.random.randint(91,99))
renpy.say(инициал_server, ‘Простите, данное имя уже занято. Попробуйте следующие имена:\nЭлектроник’+инициал_temp_rand+’, Mr.Электроник, xXxЭлектроникxXx’)
renpy.jump(s)
elif «шурик» in name.lower():
инициал_temp_rand = str(renpy.random.randint(91,99))
renpy.say(инициал_server, ‘Простите, данное имя уже занято. Попробуйте следующие имена:\nШурик’+инициал_temp_rand+’, СуперШурик, Шурик_БЛ’)
renpy.jump(s)
def инициал_cases(): #склонение имён по падежам. не работает с несклоняемыми (он их будет склонять :с)
global pname, bname
pname = pname.capitalize()
consonants = [u’б’, u’в’, u’г’, u’д’, u’ж’, u’з’, u’й’, u’к’, u’л’, u’м’, u’н’, u’п’, u’р’, u’с’, u’т’, u’ф’, u’х’, u’ц’, u’ч’, u’ш’, u’щ’, u’ь’]
last_symb = pname[len(pname)-1]
if last_symb in consonants:
if last_symb == u’й’ or last_symb == u’ь’:
bname = [pname[:len(pname)-1]+u’я’,pname[:len(pname)-1]+u’я’, pname[:len(pname)-1]+u’ю’, pname[:len(pname)-1]+u’ем’, pname[:len(pname)-1]+u’е’]
else:
bname = [pname+u’а’,pname+u’а’, pname+u’у’, pname+u’ом’, pname+u’е’]
elif last_symb == u’а’:
bname = [pname[:len(pname)-1]+u’ы’,pname[:len(pname)-1]+u’у’, pname[:len(pname)-1]+u’е’, pname[:len(pname)-1]+u’ой’, pname[:len(pname)-1]+u’е’]
elif pname[len(pname)-2 == u’ия’:
bname = [pname[:len(pname)-1]+u’и’,pname[:len(pname)-1]+u’ю’, pname[:len(pname)-1]+u’и’, pname[:len(pname)-1]+u’ей’, pname[:len(pname)-1]+u’и’]
elif last_symb == u’иа’ or last_symb == u’я’:
bname = [pname[:len(pname)-1]+u’и’,pname[:len(pname)-1]+u’ю’, pname[:len(pname)-1]+u’е’, pname[:len(pname)-1]+u’ей’, pname[:len(pname)-1]+u’е’]
else:
bname = [pname, pname, pname, pname, pname]
def инициал_meet(who, name):
gl = globals()
global store
store.names[who] = name
gl[who+»_name»] = store.names[who]
вместо инициал пишешь инициалы своего мода
init:
define инициал_server = Character(u»название твоего мода», color = «#2F4F4F», what_color = «#A9A9A9», drop_shadow = [ (2, 2) ], drop_shadow_color = «#000», what_drop_shadow = [ (2, 2) ], what_drop_shadow_color = «#000&
В общем я тут немного посидел, пописал спрайты и понял как их написать чуточку легче, чем предлагается в этом ФАКе, а также свести количество ошибок к нулю.
Плюсы: проще.
Минусы: придётся прописывать разные опции одного и того же спрайта для разного времени суток.
image НАЗВАНИЕ СПРАЙТА, МОЖНО НЕСКОЛЬКО СЛОВ = im.MatrixColor( im.Composite((900,1080), (0,0), «ПУТЬ К ФАЙЛУ ТЕЛА»,(0,0), «ПУТЬ К ФАЙЛУ ОДЕЖДЫ»,(0,0), «ПУТЬ К ФАЙЛУ ЭМОЦИИ»), im.matrix.tint(0.63, 0.78, 0.82) )
А теперь обрати внимание на цифры в скобках после im.matrix.tint. Эти цифры и отвечают за «Время суток» спрайта.
image REUNION DV SMILE COAT NORMAL= im.MatrixColor( im.Composite((900,1080), (0,0), «SPRITES/NORMAL/DV/DV_4_BODY.PNG»,(0,0), «MODS/REUNION/IMAGES/SPRITES/NORMAL/DV/DV4_COAT.PNG»,(0,0), «SPRITES/NORMAL/DV/DV_4_SMILE.PNG»), im.matrix.tint(0.63, 0.78, 0.82) )
Данный пример для спрайта Алисы в добавленной одежде для «Ночи».
Я надеюсь, что хоть кому-нибудь это будет полезно.
Источник
Как писать мод на бесконечное лето
Возможно кому-то пригодится:
Если кому-то нужно получить файл с папки воркшопа через open()/file() или же удалить его через os.remove(), добавить свои модули или же что либо ещё что требует ПОЛНОГО пути к папке С МОДОМ,, то можно использовать такую штуку в путях, как «..»
Все модификации хранятся в папке workshop, которая размещена в той же папке steamapps, где размещена папка common с игрой, даже если steamapps несколько.
То есть, чтобы получить пути к целевой папке steamapps можно использовать
C:\SteamLibrary\steamapps\common\Everlasting Summer\..\..
Ещё проще)
C:\SteamLibrary\steamapps\common\Everlasting Summer\..\..\workshop\content\331470\
Вот и попали в папку модов для БЛ (относительно моего пути к БЛ).
Если нужно получить папку какого-то конкретного мода, то просто дописываем его ID
Например, получим папку Саманта-мода:
Ну, а поскольку в питоне «\» означает кое-что другое, то меняем все «\» на «/»
Но, как я уже говорил, это мой путь к БЛ.
Поэтому, «спрашиваем» в Ren’Py (движок БЛ) какой же наш путь:
Это и будет наш путь к Саманта-моду.
Потом можно делать с ним всё, что вздумается.
Как задействовать клавиатуру в моде, например, для мини-игр.
Первым делом, нужно выбрать клавишу, которую мы будем использовать. Для начала возьмём пробел.
Чтобы человек мог нажать на клавишу в определённый момент времени, нужно её нарисовать и вставить в код ренпая с помощью самой обычной команды для внедрения своего бг или цг.
Мы загрузили изображение пробела. Теперь приступим к коду.
Возьмём самый простой для задействования всего одного пробела:
(Скриншот)
Если вы успели нажать на кнопку, вас перебрасывает на лейбл, который означает победу.
Если не успели, то после двух секунд функция пробела исчезает и продолжается сюжет, перебросив вас на лейбл, означающий поражение. В нём вы можете дать очко переменной для определённых событий, или же перебросить обратно на начало мини-игры, дав переиграть для достижения победы.
Кстати, вот вам кнопка пробела, делал для своего мода.
Источник