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

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

Быстрое разворачивание Minecraft-сервера

24.11.2020 18:14:36 | Автор: admin


Играя в Minecraft в одиночку, всегда настаёт тот момент, когда хочется добавить к себе друзей в свой мир. Построить с ними вместе различные строения, отправиться в путешествие, вместе убить дракона или открыть новые миры. И тогда встаёт логичный вопрос: как создать свой сервер? До сего момента для игрищ использовал только сервера linux. А тут решил попробовать готовый сервер из Маркетплейса на Windows без графического интерфейса (чистый PowerShell). Мне кажется были собраны все грабли, которые только можно, но из битвы с Windows Server я вышел победителем.

Разворачиваем сервер


У меня есть некоторый опыт создания серверов Minecraft под linux, да и вообще администрирования linux, но совершенно не представлял как же быть с Windows. Возможно даже расскажу некоторые капитанские вещи, но для меня они были открытием. Самое большое откровение для меня был PowerShell. Даже не могу передать всех эмоций, использования Windows в консольном режиме. Microsoft сделало максимально неудобным всё. Почему нельзя было взять лучшее у *nix систем, внедрить у себя и улучшить? Почему нельзя сделать поддержку ssh, posix-совместимую систему команд, для чего этот велосипед?
Но спустя некоторое время даже начал получать некоторое удовольствие от интерфейса, и видеть даже какую-то логику. В общем, перейти с Windows на linux было сильно проще, чем сделать это обратно.
Итак, сервер я создавал в нашем :



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



Моя практика создания серверов показала, что для Minecraft-сервера необходимо не менее двух ядер, лучше больше 4-х ГБ ОЗУ. В целом, всё может работать на одном ядре, даже с 2 ГБ ОЗУ, но при большом количестве объектов, могут быть тормоза и пропуски хода.
Лично я такое наблюдал на куриной ферме, когда количество куриц у меня было более нескольких сотен. Тогда сервер реально начинал тормозить.


Корпус для аккумулятора

После создания сервера, спустя несколько минут у нас будет IP-адресс сервера, его логин и пароль.



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

Подключение к удалённому серверу из Windows


В Windows всё просто. Жмём Пуск->Выполнить и вводим mstsc. Вводим параметры нашего сервера.



Если мы хотим копировать данные на сервер и с сервера (а я хочу), то идём во вкладку Локальные ресурсы, и там нажимаем клавишу Подробнее.



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



После этого мы можем подключиться к нашему серверу и увидим одно единственное окно PowerShell.



Содержимое диска C: нашего компьютера будет доступно в сетевой папке:

\\TSCLIENT\c



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

Подключение к удалённому серверу из Linux


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

sudo apt-get updatesudo apt-get install libfreerdp-plugins-standard remmina remmina-plugin-rdp

После установки запускаем remmina, и конфигурируем подключение к удалённому серверу.



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

\\TSCLIENT\rdpfiles



Стартуем ванильный сервер


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

Approve-MinecraftEULA



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

Start-Minecraft

И всё, ваш сервер готов к работе, он создаёт новый мир и идёт загрузка, но дьявол кроется в мелочах. Сам сервер очень старый, версии 1.15.2 (тогда как на момент написания этой статьи была версия Minecraft 1.16.4).



Но, продемонстрирую, что сервер в действительности работает. Надо только в лаунчере поставить запуск старой версии (1.15.2), и указать при сетевом подключении IP-адресс нашего сервера.


Подключение успешно состоялось.

Как же обновить сервер, спросите вы? Оказывается очень просто. Последняя версия сервера у. Там нужно будет скопировать ссылку на данный файл.
Все файлы этого Minecraft-сервера (кроме стартовых скриптов) обитают в папке C:\Minecraft\ . Поэтому переходим в неё, и все процедуры делаем в ней.

cd C:\Minecraft\#удаляем старый серверrm C:\Minecraft\server.jar

Для того, чтобы скачать файл, в PowerShell есть аналог wget.

Invoke-WebRequest -Uri "http://www.contoso.com" -OutFile "C:\path\file"

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

Invoke-WebRequest -Uri "https://launcher.mojang.com/v1/objects/35139deedbd5182953cf1caa23835da59ca3d7cd/server.jar" -OutFile "./server.jar"

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

Start-Minecraft

И видим, что у нас обновлённая версия сервера вполне себе работает.



Устанавливаем моды


Эта часть попила у меня чудовищное количество крови, и я с ней очень долго бодался, пытаясь понять что же не так. Для того, чтобы работали моды, необходимо установить дополнение Forge. Не смотря на то, что скрипт запуска Forge есть на данном сервере, сам Forge не установлен! И это главная беда.
Обращаю ваше внимание, что для каждого мода требуется своя версия Forge! Поэтому ищите детальное описание на вашу модификацию, и подбирайте совместимость версии Forge и версии мода. Поскольку у меня не хватило терпения на этот квест подбора соответствующих модулей, то рассказываю основной принцип. Нет, forge с модулями завёлся, но не совсем так как от него ожидалось.
Нам необходимо скачать (выбирайте подходящую версию под ваш мод). Для этого создадим временую папку C:\tmp:

mkdir c:\tmp cd c:\tmp#скачиваем forgeInvoke-WebRequest -Uri "https://files.minecraftforge.net/maven/net/minecraftforge/forge/1.16.3-34.1.0/forge-1.16.3-34.1.0-launcher.jar" -OutFile "forge-1.16.3-34.1.0-launcher.jar"#запускаем инсталятор.\forge-installer.jar


Выбираем Install server и выбираем папку куда ставить (C:\Minecraft) жмём ОК. И дожидаемся загрузки.



После окончания установки, будет выведено такое окно.



Успешность установки, можно проверить командой.

Start-Minecraft -Type Forge -LogFile "C:\Minecraft\stdout.txt" -MinecraftPath "C:\Minecraft"


Если всё запускается без ошибок, всё, ваш сервер готов к запуску модов. Дальше вы можете моды скопировать в вашу сетевую папку, в моём случае rdpfiles и затем скопировать все моды в папку C:\Minecraft\mods\ (предварительно её создав).

mkdir C:\Minecraft\mods\cd \\TSCLIENT\rdpfilescp *.jar C:\Minecraft\mods\

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

rm C:\Minecraft\world\ 

Соглашаемся со всем, нажимая букву А на латинской клавиатуре. Всё, можем стартовать новый мир с модами.

Start-Minecraft -Type Forge -LogFile "C:\Minecraft\stdout.txt" -MinecraftPath "C:\Minecraft"

Удалять моды можно точно так же удаляя файлы в папке C:\Minecraft\mods\.

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


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

whitelist on



Можно даже попробовать зайти на сервер и убедиться, что никто теперь на него не зайдёт.



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

whitelist add dlinyj 



Всё, теперь я могу заходить на данный сервер.

Для того, чтобы конфигурировать сервер, нужно править файл server.properties. Завершить работу сервера можно комбинацией ctrl-c. Далее можно открыть этот файл обычным блокнотом.

.\notepad.exe C:\Minecraft\server.properties



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

Выводы


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

Restart-Computer 

Если случайно закрыть окно PowerShell, то запустить его можно комбинацией Ctrl-Shift-Esc. Затем там выполнить PowerShell.





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



Подробнее..

Из песочницы Ретроспектива разработки интерфейса листа персонажа

22.11.2020 14:12:21 | Автор: admin


Близится 2021 год, а значит, минуло почти 4 года с момента, когда я присоединился к разработке Pathfinder:Kingmaker в качестве разработчика интерфейсов. За это время игра превратилась из маленького прототипа с минимальным функционалом в огромную, сложную систему. Игра пережила релиз, год активного багофикса и поддержки DLC, а также портирование на консоль. И теперь, когда разработку этого проекта можно считать завершенной, пришло время оглянуться и попробовать собрать ретроспективу того, как проектировались и создавались интерфейсы.


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

Введение


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



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


Взято отсюда: http://runelords.peepersbog.org/index.html

В отличии от своих, более опытных в играх и разработке коллег, весь мой опыт настольно-ролевых игр сводился к играм в юности по обрывкам правил DnD и прохождения Baldurs Gate в момент, когда я даже не понимал, что она сделана по настольной игре. И, конечно, такой опыт является огромным минусом, когда нужно перенести настольную игру в компьютерную. Однако, сейчас я понимаю, что в тот момент недостаток обратился в достоинство, потому что это дало возможность взглянуть на интерфейс с точки зрения человека, ничего не знающего об игре. По сути задачей стало объясни самому себе, как это устроено, что, конечно, намного проще. Ведь никто так не сможет рассказать, как пользоваться чем-то, кроме как человек, только что этому научившийся. В момент, когда была поставлена задача на дизайн листа персонажа в игре, всё казалось очень просто: перенеси его в цифровой вид, убери лишнее и готово! И, конечно же, это оказалось не так. Чем глубже я погружался в устройство правил настольной игры, тем более ясным становилось, что Pathfinder это игра не по правилам, а по исключениям из правил.

Информационное проектирование


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

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

Переосмысление существующего, бумажного, в совокупности с новым, компьютерным, привело к идее разбиения экрана на три столбца. Хотя, правильней сказать, к идее протягивания уже существующей компоновки инвентаря. Левая треть экрана должна была стать сквозным информационным ядром интерфейсов персонажа и вобрать в себя основные характеристики. А ключевой частью этого блока должен был стать портрет. В отличии от других современных RPG, где основным представлением персонажа является 3D-кукла, у нас для роли отождествления игрока, как героя игры, был рисованный портрет. На это был сделан упор по нескольким причинам: 1. Это жанровое, духовное наследие Baldur's Gate. 2. Портретом можно выразить более сложные эмоции и лучше охарактеризовать героя, сделав игровой опыт глубже. Другие составляющие блока должны были отвечать на вопросы кто? и какой?: Хаотично-добрый полуорк, варвар, сильный и красивый, но глупый, бьёт молотом так-то, защита такая-то. Остальные две трети должны были раскрывать подробности о способностях и навыках и истории. Как результат информационного проектирования, все возможные блоки персонажа были сгруппированы и распределены по столбцам и страницам. Таким образом появилось логическое разбиение.







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

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

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

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

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



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

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

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

Поиск разметки


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

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

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






В макетах использованы портреты из Baldurs Gate.

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

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







Здесь были эксперименты с группировкой способностей. Нужно было отделить способности, именуемые Feat, которые персонаж выбирает вне зависимости от класса от Special Abilities, которые уникальны для каждого класса. Плюс еще существовали Traits, сюжетное происхождение персонажа, которое за столом игрок выбирает для более интересного отыгрыша роли, но в нашем случае просто еще один способ повлиять на значения характеристик. А еще мы хотели показывать многие характеристики, которые, однако, были не всегда полезны применительно к отдельно взятому классу персонажа. Например, для мага не очень важно, насколько велик его Base Attack Bonus, он им не пользуется, когда бросает огненные шары. Но всё же некоторые блоки уже стали искать свою около-финальную компоновку с проверкой контента.




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

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

Финализация дизайна






В макетах использованы иконки из League of Legends.

Обсуждения у нас это всегда долгий процесс, отягощённый многочисленным столкновением мнений и интересов. Я не помню ни одного собрания, которое длилось бы менее 3-х часов. Одни полагают, что важнее предоставлять максимум механической информации, другие что важнее погружение в историю и атмосферу, а механические детали можно спрятать поглубже. Чаще всего такие дискуссии единственный эффективный способ выйти из тупика и, в результате обмена мнениями, прийти на следующую итерацию с новыми идеями. Страницы биографии персонажа и древо развития класса в целом были утверждены всеми участниками. А вот с главной страницы было решено убрать информацию о способностях, таблицу заклинаний и прочие числовые характеристики персонажей. Центром интерфейса решили сделать сюжетную составляющую игры. Для основного героя это стало Колесо мировоззрения, а для компаньонов мы придумали набор сюжетных карточек, ключевых событий этого персонажа, которые будут открываться игроку по мере прохождения. Баффы в этом случае также убирались из левой трети, но получали достаточно пространства, чтобы отображаться вместе с названием и параметром времени действия. Таким образом экран стал значительно чище, а также сместил фокус на то, что это в первую очередь ролевая игра, а уже потом механическая.




Способности переместились на отдельную страницу. Это позволило использовать не одни только иконки, но и названия самих способностей. Впоследствии это оказалось очень важно, потому что для отрисовки иконок под каждую способность нам в итоге не хватило времени и ресурсов. Кроме того, закодировать смысл каждой способности в иконку, а уж тем более расшифровывать её потом игроку, это слишком сложная задача. Но, опять же, ретроспективно должен отметить, что сильно недооценил количество способностей в блоке Special Abilities и переоценил их количество в блоке Traits. В итоге это вылилось в весьма несбалансированную компоновку этого экрана. Что мы, к счастью, имеем возможность исправить в будущей игре Pathfinder:Wrath of The Righteous.



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



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






Артовое оформление


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







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

Портирование на консоль


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

Консольный интерфейс в отличии от ПК имеет ряд особенностей:

  1. 1. Их смотрят на телевизоре, сидя на диване. Это повлекло за собой увеличения кегля текста во всей игре.
  2. 2. По TRC необходимо иметь 5% save-зону, в которой не должен располагаться важный контент.
  3. 3. Курсор это сложное решение для консоли. Поэтому у нас больше нет тултипа, в который можно поместить описание параметров и способностей.

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





Однако, при этом возникали неразрешённые проблемы. Непонятен принцип, что и когда разрешать выделять. К примеру, если я разрешаю выделять Ability Scores на главном экране, то должен ли я разрешать выделять их же на странице Progression?

Где выводить описание выделенного элемента? Как прокручивать это описание не переходя на новый уровень вложенности? Появляются не интуитивные случаи управления. Например, если игрок выделяет левым стиком крайний правый элемент, то описание выводится слева, а прокручивается правым стиком.

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

Так что после попыток отнаследоваться от ПК-версии в качестве базового шаблона fullscreen-интерфейсов была предложена следующая структура:



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

В правой части мы расположили контекстное описание выделенной сущности, т.е., фактически, перенесли туда тултип, который в ПК-версии появлялся при наведении курсора. Для прокрутки информации тут стал использоваться правый стик контроллера.

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

Под перемещение между экранами листа персонажа мы определили бамперы R1-L1.
Переключение между персонажами осуществляется с помощью радиального меню группы при нажатии правого курка R2.

В результате у нас получилось разбиение интерфейса на 7 экранов.







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







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

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

Заключение


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

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

Спасибо людям, принимавшим участие в работе над листом персонажа:
Михаил Ротфорт Lead UI
Василий Левинов UI Artist
Василий Болдырев Programmer
Никита Великовский Programmer
Максим Савенков Programmer
Оксана Мергер UI Programmer
Алексей Гусев QA Engineer
Александр Мишулин Creative Director
Виктор Сурков Art Director
Олег Шпильчевский Head of Owlcat Games

Автор: Павел Турчин UI Developer
Подробнее..

MMORPG больше не в Telegram Swift и Kotlin Первый большой проект Часть 1

24.11.2020 16:19:42 | Автор: admin

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

Почему больше не в Telegram

После выпуска первой статьи, энтузиазма писать игру хватило еще на неделю. Прилетели проблемы по работе, поиски новой, да и вообще лето. Проект был отброшен на задний план. В процессе поиска будущего работодателя возникла мысль попробовать себя в разработчиках. Спустя несколько часов диалогов с разными ребятами из IT, выбор пал на iOS-разработку. Благо, на Udemy курсы уже куплены, поэтому из летнего режима переходим в режим разработчика на 1.5[OT1] недели.

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

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

EventSurf - найди как провести времяEventSurf - найди как провести время

Чем же теперь заниматься? Ведь амбиции трушного разраба никуда не делись. Точно! Есть же детская мечта - написать "свою MMORPG". Да и какой-никакой код на питоне остался.

Стоп? А зачем писать в игру в телеграме? Я зря что ли курсы проходил по iOS? И тут аргументы начали приходить один за другим

  • Ограничение функционалом чатов

  • Прототип у меня неплохо получилось нарисовать (по своему собственному мнению). Значит, и игру смогу

  • MMORPG - это про айдентику игрока среди других. А это труднодостежимо с телегой

  • Визуал воспринимается проще, чем эконки emoji и одноцветный текст

Решено. Делаем iOS

Дизайн

Заходим в Figma. Новый файл. Стоп. Нужна также и айдентика игры.

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

Что следующим этапом? Верно, стартовый экран. На нем должен быть лого и должна быть картинка. Название игры пока не придумано. Берем за пример TBMMORPG (Text based MMORPG). Как сделать красиво? Создаем 2 одинаковых текста, темный подкладываем под светлым, у темного увеличиваем letter spacing.

Теперь нужна картинка. Открываем Aseprite (редактор пиксельных изображений). Час тыкаем кисточкой в пиксели. Закрываем Aseprite. Идем на сайт по продаже спрайтов. Сутки поиска подходящих сетов и 50$, и более 1800 айтемов и персонажей у нас в папке проекта. Выбираем яркого персонажа и загадочного персонажа, ставим в конфронтацию, кладем в лапу оружие, охапка дров и плов готов!

Готово окно входа. Теперь нужен и сам экран с логами.

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

Основные механики игры

Notion: выписываем все, что хотим реализовывать в первых версиях игры:

  • Классы: на начальном этапе будут Воин, Лучник, Убийца, Маг

  • Характеристики персонажей: скорость атаки, уклонение, крит

  • Автофарм - даже вне сети.

  • Player vs Mob - автоматический фарм. Выбираются типы мобов доступные в локации, сколько максимум мобов в локации, их HP и атака. Раз в пять секунд персонаж и моб обмениваются ударами. Atack speed накапливается и при скорости атаки 50%, каждый второй обмен ударами, игрок наносит два удара. Мобы бывают с одной звездой, с двумя и с тремя. Самый сложный - с тремя, но с него гораздо вкуснее лут. Но и его появления меньше. В локациях для более высоких уровней могут быть агрессивные мобы. То есть, независимо от того, каких мобов для сражения вы выбрали, агрессивный моб может напасть на вас, даже в момент, когда вы бьете другого моба. Тогда урон будет проходить по игроку от двух мобов.

  • Player vs Player - игрок может выбрать другого игрока в локации и нанести ему урон. Игрок, нанесший урон, приобретает статус PVP и для всех в локации отображается другим цветом. Если на такого игрока нападут, то выигравший получит плюс к счетчику убийств PVP. Если игрок наносит урон игроку, который не находится в статусе PVP и убивает его, игрок переходит в статус PK (Player killer). Если такого игрока убить, с высоким шансом из его инвентаря выпадет при смерти лут, который не привязан к игроку, и его смогут подобрать другие игроки.

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

  • Крафт - доступен крафт, из собираемых ресурсов, из лута падающего с мобов, из лута падающего с боссов в данжах, из лута падающего при разборе предметов.

  • Группа - на фарме, в PvP, в GvG, в данжи и на боссах можно сражаться в группе. Эффект группы дает бонусы к характеристикам персонажей.

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

  • Заточка: максимальная заточка оружия +12, максимальная заточка вещей и бижутерии +10. Безопасная точка +3. Неудачная точка свыше +3 - сбрасывает заточку до +0. Есть усовершенствованные свитки, которые сбрасывают точку при неудачной только на -1.

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

  • Арена - каждый день проводится арена в формате группового этапа. Победителям распределяются очки. Каждую неделю, персонажи набравшие большее количество очков участвуют в финалe, который проводится в режиме сетки. В воскресенье определяются победители, которые получают ништяки и возможность участвовать в Арене Героев, которая проводится раз в месяц в формате турнирной сетки. Ее победители получают уникальные шмотки/оружие, которые имеют преимущество в PvP по сравнению с другими носимыми предметами в игре, а также статус Героя, который выделяет персонажа в списке всех персонажей

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

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

  • Чаты с игроками, чаты с гильдией, аукцион, и другие моменты, которые еще не до конца продуманы.


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

Начинаем прогать все заново

Дизайн - есть, механики - есть. Нужен код.

Открываем Питонячий файл, написанный для телеги. Находим в нем WebHooks. Это нам вряд ли подходит - выбрасываем питонячий файл. Открываем PyCharm. Стоп! А как сервер писать для MMORPG?

Пару дней гуглим, находим не так много информации. Походу, MMORPG не написать копипастом из StackOverflow.

Обычные запросы нам не то, чтобы подходят. На сей раз нам помогает Reddit, где сообщают, что WebSockets отличное решение для мультиплеерных игр. Несмотря на то, что боёвка планируется по шагам (обмен ударами раз в N секунд), то PVP, GVG и другие механики требуют постоянного соединения. Поэтому выбираем Websockets и одноименный пакет для Python.

Теперь нужно получить connection к веб-сокету с клиента. Накидываем пару текстовых полей в интерфейсе. Добавляем либу. Конектим. Фейл. Еще раз - фейл. Вообще не стучится. Пробуем через браузер - стучится. Хрень какая-то. Поменяли настройки. Конектим - не стучится. Окей. Теперь время посмотреть в доку. This library for sockets connection. If you need websocket protocol you should use this library: Starscream.

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

Конектится. Погнали дальше, подключаем ORM SQLAlchemy. Как же это элементарно работает! Реализуем таблицы, классы, регистрацию, вход. Все работает как по маслу.

Ну и настало время придумать название для игры. Что ассоциируется у меня с классическими MMORPG? Perfect World, Lineage, World of warcraf. В двух из трех есть слово World. Окей, заимствуем. В чем концепт игры? В логах! Logger World

Начинаем прогать все заново

Что-то ноут тормозит и работать становится тяжеловато. Копируем папку Developer в Yandex Disk, ребутаем устройство. Reinstall OS.

Открываем Xcode, открываем Pycharm. Открываем прое.. А вы знали, что неделя работы и 95% написанного кода Pycharm сохраняет не в Developer, а в свою директорию. Ну вот! А я не знал. И не посмотрел.

Окей. Повторенье - мать ученья. Только в этот раз - не на питоне. Что у нас есть из интересного? Swift на back! Но я не IBM - мне страшно. Java, NodeJS, C#

А что там с Kotlin? Вроде как он мультиплатформенный. Запускается там, где есть JVM. На нем можно будет написать и Android клиент. А еще можно использовать Kotlin Multiplatform Mobile, чтобы объединить кодовую базу iOS и Android приложения. И там только интерфейсные истории останется написать. Звучит easy. Как раз мой внутренний недождун устал от рутинных проектов по 50 штук в день, и подавай ему что-то эдакое.

Заходим в телегу, спрашиваем: "Есть ORM и Websockets либы для Kotlin, хватит ли этого на проект?". После краткого интродакшена игры нам подтверждают, что все гуд и Kotlin потянет (а вот ты нет!). Не зря Google пляшет вокруг Kotlin. И пару часов спустя нам пишет и предлагает поучаствовать в проекте AahzBrut. Он уже писал игры на котлин, да и явно кто-то с опытом back-end разработки, лучше, чем кто-то без опыта back-end разработки. Просим AahzBrut настроить проект, чтобы мы вдвоем могли писать код на разные части проекта. И получаем через пару часов файлик с описанием: Services, DTO, Entity, POJO, Reposintories. Уходим гуглить. Окей, AahzBrut, очень интересно, но якори нам на back-end точно не нужны. С этого момента AahzBrut у нас за серверную часть, а я за клиентскую.

Хороший старт

Ну по крайней мере на back-end у нас хороший старт

На текущий момент, у нас реализовано:

  • Примерный визуал игры (как должна выглядеть)

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

  • Back-end: aутентификация, регистрация, Websockets STOMP, созданы локации, персонажи, персонажи бегают по локациям, оповещения об изменении количества игроков в локациях, и еще много разных и интересных штук, которые я бы понял, но не понял :(

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

Чао!

Подробнее..

Механики для реализации платформера на Godot engine. 5 часть

15.11.2020 16:06:22 | Автор: admin
Здравствуйте. В предыдущем опросе читатели выбрали следующие пункты на момент создания данной статьи: система характеристик оружия, система здоровья персонажа. А вот дерево навыков я так и не сообразил как правильно реализовать Точнее как создать интерфейс, чтобы отображать и управлять деревом.Предыдущие части:

Система здоровья

Ну начнём пожалуй с системы здоровья персонажа. Я решил создать отдельный файл для всего необходимого. Он назван health_system.gd и лежит в папке скриптов. Важно: это не синглтон, а просто скрипт. Дальше вы поймёте почему.
# Теперь я буду использовать синтаксис javascript. В нём хоть var подсвечивается.extends Object # Расширяем базовый объектclass_name Health # Подписываем класс как Health и после он доступен из любого места игры как тот-же Node, или Node2D.signal death # Добавляем сигнал "death", чтобы испускать его, когда персонаж умирает. Этим персонажем может быть не обязательно даже игрок, или вообще что-то живое.var health: int = 100 setget set_health, get_health # Здоровье и setget для его измененияvar max_health: int = 100# верхний иvar min_health: int = 0# нижний предел здоровьяfunc set_health(new_health: int) -> void: # Функция для того, чтобы ставить new_health здоровья игроку при вызове, что будет не больше или меньше чем можно# warning-ignore:narrowing_conversion # О том что clamp возвращает целое значение, отрезая дробную часть.health = clamp(new_health, min_health, max_health) # Ограничиваем здоровьеif health == min_health: # А если здоровья - заданный минимум - мы умираем, меньше не будет.emit_signal("death") # Испускаем сигнал о том что нечто с этим здоровьем умерлоreturnfunc get_health() -> int:return health # получаем текущее здоровье. Если возвращать константу - игрок будет бессмертным, но константа должна быть больше максимального получаемого урона в игре, иначе мы всё равно умрём.func set_min_max_health(new_max: int = 100, new_min: int = 0) -> void: # Задача верхнего и нижнего предела здоровья. Тут поддерживается отрицательный минимум, что позволит создать эффект грани жизни и смерти, что поднимет адреналин игрока, как было в первой части того же Assasin's creed, что улучшало ощущение хорошей игры.self.max_health = new_maxself.min_health = new_minreturnfunc damaged(dmg: int = 0) -> void: # Получение урона.self.health -= dmg # После некоторых разбирательств я выяснил следующее: set_health() вызывается вместо стандартного "=" и подобных, что позволяет не писать логику смерти в получении урона.return
Чтобы его добавить к персонажу нужно всего-лишь добавить к переменным
# ...var health: Health = Health.new()# ...# И подключаем сигнал смерти в _readyfunc _ready():health.connect("death", self, "dead") #сигнал "смерть" к self.dead(). Смерть я писал в предыдущих выпусках, а если точнее в 3-ей части.
И теперь игрок имеет здоровье. Правда нас всё по-прежнему убивает с 1 удара, потому что я не рассказал об оружии, что будет наносить N урона, а не просто убивать.

Система оружия

А если точнее базовое оружие, которое можно прикреплять к разным объектам и брать данные от него.Ближе к делу, поэтому начну сразу с кода.
extends Nodeclass_name Weapon # Подписываем как Weapon, чтобы можно было прикреплятьenum WeaponTypes {MILLITARY, RANGED, BLOCKER} # Ближний бой, дальний и блокировщикexport (NodePath) var weapon_owner_node_path: NodePath # Путь к владельцуexport (int) var damage: int = 10 # уронexport (int) var critical_damage: int = 20 # критический уронexport (float) var critical_damage_chance = 0.2 # шанс критического урона. Бросаем кубик, если число меньше этого - атакуем критическим урономexport (WeaponTypes) var weapon_type: int = 0 # Тип оружия из перечисленияexport (int) var max_damage_distance: int = 0x20 # Дальность атаки чтобы нанести максимальный урон, если больше - урон будет меньше. В разработке. По умолчанию 32 пикселяvar weapon_owner: Node # Заготовка weapon_owner, чтобы в _ready задать из NodePath, что позволит немного оптимизировать множественные вызовыvar use: FuncRef func _ready() -> void:weapon_owner = WeaponController.get_node_(weapon_owner_node_path)match weapon_type: # ставим в use нужный FuncRef, что вызывается с помощью use.call_func() аргументы в скобки.WeaponTypes.MILLITARY:use = funcref(self, "attack") # Обычная атакаWeaponTypes.RANGED:use = funcref(self, "ranged_attack") # Дальняя атакаWeaponTypes.BLOCKER:use = funcref(self, "block") # Блок атаки врагаfunc attack(enemy: Entity) -> bool:print("attack")enemy.health.damaged(self.damage)return true # Удачность нанесения уронаfunc ranged_attack(enemy: Entity) -> bool:var dmg: float = damageif weapon_owner.global_position.distance_to(enemy.global_position) > max_damage_distance:dmg -= damage / 4enemy.health.damaged(round(dmg))return truefunc block(enemy: Entity) -> bool:print(randi() > critical_damage_chance) # В разработке. Нужно чтобы гасить урон от атак врагов, но я до конца не придумал как реализовать его.return true
Добавляем этот узел к объекту, к примеру к пуле:
extends Entity # Тут я не буду рассказывать обо всём, потому что этот урок о том как прикреплять скрипты здоровья и сцены оружия, а не о создании пушек и других ловушек. О пушке расскажу в следующем уроке о механизмах и ловушках.var direction = Vector2(-1, 0) setget set_directionconst SPEED: int = 40onready var weapon: Weapon = $Weapon # Задаём оружиеfunc _ready():health.connect("death", self, "dead") # health есть уже в Entity, но это единственное что есть в нём.func _physics_process(delta):var motion: Vector2 = direction * SPEED * deltavar collision = move_and_collide(motion, false)if collision != null and collision.collider != null:var coll = collision.colliderif coll.name == "TileMap":self.dead()else:weapon.use.call_func(coll) # Атакуем объект со здоровьемself.dead()print(coll.health.get_health())func set_direction(vec: Vector2) -> void:direction = vecfunc dead():self.queue_free() # Метод смерти просто освобождает этот объект через queue_free()
Вот как выглядит сцена пули:Надеюсь этой картинки хватит чтобы понять как работает сцена Weapon.

Заключение

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

Перевод Базовые концепции Unity для программистов

24.11.2020 16:19:42 | Автор: admin
Привет, Хабр! При проработке темы Unity мы нашли интересный блог, возможно, заслуживающий вашего более пристального внимания. Предлагаем вам перевод статьи о базовых концепциях Unity, также опубликованный на портале Medium


Если вы обладаете опытом программирования и пытаетесь вкатиться в разработку игр, порой бывает непросто найти такие учебные материалы, в которых в достаточной степени объясняется необходимый контекст. Вероятно, придется выбирать между материалами, в одних из которых описана парадигма ООП, в других язык C# и концепции Unity, либо сразу начинать с продвинутых руководств; в последнем случае придется самостоятельно дедуктивно выводить базовые концепции.

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

Я начал путь в программировании около 17 лет назад, открыв для себя Game Maker. Многие часы потратил на самостоятельное программирование маленьких игр и инструментов, в процессе всерьез увлекшись программированием.

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

Сцена


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

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



Редактор сцен Unity, в котором загружена задаваемая по умолчанию пустая сцена в режиме 3D. В пустых сценах Unity3D по умолчанию содержатся объекты Main Camera (Главная Камера) и Directional light (Направленный свет).



Пример сцены в редакторе Unity; здесь выделено несколько объектов. Такое представление сцены можно использовать для редактирования уровней в игре.

Каждый игровой объект в Unity должен находиться в сцене.

Игровые объекты


Игровой Объект (в коде GameObject) один из базовых кирпичиков, из которых строится игра.

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

У каждого игрового объекта есть значения положения и поворота. Для метафизических объектов они не имеют значения.

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



Группа объектов, совместно вложенных в сцене и объединенных в пустом объекте Interior_Props, сделано в целях структурирования

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



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

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

Компоненты (и моноповедения)




Объект Warrior с предыдущего скриншота показан над окном Инспектор в интерфейсе Unity. Каждый из проиллюстрированных разделов (напр., Animator, Rigidbody, Collider) это компоненты, слагающие этот объект

Каждый игровой объект состоит из компонентов.

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

  • У единственного видимого элемента машины будет компонент Renderer, который отрисовывает машину и, вероятно, компонент Collider, задающий для нее границы столкновений.
  • Если машина представляет персонажа, то у самого объекта car может быть Player Input Controller (Контроллер ввода от персонажа), принимающий все события, связанные с нажатиями клавиш, и транслирующий их в код, отвечающий за движение машины.

Притом, что можно писать большие и сложные компоненты, где компонент 1 в 1 равен кодируемому объекту (напр., компонент player содержит код, полностью описывающий персонажа, а компонент enemy, в свою очередь, полностью кодирует противника) обычно принято извлекать логику, дробя ее на небольшие обтекаемые кусочки, соответствующие конкретным признакам. Например:

В коде есть MonoBehavior, вездесущий родительский класс для представления компонентов. Большинство невстроенных компонентов будут наследовать от MonoBehavior, который, в свою очередь, наследует от Behavior и Component, соответственно.

  • Все объекты, обладающие здоровьем, будь то Player (Игрок) или Enemy (Враг) могут иметь компонент LivingObject, задающий исходное значение здоровья, принимающий урон и приводящий в исполнение смерть, когда объект умирает.
  • Кроме того, у игрока может быть компонент ввода, контролирующий сообщаемые ему движения, а у врага может быть аналогичный компонент, реализованный при помощи искусственного интеллекта.

На протяжении жизненного цикла компоненты получают различные обратные вызовы, которые в среде Unity именуются Сообщениями. К Сообщениям относятся, в частности, OnEnable/OnDisable, Start, OnDestroy, Update и другие. Если объект реализует метод Update(), то этот метод будет как по волшебству вызываться Unity в каждом кадре игрового цикла, пока объект активен, а заданный компонент действует. Эти методы могут быть помечены private; в таком случае движок Unity все равно будет их вызывать.

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

Ресурсы


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

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



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

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

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

Шаблонные экземпляры


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

Вложенные шаблоны


Начиная с Unity 2018.3, поддерживается вложение шаблонов, чего и следовало ожидать:

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

Эти концепции компонуются: возможен шаблонный вариант вложенного шаблона или, например, шаблонный вариант шаблонного варианта.

Сериализация и десериализация


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

Поток сериализации/десериализации, действующий в движке Unity, загружает в память ресурсы, расположенные на диске (в вашем проекте: для редактирования или тестового прогона игры, либо в самой игре, при загрузке сцены) и отвечает за сохранение состояния отредактированных вами объектов и компонентов обратно в соответствующие сцены и шаблонные экземпляры.
Следовательно, система сериализации также является ключевым элементом работы с редактором Unity. Чтобы MonoBehavior мог принять ввод при конструировании сцены в ходе ее инициализации, эти поля должны быть сериализованы.

Большинство базовых типов Unity, в частности, GameObject, MonoBehavior и ресурсы поддаются сериализации и могут получать исходные значения при создании прямо из редактора Unity. Публичные поля в вашем MonoBehavior сериализуются по умолчанию (если относятся к сериализуемому типу), а приватные поля для этого сначала нужно пометить атрибутом Unity [SerializeField], и тогда они тоже могут быть сериализованы.


Скриншот игры Chaos Reborn производства Snapshot Games, 2015 год. BY-CC-SA 3.0

Заключение


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

Перевод Расширяемая и удобная в сопровождении архитектура игр на Unity

26.11.2020 14:19:49 | Автор: admin

Будущих студентов курса "Unity Game Developer. Professional" приглашаем посетить открытый вебинар на тему "Продвинутый искусственный интеллект врагов в шутерах".

А пока предлагаем прочитать перевод полезной статьи.


Введение

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

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

Эта статья является обновленной версией моего выступления на GDC в 2017 году (Data Binding Architectures for Rapid UI Creation in Unity).

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

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

Архитектура

Основными целями этой архитектуры являются:

  • поддерживаемость

  • расширяемость

  • тестируемость

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

  1. Инверсия управления (inversion of control)

  2. Интерфейс передачи сообщений (MPI)

  3. Модель / представление / контроллер (MVC)

  4. Модульное тестирование (Unit testing)

Инверсия управления

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

ClassA напрямую зависит от ServiceA/ServiceB. Это обременяет независимое тестирование ClassA необходимостью заботиться о деталях реализации этих двух служб.

Внедрение зависимостей (DI Dependency Injection) это подход к реализации инверсии управления. На следующем рисунке показан предыдущий пример с использованием внедрения зависимостей:

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

Для реализации этого паттерна мы остановились на Zenject/Extenject. Он основан на рефлексии. Используя функцию запекания рефлексий (reflection-baking), мы можем избавиться от негативного влияния рефлексии на производительность.

Модель-Представление-Контроллер

Суть этой архитектуры разбиение кода на отдельные уровни. Паттерн Модель-Представление-Контроллер (Model-View-Controller MVC), перенесенный на Unity, выглядит следующим образом:

Monobehaviour-ы Unity обитают на уровне представления (View), что, как предполагается, защищает остальную часть архитектуры от затрудняющих модульное тестирование элементов Unity. Этот уровень имеет доступ только к уровню контроллера. Представление создает инстансы префабов и использует [SerializeField] для использования типичных dragndrop компонентов Unity. Здесь не должно быть никакой игровой логики, только чистая визуализация данных.

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

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

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

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

Передача сообщений

Вышеупомянутая архитектура полагается на соответствующих уведомлениях (notification messages), чтобы уровень представления мог подписаться и реагировать на изменения/события (events):

Мы используем Zenject Signals.

Следующий код является примером его использования:

struct MessageType {}bus.Subscribe<MessageType>(()=>Debug.Log("Msg received"));bus.Fire<MessageType>();

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

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

Модульное тестирование

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

Для реализации технической части написания этих тестов мы используем стандартный фреймворк Unity NUnit и NSubstitute в качестве решения для создания моков.

Давайте посмотрим на один из наших тестов:

var level = Substitute.For<ILevel>();var buildings = Substitute.For<IBuildings>();// test subject: var build = new BuildController(null,buildings,level);// smoke testAssert.AreEqual(0, build.GetCurrentBuildCount());// assert that `GetCurrent` was exactly called oncelevel.ReceivedWithAnyArgs(1).GetCurrent();

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

Давайте посмотрим на более интересный пример билдинга чего-либо на слоте 0:

var level = Substitute.For<ILevel>();var bus = _container.Resolve<SignalBus>();var buildCommandSent = false;bus.Subscribe<BuildingBuild>(() => buildCommandSent = true);// test subject var build = new BuildController(bus,new BuildingsModel(),level);// test callbuild.Build(0);Assert.AreEqual(1, build.GetCurrentBuildCount());// assert signals was firedAssert.IsTrue(buildCommandSent);

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

"Погодите-ка, нельзя мокать то, что имеет корни в Zenject?" (что очень метко сказано моим хорошим другом Питером)

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

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

Заключение

Это было всего лишь взгляд с высоты птичьего полета на эту тему. Но подведем итоги:

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

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

  • практическим примером применения этих подходов,

  • мокингом сцены для тестирования пользовательского интерфейса

  • фейковыми бэкендами и сторонними SDK

  • промисами для поддерживаемого асинхронного кода


- Узнать подробнее о курсе "Unity Game Developer. Professional" и карьерных перспективах.

- Зарегистрироваться на бесплатный вебинар на тему "Продвинутый искусственный интеллект врагов в шутерах" .


Подробнее..

Перевод Как локализовать игру? Пошаговое руководство

12.11.2020 12:19:49 | Автор: admin
Иллюстрация создана компанией AlconostИллюстрация создана компанией Alconost

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

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

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

Дальше мы расскажем о том, как устроен процесс локализации в Alconost. Надеемся, что сможем дать ответы на самые сложные вопросы локализации. Поехали!

Этап 1. Подготовка к локализации

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

Исследование и анализ рынка

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

Детальное понимание целевой аудитории влияет на такие факторы, как:

  • используемая платформа для приложения (Android для Европы и большей части Азии, iOS для США);

  • функциональность игры;

  • способы геймификации;

  • список языков для локализации.

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

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

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

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

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

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

Подготовка документации для локализации

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

А ещё документация для локализации (в профессиональной терминологии называется lockit, сокращённое от localization kit) может включать в себя такие элементы:

  • глоссарий терминов;

  • предыдущие переводы;

  • файлы, предоставляющие информацию о самом продукте;

  • используемые шрифты;

  • игровые видео;

  • звуковые дорожки;

  • собранный бидл игры (намного реже).

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

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

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

Если вы хотите узнать больше именнно о подготовке к локализации, советуем изучить 10 основных правил, которые составила наша команда. Тут о выборе правильной кодировки (Unicode), об использовании шрифтов, о выборе форматов времени и даты, а также другие тонкости, которые нужно учитывать при подготовке к локализации.

Этап 2. Непосредственно локализация проекта

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

Выбор подходящей платформы для локализации

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

Схема создана компанией AlconostСхема создана компанией Alconost

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

Вот, на наш взгляд, наиболее полезные фичи Crowdin:

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

  • возможность добавлять к текстовым строкам скриншоты с исходным контентом;

  • автоматический разбор файлов на отдельные текстовые строки;

  • дополнительные функции для выбора и настройки необходимых языков перевода;

  • возможность ограничить количество символов в строке, если дизайн накладывает лимиты на длину строк;

  • возможность загрузки существующих переводов и ресурсов локализации;

  • возможность загрузки обновлённых версий файлов (Crowdin может распознавать и различать вновь добавленные или обновлённые файлы);

  • локализация без отрыва от контекста;

  • различные интеграции;

  • инструменты для коммуникации между участниками команды.

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

Процесс перевода

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

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

1. Машинный перевод

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

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

2. Краудсорсинговый (коллективный) перевод

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

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

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

Краткая история из переводческих будней: локализация игры Goat Simulator

Скриншот игры Goat Simulator в Google PlayСкриншот игры Goat Simulator в Google Play

Goat Simulator знаменитая видеоигра, разработанная студией Coffee Stain Studios. Эта игра доступна на нескольких языках: английском, немецком, испанском, французском и польском.

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

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

В случае с Goat Simulator мы также перенесли проект в Crowdin, чтобы организовать более лёгкий, быстрый и удобный процесс локализации.

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

3. Перевод своими силами

В редких случаях у компании-разработчика есть собственная команда опытных переводчиков (речь не идёт о таких гигантах, как Ubisoft или Blizzard). Когда дело доходит до локализации, большинство девелоперов нанимают команду фрилансеров. Но переводчики-фрилансеры могут не знать всех аспектов локализации.

К другим недостаткам работы с фрилансерами можно отнести:

  • сложности с контролем качества и организацией проекта;

  • высокий риск наличия ошибок;

  • риски, связанные с размером затрат или срывом сроков выполнения.

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

4. Профессиональная локализация

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

  • высокое качество перевода, обеспечиваемое опытной командой переводчиков;

  • удобное и простое управление проектами;

  • наличие всех необходимых специалистов в одной команде (переводчиков, менеджеров проектов, специалистов по контролю качества);

  • необходимые инструменты для удобной работы.

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

Передовые практики локализации

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

1. Предоставьте переводчикам справочные материалы и контекст

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

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

2. Проверьте дважды

Во время локализации нужно обратить внимание на важные моменты для конкретного рынка.

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

3. Учтите особенности дизайна

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

Краткая история из переводческих будней: локализация игры Family Island

Family Island это игра-симулятор жизни на ферме для мобильных устройств (iOS и Android), которая была выпущена на нескольких языках.

Скриншот игры Family Island в Google PlayСкриншот игры Family Island в Google Play

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

Как только мы обнаружили проблему, то сразу же сообщили о ней разработчикам.

А ещё мы постарались сократить количество символов, сохранив при этом контекст и первоначальный смысл.

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

4. Пусть переводчики сами поиграют в игру

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

5. Выполните лингвистическое тестирование

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

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

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

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

Заключение

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

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

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

О нас

Alconost профессионально занимаетсялокализацией игр,приложений и сайтовна более 70 языков. Лингвистическое тестирование, облачная платформа с API, непрерывная локализация, менеджмент проектов 24/7, любые форматы строковых ресурсов. Мы также делаемвидеоролики.

Подробнее..

Перевод Воксели против теневых карт выбор новой системы освещения для Roblox

20.11.2020 14:23:38 | Автор: admin


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

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

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


Реализация: воксели


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

Данные о мире преобразуются в набор сеток вокселей: каждая сетка центрируется вокруг персонажа и может иметь размеры вокселей от 1 до 16 (всего 5 решеток). Каждый воксель содержит информацию о наполненности (occupancy) в диапазоне от 0 до 100%. Затем вычисляются данные освещения для каждого вокселя в каждой сетке на основе этой наполненности и информации об источниках/направлении света. Все вышеперечисленное происходит на графическом процессоре, так как центральный недостаточно быстр для обновления такого количества вокселей со столь высокой плотностью.

Система хранит все данные в вокселях, в частности для каждого имеющегося вокселя есть данные о:

  • Наполненности (несколько значений, описывающих, насколько заполнен каждый воксель);
  • Skylight (какая часть неба видна из вокселя);
  • Тени от солнца (какая часть солнца закрыта вокселем);
  • Цвета светового объекта/конуса (приближение цвета/конуса воздействия локальных источников света на воксель).

Эта информация позже используется для вычисления цвета каждого пикселя при заданном разрешении. Разрешение экрана и вокселей можно регулировать независимо друг от друга. Части сетки вокселей могут обновляться покадрово по мере перемещения источников света/объектов.


Реализация: теневые карты



image

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

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

Система хранит данные в двух структурах:

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

Цвет каждого пикселя вычисляется динамически и не хранится в явном виде. Части теневого атласа можно обновлять покадрово по мере перемещения источников света/объектов.


Производительность: воксели


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

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

Производительность вокселей вычисляется как O (G) + O (L) + O (P), где G количество треугольников (геометрическая сложность), L количество источников света, P количество пикселей.

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


Производительность: теневые карты


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

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

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

Производительность карт теней рассчитывается как O (GL) + O (LP), где G количество треугольников (сложность геометрии), L количество источников света, P количество пикселей.


Производительность: оценка


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


Париж (тени от солнца, очень мало источников света, не отбрасывающих тени)




  • Воксели: обновление теней 6 мс, рендеринг сцены 1,5 мс;
  • Теневые карты: обновление теней 1 мс, рендеринг сцены 2,4 мс;
  • Стоимость вычисления базовой воксельной тени выше, поскольку графическому процессору тяжелее ее обрабатывать.


Пещеры (много отбрасывающих тени источников)




  • Воксели: обновление теней 7 мс, рендеринг сцены 0,9 мс;
  • Теневые карты: обновление теней 10 мс, рендеринг сцены 2,1 мс;
  • Из-за большого количества геометрии и движущихся источников света обновление теневых карт обходится дорого.


Вестерн (много отбрасывающих тени источников)




  • Воксели: обновление теней 8 мс, рендеринг сцены 1 мс;
  • Теневые карты: обновление теней 15 мс, рендеринг сцены 2,5 мс;
  • С движущимися источниками света и большим количеством треугольников обновление карты теней оказывается дорогим.


1000 источников света без тени




  • Воксели: обновление света 20 мс, рендеринг сцены 0,5 мс;
  • Теневые карты: обновление света 0,5 мс, рендеринг сцены 5 мс;
  • Совокупный объем перекрытия света и вокселей в этом случае замедляет обновление вокселей. Кроме того, можно увидеть, что в ближнем каскаде приближение для одного источника света в каждом вокселе не выполняется.


Производительность: заключение


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


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


Требования к памяти


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

В случае вокселей в памяти хранятся несколько текстур для каждого каскада, поэтому их совокупный размер зависит от количества каскадов и размера каждого из них. В настоящее время используется 4 каскада (с размерами вокселей 1..8) по 128x64x128 вокселей в каждом, что добавляет до 128 МБ используемой VRAM. Можно было бы завести еще 2 каскада (0,5 вокселя и 16 вокселей) или перенастроить имеющиеся, что увеличило бы это значение до 192 МБ. Можно, наоборот, уменьшить количество каскадов (удалив некоторые близкие каскады) в системах с ограниченным объемом памяти, и тогда минимальное воздействие на память может составить около 64 МБ с двумя каскадами (4..8) и около 96 МБ с тремя (4..16).

В случае теневых карт используются атлас теневых карт и фроксельная сетка. Последняя отчасти зависит от разрешения. Размер теневого атласа, в свою очередь, можно уменьшить, если нужно уменьшить качество теней для улучшения производительности/памяти. Текущая система использует 73 МБ видеопамяти, большую часть из которых (64 МБ) занимает теневой атлас. Можно уменьшить его и таким образом ограничить количество затемненных источников света или качество теней. Также можно рассмотреть некоторые варианты теневых карт, для которых требуется больше памяти для поддержки полупрозрачности, а значит, они займут больше места (до 130 МБ или более). Минимальное воздействие на память системы, вероятно, будет достигнуто, если уменьшить размер теневого атласа и воспользоваться его более простым вариантом, который будет занимать около 25 МБ.

Для сравнения: текущая система освещения имеет два режима: для высокого (ПК) и низкого качества (мобильные девайсы). Вариант для ПК занимает ~ 40 МБ (24 МБ RAM, 16 МБ VRAM); мобильный ~ 11 МБ (6 МБ RAM, 5 МБ VRAM).

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


Мобильная совместимость


Аудитория игры становится все более мобильной, и это означает, что при сравнении выбранных реализаций нужно учитывать еще и различные игровые устройства. На high-end девайсах должно быть достаточно возможностей API для реализации обоих методов, но, конечно, они могут оказаться не столь практичными с точки зрения памяти и производительности.

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

  • Сохранить существующую систему в мобильном виде, новая же будет только ПК/консольной. Это означает, что большой сегмент пользовательской базы не будет иметь доступа к новой системе.
  • Небольшое улучшение существующей системы для передовых мобильных устройств (слегка уменьшенный размер вокселей, улучшенное представление вокселей), использование новой системы для ПК/консолей.
  • Сохранить существующую систему на low-end девайсах, найти способ уменьшить масштаб новой системы, чтобы она могла работать на современных мобильных устройствах.

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


Качество: источники света


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

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



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

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



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


Качество: тени


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



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

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



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


Качество: skylight


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




Качество: геометрическая точность


Стоит отметить фундаментальные различия в представлении геометрии между вокселями и теневыми картами.

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




Качество: light leaks


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



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

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

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


Качество: заключение


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

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


Видимость: полупрозрачность


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



Ниже представлено видео этого эффекта в движении:


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


Видимость: растительность


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




Видимость: self-illumination


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



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


Видимость: глобальное освещение


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

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

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

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


Резюме


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



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

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

Meta Gameplay Framework, или бэкенд без серверных разработчиков

12.11.2020 12:19:49 | Автор: admin


Привет! Меня зовут Кирилл, я руководитель отдела серверной разработки в Pixonic. Здесь я работаю уже более 5 лет. Долгое время Pixonic была компанией одной игры War Robots. Но однажды к нам пришло осознание, что так больше продолжаться не может, и мы начали работу над созданием новых проектов.

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

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

После долгих размышлений наши желания оформились в следующие требования:

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

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

  • Код пишется на JavaScript, что не дает возможности полноценного переиспользования в Unity 3D, и в любом случае приходится преобразовывать ответы сервиса в модели клиента. Получается, что разработчик должен знать два языка программирования и выполнять дополнительную работу, которой хотелось бы избежать.
  • Наша цель разработка хита, а значит речь идет о миллионах игроков в день. Стоимость работы этих сервисов на наших объемах становится значительно больше, чем стоимость самостоятельного владения подобным решением.

Итак, у нас получился следующий набор необходимых технологий и методов:

  • C# (.net core для сервера и клиента, .net 3.5, 4.X для клиента). Мы хотим, чтобы разработчик мог разрабатывать как клиентскую, так и серверную часть задачи. Уйти от Unity 3D мы не можем, а вот написать сервер на C# вполне.
  • Orleans фреймворк для построения распределенных, отказоустойчивых и масштабируемых систем в модели акторов от Microsoft (использовался в Halo). Использование этого фреймворка обусловлено тем, что с нашими задачами рано или поздно придется масштабироваться к тому же, хочется, чтобы решение было отказоустойчивым.
  • GRPC для общения сервисов между собой, так как в системе, кроме сервиса игроков, построенного на Orleans, существуют и другие: авторизация, загрузка каталогов и прочее в том числе и сервисы, которые ранее были написаны на Java и оказались по-настоящему автономны и независимы от того проекта, в котором используются.
  • Postgres для хранения данных игроков. Для масштабирования базы данных мы используем шардирование.
  • Docker с ним удобно разворачивать окружение локально и в тестовой среде. Таким образом, геймдизайнеры и разработчики могут работать с метой так, чтобы никому не мешать. Можно у себя ее локально поднять, проверить, что все работает, как нужно, и запушить уже измененный код в репозиторий.
  • Prometheus для мониторинга.
  • Event Sourcing парадигма, которую мы используем для хранения данных игроков. Она часто используется в банках. Подход здесь такой: когда мы работаем через Event Sourcing, все, что мы делаем, представлено в виде потока событий. Как упоминалось ранее, хотелось бы постоянно иметь историю, которая сохраняется в базе данных. Этот поток событий и есть наша история, по которой мы можем отслеживать, что происходило. Если что-то пошло не так, мы можем посмотреть интересующее нас событие в прошлом и полностью восстановить состояние игрока.

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

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

  • вкладки конфигурирования игровых предметов;
  • вкладки настройки экспериментов (A/B тестов);
  • вкладки настройки лутбоксов;
  • вкладки настройки игровых валют;
  • вкладки для хранения простых настроек, заданных в виде ключ-значение.



Пример конфигурирования предмета

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

// Находим в каталоге предмет с идентификатором 'Reaver_1':ItemBlueprint itemBlueprint = catalog.GetItemBlueprint(ItemBlueprint.ValueOf("Reaver_1")); // Получаем проверенное значение из колонки с названием 'grade'. // Если поле отсутствует или имеет неверный тип, далее этот результат будет передан // в админку, где будет выведена информация о месте нахождения ошибки:Validated<int> grade = itemBlueprint.ShouldHasIntAttr("grade");

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

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

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

  • Лутбоксы. Сейчас без них немыслима ни одна free-to-play игра. Наше решение позволяет задавать различные варианты генерации контента для выдачи: от 100% гарантированного в этом случае лутбоксы можно использовать как обычные контейнеры, до полностью случайного.

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

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

// Описываем команду, представляющую из себя обычную DTO,// которая может быть сериализована в Json:public class DemoCommand : ICommand{    public string BlueprintId;    public int Value;} // Описываем обработчик команды:public class DemoHandler : HandlerBase, ICommandHandler<DemoCommand>{    public void Handle(ICommandContext context, DemoCommand command)    {        // Inventory  объявлен в HandlerBase.        // Создаем новый предмет по образцу из каталога:        var demoItem = Inventory.GrantItem(ItemBlueprintId.ValueOf(command.BlueprintId));         // Задаем предмету значение атрибута 'demo_value':        demoItem.Attributes["demo_value"] = command.Value;     }}

Заводим команду и ее обработчик. В реализации обработчика видно, что мы обращаемся к инвентарю и выдаем предмет игроку. После этого мы присваиваем предмету атрибут demo_value со значением, переданным в команде.

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

// Выполняем команду на сервере:var command = new DemoCommand { BlueprintId = "Reaver_1", Value = 777 };var commandResult = connection.Execute(command); // Из ответа получаем обновленный инвентарь игрока:var inventory = commandResult.Player.Inventory; // Получаем последний созданный предмет:var demoItem = inventory.FindItemsByBlueprint(ItemBlueprintId.ValueOf("Reaver_1")).Last(); // Выводим установленное значение:Console.WriteLine(demoItem.Attributes["demo_value"]);

Так при чем здесь Event Sourcing?

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

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

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



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

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


Пример лога транзакций из реального проекта

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

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

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

Перевод Тестирование игр

16.11.2020 20:18:08 | Автор: admin

Эксперт OTUS Дмитрий Шадрин приглашает всех желающих на бесплатный демо-урок курса "Game QA Engineer", в рамках которого расскажем про то как устроено современное тестирование игр, обсудим перспективы развития специалистов в сфере геймдева, а также рассмотрим основные отличительные черты в тестировании игр.


Чем занимаются тестировщики игр?

Официально вакансия называется QA tester, или, по-русски, тестировщик. QA означает quality assurance, то есть обеспечение качества видеоигры. Эти слова описывают цель работы и отражают разницу между простым прохождением игр и их тестированием.

А суть работы состоит в поиске багов.

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

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

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

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

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

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

Сколько времени занимает тестирование игры?

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

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

Если перспектива сыграть в файтинг тысячу раз вас все еще вдохновляет, то вы, наверное, представляете себе свою любимую игру. Скажем, Marvel vs Capcom, Dead or Alive или Mortal Kombat.

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

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

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

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

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

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

Что должен уметь тестировщик игр?

Давайте поговорим о навыках.

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

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

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

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

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

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

Узнать подробнее о курсе "Game QA Engineer" можно здесь.

Подробнее..

Тестирование игр

23.11.2020 04:19:22 | Автор: admin

В преддверии старта курса "Game QA Engineer", эксперт OTUS - Дмитрий Шадрин подготовил статью в которой рассказал об особенностях и требованиях к тестированию мобильных игр.


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

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

Мобильная игра

Для начала разобьем любую игру на 4 основных составных части:

  1. Геймплей

  2. Управление

  3. Графика

  4. Производительность

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

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

Жанры и механики

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

На данный момент могу выделить следующие жанры мобильных игр:

  1. Платформеры

  2. Шутеры

  3. Гонки

  4. Adventure

  5. RPG

  6. Аркады

  7. Настольные игры

  8. Match 3

  9. Hidden Object

Соответственно существуют особенные механики, которые могут использоваться в мобильных играх:

  1. Touch / Swipe / Multi Touch основные механики управления на мобильных устройствах, которые приводят к похожим простейшим механикам с ПК индустрии (click, drag and drop). Чаще всего данные механики встречаются в настольных играх, в некоторых адаптированных RPG, аркадах, Match 3 и Hidden object.

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

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

Специфика тестирования мобильных игр

Для тестирования любого продукта на мобильной платформе можно выделить следующие особенности:

Первая особенность мобильных платформ размер экрана.

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

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

Вторая особенность мобильных игр инпуты или способ взаимодействия с игрой.

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

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

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

Четвертая особенность мобильных игр способ связи с интернет.

Пользователь априори не может всегда быть онлайн. Мобильность подразумевает, что игрок может находиться где угодно: в метро, в лесу, дома с WiFi, на прогулке с 4g. Поэтому игры должны корректно вести себя при переключении между основными состояниями связи: мобильная связь (2-3-4g, пугающая многих скорость Е), WiFi, отключение связи (режим полета, потеря сигнала). Часть геймплея должна позволять играть в игру и без интернета, чтобы позже загрузить свой прогресс при восстановлении сигнала. При нестабильном подключении можно выдавать сообщения о качестве соединения.Нестабильное подключение или слабый сигнал приводит к разномастным багам:- телепортации модели игрока в командных шутерах. Игрок со слабым интернетом реже отдает пакетные данные и остальные получают лишь промежуточные данные о его перемещениях по системе координат- высокий ping, что делает невозможным нормальную игру в играх на реакцию и сетевой составляющей- потеря прогресса игрока

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

Тестировщикам необходимо условно разделять таргет-девайсы для своей игры:

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

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

  • флагманы - новые и новейшие телефоны. Здесь минимальная планка для fps остается 60, качество текстур приближено к максимально допустимому. Так же уделяется внимание качеству отображения эффектов, теней и сглаживанию.

Требования к тестированию мобильных игр

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

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

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

Далее проверяется основной (core) геймплей. Для этого помощником служит заранее составленный чек-лист всех проверок по геймплей.

Проверяется работа всех игровых механик, которые так же занесены в чек-листы.

Проверяются общемобильные кейсы: работа с прерываниями, сворот/разворот на основных экранах, работа с системными кнопками.

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

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

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


Узнать подробнее о курсе.


Читать ещё:

Подробнее..

Перевод Создавайте игры из виртуальных блоков LEGO в LEGO Microgame

25.11.2020 18:12:55 | Автор: admin

В преддверии старта нового потока курса "Unity Game Developer. Basic" перевели для вас интересную статью из официального блога Unity.


А также приглашаем всех желающих на бесплатный
демо-урок по теме: "2D платформер-головоломка". Если же вы хотите подробнее узнать о карьерных перспективах в геймдеве, по следующей ссылке можно бесплатно посмотреть запись карьерного вебинара по Unity.


Последний шаблон серии Microgames предназначен для новых пользователей: они смогут поделиться своей первой 3D-игрой, на разработку и настройку которой уйдет не больше часа.

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

Если вы когда-то увлекались созданием миров из кирпичиков LEGO, проект Microgame будет идеальным началом вашего творческого путешествия: для разработки собственной игры не требуется опыт программирования, к тому же это абсолютно бесплатно. Над созданием этого проекта мы работали вместе с LEGO Games, и у пользователей была возможность поучаствовать в открытом бета-тестировании. Глобальный релиз это знаменательная для нас дата: впервые в редакторе Unity появились наборы LEGO System in Play и мини-фигурки LEGO.

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

  • Комбинируйте LEGO Behaviour Bricks блоки, которые при взаимодействии производят неожиданный эффект. Вы построите по-настоящему интерактивный мир LEGO один виртуальный кирпичик за другим.

  • Выберите для игры одну из четырех мини-фигурок LEGO (созданных LEGO Games специально для этого шаблона Microgame!).

  • Используйте Библиотеку модов (Creative Mods) для персонализации игры, а также дополнительные темы, которые можно загрузить из Unity Asset Store. Ваша игра станет действительно уникальной!

  • Делитесь готовой браузерной игрой с друзьями и находите новые идеи для творчества на нашем сайте Unity Play, где доступны игры других авторов.

С чего начать

  • Новые пользователи.Пользователям ноутбуков и персональных компьютеров нужно перейти на страницу LEGO Microgame и нажать кнопку Начать в верхней части страницы.

  • Зарегистрированные пользователи. У зарегистрированных пользователей должна быть установлена версия Unity 2019.4 LTS: откройте Unity Hub (v2.4.2 или более поздней версии) выберите вкладку Обучение (Learn) выберите LEGO Microgame.

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

Библиотека модов и дополнения для персонализации игры

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

В Библиотеке модов (Creative Mods) и каталоге дополнений Asset Store доступно множество компонентов для игр, и их количество будет увеличиваться.

Девять способов сделать игру уникальной

На странице Unity Learn | LEGO Microgame вы можете найти девять классных дополнений, которые позволят персонализировать игру уже на этапе изучения основ Unity. В Библиотеке модов можно выбрать собственную мини-фигурку, создать врага или закрытую территорию, где можно спрятать трофеи. И не только это!

Если вы хотите разработать действительно потрясающую игру (особенно это касается взрослых любителей LEGO), вы можете купить виртуальные наборы, мини-фигурки и элементы LEGO в магазине BrickLink, собрать из них в Студии собственные компоненты для игры и импортировать их в проект!

Работа с дополнением из Библиотеки модов

Девять потрясающих дополнений

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

Открываемые дополнения

  • Knights Kingdom поделитесь игрой, чтобы открыть

  • Space Cadet обновите игру, чтобы открыть

  • Danger Zone примите участие в геймджеме 19 ноября, чтобы открыть (см. ниже)

  • Island Adventure расскажите о своей игре, чтобы открыть (см. ниже)

Краткий обзор дополнения LEGO Microgame (доступно в Unity Asset Store)

Как запустить LEGO Microgame в Unity Hub

Поделитесь игрой и получите советы профессиональных гейм-дизайнеров Unity и LEGO

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

Онлайн-курсы с Unity и LEGO

  • ЧТО?Увлекательные вебинары, на которых вы узнаете, как персонализировать игру и работать над проектом LEGO Microgame.

  • ЗАЧЕМ? Вебинары проводят профессиональные гейм-дизайнеры Unity и LEGO. Вы сможете задать им вопросы и получить отзыв о своей игре.

  • КОГДА? Вебинары проводятся еженедельно с 9 по 30 ноября в 20:00 по московскому времени. Длительность вебинара 1 час. Всего состоится четыре вебинара. Вебинары будут записываться.

  • КАК?Зарегистрируйтесь на этой странице.

От редактора: Онлайн-курс "Unity Game Developer" от OTUS.

Геймджемы с Unity и LEGO

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

  • ЗАЧЕМ? Вебинары проводят профессиональные гейм-дизайнеры Unity и LEGO. Мы вместе построим крутую полосу препятствий, которая наверняка вдохновит вас на новые идеи для собственной игры.

  • КОГДА? В четверг, 19 ноября, в 21:00 по московскому времени. Длительность геймджема: 22,5 часа.

  • КАК?Подписывайтесь на нас в Twitter, Facebook, Instagram или YouTube и следите за новостями мы обязательно расскажем, как принять участие.

Презентация проекта LEGO Microgame

  • ЧТО?На этих мероприятиях пользователи могут продемонстрировать свой проект. О лучших мы расскажем на канале LETS PLAY!

  • ЗАЧЕМ? Вы сможете не только оказаться в центре внимания, но и получить цифровую эмблему, которая будет видна на вашей странице. Мы поиграем в игры, прошедшие отбор, а лучшие из них через несколько дней получат награду во время трансляции на нашем канале UnityTech в Twitch.

  • КОГДА? Первая презентация состоится 19 ноября, контент принимается до 16 декабря включительно. О датах проведения последующих презентаций LEGO Microgame мы сообщим позже.

  • КАК?Переходите на страницу Unity Play, просматривайте презентации других пользователей и делитесь своими. Для загрузки контента вам потребуется Unity ID.

Создайте свой первый проект LEGO Microgame уже сегодня

  • Новые пользователи.Пользователям ноутбуков и персональных компьютеров нужно перейти на страницу LEGO Microgame и нажать кнопку Начать в верхней части страницы.

  • Зарегистрированные пользователи. У зарегистрированных пользователей должна быть установлена версия Unity 2019.4 LTS: откройте Unity Hub (v2.4.2 или более поздней версии) выберите вкладку Обучение (Learn) выберите LEGO Microgame.


Узнать о карьерных перспективах.


Читать ещё:

Подробнее..

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

21.11.2020 16:12:42 | Автор: admin
Привет, Хабр! Представляю вашему вниманию перевод статьи 12 Persistent and Harmful Misconceptions that Hurt the Player Experience автора Pascal Debroek.



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

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

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

1) Кто угодно может быть специалистом или руководителем службы поддержки игроков


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



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

2) Саппорта на английском языке достаточно


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

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

3) ИИ (скоро) заменит людей


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

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

4) Довольные игроки = Лояльные игроки


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

5) Мнения и отчеты важны только в больших цифрах


В какой момент вы предупреждаете команду об отрицательном отзыве или сообщениях о возможном ошибочном поведении? Жалуется только 1 из 26 недовольных клиентов. Остальные уходят. Отсутствие обратной связи не является признаком удовлетворения игрока. Безразличие убивает бизнес.

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

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



6) Радуйте игроков подарками


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

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

7) Улучшение сервиса за счет найма


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

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

8) Поддержка игроков должна быть максимально быстрой


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

9) Качество саппорта зависит от правил и политики компании


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

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



10) Саппорт практически не требует технических ресурсов


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

  • CRM-софт. Позволяет получать, классифицировать и отвечать на сообщения игроков. Современный CRM часто включает в себя автоматизированные функции, управление рабочим процессом, машинное обучение и функции аналитики (и это еще не все). Многие из них предлагают решения для поддержки в приложениях (интеграция через SDK), которые лучше всего подходят для мобильных игровых студий и интегрируются с различными каналами. Интеграция, новые функции и регулярное обслуживание требуют технических знаний.
  • Портал администрирования: они позволяют специалистам саппорта управлять или искать профилем игрока для решения запроса. Большинство из них представляют собой визуальное представление данных профиля с добавленным к ним слоем функций. Они позволят связывать учетные записи с идентификаторами, управлять счетами или внутриигровыми ресурсами, сбрасывать прогресс игрока и так далее. Здесь постоянно требуются технические знания, поскольку новые игровые фичи часто требуют новых административных функций. Ни при каких обстоятельствах вы не захотите, чтобы кто-либо напрямую управлял необработанным JSON-файлом.

В зависимости от ваших потребностей (и размера/ресурсов студии) существует множество дополнительных инструментов, которые вы можете использовать для улучшения саппорта. Если у вас есть внутриигровой чат, убедитесь, что у вас установлена программа для модерации. Программное обеспечение для управления проектами или работой часто требуется для отслеживания задач и проблем. А если вы хотите доказать окупаемость инвестиций (ROI) вашего отдела поддержки, то получите ресурсы для интеграции ваших данных с данными Business Intelligence.



11) Отзывы игроков это негатив и жалобы


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

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

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

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

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



12) Только саппорт несет ответственность за удовлетворенность игроков


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

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

Math Invasion. Мой долгострой

23.11.2020 16:15:20 | Автор: admin
Привет, народ!

Расскажу я вам свою историю о том, как я разрабатывал игру. Идея о том, чтобы скрестить shoot em up с математикой, мне пришла ещё в студенческие годы (Где-то в 2008 году).

Собственно, уже тогда я ещё делал попытки воплотить идею в жизнь. Для реализации своих целей, тогда я использовал язык программирования Delphi и, только осваиваемую мною, библиотеку GLScene. Как результат, у меня получилась игра видео которой Вы можете наблюдать ниже. Кстати, саму игру Вы можете скачать по данной ссылке. Запускается она через файл Project1.exe который находится в папке TestFireCursorProject19

С чего начинался Math Invasion


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

Лучшие времена не пришли.

Но, спустя 10 лет, объявилось желание воскресить прежнюю задумку уже в новом формате. К тому же, миру были подарены мощные инструменты для разработки игр. Моё внимание пало на Unity3D. По слухам, удобный инструмент для разработки игр в 2D. Как раз, то что было мне нужно. В 2019 году я приступил к разработке. Для написания кода я выбрал C#, так как с магией JavaScript я был знаком и не хотел портить себе нервы. Но ввиду того что я не был знаком с C#, я тратил на разработку больше времени чем могло уйти. И вот, спустя 2 месяца, имея на руках MVP, по причине нехватки времени для работы которая меня кормит, я забросил разработку ;-D

Прошёл ещё один год.

Я вернулся к доработке. А точнее, к переделке. Потому что за год я успел показать недоделанную игру своим друзьям и знакомым (коим огромное спасибо) и собрать фидбек. Оказалось, что игру я создавал лично для себя, а не для пользователя. (Полную историю изменения игры вы сможете найти у меня в Telegram канале или на странице в Facebook).

Первая версия на Unity3D
image

Я адаптировал игру под мобильное приложение. Внёс изменения в интерфейс и механику игры. Что бы игра не выглядела совсем сухо, я добавил ей дух соперничества, т.е. врага который хочет, что бы вы проиграли. Он то и шлёт на вас эти математические задачи и радуется каждой вашей ошибке. Отсюда и название Math Invasion (Математическое наступление). Мои знакомые сказали, что враг в игре это лишнее.

Мне подсказали другую механику, при которой игра будет более интересна для пользователя. Я не стал переделывать игру ещё раз, но решил в дальнейшем внести новую механику как дополнительный способ прохождения. Назову я этот способ CHALLENGE!!!.

Релиз


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

Какой я вынес урок для себя?

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

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

23.11.2020 14:22:47 | Автор: admin
Небольшая история от том как я стал разработчиком игр. Постараюсь осветить проблемы, с которыми я столкнулся на своем пути, и поделиться некоторыми цифрами. Программистом работаю давно, с 2001 года, компьютерами занимаюсь с детства, но играми начал заниматься лишь в начале 2014 года. И катализатором этого стала статья на Хабре. Где-то в начале 2014го, читая статейки на Хабре, я нашел статью про то, как один молодой человек сделал простенькую игру для ВК. Простая игра про сражение на самолетиках в 2D. Про саму игру в статье было мало, но меня заинтересовало то, что ему предложили продать игру за 700 баксов. Он отказался и потом пожалел, так как игра принесла ему только убытки. И эта история успеха как-то меня вдохновила.

Я подумал, неужели я не смогу сделать подобную игру? Да я таких в месяц смогу написать десяток. Изучая вопрос разработки для веба, я решил выбрать флэш, кажется, в той статье была игра как раз на нем, хотя его закат был уже предрешен. Итак, я начал осваивать флэш, смотреть ролики на ютубе, пытаться повторять небольшие примеры. Больших раздумий о выборе того, что я хочу сделать не было, я хочу сделать свой Command&Conquers со своим сервером и юнитами :) Рисовать я не умею, поэтому я взял картинки от оригинальной игры, которые можно найти на просторах интернета. Я думал, что если что-то выйдет, я закажу арт для игры у того, кто это делать умеет. Когда что-то получалось, то я выкладывал видосы и скрины на своей странице в ВК. Уже не помню, сколько времени я этим занимался, но, как я планировал ранее, сделать море игр в ближайшие недели у меня не получилось. Основная работа так же съедала много времени, и я двигался очень медленно. Немного позже мне предложил помощь в проекте мой давний знакомый Дима, также большой фанат стратегических игр. Он придал проекту ускорение. Более того, как оказалось, он был знаком с художником, который уже участвовал в создании подобных проектов для PC. Поэтому у него уже были наработки, модели зданий и техники.

Мы пообщались и решили сделать игру вместе. У нас был один программист, это я, художник Сашка и сценарист Дима. Мы договорились, как будем делить шкуру неубитого медведя, придумали название проекта и взялись за работу. Через некоторое время мы отказались от ВК и начали делать игру под мобилки. Так как часть проекта уже разрабатывалась мной на флэше, то и было решено не уходить с него, используя Adobe AIR, можно было писать практически под любую платформу. ( Небольшое отступление, пишу про флэш, как будто оправдываюсь, если честно, не особо понимаю всех нападок на эту технологию, все как будто вместе обиделись на флэш и дружно ушли с него. Мне вообще нравится флэш, поэтому больше никаких оправданий.

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

Игра не отличалась какими то фишками, все игровые механики были заимствованы из различных стратегических игр конца 90х начала 2000х.

Так как игра сделана в изометрическом стиле, то все используемые объекты состояли из заранее отрендеренных картинок. Сейчас их более 8000. Сашка часто их перерисовывал и давал мне наборы, зачастую меняя имена картинок, и это приводило к тому, что и код нужно было править, и в определенный момент пришлось написать уже отдельную программу, которая бы систематизировала картинки и писала код, чтобы этими наборами можно было легко пользоваться. Это экономило много времени. Тумана войны изначально не было, потом я сделал некий костыль из черной картинки, которую дырявил овалами, а затем я подсмотрел алгоритм рисования тумана в движке stratagus. Сам ландшафт-карта в игре была нарисована одной картинкой. На карте заранее указывались места, где нельзя было перемещаться. Для этого я написал некий редактор, где можно было обозначить эти места некими прямоугольниками. А уже в игре загружал их в массив и постоянно перебирал, наткнулся ли юнит на данный прямоугольник или нет. Что удивительно, это было очень быстро, да и карты составлялись с наименьшим количеством данных мест. Алгоритмов поиска пути я не знал, и по какой то удивительной причине решил изобрести свой, несмотря на то, что в интернете можно было нагуглить уже готовые на AS3. Когда юнит натыкался на такой невидимый прямоугольник, обозначающий некое препятствие, например скалу, он начинал поворачиваться по часовой стрелке (на самом деле я уже не помню, в какую сторону он начинал поворачиваться, да это уже и не важно), проверял, может ли он туда идти и продолжал идти, либо снова поворачивал.

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

image

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

image
Вот так вот выглядел доход за первый месяц

Сервер игры


У меня был опыт написания сервера на C++, это совсем простое клиент-серверное приложение с использованием сокетов, в котором у меня было 2-3 клиента Но тут требовалось изобрести велосипед покруче. Я выбрал C# так как к тому времени уже долгое время программировал на нем, а также Microsoft SQL Server для хранения статистики. Нагуглил пример сервера на C#, начал разбираться с реализацией сокетов на AS3 (буду в дальнейшем писать про флэш так). Идея была проста, у меня юниты уже имели очередь команд, которые затем выполняли, нужно просто при добавлении команды юниту на одном устройстве, передавать ее на сервер, а сервер будет эту команду отправлять второму устройству, и обратно. А также некие сервисные функции, авторизации на сервере, создание комнаты, контроля версий игры, игра очень часто обновлялась, в нее добавлялись новые юниты, исправлялись ошибки, и это требовало, чтобы игроки играли одинаковыми версиями и т.п. Относительно быстро мне удалось написать рабочий сервер. И, о чудо! мы можем играть друг с другом! Создание комнат я прикрутил намного позже, а вначале игроки просто могли лишь выбрать карту для создания игры, а второй игрок должен был нажать присоединиться к серверу, и тогда они соединялись и играли на карте, которую выбрал создавший игру игрок. И этот сервер располагался снова у меня в квартире. Постепенно я довел мультиплеер до более- менее приличного вида. Сейчас на одной карте могут играть до 8 игроков, в различных вариантах, до 3-х команд. Также статистику игры и некоторые функции можно смотреть на сайте игры, который я написал на ASP.net. Все игры, которые происходят на сервере, сохраняются в xml файлах, которые можно скачать и посмотреть на клиенте с несколькими режимами скорости. Храню реплеи на диске, а не в базе и их накопилось уже достаточно большое кол-во. Не уверен, что это хорошая идея, но запихивать более 100 гиг реплеев в базу, тоже нет желания. За победу в игре начисляется рейтинг, с небольшими изменениями, это рейтинг рассчитанный по системе ЭЛО. Периодически я сталкивался с различными проблемами оптимизации, необходимости разбираться с приемами асинхронности, нехватки места на сервере и многим другим. И я в конце концов арендовал нормальный сервер. Сначала виртуальный, а потом уже настоящий.

Читеры


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

image

Боты


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

Платная версия игры


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

image

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

image

В июне 2015-го года мы запустили платную версию нашей стратегии, и это было совсем не плохо. Игра долго держалась в топах платных стратегий в России и еще в некоторых странах. И принесла где- то 1000$ за первый месяц. Это был первый нормальный доход с игр, я поверил, что этим можно что-то заработать. За все время платная версия на андроиде принесла примерно 22K $ (уже с вычетом гугла).

image

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

Локализация


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

Поглядел статистику показа рекламы, там никаких изменений не заметил. Поглядел некоторые ip игроков, все они были из Китая. Погуглил и нашел на китайских просторах интернета свою игру, полностью локализованную. Кто -то ее распотрошил, перевел все вплоть до картинок и выложил. Также в игре была удалена реклама, разблокированы различные платные функции и т.п. Я смог извлечь из этого выгоду, взял оттуда китайский перевод и поставил себе в игру! Украл перевод из украденной у меня игры. Обновил версии и отключил возможность играть старыми. Удивительным образом игра была очень популярна в Таиланде, хотя не имела локализации из 1.3 М скачиваний 250 тыс скачиваний в Таиланде, который идет первым, за ним Россия с 160 тысячами. Этот график я покажу немного позже.

image

Озвучка игры


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

Музыка в игре была написана нашим художником Александром, а некоторые композиции написал нам Юрий (GraYaSDF).

Реклама


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

image

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

Другие платформы


Также я выпустил игру на iOS, и потом в стим. Это очень просто, используя технологию Adobe Air. Некоторое время, у меня была даже браузерная версия игры в ВК. Но там даже близко не было тех скачиваний что на андроиде. Поэтому основной платформой для меня является андроид.

Другие мои игры


Я написал про одну игру. На самом деле их уже три. Они по сути являются одной, так как сделаны на одном движке и являются закосами под уже варкрафт Warage и дюну Expanse.

image

Заключение


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

Перевод История Crazy Taxi интервью с создателем серии Кенджи Канно

17.11.2020 18:17:45 | Автор: admin

image


Спустя 15 лет после того, как в аркадных залах заиграла группа The Offspring, издание Retro Gamer пригласило Кенджи Канно поболтать о создании популярного гоночного франчайза Crazy Taxi (интервью было взято в 2014 году).




Уважаемый читатель, позвольте ввести вас в курс дела. Сегодня мы добрались до работы на такси: очень быстро и с ветерком. Благодаря сумасшедшему водителю поездка отняла у нас всего половину обычного времени. Его навыки включали умение со скрежетом просачиваться между машинами и неспособность видеть красный свет. Сильный акцент делал большую часть его болтовни непонятной, но, если честно, нас больше волновало желание не разбиться в поездке. А что мы выкрикивали!.. Таких выражений вы не услышите и в переводах Гоблина. Любой нормальный человек, прокатившийся с этим таксистом, запомнил бы номерной знак и сообщил о лихаче в полицию. Однако редакция Retro Gamer не относит себя к нормальным людям вместо этого мы просто подумали: Это было чертовски похоже на Crazy Taxi.


image


Для законопослушных граждан опасное вождение просто фантазия, но для Кенджи Канно простаивание в пробках стало источником вдохновения. Я немного увлекаюсь автомобилями, и однажды ездил себе в удовольствие, но застрял в пробке, рассказывает нам Канно. При этом встречная полоса была совершенно свободна! И когда я это увидел, то подумал, что есть сотни других людей, мечтающих об одном: выехать бы на встречку и добраться до места с ветерком! Это желание отбросить все правила дорожного движения стало основой игрового процесса в Crazy Taxi. Однако это был далеко не единственный из источников вдохновения Канно. В то время выходило много гоночных симуляторов. И, честно говоря, я от них устал, говорит Канно. Есть куча фильмов с автомобильными погонями. Вот я и подумал: что, если сделать игру, похожую на них, чтобы люди получали от процесса ещё больше наслаждения?


Учитывая, что гоночные симуляторы доминируют в аркадных залах, эти слова звучат просто удивительно. Погони в фильмах также вдохновили разработчиков серии Driver, которая вместе с Crazy Taxi основала поджанр гоночных игр в открытом мире. Однако Driver создана под впечатлением от классических картин про погони семидесятых годов, тогда как Crazy Taxi присущи более современные мотивы. Дизайн Канно опирался на калифорнийскую панк-рок-сцену. Хотя это и похоже на гонки, я стремился создать игру-экшен, а в них важны ритм и темп, объясняет он. Я уже подобрал музыку, которую хотел включить в свое детище. Проект создавался под неё чтобы геймплей был в одном с ней ритме.


image


Калифорнийский дух не ограничился саундтреком от групп The Offspring и Bad Religion. Стремление Канно к красочной и холмистой местности привело к созданию города, основанного на Сан-Франциско. Хотя это не было детальным воссозданием города, в игре легко узнать его основные достопримечательности. Я хотел больше реализма, вспоминает Канно. Чтобы это ощущение присутствовало, я решил, что в игре будут популярные места для досуга и развлечений. В Crazy Taxi пассажиры просят игрока отвезти их в такие места, как Tower Records, KFC и Pizza Hut, а также на стадион, к полицейскому участку или торговому центру.


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


image


Добившись успеха в аркадных залах, Sega поспешила выпустить игру на Dreamcast. И хотя аркадные автоматы были построены на базе Sega NAOMI (по сути, аналога Dreamcast), при портировании возникли сложности из-за размера города. В аркадной версии открытый мир не был проблемой, потому что у NAOMI были загрузки с картриджа и вдвое больше оперативной памяти, чем у консоли. Чтобы преодолеть ограничения Dreamcast, команде Канно пришлось запрограммировать метод потоковой передачи данных о городе с диска прямо во время игры. И эти усилия стоили того, поскольку версия для приставки оказалась практически неотличимой от аркадной.


Crazy Taxi для Dreamcast не только считается идеальным портом, но и включает в себя много дополнений. Наиболее заметным их них стал режим Original Mode, который позволяет игрокам наслаждаться новым городом с извилистыми улицами и трамвайными путями. Также имелся Crazy Box Mode набор мини-игр, в которых такси сбивает кегли в боулинге или лопает воздушные шары. Канно поручил команде самостоятельно обдумать концепцию мини-игр в свободное время, чтобы затем собраться в офисе и отобрать лучшие идеи. Мы рассмотрели различные элементы игры, за выполнение которых игрок мог получить оценку. Например, дрифт, вспоминает Канно, подчеркивая роль Crazy Box Mode в обучении геймеров продвинутым техникам. Это режим, в который ты просто играешь и получаешь удовольствие. Но его можно использовать и в качестве практики.


image


Версия Crazy Taxi для Dreamcast, выпущенная в начале 2000 года, была тепло принята игровыми изданиями, отметившими отличное качества порта. Удивительно, но Канно не был в курсе этих хвалебных отзывов. На самом деле я даже не знал, что к игре так отнеслись, ответил он. Я думаю, что основная причина успеха заключалась в следующем: мы предлагали игрокам то, чего не могли предложить другие проекты того времени. Геймеры с восторгом приняли игру, раскупив более 1 миллиона копий.


Однако финансовые проблемы Sega привели к тому, что всего через год компания ушла с консольного рынка, перестав выпускать игры эксклюзивно для своей провальной консоли. Acclaim лицензировала Craxy Taxi и разработала версии для PlayStation 2 и GameCube. А Sega в это время заключила контракт со студией Strangelite на разработку версии для ПК. Ни один из портов не обрёл такой любви критиков, как Dreamcast-версия, однако версия для PlayStation 2 в конечном итоге превзошла продажи оригинала, хоть и не намного. Закончив работу над портом для Dreamcast, команда Канно из студии Hitmaker переключилась на создание продолжения.


image


Основная формула вождения без правил, чтобы доставить клиентов к месту назначения, не изменилась, но в Crazy Taxi 2 были представлены четыре новых героя и две новые карты. Эти локации, основанные на Нью-Йорке, представляют собой плотную городскую среду с небоскрёбами, тогда как местность стала менее холмистой. Новый дизайн был частью плана команды, чтобы предоставить игроку новые ощущения от вождения. Первая часть являлась линейной игрой, основанной на движении по полосам, и вы могли избежать столкновения, просто увернувшись влево или вправо. Так что в некоторым смысле это была почти двухмерная игра, объясняет Канно. В Crazy Taxi 2 мы хотели больше трёхмерного дизайна, и Crazy Hop это результат того, чего мы пытались достичь.


Безумный прыжок (Crazy Hop) это новая способность, представленная в Crazy Taxi 2, которая позволяет такси прыгать. Хотя в локациях Around Apple и Small Apple не так много холмов, разработчики восполнили это эстакадами и трамплинами на крышах, что позволило игрокам с быстрой реакцией сократить маршрут. Более того, новые мини-игры в режиме Crazy Pyramid Mode также используют новую механику. Еще в игре появились группы пассажиров. Теперь в ваше такси могут сесть до четырёх человек, каждый из которых направляется в разный пункт назначения. Ограничение по времени при этом довольно жёсткое, но опытные игроки могут заработать сумасшедшие деньги помимо платы за проезд, вы получаете множитель чаевых за каждого пассажира.


image


Crazy Taxi 2, вышедшая в середине 2001 года, тоже получила хорошие отзывы, но не достигла такого же уровня оценок, как её предшественница. Критики отметили безумный экшен, как в оригинальной игре, и ещё больше треков группы The Offspring, но посчитали, что игра практически идентична оригиналу визуально и совсем незначительно отличается по части геймплея. По факту, самое серьёзное изменение в игровом процессе стало самым спорным. Некоторым игрокам это не понравилось, другие прониклись новой механикой, то есть реакция получилась неоднозначной, объясняет Канно, рассуждая о механике безумного прыжка. Для многих острые ощущения при уклонении от столкновений пропали с появлением возможности перепрыгивать через эти преграды. Несмотря на неоднозначный приём, безумный прыжок остался и в третьей части серии.


Crazy Taxi 3 стала одним из первых эксклюзивов Sega для консоли от Microsoft Xbox. Выбор платформы был довольно странным, ведь Xbox являлась первой приставкой этой корпорации. Более того, Crazy Taxi уже успешно продавалась на PlayStation 2. Канно рассказал нам, что на такое решение повлиял энтузиазм со стороны американской компании: Мы разговаривали с Microsoft о серии Crazy Taxi, и им действительно нравился этот проект!


image


Ранние планы Crazy Taxi 3 были ещё более амбициозными, чем Crazy Taxi 2. В интервью с Хисао Огучи, который работал продюсером первых двух игр, упоминалось, что команда экспериментировала с мультиплеером, но в конечном итоге от него отказалась. Также планировалась смена дня и ночи, чтобы маршруты пассажиров менялись в течение суток. Команда даже решила изучить местность вживую, съездив в ранее добавленные в игру города такие, как Нью-Йорк. Я не хотел ехать, рассказывает Канно о поездке. Однако наш дизайнер там побывал, и очень здорово, что у него был жёсткий график. Ровно за неделю до терракта 9/11 он находился в одном из этих зданий. Немного жутковато, правда?


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


Финальная версия игры стала своего рода сборником прошлых частей серии, хоть и со значительными дополнениями. В игре есть локация West Coast из первой части с некоторыми новыми областями, предназначенными для безумного прыжка. Присутствует и Small Apple из сиквела, но в ночном сеттинге. Единственной новой картой Crazy Taxi 3 стала Glitter Oasis тематический район Лас-Вегаса в ночное время, в котором игрок может насладиться яркими огнями города и окраинами Большого каньона. В игру были добавлены четыре новых героя и восемь из прошлых частей. А в режиме Crazy X Mode появились новые мини-игры.


image


Crazy Taxi 3 вышла в середине 2002 года и получила сдержанные оценки от критиков. Им по-прежнему нравилась основная механика игры, но все издания были едины во мнении, что здесь недостаточно нового контента. Также отмечали плохое техническое исполнение: были проблемы с расстоянием прорисовки и тормозами, особенно на локации Glitter Oasis. ПК-версия вышла в 2004 году за неё вновь отвечала студия Strangelite, и она оказалась лишь немного лучше. Но зато Crazy Taxi 3 удалось вернуть в аркадные залы. Sega выпустила автомат в 2003 году: он был построен на плате Chihiro, которая начинкой походила на Xbox. Канно не усмотрел в этом ничего необычного: Это казалось правильным решением: эй, если мы вернём игру в аркады, наши потребители будут счастливы.


В 2003 году THQ приобрела права и выпустила версию Crazy Taxi для консоли Game Boy Advance. Crazy Taxi: Catch A Ride, разработанная студией Graphic State Games, оказалась неудобной для портативной системы. Как и другие попытки создания трёхмерных гоночных игр на этой консоли, проект ужасно выглядел, страдал от низкой частоты кадров и быстро расходовал заряд батареи. Позже, в том же году, серия попала в новости из-за судебного процесса о нарушении авторских прав Sega подала в суд на Electronic Arts, Fox Interactive и Radical Entertainment. Причиной стала игра 2001 году The Simpsons: Road Rage, которая была очень похожа на Crazy Taxi. Иск был урегулирован во внесудебном порядке за сумму, которая не разглашалась.


image


В последующие годы франчайз Crazy Taxi стал для Sega способом заработать на ностальгии. Crazy Taxi: Fare Wars 2007 года был сборником первых двух игр для PSP. Несмотря на то, что из игры вырезали большую часть музыки и сетей фастфуда, она выделялась многопользовательским режимом. Оригинальные части Crazy Taxi позже выходили на Xbox 360, PlayStation 3 и PC, но с тем же отсутствием контента. Зато в этих версиях есть возможность слушать собственную музыку, так что вернуть оригинальный саундтрек не будет проблемой. В версиях для iOS и Android имеется оригинальный саундтрек, но нет сетей фастфуда.


Последней игрой в серии (на момент интервью) стала Crazy Taxi: City Rush бесплатная мобильная игра, которая сочетает в себе дух серии с форматом раннера. Хоть Crazy Taxi и казуальная игра, но в ней есть шарм и притягательность, которые делают её захватывающей, говорит Канно о решении развить серию в этом новом направлении. Поскольку мобильные устройства так широко распространены, мы подумали, что они станут идеальной платформой для проекта. Преобразование было выполнено Hardlight британской студией Sega, которая специализируется на играх для мобильных платформ. Это решение Канно объясняет большой популярностью серии на Западе.


image


Хотя мобильная игра и относится к жанру раннеров, в ней есть некоторые характерные для Crazy Taxi механики. Например, игроки по-прежнему получают бонус Crazy Through за уклонение от другого транспорта. Но аутентичность механики игры не является целью для Канно, который больше стремится сохранить дух серии. По его словам: Дело не в автомобилях, технических деталях или механике, а в том, похоже ли это на Crazy Taxi?. City Rush также привносит новые элементы игрового процесса, такие, как апгрейд такси.


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


image


Итак, Crazy Taxi оставила значимый след в игровой истории. И спустя два десятка лет франчайз привлекает внимание геймеров. Даже Канно испытал последствия популярности игры на собственном опыте: Однажды я отправился в отпуск, в Лас-Вегас, и мне повезло сесть к таксисту, который ехал на головокружительной скорости, чтобы доставить меня к месту назначения. А потом, когда я выходил из машины, он выдал: Я сумасшедшее такси! Но он даже не знал, кто я такой! Это был просто безумный таксист!


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




Статью взял из 130 номера журнала Retro Gamer.

Подробнее..

Из песочницы Чему хорроры должны научиться у rogue-like

20.11.2020 18:16:58 | Автор: admin
Привет, Хабр! Представляю вашему вниманию перевод статьи Roguelike Lessons Horror Games Need to Learn автора Josh Bycer.



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

Страх перед неизвестным


Ужас в любом виде связан с неизвестным факт того, что вы попадаете в ситуацию, в которой не знаете, что произойдет. Подобных знаковых моментов очень много: собака, прыгающая в окно в Resident Evil 1, первое появление Пирамидоголового в Silent Hill 2, или момент, когда понимаешь, во что вляпался герой Outlast.

Это не то же самое, что в игре вроде Amnesia, где разработчики используют амнезию как способ удержания игрока в неведении. История, как и память персонажа, в какой-то момент будет восстановлена либо для твиста, либо для завершения игры. Самый лучший ужас это не момент Ага!, когда все выясняется.

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

Именно здесь геймдизайн проектов жанра rogue-like может значительно улучшить хорроры. Стоит создать особый вид случайности.

Определение случайности


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

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

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

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

Идеальный темп


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



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

Пейсинг проблема трех последних Resident Evil, и главное причина беспокойства за RE 8. Седьмая ощущалась слишком затянутой для своего содержания, а 2 и 3 были слишком коротки и большую часть времени состояли из боевки.

Дизайн и пейсинг rogue-like идеально подойдут ужасам. Хорошим примером станет предстоящая игра World of Horror, она умело смешивает таинственность хорроров с укороченным темпом рогаликов. Типичная игровая сессия в ней длится менее часа, и как в любом хорошем рогалике каждая час отличается от предыдущего.

Микро-хоррор


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

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

Сражения


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

В каком-то смысле это правда, но все не так просто. Проблема с проектами вроде Resident Evil, Dead Space, Alan Wake и другими AA/AAA, заключается в том, что бой становится формой заполнения игры. Нельзя постоянно поддерживать ужас в игре с большим количеством боев он просто не будет работать. Такой же эффект случится, когда взаимодействие с игрой будет минимально.

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



Хочется, чтобы в сочетании с коротким темпом ужас принял более интуитивную форму боя. Речь идет не об опасных боях сражения со 100 врагами, а просто о борьбе с одним. Вот почему мы часто вспоминаем альфа-антагонистов, таких как ксеноморф из Alien Isolation, Мистер X из Resident Evil 2 и, конечно же, встречи с Пирамидоголовым в Silent Hill 2.

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

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

Будущее страха


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

Есть золотая середина между короткими инди-хоррорами и крупными AAA-проектами. Нужно просто это объединить.

Если вас интересуют мои книги по геймдизайну, то сейчас вышли Game Design Deep Dive Platformers и 20 Essential Games to Study. Game Design Deep Dive Roguelikes выйдет в начале 2021 года.
Подробнее..

Из песочницы Уникальные тропы Death Stranding или гениальный левел-дизайн

21.11.2020 14:13:58 | Автор: admin
Привет, Хабр! Представляю вашему вниманию перевод статьи Death Stranding Level Design Tropes автора Iuliu-Cosmin Oniscu.



Играл в Death Stranding и пытался сформулировать, чем она отличается от других игр с открытым миром по классической формуле. И пришел к выводу, что игра целится совсем в другое. Под катом разбор оригинального левел-дизайна проекта Хидео Кодзимы.

Разница не в традиционных факторах. Если ими руководствоваться, то можно сказать, что DS ничем не отличается от Breath of the Wild, Watch Dogs, Assassins Creed, Ghost Recon или любой другой опенворлд-игры, у которой есть:

  • Системный игровой процесс
  • Сред, информирующая о выборе игрока



Но очевидно, что DS не похожа на Breath of the Wild, несмотря на то, что обе игры предлагают области для исследования, которые откроют другие области.


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

Можно пойти дальше, чтобы определить различия между DS и BofW как таковыми:

  • Окружение в DS противник
  • Окружение в BW помощник

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


Death Stranding


Ghost Recon Wildlands

И да, и нет в основном потому, что это обсуждение возможных действий.

В Ghost Recon Breakpoint основное контроль ситуации. Окружающая среда увеличивает вашу способность к маскировке и скрытности. Что означает избжать лишних рисков и ранений.

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

  • Не спотыкаться.
  • Не повредить снаряжение.
  • Не напугать BB.
  • Не потерять посылки.

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

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


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

Для BT (Твари) эмоции:

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

Они происходят по разным причинам:

  • Игрок не побежден.
  • Игрок не видит призраков, полагается на BB, а тот капризничает.
  • Лагеря МУЛов похожи на аванпосты, но игрок не может сражаться. Поэтому при обнаружении важно то, насколько быстро вы сможете убежать и спрятаться.


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

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

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



В большинстве случаев типы местности объединяются, создавая различные комбинации:







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



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





С этой точки зрения игра представляет собой хоррор:

  • Окружение агрессивно.
  • Ребенок (BB) плачет.
  • Лес населен призраками.
  • На вас охотятся мародеры.

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



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



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



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



Далее нужно выделить безопасные области вокруг целевой зоны:



Безопасные зоны, вероятно, являются наиболее трудными для пересечения. Мир Death Stranding очень искривлен и опасен:



Это должно подчеркиваться на любой высоте для каждого слоя.



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



После всего этого проиллюстрируем пути игрока:



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



Вот что произойдет:

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

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

Заставы мулов более стандартны.

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

  • Высокая трава
  • Сторожевые башни



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



NPC в этой локации несут опасность, которая заставляет игрока прокрасться, задержать дыхание и украсть или найти и убежать. Чернила Тварей это не то же самое, что силовые посохи МУЛов.



Death Stranding это свидетельством того, насколько далеко можно продвинуть уникальную концепцию, когда есть четкое видение.

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

Перевод Исправляем кривой запуск первого Mass Effect

23.11.2020 10:05:21 | Автор: admin
image

Часть 1


В последнее время я работал над собственным форком ME3Explorer [неофициальный редактор игр серии Mass Effect], содержащим множество важных улучшений и даже новые инструменты. Также я поработал над Mod Manager 5.1, который имеет удобные новые функции импорта сторонних модов, однако был отодвинут на второй план, пока я работал над новым фронтендом установщика ALOT.

ALOT Installer с манифестом 2017 года

Для его реализации я сотрудничал с CreeperLava и Aquadran; он должен упростить жизнь конечным пользователям, устанавливающим ALOT и его аддон (сторонние текстуры). Одна из моих проблем заключалась в том, что Origin не запускал игру после установки ALOT, если не запустить его с правами администратора. И поскольку запуск Origin при загрузке невозможно выполнить с правами админа, это очень раздражает. К тому же это влияет на мод MEUITM. Поэтому я начал разбираться, почему это происходит. Дело оказалось в идеальном сочетании реализации защиты, плохого кода и желания упростить жизнь других людей.

Давайте посмотрим, как работает Mass Effect с Origin в неизменённом состоянии под Windows 10.

  • Пользователь запускает MassEffect.exe. Файл немедленно запрашивает повышение прав до администраторских.
  • В конце образа MassEffect.exe есть код вызова Origin для запуска игры, это некая DRM. Он вызывает Origin, а затем выполняет выход.
  • Origin проверяет права пользователя на запуск игры, а затем запускает MassEffect.exe в соответствии с указаниями в реестре (не тот, который вы запустили сами), после чего пытается запустить исполняемый файл.
  • Origin не может запустить исполняемый файл, потому что он требует повышения прав. Чтобы DRM работала, она должна иметь возможность взаимодействия с процессом, поэтому она повышает права одного из внутренних сервисов, чтобы он мог общаться с игрой в целях DRM-защиты.
  • MassEffect.exe выполняется с правами администратора. Origin обменивается данными с MassEffect.exe и выполнение игры продолжается, как это было бы в случае с DVD-версией.

Всё это работает (через два UAC-запроса) на немодифицированной игре. Но если установить MEUITM или ALOT, то вы больше не сможете запускать игру через Origin как стандартный пользователь. Что за дела?

Сигнатуры файлов


И MEUITM, и ALOT модифицируют исполняемый файл MassEffect.exe, чтобы он мог использовать Large Address Aware. Это позволяет 32-битному процессу Mass Effect использовать до 4 ГБ ОЗУ вместо обычного 32-битного ограничения в 2 ГБ. При модификации флага LAA цифровая сигнатура MassEffect.exe оказывается поломанной сигнатура используется для проверки того, что файл не модифицирован. После модификации файла сигнатура становится неверной.

Origin при выполнении процесса с повышенными правами проверяет, подписан ли EXE компанией EA и правилен ли он. Если он не подписан EA, то он не повышает права модуля обмена данными DRM. Mass Effect загружается, а затем немедленно закрывается, потому что разблокировка DRM не работает, ведь со стороны Origin ей не с чем общаться, поскольку отказано в повышении прав.

То есть при модификации EXE Origin будет отказываться запускать исполняемый файл игры с повышенными правами. Но нам нужен LAA, поэтому необходимо как-то обойти эту проблему. Наша единственная надежда заключается в том, чтобы помешать MassEffect.exe запускаться с правами администратора. Сначала нужно разобраться, как задан его запуск с правами администратора.

Изучив манифест EXE, я увидел, что он запускается как инициатор вызова пользователь, запускающий EXE. Это означает, что этот исполняемый файл не должен требовать администраторских прав. Я проверил свои параметры совместимости, там тоже ничего не было. Каким-то образом права повышаются при запуске, но не через сам exe и не из-за моих настроек. В чём же хитрость? В Microsoft Windows Compatibility Database.

mirh (я встречался с ним в кругах любителей моддинга) провёл исследование того, почему Mass Effect вынужден запускаться с правами администратора. Он соответствует критериям базы данных в ней есть запись для Mass Effect, в которой указано, что нужно всегда принудительно запускать параметры совместимости. Это логично пользователь не должен конфигурировать параметры, если MS уже знает, какие из них работают (теоретически).


Как видите, для этой игры есть две записи MassEffect.exe (игра) и загрузчик (который, к сожалению, не включён в версию Origin). Для совместимости включается RunAsHighest (что означает права администратора). Критерии включения таковы:

  • EXE имеет название MassEffect.exe
  • Название компании в манифесте: BioWare
  • Название продукта в манифесте: Mass Effect
  • Версия продукта равна или меньше 1.2.0.0.

Эти критерии соответствуют всем известным версиям игры, в том числе, полагаю, и пиратским. Поэтому из-за совпадения всех этих критериев exe принудительно запускается с правами администратора. Это можно легко проверить, переименовав MassEffect.exe, после чего ему не потребуются администраторские права. (Однако Origin будет недоволен).

Исправление


Итак, теперь у нас есть понимание, как это исправить, но почему в базе данных есть эта запись? Поскольку Demiurge/Bioware не поддерживают идею Least User Access (LUA), Mass Effect при самом первом запуске требует прав администратора для выполнения записи в ключ реестра HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432NODE\AGEIA Technologies. Если этот ключ не существует, он пытается создать его без прав администратора у него нет для этого доступа, и игра просто вываливается. Похоже, в этом ключе содержится некая информация о том, что сейчас называется PhysX. Вероятно, запись в реестр мог внести и установщик игры, но разработчики реализовали это в самой игре.

Именно поэтому Microsoft вынуждает игру всегда запускаться с правами администратора, из-за этого единственного пункта. Это логично если заставить её запускаться под администратором, но пользователю не нужно будет беспокоиться о параметрах совместимости. Однако из-за этой комбинации трёх проблем (LAA портит сигнатуру, MS принуждает запускаться игру с правами администратора, Origin отказывается работать с процессами с повышенными правами, имеющими сломанную сигнатуру EA) Mass Effect не запускается с Origin и LAA.

Как же нам это исправить? Просто изменим в EXE название продукта с Mass Effect на Mass_Effect. Серьёзно, это всё. Проверка критериев не срабатывает, игре больше не нужны права администратора и Origin доволен (если не считать постоянного ворчания из-за обновлений). В MEUITM и ALOT Installer мы добавили код, создающий ключ реестра с правами записи для текущего пользователя, поэтому если Mass Effect нужно создать эти ключи (допустим, если его никогда не запускали), то игра будет довольна.

Часть 2


Mass Effect на PC: что ожидать от порта с консолей середины 2000-х


Если вы не знали, Mass Effect вышла на PC в 2008 году, она была портирована с Xbox 360 студией под названием Demiurge, которая также разработала Pinnacle Station для Mass Effect. Это очень посредственный порт, не особо хорошо переживший смену времён. Он приемлем как игра, но имел множество проблем даже на момент выхода. LOD частиц работали неправильно, LOD текстур считывались в обратном порядке, параметры ini случайным образом сбрасывались на значения по умолчанию проблем было довольно много. Но не было ничего, что бы полностью ломало игру.

Ну, или типа того. Была одна проблема, но вызванная не конкретно самой Mass Effect. Серьёзная проблема заключается в том, что Mass Effect требует для запуска прав администратора потому что Demiurge, похоже, считала, что все должны запускать игру как администратор это вполне могло быть приемлемым, если бы игра разрабатывалась во время, когда была только Windows XP, однако на момент выпуска игры уже больше года существовала Windows Vista. Но даже Windows XP имела концепцию LUA (Least User Access) с разделёнными аккаунтами пользователей. Подробнее об этом можно прочитать в первой части статьи.

Ух ты, PhysX, моя любимая библиотека физики!



Наверно, у меня небольшая неприязнь к этому SDK.

Mass Effect для PC работает на немного модифицированной версии Unreal Engine 3, который был выпущен примерно в конце 2006. По словам некоторых бывших разработчиков из BioWare, эта версия Unreal Engine тогда была немного сыроватой, если не сказать больше. Согласно рассказам этих разработчиков, было очень сложно работать с ней, потому что Epic Games сосредоточенно работала над Gears of War и не уделяла особо много времени своим партнёрам, тоже использующим движок.

Для расчёта физических взаимодействий Unreal Engine 3 использует PhysX, поэтому Epic Games создала dll, реализующую интерфейс между PhysX и форматами данных Unreal Engine через файл под названием PhysXLoader.dll, который загружает библиотеки PhysX с обеих сторон. PhysX это библиотека симуляции физики, приобретённая компанией AGEIA Technologies в середине 2000-х перед тем, как саму AGEIA в начале 2008 года купила Nvidia. Возможно, вы помните карты Physics Processing Unit (PPU) они использовали PhysX до того, как Nvidia похоронила эту идею.


PhysXLoader.dll, PhysXCore.dll и NxCooking.dll составляют библиотеки PhysX для Mass Effect.

Все три части Mass Effect используют PhysX, однако Mass Effect 2 и Mass Effect 3 используют установленную в систему PhysX, а Mass Effect локальную PhysX игры. Кроме того, в Mass Effect 2 и Mass Effect 3 применяется современная версия PhysX, а не устаревшая, которая была выпущена AGEIA. После приобретения Nvidia изменила некоторые пути внутри библиотеки, отделив устаревшие части от современных версий.

Но, похоже, это не мешает программе удаления старой PhysX удалять файлы/ключи реестра современной PhysX, поэтому в процессе тестирования моего исправления другие копии Mass Effect 2/3 не работали даже после установки современного дистрибутива PhysX. Очень бесит, что BioWare не смогла просто установить библиотеку на 8 МБ вместе с игрой в комплекте с игрой всё равно поставляется установщик PhysX, то есть это даже не экономило место!

Ну да ладно

Проблема PhysXLoader.dll компании Epic Games в том, что она может загружать PhysXCore.dll локально или из установленной в систему версии


Что? Как это может быть проблемой? Разве нельзя просто загружать локальную dll, и если она не существует, загружать системную? Почему это вообще проблема?


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

При запуске Mass Effect записывает в реестр Windows HKEY_LOCAL_MACHINE два значения:

REG_BINARY HKLM\SOFTWARE\AGEIA Technologies enableLocalPhysXCore [mac-адрес, 6 байт]

REG_DWORD HKLM\SOFTWARE\AGEIA Technologies EpicLocalDllHack [1]

*Mass Effect это 32-битная программа, поэтому на 64-битной системе она выполняет запись в HKLM\SOFTWARE\WOW6432Node\AGEIA Technologies (на случай, если вы захотите проверить сами).

Запомните эти значения реестра, они будут важны в дальнейшем!

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

Нам нужно изменить исполняемый файл, чтобы включить Large Address Aware, благодаря чему игра сможет загружать текстуры повышенного разрешения без переполнения памяти, поэтому нет никакого способа избежать порчи сигнатуры. Это, в свою очередь, привело к тому, что Origin больше не мог запускать игру, потому что он не может повышать права игры без правильной сигнатуры EA. Но если игра не имеет возможности записывать эти ключи реестра при запуске, то она может вылететь

Итак, это само по себе уже длинная цепь проблем, но мы обошли необходимость прав администратора в Mass Effect, просто дав аккаунту пользователя разрешение на этот конкретный ключ реестра AGEIA Technologies. Это позволит процессу игры записывать нужные ему значения. Я предполагал, что игра вылетает, потому что ей запрещался доступ для записи, а Demiurge не озаботилась написать try/catch вокруг кода записи в реестр.

Вероятно, не стоит называть значения реестра hack


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


Два значения реестра, записываемые Mass Effect.

Модератор PC Gaming Wiki под ником mirh долгие годы бил тревогу о том, что мы каким-то образом ломали другие игры в ALOT Installer, даже несмотря на то, что наше приложение никак не меняла способ записи Mass Effect этих значений, поэтом наше изменение никак не может сломать другие игры.

Спустя много месяцев он написал довольно подробное обоснование того, почему ALOT Installer (то есть на самом деле это была Mass Effect) ломает другие игры: находящийся в реестре enableLocalPhysXCore используется другими играми, работающими с PhysXLoader.dll. Когда я писал версию V4 установщика ALOT Installer, то сказал mirh, что серьёзнее рассмотрю его идею решения, не позволяющего ломать другие игры, хотя тогда я ещё не понимал, как ключ реестра с MAC-адресом системы может ломать другие игры и зачем вообще используется MAC-адрес.

Похоже, mirh был уверен, что эта enableLocalPhysXCore позволяет Mass Effect использовать PhysXCore.dll/NxCooking.dll в локальной папке, а не загружаться из установленного дистрибутива PhysX. Mass Effect не устанавливает дистрибутив PhysX, поэтому не может полагаться на её существование и вынуждена использовать локальные библиотеки.

Держитесь, теперь начинается нечто совершенно тупое:

MAC-адрес, сохраняемый в реестр файлом MassEffect.exe, считывается библиотекой PhysXLoader.dll и сравнивается с MAC-адресом вашей системы, чтобы определить, нужно ли загружать библиотеки PhysX из локальной папки или из системной.


Какой MAC-адрес?

\_()_/


Итак, Mass Effect работает следующим образом:

  1. В самом начале процесса загрузки MassEffect.exe MAC-адрес вашей системы считывается и записывается в реестр как enableLocalPhysXCore (вместе с EpicLocalDllHack)
  2. MassEffect.exe загружает PhysXLoader.dll
  3. PhysXLoader.dll считывает значение enableLocalPhysXCore и сравнивает с ним MAC-адрес вашей системы
  4. Если они совпадают, она использует PhysX из локальной папки, если нет, то версию дистрибутива PhysX из системы

Да, вы всё поняли правильно.

Оказалось, что другие игры, например, Mirrors Edge, имеют PhysXLoader.dll, которая тоже считывает эти значения (так как они основаны на одинаковом коде), но в этих играх нет локальных библиотек PhysX. Поэтому эти игры загружаются, видят enableLocalPhysXCore и пытаются загрузить локальную библиотеку, терпят неудачу и игра не запускается. Эту информацию я получил от mirh сам я не тестировал другие игры, поломанные этим значением реестра.

Обычно этого значения не существует, и игра должна использовать PhysX. Это поведение можно протестировать в Mass Effect, запретив доступ на запись к ключу реестра, удалив значения и установив старую версию PhysX она будет использовать системные библиотеки. Если системная PhysX не установлена, приложение не загрузится именно поэтому мы изначально разрешали записывать эти ключи Mass Effect, в противном случае бы казалось, что установщик портит Mass Effect, хотя на самом деле виновата ужасная реализация со стороны Epic Games.


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

Если вы реализуете интерфейс с библиотекой, имеющей экспорт, который можно вызвать для инициализации/загрузки PhysX SDK, то разве нельзя просто передать ей булево значение, приказывающее ей загрузиться локально? Почему она вообще не начинает с локального поиска? И что за дела с MAC-адресом? Почему он находится в реестре, где ведёт себя как глобальный параметр???

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

Находим начальную точку


Предупреждение: я совершенный новичок в реверс-инжиниринге. Я создавал ассемблерные моды для игр Megaman Battle Network (и написал неплохое руководство по созданию хуков), проектировал моды на ActionScript2 P-Code и работал с байт-кодом UnrealScript, но никогда не углублялся в ассемблер x86. Я множество раз открывал IDA и могу находить нужные мне вещи, но никогда не понимал их. Уверен, что для более опытных реверс-инженеров этот процесс намного проще.


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

Недавно (пару лет назад), Агентство национальной безопасности США (АНБ) выпустило Ghidra бесплатный тулкит для реверс-инжиниринга с открытыми исходниками, который может отреверсировать ассемблерный код в довольно читаемый код на C; его бесконечно проще читать, чем ассемблерные графы IDA. И IDA, и Ghidra имеют свои сильные стороны: в IDA есть отладчик, позволяющий пошагово пройти по ассемблеру и посмотреть, какие пути кода будут выполняться, а также она может находить Unicode-строки (которые используются в Mass Effect ). Ghidra может рекомпилировать ассемблерный код из его декомпилированного кода на C (иногда), имеет преобразователь из ассемблера в C (простите, не знаю его названия), обладает открытыми исходниками и работает на куче платформ и со множеством двоичных форматов.


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

Итак, в начале я знал, что Mass Effect записывает enableLocalPhysXCore и EpicLocalDllHack. Давайте начнём с изучения MassEffect.exe, найдём эти строки и посмотрим, что на них ссылается. Открыв шестнадцатеричный редактор, я знал, что это unicode-строки, поэтому я буду искать их в IDA, потому что Ghidra, похоже, не поддерживает эту функцию.


Окно IDA Strings. Я наконец узнал, что эта полезная вкладка открывается по Shift + F12.

Поискав внутри окна IDA Strings строку enableLocalPhysXCore, я её нашёл. При двойном нажатии программа переносит нас к области данных исполняемого файла, в которой она задаётся:


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

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


Режим IDA View, а не Graph View.

Изучив это, мы видим, что здесь записывается RegSetValueExW. Я очень слабый разработчик на C, поэтому после гугления я понял, что это подготовка стека для вызова на C метода из Windows API, что можно увидеть по отображаемому IDA названию параметра, например, lpData и dwType. Мы знаем, что значению enableLocalPhysXCore присваивается MAC-адрес системы. Давайте посмотрим, где выполняется это присваивание. Чтобы выглядело логичнее, переключимся на режим графа.


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


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


Эта подпроцедура содержит названия, взятые из Windows API, и они показывают нам, что это как-то связано с сетью. Нас не волнует MAC-адрес, но давайте зададим название этой подпроцедуре. Назовём её GetMacAddress. Вернёмся к исходной подпроцедуре, которую изучали, и тоже переименуем её похоже, это что-то типа SetupPhysXSDKLoad, поэтому назовём её так.


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

Вскрываем PhysXLoader.dll


Теперь мы знаем, что исполняемый файл Mass Effect никогда не считывает этот ключ; значит, это делает одна из dll. Здесь я этого не показал, но в ProcMon (отличном инструменте для моддинга и подобных вещей в целом) я вижу, что значение реестра считывается непосредственно перед загрузкой библиотеки в процессе MassEffect.exe и перед загрузкой локальной dll. Я увидел, что после того, как запретил Mass Effect доступ на запись в эту папку, он считывает системную библиотеку, и игра не загружается, если не установлена системная версия старой PhysX.

Первой из dll загружается PhysXLoader, после которой загружается PhysXCore.dll, поэтому логично будет анализировать её. Давайте откроем её в IDA и посмотрим, где там используется enableLocalPhysXCore. Также я открою эту dll в Ghidra, чтобы лучше понимать, что происходит. Проделав ту же последовательность действий по поиску мест использования строки enableLocalPhysXCore, мы находим подпроцедуру:


Подпроцедуру читать не так уж сложно, особенно в режиме графа мы видим, что есть цикл, идущий из левого блока в блок над ним. Тем не менее, всё это не так просто читать для новичка, поэтому давайте посмотрим, как это выглядит в Ghidra. Я использую адрес этой подпроцедуры, чтобы перейти к ней в Ghidra (0x10001640).


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

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

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


Мы знаем, что Mass Effect записала в реестр 6-байтный mac-адрес, и что PhysXLoader.dll просто считала это значение из реестра, и что подпроцедура сравнивает что-то побайтно 6 раз. Логически мы можем предположить, что local_14 с показанного выше изображения это MAC-адрес. Зная это, мы также можем предположить, что FUN_10001580 получает MAC-адрес и задаёт его, поэтому мы переименуем ещё несколько элементов подпроцедуры.

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


IDA показывает, что al присваивается 1 при нормальном выходе из цикла и 0 (xor al,al), если какие-то байты не совпадают. Ghidra этого не показывает, на самом деле она показывает, что возвращаемый тип равен void, что кажется ошибкой.

Немного погуглив информацию для этой части поста, я узнал, что EAX обычно используется как регистр возврата для x86, а регистр al это нижние 8 бит EAX. Я не имею достаточно опыта в Ghidra, чтобы знать, как сменить тип сигнатуры для этого вида возвращаемых нижних 8 битов; возможно, Ghidra пока этого не поддерживает, или я упустил какую-то настройку, которую нужно использовать.


Дизассемблированная подпроцедура, вызывающая ту, которая ищет enableLocalPhysXCore.

Однако если мы взглянем на ссылки на эту подпроцедуру (их две скорее всего, по одной на каждую библиотеку) в IDA и Ghidra, то увидим, что при вызове ShouldUseLocalPhysX она проверяет, не равен ли al нулю. Если он не равен нулю, то она загружает локальную PhysXCore.dll. Если равен, то она ищет библиотеку через системную установку PhysX, которая находится по ещё одному значению реестра в ключе AGEIA Technologies под названием PhysXCore Path. На самом деле это нам неинтересно, потому что мы хотим заставить PhysX всегда загружаться локально, вне зависимости от значения enableLocalPhysXCore.

Посмотрев на другую перекрёстную ссылку, можно и в самом деле увидеть, что она загружает библиотеку NxCooking, используя ShouldUseLocalPhysX таким же образом:


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

Например, если мне нужно было удалить проверку if, то мне приходилось находить способ изменить сравнения таким образом, чтобы они всегда были true или false. Один из способов возврата false проверкой if заключается в изменении ссылок на объект и токенов байт-кода сравнений, чтобы создать условный оператор вида if (objectA != objectA), всегда возвращающий false (если они не равны null). Мне нужно найти способ, чтобы в ShouldUseLocalPhysX всегда получался результат true.

Когда я писал таблицу символов для Megaman Battle Network 3, то научился всегда комментировать всё, что узнал об дизассемблированном коде. Я работал часами, совершенно забывая, что уже сделал, но мог вернуться к своим комментариям, и снова во всём разобраться.

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

Патчим худшую в мире проверку boolean



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

В x86 есть удобная однобайтная команда nop, которая в буквальном смысле не делает ничего, но занимает один байт. Также удобно то, что команда перехода в этот блок занимает 2 байта и состоит из 0x75 (jnz rel8) и 0x19 (относительного смещения).


[ЗАБАВНАЯ ИСТОРИЯ] Увидев это однобайтное смещение, я вспомнил времена, когда я работал над моддингом Megaman Battle Network. Тогда от команд перехода/ветвления зависела возможность моддинга отдельных частей ROM. При написании хука (перенаправляющего счётчик программы к вашему собственному коду) вам нужно найти команду перехода или ветвления, относительное смещение которой можно модифицировать так, чтобы оно указывало на ваш код. Затем нужно записать регистры в стек, запустить код, а затем вернуть стек обратно, чтобы подпроцедура выполняла выход правильным образом.

ARM (а конкретнее THUMB) имеет ограниченные команды ветвления, использующие в качестве относительных смещений разные размеры, которые не всегда могли перейти в любую точку ROM из-за своего местоположения в ROM. Так как игра была написана на ассемблере, находить свободное место временами было сложновато иногда приходилось соединять в цепочку несколько хуков, пока не удавалось переместить счётчик программы в свободную область, чтобы писать новый ассемблерный код. Этот jnz использует опкод 0x75, что даёт jnz rel8, то есть он может переходить только на расстояние до 128 байт (или, если переход возможен только вперёд, на 255?), что было бы настоящей проблемой, если бы я выполнял моддинг ассемблера так же, как мы работали раньше, когда не было мощных инструментов наподобие IDA и Ghidra. [КОНЕЦ ЗАБАВНОЙ ИСТОРИИ]

После замены nop-ами этого jnz наша подпроцедура ShouldUseLocalPhysX выглядит так:


Теперь в блок условия неравенства попасть нельзя. Проверка по-прежнему выполняется, но она никогда не возвращает false. Будет всегда использоваться локальное ядро PhysX.

Недостатки


Файл PhysXLoader.dll подписан Epic Games, поэтому это очевидно разрушает сигнатуру, ведь мы модифицировали файл. Игра не проверяет сигнатуры при загрузке, поэтому это не проблема. Некоторые антивирусы могут жаловаться на сломанные сигнатуры, но со временем обычно перестают. Кроме написания патча внутри памяти (как мы делаем это в загрузчике мода asi), нам нужно будет модифицировать двоичный файл библиотеки.

Получившееся поведение


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

Этот процесс оказался хорошим опытом учёбы, я намного больше узнал о Ghidra и IDA, а также о других проблемах в PC-версии Mass Effect. Этот патч автоматически применяется в процессе установки ALOT Installer, поэтому пользователям не придётся беспокоиться о задании ключа enableLocalPhysXCore. Также мы модифицировали исполняемый файл Mass Effect для записи значения enableLocalPhysXCor_, чтобы наши пропатченные версии не записывали значение, портящее игры. Ванильные исполняемые файлы Mass Effect всё равно портят другие игры, но защита программ от криво написанных загрузчиков PhysX уже не входит в мои задачи.

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

Разве добавление параметра PreferLocalSDK для PhysXLoader.dll это слишком сложно для Epic Games?
Подробнее..

Умная навигация в играх на примере Mafia Definitive Edition

25.11.2020 12:06:49 | Автор: admin

Привет Хабр! Представляю вашему вниманию перевод статьи Mafia: Definitive Editions Clever Navigation System автора Tushar Deb.

Размер игр с открытым миром становится больше с каждым новым релизом: большие карты, больше исследований и еще больше перемещений. Исключение составляют относительно линейные проекты, в которых игроки могут двигаться одними и теми же путями. Например, в серии Need for Speed или Grand Theft Auto: Vice City, где игрок быстро запоминает маленький открытый мир и легко в нем ориентируется. В противном случае искать удобный и короткий путь в опенворлде не самое увлекательное занятие.

И вот тут на помощь приходят мини-карта и метки отмечаете точку и следуете маршруту. Легко!

Red Dead Redemption 2. Метка на карте (слева) и мини-карта, направляющая к нейRed Dead Redemption 2. Метка на карте (слева) и мини-карта, направляющая к ней

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

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

В Mafia: Definitive Edition проделана огромная работа по интеграции навигационной системы в окружающую среду игры. Это дало гораздо более захватывающий опыт, который не кажется рутиной, а наоборот добавляет естественного реализма.

Mafia: Definitive Edition. Навигационный дорожный знак, указывающий прямоMafia: Definitive Edition. Навигационный дорожный знак, указывающий прямоMafia: Definitive Edition. Навигационный дорожный знак, указывающий налевоMafia: Definitive Edition. Навигационный дорожный знак, указывающий налево

Вы не найдете эту навигационную систему в оригинальной Mafia, в которой обычная система посмотрите на мини-карту, как, например, в Red Dead Redemption 2. Мир RDR2 огромен, без меток в нем не обойтись, поэтому постоянно приходится смотреть на мини-карту, отвлекаясь от происходящего на экране.

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

Когда я спешу в игре, то мой навигационный игровой опыт выглядит примерно так:

Mafia: Definitive Edition. Игровой экран и мини-карта поменялись местамиMafia: Definitive Edition. Игровой экран и мини-карта поменялись местами

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

Конечно, в других проектах тоже придумали неплохие решения. Например, в Far Cry 5 синие направляющие на дороге помогают сориентироваться, не отвлекаясь на мини-карту.

Far Cry 5. Синие направляющие к метке на картеFar Cry 5. Синие направляющие к метке на карте

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

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

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

Подробнее..

Категории

Последние комментарии

© 2006-2020, personeltest.ru