• Стоит ли заранее заботится о возможности поддержки предыдущих версий многопользовательской мобильной онлайн игры? И как?

    Tiendil
    @Tiendil
    Разработчик ПО.
    Вопрос можно разделить на два:

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

    С протоколом всё просто. Есть много вариантов, я предпочитаю такой подход:

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

    С логикой сложнее. Но тоже есть варианты:

    - Самый простой - принудительное обновление. Выкатили новый сервер, все должны обновить клиент. Наиболее просто в поддержке, если не делается топовый продукт, то лучше так и поступать - сэкономит огромное количество ресурсов. Но сесть нюансы, например, сложно добиться одновременного выхода мобильных клиентов на разных платформах (Google Play, App Store) из-за особенностей ревью, договорённостей по фичерингам, etc.
    - Запускать несколько версий сервера: старую и новую. Если игрок обновил клиент и поиграл на новой версии, старым клиентом он уже не подключится. Тут надо грамотно распределять клиентов по серверам и озаботиться непересечением разных версий игры. Например, нельзя чтобы клиенты с разными версиями играли совместно (PvP, турниры, etc).
    Ответ написан
    Комментировать
  • Стоит ли заранее заботится о возможности поддержки предыдущих версий многопользовательской мобильной онлайн игры? И как?

    @MarkusD
    все время мелю чепуху :)
    В процессе сопровождения игры может измениться протокол клиент/серверного взаимодействия или еще что-то, после чего предыдущие версии игры перестанут поддерживаться.

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

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

    В процессе обновления протокола мы обычно приходим к одному из двух вариантов:
    • Меняется именно протокол - т.е. набор и содержание пакетов.
    • Меняется сервисный код протокола - т.е. сервисный код для сериализации данных в пакеты.


    В первом случае проблем особых не возникает. Второй случай действительно приводит к нарушению совместимости.
    Чтобы в первом случае добиться совместимости между версиями клиентов и сервера, разработчик обычно использует библиотеки сериализации с поддержкой обратной (или/и прямой) совместимости.
    Примерами таких библиотек являются Google Protobuf, Google Flatbuffers и Cap'N Proto. (да, тега C++ нет, но делу это не мешает)
    Еще я сталкивался с самостоятельно разработанными решениями, которые в разной степени обладают достоинствами приведенных библиотек.

    Есть ли статистика по влиянию обязательных обновлений игры на заинтересованность пользователей?

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

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

    Если мы ведем проект для мобильных платформ, то там ситуация с обновлениями еще интереснее. Тебе никто никогда не скажет, когда в конкретном маркете обновится твоя версия клиента. Выкладка версии - это долгий процесс, синхронизировать его между разными маркетами невозможно. Если у тебя в охвате только GooglePlay и AppStore, то это еще половина проблемы. Обычно маркетов десятки, куда обязательно входит Я.Стор для Android, маркеты от Самсунга, сотовых операторов, мелких лавочников и тому подобного. А если мы заходим в Китай, то число маркетов начинает достигать сотен. И каждый из них твое приложение обновит только когда захочет.
    Это все говорит о том, что обновление сервера и мобильных клиентов - дело несинхронизируемое. Сервер сразу должен быть готов принять обновленные клиенты, поэтому его надо обновить одномоментно с выкладкой версий в маркеты. И в то же время этот новый сервер должен уметь впускать старые клиенты, потому что новые еще не прошли проверку и не выложились для скачивания пользоавтелям.

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

    Да, реально, примеры таких игр уже лет 8 с лишним бороздят просторы Appstore и GP. Названий не дам, рекламой не занимаюсь, пеарить не привык.
    Я в своей работе использую Cap'N Proto и Flatbuffers. Эти две библиотеки покрывают задачи обратной совместимости для протокола и бинарных ресурсов. Использования этих библиотек хватает для свободы изменять данные не боясь потерять клиентов.
    В общем, для решения этой проблемы нужны инструменты обеспечения обратной и прямой совместимости.

    Важно понимать, что совместимость обеспечивать надо не только для протокола, но и для ресурсов клиента.
    Ресурсы могут быть залиты на локальный CDN провайдера пользователя и поставляться по каналу связи с льготным тарифом, но у пользователя может не быть возможности зайти в Appstore и обновить само приложение клиента.
    Поэтому, старый клиент должен иметь возможность запускаться с новыми ресурсами в режиме совместимости.
    Именно эту задачу и решает библиотека Flatbuffers. Она дает возможность обновлять формат бинарных данных вперед и сохранять очень эффективный доступ к ним через старую версию формата.

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

    Может ли задача сопровождения предыдущих версий сильно влиять на архитектуру ПО, скорость и процесс разработки?

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

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

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