"Время играть!": ретроспектива проекта на КОД20

FriendRender_7.png

К своему стыду я долгое время игнорировал конкурс КОД. Так как на гамине вообще много разных конкурсов: глобальные гаминаторы, специализированные «звуки гамина», «триколор», когда я давно впервые увидел КОД, я сделал вывод о его сути на основе его названия, и решил, что он типа конкурс для тру-программистов, и там нужно писать сложный код. В итоге даже не интересовался этим конкурсом. Программистом я себя хорошим никогда не считал, а пару лет назад моих навыков и знаний от универа и вовсе практически не осталось. Посмотреть на конкурс еще раз меня заставил Дима, который в прошлом КОД все же поучаствовал, и тогда то я понял, что тоже могу, что КОД это ультракороткий гаминатор, и что в нем нужно обязательно поучаствовать, поэтому когда анонсировали КОД20 я уже морально был готов.

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

Начало

Я давно уже хотел сделать микрохоррор. Еще до оглашения темы у меня было несколько идей, но так как тему я еще не знал остановиться на чем-то одном было сложно. Я думал в основном о камерных хоррорах.

  • «Кукольный домик». Дочка говорит, что в ее кукольном домике появилась страшная кукла, и просит ее выкинуть. Мы заглядываем в кукольный домик и наш взгляд приковывает светящий предмет, мы подходим подбираем его с пола и в этот момент осознаем, что мы оказались внутри кукольного домика, а гигантская криповая кукла за нами закрывает пластиковую прозрачную «четвертую стену»… Этот проект бы больше походил на наш старый проект For Mari, но собранный куда более компетентно.
  • «Телефонная будка». Ты заперт в телефонной будке, и сколько бы ты не стучал в дверь, никто снаружи тебя не слышит, ты как будто застрял между измерениями. В этой игре игроку предстояло бы решить простенький «квеструм», из активных элементов у нас был бы только кнопочный телефон, нужно было бы искать подсказки «куда позвонить» в окружении, в диалогах и в результате докопаться до истины, что же произошло на самом деле.
  • «Китайская комната», игра на основе одноименного мысленного эксперимента, однако здесь действие разворачивалось в небольшом комплексе, а не одной комнате, и все было бы подписано геометрическими символами, игроку бы так же приходили инструкции в виде последовательности таких символов, и игрок должен был б разбираться что от него вообще хотят. Однако потом в записках с символами бы стали появляться подсказки проливающие свет на то, что вообще сейчас происходит.
  • Еще хотелось сделать свой Sentient, только немного иной. В Sentient главный герой подопытный к некой лаборатории, каждый его день это выполнение дурацких инструкций которые диктуются из динамика, за выполнение которых игрока вознаграждают печеньками. В одной из стен находится дыра, которая является точкой напряжения игры и из которой периодически доносятся разные странные звуки. Судя по всему в соседних комнатах такие же подопытные как и ты, и нам даже предлагают поиграть с соседом через дыру в стене с помощью мяча, и все бы относительно хорошо, пока не случается сбой в системе безопасности и сосед не приходит к нам гости. Хотелось сделать что-то с таким же вайбом, у меня давно есть обзор на это творение.

Возможно, эти все идеи когда-нибудь в том или ином виде реализуются. Однако тема была довольно неожиданной и сломала все мои планы о «неспешных» ужастиках. Когда DarkDes предложил в комментариях к загаданной теме «Движение — жизнь», то я сразу понял, что оно так и есть и в голове начал потихоньку прикидывать идеи для проекта. Сперва хотел сделать что-то типа фрагмента из начала The Evil Within, когда ты хромаешь по длинному коридору от циркулярных пил. По сути игра бы представляла собой такой «калечный раннер», где ошибки бы карались увечьями и уменьшением скорости протагониста, но чтобы это не было так критично с помощью специальных действий можно было б замедлять движущуюся за тобой «смерть». Но я эту идею быстро отбросил, потому что не хотел делать игру от третьего лица, а от первого такое бы не очень работало, а во вторых потому что пришла идея Time To Play. Я как обычно сидел генерировал разные идеи в ChatGPT и мне выдало это:

«Название: «Темные Пульсации» (Dark Pulsations)

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

Геймплей: Игроку предстоит исследовать особняк, раскрывая его тайны и пытаясь выжить. Поддерживая высокую скорость пульса героя, игрок сможет видеть скрытые пути, подсказки и предупреждения о приближающейся опасности. Однако, высокая пульсация также привлекает внимание монстров, увеличивая риск быть обнаруженным."

Мой взгляд зацепился за фразу «Чем выше скорость пульса героя, тем больше света», БИНГО! Остальное можно было уже не читать, так как воображение завелось и в миг нарисовало мне концепт игры.

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

  • Погрузиться полностью в опасную тьму и не иметь возможностей к навигации, либо вырабатывать свет для фонарика с помощью движений и тем самым шуметь навлекая на себя опасность в виде «друга».
  • В то же время если медленно ходить (например практически не шумя на карачках) либо вовсе стоять, то активируется ошейник, который через некоторое время превратит голову протагониста в фаршик.

Разработка

Времени на расписывание ГДД не было (и благо я работал один, а проект не настолько большой, чтобы терять в голове нюансы), поэтому я сразу сел за производство. Времени было мало, поэтому промежуточные стадии я не скриншотил и не записывал.

За некоторое время ДО, у меня была идея хоррора с вайбом нашумевшей Unrecord,

Фотограмметрия + анимация камеры + пост эффекты = крутота

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

image.png
Крипта

Дальше я приступил к созданию контроллера персонажа. Начал я с темплейта first person, на нем реализовал функции сердцебиения и взрывающегося ошейника, но позже у меня начали возникать проблемы, одной из которых была непривычная реализация работы с input system, я не сразу понял, как их методом получать команды на вход для реализации приседания, поэтому я полез в старые наработки и начал подглядывать туда.

Доп. помощником мне стал вновь ChatGPT, которому очень удобно поручать писать небольшие функции, правда пару раз он мне вставил палки в колеса написав вполне правдоподобную, но неправильную логику, поэтому мне приходилось тщательно вычитывать, что он там пишет вообще.

Одной из потенциальных проблем мог стать новый Navigation System, а я ведь спецом обновил Unity перед КОД, чтобы потыкать новые функции, хотя даже не знал о новой навигации, но к большому счастью, они не стали ее перепиливать кардинально, а лишь улучшили и упростили, благодаря чему вкатиться оказалось очень просто.

Теперь без сторонних плагинов можно делать так

Параллельно этому всему я уже накидывал сюжет, идея сделать свою «Пилу» пришла как-то сама вместе с ошейником, якобы герой играет в «игру маньяка», мотивы которого нам не особо известны. Пока гулял с псом вбивал текст себе в заметки, а придя домой написал Роме, мол «озвучь пжлст», он был не против. TTP не первая моя игра где есть озвучка в том или ином виде, да и помимо игр я много работал с озвучкой, и тут возникают вопросы режиссуры. Обычно я отдаю текст с кратким описанием персонажа, где как нужно озвучивать, но по сути доверяю полностью исполнителю, иногда это оправдывает себя, но чаще всего не очень, к тому же бывают досадные штуки, когда интонация в важном моменте совершенно не та, либо слово можно прочитать с разными ударениями и актер читает не так, а так как нет возможности «онлайн» мгновенно его поправить то возникают проблемы. Поэтому я решил попробовать сперва зачитать все самостоятельно, как я это вижу, и чтобы эта запись была ориентиром. Маньяка я видел как этакую криповую смесь Джокера и Доктора Ливси. Сперва играя с после прогулки с собакой в мяч, я чутка потреннировался, а после записал Роме звуковые сообщения, которые сопроводил текстом.

Мой тестовый голос

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

Чутка блуперсов от Ромы

Но вернемся немного назад по таймлайну. После первой версии First Person контроллера я накидал быстренько еще пару скриптов по типу сбора ключей, открывания финальных дверей (изначально открывались не таймлайном, а через код). можно сказать, что игра стала проходимой, и тут я понял, что без генерации как-то скучно. Поняв где что лежит у игрока будет еще меньше напряжения от встречи с «другом», он просто пробежит но запомненным координатам, и пройдет легко игру через 1−2 попытки. Мне этого не хотелось, к тому же мне как разрабу самому тоже хочется играть в свою игру, а для этого нужно, чтобы я сам не знал, как однозначно ее проходить. Сперва придумал какую-то сложную идею, где абстрактный невидимый NavMesh agent со скоростью флеша носится по рандомным точкам уровня и дропает ключи и «издающие звук объекты», но потом решил, что это и звучит бредово, да и слишком много хаоса, мб оно вообще перед выходом из начальной комнаты все «засрет» объектами и «что тогда?». Плюс я хотел генерировать стены, чтобы менять геометрию самого уровня, поэтому мне потребовался более универсальный и контролируемый подход. В итоге у меня есть ряд объектов на уровне, которые я выставляю заранее, то есть пул, и есть пул точек, куда объекты из пула объектов будут расставляться. Точки я расставлял вручную. И так как делал это на скорую руку в версии 1.0 там все криво косо с ними, однако позже я исправился.

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

monter2-3.png

image.png
Оригинальный концепт от Xenna Demonorph

Закончив более менее рабочую версию «друга» стоило определиться как он будет выглядеть. Сперва я хотел уже садиться за его моделинг, но поняв, что мне еще локацию с нуля делать, я решил, что точно не вывезу, тогда я вспомнил, что у меня есть в запасах модели. Зарелизив Метаинститут на гаминатор 21, я какое-то время еще хотел допиливать этот проект, но там все заглохло, тем не менее остались концепт-арты одной клевой художницы, по одному из которых я уже сделал модель. Эта модель в целом и определила графический стиль, и полную необходимость в отказе от фотоскана, который я использовал в данный момент. Так же эта модель определила нужду в специальных анимациях, потому что у монстра нетипичная анатомия и много дополнительных костей, а собранный аниматор работал с humanoid анимациями. Поэтому в версии от 2 июля монстр ходит с вытянутым вперед «щупальцем». Еще интересный момент, это извивающиеся тентакли, референсом к которым стало аниме «паразит» и RE4. Но вот не задача, я откровенно не знаю как их анимировать вручную. Поэтому я в одно время решил поступить проще и написать специальный скрипт, который анимирует эти штуки процедурно. Эффект не идеальный, но вроде все равно сносный и добавляет мерзости антагонисту. Если есть идеи как сделать лучше, напишите мне, пожалуйста).

В воскресенье я был готов трайхардить до 3 ночи (по моему местному времени), чтобы все успеть в том или ином виде, но благо конкурс продлили на день, поэтому я закончил «демку», собрал недо-меню и спокойно пошел отдыхать.

Понедельник выдался тяжелым. Я просидел за игрой с 8 утра, до часу ночи с перерывами на покушать, погулять собаку. Для создания окружения я решил использовать пайплайн на тримшитах, который хорошо зарекомендовал себя и в Маяке, но тут я делал текстуры не с нуля, а набрал готовых на ambient.cg. Теперь нужно было собрать тримшит. Я попробовал разные варианты и понял, что в Youtube нет нормального видоса по этой теме. Сперва я сел в Substance designer, однако в моей версии я не смог нормально через Material blend мешать ч/б текстуры и нормалки. В итоге я собрал все в фотошопе, что было чутка геморно, но довольно быстро. Потом я еще и экшен записал полезный по теме, нужно будет видос сделать и экшен этот туда ссылкой пробросить.

Smeshannyy_trimshit.png

С готовым тримом делать уровень было очень клево, я прям влюбился в этот пайплайн снова. Я открыл модель с фотограмметрией крипты, сделал большой массив для пола, нарезал и вырезал лишние куски. Потом делал массивы для стен и расставлял по периметру пола. Так же нужно было сделать из тримов ряд ассетов, вроде колон, решеток, даже столы делал с того же трима. После того как стены готовы, просто перетаскиваешь UV остновки на нужные части текстуры, и локация преображается.

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

image.png

Благодаря этому пайплайну и малому количеству динамического освещения мне даже не пришлось запариваться над оптимизацией, и даже на ноуте Pooffick’а, на котором только встроенная видеокарта, проект игрался нормально без сильных просадок FPS. Хотя я использовал HD render pipeline, потому что нуждался в качественном освещении и тенях.

Дополнительные ассеты я сделал по методике Ian Hubbert’а, накачал на халявные 15 баллов на texture.com фоточек индустриальных объектов, собрал из них атлас, пожал, и с помощью инструментов knife и extrude наделал кучу клёвых ассетов. В итоге они и выглядят классно, и потратил я на них от силы час времени.

image.pngimage.png

Теперь нужно было проанимировать монстра. Делать это нужно было очень быстро и халявно, сперва начал с Idle анимации, поставил его в позу, накрутил на торс модификатор noise, чтобы он рандомно дергался и настройками сделал так, чтобы анимация циклилась. После нужно было проанимировать руки и куски головы, тут я использовал экспериментальную технику, я просто в режиме auto key запустил timeline и в режиме реального времени вращал/двигал ту или иную кость. SIC!

Теперь нужно было проверить все ли ок, я вывел эту анимацию, засунул в движок и все сломалось. Почему? потому что у монстра нет левой руки, и костей тоже нет. Тогда я переделал скелет так, чтобы геометрии руки не было, но кости было. Однако Unity в таком варианте у меня тупит и отказывается выставлять T-pose персонажу. Пришлось добавить вытянутый кубик, привязать его к этим костям, а внутри Unity куб отключать. Теперь все работает как нужно, важно так же в каждой анимации указывать все доп. кости, которые задействованы в анимации и не используются Humanoid в Unity. После я проанимировал еще ряд анимаций: walk, run, grab, kill, hearsomething. Последняя к слову в игру так и не попала, даже в версии 1.1 .

Теперь нужно было все отполировать и собрать в воедино. И это заняло тоже кучу времени, везде были те или иные шероховатости, которые я параллельно выписывал себе в списочек. Тут же у меня впервые попался софтлок, я его вроде исправил, но на самом деле нет, что аукнется Rubel’ю на стриме). Под вечер мне уже было так плохо целого дня работы, что у меня немели конечности и болела голова. Тем не менее я смог закончить в срок, и даже не в последние минуты, как это иногда бывает.

Итог

Конечно, успел далеко не все, и пришлось садится и выкатывать пропатченную версию, но в целом проектом доволен. Доволен реакцией игроков и стриммеров. За что я люблю хорроры, так это наблюдать потом за игроками, когда игрок пугается или начинает паниковать, я злобно смеюсь, потираю ручки и шепчу «шалость удалась». Ну и разумеется доволен победой по очкам на КОД, хотя удалось вырваться вперед не во всех номинациях.

FriendRender.jpg

FriendRender1.jpg

FriendRender2.jpg