diff --git a/game/audio/access_denied.ogg b/game/audio/access_denied.ogg new file mode 100644 index 0000000..c555a9f --- /dev/null +++ b/game/audio/access_denied.ogg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f565dad91ebb5db4492393a21c363156d17dbda4ed5dec1e9c644cb2949b83e9 +size 30565 diff --git a/game/audio/access_granted.ogg b/game/audio/access_granted.ogg new file mode 100644 index 0000000..c1aa3df --- /dev/null +++ b/game/audio/access_granted.ogg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:566e04c4cf3d75c5a41691bf46e9b3b126bb04017941b82a08452558ae11e07e +size 26221 diff --git a/game/audio/door_open.ogg b/game/audio/door_open.ogg new file mode 100644 index 0000000..6a18275 --- /dev/null +++ b/game/audio/door_open.ogg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:26933744e62086f8a2e5098c28b3b52e64b18ebe4250686adf495480d1efa353 +size 94798 diff --git a/game/audio/explosion.ogg b/game/audio/explosion.ogg new file mode 100644 index 0000000..f441772 --- /dev/null +++ b/game/audio/explosion.ogg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1532bc0cf6ca2df4efa02fcf79cd49c0eac051069642a7d0827adb99916ed6c1 +size 32692 diff --git a/game/audio/final_theme.ogg b/game/audio/final_theme.ogg new file mode 100644 index 0000000..96c6f88 --- /dev/null +++ b/game/audio/final_theme.ogg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:fd629a7d64a2b4774396ddf5a2ff1ccef378d6b4e4ae6902fcdae9d4d2a34779 +size 13628090 diff --git a/game/audio/footsteps.ogg b/game/audio/footsteps.ogg new file mode 100644 index 0000000..7f9f1a0 --- /dev/null +++ b/game/audio/footsteps.ogg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b8d0cbfea3f6baa89c8119e4d161fc1b1bb665d59c372cd9094cda2c727ecda6 +size 36790 diff --git a/game/audio/generator.ogg b/game/audio/generator.ogg new file mode 100644 index 0000000..e0f1016 --- /dev/null +++ b/game/audio/generator.ogg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:913a3a3ed048406b7f3e861088f75ac5e1a2e13e2834d12803789766ce3d578e +size 156620 diff --git a/game/audio/glass_break.ogg b/game/audio/glass_break.ogg new file mode 100644 index 0000000..318e4ae --- /dev/null +++ b/game/audio/glass_break.ogg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:31886737fb9905d76534b124658dd36c3a16defe12897b6160f52c5f79ff3bdd +size 35459 diff --git a/game/audio/glass_rub.ogg b/game/audio/glass_rub.ogg new file mode 100644 index 0000000..0a25eef --- /dev/null +++ b/game/audio/glass_rub.ogg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:82f6c454f5a91b6ec0105b9d1d6ee24c8abcffd39cabcd2e8d668fecefd4303b +size 73753 diff --git a/game/audio/main_theme.ogg b/game/audio/main_theme.ogg new file mode 100644 index 0000000..e73b1b7 --- /dev/null +++ b/game/audio/main_theme.ogg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ac54fa88967a8ade86aec83a0db74b9ef4ac753da584b485b9a421845b1fb201 +size 15685783 diff --git a/game/audio/pouring.ogg b/game/audio/pouring.ogg new file mode 100644 index 0000000..ab441ad --- /dev/null +++ b/game/audio/pouring.ogg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:777c1da0a23555e243fc787b5f0ecc8cae1916b8a0a437eecb33663cacf8affd +size 176614 diff --git a/game/audio/server.ogg b/game/audio/server.ogg new file mode 100644 index 0000000..ace164e --- /dev/null +++ b/game/audio/server.ogg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b7c019917fb5d6eae8c96182533bfb900fc8f29db7febf454c75e1064a4583ec +size 1031609 diff --git a/game/audio/typing.ogg b/game/audio/typing.ogg new file mode 100644 index 0000000..ea8bd59 --- /dev/null +++ b/game/audio/typing.ogg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7be0c3cf1f99d081d150bf61d6f3ce97f7709828efc872897e7f037072511db3 +size 482705 diff --git a/game/audio/wind.ogg b/game/audio/wind.ogg new file mode 100644 index 0000000..054849a --- /dev/null +++ b/game/audio/wind.ogg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:231d4a80b7ace48c3b1a15e2078d5220dccea7290f6f13e6c04026200e4efe32 +size 13121465 diff --git a/game/script.rpy b/game/script.rpy index 7b3c547..3e924f8 100644 --- a/game/script.rpy +++ b/game/script.rpy @@ -2,7 +2,10 @@ return init python: - renpy.music.register_channel("ambient", "sfx") + renpy.music.register_channel("ambient_generator", "ambient", loop=True) + renpy.music.register_channel("ambient_server", "ambient", loop=True) + renpy.music.register_channel("ambient_wind", "ambient", loop=True) + renpy.music.register_channel("footsteps", "ambient", loop=False) _game_menu_screen = None _skipping = False @@ -45,7 +48,6 @@ screen journal(): frame: align (0.5, 0.5) xsize 700 ysize 500 - background "#333333" vbox: text "МЫСЛИ" size 50 for entry in journal: @@ -117,20 +119,35 @@ screen terminal_rhythm_screen(): transform slow_zoom_pan: zoom 1.0 - linear 15.0 zoom 1.05 + linear 15.0 zoom 1.02 linear 15.0 zoom 1.0 repeat +transform shake_effect(rate=0.090): + zoom 1.1 align (0.5, 0.5) + linear rate xoffset 2 yoffset -6 + linear rate xoffset -2.8 yoffset -2 + linear rate xoffset 2.8 yoffset -2 + linear rate xoffset -2 yoffset -6 + linear rate xoffset +0 yoffset +0 + +define chapter_title = Character(None, + what_xalign=0.5, + what_yalign=0.4, + window_yalign=0.5, + window_background = None + ) + label start: scene black play sound "audio/typing.ogg" loop fadein 0.5 - - show text "{size=150}{cps=2}ТИШИНА{/cps}{/size}" with dissolve + + chapter_title "{size=150}{cps=5}ТИШИНА{/cps}{/size}" with dissolve pause 2.0 hide text with dissolve - show text "{size=120}{cps=2}20.04.2023{/cps}{/size}" with dissolve + chapter_title "{size=120}{cps=5}20.04.2023{/cps}{/size}" with dissolve pause 2.0 hide text with dissolve @@ -150,6 +167,12 @@ label phase_1_intro: $ routine_tasks = 0 scene bg_room at slow_zoom_pan with dissolve + + play music "audio/main_theme.ogg" + + $ renpy.music.set_volume(0.6, delay=0, channel='ambient_generator') + play ambient_generator "audio/generator.ogg" + "Я просыпаюсь. Шум генератора — единственное, что доказывает, что я еще здесь. Но сегодня этот звук другой. Он надтреснутый, хриплый, как дыхание умирающего." "Индикатор на консоли мигает тусклым оранжевым. 100\%. Это последняя порция топлива. Последние искры жизни этой консервной банки." "Семь лет назад я считал эту станцию своей крепостью. Теперь — это мой склеп, где я сам себе надсмотрщик, а генератор — мой метроном, отсчитывающий секунды до полной темноты." @@ -161,7 +184,10 @@ label phase_1_intro: jump routine_loop label routine_loop: - scene bg_room with fade + if "bg_room" not in renpy.get_showing_tags("master"): + scene bg_room at slow_zoom_pan with dissolve + + $ renpy.music.set_volume(0.6, delay=0, channel='ambient_generator') if routine_tasks >= 3: jump start_game_proper @@ -172,7 +198,14 @@ label routine_loop: "Налить остывший кофе" if not coffee_done: $ coffee_done = True $ routine_tasks += 1 - scene bg_room_coffee with fade + + play footsteps "audio/footsteps.ogg" + pause 1.0 + + scene bg_room_coffee at slow_zoom_pan with dissolve + + play sound "audio/pouring.ogg" + "Чашка холодная, стенки покрыты въевшимся коричневым налетом. Я смотрю на эту мутную жидкость и вспоминаю, как раньше мы спорили о том, какой сорт кофе лучше — с кислинкой или с горчинкой." "Теперь мне всё равно. Это просто топливо. Жидкая горечь, чтобы хоть как-то почувствовать себя живым. Я делаю глоток, и холод металла чашки обжигает губы сильнее, чем сам напиток. Это вкус прощания." jump routine_loop @@ -180,7 +213,14 @@ label routine_loop: "Подойти к окну и стереть иней" if not window_done: $ window_done = True $ routine_tasks += 1 - scene bg_room_iney with fade + + play footsteps "audio/footsteps.ogg" + pause 1.0 + + scene bg_room_iney at slow_zoom_pan with dissolve + + play sound "audio/glass_rub.ogg" + "Стекло промерзло насквозь. Я провожу рукавом, оставляя длинную, неровную полосу. Иней осыпается, как пепел." "За окном — только серая, бескрайняя пелена. Ни горизонта, ни неба. Иногда мне кажется, что я нахожусь не на станции связи, а внутри собственного разума, куда забыли подать свет." "Я вглядываюсь в это 'ничто', надеясь увидеть хоть что-то, кроме собственного бледного отражения. Но вижу лишь глаза человека, который три года назад решил, что ожидание лучше, чем риск." @@ -189,7 +229,14 @@ label routine_loop: "Проверить статус генератора" if not power_done: $ power_done = True $ routine_tasks += 1 - scene bg_room_generator with fade + + play footsteps "audio/footsteps.ogg" + pause 1.0 + + scene bg_room_generator at slow_zoom_pan with dissolve + + $ renpy.music.set_volume(1, delay=0, channel='ambient_generator') + "Я подхожу к главному щитку. Индикаторы мерцают, как нервные окончания, готовые вот-вот перегореть. Семь лет эксплуатации — это не шутки. Сегодня он сдастся." "Генератор стонет под нагрузкой. Я касаюсь рычага, чувствуя его дрожь. Если я сейчас уйду — он просто сгорит. Если останусь — буду жечь последние крохи энергии на поддержание пустоты." "Каждый мой шаг здесь — это повторение того, от чего я пытаюсь сбежать, но я не могу позволить станции заглохнуть раньше времени. Это моё единственное наследие, мой памятник трусости." @@ -204,13 +251,13 @@ label start_game_proper: jump main_loop label main_loop: + $ renpy.music.set_volume(0.0, delay=0.2, channel='ambient_wind') + if battery <= 0: jump ending_silence show screen game_ui - # play ambient "audio/ambient_low_hum.ogg" fadein 2.0 loop - "Станция ждет. Сегодня всё закончится. Что я буду делать, пока ещё есть свет?" menu: @@ -233,18 +280,27 @@ label main_loop: jump phase_3_culmination label qte_date_input: - scene bg_desk_close with fade - # play sound "audio/keyboard_clack.ogg" + play footsteps "audio/footsteps.ogg" + pause 1.0 + + $ renpy.music.set_volume(0.4, delay=0, channel='ambient_generator') + + if "bg_room" not in renpy.get_showing_tags("master"): + scene bg_desk_close at slow_zoom_pan with fade + else: + scene bg_desk_close at slow_zoom_pan with dissolve "Рабочий стол. Слой пыли здесь настолько толстый, что кажется, будто никто не садился сюда вечность." "Курсор на экране терминала мигает в ритме моего пульса. Сегодня двадцатое апреля, двадцать третьего года." "Ровно три года с того дня, когда всё пошло прахом. Три года тишины, которую я сам на себя наложил." "Чтобы получить доступ к архиву за тот день, система требует подтвердить текущую дату. Словно издевается, заставляя меня признать, сколько времени я потратил на это самобичевание." + play sound "audio/typing.ogg" loop $ date_input = renpy.input("Введите сегодняшнюю дату (ДД.ММ.ГГГГ):", length=10) + stop sound if date_input == "20.04.2023": - # play sound "audio/access_granted.ogg" + play sound "audio/access_granted.ogg" "Экран на мгновение вспыхивает ярким, почти болезненным белым цветом. Система приняла ввод." "Я вхожу в архив. Передо мной всплывают логи трехлетней давности. Двадцатое апреля, двадцатый год." "Я помню этот день по секундам. День, когда я должен был сказать одно слово, но вместо этого промолчал." @@ -253,7 +309,7 @@ label qte_date_input: $ fragments += 1 $ journal.append("20.04.2020. Дата моего заточения. Спустя три года я наконец-то открыл архив, который так боялся увидеть.") else: - # play sound "audio/access_denied.ogg" + play sound "audio/access_denied.ogg" "На экране высветилось: 'ОШИБКА ДОСТУПА'." "Даже простая проверка даты выбивает меня из колеи. Мои руки дрожат так сильно, что я путаю цифры." "Я чувствую, как с каждой неудачной попыткой станция становится всё холоднее. Или это просто моё отчаяние?" @@ -262,17 +318,24 @@ label qte_date_input: jump main_loop label qte_corridor_puzzle: - scene bg_corridor with fade - # play sound "audio/wind_echo.ogg" + play footsteps "audio/footsteps.ogg" + pause 1.0 + + $ renpy.music.set_volume(0.2, delay=0, channel='ambient_generator') + + $ renpy.music.set_volume(0.8, delay=0.2, channel='ambient_wind') + play ambient_wind "audio/wind.ogg" + + scene bg_corridor at slow_zoom_pan with fade "Коридор. Место, где время растянулось, как жевательная резинка." "В конце — разбитое зеркало. Я смотрю в него, и мои глаза встречаются с глазами человека, который проиграл эту жизнь три года назад." "Оно разбито на четыре неравных куска. Я вижу в этих осколках фрагменты того самого дня. Если я соберу их... если я заставлю себя посмотреть на них..." call screen corridor_puzzle_screen - $ result = _return - if not result: + if not _return: + play sound "audio/glass_break.ogg" "Я смотрю на пустые места в зеркале. Я не могу... Руки не слушаются. В голове только шум и липкий страх." "Я слишком слаб, чтобы видеть всё это целиком. Может быть, позже..." jump main_loop @@ -290,8 +353,12 @@ label qte_corridor_puzzle: jump main_loop label qte_terminal_rhythm: - scene bg_terminal with fade - # play sound "audio/terminal_hum.ogg" + play footsteps "audio/footsteps.ogg" + pause 1.0 + + $ renpy.music.set_volume(0.6, delay=0, channel='ambient_generator') + + scene bg_terminal at slow_zoom_pan with fade "Терминал. Моё единственное окно в мир, который меня забыл." "Экран забит мусором — тысячи системных сообщений, ошибок и битых секторов. Где-то там, под слоем цифровой пыли, всё ещё лежат записи того дня." @@ -302,7 +369,7 @@ label qte_terminal_rhythm: call screen terminal_rhythm_screen if _return: - # play sound "audio/success_beep.ogg" + play sound "audio/access_granted.ogg" "Синхронизация завершена. Помехи исчезли, оставив на экране четкие строки." "Я прокручиваю лог вниз. Вот оно. Сообщение, которое я никогда не открывал." "Моё сердце пропускает удар. Я не отправляю ничего. Я просто читаю её последние слова, и это ранит сильнее, чем любая ошибка связи." @@ -310,7 +377,7 @@ label qte_terminal_rhythm: $ fragments += 1 $ journal.append("Терминал: Я открыл её последнее сообщение. Теперь я знаю, что именно я потерял.") else: - # play sound "audio/fail_buzz.ogg" + play sound "audio/access_denied.ogg" "Ошибка синхронизации. Архив свернулся, защищая себя от доступа." "Я снова промахнулся. Руки дрожат, экран гаснет, и я остаюсь в тишине." "Она осталась для меня неразгаданной. Снова. Всегда опаздываю — даже чтобы просто узнать правду." @@ -330,17 +397,29 @@ label deep_reflection: jump main_loop label phase_3_culmination: - scene bg_door_to_server with dissolve - # play sound "audio/heavy_door_open.ogg" + play footsteps "audio/footsteps.ogg" + pause 1.0 + + $ renpy.music.set_volume(0.1, delay=0, channel='ambient_generator') + + scene bg_door_to_server at slow_zoom_pan with fade "Серверная. Место, где родилась вся эта ложь." "Я помню, как три года назад входил сюда, чтобы заглушить голос совести. Семь лет работы, три года молчания — всё это здесь." - jump final_choice label final_choice: + stop music fadeout 0.3 + play footsteps "audio/footsteps.ogg" + pause 1.0 + + $ renpy.music.set_volume(0.6, delay=0, channel='ambient_generator') + + play ambient_server "audio/server.ogg" + play music "audio/final_theme.ogg" + + play sound "audio/door_open.ogg" scene bg_server_close with dissolve - # play music "audio/tension_finale.ogg" fadein 5.0 "Светодиоды на стойках серверов мигают, словно конвульсии умирающего. Воздух здесь настолько сухой и горячий, что обжигает горло при каждом вдохе." "На центральном терминале мерцает последний интерфейс. Если я нажму 'Ввод', пути назад не будет. Станция отключит жизнеобеспечение окончательно." @@ -357,11 +436,17 @@ label final_choice: "Признать ошибки и выйти (Переосмысление)" if fragments >= 3: jump ending_reflection - "Отправить извинения (Свет)" if fragments >= 3 and sync_points >= 3: + "Отправить извинения (Свет)" if fragments >= 3 and thoughts_processed >= 3: jump ending_light label ending_silence: - scene black with fade + scene black with Fade(0.1) + + stop music fadeout 0.1 + stop ambient_generator fadeout 0.1 + stop ambient_server fadeout 0.1 + stop ambient_wind fadeout 0.1 + "Экран погас. Вместе с ним погас и последний источник света в этом склепе." "Генератор сделал последний судорожный вдох и замолчал. В этой абсолютной темноте я наконец-то слышу то, чего так боялся." "Ничего. Пустоту. Тишину, которая заполняет легкие вместо воздуха." @@ -369,8 +454,14 @@ label ending_silence: jump quit_after_ending label ending_anger: - scene bg_server_close_broken with shake - # play sound "audio/glass_shatter.ogg" + scene bg_server_close_broken at shake_effect + + stop music fadeout 0.1 + stop ambient_generator fadeout 0.1 + stop ambient_server fadeout 0.1 + stop ambient_wind fadeout 0.1 + + play sound "audio/explosion.ogg" "Гнев — это единственное, что заставляет меня чувствовать себя живым. Я срываю красную панель, сдирая кожу на пальцах до крови." "Тумблер падает вниз с хрустом ломающихся костей. Искры бьют в лицо, выжигая остатки рассудка." "Станция умирает, и я тяну её за собой в небытие. Я зол на этот холод, на эти три года, на её молчание... я зол на себя, но мне проще сжечь этот мир, чем признать свою вину." @@ -378,26 +469,35 @@ label ending_anger: jump quit_after_ending label ending_acceptance: - scene bg_server_close_off with fade + stop music fadeout 2.0 "Курсор мигает в ритме моего безразличия. Раз, два... Раз, два..." "Зачем что-то менять? Зачем бороться с энтропией, если она всё равно победит?" "Я откидываюсь на спинку кресла. Инфантильное желание просто закрыть глаза и ждать, пока тьма поглотит эту станцию, кажется единственно верным." + scene bg_server_close_off with dissolve "Пусть всё закончится само собой. Я устал играть в героя. Я просто... буду ждать." jump quit_after_ending label ending_reflection: - scene bg_server_close_keyboard with fade + scene bg_server_close_keyboard with dissolve + play sound "audio/typing.ogg" "Я печатаю дрожащими пальцами: 'Я был неправ. Это была глупая, бесконечная игра в мученика, в которой не было победителей'." - "Я признаю это. Три года я строил стены из своего молчания, думая, что защищаюсь. Но я просто возвел свою собственную тюрьму." + "Я признаю это. Но не могу отправить сообщение." + "Три года я строил стены из своего молчания, думая, что защищаюсь. Но я просто возвел свою собственную тюрьму." + scene bg_server_close_off with dissolve "Я выключаю станцию. Впервые за долгое время я чувствую, что в воздухе стало меньше гари. Я должен двигаться дальше. Я не знаю, что там, во внешнем мире, но я больше не заперт внутри себя." jump quit_after_ending label ending_light: - scene bg_server_close_light_from_monitor with fade + scene bg_server_close_light_from_monitor at slow_zoom_pan with dissolve + + stop ambient_generator fadeout 1.0 + stop ambient_server fadeout 1.0 + stop ambient_wind fadeout 1.0 + "Я направляю остатки энергии на передатчик. Каждый процент заряда — это вырванный из жизни кусок, который я отдаю за шанс сказать правду." "Я пишу не для того, чтобы получить ответ. Я пишу, чтобы освободиться. 'Прости за тишину. Она была моей ошибкой'." "Нажимаю 'Отправить'. Система оповещает о передаче пакета, и тут же питание отключается. Станция замирает." - scene bg_exit_winter with fade + scene bg_exit_winter at slow_zoom_pan with dissolve "Я встаю и иду к выходу. Я не оглядываюсь. Мой долг перед прошлым оплачен, а будущее... будущее наконец-то принадлежит мне." jump quit_after_ending