Adventure Jam 2016
Хочется рассказать про опыт участия в Adventure Jam 2016. Некоторое время назад я решил попробовать принять участие в каком-нибудь геймджеме и вывесил пост про поиск команды в одном из сообществ вконтакте. Прошло больше месяца, никто не писал, и я уже забыл об этой затее, но внезапно на связь вышел художник Сергей. Довольно быстро мы нашли крупный конкурс длиной в две недели, темой которого были игры-адвенчуры. Решено было делать классический point’n'click-квест. Команду пополнили аниматор Борис и композитор Василий, за несколько скайп-сессий мы обсудили сеттинг и сюжет, после чего принялись за работу. Под катом вы найдете небольшой постмортем в четырех частях от лица каждого участника команды, с описанием техпроцесса, проблемами и решениями, впечатлениями и выводами, которые каждый вынес из участия.
Часть Виктора (код)
I. Движок
После того как мы определись с жанром и механикой, настало время выбирать оружие. Чтобы в вашу игру поиграло наибольшее количество людей, она должна быть максимально доступной. Мало кому хочется качать и ставить билды по несколько сотен мегабайт, тем не менее, многие участники выбрали именно этот путь. Запусков у игр, поддерживающих браузер, больше на порядок, поэтому идеальным вариантом было сделать что-то под веб. У меня довольно много опыта с С++ версией Cocos2d-x, но она ориентирован на десктопы и телефоны/планшеты, а вот JS-версия позволяет запускать игру в том числе и в браузере. На JavaScript я до этого ни разу ничего не писал, продолжительность джема — всего две недели, поэтому этот вариант вызывал определенные опасения, но наличие опыта с самим фреймворком и С-подобность JS выглядели неплохой компенсацией.
II. Хронология
Разработка началась с импорта тестовой сцены и эффекта параллакса (когда разные слои движутся с разными скоростями, создавая иллюзию глубины). Здесь очень помог Python, в котором есть замечательный модуль psd-tools, он позволяет читать PSD-файлы и экспортировать слои как отдельные изображения. Скрипт парсил полученную от художника сцену и генерировал папочку с картинками и json с координатами.
Далее настала очередь главного персонажа, нужно было научить его передвигаться по сцене и взаимодействовать с объектами игрового мира. Я решил задать возможные пути в виде графа, при клике на сцену героиня шла к ближайшей вершине, прокладывая себе путь обходом в ширину. Когда объект для взаимодействия оказывался достаточно близко, на нем появлялись кнопки с возможными действиями.
Основа геймплея была готова, оставалось релизовать сюжет. На это ушло около недели довольно бодрого программирования по вечерам после работы. Прошлое знакомство с движком дало свои плоды, каких-то существенных проблем на этом этапе не возникло, но все требовало времени. Кульминацией стала ночь перед дедлайном, пришлось сурово посидеть до 4 часов утра.
III. JavaScript
JavaScript как будто создан для режима code like hell. Скорость разработки по сравнению с С++ больше раза в 3–4, без шуток. Мне хватило одного поста (https://developer.mozilla.org/en-US/docs/Web/JavaScript/A_re-introduction_to_JavaScript) и примеров из движка, чтобы за пару дней начать более или менее изъясняться. Конечно, поспешность сказалась на качестве кода, но, с другой стороны, на то это и джем.
В качестве IDE я использовал WebStorm, автокомплит работает отлично, ошибки подсвечиваются. Для отладки вместо веб-версии запускал нативный билд, в котором забиндил кнопку R для перезагрузки всех скриптов с диска. Пришлось пожертвовать возможностью пошагового дебага, но он оказался не очень-то и нужным. В итоге workflow был следующим: пишем код, альт-таб в приложение, R, все за секунду подгружается, смотрим на изменения, альт-таб в IDE, пишем код. Скорость итераций неимоверная.
Еще один положительный момент в JavaScript — возможность переопределить метод у существующего класса или расширить его без наследования, например вот так:
cc.Node.prototype.runActionWithDelay = function(delay, action) {
this.runAction(cc.sequence(cc.delayTime(delay), action));
}
В кокос все обычно вставляют свои костыли, пользуясь его опенсорсностью, а потом возникают проблемы с апдейтами. В JS-проекте все дополнения и изменения подобного плана можно собрать в одном месте и обновлять версию двжика методом копипаста.
Механизм заливки оказался довольно простым, cocos compile -p web -m release, архивируем, заливаем на gamejolt.com или itch.io, там же можно указать размеры окна с игрой, что позволяет избежать мук с разрешениями. Игр, использующих Cocos2d-x, несмотря на простоту и удобство разработки, на GameJolt довольно мало, я думаю наша была первым проектом на JS версии.
IV. Проблемы
Анимации пресонажей и действий делались во Flash, для импорта использовали покадровую нарезку. К сожалению, нормальной поддержки SWF для HTML5 версии движка я не обнаружил, хотя ранее успешно использовал для этих целей SuperAnim в С++ и Lua версиях. Покадровые анимации не самым позитивным образом сказались на размере билда, буквально за несколько дней он разъелся до 130 мб. И хотя на большой размер в веб-версии никто не жаловался, пользователи мобильной версии такой игры сразу заметят неладное. В качестве возможного решения для анимаций можно использовать Spine, он хорошо поддерживается движком и позволяет избежать гиганстких атласов с покадровыми анимациями.
Не очень удачной оказалась реализация передвижения, ребра графа в качестве возможных путей слишком жестко ограничивают свободу. Хотя во многих популярных квестах (например в Machinarium) используется именно такая система, лучше задавать зоны для ходьбы с помощью полигонов. Не уверен, что я успел бы реализовать этот вариант в рамках джема, но в будущем я планирую использовать именно его.
V. Итоги
Перед началом джема необходимо иметь какой-то базовый код для выбранного типа игры. Всегда приятно писать свои велосипеды, но лучше делать это загодя, чтобы оставить максимум времени для написания непосредственно геймлпея. В правилах некоторых джемов прямо запрещается использовать какие бы то ни было собственные надстройки над движками, но с одним исключением: если код выложен в публичный доступ и доступен другим участникам джема, его разрешено использовать — вот и повод выложить свои поделия на GitHub. Я писал все с нуля, и часть моих временных оценок оказалась излишне оптимистичной, что, увы, сказалось на интенсивности последних 2–3 дней разработки перед дедлайном.
Процентов 10–20 от всего времени нужно оставить на полишинг и плейтест — это очень важный пункт, который легко забыть в боевом запале. Пропустить какую-нибудь досадную ошибку крайней легко, и она самым печальным образом скажется на оценках. В этом джеме одну из ключевых механик я начал писать ночью, за три часа до дедлайна, как результат в версии 1.0 было определенное количество неприятных шероховатостей. К счастью правила джема позволяли вносить косметические патчи, после воссатновления хп и маны все огрехи были исправлены.
Я остался крайне доволен процессом и результатом, во многом благодаря товарищам по команде. Джем позвозяет в очень сжатые сроки получить опыт, аналогичный опыту разработки коммерческого проекта в студии за существенно более длительный срок. Рисков фактически нет, поэтому можно использовать любую технологию или язык. Свобода ограничивается только временем.
Часть Сергея (арт)
I. Разработка сеттинга/стилистики
На раннем этапе имеет смысл определиться с сеттингом и стилистикой проекта. Тут я сделаю небольшое отступление. Дело в том, что в игровой индустрии существует мейнстрим, широко распространенные сеттинги (фэнтези, sci-fi и т.д.) и стилистики (визуальные языки, в рамках которых эти сеттинги воплощаются), которые полюбились игрокам. При этом распространено копирование и компиляция, зачастую трудно отличить один фэнтезийный проект от другого, т.к. формы и приемы кочуют из одного проекта в другой. Я убежден в том, что делать то же, что и все, имеет смысл лишь в том случае, если у вас есть достаточно ресурсов и навыков, чтобы сделать это лучше других. В условиях ограниченности ресурсов эффективнее просто отличаться, иметь узнаваемое лицо. Если вы смогли подобрать уникальный визуальный язык, то игрок простит вам возможные огрехи в исполнении, он запомнит вашу игру. Если вы делали то же, что и другие, но не дотянули до того, чтобы поднять планку выше, то все забудут о вашей игре, едва закрыв окно приложения.
Отсюда возникает логичный вопрос:, а как вообще сделать что-то новое? Ответ прост и логичен: нужно брать материал вне среды видеоигр. Это могут быть смежные профессиональные среды, например, иллюстрация и другие формы изобразительного искусства — в них можно найти уже готовые, проработанные изобразительные языки, которые еще не воплощались в играх (так, например, сделали создатели Year Walk — сравните то, что они сделали, с работами иллюстратора Jon Klassen). Можно также искать материал в других сферах жизни, но тогда перерабатывать и унифицировать его в стилистику вам придется самим.
В рамках этого джема я решил пойти по второму пути, и взял в качестве материала страшноватые объекты с постсоветских детских площадок. Я не припомню, чтобы кто-то использовал такую эстетику в видеоиграх, так что мне весьма интересно было ступить на непаханое поле.
1) Сбор материала и отбор
Еще до начала джема я основательно покопался в недрах рунета и собрал множество референсов. Проанализировав их, я сделал вывод, что объекты с детских площадок очень сильно разнятся эстетически, и рисовать их без предварительного отбора и унификации было бы ошибкой. Сильнее всего объекты отличались по материалу — были деревянные, как правило вытесанные из бревен, металлические и сделанные из грубо покрашенных цементных глыб. Каждый из видов представляет собой очень богатый материал, но для простоты я решил выбрать один вид — деревянные статуи.
2) Предварительные наброски объектов.
Задача этого этапа — поиск стилизации и дизайна объектов. Срисовывать статуи один в один, не стилизуя — не лучшая идея, т.к. результат вышел бы менее выразительным и более разнородным. Нужно было провести поиск выразительных средств, посмотреть, как вообще объекты будут смотреться, будучи выраженными через линию и упрощенными. Это именно тот этап, где материал перерабатывался в узнаваемые и зарифмованные формы.
На этом этапе у меня уже был материал, который можно было показать коллегам и обсудить, что мы вообще делаем, какую эмоцию передаем, чтобы это было не просто на словах. Материал, который я собрал на предыдущем этапе, можно было переработать очень по-разному, и каждый вариант имел бы свою интонацию. Когда примерно понятны стилизация и дизайн, другие участники команды уже могут понять, какую эстетику мы воплощаем, нравится она им или нет, и как они будут строить свою работу. В совместной работе очень важно быть уверенным, что вы имеете в виду одно и то же.
3) Наброски композиции
На этом этапе я продумывал сюжет игры одновременно с размышлением над композицией отдельных фонов. Изначально мы задумывали сделать несколько сцен и даже миниигру. Джем, как водится, внес свои коррективы — мы успели только одну сцену, и сюжет не получился завершенным. Однако в рамках джемов более выгодно выглядят проекты, которые выглядят не как завязка, а как полноценные произведения. Здесь мы допустили промашку — нужно точнее понимать свои силы и распределять их так, чтобы успеть исполнить минимальный объем задуманного. Часто стоит делать контент менее проработанным, чтобы успеть больше. К сожалению, я имею привычку закапываться в деталях, это моя хроническая ошибка. Возможно, десяток джемов отучит от этого. Было бы неплохо.
II. Производство контента
Собственно, от начала джема прошла уже пара дней, и в глаза бросалась следующая проблема: другие члены команды не могут толком начать работу, пока я не выдам им контент. Аниматор Борис не мог начать анимировать персонажа, пока нет персонажа, а программист Виктор не мог собирать сцену и разбираться с движением персонажа, пока не определена хотя бы на кубиках композиция сцены. Нужно было срочно что-то с этим делать.
1) Персонаж
Поэтому я отложил работу над фоном, чтобы быстро сделать персонажа. К сожалению, у меня не было толком времени подумать над его дизайном, и, что самое страшное, я даже не мог определиться с его цветовой схемой, пока неясна цветовая схема фона. По-хорошему, решение персонажа должно приниматься в зависимости от среды, в которой он находится, но над ней предстояло еще много работать. Поэтому я быстро сделал персонажа наобум, надеясь, что он впишется по цвету в будущий фон. На случай, если не впишется, мы с аниматором оговорили возможность его перекраски при условии сохранения самих форм неизменными.
Итак, персонаж был готов. Из-за костюма он получился некоторым оммажем Коралине из известного анимационного фильма, о чем я жалею. Стоило сделать персонажа более уникальным. Так или иначе, персонаж был нарезан на векторные части и отдан аниматору, чтобы тот сделал базовые анимации движения.
2) Фон
Что касается фона, то напрашивалось такое решение — использовать для прототипа еще не прорисованный фон, но уже с нарезанными и должным образом проименованными слоями.
Так и сделали, и в дальнейшем ребята работали именно с таким прототипом задника, а я мог спокойно работать над финализацией графики у себя.
3) Разработка фона:
-предварительный набросок (thumbnail sketch) композиции
-проработанный линейный рисунок (lineart). Я редко делаю детальные лайнарты, поскольку не хочу делать лишнюю работу — лайнарты сильно меняются при покраске объекта и частично даже не используются. Поэтому этот этап у меня не так сильно отличается от предыдущего.
-заливки форм, каждому объекту — отдельная заливка по силуэту. Как раз на этом этапе я отдал ребятам черновой вариант графики (см. п.2).
-прописывание каждого объекта одного за другим внутри заливки, начиная с самых крупных масс. Вот это опасный номер. Дело в том, что делая так, мы нарушаем принцип «от общего к частному» и рискуем получить картинку с абсолютно дробной цветовой схемой, где объекты не сочетаются друг с другом ни по цвету, ни по тону. Поэтому делать так имеет смысл только если у вас много опыта и вы в уме хорошо представляете, какой цвет где должен быть, или если композиция очень проста. Я делал так, потому что иначе я бы вообще не успел, пришлось понадеяться на свой опыт. Классическое решение данной проблемы — это как делают академические художники: перед началом картины они делают этюды, в которых прикидывают общее цветовое и тоновое решение. Но у них нет другого выбора, т.к. если они испортят картину, то все, ничего не поделать. В цифре есть и другие способы решения данного вопроса, в целом каждый делает как ему удобно.
В итоге получился такой фон. Хочу также упомянуть, что я прописывал фон, учитывая цвет персонажа, тк необходимо, чтобы в любой точке фона персонаж был читаемым. Так что перекрашивать персонажа не пришлось.
Вот, в общем-то, и все. Последние несколько дней мы в основном в спешке работали над геймплейными и сюжетными моментами, работа по графике, анимации и звуку уже была закончена.
III. Послесловие
За две недели джема я выходил из дома всего несколько раз, работать пришлось много и быстро, но у меня уже был опыт участия в джемах, и я знал на что иду. Опыт того, что за небольшое количество времени и концентрированной работы, у вас получается нечто новое и живое, очень ценен. Это совсем не похоже на то, как строится работа в студиях, с их большой сложившейся иерархией, неповоротливостью и коммерческой ориентированностью. Суть геймджемов именно в свободе и радости творчества. Для одних это хорошая возможность попробовать воплотить идеи, которые давно хотелось воплотить, для других — возможность нащупать новые механики, для кого-то — избавиться от ограничений, связанных с работой на заказчика и необходимостью соответствовать его ожиданиям/требованиям. Я очень благодарен коллегам, с которыми мы сделали эту игру, за то, что они вложили свое время и свой талант в нашу общую затею, каждый вложился как мог.
Часть Бориса (анимации)
I. Flash
Говорить о работе аниматора в этом проекте — сущее наказание. Практически все, что я делал, было сделано не совсем или совсем не так, как это делается обычно. Мы не обсуждали с художником-постановщиком характер анимации персонажа, практически не обсуждали графику (здесь обошлось, поскольку Сергей сделал персонажа максимально условным, что существенно развязало руки аниматору, то есть мне), анимации взаимодействия персонажа и объектов фона мы «запекали», что привело к небольшим скачкам в четкости объектов, мы использовали Flash исключительно как графический инструмент, так как в игру анимация импортировалась в форме растровых сиквенсов. Сделано это было, разумеется, не из-за безалаберности, а из-за катастрофической нехватки времени.
Поэтому описать работу над анимациями персонажа можно очень коротко: я делал это очень быстро и очень неправильно.
II. Подготовка движения
А вот рассказать об анимации объектов фона — деревянных изваяний, будет полезно. Здесь у аниматора вообще минимальная свобода: объекты практически не имеют движущихся частей и заранее отрисованных фаз движения (состояния объекта, которые не могут быть сделаны простым перемещением его частей, например градации «расколотости» хранителя ключа). Для борьбы с эти используется прием «подготовка движения». Прием формулируется так: подготовка движения важнее самого движения. Глаз, вернее мозг, часто обманывается и «дорисовывает» недостающие части движения, грех этим не воспользоваться. Рассмотрим пример.
Продолжительность анимации раскалывания хранителя ключа — двадцать кадров, и половину из них мы используем даже не на движение, а на замах: десять кадров изваяние слегка увеличивается в высоту, усы и брови слегка опускаются внешними концами вниз. За это время глаз обращает внимание на происходящее — движение началось. С десятого по двенадцатый кадр статуя начинает резкое движение вниз (брови и усы отыгрывают в противоположную сторону, имитируя инерцию), в тринадцатом кадре мы подменяем изображение слегка расколотой статуи на совсем расколотую. Эта фаза по высоте немного ниже предыдущей и иллюзия продолжения движения сохраняется. Единственная подвижная часть в этой фазе ключ и с тринадцатого по двадцатый кадр он совершает одно качание, завершая движение. Таким образом, при проигрывании мы получаем связное движение, хотя собственно анимации раскалывания в этой последовательности вообще нет. После этого можно тихонько сказать себе: «Ура!» — мы обманули глаз, использовав минимальное количество фаз.
Часть Василия (музыка)
I. Вводная часть
Когда мне предложили поучаствовать в джеме, я согласился почти сразу же, мне очень понравилось визуальное решение игры, а также концептуальная часть — игр, которые возвращали бы тебя в детство, не так много, как может показаться, поэтому попробовать воссоздать такое ощущение — это интересная задача. Кроме того, мне понравился подход автора идеи Сергея, который заключался не в режиссерском деспотизме «сделать надо как мне виднее», а в полной творческой свободе «ты лучше знаешь, как это должно быть». В таком случае — ты сам себе заказчик, а кто будет принимать работу строже внутреннего критика? Так что это было интересное предложение, и я согласился.
II. Музыка
Музыка в играх такого жанра, как правило, играет важную роль: она не должна сильно надоедать, поскольку мы не знаем, за какое время игрок решит ту или иную задачу, прежде чем зазвучит другой трек. Поэтому важно, чтобы мелодия была ненавязчивая и не оттягивала на себя внимание. Во время разработки нашей сцены было решено сделать три мелодии — стартовую, мелодию «что-то пошло не так» и динамичную, нагнетающую тему. Звучит довольно просто, если говорить о классических хоррорах, однако в нашем сучае — это все же ощущение детства, некоторой сказочности всего происходящего. Музыка должна была подчеркивать настроение, а не пугать.
Таким образом в основу первых двух треков легли импровизации на электропианино (я использовал синтезатор waldorf blofeld как инструмент, обладающий широкими возможностями для мягкого и глубокого звука), синтезаторная партия на «заднем плане», электронный бас и струнные секции. От ударных и перкуссии я решил отказаться вовсе. В итоге получились довольно ненавязчивые темы, которые при проигрывании в цикле не напрягали игрока и свободно сменяли друг друга. Третья музыкальная тема была сделана с использованием тех же инструментов, кроме того, что в ней были использованы помимо протяжного звука струнных короткие музыкальные фразы, вполне классического звучания. Также, настроение третьей темы довольно весомо отличалось от первых двух, что в итоге позволило выделить своего рода кульминацию игрового повествования.
III. Звуковое оформление
Говоря о звуковом оформлении я отталкивался от материалов наших персонажей. Как правило всё это деревянные истуканы, поэтому очевидным решением стал треск и скрип рассошегося дерева. Такой подход оправдал себя в моментах касающихся «Хранителя ключа», создать звук «деревянного чихания», движения усов из коротких семплов самых разных скрипов оказалось довольно интересной задачей. Анимации озвучивались отдельно, так, чтобы звуки были синхронизированы с движениями, а на шаги персонажа-девочки я создал дополнительный набор хрустов, которые проигрывались в случайном порядке, в определенном интервале шагов. Фоновым шумом для всех игровых моментов стал звук сверчков — тоже стандартное решение, которое прекрасно себя оправдало. Хотя иногда хочется удивить нетривиальным подходом к решению задач звука, нужно также понимать, в каких моментах велосипед уже изобретен. Было бы здорово, конечно, озвучить реплики персонажей, но в наших условиях это было уже перфекционизмом. К слову, факт того что реплики не были озвучены дал прекрасную возможность нашим летсплеерам озвучить их самостоятельно.
IV. Резюме
В завершение хочу сказать, что для меня это был первый опыт участия в каких бы то ни было джемах. И это был очень интересный опыт. Ощущение того как почти незнакомые люди работают как одна команда усиливалось все время, пока мы разрабатывали игру, и я хочу выразить признательность моим коллегам за уникальную возможность не просто выполнять свою работу, но и буквально сразу же видеть и ее реализацию, возможность видеть ошибки и сразу же их исправлять. Хотя ограничение по времени должно подразумевать напряжение, для меня этот опыт был скорее приятным, позволившим лучше разобраться в своих возможностях и узнать новые аспекты разработки игр. И хотя я уже достаточно давно вовлечен в эту индустрию — она не перестает меня удивлять. Всегда найдется что-то новенькое, и это невообразимо здорово.
Если вы занимаетесь разработкой игр и еще ни разу не участвовали в джемах, вот несколько сайтов, где можно найти неплохую подборку уже идущих и предстоящих конкурсов:
http://www.indiegamejams.com
https://itch.io/jams
http://jams.gamejolt.com/browse/active