Русский
Русский
English
Статистика
Реклама

Разработка игр

Сыграйте на выпивание с Ричардом Левелордом Греем. Онлайн, без смс и регистраций

19.06.2020 14:16:52 | Автор: admin

Вы когда-нибудь мечтали сходить в бар и потусить с легендой своего детства? Тогда легенда выезжает к вам.

ЗАВТРА, В субботу 20 июня пройдет прямой эфир с Ричардом Греем в необычном формате: zoom-вечеринка, где вы можете сыграть с Ричардом на выпивание, поболтать с ним о жизни, гейм-индустрии, послушать байки и выпить вместе бутылочку пива или чего покрепче.

Правила игры простые:

  • Вы задаете Ричарду вопрос
  • Если на этот вопрос он еще не отвечал ни на одном интервью выпивает Ричард
  • После каждого третьего отвеченного вопроса выпиваете вы
  • Игра заканчивается через 60 минут

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

Кто такой Ричард Левелорд Грей
Ричард легендарный гейм-дизайнер уровней, создатель игр Duke Nukem 3D, SiN, Blood. Также Ричард создал несколько уровней для Quake: Scourge of Armagon.

Внес значительный вклад в то, как проектируются игры сейчас он автор первой карты вида острова в пустоте, которые теперь считаются классикой уровней.

Также он отец одной из первых пасхалок в играх, знаменитой надписи You are not supposed to be here на стене в спрятанной комнате в Duke Nukem.

Последние годы Ричард живет в России, но прямо сейчас застрял в Далласе из-за эпидемии Covid-19, очень скучает по России и будет рад встретиться с русскими ребятами и посидеть, будто он уже в Москве.

Сейчас Ричард консультирует Mundfish с их новой игрой Atomic Heart первой ААА-игрой, которая создается российской командой.

Где пройдет трансляция


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

Как включить пуши на каждой платформе
Инстаграм пуши будут приходить только от конкретного аккаунта

Ютуб


О чем Ричард с радостью поговорит:


  • О России, о том, как застрял в Техасе, о сумасшествии мира на Короне
  • О Москве и за что ее любить
  • Маленькие проекты, которые он делал, но мир так их и не увидел
  • Becky Brogan Adventures последняя профессиональная игра, которую делал Ричард и почему он обожает работать в команде из одного человека его самого. Почему практически нереально делать инди-игрушки одному
  • Как Ричард занимается дизайном и консультированием в Levelord Games
  • Game Garden и Dou Dou Games
  • Работа со школой бизнес-информатики ВШЭ, работа со Славой Уточкиным
  • 20 юбилейный выпуск Duke Nukem с Gearbox
  • Работа с Balanced Media, HEWMEN
  • Atomic Heart почему это первая ААА-игра, которую Ричард ждет, команда проекта, нравится ли ему атмосфера, история, технологии
  • Motion capture, VR, AR и другие технологии, которые вдохновляют Ричарда

Как задать Ричарду вопрос?


Есть 3 способа:

  1. в комментариях к этому посту в инстаграм
  2. в комментариях к этой статье на Хабре
  3. в комментариях прямо во время стрима на ютуб и в инстаграм

Приоритетом обладают вопросы, заданные в инстаграме. Потом уже вопросы во время стрима, потом Хабр-комментарии. Если вы не будете в эфире, но вы задали вопрос на него все равно ответят.

Будет ли перевод на русский?


Да. Эфир будет на сдвоенном экране, и к Ричарду подключится девушка и будет переводить все, что он говорит, на русский и помогать ему с переводом сложных вопросов.

Будет ли запись эфира и расшифровка?


Да. Мы всегда делаем расшифровки всех встреч, которые проводим онлайн в нашем инстаграм. Расшифровка появится на Хабре через неделю.

Напоминаем время и место


Начало: 20:00, суббота, 20 июля
Где: наш youtube, или instagram



Подробнее..

Перевод Самый опасный геймер (про четвертое измерение, про игры Braid, Witness и их загадочного творца Джонатана Блоу)

22.06.2020 12:13:23 | Автор: admin
Статья 2012 года

Видеоигры сейчас один и самых прибыльных видов развлечений в Америке, а также один из самых подростковых, глупых и не нагружающих мозг. Серьезно? По крайней мере, так считает Джонатан Блоу. Он самый жесткий критик игровой индустрии и ее самый ценный разработчик, который стремится изменить наше представление об играх и сторителлинге. Следующим релизом, The Witness, Блоу может укрепить свое наследие или закончить карьеру. Может ли истинное искусство процветать в индустрии с многомиллиардным доходом от лазерных пушек и плотоядных пришельцев?



Как и многие состоятельные люди, Джонатан Блоу хорошо помнит момент, когда он стал богатым. В то время, в конце 2008 года, он был в минусе на 40 000 $ и жил в скромной квартире в Сан- Франциско, более трех лет тщательно оттачивая свою видеоигру, Braid в жанре платформер-головоломка с возможностью изменения масштаба времени. (как если бы, Super Mario Bros. встретился с Борхесом), в которую Блоу влил еще 200 000 $. Хотя Braid был выпущена и разрекламирована прессой, на августовском сервисе Microsofts Xbox Live Arcade, Блоу не увидел ни цента от игры, пока в один осенний день он не сел в кафе in the citys Mission district.



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

Однако, на этом сходство Блоу со средним миллионером заканчивается, потому, что в отличие от большинства богатых людей, он, кажется, слегка раздражен воспоминанием о том, как разбогател. Когда Блоу сказал мне во время типично метафизического разговора в парке возле его офиса в Беркли, что его неожиданность оказалась абсурдной, он не имел в виду это в причудливом смысле Можете ли вы поверить в мою удачу? он имел в виду это в философском, разочарованно-горьком смысле глубоко ироничной шутки Провидения.

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

Которая, однако, не означала, что Блоу откажется от своего состояния. Когда Braid стал настоящим феноменом в первый год продал несколько сотен тысяч копий, завоевал множество отраслевых наград и стал Примером с большой буквы в случае с видеоигрой (как с законным творческим средством) Блоу значительно улучшил свой аскетический образ жизни. Вместо своей старой Хонды он теперь управляет алой Tesla Roadster, с низкой посадкой и полностью электрическим двигателем, стоимостью 150 000 долларов, которое рвёт с места словно пуля, когда Блоу жмет газ в пол. И после триумфального года, наполненного лекциями и лаврами, он переехал в просторную квартиру на вершине холма, где из окон открывался вид на восточную часть города и залив сапфирового цвета.



И все же, кроме своего электромобиля достоинства которого он превозносит с мессианским рвением Блоу демонстрирует полное безразличие к материальным плодам богатства. Его квартира в основном пустует; книги по физике и восточной философии навалены беспорядочными грудами, как будто он только наполовину перевез свои вещи. Его минималстичная коллекция мебели почти полностью взята в аренду, в том числе пружинящий бежевый диван, который он купил всего несколько месяцев назад, лишь для того, чтобы нескольким журналистам по видеоиграм, с которыми он договорился о встрече, было где сидеть. Мне никогда не нравились деньги, сказал мне Блоу Мне не интересно иметь много очков на банковском счете. У меня сейчас хорошая машина, но у меня не так много вещей, и я не знаю, на что еще я бы потратил деньги. Так что для меня, деньги это лишь инструмент, который я использую, чтобы добиться цели.

В частности, Блоу решил использовать свои деньги почти все для финансирования самой амбициозной в истории видеоигры, которая, как он надеется, радикально расширит горизонты мира видеоигр. Хотя видеоигры давно достигли полной коммерческой зрелости (например, пропитанный адреналином военный шутер Call of Duty: Modern Warfare 3 набрал 400 миллионов долларов в первые 24 часа продаж в магазинах прошлой осенью), эта форма остается художественным застоем, страдающее от мультяшных убийств и бесконечных продолжений, приносящих доход. Блоу намеревается встряхнуть это подростковое господство с The Witness, одиночной игрой-головоломкой на загадочном заброшенном острове. В среде, все еще ожидающей своего квантового интеллектуального скачка, Блоу стремится сделать The Witness новаторским образцом интерактивного искусства сотворить своего рода гражданина Кейна в видеоиграх.



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

Как разработчик, личный успех которого освободил его от власти монолитных игровых корпораций, Блоу имеет привычку лоббировать риторические ручные гранаты в отрасли. Он заклеймил так называемые социальные игры, такие как FarmVille, злом, потому что весь их смысл в том, чтобы максимизировать корпоративную прибыль, заставляя игроков одержимо регистрироваться и покупать бесполезные внутриигровые предметы. (В одном из выступлений Блоу удалось сравнить разработчиков FarmVille с грабителями, алкоголиками, Берни Мэдоффом и муравьиными паразитами.) Однажды во время онлайн-дискуссии о достоинствах короткого игрового опыта Блоу написал: Геймеры кажется, хвалят игры за то, что они вызывают зависимость, но разве это не похоже на стокгольмский синдром?

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

Тем не менее, несмотря на то, что Блоу может быть суровым по отношению к своей отрасли, он применяет еще более строгие стандарты к своей собственной работе. С The Witness, на который он потратил около 2 миллионов долларов своих собственных денег, он планирует сделать не что иное, как превратить видеоигру в произведение искусства среду, способную создавать нечто более богатое и более значимое, чем предлагаемые в настоящее время мертвые цифровые игрушки.



Блоу рисует в своем воображении игры будущего, которые передают такие же острые и возвышенные впечатления, как те, что можно найти в литературе и фильмах, но выраженные способами, характерными для игр. Если видеоигра будет использоваться в художественных целях, то она должна использовать ее форму каким-то образом, специфичным для этой среды, верно?, сказал он мне. Фильм и роман могут одновременно создавать повествовательные сюжеты, но романы очень сильны во внутренних ментальных махинациях в чем фильмы посасывают, а фильмы хороши в выполнении определенных визуальных вещей. Таким образом, вопрос в том, где находятся игры на той же карте? Это вопрос, на который намеревается ответить Блоу.

Я встретил Джона Блоув начале 2011 года, когда мой друг Том Бисселл журналист и автор, нанятый для написания сценария для The Witness пригласил меня на ужин однажды вечером, когда Блоу посещал Портленд, штат Орегон. Зная неоднозначную репутацию Блоу, я ожидал что-то вроде огнедышащего техно-Демона, охваченного яростью ботаника.
Вместо этого, когда я вошел в квартиру Бисселла, я увидел очень серьезно выглядящего мужчину, медленно исполняющего ряд движений Тай-цзи в гостиной.


Jonathan Blow

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

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

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

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

Хотя такие моменты, как правило, подтверждают репутацию Блоу как мизантропа, на самом деле он почти одержимо добросовестен. Просто у него нет терпения, чтобы няньчиться или поливать дерьмом. Много месяцев спустя в его офисе в Беркли, когда я играл в более утонченную сборку The Witness, я повернулся к Блоу за соседней партой и спросил, не упустил ли я какой-нибудь ключ к разгадке конкретной головоломки. Он уставился на меня взглядом, который мог вбить гвоздь в стену. Ключ к разгадке в том, что ты делаешь это неправильно сказал он. Другими словами: не проси меня думать за тебя.

Даже друзья Блоу выбирают такие слова, как сложный и колючий, когда описывают его. Вы должны подойти к Джону на условиях Джона, сказал Крис Хеккер, его ближайший друг из игровой индустрии, за эмпандасом с Блоу в просторном кафе в Окленде. Это не Давай пойдем и повеселимся. Это больше похоже на Давайте обсудим эту тему или Давай поработаем над нашими играми. Вы не спрашиваете Джона о тусовках, потому что он просто спросит: Зачем?

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

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

Я думаю, что мы могли бы жить намного ближе правде, и нам всем было бы лучше, ответил он.

Беспощадное стремление Блоу к более глубокой правде началось в раннем возрасте. По словам Блоу, родившийся в 1971 году в семье среднего класса из Южной Калифорнии, эмоционально далекий от родителей, он начал выписываться из своей семьи (от которой он по-прежнему отчужден) еще в начальной школе. Его мать была набожной бывшей монахиней, которая постоянно напоминала своему склонному к науке молодому сыну о скором возвращении Иисуса. (Когда старшая сестра Блоу вышла в роли лесбиянки в середине 80-х годов, их мать отреклась от нее.) Отец Блоу весь день работал на подрядчика по обороне TRW, затем возвращался домой и проводил каждый возможный момент один в своей берлоге, где детям были не рады. Очень рано я обнаружил, что дома нет хороших примеров, так что, я вроде как должен был сам разобраться сказал мне Блоу. Я должен был принять парадигму самодостаточности.

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

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

Вместо эмоциональной связи со своей семьей или с другими детьми, молодой Блоу развил глубокую привязанность к компьютерам. Когда он впервые столкнулся с Commodore VIC-20 в компьютерном классе на пятом году обучения, Блоу интуитивно понял это; он видел волнующую чистоту в логике его внутренних систем. И вскоре он почувствовал рывок своего призвания.



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

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



На Commodore 64 Блоу сделал еще одну игру, которая была объективно лучше, чем Pac-Man во многих отношениях, а именно потому, что в ней было большое разнообразие карт.



Но только в середине 20-х годов Блоу начал заниматься разработкой игр. После пятилетнего обучения в университете Беркли, где он изучал информатику и писательское мастерство, но не успел закончить один учебный семестр, Блоу несколько лет метался от скучных технических работ в Bay Area.

В 24 лет, он взял 24 000 $ своих сбережений и с другом из Беркли создал свою собственную гейм-дизайн студию бизнес, который упорно отказывался процветать. Несмотря на то, что они выпустили законченную игру (трехмерную многопользовательскую научно-фантастическую игру о войне с ховертанками). Эта крошечная фирма стартовала как раз в то время, когда кончалась эра небольших студий и началось доминирование многомиллионных корпораций разработке игр. Бизнес рухнул через четыре года, задолженность составила 100 000$.

К началу 2000-х над Блоу нависла серьезная опасность стать провальным разработчиком игр. Он зарабатывал на жизнь консалтингом для технологических компаний и игровых студий, но изо всех сил старался поддерживать любой энтузиазм по этому поводу. У меня ужасная трудовая этика, когда я делаю вещи, которые меня не волнуют, сказал он мне. Я не могу замотивировать себя что-то делать, если это что-то не самое важное для меня. Так что, я бы делал плохую работу.

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

Затем, в конце 2004 года, у Блоу появилась идея Braid, и все изменилось навсегда.
Нет хорошего способа сказать это, но это должно быть сказано: видеоигры, с очень немногими исключениями, являются тупыми. И они не просто глупы, в том радостном, подмигивающем способе, что и большой голливудский фильм; они глупы в своей легкомысленности, мучительно-серьезно глупы, как взрослый человек в силиконовых эльфийских ушах, рассказывающий эпическую поэму о Гэндальфе. Помимо нескольких по-настоящему умных игр, рейтинговые, такие как The Elder Scrolls V: Skyrim и Call of Duty: Black Ops как правило, так простецки и плохо написаны, что они делают фильмы Майкла Бэй похожими на сериал Крестный отец.

В играх кирпично-подобные мужчины выкрикивают такие броские фразы, как Suck pavement!, и держат в руках гигантские винтовки, которые выглядят как двуручная пила, в то время невероятно пышногрудые женщины рвутся в бой в одежде, которая заставит даже фотографа Victoria's Secret покраснеть. Нюансов и развития персонажей в играх просто не существует. В играх любое затруднительное положение или линия диалога, от которой у среднестатистического студента-второкурсника, страдающий от СДВГ, начнут зудеть мозги, вычеркивается, а затем, в идеале, заменяется катсценой чего-то большого взрывающегося.

Даже самые стойкие защитники отрасли признают хроническую тупость современных видеоигр, обычно с беспомощным пожатием плеч, потому что, эй, самые нелепые игры также могут быть самыми веселыми. (В конце концов, тот факт, что в играх Super Mario речь идет о пухлом водопроводчике с густым итальянским акцентом, который прыгает на зловещих двуногих грибах, не делает игры менее приятными для прохождения). Но эта ситуация ставит в тупик защитников видеоигр. Трудно требовать уважения к творческой среде, когда нужно постараться назвать хоть что-то, что можно назвать художественным или высокоинтеллектуальным из того, что в это среде создано за последние 30 лет.

Когда я впервые встретил друга Блоу Криса Хекера в его бунгало в Окленде, он бросился к своему столу в тапочках с клейкой лентой, чтобы показать мне свою любимую демонстрацию этой обескураживающей реальности. Посмотрите на это никогда не подводит, сказал он, склонившись над клавиатурой компьютера. На одном из своих мониторов-близнецов Хеккер открыл раздел трейлеры фильмов на Apple.com; с другой стороны, он загрузил страницу предстоящих релизов GameSpot.com.

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

Люди думают, что игры появятся, когда люди начнут воспринимать их всерьез, сказал Хеккер, взволнованно повысив голос. Нет! К играм не относятся серьезно, потому что материал, который выходит дерьмо. Почему это кого-то волнует? Это просто подростковая ерунда.

Фактически, когда Роджер Эберт лихо заявил в своем долгом (и плохо изученном) эссе, что видеоигры никогда не смогут быть искусством, интеллектуальная элита игрового сообщества смогла указать только два популярных названия, которые могли опровергнуть его утверждение.

Одно из них успокаивающая игра для PlayStation 3 Flower, в которой игрок берет на себя роль ветра и проникает через буколические пейзажи, опыляя растения и исправляя экологические ошибки. Это замечательная игра, такая же художественная, как картины Томаса Кинкейда.

Другим, более подходящим предложением была игра Блоу Braid.

Когда в августе 2008 года дебютировал Braid, никто никогда не видел видеоигру, подобную ей. Одной только ее эстетики было бы достаточно, чтобы Блоу выиграл награду.

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

На первый взгляд, Braid это простой двумерный платформер с боковой прокруткой (игра, в которой персонаж тратит много времени на прыжки между платформами), который логически вытекает из устаревших игр. Тим отправляется на поиски, чтобы спасти принцессу, читает Тим в первой книге, среди облаков и разноцветных блесток, сверкающих на ее страницах. Ее схватил ужасный и злой монстр. Но Braid настолько же о спасении принцессы, насколько Метаморфоза Кафки о насекомом.



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

Вдохновленный альтернативными реальностями, представленными в Невидимых городах Итало Кальвино и Снах Эйнштейна Алана Лайтмана, Блоу создал пять основных сфер, в которых время ведет себя совершенно по-разному. В одном мире некоторые объекты не подвержены перемотке Тимом; в другом его простое движение влево и вправо заставит жителей мира путешествовать во времени назад и вперед.

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

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

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

Это чувство авторства не было случайностью, потому что основной целью Блоу в Braid было передать сообщение, которое, как он выразился, достаточно важно для меня, чтобы я провел три с половиной года своей жизни, пытаясь выразить его. Удивительно, но базовое игровое программирование заняло совсем немного времени. Когда в декабре 2004 года Блоу впервые решил воплотить в жизнь свою идею о перемотке времени, он был в отпуске с другом в Таиланде.

Я чувствовал себя довольно замотивированным, вспоминал Блоу в своей квартире однажды вечером. Итак, я сказал: Почему бы мне не провести эту неделю в кафе в Чиангмае и не заняться этой идеей? И за эту неделю у меня уже была рабочая основа игры.

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

К концу 2005 года, головоломки из Braid были закончены, но Блоу отказался выпускать игру до того, как он почувствует, что она готова. Джона не напрягало время или бюджет, сама игра всегда была на первом месте сказал Дэвид Хеллман, художник, который создал живописные картины для Braid. Я дал Джону кучу идей, и быстрый выбор не был для него главным приоритетом. Даже когда мы приступили к мельчайшим деталям, он все еще искал, что изменить в одной строке, если это позволит сделать ее тоньше.


David Hellman

Блоу упаковал мир Braid с небольшими визуальными намеками на более глубокую историю. И вместо того, чтобы платить композитору игровой музыки за создание саундтрека, Блоу сделал необычный шаг в лицензирование существующей музыки. Люди, которые создавали эти песни, законно заботились о музыке, которую создавали, пояснил он. Это было правило номер ноль, самое важное.

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

После прохождения в Braid пяти основных царств, Тим, наконец, достигает мира, который удерживает его принцессу, места, где время беспрестанно течет оборот. Когда саундтрек катится назад, мы видим, как пузатый рыцарь, спускается по лозе, а у него в лапах принцесса, которая вырывается от него и взывает о помощи. Между Тимом и принцессой стоит длинный горизонтальный барьер. Когда стена огня приближается к ним слева, они мчатся назад к моменту времени, когда они были в последний раз объединены, уклоняясь от врагов и помогая друг другу выбираться из ловушек. Однако, когда Тим наконец достигает принцессы, нет нежной сцены воссоединения влюбленных; вместо этого его прибытие вызывает зловещую вспышку. Мы видим принцессу, спящую в коттедже. Тим беспомощно стоит снаружи.

И затем время начинает перематываться (что заставляет события разворачиваться в их правильной последовательности), позволяя нам увидеть правду: все это время принцесса не ждала Тима, чтобы он спас ее; она бежала от него. То время, когда, казалось, она убирала препятствия для Тима, на самом же деле, она отчаянно бросала их на его пути. Крепкий рыцарь, который ее утащил, на самом деле был ее спасителем. Мы понимаем, что ужасный и злой монстр Тим. Далее следуют звуки взрывов мозга нескольких сотен тысяч игроков.



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

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


Tom Bissell

Однако, к бесконечному ужасу Блоу, основное сообщество видеоигр оказалось не заинтересованным в изучении скрытых глубин Braid. Чаще всего люди предполагают, что игра о расставании, что Блоу горячо отрицает; он даже оставил гневные комментарии на интернет-досках объявлений, чтобы исправить неверные интерпретации. Что еще более распространено, так это то, что люди проходят финальный уровень с принцессой, а затем начинают считать, что это похоже на неожиданный финал М. Найт Шьямалана, сказал Блоу, когда немного поостыл, и смог сдерживать свою ярость. Как если бы вы сказали: Вот, дерьмо, Тим все это время был сталкером! Но это даже не имеет смысла.

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

Другими словами: не просите меня думать за вас.

Несмотря на его хладнокровие, сдержанную манеру вести себя, Джон Блоу вряд ли самый терпеливый человек в Сан-Франциско. Столкнувшись с какой-либо задержкой, он имеет привычку нервно барабанить по ближайшей поверхности или проскальзывать в последовательность Тай-цзи.

Даже не источая бешеной, зависимой от смартфона ауры современного бизнесмена, Блоу является ревностным максимизатором своего времени. Он презирает просмотр спортивных состязаний, потому что слишком мала их реальная отдача от часов, инвестированных в них. Если электрическая бритва и волнистые пучки волос, разбросанные вокруг его раковины в ванной, являются доказательством, он, кажется, сам подстригает волосы дюжиной быстрых движений, когда это необходимо. И чтобы сделать получасовые поездки из своей квартиры в Беркли более конструктивными, Блоу слушает аудиокниги литературной классики в своей Tesla. Когда я пришел в гости, он только что отбросил Анну Каренину за то, что этот роман слишком похож на мыльную оперу. Теперь он слушал Уолдена.

На протяжении всего моего визита, каждый раз, когда я забирался в его Roadster, мы сразу же слышали, как актер делал свое лучшее впечатление Торо, заявляя в стенторианских тонах о пушистых зверях в их норах. Это имело определенное резкое качество. Однако однажды, после долгого разговора о видении Блоу The Witness, шокирующе громко Торо казался почти ясновидящим. С чуть более обдуманным выбором своих занятий, заявил он, все люди, возможно, станут учениками и наблюдателями, поскольку их характер и судьба, несомненно, интересны для всех.

Блоу выключил стерео и повернулся ко мне. Честно говоря, я этого не планировал, сказал он.

В очень многих словах Громкий Торо только что описал центральную идею Блоу для The Witness. В то время как многие современных игр построены на основе стрельбы или прыжков, или, скажем, творческого использования шахтерского оборудования для уничтожения космических зомби, Блоу хочет, чтобы смысл The Witness был актом наблюдения, обращением внимания на окружающее. Говоря об этом, он начинает звучать почти как мастер Дзен. Вещи сокращаются до базовых актов движения и наблюдения, пока эти чувства не станут утонченными, сказал он мне. Чем дальше погружаешься в игру, тем больше речь идет даже не о мыслящем уме, но об интуитивном уме.

Таким образом, игровой мир The Witness источает монашеское чувство тишины и покоя, которое только усиливает великую тайну в его сердце. Когда игра начинается, вы обнаруживаете себя в мрачном коридоре, ваш взгляд сосредоточен на отдаленном участке света. После перемещения вперёд (The Witness, в отличие от Braid, представлен в 3D), вы попадаете в то, что кажется бункером времен Второй мировой войны, как если бы его придумала IKEA, оборудованный редкой модернистской мебелью, сквозь окна проникает солнечный свет. Вскоре вы обнаружите, что застряли в странном комплексе на маленьком острове (установка, вдохновленная классической игрой Myst), чьи пышные сады были созданы и окружены заботой на уровне Букингемского дворца. Единственный ключ к разгадке, почему вы там, который вы получаете, это ряд аудиокассет, разбросанных по всему острову, рассказанных загадочным человеком, который утверждает, что хочет помочь вам. Все здания заперты вам придется выяснить, как попасть внутрь, говорит он, имея в виду сотни разбросанных вокруг голубых панелей-загадок. Но он добавляет: У вас есть время; вам не угрожает какая-то опасность не больше, чем мне, во всяком случае".

Отсюда и игра сама простота (за исключением, конечно, время от времени взрывающих мозг головоломок). Игрок может свободно бродить по острову, принимая вызовы в любом желаемом порядке. Кривой обучения не существует; все, что вы делаете в The Witness, это передвигаетесь, решаете головоломки и замечать вещи. Этот аскетизм следует основным принципам философии игрового дизайна Блоу. То, что я делаю сейчас, это то, как много вы можете сделать и как далеко вы можете продвинуться с минимальными элементами управления, сказал он мне. Каждый раз, когда вы выбираете игру, в которой есть много элементов управления, вы начинаете нажимать не на те кнопки и вновь задаетесь вопросом: "Что же делает X?" Это не тот игровой процесс, который мне нужен. Вместо того, чтобы заставлять вас играть с 15 кнопками, Блоу хочет, чтобы вы обратили внимание на в общем-то, чтобы вы обращали внимание. И он упаковывает The Witness с минимальным и достаточным количеством деталей окружающей среды, чтобы сделать осознанность полезной.
Первый день, который я провел в его небольшом открытом офисе в Беркли, Блоу осмотрел тщательно продуманный новый игровой мир с архитектором-дизайнером по имени Динна Ван Бурен, которую он нанял для проектирования зданий острова. Хотя Блоу и Ван Бурен работали над архитектурой The Witness более года, целью ее визита в этот день было собрать скриншоты зданий для публикации дизайна. Однако остров был в беспорядке. Блоу и его команда 3D-художников активно обновляли визуальные эффекты с тех пор, как я в последний раз видел игру, почти год назад, поэтому сейчас, когда цвета бросались в глаза, а вода мерцала великолепно, в процессе все беспорядочно перемешалось; деревья местами парили на высоте 20 футов над землей, а блестящие клочки травы были похожи на разбитые окна в другом измерении.

Ничто из этого не создавало проблем для Блоу, который не только знал каждую причуду острова, но и сам написал программу редактирования уровней игры. Для первых снимков Блоу пилотировал себя в Крепости, разрушенной серой башне, расположенной среди живых изгородей и пушистых осенних деревьев красного, оранжевого и желтого цветов. Его пальцы пролетели над клавиатурой, складывая и вычитая визуальные элементы. О, мне это нравится, сказал Ван Бурен, когда его взгляд залип на лестнице внутри башни, ведущей вверх. Это на самом деле передает историю этого места. Позже Блоу ускорился к Фабрике, просторному зданию с красной крышей, которое, как оказалось, плыло по ряби океана. Брови Блоу нахмурились. Давайте поместим это на какую-то землю, сказал он, вызывая травянистую равнину.

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

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

И все же, к своему удивлению, я обнаружил лишь несколько атрибутов традиционного повествования в этих лентах очень мало предыстории или драматических сюжетов. Вместо этого я столкнулся с серией очень личных виньеток. В одной рассказчик говорит о своем одиноком детстве в Калифорнии 1970-х годов; он вспоминает, что на каждой перемене он в одиночестве играл на качелях, закрывая глаза и фантазируя, что когда-нибудь Та Самая Девушка просто увидит меня здесь, мои глаза будут все еще закрыты; она подойдет, ничего не говоря, и нежно поцелует меня Я ждал, но этого не случилось. В другой записи он описывает эмоциональную боль, которую он испытывал, когда начал лысеть в 20 лет, и как сегодня полуостров из волос высовывается наружу под углом к левой стороне моего лица. Возможно, самая поразительная запись начинается так: Я мог сделать что-нибудь со своей жизнью, но каким-то образом я закончил создавать головоломки, ни последние из них находятся здесь, на этом острове.

Я отвернулся от монитора и посмотрел на мужчину на диване лицо, залитое светом его ноутбука, V-образная линия роста волос слегка отклонился влево, и я понял, что с самого начала я бродил внутри разума Блоу.

Отложив в сторону описание Блоу The Witness как игры, основанной на обращении внимания, трудно точно сказать, о чём игра. В первом воплощении своей истории Блоу работал с Бисселлом над созданием традиционного повествования, наполненного сложными персонажами и драматическими ритмами, подход, от которого Блоу вскоре отказался, так как он был слишком голливудским. (Только в мире Джона Блоу супер-сжатая история, основанная на картинках из сознания замученного человека, станет голливудским сценарием, усмехнулся Бисселл) Таким образом, Блоу взял на себя обязанности по написанию и создал непоследовательную вымышленную структуру, которая расширяет саму идею повествования в интерактивной среде. Чтобы разгадать тайну вашей цели на острове, вы должны собрать воедино ответы из подсказок, похожих на сфинксов. Но если вернуться к вопросу в начале этого абзаца, The Witness на самом деле о двух вещах: о Джоне Блоу и о смысле жизни.

Или, объединяя эти два момента, речь идет о смысле жизни Джона Блоу.

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

Отказ Блоу объяснить смысл его игр, в конце концов, проистекает из глубокого уважения к его искусству. С тех пор, как современные технологии впервые сделали возможным создание сложных видеоигр, разработчики предположили, что художественная судьба видеоигры стать фильмом с интерактивностью игрой, переплетенной со сценами, основанными на языке кино. И не только любые фильмы. Фактически, эталоном для видеоигр является дерьмовый боевик, сказал Блоу во время разговора в столовой с Крисом Хеккером одним солнечным днем. Вы не пытаетесь создать такую игру, как Гражданин Кейн; вы пытаетесь сделать Bad Boys 2. Но несмотря на то, что вопросы о вкусе фильма не имеют значения, идея о том, что игры даже попытались бы избежать неприятностей, связанных с фильмом Блоу. Как объяснил Хеккер: Смотри, фильм не превращался в фильм, пытаясь быть театром. Во-первых, они должны были выяснить, что они могли сделать, а чего не мог театр, например, перемещать камеру и редактировать эпизоды и только тогда фильм стал самим собой. Именно поэтому Гражданин Кейн сделал так много, чтобы поставить кинопроизводство на карте: не просто потому, что оно было хорошо сделано, а потому, что оно дало богатый опыт, который не мог предоставить ни один другой медиум до этого.

И поэтому Блоу, всегда верный своему кодексу, чувствует, что он обязан защищать свое призвание, не сводя видеоигры к терминам, которые мы используем при разборе фильмов и книг. Это означает, что в некоторой степени невероятно, что Блоу не верит даже в попытку передать главное послание игры словами; сам носитель, утверждает он, является посланием. Если игры это просто фильмы с интерактивностью, если у них нет ничего, что является их основной компетенцией, то вы не сможете использовать их эффективно, пояснил он. Теперь, одна из этих ключевых компетенций для игр это определенный вид невербального сложного общения, верно? Вы играете в игру часами, и, в конце концов, у вас, надеюсь, будет несколько возвышенное и сложное понимание того, что трудно выразить словами, потому что вы поняли это невербально.

К черту, головоломки и окружения как Braid, так и The Witness функционируют как длинный поток невербального общения вот почему он не будет убивать их, выражая их сообщения словами. В одной памятной беседе после разговора, который он дал в Университете Райса, студент настаивал на объяснении начальных образов Braid, и Блоу ответил категорическим отказом. Насколько я понимаю, вся информация о том, что там происходит, содержится в игре, и это все, что должно произойти, сказал он. И именно поэтому я делаю видеоигры. Вот почему я не хочу тебе говорить.

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

Я не думаю, что для человечества в конечном счете слишком важно, чтобы я сообщал о проблемах моей личной жизни, пояснил он. Мне больше интересно говорить о более широких фактах существования, которые выходят за рамки индивидуумов, но путь к этому честно и без обиняков лежит через личное. Эти откровения жгут его, но Блоу чувствует, что его высшая цель в создании The Witness оправдывает дискомфорт.

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

Это то, что делает игры Блоу такими замечательными: за большие личные деньги, способами, которые ни один другой разработчик даже не пытался, он изо всех сил пытается донести глубоко достоверное видение смысла человеческого существования. В обеих играх Блоу стремится использовать уникальный язык видеоигр, чтобы передать мудрость, которую он приобрел на своем жизненном пути. В The Witness он надеется помочь игрокам попытаться выйти за пределы своей человеческой точки зрения и увидеть, что представляет собой мир. А в Braid он стремился рассказать что-то более личное.
Однажды ночью в его квартире, когда огни Сан-Франциско мерцали за его окнами на многие мили, я предупредил Блоу, что собираюсь сделать что-то, что может его раздражать: я собирался сказать ему, что я думал о Braid, и он мог делать с этим все, что он хотел.

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

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

Блоу молчал.

Это имеет смысл? спросил я.
Да-да.
Так?
Ну, я бы сказал, что я не буду разочарован такой интерпретацией он улыбнулся.

Самая большая удача, которую я когда-либо видел, была, когда однажды ночью мы встретились с его другом Марком Тен Бошем в Оклендском филиале легендарной местной сети под названием Чикагская пицца Закари. Тен Бош высокий, серьезный независимый разработчик, чья серьезная сдержанность дала развлекательный контрапункт философской экспансии Блоу. Когда Тен Бош упомянул, что он некоторое время работал в Electronic Arts в команде, которая разработала стратегическую игру в реальном времени Command & Conquer: Red Alert 3, я спросил, нашел ли он проект интересным. Тен Бош задумался об этом на мгновение с торжественной силой человека, свидетельствующего перед подкомитетом Сената.

м, наконец сказал он.
Ооо! вмешался Блоу. Это абсолютный дисс!
Именно когда Тен Бош начал объяснять мне свой текущий игровой проект, Блоу казался больше всего в своей стихии. На самом деле, я должен изменить это, чтобы попытаться объяснить, потому что за те 20 минут, которые десять Бош потратил на описание своей игры, Miegakure, почти все, что он сказал, соскользнуло с моего мозга, как капли дождя с Горе-Текса. Он сказал, что Miegakure это платформер на основе головоломок, который разворачивается в четырех измерениях четырех пространственных измерениях.

Но нет четырех пространственных измерений, запротестовал я.
Ну, возразил Тен Босх, это то, что было бы, если бы они были.

И это было последнее, что он сказал, и я понял это довольно долго, пока он и Блоу жадно болтали о выдавливаемых поверхностях и воображении плоскости в виде труб. В Miegakure два пространственных измерения постоянны, и игрок решает головоломки, переключаясь между двумя другими с нажатием кнопки. Даже когда Блоу и Тен Бош становились все более оживленными, а их объяснения более изобретательными, их слова продолжали отскакивать от моего лба как теннисные мячи. Наконец, Тен Бош вытащил свой iPhone и загрузил Miegakure, включив образец видео игрового процесса, в котором крошечный рыжеволосый персонаж шел по плавучему острову. По подсказке игрока ткань игрового мира внезапно деформировалась и сместилась так, что наземная масса, казалось, воссоздала себя изнутри. Эффект был завораживающим.

Это четвертое измерение, сказал Тен Бош.
Челюсть отвисла, я посмотрел на Блоу, который просто улыбнулся мне.

Для Блоу, такой проект, как Miegakure, воплощает то, что делает видеоигру уникальной и захватывающей художественной средой. Так же, как он работал, чтобы донести до человека что-то невыразимое о состоянии человека в Braid и в The Witness, Тен Бош в своей игре дает игрокам новый взгляд на мир так, как это может сделать только игра. Это ценный вклад в человеческий опыт, верно?, сказал позже Блоу. Мне нравятся игры, которые показали мне то, чего я иначе не увидел бы, и Марк создает опыт, который был бы невозможен, если бы он не сделал это. И это довольно интересно.

Блоу хорошо знает, что достижение этой высокой цели через The Witness может заставить его обанкротиться. Он хотел бы, чтобы игра хорошо продавалась, когда она выйдет, возможно, в конце этого года, но его главной заботой является то, что она соответствует художественным параметрам, которые он для нее установил. Я всегда могу вернуться к тому, чтобы стать независимым разработчиком, пожал он плечами. Даже если у меня будет ноль долларов, я смогу сделать то же, что и в 2005 году, но лучше. Если мне удастся просто сэкономить на год или два на низкобюджетную жизнь, это все, что мне нужно. Несмотря на свое богатство, Блоу все еще думает как аскет.

Которым, в некотором смысле, он и является духовным искателем, стремящимся к истине в еще не изученном мире. Это условия, в которых он видит свое искусство. Люди, подобные нам, которые делают что-то немного отличное от основного направления, каждый выбрали одно направление, в которое мы выходим в пустыню, но мы все еще не очень далеко от лагеря, сказал он мне. Там просто огромное количество территории, чтобы исследовать и пока у вас нет карты этого, никто не может сказать, на что способны игры.

image

Узнайте подробности, как получить востребованную профессию с нуля или Level Up по навыкам и зарплате, пройдя платные онлайн-курсы SkillFactory:



Читать еще




Подробнее..

Перевод Клон Doom в 13 килобайтах JavaScript

17.06.2020 08:10:07 | Автор: admin
В прошлом году я участвовал в соревнованиях JS13K 2019, на которых людям предлагается разрабатывать игры в менее чем 13 КБ кода на JavaScript. Я участвовал с клоном Doom, который назвал Ещё один клон Doom (Yet Another Doom Clone).


Поиграть в него можно здесь. Исходный код выложен сюда.

Зачем создавать клон Doom?


Зачем писать FPS на JavaScript всего в 13 КБ (с учётом сжатия)? По нескольким причинам. Но лучше всего на этот вопрос отвечает раздел FAQ соревнований JS13K Можно ли использовать WebGL?:

Да, но может быть сложно уместить его в 13 килобайта, если вы планируете писать FPS.

Кроме того, в то время я как раз написал 3D-рендерер и хотел поработать над ним ещё. К тому же мне нравится создавать сильно сжатый код. (Например, много лет назад я создал язык и написал компилятор для нового языка, предназначенный специально для использования в код-гольфинге.)

Именно поэтому я выбрал FPS. Остаётся вопрос: Почему Doom? На него ответить проще: если вы хотите написать FPS, и чтобы он при этом был небольшим, то Doom практически самый минималистичный вариант.

Причина, по которой Doom настолько прост (по современным стандартам) понятна: Doom должен был работать на железе на пять порядков более медленном, чем сегодня. За ту же цену сейчас можно собрать машину, которая способна выполнять в сотню тысяч раз больше работы, чем Pentium 1994 года. Поэтому я решил, что будет интересно попробовать воссоздать нечто наподобие Doom, но вместо ограничений производительности использовать ограничения объёма кода.


Фундамент: 3D-рендерер на JavaScript


Движок игры я начал строить на основе написанного ранее 3D-рендерера, который я хотел реализовать как можно более простым. Оказалось, что благодаря своей простоте он к тому же довольно мал: ядро движка 3D-рендеринга заняло всего примерно 5 КБ сжатого JavaScript, то есть на игру осталось всего 8 КБ. Я решил, что ситуация не так уж и плоха. Если я не будут использовать большие спрайты или файлы объектов, то всё должно получиться.

Движение игрока



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

Первый шаг к этому реализация ускорения движения игрока в направлении его взгляда до какой-то (высокой) максимальной скорости. Я добавил больше ускорения, чем в оригинальном Doom, потому что сегодня это ощущается привычнее. Важнее для воссоздания ощущения Doom было добавление раскачивания камеры при движении игрока.

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

Если ничего не добавлять, то игрок будет продолжать раскачивание с того самого состояния, в котором он находился во время остановки. Это выглядит очень неестественно. Чтобы это исправить, потребовались крошечные изменения: у игрока есть переменная текущего состояния анимации в цикле (по модулю 2 пи), и когда игрок прекращает двигаться во всех направлениях, то переменная сбрасывается на ноль. Это делает движение более чётким, а его начало и завершение выглядят правильно.

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

Затем я добавил ограничение движения. Нет никакого смысле создавать сложные лабиринты в стиле Doom, если игрок может проходить сквозь стены. Для правильной реализации ограничений нужно сделать игрока сферой, стены плоскостями и вычислять пересечения сферы с плоскостью. Я беспокоился, что это займёт слишком большую часть наших 13 КБ.

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

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

Object Lathing



Чтобы в игре были объекты, мне нужно каким-то образом их описать. Логичным способом было бы использование формата файлов .obj. К сожалению, он довольно большой и неуклюжий. (Я использовал его в своём предыдущем 3D-рендерере для загрузки стандартного чайника.)

Поэтому вместо него я решил написать минималистичный метод точёных объектов (object lathe):
мы задаём 2D-контур, представленный в виде ряда точек, обтачиванием вращаем точки по кругу для генерации 3D-объекта. Это позволяет создавать красивые объекты, занимающие мало пространства. Например, для описания показанного выше кувшина потребовалось примерно двадцать байтов.

Задолго до разработки игры я также создал тщательно минимизированную до 300 байт реализацию подразделения поверхностей (surface subdivisioning) (которую ранее использовал для 3D-рендерера). Но в конечном итоге мне не хватило места и от неё пришлось отказаться. Однако я особо не жалею, потому что она не добавляла в игру ничего важного.

Игровой цикл


Всё описанное выше было довольно статичным, по миру перемещалась только камера. Однако для создания игры требуется интерактивность. И здесь нам пригодится игровой цикл.

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

      function game_step(now) {          if (game_is_over) return;          frame = requestAnimationFrame(game_step);  player_check_dead();  player_move();          player_clip_walls();          player_fall();          player_set_position();          lights.map(light => light.compute_shadowmap());          camera.draw_scene();          objects.map(object => object.update(dt));          garbage_collect();      }

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

Оружие и враги



Шутер от первого лица не особо интересен, если нам нечем и не в кого стрелять.

Я начал с реализации стрельбы. Я не был уверен, хватит ли у меня места на несколько видов оружия (в результате его и не хватило), поэтому решил, что в шутере логично будет использовать пулемёт (chaingun) из Doom.

Модель оружия это просто несколько цилиндров, созданных при помощи object lathe. Первым этапом здесь была реализация естественного движения с оружием. Для этого я снова воспользовался уже имеющимся отслеживанием движения вверх-вниз при ходьбе: пулемёт движется вверх-вниз и в стороны, в зависимости от текущего состояния цикла ходьбы игрока.


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

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

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

(Чтобы можно было стрелять по потолку и полу, потребовалось ещё одно небольшое дополнение. В противном случае при высоком прицеливании не было бы взрывов, и это казалось бы неправильным. Вся остальная система распознавания коллизий определяет коллизии только по горизонтали, а эти коллизии ориентированы по вертикали, а значит, им требуется специализированный код. На самом деле, написать его было не так сложно: записываем начальную высоту по Z и наклон игрока по поперечной оси (угол относительно плоскости xy), а затем для каждого полигона всей карты проверяем, насколько далеко должен растянуться луч, чтобы попасть по потолку и полу этого полигона; затем проверяем, действительно ли при движении луча на такое расстояние он сталкивается с полигоном в этом месте.)

После этого я сортирую все потенциальные коллизии и выбираю ближайшую.

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


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

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

Сначала блоки, из которых состоял враг, просто разлетались сквозь стены и пропадали с экрана. Это сбивало с толку, поэтому я добавил эффект отскакивания блоков от стен. Если говорить кратко, то отскоки совершенно физически недостоверны. Коллизии снова реализованы при помощи пересечения лучей. Если ближайшая стена полностью находится на плоскости xz, то объекты меняют знак свой скорости по y. Если стена полностью на плоскости, то меняется знак скорости по x. Во всех остальных случаях меняются знаки скоростей по x и y.

Когда позиция объекта меньше, чем высота пола текущей комнаты, скорость по z меняет свой знак и уменьшается на 20%. Каждую секунду объект замедляется на 50% (как будто к нему применяется какое-то гипотетическое трение).

ИИ врагов


Несмотря на то, что я изучал и имел дело в работе с "ИИ" (со множеством кавычек), враги в игре довольно неинтеллектуальны. У врагов есть позиция и поворот. Они постоянно ходят туда и обратно, пока не пробудятся по одной из двух причин:

(а) игрок находится в поле их зрения

или

(б) игрок подстреливает врага, находящегося в поле зрения.

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

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

Кроме того, в момент смерти враг запрашивает помощь у других врагов, которых может видеть (снова при помощи испускания лучей). Благодаря этому сложно устранять врагов по одному из-за угла, потому что это скучная механика, и не стоит её поощрять.

Текстуры


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




Генерация кирпичей довольно тривиальна. Отрисовываем горизонтальные линии через каждые N шагов, а затем вертикальные линии через каждые N со смещением на N/2 в чётных строках. Код выглядит так:

      make_texture(cartesian_product_map(range(256),range(256),(y,x) => {          if ((y%64) <= 2 || Math.abs(x-(((y/64)|0)%2)*128) <= 2) {              return [0,0,0,1];          } else {              var r = .9-perlin_noise[x*256+y]/20;              return [r,r,r,1];          }      }).flat())

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

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

Анимации врагов



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


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

Звук


Казалось очевидным, что для добавления звука нужно использовать JSFXR, однако на этом этапе места уже начинало не хватать. Взглянув ещё раз на код, я увидел, что ещё многое можно оптимизировать.

Благодаря последовательности небольших изменений мне удалось сократить его почти в два раза. Самая большая экономия получилась благодаря удалению map из массива в воспроизводимый файл WAV и замене его на вызов функции WebAudio, получающей непосредственно массив float. Ещё одна серьёзная экономия получилась благодаря замене куче операторов case на операции поиска в массиве. То есть я реализовал принцип мультиплексора и вычислил все возможные случаи внутри массива, а затем просто выбирал индекс нужного значения. Это медленнее, зато код короче. После замены циклов for на map и создания вспомогательной функции clamp код оказался достаточно коротким, чтобы можно было написать красивые звуковые эффекты.

Затем я захотел сделать так, чтобы аудиосистема реагировала на то, где находится игрок в 3D-пространстве. Я думал, что эта часть потребует много усилий, но оказалось, что это довольно просто, и теперь в коде есть функция createStereoPanner, выполняющая эту задачу.

В качестве фоновой музыки я переписал среднюю часть токкаты и фуги ре минор. Она просто повторяется бесконечно.

Описание карты



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

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

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

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

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

Я даже добавил функции, позволяющие создавать циклы for и вызовы/возвраты, чтобы можно было, например, изготавливать лестницы, а затем многократно применять функцию make-stairs там, где мне были нужны лестницы.

К сожалению, проектировать карты всё равно было сложно, потому что для этого требовалось программирование черепашки на языке ассемблера, который разрабатывался как максимально компактный. У меня был всего месяц на создание всей игры, поэтому я никак не мог себе позволить потратить несколько дней на проектирование карт. Более того, на самом деле это не экономило особо много пространства. Так как ограничение в 13 килобайта относится к размеру запакованного zip исходного кода, вполне можно было использовать дублирование одной функции: сжатие zip сэкономит пространство.

Поэтому код черепашки стал таким:

      function run_turtle(commands) {          var regions = []          var turtle_location = [ZERO];          var floor_height = 4;          var ceil_height = 40;          var do_later = [];          for (var i = 0; i < commands.length;) {              var cmd = commands[i++];              // Get the "opcode" and "argument" to the command      var [low, high] = [cmd&31, cmd>>5];              // Opcode 0 is a "make polygon" command              if (high <= 1) {                  var coordinates = [turtle_location[0]]                  coordinates.push(...range(low).map(x=> {                      var dydx = NewVector(((commands[i]>>4)-7)*8,                                           ((commands[i++]%16)-7)*8, 0)                      turtle_location.unshift(turtle_location[0].add(dydx));                      return turtle_location[0];                  }));                  regions.push(new MapPolygon(coordinates,                                              floor_height,                                              ceil_height))                  // Opcode 1 is a "goto" command                  if (high == 1) {                      regions.pop();                  }              }              // Opcodes 4: adjust ceiling              floor_height += 2*(low-15)*(high==4);              // Opcodes 5: adjust floor      ceil_height += 4*(low-15)*(high==5);              // Opcodes 6: backtrack              turtle_location.splice(0,low*(high==6));          }          return [regions, do_later];      }

Чтобы упростить создание карт, я избавился от большей части языка и создал гораздо более простой язык. Я убрал циклы, вызовы функций, повороты и реализовал всего два опкода: make-polygon и goto. Опкод make-polygon получает количество вершин и последовательность байтов, где старшие 4 бита определяют сдвиг по оси x, а младшие 4 бита сдвиг по оси y. После достижения последней вершины цикл завершается и черепашка создаёт многоугольник. Опкод move просто перемещает черепашку в новое место для создания нового многоугольника.

После создания нескольких карт я посмотрел, какие части моего языка turtle занимают больше всего места. Я понял, что трачу много места на перемещение черепашки от многоугольника к многоугольнику. Как можно сократить этот процесс? Обратим внимание, что обычно многоугольники не изолированы: они соединяются с другими многоугольниками вершиной. Поэтому я добавил ещё одну функцию backtrack. При каждом движении черепашки она добавляет своё местоположение в стек. Backtrack извлекает позицию черепашки определённое количество значений назад. Это очень эффективно: более 95% перемещений черепашки было заменено командами backtrack.

Редактор карт



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

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

Так как этот редактор не будет находиться в составе игры, я мог не волноваться о качестве кода или удобстве редактора. Он невероятно уродлив и некрасив, в нём используются непонятные горячие клавиши. (Хотите добавить новый многоугольник? Выберите созданную вершину и нажмите Shift-A для выделения соседнего ребра, а затем E (для экструдирования). Хотите добавить вершину к уже существующему ребру? Shift-A и S (для разбиения). Нужно удалить многоугольник? Shift-Q. Если знать, что делать, то всё вполне логично, но не особо интуитивно понятно.)

Мысли об экономии пространства


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

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

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

      var pairs = (lst,fn) => lst.slice(0,-1).map((x,i)=>fn(x,lst[i+1],i))      var transpose = (mat) => mat[0].map((x,i) => mat.map(x => x[i]))      var range = (N,a) => Array(N).fill().map((_,x)=>x+(a||0));      var reshape = (A,m) =>          range(A.length/m).map(x=>A.slice(x*m,(x+1)*m));      var urandom = _ => Math.random()*2 - 1;      var push = (x,y) => (x.push(y), x);      var clamp = (x,low,high) => Math.min(Math.max(low, x), high)      var sum = (x) => x.reduce((a,b)=>a+b)

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

В самом некрасивом моём коде я сделал так, что умножения матриц 4x4 стали и очень эффективными, и одновременно очень короткими; для этого пришлось потрудиться:

    var mat_product_symbolic = B =>        `(a,b)=>[${reshape(range(16),4).map(c=>B[0].map((_,i)=> B.reduce((s,d,j)=>`${s}+b[${d[i]}]*a[${c[j]}]`,0))).flat()}]`;    multiply = eval(mat_product_symbolic(reshape(range(16),4));

Для постоянного отображения текущего размера сборки требовался автоматизированный процесс сборки. Сначала скрипт сборки просто запускал uglifier, за которым выполнялся стандартный zip, чтобы я мог отслеживать занимаемое пространство. Вскоре я осознал, что есть оптимизации, которые позволят мне автоматизировать процесс, чтобы ещё больше сжать код. Я написал короткий скрипт, определяющий все имена переменных webgl и заменяющий их короткими однобуквенными именами (потому что uglify этого не делал). Затем я модифицировал эту программу так, чтобы она переписывала длинные имена функций WebGL, например, framebufferTexture2D, коротким трёхсимвольным кодом вида e2m (я брал восьмой символ с конца, второй символ с конца и третий символ с начала). Ближе к концу разработки я узнал о advzip, который ещё больше помог мне с улучшением сжатия.
Подробнее..

Портируем старую игру в жанре shoot em up на JavaScript на коленке

30.06.2020 02:04:50 | Автор: admin

Имеется древняя игрушка LaserAge, которая написана на Flash (на очень древнем Macromedia Flash 4) и работает только под Windows. В детстве она мне очень понравилась, поэтому я решил для души портировать её, чтобы можно было играть с браузера со всех устройств.


Цель игры заключается в том, чтобы уничтожать противников своим космическим кораблём на различных уровнях и получать бонусы, если поймать бонус улучшается оружие. При попадании торпеды противника даунгрейд оружия игрока.
При уничтожении всех противников на уровне происходит переключение на следующий уровень. Всего 100 уровней.
В терминах игры уровень волна (Wave), а несколько волн объединены в большой уровень (Level), который представляет из себя просто смену заднего фона,
т. е. всего 4 больших уровня в каждом из которых 25 волн. В последней волне большого уровня обычно бывает босс противник с огромным значением жизни и мощным оружием.


http://personeltest.ru/aways/github.com/EntityFX/laseroid/blob/master/doc/LaserAgeNext.png?raw=true


[TOC]


Бизнес логика игры


Игровое пространство


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


http://personeltest.ru/aways/github.com/EntityFX/laseroid/blob/master/doc/Stage.png?raw=true


Оружие


Оружием обладает космический корабль игрока и корабли противника.
Оружие игрока может быть ручным (стреляет при нажатии мыши) и дополнительное автоматическое (стреляет периодами).
Оружие стреляет торпедами, алгоритм движения которых очень примитивный: торпеды противника движутся на игрока (сверху вниз), а торпеды игрока движутся снизу вверх.
При попадании торпеды противника в игрока вычитается 1 уровень жизни (апгрейда), при 0 игра завершается поражением.


Оружие космического корабля игрока


  • Торпеда стреляет маленькими ракетами
    • Одинарная Торпеда 1 уровень апгрейда
    • Двойная 2 уровень апгрейда
    • Тройная 3 уровень апгрейда
  • Автоматические пушки
    • Дополнительная автоматическая Торпеда слева корабля 4 уровень апгрейда
    • Дополнительная автоматическая Торпеда справа корабля 5 уровень апгрейда
  • Зелёная плазма 6 и 7 уровень апгрейда (увеличивается скорострельность)
  • Фиолетовая плазма 8 уровень апгрейда (наносит урон всем противникам по траектории полёта)
  • Зелёный лазер 9 уровень (наносит урон всем противникам, а также активно одну секунду, тем самым можно задеть соседних противников)

Дополнительное оружие:


  • Красная плазма 15-19 уровень (наносит урон всем противникам, а также активно одну секунду, тем самым можно задеть соседних противников)
  • Зелёная плазма 20-24 уровень
  • Синяя плазма 25-29 уровень апгрейда
  • Фиолетовая плазма 30-34 уровень апгрейда
  • Фиолетовая плазма 30-34 уровень апгрейда
  • Дополнительная автоматическая Торпеда слева стреляет желтой плазмой 35 39 уровень апгрейда
  • Дополнительная автоматическая Торпеда справа стреляет желтой плазмой 40+ уровень апгрейда

Таблица с характеристиками оружия игрока


Оружие Hit Points Скорость спрайта Интенсивность Тип Дополнительно Вид
Торпеда 1 5 25 Торпеда Одинарная, двойная, тройная
Автоматическая Торпеда 1 5 50 Торпеда Слева и Справа
Зелёная плазма 3 7 30 Торпеда
Фиолетовая плазма 2 8 30 Торпеда Атакует до 3х целей
Красная плазма 2 4 30 Торпеда
Синяя плазма 4 4.5 30 Торпеда
Жёлтая плазма 2 3.8 40 Торпеда Только автоматическая
Зелёный Лазер 4 - 15/55 Лазер Атакует до 5ти целей одновременно

Таблица с конфигурацией оружия игрока в зависимости от уровня жизни


Уровень жизни Конфигурация оружия
1 Торпеда
2 Торпеда + Торпеда
3 Торпеда + Торпеда + Торпеда
4 Торпеда + Торпеда + Торпеда + Автоматическая торпеда слева
5 Торпеда + Торпеда + Торпеда + Автоматическая торпеда слева + справа
6 Зелёная плазма + Автоматическая торпеда слева + справа
7 Зелёная плазма + Автоматическая торпеда слева + справа
8 Фиолетовая плазма + Автоматическая торпеда слева + справа
9 Зелёный лазер + Автоматическая торпеда слева + справа
15 19 Зелёный лазер + Красная плазма + Автоматическая торпеда слева + справа
20 24 Зелёный лазер + Красная плазма + Автоматическая торпеда слева + справа
25 29 Зелёный лазер + Синяя плазма + Автоматическая торпеда слева + справа
30 34 Зелёный лазер + Фиолетовая плазма + Автоматическая торпеда слева + справа
35 39 Зелёный лазер + Фиолетовая плазма + Автоматическая желтая плазма слева + торпеда справа
40+ Зелёный лазер + Фиолетовая плазма + Автоматическая желтая плазма слева + желтая плазма справа

Оружие противников


Таблица с конфигурацией оружия противников


Оружие Скорость спрайта Тип
Торпеда 2.5 Торпеда
Красная плазма 3.5 Торпеда
Синяя плазма 4.5 Торпеда
Зелёная плазма 5 Торпеда
Синяя Торпеда 3 Торпеда
Жёлтая плазма 3.2 3.8 Торпеда
Белая плазма 4 6 Торпеда
Зелёный Лазер - Лазер

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


Пример конфигурации оружия:


"torpedo": {    "sprite": "Bullet1_1.png", //картинка спрайта    "isRandomIntensity": false, //нужно ли переключать случайно слоты - true или по порядку - false    "intensity": [        //слот 0        {            "min": 50, //минимальное число фреймов            "max": 200, //максимальное число фреймов            "type": "pause" //pause - оружие неактивно, shoot - активное (стреляет)        },        //слот 1        {            "min": 100,            "max": 200,            "type": "shoot"        },        {            "min": 50,            "max": 80,            "type": "pause"        },        {            "min": 30,            "max": 100,            "repeat": 2        }    ],    "speed": 2.5, //скорость    "type": "bullet", //тип оружия    "sound": "alienTorpedo"}

Действующие лица


Корабль игрока


Корабль игрока может перемещаться в ограниченной области, чтобы не пересекаться с кораблями противников.
Управляется движением мыши или стрелочками и . На экране мобильного телефона тапом и движением по экрану.
Оружие активирует при удержании левой клавиши мыши (тапом и удержанием по экрану на мобильном телефоне).


Противники


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


Корабль противника Жизнь Тип Движения Оружие Вид
Чужой 1 2 Обычный Нормальное горизонтальное Торпеда
Чужой 2 4 Обычный Нормальное все направления Торпеда
Быстрый чужой 10 Обычный Быстрое горизонтальное Торпеда (Интенсивная)
Фрегат чужого 10 Обычный Нормально-быстрое все направления Красная плазма
Броневик чужого 10 Обычный Медленное вниз Торпеда (Очень интенсивная)
Быстрый Фрегат чужого 30 Обычный Медленное вниз (следит за игроком) Красная плазма (Очень интенсивная)
Красный истребитель 30 Обычный Медленное вниз (следит за игроком) Синяя плазма
Зелёный истребитель 30 Обычный Быстро вертикально Синяя плазма
Чужой 1 модификация 2 Обычный Нормальное горизонтальное Синяя Торпеда
Бомбардировщик 30 Обычный Нормальное все направления (следит за игроком) Зелёная плазма
Тяжёлый Чужой 30 Обычный Нормальное все направления Торпеда
Тяжёлый Фрегат Чужого 35 Обычный Нормальное все направления Синяя Торпеда + Синяя Торпеда
Тяжёлый броневик 35 Обычный Нормальное вниз Жёлтая Плазма + Жёлтая Плазма + Жёлтая Плазма + Жёлтая Плазма
Линкор 100 Босс Нормальное все направления Синяя плазма (очень интенсивная) + Зелёная плазма (очень интенсивная)
Крейсер 250 Босс Нормальное все направления Зелёная плазма (сверх интенсивная)
Тяжёлый Крейсер 500 Босс Быстрое все направления Жёлтая Плазма + Жёлтая Плазма + Синяя Торпеда + Синяя Торпеда + Синяя Торпеда + Синяя Торпеда + Белая плазма + Белая плазма
Эпичный Тяжёлый Крейсер 1000 (восстанавливается) Босс Быстрое все направления Жёлтая Плазма + Жёлтая Плазма + Синяя Торпеда + Синяя Торпеда + Синяя Торпеда + Синяя Торпеда + Белая плазма + Белая плазма+ Зелёная плазма (очень интенсивная)

JSON-конфигурация противника:


"alien10": {    "life": 35,    "weapons": [        {            "weapon": "blueTorpedo",            "position": {                "x": -6,                "y": 0            }        },        {            "weapon": "blueTorpedo",            "position": {                "x": 6,                "y": 0            }        }    ],    "sprite": "AlienShip10_1.png",    "movement": "horizontalFast",    "killPoints": 2100}

JSON-конфигурация движения противника :


"horizontalFast": {    "movements": [        {            "type": "freeMovement", //freeMovement - обычное, followPlayer - следит за игроком (движется в направление)            "speedDelta": {                "vx": -6,                "vy": 0            },            "intensity": [ //интенсивность движения в виде слотов                {                    "min": 20,                    "max": 150                },                {                    "min": 150,                    "max": 350                }            ]        }    ]}

Бонусы


Специальный вид противника http://personeltest.ru/aways/raw.githubusercontent.com/EntityFX/laseroid/master/resources/laser-age/graphics/PowerUps_1.png , который не имеет оружия и при уничтожении порождает спрайт с бонусом http://personeltest.ru/aways/raw.githubusercontent.com/EntityFX/laseroid/master/resources/laser-age/graphics/Upgrade.png , который должен поймать корабль игрока. Если игрок поймает бонус, то увеличивается его уровень (жизнь).


Уровни


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


JSON-конфигурация уровня :


        "2": {            "level": 1,             "enemies": [ // список противников                {                    "id": "alien1",                    "position": {                        "x": 200,                        "y": 35                    }                },                //...                {                    "id": "alien1",                    "position": {                        "x": 525,                        "y": 40                    }                }            ],            "bonuses": [ // список бонусов                {                    "id": "bonus1",                    "position": {                        "x": 350,                        "y": 10                    }                }            ]        },

Выбор JavaScript библиотеки для реализации


Я просмотрел множество библиотек графики для JavaScript, но остановился на Hexi JS: https://github.com/kittykatattack/hexi .


Возможности библиотеки:


  • Простота
  • Рисование примитивов
  • Рисование просты интерфейсов (кнопки, события)
  • Перемещение, масштабирование, вращение
  • Рисование спрайтов
    • Анимированные спрайты
    • Работа со спрайтами как с объектами
    • Загрузка спрайтов в виде большой текстуры-атласа. Можно разместить множество изображений в одном файлы и на выходе получить одну большую текстуру и JSON файл с описанием спрайтов (область, смещение)
  • Логика столкновений
  • Работа с устройствами ввода (клавиатура), тач-скрин.

Пример текстуры-атласа создаваемого с помощью программы TexturePacker
http://personeltest.ru/aways/github.com/EntityFX/laseroid/blob/master/doc/ships-atlas-texture.png?raw=true


Звуковая библиотека: https://github.com/kittykatattack/sound.js


Возможности библиотеки:


  • Простота
  • Воспроизведение звуков
  • Воспроизведение музыки
  • Эффекты

Архитектура


Общая диаграмма классов:


http://personeltest.ru/aways/github.com/EntityFX/laseroid/blob/master/doc/diagrams/game.png?raw=true


Ядро игры


http://personeltest.ru/aways/github.com/EntityFX/laseroid/blob/master/doc/diagrams/core.png?raw=true


Класс Main


Является точкой входа и контейнером игрового кода.


Поля:


  • resources содержит список всех загружаемых ресурсов (текстуры, звук, json)
  • sounds словарь звуков: Ключ название, Значение путь
  • gameScene объект HexiJS на
  • game экземпляр объекта Game
  • hexi инстанс HexiJS
  • gameStorage сохраняет состояние игры в localStorage

Методы:


  • init() инициализирует HexiJS
  • load() загружает ресурсы (текстуры, звук, json)
  • setup() устанавливает игровую область, события нажатия кнопок, запускает фоновую музыку
  • playLoop() точка изменения состояния игры (считает движение, коллизии, снаряды, перерисовывает пространство).
  • saveGame() сохраняет игру
  • loadGame() загружает игру

Пример списка ресурсов текущей реализации игры:


Main.resources = [        "images/environment1.png",        "images/environment2.png",        "images/environment3.png",        "images/environment4.png",        "images/interface.png",        "images/life-icon.png",        "images/ships-texture.json",        "images/bullet-texture.json",        "sounds/alien-torpedo-shoot.wav",        "sounds/alien-red-plasma-shoot.wav",        "sounds/hero-torpedo-shoot.wav",        "sounds/explode.wav",        "sounds/hero-green-plasma-shoot.wav",        "sounds/alien-green-plasma-shoot.wav",        "sounds/alien-blue-torpedo-shoot.wav",        "sounds/alien-yellow-laser.wav",        "sounds/pulse-plasma.wav",        "sounds/laser.wav",        "sounds/track0.ogg",        "sounds/track1.ogg",        "sounds/track2.ogg",        "sounds/track3.ogg",        "sounds/track4.ogg",        "data/hero-configuration.json",        "data/levels-configuration.json",        "data/enemy-configuration.json",        "data/ui-configuration.json",    ];

Класс Game


Основной класс игры.


Поля:


  • level информация о уровне. Значение: { "wave": 1 //номер волны, "type": 1 }
  • score информация об очках. Значение: {"points": 0 }
  • bulletsController Экземпляр класса BulletsController. Управляет поведение торпед и лазеров оружия
  • enemyController Экземпляр класса EnemyController. Управляет поведением всех противников на уровне (в т.ч. и бонусами)
  • player Экземпляр Player
  • hexi экземпляр класса Hexi (ссылка)
  • game экземпляр объекта Game
  • gameStorage экземпляр объекта GameStorage

Методы:


  • clearShips() очистка всех проиивников, бонусов
  • setupLevel() настроить уровень (добавить противников, бонусы, расстановка)
  • nextLevel() переход на следующий уровень
  • previousLevel() переход на предыдущий уровень
  • forwardLevel() перепрыгнуть на несколько уровней вперёд (на 5)
  • rewindLevel() перепрыгнуть на несколько уровней назад (на 5)
  • restoreState(gameState: JSON) восстановить по объекту gameState
  • resetGame() сбросить игру (начать сначала)
  • update() обновить игровой мир
  • enemyDestroyed() обработчик срабатывает при уничтожении всех противников

Класс GameStorage


Сохраняет и загружает состояние игры .


Поля:


  • game экземпляр объекта Game

Методы:


  • save() сохранить состояние игры
  • load() загрузить состояние игры

Класс InputDevice


Работает с событиями устройств ввода: click и touch кнопок, нажатие клавиш клавиатуры.


Поля:


  • game экземпляр объекта Game

Методы:


  • init() инициализирует все обработчики события и callback'и
  • loadTapped() нажата кнопка "Load"
  • storeTapped() нажата кнопка "Store"
  • resetTapped() нажата кнопка "Reset"
  • pauseTapped() нажата кнопка "Pause"

Иерархия классов действующих лиц


http://personeltest.ru/aways/github.com/EntityFX/laseroid/blob/master/doc/diagrams/actors.png?raw=true


Actor


Класс участника.


Поля:


  • hexi экземпляр класса Hexi (ссылка)
  • game экземпляр объекта Game
  • life текущее значение жизни
  • initialLife начальное значение жизни
  • sprite экземпляр класса Hexi.Sprite
  • shipConfiguration конфигурация бонуса

Методы:


  • move() переместить действующее лицо
  • update() обновить действующее лицо
  • setPosition(position: {x, y}) установить по координатам

WeaponedActor


Класс участника (противник или игрок) обладающем оружием.


Поля:


  • automatedWeapons массив автоматических оружий
  • canShoot мжет ли стрелять
  • isWeaponShooting активено ли оружие

Методы:


  • startShoot() запустить выстрелы оружием
  • stopShoot() остановить выстрелы оружием
  • onShootStarted() обработчик события, что запущены выстрелы оружием
  • onShootStopped() обработчик события, что остановлены выстрелы оружием
  • updateShooting() выполняет алгоритмы выстрелов

Enemy


Класс противника.


Поля:


  • type тип противника
  • syncWeapons массив конфигураций для синхронного оружия
  • movementEngine экземпляр класса MovementEngine

Методы:


  • setWeapon() установить оружие используя текущую конфигурацию
  • shootWithWeapon() выполняет выстрел противником
  • setLifeLine() рисует линию жизни противника
  • hit() проверяет столкновение торпед (лазера) игрока с текущим противником

MovementEngine


Класс управляющий движением.
Для придания сложности движения, используется конфигурация со слотами. В каждом слоте задаётся
вектор направления vx, vy и интенсивность. Имеется возможность отключения отражения от нижней границы и
режим слежения за игроком (противник всегда движется за игроком).


Поля:


  • movementsConfiguration конфигурация движения
  • firstMovementConfiguration первый элемент из списка конфигураций
  • movementItensity интенсивность движения
  • movementItensityCounter счётчик интенсивности движения
  • movementItensitySlot номер слота интенсивности
  • isBounceBottom флаг на проверку отражения от нижней границы. Если false, то противник не отражается от нижней границы

Методы:


  • setMovement() настраивает движение
  • updateMovement() обновляет движение по конфигурации движения

Player


Класс игрока.


Поля:


  • weapons массив оружия игрока
  • collisionSprite спрайт коллизии (торпеды противника сталкиваются со спрайтом коллизии, а не спрайтом игрока)
  • weaponLifeLevels значения уровня жизни для проверки на апгрейд оружия
  • invisibilityCounter счётчик невидимости от торпед (нужен для того, чтобы при столкновении с торпедой противника игрок стал временно недосягаем для других торпед)

Методы:


  • upgrade() апгрейд игрока (+1 жизнь)
  • downgrade() даунгрейд игрока (+1 жизнь)
  • shootWithLaser(currentWeapon, weapon) выстрел лазером
  • shootWithBullets(currentWeapon, weapon) выстрел торпедой
  • setWeapon() установить оружие используя текущую конфигурацию
  • setLife(life: number) установить значение жизни (меняет оружие в соответствии со значением жизни)
  • hitUpgrade(upgradeItem) проверить столкновение со спрайтом апгрейда

Bonus


Класс Бонуса. При уничтожении порождает спрайт апгрейда.


Поля:


  • type тип бонуса
  • movementEngine экземпляр класса MovementEngine
  • upgradeBonus конфигурация апгрейда

Методы:


  • shootWithUpgrade(upgradeBonus: JSON) породить спрайт апгрейда

EnemyController


Управляет состоянием противников, бонусов, апгрейдами.


Поля:


  • enemies массив всех противников на уровне
  • bonuses массив всех бонусных кораблей на уровне
  • player объект игрока
  • upgrades массив всех спрайтов апгрейда

Методы:


  • isLevelCompleted() проверка на завершённость уровня (уничтожены все противники и бонусы, пойманы апгрейды)
  • update() обновляет состояние всех противников
  • clear() очистка уровня от проиивников, бонусов

BulletsController


Управляет состоянием торпед (перемещение), лазерами игрока и противников.


Поля:


  • playerBullets массив торпед игрока
  • enemyBullets массив торпед всех противников
  • explosionSplashes массив спрайтов взрыва
  • playerLaser состояние спрайта лазера игрока (Если оружие доступно).

Методы:


  • update() обновляет состояние всех торпед, лазеров
  • clear() очищает уровень от всех торпед, лазеров
  • updatePlayerBullets() изменяет состояние всех торпед игрока
  • updatePlayerLaser() изменяет состояние лазера игрока
  • updateEnemyBullets() изменяет состояние всех торпед противника
  • updateExplosions() изменяет состояние всех взрывов

Выводы


Я постарался достаточно подробно рассказать как портировать существуюшую игру на JavaScript.
Игру можно модифицировавть и снабдить своими текстурами, музыкой, сделать собственную конфигурацию уровня или вариацию всей игры.
Очень хотелось бы получить от вас комментарии по архитектуре игры, варианты рефакторинга, по именованию методов и т.д.
Согласен, архитектура не очень идеальная и есть куда стремится!


Спасибо и интересных Вам проектов!


Ссылки


http://laseroid.azurewebsites.net/ сама игра
https://github.com/EntityFX/laseroid исходный код игры

Подробнее..

Сколько стоит сделать ролик об игре своими силами

29.06.2020 16:21:22 | Автор: admin


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

Из этой статьи вы узнаете, расходы какого порядка могут скрываться за решением самостоятельно сделать видеоролик о своей игре. Предупреждаем: это лонгрид с зубодробительными подробностями видеопроизводства. Поехали?

Написано в Alconost

При подготовке этого материала мы опирались на собственный опыт создания роликов об играх: мы сделали их больше сотни за последние 8 лет. А чтобы перевести времязатраты в деньги, мы воспользовались результатами исследования InGame Job по зарплатам в геймдеве. С опорой на опыт и знания мы попробуем посчитать, в какую сумму среднестатистической геймдев-студии может обойтись создание ролика об игре собственными силами.

Ролики об играх бывают очень разные. Иногда это нарезка видеозахватов, а иногда анимация персонажей или 3D-моделей или даже мультипликация. Безусловно, разная сложность это и разные трудозатраты, поэтому ролики об играх могут в разы отличаться друг от друга по стоимости. Звучит логично, но уж слишком абстрактно, правда?

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

Начнём с трёх допущений: какой именно ролик вам нужен, какими именно сотрудниками вы располагаете и как именно вы выстроите процесс производства видео.

  • Ролик: допустим, вам нужен ролик-трейлер, длительностью не больше минуты, для размещения на сайте игры и в Google Play. Пусть ролик будет на английском, с озвучкой диктором-носителем английского языка, с музыкой и звуковыми эффектами.
  • Команда: предположим, что в команде есть ребята, у которых достаточно знаний, навыков и квалификации, чтобы написать сценарий, создать графику для ролика и анимировать её, а также сделать звуковое оформление видео. Также предположим, что в команде полное взаимопонимание, и каждый в команде может выделять на эту задачу половину рабочего дня без ущерба прочим обязанностям.
  • Процесс: возможно, вы решите следовать процессу создания роликов в Alconost: написать сценарий, сделать раскадровку, записать озвучку, подобрать фоновый трек, собрать анимацию, смонтировать музыку, добавить звуковые эффекты. Не исключено, что в вашем случае процесс нужно подтюнинговать, но как именно можно судить, только зная особенности конкретной игры и конкретной команды. Раз сама ситуация, ролик и команда у нас условные, пусть хотя бы процесс будет конкретный и универсальный.

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


Фото: StartupStockPhotos, Pixabay

Сценарий


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

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

  • В каком визуальном контексте будет происходить всё действие? Это простой градиент, плоский детализированный арт или 3D-окружение? С этим нужно разобраться в самом начале, чтобы все решения по визуальной части были консистентными. Добавляйте в сценарий референсы.
  • В каком порядке в ролике будут показаны главные фичи игры и каким именно образом? Если некоторые фичи выглядят недостаточно фотогенично (мешают кнопки, много текста, мелкие иконки), в сценарии нужно предусмотреть, как именно такие фичи будут демонстрироваться.
  • Каким будет закадровый текст? Диктор озвучивает предоставленные ему фразы, не внося корректировок на свой вкус, так что сценаристу нужно убедиться, что текст озвучки ёмкий, точный и складный.


Фото: Free-Photos, Pixabay

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

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

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

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

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

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

Раскадровка


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


Фото: VitalikRadko, Depositphotos

Первым делом художник проникается сценарием, смотрит референсы и подбирает арт из уже отрисованных ассетов (находит графические исходники персонажей и, конечно, наручей испуганной нимфы в архиве игровой графики). Затем разрабатывает визуальный стиль: готовит фон, рисует плашки, подбирает шрифт. Так как по сценарию предусмотрено кадрирование видеозахватов, художнику нужно подумать, как компенсировать разницу пропорций между соотношением сторон кадрированного видео (может получиться, например, 1:1) и высотой и шириной кадра (обычно 16:9).

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

Предположим, что в нашем случае художник уделяет раскадровке по 4 часа в день и справляется за неделю, включая один-два цикла правок. В этом случае его времязатраты составят около 20 часов.

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

Анимация


Аниматор знакомится со сценарием, смотрит референсы и анимирует раскадровку, подготовленную художником. Также аниматор монтирует видеозахваты: менеджер проекта (о нём далее) их уже отснял и предоставил аниматору вместе с таймкодами удачных фрагментов и инструкциями по их кадрированию и улучшению.


Фото: sonerbakir, Depositphotos

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

Предположим, что анимация графики займет 30 часов, а работа с захватами 10. Допустим, полная черновая сборка в целом понравится команде, но без улучшений не обойтись. Пропустим черновик анимации через три цикла правок (пусть они займут 4, 3 и 2 часа: чем ближе к финальной версии, тем меньше корректировок) и дадим аниматору ещё часок на шлифовку финальной версии. При таком ходе работ трудозатраты аниматора составят 50 часов.

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

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

Звукорежиссура


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

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

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


Фото: princeoflove, Depositphotos

Будем считать, что на монтаж музыки, подбор звуковых эффектов и сведение у звукорежиссёра уйдет около 4 часов, и ещё час понадобится на внесение правок после согласования с командой (бдыщь не подошел надо буммм, и тому подобное). Итого 5 часов.

Остаётся только попросить аниматора свести финальное видео с финальной аудиодорожкой и ролик готов.

Менеджмент


Менеджер делает всё, чтобы процесс работы над роликом шёл продуктивно и был команде в кайф. Иначе зачем это всё?

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


Фото: ilixe48, Depositphotos

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

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

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

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

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

Суммируем время


Давайте подсчитаем, сколько приблизительно времени ушло на создание ролика в нашем случае.

  • Сценарий: 10 ч.
  • Раскадровка 20 ч.
  • Анимация: 50 ч.
  • Звукорежиссура: 5 ч.
  • Менеджмент: 30 ч.

Итого: 115 часов.

Условной геймдев-команде понадобилось около 115 часов, чтобы сделать условный видеоролик о своей игре. Безусловно, наши воображаемые ребята могли где-то справиться быстрее, а где-то залипнуть надолго. Может быть, команда поторопилась со сценарием и при создании раскадровки выяснилось, что не всё получается показать так, как задумано? Или при сборке анимации оказалось, что в сценарии не упомянули что-то важное, и пришлось вернуться на пару шагов назад? А может, ребятам удалось подключить разработчиков к созданию ролика, снять с движка идеальный геймплей и времязатраты на сборку анимации и монтаж захватов удалось сократить?

Жаль, что нет хрустального шара, который предсказал бы ход процесса и выдал точное (а ещё лучше небольшое) количество часов, нужное на производство любого видеоролика о любой игре любой командой разработчиков.

Реальные времязатраты на создание конкретного видеоролика об игре могут быть как 20 часов, так и 200. Точному расчету, который было бы справедливым для любого ролика о любой игре, мешают нюансы. А их десятки: от специфики конкретной игры и её фотогеничности до нюансов разработки, технических и организационных, которые в каждом случае уникальные.

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

Переводим в деньги


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

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

Для этого воспользуемся исследованием компании InGame Job, которая в 2019 году опросила 2000 сотрудников геймдев-компаний из России, Беларуси и Украины и высчитала медианную зарплату специалистов на разных должностях.

Роли, которые сотрудники геймдев-студии исполняют в нашем условном проекте, мы соотнесём с должностями, упомянутыми в исследовании. Чтобы выяснить, сколько стоит один час работы каждого специалиста, разделим медианное значение зарплаты за месяц на 21 рабочий день, а полученное число разделим на количество часов в рабочем дне 8.
Роль в проекте / Должность в списке InGame Job Медианная зарплата, $ Стоимость 1 рабочего часа, $ Затрачено времени на ролик, ч. Стоимость часов, затраченных на ролик, $
Копирайтер / Narration Designer 1100 6,5 10 65
Художник / 2D Artist 950 5,6 20 113
Аниматор / Animator 1420 8,5 50 423
Звукорежисcёр / Sound Engineer 1200 7,1 5 36
Менеджер проекта / Project Manager 1800 10,7 30 321
Итого 958

Выходит, что время, затраченное условной командой на создание условного ролика, эквивалентно приблизительно 960 долларам. Это без учёта времязатрат, которые понадобились команде на переговоры друг с другом при обсуждении промежуточных результатов. Оставим это время за скобками: разброс времязатрат здесь практически непредсказуемый, вплоть до отличий на порядок, а количество допущений в расчётах уже приближается к критическому.

Но есть кое-что ещё, что поддается относительно точной калькуляции, а мы это пока не отразили в расчётах.

Прочие расходы



Фото: Arek Socha, Pixabay

  1. Перевод: $20. Столько стоит перевод 1000 знаков с русского на английский в исполнении английского носителя языка в сервисе профессиональных переводов Nitro. 1000 знаков это как раз 120 слов озвучки (идеально для минутного видео) и 8 коротких слоганов.
  2. Дикторская озвучка: $100. Цены на озвучку зависят и от объема текста, и от конкретного исполнителя и его условий, в том числе от минимальной стоимости заказа. Предположим, что мы выбрали опытного диктора из США, который записывается в профессиональной студии и в списке услуг которого есть как раз то, что нам нужно: озвучка роликов для Интернета, длительность до 1 минуты за фиксированную ставку.
  3. Стоковый трек: $30. Бывают треки и по $15, и по $50, а ещё цена в разы увеличивается, если нужна лицензия расширенного типа например для использования в ролике, который будет размещаться на ТВ. Допустим, мы выбрали не самый дорогой трек по стандартной лицензии, которая как раз подходит для публикации ролика на Youtube.

Прибавим эти затраты ($150) к ранее вычисленной сумме. $960+150 = $1110.

Выводы


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

Заказать ролик на аутсорсе или всё же сделать самостоятельно? Каждая геймдев-команда решает на своё усмотрение.

Если вы решите аутсорсить видео посмотрите, какие ролики об играх делают в Alconost.

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

Об авторе


Статья написана в Alconost. Мы уже 8 лет создаём рекламные и обучающие видео, в том числе трейлеры, тизеры и прероллы для игр и приложений. А ещё мы занимаемся локализацией приложений, игр и сервисов на 80+ языков.

Подробнее: alconost.com. Подпишитесь на нас ВКонтакте, Фейсбуке или Твиттере, чтобы первыми увидеть наши свежие работы и анонсы новых публикаций.

Другие наши статьи о создании видеороликов


Подробнее..

Перевод Обучение умных игровых соперников в Unity методом игра с самим собой средствами ML-Agents

18.06.2020 14:14:33 | Автор: admin
Привет, Хабр!

Как знают наши постоянные читатели, мы давно и успешно издаем книги по Unity. В рамках проработки темы нас заинтересовал, в частности, инструментарий ML-Agents Toolkit. Сегодня мы предлагаем вашему вниманию перевод статьи из блога Unity о том, как эффективно обучать игровых агентов методом игры с самим собой; в частности, статья помогает понять, чем этот метод эффективнее традиционного обучения с подкреплением.



Приятного чтения!


В этом после дается обзор технологии self-play (игра с самим собой) и демонстрируется, как с ее помощью обеспечивается стабильное и эффективное обучение в демонстрационной среде Soccer из инструментария ML-Agents Toolkit.

В демонстрационных средах Tennis и Soccer из инструментария Unity ML-Agents Toolkit агенты стравливаются друг с другом как соперники. Обучение агентов в рамках такого состязательного сценария порой весьма нетривиальная задача. На самом деле, в предыдущих релизах ML-Agents Toolkit для того, чтобы агент уверенно обучился, требовалась серьезная проработка награды. В версии 0.14 была добавлена возможность, позволяющая пользователю тренировать агентов методом обучения с подкреплением (RL) на основе self-play, механизма, имеющего принципиальное значение в достижении одних из наиболее высококлассных результатов обучения с подкреплением, например, OpenAI Five и DeepMinds AlphaStar. Self-play при работе стравливает друг с другом актуальную и прошлую ипостаси агента. Таким образом, мы получаем противника для нашего агента, который может постепенно совершенствоваться с использованием традиционных алгоритмов обучения с подкреплением. Полноценно обученный агент может успешно соперничать с продвинутыми игроками-людьми.

Self-play предоставляет среду для обучения, которая построена по тем же принципам, что и соревнование с точки зрения человека. Например, человек, который учится играть в теннис, будет выбирать для спарринга соперников примерно того же уровня, что и сам, так как слишком сильный или слишком слабый соперник не так удобен для освоения игры. С точки зрения развития собственных навыков, для начинающего теннисиста может быть гораздо ценнее обыгрывать таких же начинающих, а не, скажем, ребенка-дошкольника или Новака Джоковича. Первый даже не сможет отбить мяч, а второй не подарит тебе такой подачи, которую ты сможешь отбить. Когда начинающий разовьет достаточную силу, он может переходить на следующий уровень или заявляться на более серьезный турнир, чтобы играть против более умелых соперников.

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

История игры с самим собой в играх

У феномена игры с самим собой долгая история, отразившаяся в практике разработки искусственных игровых агентов, призванных соперничать с человеком в играх. Одним из первых эту систему использовал Артур Сэмюэл, разработавший в 1950-е симулятор для игры в шахматы и опубликовавший эту работу в 1959 году. Эта система стала предтечей эпохального результата в обучении с подкреплением, достигнутого Джеральдом Тезауро в игре TD-Gammon; итоги опубликованы в 1995 году. В TD-Gammon использовался алгоритм работы по методу временных различий TD() с функцией игры самим с собой, чтобы обучить агент игре в нарды настолько, что он мог бы посоперничать с человеком-профессионалом. В некоторых случаях наблюдалось, что TD-Gammon обладает более уверенным видением позиций, чем игроки международного класса.

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

Игра с самим собой наделяет агентов определенной креативностью, не зависящей от творчества программистов. Агент получает лишь правила игры, а затем информацию о том, выиграл он или проиграл. Далее, опираясь на эти базовые принципы, агент должен сам выработать грамотное поведение. По словам создателя TD-Gammon, такой подход к обучению освобождает, в том смысле, что программа не стеснена человеческими склонностями и предрассудками, которые могут оказаться ошибочными и ненадежными. Благодаря такой свободе, агенты открывают блестящие игровые стратегии, совершенно изменившие представления специалистов-инженеров о некоторых играх.

Обучение с подкреплением в состязательных играх

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



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

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



Пример со средой Теннис из инструментария ML-Agents

Рассмотрим демо-пример ML-Agents Tennis. Голубая ракетка (слева) это обучающийся агент, а фиолетовая (справа) его соперник. Чтобы перекинуть мяч через сетку, агент должен учитывать траекторию мяча, летящего от соперника, и делать поправку угла и скорости летящего мяча с учетом условий среды (гравитации). Однако, в состязании с соперником перебросить мяч через сетку это лишь полдела. Сильный соперник может ответить неотразимым ударом, и в результате агент проиграет. Слабый соперник может попасть мячом в сетку. Равный же соперник может вернуть подачу, и поэтому игра продолжится. В любом случае, как следующее состояние, так и соответствующая ему награда зависят как от условий окружающей среды, так и от соперника. Однако, во всех этих ситуациях агент делает одну и ту же подачу. Поэтому как обучение в состязательных играх, так и прокачка сопернических поведений у агента это сложные проблемы.

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



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

Вот здесь нам и пригодится игра с самим собой! Сам агент удовлетворяет обоим требованиям к искомому оппоненту. Он определенно примерно равен по силе самому себе, и навыки его улучшаются со временем. В данном случае в окружающую среду встроена собственная политика агента (см. на рисунке). Тем, кто знаком с постепенно усложняющимся обучением (curriculum learning), подскажем, что эту систему можно считать естественным образом развивающимся учебным планом, следуя которому, агент научается сражаться против все более сильных оппонентов. Соответственно, игра с самим собой позволяет задействовать саму окружающую среду для обучения конкурентоспособных агентов для состязательных игр!

В двух следующих разделах будут рассмотрены более технические детали обучения конкурентоспособных агентов, касающиеся, в частности, реализации и использования игры с самим собой в инструментарии ML-Agents Toolkit.

Практические соображения

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

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

Реализация и детали использования

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

В состязательных играх накопительная награда, выдаваемая средой пожалуй, не самая информативная метрика для отслеживания прогресса в обучении. Дело в том, что накопительная награда целиком и полностью зависит от уровня оппонента. Агент, обладающий определенным игровым мастерством, получит большую или меньшую награду, в зависимости от менее умелого или более умелого оппонента, соответственно. Мы предлагаем реализацию рейтинговой системы ELO, позволяющей рассчитывать относительное игровое мастерство у двух игроков из определенной популяции при игре с нулевой суммой. В течение отдельно взятого тренировочного прогона это значение должно стабильно увеличиваться. Отслеживать его, наряду с другими метриками обучения, например, общей наградой, можно при помощи TensorBoard.

Игра с самим собой в среде Soccer



В последние релизы ML-Agent Toolkit не включается политика агентов для учебной среды Soccer, поскольку надежный учебный процесс в ней не выстраивался. Однако, задействовав игру с самим собой и проведя некоторый рефакторинг, мы сможем обучать агента нетривиальным вариантам поведения. Наиболее существенное изменение это удаление игровых позиций из числа характеристик агента. Ранее в среде Soccer явно выделялись вратарь и нападающий, поэтому весь геймплей выглядел более логично. В данном видео представлена новая среда, в которой видно, как спонтанно формируется ролевое поведение, при котором одни агенты начинают выступать в качестве нападающих, а другие в качестве вратарей. Теперь агенты сами учатся играть на этих позициях! Функция награды для всех четырех агентов определяется как +1.0 за забитый гол и -1.0 за пропущенный гол, с дополнительным штрафом -0.0003 за шаг этот штраф предусмотрен, чтобы стимулировать агентов на атаку.

Здесь еще раз подчеркнем, что агенты в учебной среде Soccer сами научаются кооперативному поведению, и для этого не используется никакого явного алгоритма, связанного с мультиагентным поведением или присваиванием ролей. Этот результат демонстрирует, что агента можно обучать сложным вариантам поведения, пользуясь сравнительно простыми алгоритмами при условии, что задача будет качественно сформулирована. Важнейшее условие для этого заключается в том, что агенты могут наблюдать за своими сокомандниками, то есть, они получают информацию об относительной позиции сокомандника. Навязывая агрессивную борьбу за мяч, агент косвенно подсказывает сокоманднику, что тот должен отойти в защиту. Напротив, отходя в защиту, агент провоцирует сокомандника на нападение.

Что дальше

Если вам доводилось пользоваться какими-либо новыми возможностями из этого релиза расскажите о них. Обращаем ваше внимание на страницу ML-Agents GitHub issues, где можно рассказать о найденных багах, а также на страницу форумов Unity ML-Agents, где обсуждаются вопросы и проблемы общего характера.
Подробнее..

Из песочницы Обнаружение столкновений и теорема о разделяющей оси

04.07.2020 20:20:46 | Автор: admin
В наше время компьютеры представляют собой мощные вычислительные машины,
способные выполнять миллионы операций в секунду. И естественно не обойтись без симуляции реального или игрового мира. Одна из задач компьютерного моделирования и симуляции состоит в определении столкновения двух объектов, одно из решений которой реализуется теоремой о разделяющей оси.



Примечание. В статье будет приведен пример с 2 параллелепипедами(далее кубы), но идея для других выпуклых объектов будет сохранена.
Примечание. Вся реализация будет выполнена в Unity.

Акт 0. Общая теория


Для начала нужно познакомиться с "теоремой о разделяющей гиперплоскости".Именно она будет лежать в основе алгоритма.

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


Разделяющая ось (двумерный случай)


Разделяющая ось (трехмерный случай)
Можно заметить, что проекции на разделяющую ось не пересекаются.

Свойство. Потенциальная разделяющая ось будет находиться в следующих множествах:
  • Нормы плоскостей каждого куба(красные)
  • Векторное произведение ребер кубов $\{[\vec{x},\vec{y}] : xX, yY\}$,

где X ребра первого куба (зеленые), а Y второго (синие).



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

Создадим для этого дополнительный класс, экземпляры которого будут предоставлять информацию о кубе.
public class Box{    public Vector3 Center;    public Vector3 Size;    public Quaternion Quaternion;    public Box(Vector3 center, Vector3 size, Quaternion quaternion)    {       this.Center = center;       this.Size = size;       this.Quaternion = quaternion;    }    // дополнительный конструктор, который    // позволяет сгенерировать объект на основе GameObject    public Box(GameObject obj)    {        Center = obj.transform.position;        Size = obj.transform.lossyScale;        Quaternion = obj.transform.rotation;    }}

Акт 1. Кватернионы


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

Кватернион это гиперкомплексное число, которое определяет вращение объекта в пространстве.

$w+xi+yj+zk$


Мнимая часть(x,y,z) представляет вектор, который определяет направление вращения
Вещественная часть(w) определяет угол, на который будет совершено вращение.

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

Рекомендую две статьи, в которых подробно рассказывается о кватернионах:

Раз
Два

Теперь, когда у нас есть минимальные представления о кватернионах, давайте поймем, как вращать вектор, и опишем функцию вращение вектора кватернионом.

Формула вращения вектора

$\vec{v}' = q * \vec{v} * \overline{q}$


$\vec{v}'$ искомый вектор
$\vec{v}$ исходный вектор
$q$ кватернион
$\overline{q}$ обратный кватернион

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

$q = w+xi+yj+zk$
$\overline{q} = w-xi-yj-zk$

Посчитаем $\vec{v} * \overline{q}$

$ M = \vec{v}*\overline{q} = (0 + v_xi + v_yj + v_zk)(q_w - q_xi - q_yj - q_zk) = $
$=\color{red}{v_xq_wi} + \color{purple}{v_xq_x} - \color{blue}{v_xq_yk} + \color{green}{v_xq_zj} +$
$+\color{green}{v_yq_wj} + \color{blue}{v_yq_xk} + \color{purple}{v_yq_y} - \color{red}{v_yq_zi} +$
$+\color{blue}{v_zq_wk} - \color{green}{v_zq_xj} + \color{red}{v_zq_yi} + \color{purple}{v_zq_z}$

Теперь выпишем отдельные компоненты и из этого произведения соберем новый кватернион
$M = u_w+u_xi+u_yj+u_zk$
$u_w = \color{purple}{v_xq_x + v_yq_y + v_zq_z}$
$u_xi = \color{red}{(v_xq_w - v_yq_z + v_zq_y)i}$
$u_yj = \color{green}{(v_xq_z + v_yq_w - v_zq_x)j}$
$u_zk = \color{blue}{(-v_xq_y + v_yq_x + v_zq_w)k}$

Посчитаем оставшуюся часть, т.е. $ q*M $ и получим искомый вектор.

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

$\vec{v}' = q*M = (q_w + q_xi + q_yj + q_zk)(u_w + u_xi + u_yj + u_zk) =$
$= \color{red}{q_wu_xi} + \color{green}{q_wu_yj} + \color{blue}{q_wu_zk} + $
$ +\color{red}{q_xu_wi} + \color{blue}{q_xu_yk} - \color{green}{q_xu_zj} +$
$+\color{green}{q_yu_wj} - \color{blue}{q_yu_xk} + \color{red}{q_yu_zi} +$
$+\color{blue}{q_zu_wk} +\color{green}{q_zu_xj} -\color{red}{q_zu_yi}$

Соберем компоненты вектора

$v_x' = \color{red}{q_wu_x + q_xu_w + q_yu_z - q_zu_y}$
$v_y' = \color{green}{q_wu_y - q_xu_z + q_yu_w + q_zu_x}$
$v_z' = \color{blue}{q_wu_z + q_xu_y - q_yu_x + q_zu_w}$

$v' = (v_x', v_y', v_z')$
Таким образом необходимый вектор получен

Напишем код:

private static Vector3 QuanRotation(Vector3 v,Quaternion q){        float u0 = v.x * q.x + v.y * q.y + v.z * q.z;        float u1 = v.x * q.w - v.y * q.z + v.z * q.y;        float u2 = v.x * q.z + v.y * q.w - v.z * q.x;        float u3 = -v.x * q.y + v.y * q.x + v.z * q.w;        Quaternion M = new Quaternion(u1,u2,u3,u0);                Vector3 resultVector;        resultVector.x = q.w * M.x + q.x * M.w + q.y * M.z - q.z * M.y;          resultVector.y = q.w * M.y - q.x * M.z + q.y * M.w + q.z * M.x;        resultVector.z = q.w * M.z + q.x * M.y - q.y * M.x + q.z * M.w;                return resultVector;}

Акт 2. Нахождение вершин куба


Зная как вращать вектор кватернионом, не составит труда найти все вершины куба.

Перейдем к функцию нахождении вершин куба. Определим базовые переменные.

private static Vector3[] GetPoint(Box box){        //Тут будут храниться координаты вершин        Vector3[] point = new Vector3[8];        //получаем координаты        //....        return point;}

Далее необходимо найти такую точку(опорную точку), от которой будет легче всего найти другие вершины.

Из центра покоординатно вычитаем половину размерности куба.Потом к опорной точке прибавляем по одной размерности куба.

//...        //первые четыре вершины        point[0] = box.Center - box.Size/2;        point[1] = point[0] + new Vector3(box.Size.x , 0, 0);        point[2] = point[0] + new Vector3(0, box.Size.y, 0);        point[3] = point[0] + new Vector3(0, 0, box.Size.z);//таким же образом находим оставшееся точки        point[4] = box.Center + box.Size / 2;        point[5] = point[4] - new Vector3(box.Size.x, 0, 0);        point[6] = point[4] - new Vector3(0, box.Size.y, 0);        point[7] = point[4] - new Vector3(0, 0, box.Size.z);//...


Можем видеть, как сформированы точки

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

//...        for (int i = 0; i < 8; i++)        {            point[i] -= box.Center;//перенос центра в начало координат            point[i] = QuanRotation(point[i], box.Quaternion);//поворот            point[i] += box.Center;//обратный перенос        }//...

полный код получения вершин
private static Vector3[] GetPoint(Box box){        Vector3[] point = new Vector3[8];                //получаем координаты вершин        point[0] = box.Center - box.Size/2;        point[1] = point[0] + new Vector3(box.Size.x , 0, 0);        point[2] = point[0] + new Vector3(0, box.Size.y, 0);        point[3] = point[0] + new Vector3(0, 0, box.Size.z);//таким же образом находим оставшееся точки        point[4] = box.Center + box.Size / 2;        point[5] = point[4] - new Vector3(box.Size.x, 0, 0);        point[6] = point[4] - new Vector3(0, box.Size.y, 0);        point[7] = point[4] - new Vector3(0, 0, box.Size.z);        //поворачиваем вершины кватернионом        for (int i = 0; i < 8; i++)        {            point[i] -= box.Center;//перенос центра в начало координат            point[i] = QuanRotation(point[i], box.Quaternion);//поворот            point[i] += box.Center;//обратный перенос        }                return point;}


Перейдем к проекциям.

Акт 3. Поиск разделяющих осей


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

  • Нормали плоскостей каждого куба(красные)
  • Векторное произведение ребер кубов $\{[\vec{x},\vec{y}[ : xX, yY\}$, где X ребра первого куба (зеленые), а Y второго (синие).



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



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

  • $\vec{a}$ и $\vec{b}$
  • $\vec{b}$ и $\vec{c}$
  • $\vec{a}$ и $\vec{c}$

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

такой код позволяет получить эти вектора и найти нормали к плоскостям для двух кубов(понятный вариант)
private static List<Vector3> GetAxis(Vector3[] a, Vector3[] b){        //ребра        Vector3 A;        Vector3 B;        //потенциальные разделяющие оси        List<Vector3> Axis = new List<Vector3>();        //нормали плоскостей первого куба        A = a[1] - a[0];        B = a[2] - a[0];        Axis.Add(Vector3.Cross(A,B).normalized);                A = a[2] - a[0];        B = a[3] - a[0];        Axis.Add(Vector3.Cross(A,B).normalized);                A = a[1] - a[0];        B = a[3] - a[0];        Axis.Add(Vector3.Cross(A,B).normalized);                //нормали второго куба        A = b[1] - b[0];        B = b[2] - b[0];        Axis.Add(Vector3.Cross(A,B).normalized);                A = b[1] - b[0];        B = b[3] - b[0];        Axis.Add(Vector3.Cross(A,B).normalized);                A = b[2] - b[0];        B = b[3] - b[0];        Axis.Add(Vector3.Cross(A,B).normalized);        //...}


Но можно сделать проще:
private static List<Vector3> GetAxis(Vector3[] a, Vector3[] b){        //ребра        Vector3 A;        Vector3 B;//потенциальные разделяющие оси        List<Vector3> Axis = new List<Vector3>();//нормали плоскостей первого куба        for (int i = 1; i < 4; i++)        {            A = a[i] - a[0];            B = a[(i+1)%3+1] - a[0];            Axis.Add(Vector3.Cross(A,B).normalized);        }//нормали второго куба        for (int i = 1; i < 4; i++)        {            A = b[i] - b[0];            B = b[(i+1)%3+1] - b[0];            Axis.Add(Vector3.Cross(A,B).normalized);        }        //...}

Еще мы должны найти все векторные произведения ребер кубов. Это можно организовать простым перебором:

private static List<Vector3> GetAxis(Vector3[] a, Vector3[] b){        //...        //получение нормалей        //...        //Теперь добавляем все векторные произведения        for (int i = 1; i < 4; i++)        {            A = a[i] - a[0];            for (int j = 1; j < 4; j++)            {                B = b[j] - b[0];                if (Vector3.Cross(A,B).magnitude != 0)                {                    Axis.Add(Vector3.Cross(A,B).normalized);                }            }        }        return Axis;}

Полный код
private static List<Vector3> GetAxis(Vector3[] a, Vector3[] b){//ребра        Vector3 A;        Vector3 B;//потенциальные разделяющие оси        List<Vector3> Axis = new List<Vector3>();//нормали плоскостей первого куба        for (int i = 1; i < 4; i++)        {            A = a[i] - a[0];            B = a[(i+1)%3+1] - a[0];            Axis.Add(Vector3.Cross(A,B).normalized);        }//нормали второго куба        for (int i = 1; i < 4; i++)        {            A = b[i] - b[0];            B = b[(i+1)%3+1] - b[0];            Axis.Add(Vector3.Cross(A,B).normalized);        }        //Теперь добавляем все векторные произведения        for (int i = 1; i < 4; i++)        {            A = a[i] - a[0];            for (int j = 1; j < 4; j++)            {                B = b[j] - b[0];                if (Vector3.Cross(A,B).magnitude != 0)                {                    Axis.Add(Vector3.Cross(A,B).normalized);                }            }        }        return Axis;}


Акт 4. Проекции на оси


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

Но для начала напомним формулу скалярной проекции вектора v на единичный вектор a:

$proj_\left\langle \vec{a} \right\rangle \vec{v} = \frac{(\vec{v},\vec{a})}{| \vec{a} |}$



private static float ProjVector3(Vector3 v, Vector3 a){        a = a.normalized;        return Vector3.Dot(v, a) / a.magnitude;        }

Теперь опишем функцию, которая будет определять пересечение проекций на оси-кандидаты.

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

private static Vector3 IntersectionOfProj(Vector3[] a, Vector3[] b, List<Vector3> Axis){        for (int j = 0; j < Axis.Count; j++)        {           //в этом цикле проверяем каждую ось           //будем определять пересечение проекций на разделяющие оси из списка кандидатов        }        //Если мы в цикле не нашли разделяющие оси, то кубы пересекаются, и нам нужно         //определить глубину и нормаль пересечения.}

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



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

private static void ProjAxis(out float min, out float max, Vector3[] points, Vector3 Axis){        max = ProjVector3(points[0], Axis);        min = ProjVector3(points[0], Axis);        for (int i = 1; i < points.Length; i++)        {            float tmp = ProjVector3(points[i], Axis);            if (tmp > max)            {                max = tmp;            }            if (tmp < min)            {                min= tmp;            }        }}

Итого, применив данную функцию( ProjAxis ), получим проекционные точки каждого куба.

private static Vector3 IntersectionOfProj(Vector3[] a, Vector3[] b, List<Vector3> Axis){        for (int j = 0; j < Axis.Count; j++)        {            //проекции куба a            float max_a;            float min_a;            ProjAxis(out min_a,out max_a,a,Axis[j]);            //проекции куба b            float max_b;            float min_b;            ProjAxis(out min_b,out max_b,b,Axis[j]);                        //...        }        //...}

Далее, на основе проекционных вершин определяем пересечение проекций:



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

            float[] points = {min_a, max_a, min_b, max_b};            Array.Sort(points);

Заметим следующее свойство:

1) Если отрезки не пересекаются, то сумма отрезков будет меньше, чем отрезок сформированными крайними точками:



2) Если отрезки пересекаются, то сумма отрезков будет больше, чем отрезок сформированными крайними точками:



Вот таким простым условием мы проверили пересечение и непересечение отрезков.

Если пересечения нет, то глубина пересечения будет равна нулю:

            //...            //Сумма отрезков            float sum = (max_b - min_b) + (max_a - min_a);            //Длина крайних точек            float len = Math.Abs(p[3] - p[0]);                        if (sum <= len)            {                //разделяющая ось существует                // объекты непересекаются                return Vector3.zero;            }            //Предполагаем, что кубы пересекаются и рассматриваем текущую ось далее            //....

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

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

Создадим этот вектор перед циклом, и будем хранить в нем вектор с минимальной длинной. Тем самым в конце работы цикла получим искомый вектор.

private static Vector3 IntersectionOfProj(Vector3[] a, Vector3[] b, List<Vector3> Axis){        Vector3 norm = new Vector3(10000,10000,10000);        for (int j = 0; j < Axis.Count; j++)        {                //...        }        //в случае, когда нашелся вектор с минимальным пересечением, возвращаем его        return norm;{

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

Так же я добавил определение ориентации нормали по отношению первого куба.

//...if (sum <= len){   //разделяющая ось существует   // объекты не пересекаются   return new Vector3(0,0,0);}//Предполагаем, что кубы пересекаются и рассматриваем текущий вектор далее//пересечение проекций - это расстояние между 2 и 1 элементом в нашем массиве//(см. рисунок на котором изображен случай пересечения отрезков)float dl = Math.Abs(points[2] - points[1]);if (dl < norm.magnitude){   norm = Axis[j] * dl;   //ориентация нормали   if(points[0] != min_a)   norm = -norm;}//...

Весь код
private static Vector3 IntersectionOfProj(Vector3[] a, Vector3[] b, List<Vector3> Axis){        Vector3 norm = new Vector3(10000,10000,10000);        for (int j = 0; j < Axis.Count; j++)        {            //проекции куба a            float max_a;            float min_a;            ProjAxis(out min_a,out max_a,a,Axis[j]);            //проекции куба b            float max_b;            float min_b;            ProjAxis(out min_b,out max_b,b,Axis[j]);            float[] points = {min_a, max_a, min_b, max_b};            Array.Sort(points);            float sum = (max_b - min_b) + (max_a - min_a);            float len = Math.Abs(points[3] - points[0]);                        if (sum <= len)            {                //разделяющая ось существует                // объекты не пересекаются                return new Vector3(0,0,0);            }            float dl = Math.Abs(points[2] - points[1]);            if (dl < norm.magnitude)            {                norm = Axis[j] * dl;                //ориентация нормы                if(points[0] != min_a)                    norm = -norm;            }        }        return norm;}


Заключение


Проект с реализацией и примером загружен на GitHub, и ознакомиться можно с ним здесь.

Моей целью было поделиться своим опытом в решение задач связанных с определением пересечений двух выпуклых объектов. А так же доступно и понятно рассказать о данной теореме.
Подробнее..

Быстрый лайфхак для роста приложений ASO на других языках

18.06.2020 16:09:14 | Автор: admin


Нужно больше золота пользователей Знакомая проблема? Мы расскажем, как решить ее за счет ASO-оптимизации на других языках.

Многие игры и приложения для расширения аудитории выходят на зарубежные рынки. И это отличный growth hack, но надо переводить не только саму игру, но и ее страницу то есть делать локализацию ASO. Иначе представьте: ваша игра локализована на 10 языков, но, наткнувшись на нее в сторе, немец увидит описание и скриншоты на английском. Конечно, он подумает, что немецкой версии нет.

Локализация метаданных нужна для того, чтобы пользователь легко мог найти приложение на своем языке. Вот, например, как резко выросли позиции RetouchMe (приложения для профессиональной ретуши) после локализации метаданных на 10 языков. После этого успеха RetouchMe локализовали на 35 языков.



Что входит в ASO-оптимизацию?


Говоря про ASO, первым делом вспоминают про ключевые слова. Но ключевики не единственное, что повышает в выдаче ваше приложение и влияет на установки.

Посмотрим, какие элементы страницы входят в ASO-оптимизацию:

  • Название приложения
  • Подзаголовок
  • Описание приложения
  • Ключевые слова
  • Иконка
  • Скриншоты
  • Видео

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

Локализация текста на странице


Название и подзаголовок. Обычно есть одно англоязычное название, которое сохраняется на всех языках. Иногда название могут транслитерировать: например, Bon Voyage Бон Вояж, Tinder (звучит как Tindeo на корейском). Идеально, когда в названии фигурируют универсальные слова, которые известны во всем мире например, War Robots. Компания Pixonic рассказывала, что изначально игра называлась Walking War Robots, но в итоге его сократили до более емкого и понятного War Robots.

Посмотрите, как меняется название игры Blocky Cars в зависимости от локали. Для Китая и Турции название перевели, но в скобках все же оставили оригинальное Blocky Cars.



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

Подзаголовок есть только в App Store, и он, можно сказать, компенсирует короткое название (в App Store это всего 30 символов, в то время как в Google Play 50). В подзаголовок можно добавить те ключевые слова, которые не уместились в названии.

Описание. В Google Play есть краткое описание первые 80 символов описания, те самые 1-2 строчки, на которые можно кликнуть и прочитать полное описание. Советуем регулярно проводить A/B-тестирование краткого описания.

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

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

Из статьи 6 принципов работы с метаданными

Таким образом, для Google Play вам нужно будет аккуратно распихать ключевые слова по описанию так, чтобы они органично вписывались в текст. Есть мнение, что первые 160 символов имеют наибольший вес для индексирования, поэтому стоит использовать самые релевантные ключевые слова в начале описания.

Ключевые слова. Есть отличная статья от ASOdesk о том, как подбирать ключевые слова для названия и описания.

Добавим, что хотя ASO часто называют SEO для мобильных приложений, нельзя судить о популярности ключевого слова по его частотности в веб-поиске (Google, Wordstat) в магазинах приложений свои топы ключевых слов!

Имейте ввиду, что иногда лучше взять два ключевых слова со средней популярностью вместо одного с высокой популярностью (high score), так как почти нет шансов пробиться с ключевиками типа game, taxi и пр. Есть разные инструменты для проверки популярности ключевиков и шансов подняться в выдаче с конкретными ключевыми словами, такие как Mobile Action, Apple Search Ads и др.

Как подобрать ключевые слова на языках, на которых вы не говорите? Для этой задачи есть ряд инструментов в ASOdesk. Keyword Manager предлагает подсказки по ключевым словам, релевантным вашему приложению. К ним прилагается автоматический перевод на английский, что упрощает подбор ключей на других языках.

Также в Keyword Manager есть инструмент Missing Ranked Keywords, показывающий запросы, которые еще не отслеживаются, но по которым приложение ранжируется в конкретной стране. Для этого инструмента также доступен автоматический перевод на английский. Вы можете потестировать эти инструменты для ASO на других языках в бесплатном доступе к ASOdesk.

Важно: если ASO отлично работает в США, и вы решили попробовать этот же набор ключевых слов в Великобритании, Канаде и Австралии это не сработает. Дело в том, что, хоть язык в этих странах и общий, но есть различия в зависимости от страны. Например, слово отпуск в американском английском vacation, а в британском holiday.

Соответственно, поисковые запросы будут отличаться. Та же история с португальским в Бразилии vs. португальский в Португалии, французским во Франции и в Канаде, а также с испаноговорящими странами: то, что работает в Испании, может не работать в Мексике, Аргентине и др.

В некоторых странах говорят на нескольких языках, так что вы можете добавить 2-3 языка для этой страны и увеличить охват аудитории. Например, в США это английский (US) и испанский (мексиканский вариант), в Швейцарии немецкий, итальянский, французский и английский (UK). Полную таблицу по дополнительным языкам в App Store можно посмотреть здесь.

Локализация графики на странице


Помимо текстов, к ASO-оптимизации относятся и графические изображения, а именно иконка и скриншоты.

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

Компания Pixonic интересно подошла к иконкам. Для большинства стран немного меняются элементы фона, но для для турецких пользователей на иконке разместили флаг Турции.



Скриншоты. Многие оптимизируют скриншоты под определенные локали. Это менее актуально для игр, но для приложений это часто оправданно, особенно если на скриншотах изображены люди. Чаще всего есть один вариант скриншотов для Европы и Америки, и второй для Азии (а именно для Японии, Кореи и Китая; остальным азиатским странам показывают европейские скриншоты). В зависимости от типа приложения могут нарисовать скриншоты специально под аудиторию Бразилии и аудиторию из арабских стран.

В PicsArt отдельные варианты скриншотов представлены чуть ли не для каждой страны, для которой есть локализация приложения! Вот некоторые из них:



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

Важно! ASO-оптимизация для Google Play и App Store будет отличаться. Иногда сильно отличаться. Мало того, что у сторов разные требования к скриншотам и объему текста, так еще и ключевые слова должны подбираться отдельно. Именно поэтому у приложений в App Store и Google Play часто не совпадают названия.

То есть запомним: нельзя взять одинаковый текст, ключевики и скриншоты и использовать этот набор и в Google Play, и в App Store. Если так сделать, то эффективность ASO в одном из сторов а может, и в обоих будет низкая.

Влияние локализации ASO на реальных примерах


Давайте рассмотрим влияние ASO на реальном кейсе студии Full HP. Они переводят у нас две популярные игры, free-to-play экшны Blocky Cars и Mad GunZ. Эти игры доступны на 12 языках, а их суммарные загрузки достигают 50 млн. Они засветились в фичеринге от Google Play, и не последнюю роль в этом сыграла ASO-оптимизация.

На скриншотах ниже вы видите показатели конверсии для игры Blocky Cars в Германии:



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

Справа как изменилась конверсия, когда страницу перевели и подобрали ключевые слова на немецком. Прямоугольник на скриншоте стал зеленым, потому что на странице стало больше посетителей, а конверсия выросла на 25%.

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

Перевод описания, текстов на скриншотах и выносках видео удобно отдавать переводчикам-носителям в сервисе профессионального перевода Nitro. Фишка в том, что вам не надо бегать к 10-20 переводчикам с этими мини-текстами: достаточно вставить текст, отметить нужные языки и получить все переводы в течение суток.

Когда можно ждать результатов от ASO-оптимизации? Надо понимать, что ASO разгоняется долго. Чтобы увидеть, как подрастет конверсия, нужно наблюдать и постоянно работать над ключевыми словами и скриншотами, и тогда первые существенные результаты вы заметите через 2-3 месяца.

При этом нельзя один раз сделать ASO и забыть о нем: надо держать руку на пульсе и проверять, какие появляются новые тренды в играх в конкретных локалях и в мире, не появились ли новые удачные ключевые слова. Компания Full HP рассказывала, что чаще всего переписывать ASO приходится в Японии, в Корее, а вот в США нечасто что-то меняют, так как там ASO показывает стабильные результаты.

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

Перспективные рынки для локализации приложения и работы с ASO


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



Это языки, на которые мы рекомендуем локализовать игры. Вы можете захотеть протестировать эти рынки, прежде чем заказывать локализацию игры. Перевод страницы игры то есть локализация ASO как раз помогает проверить потенциал конкретных рынков для вашей игры. Это так называемая Minimum Viable Localization (локализация по программе-минимум).

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

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

Отметим, что выход на рынок Японии, Кореи и особенно Китая сильно отличается от того, к чему мы привыкли в западных странах. Мы написали статью о продвижении приложений в Азии, чтобы вы были готовы к тонкостям Востока заранее.

В мире много быстрорастущих рынков, места на которых лучше занимать заранее. Если вы вдохновились возможностями роста благодаря локализации и ASO на других языках, мы в Alconost будем рады помочь вам с любыми из 70+ наших языков.

Хотите увидеть больше примеров с влиянием ASO и локализации? Читайте наши кейсы:
Кейс Full HP: Как получить фичеринг от Google Play и адаптировать ASO под разные страны
Кейс Wachanga: Локализация приложения на 50+ языков как growth hack

Об авторе

Статья написана в Alconost.

Nitro служба профессионального перевода онлайн на 35 языков. Создана компанией Alconost. Переводчики-носители языка, заказ от 1 слова, онлайн-чат со службой поддержки.
50% заказов готово в течение 2 часов, 96% менее чем за 24 часа.

P.S: Nitro хорошо подходит для перевода небольших текстов. Если вам нужна локализация или перевод проекта посерьезней, добро пожаловать в Alconost.
Подробнее..

Что общего у научной визуализации данных и геймдева обсуждаем в новом подкасте ITMO Research_

20.06.2020 12:14:32 | Автор: admin
Это вторая часть интервью с Андреем Карсаковым (kapc3d), к.т.н., старшим научным сотрудником Национального центра когнитивных разработок, доцентом Факультета цифровых трансформаций.

С 2012 года Андрей работает в научной группе Визуализация и компьютерная графика. Занимается крупными прикладными проектами на государственном и международном уровне.


Фото Hello Lightbulb (Unsplash.com)

В первой части беседы мы обсудили опыт AR-сопровождения массовых мероприятий:




Научная визуализация данных и моделирование процессов


Таймкод (в Apple Podcasts) 40:00



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

kapc3d: Даже скажем так: вот эти проекты, они хоть и крупные, и достаточно громкие, но это 20% из всего объёма задач, которые мы делаем. Мы команда визуализации. Занимались именно научной визуализацией и разрабатывали (и до сих пор разрабатываем) различные инструменты для визуализации данных, связанных с исследованиями. По этой ветке продолжаем работать с крупными заказчиками и с небольшими частными, назовём так, нашими внутренними заказчиками ребятами из других научных групп, которым нужен инструментарий. Например, для визуализации данных, чтобы с ними было удобно работать. К дополненной реальности мы пришли благодаря тому, что используем технологии игровой индустрии для работы с серьёзной визуализацией.


Дмитрий: Стоит пояснить, что можно подразумевать под визуализацией данных для самых разных проектов. Например, расчёт движения людей на определённой станции.

Андрей: Да, вы упомянули проект, который не только с визуализацией связан. Визуализация это представление либо численной, либо абстрактной информации. Мы любим с динамическими формами работать, когда что-то во времени ещё происходит. Визуализация может быть разной, начиная от инфографики. Но визуализация и инфографика это разные вещи. Визуализация данных это больше инженерный процесс. Его задача состоит в том, чтобы показать информативность тех данных, которые у тебя есть. Если они завёрнуты в красивую оболочку, это дополнительный плюс.

Это может быть визуализация воздушных потоков, томография, МРТ-снимки. В таких данных пространственное измерение определёно физическими и химическими свойствами естественных объектов, и мы не можем их изменять. С точки зрения визуализации данных, в частности, абстрактных данных, мы визуальный канал пространства можем использовать как вздумается.


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

Ещё одна из дополнительных веток научной деятельности в нашей лаборатории разработка систем искусственного интеллекта как раз для пешеходной мобильности. Мы занимаемся визуализацией подобных физических процессов. У нас был проект по инструментарию и визуализации гидрометеорологических данных. Занимались прогнозированием уровня,температуры, течения нашего моря, океана, осадков, ветра, геомагнитной обстановки. Работаем с урбанистикой, девелопментом. Ввиду того, что мы делаем визуальную часть, мы исполняем роль неких интеграторов, сборщиков всего в одну кучу, потому что мы предоставляем конечный пользовательский интерфейс. Поэтому какая-то конкретная предметная область для нас не сильно принципиальна, мы с большим количеством отраслей поработали: медицина, урбанистика, с финтехом сейчас крупный проект идёт.



Геймдев и магистерская программа


Таймкод (в Apple Podcasts) 48:52



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

kapc3d: Да.

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

Андрей: Скорее второе. Это эволюционное развитие, нежели какое-то подстраивание под тренды. Раньше ветка с научной визуализацией, с симуляторами, тренажёрами, и ветка потребительской индустрии компьютерных игр достаточно далеко друг от друга жили. Разные технологии, разный уровень оборудования. Для serious games нудны определённые компьютерные мощности, чтобы всё по-честному считалось, это какие-то реальные симуляторы, построенные на реальных моделях (например, тренажёры боевых действий). С другой стороны, компьютерные игры работают на упрощение в угоду оптимизации. Не всегда нужно достоверно что-то воспроизводить, чтобы не терять интерес игрока. Но последние три года эти области приблизились друг к другу, начали смешиваться.

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

Дмитрий: Возникает логичный вопрос. Обыватель представляет себе работу над играми, как некий творческий процесс и для него научная составляющаязанимает процентов 5-10% максимум. Как у вас обстоят дела с этим? Как вы объясняете людям, что эта часть имеет вес?

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

С другой стороны, есть бизнес, который приносит немаленькие деньги. В прошлом году игровая индустрия в два раза превысила по объёму выручки киноиндустрию. Это огромные деньги. Нужно делать конкретные шаги, чтобы отбить стоимость этой разработки. Для этого нужны квалифицированные кадры, чтобы выстроить процессы правильно, эффективно и принимать в нужный момент оптимальные решения. Без науки здесь никуда. Всё, что мы видим в интересных игровых проектах, всё, что нас там цепляет, за всем этим есть очень мощная база R&D.


Диснеевская и пиксаровская команда внесла огромный вклад в развитие компьютерной графики. У них в каждом новом мультфильме или фильме есть новые фишки и технологии, которые они выпускают на SigGraph именно как научные публикации. Например, диснеевская команда придумала метод симуляции снега в Холодном сердце, чтобы он корректно скатывался, следы оставлял. На это тратится невероятное количество человеко-часов, а если ты сделал систему, которая позволяет это воспроизводить, то сразу сокращается стоимость производства, но ты сразу потратился на R&D.

В каждом проекте есть моменты, которые сильно развивают индустрию. Если говорить про игровые проекты, у нас Саша техлид пытается всю нашу команду затянуть в Star Citizen, которая уже долгое время находится в разработке. Каких-то оценок по нему давать не буду. Выглядит всё очень круто. Если посмотреть на техническую составляющую, что они внутри реализуют это просто сумасшествие технологий внутри.

Там практически полностью бесшовная вселенная, притом не уровня No Mans Sky, а в реальных масштабах. Когда ты можешь взлететь с планеты, увидеть где-то там: О, маленькая светящаяся точка на небе, пойду-ка я до неё долечу. Ты садишься в свой космический корабль, взлетаешь с поверхности планеты, влетаешь на орбиту, видишь космическую станцию, к ней подлетаешь, видишь у неё посадочные доки, садишься туда, выходишь из корабля, идёшь по ней гулять всё бесшовно.

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

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


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

Не нужно ехать на природу, чтобы снять красивые кадры. Достаточно поставить перед гринскрином человека, плюс-минус правильно выставить свет. Кстати, и с этим поможет инструментарий условного игрового движка, когда ты знаешь, какое окружения у тебя будет. Так ты уменьшаешь дальнейшие трудозатраты по постпродакшену. В кинопроизводстве это заметно. И даже на примере профессиональных мероприятий. Раньше конференции вроде CG Event были посвящены преимущественно кинопроизводству, спецэффектам, телевизионным фишкам. Последние годы активно заходит блок производства компьютерных игр и блок игровых технологий в цифровых медиа. Например, в Москве чуть ли не отдельная секция была под Unreal Engine.

Дмитрий: Что вы можете сказать о пререквизитах для тех, кто хочет пойти в игрострой? Что нужно знать и что можно посоветовать тем, кто готов посвятить этому свое время?

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

Всё, ты попал в индустрию. Дальше ты понимаешь, как ты хочешь развиваться, учишься, двигаешься, куда угодно. С другой стороны, у нас отсутствует система образования для индустрии игр в России, хотя в Европе и США это давно вполне себе академическая ветка в бакалавриате, магистратуре. У нас это пока серьезно не воспринимали. Когда игровая индустрия начала активно развиваться, у нас были лихие 90-е, где в академии не развивалось ничего. Многие хотят учиться, но не понимают зачем.

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

Главное не быть ленивым. У нас есть возможность поступления по портфолио, если есть проекты, участие в конференциях, шоукейсы или опыт работы в области, связанной с играми, интерактивными технологиями. Достаточно жёстко отбираем, смотрим мотивацию. В этом году 2-3 человека прошло по портфолио, и мы не жалеем. Ребята замотивированные.

Послушать и поддержать нас можно тут:






Тем временем на англоязычной версии Хабра: memory, cyberpunk and startups.


Подробнее..

Перевод Создание шейдерной анимации в Unity

24.06.2020 08:22:39 | Автор: admin
Недавно я работал над анимацией респауна и спецэффектом главного героя моей игры King, Witch and Dragon. Для этого спецэффекта мне нужна была пара сотен анимированных крыс.


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

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

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

Я подробно опишу создание вот этой анимации:

Rat animation

Подготовка


Для начала я создал в Blender низкополигональную модель крысы.

Rat model

Для разделения модели на разные части (тело, хвост, лапы) я использую UV-координаты. Чтобы всё работало как нужно, модель нужно развернуть особым образом.

Rat UV

Основное движение крысы это прыжки. Чтобы все вершины анимировались плавно и синхронно, нам нужно разместить всё тело крысы вдоль одной из осей. Для удобства я разместил её вдоль горизонтальной оси U.

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

Хвост крысы занимает левую половину развёртки (координаты U от 0,0 до 0,5). Это будет нашей маской хвоста, которую мы используем для анимации хвоста.

Лапы расположены в нижней половине развёртки (координаты V от 0,0 до 0,4). Это наша маска лап. Кроме того, лапы сжаты по горизонтальной оси U, чтобы предотвратить нежелательную деформацию при движении вперёд-назад. Так как в своём проекте я использую cel-shading без детализованной текстуры, сжатые UV не вызовут проблем.

На основании этой UV-развёртки я создал диффузную текстуру. Теперь мы можем начать работу над шейдером.

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

Создание шейдера


Сначала я создам этот шейдер в Shader Graph движка Unity, а затем покажу текстовую версию.

Давайте создадим Unlit Graph, в качестве Preview выберем Custom Mesh, а затем выберем модель крысы.


Накладываем текстуру


Создадим новый параметр Texture 3D, это будет наша основная диффузная текстура. Создадим нод Sample Texture 2D, соединим наш новый параметр с его полем texture, а затем соединим нод с полем Color нода Master.


В дальнейшем мы будем работать только с вершинами.

Основное движение


Мы создадим его при помощи синусоиды. Чтобы настроить форму волны, нам нужны три параметра:

  • Jump Amplitude высота прыжков крысы
  • Jump Frequency частота прыжков крысы
  • Jump Speed скорость движения вдоль вертикальной оси


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

Мы можем управлять скоростью прокрутки синусоиды, умножив нод Time на параметр Jump Speed.

Если умножить горизонтальный компонент UV на Jump Frequency, то мы сможем управлять сжатием и растягиванием синусоиды.

Сумма этих произведений даст нам синусоиду нужной формы. По умолчанию синусоида возвращает значения в интервале от -1,0 до 1,0. Если мы умножим их на Jump Amplitude, то получим траекторию прыжка.

Building sive wave

Теперь нам нужно применить результат к позициям вершин, но только к их вертикальной компоненте (локальной оси Y). Мы используем нод Position и соединим его с нодом Split. Затем прибавим значение синусоиды к компоненте Y и соберём всё вместе при помощи нода Combine. Подключим выход этого нода к полю Vertex Position нода Master.

Apply Y-offset

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

Rat sine wave

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

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

Absolute values of the sine wave

Сверху обычные значения, снизу абсолютные.

Давайте добавим этот нод к нашему графу.

Graph absolute node

Теперь анимация стала более скачущей.

Rat absolute sine wave

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

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

Sine wave vertical offset

Сверху абсолютное значение, посередине со смещением, внизу максимум между синусом и нулём.

Чтобы реализовать это в графе, нам нужен новый параметр Jump Vertical Offset, который позволит нам настраивать величину сдвига синусоиды.

Graph abs sine offset

Теперь крыса может какое-то время оставаться на земле.

Rat jump with vertical offset

Дополнительное раскачивание хвоста


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

Мы используем UV-координаты для маскировки хвоста и анимирования его отдельно от тела.

Мы знаем, что хвост расположен в левой половине UV-развёртки. Создадим плавный градиент от 0,0 до 0,5 (или даже до 0,6, чтобы эффект был более плавным) по горизонтальной оси U. В 0,0 у нас будет белый цвет, в 0,6 и далее чёрный. Чем ярче пиксель градиента, тем больше дополнительного движения прикладывается к вершине. По сути, на кончик хвоста он будет влиять сильнее всего, а ближе к телу эффект будет ослабевать.

Для создания этого градиента мы используем нод Smooth Step.

Также нам потребуется новый параметр Tail Extra Swing для задания величины дополнительного движения.

Умножив этот новый параметр на выход нода Smooth Step, мы получим распределение движения вдоль хвоста. Затем мы прибавим его к параметру Jump Amplitude, чтобы получить окончательное движение тела, учитывающее дополнительное раскачивание хвоста.

Graph tail mask

Graph tail mask full

Теперь движение хвоста более заметно (Tail Extra Swing = 0.3).

Rat extra tail swing

Движение лап


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

  • Legs Amplitude величина перемещения лап относительно их позиций по умолчанию
  • Legs Frequency частота движения лап

Нам не нужен параметр Legs Speed, потому что движение лап должно быть синхронизировано с движением тела, поэтому мы снова используем параметр Jump Speed. Единственное, что здесь стоит учитывать: поскольку мы используем абсолютное значение синусоиды, за один цикл получается два прыжка. Поэтому чтобы компенсировать это, мы используем Jump Speed * 2.

Лапы должны двигаться вперёд и назад (и положительное, и отрицательное смещение), поэтому в этом случае нам не понадобится нод Absolute.

Graph legs sine wave

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

Мы снова используем нод Smooth Step, но на этот раз в качестве входного параметра выберем вертикальную ось UV. Давайте зададим градиент от 0,1 до 0,4.

Почему 0,1, а не 0,0? Чтобы избежать деформации лап. Все вершины ниже уровня 0,1 будут иметь одинаковое смещение.

Нам нужно настроить значение Legs Frequency таким образом, чтобы когда передние лапы идут вперёд, задние двигались назад, и наоборот. В моём случае я задал значение 10.

Graph legs mask

Давайте прибавим результат к локальной позиции вершин по Z. Я временно отключил движение тела, чтобы отдельно посмотреть на анимацию лап.

Graph isolated legs movement

Rat isolated legs movement

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

Rat slomo

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

Чтобы решить эту проблему, создадим новый параметр Legs Phase Offset, позволяющий нам компенсировать эту разность фаз и согласовать анимации.

Чтобы это смещение фаз работало, нужно добавить его в нод Time уже после умножения на Jump Speed (чтобы не изменять скорость), но перед всеми остальными манипуляциями.

Graph phase offset

После настройки значения (я указал -1,0) анимация стала правильной.

Rat with phase offset

Вот как это выглядит при нормальной скорости.

Rat final

Готовый граф:

Complete graph

Текстовая версия шейдера


Для тех, кто пока не перешёл на URP/HDRP или просто предпочитает писать шейдеры вручную, вот версия в коде:

Shader "Unlit/Rat"{    Properties    {        _JumpSpeed("Jump Speed", float) = 10        _JumpAmplitude("Jump Amplitude", float) = 0.18        _JumpFrequency("Jump Frequency", float) = 2        _JumpVerticalOffset("Jump Vertical Offset", float) = 0.33        _TailExtraSwing("Tail Extra Swing", float) = 0.15        _LegsAmplitude("Legs Amplitude", float) = 0.10        _LegsFrequency("Legs Frequency", float) = 10        _LegsPhaseOffset("Legs Phase Offset", float) = -1        [NoScaleOffset]        _MainTex ("Texture", 2D) = "white" {}    }    SubShader    {        Tags { "RenderType"="Opaque" }        LOD 100        Pass        {            CGPROGRAM            #pragma vertex vert            #pragma fragment frag            #include "UnityCG.cginc"            struct appdata            {                float4 vertex : POSITION;                float2 uv : TEXCOORD0;            };            struct v2f            {                float2 uv : TEXCOORD0;                float4 vertex : SV_POSITION;            };            sampler2D _MainTex;            float4 _MainTex_ST;            half _JumpSpeed;            half _JumpAmplitude;            half _JumpFrequency;            half _JumpVerticalOffset;            half _TailExtraSwing;            half _LegsAmplitude;            half _LegsFrequency;            half _LegsPhaseOffset;            v2f vert (appdata v)            {                float bodyPos = max((abs(sin(_Time.y * _JumpSpeed + v.uv.x * _JumpFrequency)) - _JumpVerticalOffset), 0);                float tailMask = smoothstep(0.6, 0.0, v.uv.x) * _TailExtraSwing + _JumpAmplitude;                bodyPos *= tailMask;                v.vertex.y += bodyPos;                float legsPos = sin(_Time.y * _JumpSpeed * 2 + _LegsPhaseOffset + v.uv.x * _LegsFrequency) * _LegsAmplitude;                float legsMask = smoothstep(0.4, 0.1, v.uv.y);                legsPos *= legsMask;                v.vertex.z += legsPos;                v2f o;                o.vertex = UnityObjectToClipPos(v.vertex);                o.uv = TRANSFORM_TEX(v.uv, _MainTex);                return o;            }            fixed4 frag (v2f i) : SV_Target            {                fixed4 col = tex2D(_MainTex, i.uv);                return col;            }            ENDCG        }    }}

Заключение


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

Такой способ подойдёт для фоновых объектов, не находящихся в основном фокусе внимания игрока. Кроме того, по сравнению с рендерерами мешей со скиннингом (Skinned Mesh Renderers), он обеспечивает более высокую производительность.

Надеюсь, он был для вас интересным и/или полезным.
Подробнее..

Игра на WebAssembly, часть 2 уровни и опыт, админка

01.07.2020 02:19:17 | Автор: admin
В предыдущей статье получилось сделать прототип игры с вопросами. Но не получилось сделать это полноценно на WebAssembly. В этот раз предлагаю конвертировать этот прототип, сделав с него полноценное WebAssembly приложение, а так же добавить к нему атрибуты большинства игр опыт и уровни игрока. А так же простую логику при переходе на некоторые уровни будем открывать новые навыки.

Demo



Создаем WebAssembly проект


Создадим новый проект, который будет хостить WebAssembly приложение, внутри Web приложения (ASP.NET Core ). Если быть точнее, то Web приложение возвращает WebAssembly приложение, которое остается в браузере у пользователя и взаимодействует с сервером посредством http (или веб сокетов). Для этого, нам нужно создать BlazorApp проект и выбрать пункт ASP.NET Core hosted


Или же, из консоли:
dotnet new blazorwasm --hosted


По скольку у нас уже есть Blazor проект с предыдущей статьи, а синтаксис одинаковый у проектов с серверным хостингом и WebAssembly, то все страницы можно просто скопировать. Но с классами для логики так не получится нужно создать новый контроллер, как часть backend-а. Это обычный asp.net контроллер, с которым наш клиент будет коммуницировать.

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

Меняем версию на .NET 5 preview 6


Срочной необходимости это делать нет. Но, поскольку предварительная версия .NET 5 уже доросла до шестой, поддерживает Blazor и в ней есть некоторые новые фичи (например, extension методы для запросов на сервер), то почему бы и не перейти на неё сейчас. Мигрировать довольно просто, если знать что делать. В нашем случае это замена версий target framework в серверном проекте и переход на новую версию всех nuget пакетов.

Github commit: Update to .NET 5 preview 6


Добавляем опыт и уровень


Для связи между уровнем и опытом будем использовать простую формулу: минимум опыта для уровня = 2^(уровень). Для того, чтобы игрок мог понимать сколько опыта он накопил и какого он уровня, добавим в его модель эти два параметра. А так же, добавим поле в таблицу с вопросами для индикации сколько очков опыта даст один вопрос. Пока все вопросы будут добавлять 1 очко опыта.

Для отображения на пользовательском интерфейсе, используем простые компоненты Bootstrap.
<div class="row">    <div class="col-md-auto">        <span class="badge badge-warning">            Уровень <span class="badge badge-light">@state.Level</span>        </span>    </div>    <div class="col">        <div class="progress mt-1">            <div class="progress-bar" role="progressbar" style="width: @GetExperienceWidgetWidth()" aria-valuenow="@state.Experience" aria-valuemin="0" aria-valuemax="@experienceDiff">                XP: @state.Experience            </div>        </div>    </div></div>


Результат:


Github commit: Add level and experience to UI


Навыки уровней


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

Github commit: Show features depending on level


Так же добавим рейтинг игроков с наивысшим уровнем. Это послужит примером того, как выглядит комит с отдельной компонентой, которая касается разных существующих частей. На мой взгляд, выглядит очень даже понятно.
Github commit: Add leader board


В этом же изменении, при редактировании фидбека на неправильный ответ, наткнулся на интересный момент. Попробовал одновременно подписаться на события нажатия клавиши (если это Enter отправить на сервер) и изменения значения контрола (если оно пустое убрать сообщение о не верном ответе). Оказалось, что такой вариант не поддерживается. Что, в свою очередь спровоцировало как-то это обойти. В описном тикете есть варианты, но я попробовал еще один:
 var timer = new Timer(1);timer.Elapsed += (object sender, ElapsedEventArgs e) => { wrongStyle = "visibility:hidden"; };timer.Start();

Работает именно так, как мне нужно при изменении ответа, сообщение пропадает. Хотя и таймер на 1 миллисекунду. Вообще, использования .NET таймера внутри браузера звучит странно. Но, похоже, что если пользователь не активен, то таймер автоматически замораживается.

Админка


Приятным бонусом использования Blazor внутри ASP.NET Core приложения является возможность использования инструментов зрелого фреймворка. В данном случае мы можем сделать простую админку для просмотра\редактирования вопросов с помощью кодо-генерации.

Добавим несколько типичных строк в логику конфигурации авторизации (Startup.cs) и сгенерируем пару стандартных частей Identity страницы для авторизации и контроллер с представлениями для просмотра вопросов. Получилась простыня кода, из которой руками писалось всего несколько строк.

Github commit: add admin part


Проверка ответов и безопасность


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

Выводы


На сегодняшний день есть как позитивные так и негативные моменты разработки на Blazor. Самое приятное это видеть как интерактивно меняется пользовательский интерфейс, при этом использовать только C# как язык программирования. Как ни странно, не смотря на простоту фреймворка, требуемый пользовательский интерфейс получается сделать довольно просто и при этом всё работает. Из негативных моментов главная проблема, это ощущение сыроватости. Возможно при использовании стабильных версий всё выглядит лучше.

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

Результат:

Github
Demo
Подробнее..

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

19.06.2020 10:21:33 | Автор: admin


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

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

Используем ее и мы в своем мобильном мультиплеерном шутере Dino Squad.

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

В паре слов о нашем коре и технологиях.

Dino Squad сетевой мобильный PvP-шутер. Игроки управляют динозаврами, обвешанными разнообразным вооружением, и сражаются друг с другом командами 6 на 6.

И клиент, и сервер у нас на Unity. Архитектура довольно классическая для шутеров: сервер авторитарный, а на клиентах работает клиентское предсказание. Игровая симуляция написана с использованием in-house ECS и используется как на сервере, так и на клиенте.

Если вы впервые услышали про лагокомпенсацию, вот краткий экскурс в проблематику.

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

Если на локальных сетях эта задержка (в народе именуемая input lag) может быть незаметна, то при игре через интернет она создает ощущение скольжения по льду при управлении персонажем. Эта проблема вдвойне актуальна для мобильных сетей, где случай, когда у игрока пинг составляет 200 мс, считается еще отличным соединением. Часто пинг бывает и 350, и 500, и 1000 мс. Тогда уже играть с инпут лагом в быстрый шутер становится практически невозможно.

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

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

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

Вооружившись этими знаниями, мы начали внедрять серверную лагкомпенсацию в Dino Squad. Прежде всего предстояло понять, как вообще восстановить на сервере то, что видел клиент? И что конкретно нужно восстанавливать? В нашей игре попадания оружия и способностей рассчитываются через рейкасты и оверлапы то есть, через взаимодействия с физическими коллайдерами противника. Соответственно, то положение этих коллайдеров, которое видел игрок локально, нам и требовалось воспроизвести на сервере. На тот момент мы использовали Unity версии 2018.x. API физики там статический, физический мир существует в единственном экземпляре. Возможности сохранить его состояние, чтобы потом его восстановить из коробки, нет. Так что же делать?

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

  1. Про каждого клиента нам нужно знать, в каком времени он видел противников, когда нажимал на клавиши. Мы уже писали эту информацию в пакет инпута и использовали ее для корректировки работы клиентского предсказания.
  2. Нам нужно уметь хранить историю состояний игры. Именно в ней мы будем держать позиции противников (а значит, и их коллайдеров). На сервере история состояний у нас уже была, мы использовали ее для построения дельт. Зная нужное время, мы легко могли бы найти нужное состояние в истории.
  3. Теперь, когда у нас на руках есть состояние игры из истории, нам нужно уметь синхронизировать данные об игроках с состоянием физического мира. Существующие коллайдеры передвинуть, недостающие создать, лишние уничтожить. Эта логика у нас тоже уже была написана и состояла из нескольких ECS систем. Использовали мы ее для того, чтобы держать несколько игровых комнат в одном Unity-процессе. И поскольку физический мир один на процесс, его приходилось переиспользовать между комнатами. Перед каждым тиком симуляции мы сбрасывали состояние физического мира и заново инициализировали его данными для текущей комнаты, пытаясь по максимуму переиспользовать игровые объекты Unity через хитрую систему пулов. Оставалось вызвать эту же логику для игрового состояния из прошлого.

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

public class TimeMachine : ITimeMachine{     //История игровых состояний     private readonly IGameStateHistory _history;     //Текущее игровое состояние на сервере     private readonly ExecutableSystem[] _systems;     //Набор систем, расставляющих коллайдеры в физическом мире      //по данным из игрового состояния     private readonly GameState _presentState;     public TimeMachine(IGameStateHistory history, GameState presentState, ExecutableSystem[] timeInitSystems)     {         _history = history;          _presentState = presentState;         _systems = timeInitSystems;       }     public GameState TravelToTime(int tick)     {         var pastState = tick == _presentState.Time ? _presentState : _history.Get(tick);         foreach (var system in _systems)         {             system.Execute(pastState);         }         return pastState;     }}

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

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

Но в Dino Squad таких механик очень мало! Большая часть оружия в игре создает проджектайлы долгоживущие пули, которые летят несколько тиков симуляции (в некоторых случаях десятки тиков). Как быть с ними, в каком времени они должны лететь?

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

У нас этой опции не было: оружие, основанное на проджектайлах, было ключевой особенностью игрового дизайна. Поэтому нам пришлось что-то придумывать. Немного побрейнштормив, мы сформулировали два варианта, которые нам показались рабочими:

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


На картинке игрок в 30-ом тике стреляет ракетой на упреждение: он видит, в каком направлении бежит противник, и знает примерную скорость ракеты. Локально он видит, что попал в цель в 33-ем тике. Благодаря лагкомпенсации попадет он и на сервере

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

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



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

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

Отдельно стоит поднять вопрос производительности. Если вам показалось, что все это будет тормозить, отвечаю: так оно и есть. Перемещение коллайдеров, их включение и выключение Unity делает довольно медленно. В Dino Squad в худшем случае в бою может одновременно существовать несколько сотен проджектайлов. Двигать коллайдеры, чтобы посчитать каждый проджектайлов по отдельности, непозволительная роскошь. Поэтому нам было совершенно необходимо минимизировать число откатов физики. Для этого мы создали отдельный компонент в ECS, в который мы записываем время игрока. Его мы повесили на все энтити, требующие лагкомпенсации (проджектайлы, способности и т. д.). Перед тем, как начать обработку таких энтитей, мы кластеризуем их по этому времени и обрабатываем их вместе, откатывая физический мир один раз для каждого кластера.

На этом этапе мы получили в целом рабочую систему. Ее код в несколько упрощенном виде:

public sealed class LagCompensationSystemGroup : ExecutableSystem{     //Машина времени     private readonly ITimeMachine _timeMachine;     //Набор систем лагкомпенсации     private readonly LagCompensationSystem[] _systems;          //Наша реализация кластеризатора     private readonly TimeTravelMap _travelMap = new TimeTravelMap();    public LagCompensationSystemGroup(ITimeMachine timeMachine,         LagCompensationSystem[] lagCompensationSystems)     {         _timeMachine = timeMachine;         _systems = lagCompensationSystems;     }     public override void Execute(GameState gs)     {         //На вход кластеризатор принимает текущее игровое состояние,         //а на выход выдает набор корзин. В каждой корзине лежат энтити,         //которым для лагкомпенсации нужно одно и то же время из истории.         var buckets = _travelMap.RefillBuckets(gs);         for (int bucketIndex = 0; bucketIndex < buckets.Count; bucketIndex++)         {             ProcessBucket(gs, buckets[bucketIndex]);         }         //В конце лагкомпенсации мы восстанавливаем физический мир          //в исходное состояние         _timeMachine.TravelToTime(gs.Time);     }     private void ProcessBucket(GameState presentState, TimeTravelMap.Bucket bucket)     {         //Откатываем время один раз для каждой корзины         var pastState = _timeMachine.TravelToTime(bucket.Time);         foreach (var system in _systems)         {               system.PastState = pastState;               system.PresentState = presentState;               foreach (var entity in bucket)               {                   system.Execute(entity);               }          }     }}

Оставалось только настроить детали:

1. Понять, насколько сильно ограничивать максимальную дальность перемещения во времени.

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

2. Определить, какие объекты можно перемещать во времени, а какие нет.

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

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

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

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

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

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

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

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

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

В 2019 версии (а может, и чуть раньше), в Unity появилась плюс-минус полноценная поддержка независимых физических сцен. Мы почти сразу после обновления внедрили их на сервере, поскольку хотелось поскорее избавиться от общего для всех комнат физического мира.

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

Помимо этого, мы провели небольшое исследование на тему того, можно ли использовать физические сцены для хранения истории физического мира. То есть, условно, выделить каждой комнате не одну сцену, а 30 сцен, и сделать из них циклический буфер, в котором и хранить историю. В целом вариант оказался рабочим, но внедрять мы его не стали: он не показал какого-то сумасшедшего прироста производительности, но требовал довольно рискованных изменений. Сложно было предсказать, как поведет себя сервер при длительной работе с таким количеством сцен. Поэтому мы последовали правилу: If it ain't broke, don't fix it.
Подробнее..

Перевод Охотники, щелкуны и Элли как устроен игровой искусственный интеллект в The Last of Us

20.06.2020 12:14:32 | Автор: admin
Вчера состоялся релиз сиквела The Last of Us игры, уже семь лет являющейся одним из наиболее узнаваемых эксклюзивов PlayStation. Это кинематографическая история о человеческих жизнях в бесчеловечной реальности мира, разрушенного современной чумой. В то время, когда игроки берут на себя управление циничным и озлобленным главным героем Джоэлом, искусственный интеллект разыгрывает других персонажей, будь то союзник, враг или зараженный.

На фоне выхода второй части игры рассказываем о том, почему игрокам так понравился оригинал. В этой переводной статье поговорим о философии дизайна The Last of Us, касающейся всех аспектов искусственного интеллекта.



Предупреждение: речь в статье идет только об оригинальной игре 2013 года.


Об игре


The Last of Us игра от третьего лица в жанре action-adventure с фокусом на механиках стелса и динамической системе укрытий. В мире постапокалиптической Америки игроки вынуждены противостоять двум типам противников: охотникам людям, контролирующим и патрулирующим отдельные территории по всей стране, и зараженным существам, в которых превращаются люди, заболевшие грибковой чумой.
Когда мы только начинали создавать прототипы ИИ в случае, когда врагом является человек, первый вопрос, которым мы задались, был следующий: как заставить игрока поверить в реальность своих противников, чтобы ему не хотелось их убивать? Ответ на этот вопрос и стал основой дизайна вражеского ИИ. Для ответа на него потребовалось нечто большее, чем просто нанять лучших актеров озвучки, лучших 3D-художников и аниматоров, хотя все это тоже было немаловажным. Прежде всего нам требовалось решить проблему самого искусственного интеллекта. Потому что, если мы не сможем заставить игрока поверить, будто эти отряды выживших мыслят и взаимодействуют, как настоящие люди, никакие передовые мокапы не удержат игрока в потоке.

Трэвис Макинтош, Вражеский ИИ в The Last of Us, Game AI Pro, том 2, глава 34, 2015

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

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


Архитектура ИИ


Начнем с объяснения основ архитектуры искусственного интеллекта различных персонажей в игре и того, почему Naughty Dog построили ее именно таким образом.

ИИ в The Last of Us строится на использовании конечных автоматов (КА) давно устоявшегося подхода к созданию искусственного интеллекта. Популяризовала его Half-Life еще в 1998 году. Его суть состоит в том, что персонаж может иметь несколько сменяющих друг друга состояний: к примеру, он будет атаковать цель либо искать ее местоположение до тех пор, пока не произойдет событие-триггер, которое переведет его из одного состояния в другое.


Простой КА с двумя состояниями

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

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

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



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

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

Марк Ботта, ИИ зараженных в The Last of Us, Game AI Pro, том 2, глава 33, 2015

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

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




Охотники


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

В первую очередь поговорим о том, как охотники и другие человеческие ИИ могут обнаружить игрока.

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

Прежде всего стоит поговорить о зрении. NPC используют различные поля обзора для обнаружения игрока в пространстве.

Изначально в The Last of Us они были такими же, как в другой серии игр Naughty Dog Uncharted. Но со своей функцией они справлялись плохо: игрока слишком быстро замечали как на близком, так и на дальнем расстоянии. Они не соответствовали темпу игры, а потому были видоизменены и имели уже не конусообразную форму. Теперь поле зрения NPC стало напоминать контур замочной скважины, тем самым обеспечивая более широкое периферическое зрение и более узкий обзор на расстоянии.


Поле зрения NPC в Uncharted


Поле зрения NPC в The Last of Us

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

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



У охотников есть множество навыков. Как мы видим, большинство из них строится вокруг боя: ближнего, дальнего, при прямом наступлении или подходе с фланга. Большинство последовательностей боевых действий в The Last of Us начинается с того, что игрок, пребывавший в невидимом режиме, оказывается обнаружен. Поэтому сейчас мы сосредоточимся на двух навыках, наиболее критических в режиме стелса: на расследовании и поиске.

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

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

Давайте рассмотрим, как эти системы запускают в работу режимы поиска и расследования.

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

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

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

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


Часть территории не видно, но ее можно проверить

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

Прежде всего, врагам может понадобиться укрытие. Как они узнают, где лучше спрятаться? В данном случае снова используется система очков укрытий, но уже с другими критериями. Нам уже не нужны открытые посты, теперь нам нужна защита для юнита. Игра выполняет подсчет 20 ближайших точек для укрытия на карте в пределах радиуса NPC, а затем запускает 4 рейкаста на каждый фрагмент укрытия, чтобы оценить, сможет ли игрок убить врага в перестрелке с этой позиции. Если система решает, что место безопасно, оно оценивается по степени удобства достижения и тому, не нужно ли ИИ при этом перемещаться перед игроком. Укрытия ранжируются по этим критериям, после чего персонаж выбирает пост, набравший наибольшее количество очков. При этом стоит учитывать, что наиболее предпочтительная позиция в данный момент может потерять свою актуальность уже спустя 5 секунд, стоит лишь игроку переместиться в другую точку, и тогда последующие расчеты других наилучших мест могут повлиять на темп битвы.


Выбор наилучшего укрытия с учетом позиции игрока

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

Перво-наперво в этот момент игра создает ссылку на местоположение игрока. Генерируется пакет данных с его координатами и соответствующей временной меткой. Ее полезно знать для того, чтобы засечь, сколько времени прошло с тех пор, когда игрока было видно в последний раз. Если Джоэла заметит другой NPC, будет сгенерирован новый пакет данных. Всякий раз, когда это происходит, сгенерированные данные совместно используются и другими NPC, находящимися поблизости. Охотники будут продвигаться к локации игрока: одни используя укрытия, чтобы застать его врасплох, другие напролом. Роли между NPC распределяет боевой координатор. Среди них: фланкер, передовой, сопутствующий стрелок, выжидающий наводчик.

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

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



Зараженные


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

Существует несколько видов зараженных, чьи навыки и даже сенсорные системы могут сильно различаться. Бегуны быстрые и злобные существа, часто атакующие группами. Сталкеры быстро передвигаются и часто устраивают засады на игрока в затемненных местах. Щелкуны полностью слепы и в выслеживании игрока полагаются только на слух. И, наконец, топляки тоже слепые и при этом достаточно медленные монстры, но в то же время имеющие мощную броню, которую вовсе не легко пробить.

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

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

Давайте посмотрим на то, как работает звук в игре.

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


Радиус распространения звука

Эти логические звуковые события генерируются для подавляющего большинства внутриигровых событий, в особенности для движения и боя либо для работы таких предметов, как генераторы или транспорт. Тем не менее, еще существуют такие невидимые события, которые генерируют звуки, но игрок их не слышит. Например, к ним относится звук дыхания Джоэла. Мы его не слышим, но он помогает NPC найти игрока, если тот прячется где-то поблизости.

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



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

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



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

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

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

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

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

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

image

Элли


Теперь, когда мы изучили философию искусственного интеллекта противника, осталась еще одна неохваченная тема: ИИ союзника и, в частности, Элли.

Одна из первых демонстраций игры в январе 2013 года показывала то, как игроки покидают карантинную зону Бостона. Тэсс и Элли под предводительством Джоэла пробирались сквозь небоскреб, переполненный бегунами и щелкунами. В этом демо персонажи-компаньоны должны были держаться поодаль от места чистки от зараженных, но в то время их ИИ был еще сырым и не соответствовал задуманному Naughty Dog.

Итак, давайте поговорим о приоритетах ИИ в случае с Элли:

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

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

Чтобы Элли могла следовать за Джоэлом, игра создает область вокруг игрока, которой также стараются придерживаться Тэсс, Билл, Генри и Сэм хотя обычно они держатся на большем расстоянии от Джоэла, нежели Элли. Как только эта область выстроена, игра отправляет рейкасты параллельно навигационной сетке в целью поиска подходящих позиций для размещения компаньонов. Как и в случае системы очков укрытий, каждая позиция оценивается по таким параметрам, как расстояние до врагов и союзников, угол относительно позиции игрока, не блокирует ли геометрия взгляд на Джоэла или движение вперед. Решить эту проблему правильно невероятно трудно и все же, пусть система неидеальна, гораздо чаще ей удается разместить персонажа правильно, чем не удается.


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

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

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

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


Режим следования в укрытии


Режим защиты в укрытии

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

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

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

И остается еще один немаловажный приоритет.

ИИ Элли читерит в пользу игрока в очень специфических ситуациях, но как часто случается в играх делает это для того, чтобы свести к минимуму разочарование игрока и улучшить общее впечатление от прохождения игры. Так, Элли телепортируется к Джоэлу, если его удерживает противник, чтобы помочь тому избавиться от угрозы. В бою точность стрельбы девочки будет варьироваться в зависимости от того, находится ли ее противник в поле зрения игрока или вне его. За экраном Элли не причинит противнику никакого вреда, но часто поворачивается для того, чтобы выстрелить в кого-то, кого Джоэл может видеть. Отчасти это сделано для поддержки игрока, но также и для того, чтобы показать, что она не просто привязанный к игроку NPC, но действительно вовлечена в конфликт.

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

Заключение


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

Godot, 1000 мелочей

01.07.2020 20:13:32 | Автор: admin
Недавно открыл для себя Godot engine, опенсурсный игровой движок. Делюсь некоторыми приёмами и заметками, в основном из области 3д, кода или общих моментов.


У Godot в целом репутация скорее 2д движка, которое проработано довольно хорошо, но и не так давно появившиеся 3д возможности позволяют делать трёхмерные игры. Особенно если вы в состоянии оптимизировать какие-то вещи самостоятельно, не делаете слишком уж тяжёлую и комплексную игру, а также вас устраивают текущие варианты рендера. Ну или можете ждать будущих оптимизаций и появления vulkan.

Из коробки в движке есть некоторая физика, в том числе джоинты и колёсный транспорт. Нет встроенного редактора terrain, но можно воспользоваться плагином, импортировать из специализированных программ или просто как меш из 3д пакета. В последнем случае ради производительности придётся самостоятельно резать ландшафт на фрагменты-чанки, и скорее всего делать им отдельные меши под коллизии. Что касается мешей под форму коллизии ландшафта чтобы не было визуальных нестыковок, нужно триангулировать модель во время экспорта из 3д пакета. Например, один из простейших способов это сделать в Blender экспортировать меш в формате collada (.dae), там по дефолту стоит галочка triangulate.

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


Сцена с объектом theEnergy, который будет помещён на уровень для сбора игроком. В качестве основы используется узел Area, к которому прикреплена форма коллизии, а также сферический примитив, внутрь которого вложен ещё один.

Что касается языков, то если не рассматривать низкоуровневый способ, то наиболее ходовые варианты это скриптовые языки GDScript и C#, а также визуальный скриптинг для чего-то простого. GDScript лучше интегрирован в движок, имеет больше примеров, не требует запуска внешней среды, а в плане общей структуры тут будет происходить всё то же, что в варианте C# объявление переменных, вызов функции инициализации, цикл процессов, цикл физических процессов и так далее. Так что выбор GDScript в качестве основного скриптового языка разработки имеет смысл. Пересаживаясь на C# получим разве что большую аккуратность и подробность записи, теряя в лаконичности, но усиливая разборчивость и контроль над ситуацией фигурные скобочки вместо использования табуляции, отметки конца строки, более формальную типизацию.
Что касается глобальных переменных, то для их использования что в GDScript, что в C# потребуется добавить в параметрах проекта глобальный скрипт/скрипты в автозагрузку, к переменным которого можно будет обращаться глобально.
Также в Godot действует ограничение -на каждом объекте не может быть больше одного скрипта. Но этот момент можно обойти, например, повесив второй скрипт на дочерний объект.

Сигналы


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


Заводим сигнал

Излучаем его в том же скрипте при нажатии кнопки или других условиях

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


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

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


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

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



CGS-объекты



Один из полезных 3д инструментов в Godot примитивы constructive solid geometry. Проще говоря это объекты, поддерживающие булевы операции пересечение, исключение, объединение. Кроме набора примитивов есть универсальный CGS Mesh, в качестве формы для которого можно установить уже произвольный меш.



Пустышка CGS Combiner потребуется для использования в иерархии, чтобы управлять приоритетом применения операций, если в этом есть необходимость при сборе какой-то сложной конструкции.

Основное применение CGS удобство и простота прототипирования статики уровня и каких-то его элементов. По факту можно сделать меш в 3д пакете, и повторить в нём те же самые результирующие формы, разве что этим надо будет заниматься вне игрового редактора.

Следующее применение статических CGS имитация разрушаемости и повреждений. для этого требуется расставить CGS примитивы в режиме исключения, как дыры, огрызки и вмятины, а затем временно скрыть, включая видимость в нужный момент. Ограничение тут в том, что повреждать мы можем только поверхность CGS объекта, к тому же повреждение должно быть изначально прикреплено к нему как дочернее либо крепиться через код, как потомок. Зато такой вариант по гибкости настройки уже значительно выигрывает по сравнению с заготовленным в 3д-пакете разрушаемым объектом.




Далее у нас идут CGS движущиеся. Через код, либо записанную анимацию. В целом через этот способ можно реализовывать какие-то эффекты, но очень желательно чтобы подобные анимации не крутились на сцене в цикле. Несколько анимированных CGS могут заметно посадить производительность, к тому же в Godot оптимизирует не все вещи, и если вы не вырубите анимированные CGS самостоятельно, то они будут продолжать расходовать производительность вне видимости камеры.
Тем не менее эффекты анимированных CGS уже сложно заменить решениями 3д пакета, поэтому вы можете быть заинтересованы именно в их использовании (по крайней мере, если не собираетесь рисовать продвинутое 3д через код). Главное найти им правильное применение, лучше всего их использовать точечно, в определённых местах, включая анимацию по триггеру. Как эффект открытия прохода или прочий разовый спецэффект. Естественно, чем проще форма CGS объектов тем лучше. А основную вычислительную нагрузку они оказывают именно в процессе соприкосновения в движении, притом нет особой разницы, какой именно объект двигать относительно другого.


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

Вложенность нейросетей инструмента автопозинга в Cascadeur

17.06.2020 16:18:48 | Автор: admin

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

В этой статье будет рассмотрен подход, позволивший нам реализовать достаточно продвинутый функционал, используя лишь стандартные deep learning методы.

Постановка задачи


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



Использование полносвязных нейросетей предполагает фиксированные вход и выход, поэтому мы сделали несколько нейросетей с разным количеством входных точек: 6, 15, 20, 28 точек из всех 43 точек персонажа. На картинках ниже в зеленый окрашены те точки, которые подаются на вход нейросети соответствующего уровня детализации.


В чем же проблема использования уровней детализации? Если мы хотим подвинуть точку из 4-го уровня, то нам нужно подать на вход все 28 точек. Но мы не хотим заставлять пользователя ставить их все. Наша цель дать ему возможность подвинуть только несколько из них. Как в таком случае добиться хорошего результата? Наше решение предполагает вложенность входных данных, комбинирование результатов и использование физической модели.

Вложенность входных данных


Мы выбрали такие уровни детализации, которые имеют особое свойство иерархической вложенности.


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

Комбинирование результатов


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


Как только вы меняете еще одну точку, кроме основных 6, инструмент запоминает ее и начинает использовать в вычислении позиции других точек. Работа инструмента происходит в несколько этапов в зависимости от отредактированных точек. В данном случае весь процесс схематично изображен на картинке ниже.


Сперва используется сеть первого уровня она выставляет все 43 точки персонажа по 6 основным. Затем по очереди вызываются сети более детальных уровней. Каждая последующая принимает на вход все более детальные входные данные либо уточненные пользователем, либо из результата работы предыдущего уровня. Таким образом мы получаем возможность использовать нескольких нейросетей с разной детализацией одновременно.

Физическая корректность


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


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

Заключение и планы


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

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

Мы продолжаем развивать наш инструмент автопозинга. Уже в ближайшее время Cascadeur войдет в стадию открытого бета-теста. Обязательно следите за новостями на cascadeur.com и в социальных сетях проекта.

Узнать больше о Cascadeur и других проектах студии Banzai Games:

Почему 12 принципов Диснея недостаточно
Cascadeur: задача о падающей кошке
Физика в Unity-проекте на примере мобильного файтинга
Cascadeur: будущее игровой анимации
Искусственный интеллект в файтинге Shadow Fight 3

В команду Banzai Games требуется Qt GUI программист. Подробнее о вакансии можно прочитать здесь.
Подробнее..

Хочу в геймдев 27 ответов от 8 профи

17.06.2020 16:18:48 | Автор: admin
Это материал для джунов, которые хотят устроиться в геймдев. Восемь директоров дают советы: с чего начать, как вести себя на собеседовании, как на собеседованиях оценивают кандидатов, что делать, если нет нормального портфолио, нужно ли высшее образование, есть ли стажировки и многое другое.




Перед вами сухая выжимка советов и другой полезной информации с круглого стола, проведенного в конце мая через нашу площадку Leader-ID Высшей школой бизнес-информатики НИУ ВШЭ. В рамках поддержки своих обучающих программ они собрали экспертов и расспросили их про то, как джуну попасть в геймдев.

Кто давал советы и делился опытом:
  • Константин Сахнов (Kallist) совладелец издательства JustForward и игровой продюсер;
  • Михаил Кузьмин Marketing Director в TinyBuild;
  • Олег Доброштан директор по развитию и обучению в 101xp;
  • Сергей Волков HR Director в 1C Game Studios/1C Entertainment;
  • Алина Мудрая СЕО Values Value;
  • Роман Васильев Co-founder & CEO платформы inGame job;
  • Владимир Пранов Head of HR в Vintersaga;
  • Вячеслав Уточкин (viacheslavnu) директор образовательных программ по игровой индустрии ВШБИ НИУ ВШЭ.




Главный вопрос: сколько будут платить джуну?


Роман Васильев привел данные с ежегодного зарплатного опроса на inGame job.
Вот как выглядит медианная зарплата новичков по направлениям:



Лучше всего с зарплатами для джунов в локализации, аналитике и менеджменте, а замыкают список DevOpsы.

А вот медианная зарплата новичков по странам:



Где искать вакансии


Владимир Пранов: В Фейсбуке по запросу геймдев легко найти много интересных групп, где выкладываются вакансии, делятся новостями люди из индустрии, и можно выложить свое резюме. Еще есть платформы inGame Job и Talents in Games, где можно регистрироваться в качестве кандидатов, создавать резюме, откликаться, писать сопроводительные письма и пытаться найти работу.

Что должно быть в резюме



Это инструкция от Values Value. Подробнее тут

Алина Мудрая: Резюме должно быть структурированным, коротким (не больше одной страницы), не быть пестрым: черный текст, белый фон. Семейное положение может быть важно для работодателя, но демонстрировать вы его не обязаны. Называть файл с резюме лучше по своему имени и фамилии.

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

Ошибки при создании резюме и на собеседовании


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


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

Какое образование нужно


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

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


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

Роман Васильев: Многие руководители смотрят на образование не как на корочку, а как доказательство целеустремленности и способности к обучению соискателя, потратившего время на серьезную учебу.

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

Что делать, если нет опыта


Михаил Кузьмин: Если у соискателя не было опыта в геймдеве, он, скорее всего, попадет на начальные позиции вне зависимости от того, чем он раньше занимался. Кроме программистов фронтенда и бэкенда: для них ограничений не существует. Чем лучше вы понимаете свой желаемый карьерный путь, тем скорее сможете по нему двигаться, и выйдет это у вас за год-три в компании об этом узнают на собеседовании и дальше смотрят, насколько вы подходите. Для успешного старта нужна большая наигранность в самых разных жанрах, которая выражается в том, что вы знаете рынок, можете про него рассказать, и желание много работать, поначалу даже немного механистично. Первичные профессии: Q&A, техподдержка и иногда все, что с приставкой джуниор, если уже где-то подучились или есть релевантное портфолио.

В tinyBuild часто просят у геймдизайнеров ссылку на открытый Steam-профиль (или другую платформу), который может многое сказать о соискателе и его понимании жанров.

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

Иногда от резюме почти ничего не требуется: покажите мотивацию и готовность муторно работать руками.


Стартовые позиции зависят от компании, иногда достаточно горящих глаз.

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

Стажировки в геймдеве


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


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


Алина Мудрая СЕО Values Value

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

Во многих компаниях, например 1С Games и 101XP, начальные позиции как раз и выступают как стажировки.

Что может оттолкнуть в кандидате


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


Сергей Волков HR Director в 1C Game Studios/1C Entertainment

На собеседовании или обсуждении проекта с издателем


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


Константин Сахнов совладелец издательства JustForward и игровой продюсер

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

Совет про питчинг (презентацию проектов)


Константин Сахнов: Часто встречающаяся ошибка начинающих разработчиков пытаются придумать сложную концепцию. Лучше сделать что-нибудь попроще, хотя амбиции это хорошо.

Михаил Кузьмин: Есть примеры успешных кейсов у свежесобранных на энтузиазме команд. Black Skylands игра с очень красивой рисовкой, которая разрабатывалась на редко используемом движке. TinyBuild подписались на проект, дали денег, помогли с арендой офиса в Москве. Автор доукомплектовал команду, перенес игру на Unity (потому что игру будет проще портировать на различные платформы), и они сейчас ее допиливают.

Кто такой геймдизайнер и чем отличается от продюсера


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

Как придумывают игровые механики


Константин Сахнов: Все, что мы придумываем, мы осознанно или неосознанно копируем из природы или из произведений других авторов. Можно использовать эту методику открыто и последовательно.

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

Есть и другой способ: скопировать что-то и убрать какой-то элемент.
Самый простой вариант расширять свое сознание и кругозор и активно смотреть вокруг себя. Важнее всего не пытаться перенести какие-то игры целиком на другие платформы.

Удаленка и офис в геймдеве


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


Олег Доброштан директор по развитию и обучению в 101xp

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

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

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

Если геймдев супермечта


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

Профессиональное выгорание в геймдеве


Олег Доброштан: От выгорания может помочь отдых или занятие спортом. Если жить и работать как в сериале Lets dance, выгорание не создает больших проблем.

Про шансы, перспективы и трудоустройство


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

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

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

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

Вячеслав Уточкин: Будет прекрасно, если спустя несколько лет у вас появится чувство, что приняли правильное решение и стали заниматься тем, что приносит исключительное удовольствие и финансовую стабильность.

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

Роман Васильев: Бояться не надо, надо пробовать. Иногда стоит откликнуться на вакансию, ведь не все требования там ключевые. В любом случае это лучше, чем не сделать ничего.
Подробнее..

Из песочницы Анализ геймдизайна Hollow Knight. Часть 1. Забытое перепутье

17.06.2020 14:20:13 | Автор: admin


Привет! Я буду подразумевать, что если вы читаете это, то прошли Hollow Knight. Это позволит мне не описывать каждый пенек, а уделить больше времени важным вещам.

своих эссе про Город Слёз я касался темы того, как формируется поведение игрока. Но если там фокус был на самой ситуации, и я не сильно вдавался в детали, чтобы не перегружать повествование; то сейчас я хочу разобраться с этим настолько подробно, насколько это будет необходимо. Таким образом, я начинаю серию материалов о геймдизайне Hollow Knight. И здесь самое время внести ясность, поскольку понятие геймдизайна слишком широкое. В общем смысле оно о том, как передать человеку задуманный опыт. Меня интересует то, как геймплейные возможности ведут к определенному поведению, так что на этом будет центральный фокус. Ясное дело, что на то, как себя вести, будет также влиять звукорежиссура, визуальная составляющая, и прочие несомненно важные вещи, так что иногда я буду говорить и о них.

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

Если вы задумаетесь, что влияет на поведение игрока, то на ум придет множество вещей. Но на что ориентироваться в самом начале? Вероятно, вы неоднократно слышали про силу цвета, света, направляющих линий, композиции, а также других классических приемов, которые позволяют управлять человеческим вниманием. И это довольно универсальные правила, но они не являются гарантией, что даже в линейной игре человек будет делать то, что задумано. Как же Team Cherry справились с начальным этапом прохождения, где закладываются важнейшие аспекты игрового поведения? Давайте разбираться.

Your browser does not support HTML5 video.

Ролик ничего не говорит, помимо того, что произошла какая-то неведомая хрень. Это важно, поскольку если бы в нем сообщалась конкретная информация, то это сильно бы влияло на дальнейшее поведение, т.к. больше ничего о мире игрок бы не знал. ГГ падает, игрок получает управление, и сразу же возникает вопрос, а куда идти, налево или направо? Ну, во-первых ХК изначально повернут вправо, если же есть предшествующий опыт, то он тоже подскажет, что базовое направление в платформерах слева направо. Можно порассуждать о том, почему так: может потому что европейцы читают слева направо, сверху вниз. Но один из первых культовых платформеров сделали японцы и тут самое время обрубить всю эту историю, потому что вероятность определенного поведения важна, если она ведет к значимым изменениям. (А в данном случае слева находится тупик с гео). Именно поэтому в большинстве случаев я буду сначала рассматривать опции, доступные игроку, а уже потом дополнять их рассуждениями, если они вообще потребуются. По такому поводу рассмотрим сразу весь туториал.



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

Your browser does not support HTML5 video.

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

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

В нём первый NPC. Он даст некоторую информацию, что будут делать и все другие после него. Интересность их монологов будет зависеть от индивидуальности игрока. И в любом случае персонажи будут просто подстегивать чувство неизведанного, тем самым мотивируя проходить дальше. Здесь же происходит знакомство с местной системой сохранения, которую, кстати, можно абузить, при этом узнать об этом довольно легко, а сл-но многие будут этим пользоваться. В конце можно найти тупик с запертой дверью. Далее спуск в Забытое Перепутье.



Здесь у игрока есть единственная тропка, по которой он пройдет в 100% случаев, все остальное является опциональным.

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


Храм черного яйца

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



В конце этажа первый серьезный враг самое время рассказать о том, как смерть влияет на игрока. Фактора тут два. Во-1, это наказание за поражение, так что игрок будет впредь стараться его избегать. А во-2, это отрицательное подкрепление, что должно заставить возвращаться к месту смерти. Вместе это создает цену навыкам игрока: в такой ситуации достижение цели будет гораздо приятнее.

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


Шахта

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

Your browser does not support HTML5 video.

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



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


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



А вот уступ пониже уже не так явно выделяется, что не удивительно, поскольку проход на данном этапе для большого числа игроков закончится необходимостью апгрейда. Однако его можно преодолеть с помощью погинга, и в таком случае встретить мини-босса, который является сильнейшим врагом на данном этапе. Возможностей уворачиваться не так много, а суммарно придется нанести 60 ударов. Челенж хоть и нелегкий, но вполне преодолимый, поскольку есть достаточное количество окон как для хила, так и атак. В награду игрок получит кусок маски, который сам по себе ничего не делает, а гео с Чревня не выпадает вовсе. Таким образом, основной наградой будет осознание того, что человек прошел необязательное испытание, которое большинство игроков в начале пропустят. Для некоторых это будет весьма круто, но гео сверху я бы всё-таки накинул.

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



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



А тут большинство игроков в вероятнее всего встретит своего первого мини-босса. Матка Жужж не особо опасный противник, но в случае смерти идти до нее придется прилично, если не найти лавку рядом с вокзалом, и тем более рядом с горячими источниками. В награду игрок получит гео. Справа недосягаемый склон, откуда слышны тревожные маньячные звуки. И далее можно найти Слая, после диалога он будет продавать в Грязьмуте полезные вещи.



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

Your browser does not support HTML5 video.

Ложный Рыцарь явно посложнее Матки Жужж, но все еще не должен доставить трудностей. Атаки медленные, сносят стандартную одну маску как при атаках, так и при сближении. Окна для хила огромные. Проблем с хитбоксами и телеграфированием нет. Если ХК умирает, то всего пару комнат и можно попытаться снова. Кстати, о последних трех вещах я буду говорить впредь, только если будут какие-то косяки. Единственная сложность босса в том, что на нем можно накапливать душу только при атаках самого опарыша, но не его брони.

Интересная деталь: как только босс в первый раз выполнит свою атаку после нока, левая сторона арены станет хлипкой и ее можно будет сломать. По словам разработчиков, это было сделано для тех людей, которым даже первого босса будет слишком трудно одолеть. И данный вариант возможность продолжить путешествие, и с новыми силами вернуться и попытаться вновь позже. Звучит интересно, поскольку добавляет вариативности, но есть ряд проблем. Для примера: я об этой возможности не знал ровно до тех пор, пока не прочёл о ней на вики. И также читал комментарии других людей, которые тоже понятия об этом не имели, так что проблема не единичная. Почему так? Во-первых, сама возможность не очевидна. До этого боя мы могли встретить всего 2 подобных энкаунтера, и из них выбраться живым было нельзя, не победив врага. Сами разрушаемые стены точно так же можно было встретить, но нет гарантии, что конкретный игрок будет о них знать, даже с учетом всех приложенных усилий. Так или иначе, разрушаемая стена арены первый подобный случай ( и, кстати, единственный ). Ну окей, скажем, можно было догадаться, ведь отчетливо видны трещины в стене, а также визуально это подчеркнуто отлетающими досками. Ладно, но что если игрок находится в другом конце арены? Также надо учитывать, что в этот момент его внимание будет сфокусировано на бое. Если сражаться будет слишком легко, то вы может и заметите эту деталь, но она вам не пригодится. А если сложно то скорее всего упустите, если только ради прикола в панике не начнете долбить по стенам, мол выпустите меня: вот в таком случае вас будет ждать приятный сюрприз. По какой-то причине атаки босса, если он прижмет игрока к стенке, не могут разрушить выход. Также странно, что не происходит никакого треска, хруста или чего подобного вместе с визуальным эффектом.

Your browser does not support HTML5 video.

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

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

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

Your browser does not support HTML5 video.

В родовом кургане находится апгрейд, который позволит направиться в следующую локацию. Сама комната, естественно, задизайнена таким образом, что без применения заклинания ее не пройти. Так что теперь игрок будет знать, как справиться с Древним Бальдром на входе к Зелёной Тропе. Сразу после находится амулет.

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



Весь ассортимент скупить не получится, так что придется выбирать. Если полностью пробежать Перепутье, при этом ничего не терять при смерти, а также усиленно не фармить, то в итоге будет примерно 1200 гео. Из которых игрок с крайне высокой вероятностью потратит 30 на карту, 220 на компас, 120 на перо, а также 50 на вокзал. Остается 780. Важно, что фармить в этой локации не очень-то приятно. Самый эффективный способ убивать оболочку стражника, из которого высыпается 45 гео. Так что допустим, что раз максимум 5 игрок может на него сходить, но потом всё равно заскучает.

Естественно, могут быть люди, которым всё ни по чем, и они сразу же нафармят себе на фонарь 1800 гео, что позволит им второй локацией посетить Кристальный Каньон, хоть исследовать его толком и не получится, поскольку не будет необходимых апгрейдов. И закончится все в Землях Упокоения, где находится гвоздь грез. Рут возможный, но малоинтересный и маловероятный, так что подробно на нем останавливаться не будем.

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

Your browser does not support HTML5 video.

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

Игрок скорее всего неоднократно сталкивался с тем, что гео иногда падают на колючки, таким образом становясь недоступными, поэтому польза Загребущего Роя будет для него ясна. Однако на данном этапе придется выбирать, ведь доступно всего 3 ячейки.
А вот с Крепким Панцирем будет уже не так очевидно. Даже если его купить и немного поэксперементировать, то не будет ясно, насколько этот амулет полезен.



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

Итог


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

В следующий раз расскажу про Зеленую Тропу и Грибные Пустоши. Не забудьте написать свои мысли об этом материале в комментариях это поможет мне улучшить качество контента в будущем. Спасибо за внимание, пока./>
Подробнее..

Анализ геймдизайна Hollow Knight. Часть 2. Зелёная тропа Грибные пустоши

21.06.2020 18:22:59 | Автор: admin

deviantart.com/orioto

Предыдущая часть. Видеоверсия внизу.

Зеленая тропа


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


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

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


Рутинг (routing, маршрутизация) до следующего апгрейда менее банальный, чем в первой локации, но все еще вялый.

Your browser does not support HTML5 video.


Здесь опытные игроки могут перепрыгнуть, и получить ценную возможность исследования без карты, но данный путь менее вероятен, из-за труднодоступности. А при прохождении основного пути в самом начале сидит картограф, что явно уменьшает шанс заблудиться. Так исследование локации становится менее напряжным, но и менее наполненным эмоциями. Также до получения следующего апгрейда есть возможность посетить 2 различные локации, обе из которых закончатся тупиком, но о них позже.
Журнал охотника прибавляет мотивации убивать каждого врага на пути, не пропуская даже самых сильных, поскольку за убитых будет даваться информация. Но количество жертв, требуемое для получения крупиц лора таково, что некоторых мобов придется фармить а это представляется мне не самым интересным занятием.
Далее на пути будет пару интересных драк, NPC, и после этого значимые опции в исследовании локации заканчиваются, поскольку придется убить Босса.

Апгрейд охраняет Хорнет. У меня не сразу получилось ее победить, потому что я не сильно умелый игрок в 2d-экшн играх, но ушло на это менее 5 попыток. Однако я читал такие истории, где люди делали по 20 попыток и больше, прежде чем смогли продвинуться дальше. Но босс довольно легкий, почему так? Не смотря на индивидуальные особенности, можно найти причины таких событий в геймдизайне. Хорнет первый враг, где надо стабильно избегать урона, при этом сильно полагаясь на скорость реакции. Естественно, рано или поздно игрок начнет действовать упреждающе, выучив атаки, но до той поры ему придется полагаться на свою ограниченную проводимость нервных волокон. Давайте посмотрим, сколько видов мобов было встречено всего, а для скольких требуется проверка на реакцию.

Апгрейд охраняет Хорнет. У меня не сразу получилось ее победить, потому что я не сильно умелый игрок в 2d-экшн играх, но ушло на это менее 5 попыток. Однако я читал такие истории, где люди делали по 20 попыток и больше, прежде чем смогли продвинуться дальше. Но босс довольно легкий, почему так? Не смотря на индивидуальные особенности, можно найти причины таких событий в геймдизайне. Хорнет первый враг, где надо стабильно избегать урона, при этом сильно полагаясь на скорость реакции. Естественно, рано или поздно игрок начнет действовать упреждающе, выучив атаки, но до той поры ему придется полагаться на свою ограниченную проводимость нервных волокон. Давайте посмотрим, сколько видов мобов было встречено всего, а для скольких требуется проверка на реакцию.


При этом Чревень опциональный, Ложного Рыцаря можно скипнуть, да и тот очень медленный. Остальные редко встречающиеся рядовые мобы, из которых обязательно убивать только мшистого рыцаря (1 раз).

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

После получения Плаща ХК становится гораздо мобильнее, в драках теперь становится легче использовать тактику hit&run. Открывается доступ к Салюбре, а также следующей локации Грибным Пустошам. При встрече нового торговца игроку преподносится явный способ стать сильнее собирать амулеты, поскольку так откроется доступ к большему числу ячеек. Это тоже служит дополнительным поводом к исследованию ответвлений. Так, Салюбра и наличие карты дают высокую вероятность, что игрок будет возвращаться к неисследованным местам на карте, прежде чем двигаться в новый биом. Данное поведение к тому же прослеживается у некоторых любознательных игроков: таким сложно жить с фактом того, что у них за спиной находится закрытая дверь, к которой у них уже есть ключ. Они обязательно вернутся и посмотрят, что за ней, прежде чем идти дальше. Так что важно понимать, что некоторые сначала будут исследовать все комнаты, доступные прямо сейчас, и только потом двигаться к получению нового апгрейда.



Предложенные амулеты, бесспорно, полезны. Но за неимением достаточного числа ячеек наиболее эффективным будет Длинный Гвоздь, поскольку позволит лучше делать то, что уже и так умеет игрок, занимая лишь 2 ячейки. В этом он, кстати, схож с Ловцом Душ. Для драк с боссами можно будет надеть Быстрый Фокус. И да, Шаманский Камень один из самых сильных амулетов в игре, но на данном этапе он малоэффективен для неопытного игрока.

С плащом на Зеленой Тропе можно будет подобрать парочку амулетов, подраться с опциональным мини-боссом, и дальше останется только направиться к Грибным Пустошам.

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

Понимая это, разберем доступные опции к перемещению. Мы-то с вами знаем, что следующей крупной локацией будут Грибные Пустоши. Однако к ним сейчас есть два прохода: через Забытое Перепутье и Туманный Каньон. А последний является отдельной локацией, пусть сейчас из нее и доступно всего пару комнат. Поэтому игрок засомневается, стоит ли отправляться вглубь. И то же самое справедливо при переходе к Грибным Пустошам с Забытого Перепутья. Так какой вариант более вероятно выберет игрок? Я считаю, что через Туманный Каньон. Во-первых, потому что этот переход доступен до получения апгрейда. Во-вторых, локация отличается тематически, и игрок найдет ее позже, чем переход со стороны Перепутья а значит и запомнит лучше. Также имеет смысл отметить, что пройдя одинаковое расстояние как по одному, так и по-другому проходу, в случае с Туманным Каньоном игрок доберется до Вокзала, а оттуда уже более вероятно пойдет в следующую локацию.
По пути через этот проход игрок встретится с напевающим вдалеке Корнифером, а также банком, где надежно будут храниться гео, пока счет не превысит 2550 единиц, но об этом позже.

Грибные пустоши


Как и предыдущая локация, Грибные Пустоши отличаются тематически и геймплейно. Здесь акцент будет на платформинге, который усложнится как в боевых ситуациях, так и при обычном исследовании. Это первая локация, которую невозможно пройти без применения пого, так что к ее концу можно быть уверенным, что игрок понял этот аспект. Но это совершенно не гарантирует, что такой вид атак будет применяться в бою.
При входе со стороны Вокзала Королевы, сразу же можно найти картографа, что для третей локации слегка удручает. Очень сложно постоянно не подглядывать в карту, когда она есть. А так теряется весомая часть погружения, поскольку нет необходимости рисовать местность в голове, тем самым лучше ощущая масштаб мира.
Бой незначительно усложняется. У местных рядовых мобов теперь в среднем больше здоровья, и по 2 атаки, из-за чего придется сильнее полагаться на реакцию, а также лучше маневрировать, чему способствует новоприобретенный плащ.

Your browser does not support HTML5 video.
После исследования деревни богомолов откроется новый апгрейд, и вот тут в игре происходит существенное увеличение вариативности в последующем изучении локаций. Mark Brown

Об этом давайте в порядке вероятности их посещения.



1)Город слез. Скорее всего большая часть игроков сперва посетит именно его. Происходит это так: вы пытаетесь победить Лордов Богомолов, у вас не получается. Вы возвращаетесь за своей тенью, по пути встречаете Квирелла. Он дает явный комментарий о текущей неготовности к этому бою, и предлагает посетить Город, найти кузнеца и улучшить свой гвоздь. Также именно в этом направлении отправилась Хорнет, так что Город самая яркая точка интереса.

2) Глубокое гнездо. Как я говорил, есть существенная тенденция к изучению всех доступных опций в локации, прежде чем идти в следующую. Таким образом игрок найдет разрушаемую стену, и рухнет в Глубокое гнездо. Также в него попадут игроки, что одержали победу над Богомолами ( которые, к слову, являются одним из лучших боссов). Здесь важно, что в отличии от Города, из гнезда можно выбраться. А учитывая некомфортную обстановку и жирных мобов, некоторые игроки решат сперва посетить Город, чтобы улучшить оружие.

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

4) Кристальный каньон. Эта локация вряд ли будет посещена первой, поскольку игрок скорее потратит гео на апгрейды, чем на фонарь.

5) Вторая половина Города Слёз. Самый маловероятный вариант, потому что придется провернуть вот такой трюк.

Your browser does not support HTML5 video.

Да, подразумевается, что игрок при этом пройдет через Земли упокоения, но о них в другой раз

В плане исследования порядок немного поменяется:

1) Город. Потому что закрытые ворота искусственно ограничат посещение других локаций.

2) Воющие утесы. Потому что локация простая, а также не требует дополнительных поисков и ресурсов.

3) Гнездо. Потому что из него можно выбраться, а локация сложная по мобам и труднопроходимая без фонаря.

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

5) Вторая половина Города Слёз. Поскольку вход неочевиден, а враги слишком жирные для первого гвоздя.

Итог


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



Пишите, как вам сегодняшняя часть. Спасибо за внимание.

P.S.



Видеоверсия: 1, 2
Подробнее..

Перевод Видеоигры это будущее образования (размышления программиста из Palantir)

28.06.2020 02:16:08 | Автор: admin
Подписывайтесь на канал @META ОБУЧЕНИЕ, где я делюсь своими самыми полезными находками про образование и роль ИТ/игр в образовании (а так же мыслями на эту тему Антона Макаренко, Сеймура Пейперта, Пола Грэма, Джозефа Ликлайдера, Алана Кея)

В подростковом возрасте моё реальное образование складывалось из:

  1. книг, которые я сам выбирал
  2. обучения программированию (самостоятельного)
  3. видеоигр (которые находил сам)
  4. математики (из школьной программы)

Пункты 1-3 не связаны с формальным школьным образованием и сформировались даже скорее вопреки ему. О нечто подобном писал Пол Грэм:



Прежде чем играть в игры или смотреть видео про покемонов, вы должны выучить наизусть имена и характеристики первых 100 покемонов. Ритуально повторяя их в алфавитном порядке. Хочется вам того или нет. Вот что обычно понимает система образования под математическими способностями.

Симуляторы (такие как игра Pokemon) дают более быстрое и глубокое понимание, понимание до мозга костей.

Поэтому я считаю, что:

4. Видеоигры станут ключевым компонентом образования.



Звучит абсурдно, но если задуматься, симуляция уже широко используется для обучения:

  • Компьютерная игра Kerbal Space Program знаменита тем, что делает своих игроков экспертами в астродинамике.
  • Авиасимуляторы и симуляторы боевых действий готовят пилотов и военнослужащих.
  • Игра Factorio обучает вас законам капитализма, производства и экономики.
  • Среды программирования это симуляции вселенной языка программирования с быстрой обратной связью (написать код -> отладить код).


image

Видеоигра это просто:

(а) симуляция реальности
(б) с быстрой обратной связью.

Обучение это просто акт взаимодействия с внешним объектом с привлечением критического мышления и многократных догадок, с формированием выводов и построения на их основе совокупности знаний.

Поэтому вполне оправдано, чтобы видеоигры в будущем станут основной образовательной средой: это лучший способ на сегодняшний день, чтобы (а) создавать симуляции реальности (б) быстро получать обратную связь и (в) делать все это по доступным ценам.

(Кстати, это работает не только для абстрактных концепций, таких как астродинамика, но и для этических норм. К примеру, мое понимание героизма по сей день сформировано играми Final Fantasy и Metal Gear Solid. Также можно объяснить и ценность художественной литературы: можно получить телесные знания об отчаянии, прочитав Достоевского, и о ревности, прочитав В сторону Свана и др.)

5. Единственное в чем проигрывают игры, так это в переходе на реальный мир. Навыки, которые вы изучаете в конкретной игре очень специфичны. Но все изменится.



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

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

Но если у вас есть игры, которые (а) увлекательны и (б) точно передают некоторые аспекты реальности, как, например, игры KSP или Factorio, вы получаете реальное знание, которое можно переложить на реальный мир. Задача состоит в создании игр, удовлетворяющих оба аспекта.

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

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



Одно высказывание об интернете особенно хорошо мне запомнилось. Оно принадлежит Эвану Уильямсу, основателю Twitter/Blogger/Medium. Он как-то сказал, что лучший способ создать гигантскую интернет-компанию это взять то, что люди хотят сделать, и сделать это в 10 раз проще.

Эта идея легла в основу всех его компаний. Люди хотят проявить творческий подход, хотят создавать музыку, разрабатывать видеоигры, хотят писать (понятно!) и постить идеи онлайн, но барьеры на пути к этому пока еще слишком высоки.

Нам кажется, что интернет позволяет делать что-то новое", говорит Уильямс. Но люди просто хотят делать то же, что и всегда.

(...)

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


Упростить создание вещей это мегатренд эпохи интернета:

  • Blogger/Medium/Wordpress (и Хабр) позволяют легко писать в интернете;
  • Subpack позволяет легко настраивать информационные рассылки
  • YouTube и TikTok позволяют легко создавать видео;
  • Ableton позволяет легко делать музыку и т. д.


Другой момент связан с тем, что упрощение имеет нелинейный эффект. Упрощение чего-либо в 10 раз приводит к тому, что что-то появляется в 1000-кратном количестве. Отсюда и взрыв онлайн-творчества на YouTube: множество видео по шахматам, Minecraft, математике, Академии Хана, стримы на Twitch, Soundcloud и др.; вы убираете некоторые сложности и получаете грандиозный результат.

Однако эту тенденцию ждет долгий путь развития. Создание видеоигр требует колоссальных усилий и высоких затрат; вам нужно быть либо сумасшедшим гением, разработчиком инди-игр со сверхвысокой толерантностью к риску, либо мега-корпорацией, как Unity, Steam или Valve. Видеоигры еще не пережили революцию создателей.

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

Несколько важных замечаний:

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

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

И последнее: именно поэтому ИИ имеет важное значение для производительности человека. В основном речь идет о том, как ИИ заменит людей. Я придерживаюсь позиции Ликлайдера: симбиоз человека и компьютера. ИИ сделает людей более эффективными, автоматизируя утомительные задачи. Например, люди могут использовать текстовый ИИ, такой как GPT-3, чтобы генерировать идеи/шаблонное письмо, чтобы избежать страха перед пустой страницей, а затем выбирать лучшие примеры и их дорабатывать/итерировать. (AI Dril, который был создан на основе GPT-2, как раз был таким ранним примером). По мере того как искусственный интеллект будет совершенствоваться, вспомогательное творчество станет все более употребимым явлением, позволяющим людям создавать сложные артефакты (в том числе видеоигры!) как никогда проще и лучше.

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

Спасибо Саку П за то, что он прочитал мой черновик.

Обновление: интересные обсуждения на Hacker News.



Подписывайтесь на канал @META ОБУЧЕНИЕ, где я делюсь своими самыми полезными находками про образование и роль ИТ/игр в образовании (а так же мыслями на эту тему Антона Макаренко, Сеймура Пейперта, Пола Грэма, Джозефа Ликлайдера, Алана Кея)

image

Узнайте подробности, как получить востребованную профессию с нуля или Level Up по навыкам и зарплате, пройдя платные онлайн-курсы SkillFactory:



Читать еще


Подробнее..

Как опубликовать VR-игру в Oculus без нервного срыва

06.07.2020 16:22:04 | Автор: admin

Как опубликовать VR-игру в Oculus без нервного срыва


Мы продолжаем делиться нашим первым опытом разработки VR-игры Astro Collapse. В предыдущих статьях я рассказал об основной идее игры и геймдизайне.

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

Технические рекомендации к VR-играм и основные показатели производительности


Когда вы сделаете готовый билд, зарегистрируйтесь в Oculus и загрузите игру в личный кабинет. Через несколько дней вам на почту придёт уведомление. Это будет либо поздравление с успешным прохождением теста, либо просьба исправить ошибки.

В первый раз мы не учли всех рекомендаций с сайта Oculus, поэтому получили вот такой результат:
image
Подробный отчёт после первой проверки Oculus

Мы провалили тест на производительность, у нас была проблема с требуемым возвратом в меню Oculus Home и игра не устанавливалась на старшие версии Android.

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

  • FPS в игре должен быть не меньше 60;
  • от 50 до 100 вызовов отрисовки на кадр (Call Draw);
  • 1-3 миллисекунды на выполнение скриптов;
  • от 50 000 до 100 000 полигонов на кадр.

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

FPS или количество кадров в секунду


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


Показатель Draw Call


Draw Call количество вызовов текстур, которые игровой движок отправляет графическому процессору для отрисовки мира. Чтобы сократить число вызовов, движку необходимо объединить текстуры в один материал. Этот приём называется батчинг (batching).
Чем выше показатель Draw Call, тем больше времени уходит на прорисовку игрового мира.

Скрипты и скорость их выполнения


Скрипты отвечают за любые действия и операции в игре. Чтобы их выполнять, нужны обработчики. Например, Update. Он должен обрабатывать каждый кадр. Если в игре много объектов и сложных действий над ними, то этот обработчик не успевает завершать кадр. Поэтому производительность низкая, а игра виснет.
Много длительных операций в Update усложняют выполнение действий над объектами.

Полигоны на кадр


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

Как мы решили проблемы с производительностью


У нас были 4 основные проблемы, из-за которых производительность в игре не дотягивала до рекомендуемых значений. Мы сделали слишком детализированные трёхмерные объекты, столкнулись с высоким показателем Draw Call, скрипты тормозили, а память устройства была перегружена. На поиск решений этих недочётов мы потратили больше всего времени. А теперь обо всём по порядку.

Упрощаем трёхмерные объекты и понижаем полигоны на кадр


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

image
Полигоны шаттла из игры Astro Collapse

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

Объединяем текстуры в атласы и добиваемся рекомендуемого показателя Draw Call


В Astro Collapse игровой мир создан из астероидов, шаттлов, боевых кораблей, Земли и Солнца. Объектов в игре много показатель Draw Call был высоким, поэтому движок тормозил прорисовку графики. Чтобы его снизить, нужно объединить разные текстуры объектов в один атлас.
image
Атлас астероидов в игре Astro Collapse

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

Сокращаем время выполнения скриптов


Любое действие в игре происходит с помощью скриптов. В Astro Collapse множество игровых объектов и сложных операций над ними, поэтому часть скриптов выполнялась долго обработчик Update задерживал завершение кадра. Это тормозило игровые процессы.

Поэтому нам нужно было вынести сложные операции из покадрового обновления. Мы использовали обработчик корутин (co-routine), который умеет выполнять такие операции над объектами вне кадра.

Так нам удалось оптимизировать сложные операции работы с астероидами. В Astro Collapse таких объектов много: каждый астероид нужно проверять на активность, следить за его местоположением в космосе и вносить его в список. Сам список нужно обновлять, чтобы выводить в игру новые астероиды, рассчитывать их расстояние до игрока, шаттлов и соседних боевых кораблей. В итоге получается долго выполняемый цикл для кадра, с которым обработчик Update не справлялся. А при помощи корутина движок вынес эту сложную операцию из покадрового обновления и повысил производительность.
Обработчик co-routine выполняет сложные операции вне покадрового обновления, чем упрощает работу игровому движку.

Защищаем память устройства от мусора и делаем пул астероидов


В Astro Collapse очень много астероидов. Они постоянно появляются, их нужно уничтожать. Стандартные конструкторы в скрипте Instantiate и Destroy не справляются, выполняя эти операции. Они создают мусор в памяти устройства, из-за чего игра виснет. Поэтому мы сделали по-другому.

Сбитые астероиды не уничтожаются, а скрываются в игровом пространстве. Когда требуется новый объект, скрипт вызывает его из спрятанных. Этот метод называется пулом.

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

Небольшие недочёты после технической проверки


Постобработка моделей в игре: отключаем антиалиасинг


Антиалиасинг постобработка изображения сглаживанием зазубренных краев. В Astro Collapse антиалиасинг был установлен по умолчанию. Он перегружал игру, а заметного сглаживания в игре всё равно не было разрешение в шлеме Gear VR невысокое. Поэтому мы его отключили. Игроки при тестировании не заметили изменений, но производительность стала выше.
Антиалиасинг не даёт сглаженной картинки при низком разрешении Gear VR.

Зрелищные взрывы из спрайтов


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

Подбитый астероид в игре Astro Collapse

Зрелищные взрывы можно сделать с помощью спрайтов.

Тени не нужны


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

Проблема с требуемым возвратом в меню Oculus Home


Кнопка возврата на шлеме должна возвращать игрока в Oculus Home, а не в меню игры, как было в Astro Collapse. Чтобы исправить этот недочёт, я взял готовый скрипт плагина Oculus и применил его в игре.
Используйте скрипт OVRPlatformMenu.cs, чтобы кнопка возврата меню работала правильно.

Устранение недочёта с установкой игры на старшие версии Android



Недочёт с установкой решить легко. Нужно указать в настройке проекта старшую поддерживаемую версию Android.
Не забудьте в настройках игры указать минимальный требуемый уровень API Android 4.1.

Результаты после публикации игры


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

Через 2 недели после публикации Astro Collapse скачали более 7000 раз. Для VR-игр на платформе Gear VR это отличный результат: она вошла в топ-50 бесплатных игр и заняла 24 позицию в списке.

Советы для публикации игры в Oculus


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


Наши советы помогут пройти проверку в Oculus быстрее.

Сыграйте в игру Astro Collapse и оцените графику. Для этого вам понадобятся очки Samsung Gear VR. Они работают со смартфонами: Samsung Galaxy Note 4, 5, 7, S6/S6 Edge/S6 Edge+, S7/S7 Edge, S8/S8+.

Успешных разработок!
Подробнее..

Категории

Последние комментарии

© 2006-2020, personeltest.ru