Как горшки обжигаются
Поработаем!

Мы, группа разработчиков в Unity3D/Photon, рассмотрим заказы на такую внештатную работу:

Низкополигональное 3D моделирование отдельных объектов и частей игровых миров c LOD, развертками и т.п.;
Производство, оптимизация и обфускация игровой клиент-серверной логики C#, средней и высокой сложности;
Проектирование схемы, системы запросов, хранимых процедур, создание готовых моделей баз данных игры на основе Microsoft SQL;
Интеграция автомобильных физических моделей и других сторонних фреймворков в имеющийся проект;
Разработка техзаданий и отдельных алгоритмов в широком спектре задач по созданию игровых приложений;
Проведение экспертизы техзаданий и проделанных работ, оценка производительности, оценка устойчивости системы ко взлому;
Предложим методы сокращении расходов при разработке приложений на основе вашего бизнес-плана;


Немало скриншотов из игры можно увидеть в галерее.

Контактаня почта: mehanos@mehanos.ru
Постоянная ссылка на проект: http://mehanos.ru


Тестдрайв

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



Ниже по тексту можно найти и другие варианты игровых карт.


Начало

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

Браузерный принцип - вся информация хранится на сервере, а клиент скачивает только то, что требуется;
Реалистичный внешний вид (Unity3D) и гибкий GUI;
Возможность многопользовательской игры (Photon server, MsSQL);
Реальная симуляция физики автомобилей (не аркадность);
Заложение основы для масштабируемости системы;
Удобное администрирование и отладка возникающих проблем со стороны клиента и сервера;
Всего этого удалось добиться , хотя задача оказалась намного сложнее.


Технологии

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

Ниже рассказано немного подробнее об рассматриваемых приемах.


Браузерный принцип

Минимизация скачиваемого контента;
Иерархическая система логических объектов;
Приницип разбиения больших сцен через подобъекты;
Система передачи данных об объектах;


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

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

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



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

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

     В итоге, для всех потребмностей была разработана иерархическая система логических объектов Avatar Item Reference Asset, с которой работает система закачки информации и медиа-образцов для этой системы, оптимизированная для мнимизации необходимого времени от запроса объекта у сарвера до его появления в сцене.


Реалистичный внешний вид

Разработка своего GUI на основе XML конфигурации;
Использование Bitmap шрифтов;
Изготовление низкополигональных моделей с LOD;
Статическое запекание (static batching) элементов сцены;
Группы качества для объектов игровой карты;
Регуляция общего качества сцены по настройкам игрока;


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

     Моделлеры и программисты начали создавать различные игровые карты, применяя различные технологии, в конце концов мы добились плотности в ~8500 игрвых объектов, при размере карты 11 мегабайт, причем многие текстуры имеют разрешение 1024х1024. Эта карта называется Порт, на ней была широко внедрена система детализации, что позволяет на каждом лучшем уровне качества сцены отображать все больше объектов. Средние видеокарты легко освоят первые 4 уровня качества, ну а уровни Прекрасно и Фантастично могут потребовать немного апгрейда .

По нажатию на одну из картинок ниже, можно прокатиться по карте Порт:



     При всем великолепии работы с 3D графикой, на экран нужно выводить еще и 2D элементы пользовательского интерфейса - GUI, и вот тут нас ожидала неожиданность, оказалось, что в Unity несовершенная система GUI, поэтому была разработана собственная, высокооптимизированная, по обращению напоминающая Winforms. Для того, чтобы разделить программирование с дизайном, была создана система конфигурации для элементов сцен на основе XML, а чтобы не добавлять в Web клиента Unity библиотеку System.Xml, объемом более 1 мегабайта, под нужды работы с GUI используется очень простой XML парсер.


Мультиплеер

Многопользовательское приложение;
Онлайн отображение изменений аватаров за счет системы ревизий;
Система записи и воспроизведения проездов игроков;
Система синхронизации положения игроков;
Реализация механизма столкновения автомашин игроков;
Возможность персонифицировать контент;
Создание внутри игрового чата;
Cоздание специальных схем авторизации с защитой данных игровой сессии;


     Этот аспект системы потребовал выбора сервера, вначале мы написали и потестировали JAVA прототип, но разделение программистов на C# и JAVA было ошибкой, так что мы решили перейти на C# вариант, причем подобрать имеющийся фреймворк, обеспечивающий хороший базовый функционал, умеющий UDP и выбор быстро пал он на ExitGames Photon Server, а в качестве хранилища данных, инициализирующих игровой мир во время включения сервера, была использовна база MsSQL.

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

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

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



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

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

    
    
    
    


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

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


Физика

Прототипирование подключаемых модулей;
Интеграция физических фреймворков в проект;
Оценка работы физических моделей автомобилей;


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

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

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


Масштабируемость

Cоздание лобби системы;
Зоны видимости игроков и объектов игровых карт;
Оптимизация пакетов перемещения;


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

     Понять насколько масштабируема система можно через анализ ее основных узких мест. Несколько таких мест можно указать заранее:
а)
Ограничение по объему передаваемого траффика от клиента к серверу;
б)
Ограничение по количеству клиентов на один сервер;
в)
Ограничение по скорости отдачи информации серверу базой данных (Web и Игровым серверам);


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

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

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

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

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

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


Администрирование

Онлайн применение параметров физики;
Запись трейслогов действий игрока;
Создание обратной связи между базой данныхм и игровым сервером;
Создание расширенных хранимых процедур на основе CLR;
Ограничение использования читов в автогонках;


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

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

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

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



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