Мы продолжаем рассказывать о применении облака Microsoft для компаний-разработчиков решений (ISV). В этом выпуске мы представляем историю от компании Badge Keeper, создающую конструктор системы достижений. Пожалуйста, оставляйте свою обратную связь в комментариях.

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

Откуда взялась идея

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

Поиски готовых решений

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

  • Google Achievements. Может быть использовано для приложения, даже если оно не опубликовано в Google Play.Что смутило: а) Заточка достижений под игры, даже при заведении приложения просят указать «название игры» и «категорию игры». Если финансовое приложение называть игрой, то категория подойдет разве что «приключения»б) По принципу использования достижений не понравился тот момент, что необходим везде оперировать ID достижения, что не всегда удобно.в) При первой регистрации в Google Play и оплате developer account, возникла непонятная проблема с проведением платежа, которую служба поддержки решала в течение нескольких дней, что также сыграло свою роль для продолжения поисков
  • Apple Achievements. Невозможность использовать на других платформах отличных от iOS SDK. Этот момент был важен, т.к. я планировал выпустить веб-интерфейс к своему приложению, и тогда потребовалось бы дублировать логику достижений вручную.
  • Steam achievements. Доступно для игр, которые публикуются в сервисе Steam.
  • Sony trophies. Доступно для игр, которые публикуются в Sony Playstation Store
  • Hydra. Сервис заинтересовал описанием имеющейся функциональности, но на текущий момент находится в закрытой бете и посмотреть его не удалось.
  • App 24. Сервис подошел по описанию, но достижения не были его основной функциональностью. Также предоставлялись другие ненужные нам сервисы, интерфейс довольно перегружен.

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

Не хотим делать сами, хотим сервис

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

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

Прототип за 2 месяца

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

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

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

Как устроен сервис

Теперь несколько слов о том, как мы построили сервис.
Решение решили разрабатывать в облаке. Выбор пал в сторону Microsoft Azure, и вот почему:
  • Уже было успешно разработано одно решение, работающее в Azure, соответственно был опыт;
  • Мы не хотели отвлекаться на администрирование, соответственно взять PAAS было оптимальным решением;
  • У Microsoft есть замечательная программа BizSpark, которая дает как лицензированное ПО, так и некоторое количество денег на Microsoft Azure.

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

Итого, необходимо:
  • Backend, работающий на Asp.Net Web API;
  • Azure WebJob, работающий в паре с Backend;
  • Frontend, работающий на Asp.Net MVC + AngularJS;
  • SQL Database, для хранения основной информации по клиентам, а также для предоставления статистики пользователям;
  • Azure Table storage, для быстрых операций записи и выборки данных (об этом чуть подробнее ниже);
  • Azure Queue storage, для отложенной записи аналитических данных по пользователям.

А вот и общая схема в действии:



Теперь несколько слов о том, почему мы начали использовать Azure Storage (Table & Queue). Сначала мы использовали SQL Database для записи и чтения данных. Но после проведенных нагрузочных тестов решили посмотреть другие решения. Дело в том, что Azure SQL ограничена DTU (Database Throughput Unit), что для нас явилось критическим моментом. Azure Storage имеет совершенно другие показатели производительности при вставке и чтении данных. Для этого, конечно, пришлось очень хорошо подумать над Partition Key & Row Key, тем не менее, после перехода на Azure Storage результаты стали гораздо лучше.

Azure Queue Storage используется для задачи сбора и предоставления аналитики. В нашем сервисе мы планируем уделить особое внимание этому вопросу и дать клиентам возможность получать такие отчёты, как «процент пользователей с открытыми/закрытыми достижениями», «скорость получения достижения», «количество попыток для открытия достижения» и другую полезную статистику. Такая отчётность позволит проверить заданные условия для получения достижений на тему их сложности и внести правки до выхода в боевом режиме. Как вариант, все это также можно было складывать в Azure Table, только вот строить гибкие запросы очень даже проблематично. Поэтому в Web Job мы отлавливаем момент, когда в Azure Table storage идет запись данных и добавляем в очередь задание по записи данных в SQL Database. Теперь мы не создаем дополнительных задержек для работы в основном сервисе, а пользователь получает ту же самую статистику практически в режиме реального времени. Небольшая задержка конечно может быть, в зависимости от того, когда job среагирует, но происходит это практически мгновенно, да и нет необходимости отдавать аналитику в реальном времени.

Как работает сервис со стороны клиента

Для каждого достижения необходимо задать условие его получения. Мы построили сервис так, что условие можно задать в виде формулы, например, scores >= 150. Scores это то, что присылает приложение POST запросом. В запросе также приходит уникальный ключ клиента (пользователя приложения). При получении запроса от приложения мы проверяем значение у переменной scores для данного клиента, и если оно больше значения указанного в условии какого-либо достижения (одном или нескольких), то сервис вернёт ответ о полученном достижении. Можно задавать и более сложные условия, такие как:

level5_kills = 25 and level = 5 and (health >= 90 and health <= 100)

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

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

Как это выглядит

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

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


 
А вот как выглядит одно достижение в режиме редактирования.


 
На демонстрационной странице можно посмотреть, как это работает на демонстрационном проекте. Для этого мы взяли игру «Змейка» на JavaScript и подключили её к сервису.
 
Как насчёт тех, кто не занимается разработкой игр?

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

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

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

Планируете создать ещё одного убийцу сервиса Kongregate.com? Подключайте свою платформу к Badge Keeper и предоставляйте вашим клиентам встроенные средства для создания кросс-платформенной системы достижений.
 
Заключение

Несмотря на наличие готовых решений, особенно от таких гигантов как Apple и Google, мы считаем, что данный сервис имеет право на жизнь за счет более простого использования, меньшей связки бизнес-логики достижений с вашим приложением, а также расширенных возможностей самих достижений.
 
После этого короткого этапа разработки набрался список «хотелок», которые мы хотели бы видеть в сервисе. Уверены, что нам найдется что предложить другим командам, которые также, как и мы, не хотят тратить своё бесценное время на вспомогательную механику и сосредоточиться на разработке основной функциональности своего приложения.
 
Прежде чем продолжать разработку, хочется получить обратную связь и понять, что может быть востребовано еще, возможно, мы что-то не учли в своей работе. Мы открыты для запросов на добавление фич, если это не идет вразрез с основной идеологией сервиса. Если сервис вас заинтересовал, но вы не нашли в описании необходимой функциональности, то будем рады услышать об этом в комментариях к статье или в сообщении на форме обратной связи. Если вам понравилась идея сервиса и вам было бы интересно следить за новостями проекта, то присоединяйтесь к нам в Твиттере, чтобы быть в курсе происходящего. 

Спасибо за внимание! Будем благодарны любой обратной связи, вопросам и комментариям.

Комментарии (0)