Пару лет назад мы решили делать игры, и теперь в нашем коллективе сформировалась своя геймдев-студия — Feed 64. В этой статье расскажем, как мы используем любимый многими инструмент, Figma, в левел-дизайне мобильных игр.
Приступив к работе над играми, мы надеялись, что случайная генерация бесконечных уровней позволит сэкономить ресурсы за счет левел-дизайна. В итоге все равно пришлось все делать вручную. Изначально мы планировали создать алгоритм, который будет генерировать игровой коридор из небольшого массива чанков, но быстро отбросили эту идею, потому что скрипт создавал скучные и нелогичные уровни.
Так, от идеи генерации комнат мы перешли к генерации уровней из заранее созданных комнат в случайном порядке. Благодаря этому подходу мы можем управлять сложностью игры, а ловушки и препятствия получаются изобретательнее. Минусы тоже есть, и главный из них состоит в том, что игрок быстро заучивает расположение элементов в каждой из комнат и ему становится скучно. Решение тоже есть: комнат должно быть очень много.
Левел-дизайном в нашей небольшой команде занимается не один человек. Раздавать ключи от движка неудобно, поэтому мы обратились к более привычному для нас, веб-разработчиков, инструменту — Figma. Им сейчас пользуются очень многие, и при появлении нового сотрудника будет легче показать ему, как наша система работает в Figma, чем учить пользоваться движком.
Двойная работа, которая экономит время
В Figma у нас образовалась целая экосистема из проектов, и мы подумали, почему бы не ввести в нее и левел-дизайн? Тем более, что наши игры — модульные и двухмерные. Все прототипы, дизайн интерфейса, структурные и организационные детали уже собраны в приложении и доступны для всех членов команды.
Хоть созданные в Figma комнаты и приходится пересобирать с нуля в движке по отрисованному шаблону, а потом обкатывать и оптимизировать, это все равно экономит время и силы.
Вот как выглядит Throworm в Figma и в готовом виде на движке
Выше были примеры из Throworm, теперь перейдем к Gennady. При проектировании нам помогает габаритная модель физики персонажа. В модулях мы вычислили все возможности персонажа: длину и высоту горизонтального и вертикального прыжка, двойного прыжка, дэшей во всех направлениях и далее по списку. Все траектории мы отрисовали в виде набора заготовок. В рамках конструктора они легко укладываются на уровень, что помогает не только вычислять длину ям, высоту препятствий и прочие параметры, но и продумывать и визуализировать целые маршруты оптимального прохождения комнат, отчего процесс игры становится увлекательнее. В движке это делать было бы трудоемко и не так удобно.
Габаритная модель движений персонажа
Потом мы создали модульную систему компонентов в Figma, а в движке — ее аналог. Систему разбили на типы блоков, создали их родительские компоненты: элементы пола, потолка, препятствия и так далее. Затем мы наделали из компонентов массивы блоков, чтобы ускорить и упростить сборку комнат, а единичные блоки использовать лишь в отдельных случаях. Аналог, опять же, скопировали в движок. Помимо этого в игре много других элементов: вертикальные и горизонтальные платформы, разливы кислоты, прессы, — и все они собираются, как конструктор.
Монеты тоже собраны в предзаготовленные блоки: дуги выстроены в соответствии с габаритной моделью, что позволяет персонажу правильными прыжками рубить бабло миллионами, а на определенных участках монеты могут не только провести по оптимальному маршруту, но и заманить в ловушку.
Сначала мы рисовали комнаты чисто схематически, а позже, благодаря изначально грамотной настройке системы компонентов, перевели все уже собранные комнаты на игровые текстуры, отчего левел-дизайн стал максимально приближен к геймплею.
Сборка комнат в конструкторе в Figma до/после подключения игровых текстур
Так как по жанровой принадлежности Gennady — роглайт (облегченная версия роглайка), мы за максимум рандома и повышение реиграбельности экономными средствами. В нашей системе левел-дизайна, помимо самих комнат, в произвольном порядке появляются враги, препятствия и монеты. Принцип следующий: процент прозрачности объекта в нашем левел-конструкторе соответствует вероятности появления этого объекта на уровне. Например, монеты вдоль пути движения персонажа сразу заложены в блоки пола, вот только появляются они не всегда. Тот же принцип действует и с целыми типами блоков — если наложить друг на друга два полупрозрачных блока, то на уровне в этом месте появится любой из них.
Пример комнаты, собранной в Figma с игровыми текстурами
Один из больших плюсов Figma — она позволяет удобно и наглядно сортировать все созданные элементы. Готовые комнаты и только задуманные, чтобы как-то разогнать креатив, условно сгруппированы по типам. Например, лутовые комнаты, разрушаемые комнаты, быстропробегаемые, хардкорно-ловушечные, пазловые и так далее. Типизация условна, зато позволяет не зацикливаться на чем-то одном, а создавать более разнообразные ландшафты.
Нам это настолько понравилось, что мы решили пойти дальше. Теперь мы настраиваем конструктор таким образом, что сборка ландшафта становится адаптивной — размеры блоков подстраиваются под нужные запросы движением руки, а еще можно сразу добавить сверху отрисованные тайлы, благодаря чему комната практически приобретает финальный вид.
Figma отлично оптимизирована, но при создании огромного количества комнат с таким же огромным количеством элементов подлагов не избежать. Нам помогают с этим справиться три приема: