Pirate Ships Dev Blog
July 4, 2023

Pirate Ships. Сюжет мобильной игры и нейросети

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

Оглавление: Вводные / С чего начать / Интро / Сюжет / Игровая карта / Диалоги и персонажи / Обординг / Итог

Вводные

Pirate Arena - это мобильная игра об автоматических сражениях на пиратских кораблях, которую мы делаем небольшой командой в Herocraft. Игра находится в релизе, в нее играют люди, потому разрабатываем мы итерационно и последовательно, слой за слоем наращивая разные части продукта. На этот раз очередь дошла до сюжета.

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

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

А в режиме кампании ожидают покрывшиеся пылью заглушки сюжета:

В общем, пришло время найти форму для истории.

С чего начать

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

Это пример работы ChatGPT, при обобщенном запросе по формуле “придумай сюжет для игры в пиратском сеттинге”. На мой взгляд, такое поведение характеризует нейросеть как инструмент. Можно уточнять запрос, в духе “сделай больше персонажей” или “придумай твист в конце”, но придется делать это до тех пор, пока сумма кусков не достигнет объема полноценной концепции. И чем больше кусков в этом случае - тем лучше результат.

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

На моем опыте, такой подход напоминает поиск референсов в Pinterest, когда после длительного серфинга по сайту, обнаруживаешь себя воодушевленным и “полным идей”, ни одну из которых не получается применить. Потому я решил формулировать из собственного опыта.

Интро

Первое, что пришло мне в голову, это создание аналога королевской битвы. Это казалось хорошим решением, так как не требовало линейной проработки сюжета, только установки правильного контекста. Я набросил раскадровку интро, объясняющего конкурентную цель всех пиратов. Это была история о том, как все в пиратском мире узнали, что басни сумасшедшего старика о сокровищах оказались правдой. Фрагмент раскадровки:

История получилась слишком простой и обезличенной. Так что, когда появилось больше времени, я сделал еще подход к сюжетной концепции. На этот раз я действовал смелее и агрессивнее: крутил камеру в движке, нарезал коллажи из пинтерестовских картинок, менял персонажей.

Так родились три базовых идеи:

  • Игра начинается с ролика на движке, в первую очередь демонстрируя визуал и боевую часть кор-геймплея;
  • Интро ролик включается после демонстрации игры и перед началом онбординга, устанавливая сюжетную рамку;
  • Главным персонажем, на замену добродушному Диего, приходит рыжая девушка. В теории, мужской части игроков, на которых мы целимся, она должна была понравиться больше.

Теперь игра начиналась с ролика на движке:

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

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

После интро на движке запускался синематик:

И так, представление сложилось. Реализация части на движке ушла к программистам, а визуальная составляющая - к нашему художнику. При помощи Stable Diffusion и своих волшебных рук, за несколько итераций он собрал чистовые кадры:

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

Для достижения схожести персонажа между кадрами, промт содержал подробное описание девушки: красный жилет и волосы, коричневые перчатки, белая рубашка с длинными закатанными рукавами и т.д. Каждая поза реролилась по нескольку раз, а некоторые детали дорисовывались после, например юбка и воротники. Особенно плохо у ИИ получались перчатки.

Подобным образом он проработал стилистику и создал главную героиню:

А также сделал логотип игры. Да, череп по центру тоже сгенерирован в Stable Diffusion:

Наконец, я взял нейронку LeiaPix, и, поиграв с настройками, добавил картинкам объема и динамики. Это бесплатное приложение генерирует карту глубины на основе изображения, после чего позволяет менять угол камеры для создания объемного параллакс-эффекта.Я выгрузил результаты как видео, смонтировал с музыкой из доступного ассет-пака и вуаля! Можно встраивать!

Посмотреть превью можно тут: видео на YouTube.

Сюжет

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

Часть изначального промта:

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

А вот некоторые из предложений нейронки:

  • Восстание мертвецов: В результате использования одного из артефактов возникает неконтролируемая магия, которая оживляет мертвых пиратов. Игрокам предстоит остановить это явление, уничтожив источник магии и вернув мертвецов в мир мертвых.
  • Королевская армада: После слухов о падении комет и магических артефактов, королевская армада начинает активные действия по поимке пиратов и изъятию артефактов. Игрокам придется сражаться с королевскими кораблями и отстаивать свою свободу.
  • Появление таинственного путешественника: на корабль игрока поднимается таинственный путешественник, который предлагает помощь в обмен на защиту от своих преследователей.

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

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

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

“Я буду описывать тебе сценарий, в котором оказался игрок, а ты на его основе придумай персонажа, диалоги между персонажами и представь в виде таблицы, где в левом столбце будет имя говорящего персонажа, а в правом его реплика. Не используй кавычки. После таблицы добавь короткое описание внешнего вида персонажа. Персонажи должны быть выразительными и эмоциональными, старайся держать драму, но при этом добавляй легкий юмор. Для разных сцен используй разные эмоции. Со стороны игрока всегда говорит Элизабет Рид, рыжая молодая пиратка. Игрок не говорит реплики и не упоминается по имени. Элизабет вместе с игроком попадает в ситуации, которые я буду тебе описывать. Каждая ситуация или сцена происходит по сценарию: сперва затравка, до четырех сообщений в сумме, потом игровой бой без диалогов и после завершающий диалог до шести сообщений в сумме. И так, следующий сценарий: …”

Самый драматичный диалог из получившихся, на мой взгляд:

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

Игровая карта

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

Изначально карта кампании была зафиксирована в пространстве и выглядела как типичный роадмап:

В новой версии камера расположена гораздо ближе к столу:

Теперь на карту поместилось больше врагов и сюжетных точек, а путь стал ощущаться значимее, как большое путешествие.

Бонусом, на экране сам собой появился интерактив - теперь карту можно зумить и скролить, рассматривая детали на столе:

Диалоги и персонажи

Разумеется, визуальная часть подачи наиболее важна. Потому мы обновили окно диалогов:

Старые персонажи стали сильно выбиваться по стилю, так что наш художник при помощи Stable Diffusion сгенерировал несколько новых, поймав нужную рисовку.

После, я смешал получившиеся изображения в Midjourney, буквально залив их в Discord и записав полученные ссылки в один промт, а после добавил текст описания. Схематично так:

/imagine картинка1, картинка2, картинка3, портрет старого пирата, серый фон, цветной, красивый, в стиле… и т.д.

На выходе получился бесконечный генератор персонажей в нужном стиле:

Онбординг

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

Главное - ритм! В предыдущей версии онбординг работал равномерно, показывая одновременно указатель, анимированное кольцо для фокусировки внимания и диалог персонажа, произносящего задание:

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

Границы задач были размыты, они переползали одна в другую:

Если вообразить количество интереса в каждом кадре, то ритм был бы примерно таким:

В теории, такая монотонность со временем теряет эффективность, столбцы будут все меньше и ровнее. Но что, если сделать ритм более выразительным?

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

Оканчивается блок диалогом, завершающим текущую задачу и сообщающим о новой:

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

Плюс, по визуальной части, мы переделали руку-указатель. Теперь она анимирована и кольцо для привлечения внимания стало неактуальным:

Итог

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

По поводу нейросетей: нет, это все еще не кнопка “сделать красиво”, но отличное подспорье в работе, когда у вас есть сформулированная суть, и ее требуется размножить.

Ну и о процессах, на последок. Существует такое представление о разработке: всегда нужно четко понимать что ты делаешь. Идеальная картина, безусловно так. Однако на практике часто нет времени и ресурсов, чтобы все спланировать заранее, “на берегу”. И в этом случае может быть эффективнее работать в неопределенности.

В конце концов, решение работать в неопределенности - тоже определенность. А вероятность успеха повышает не столько план, сколько сила собранной команды.

Дорога возникает под ногами идущего, как известно. Но я вам не рекомендую :)


Мой блог о разработке: Пайплайнер. Подписывайтесь, ставьте комментарии, пишите лайки. Также велкам в личку тг: @alexanyone