[Перевод] Одна игра, один разработчик, шесть платформ

504d4662f6de3289540d23271ed8ca1e.png

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

Думаю, буду полезно написать пост с перечислением полученных мной уроков. Надеюсь, он поможет другим инди-разработчикам в выборе поддерживаемых платформ. Небольшое предисловие: моя собственная игра Industry Idle по большей мере разрабатывалась на основе на веб-технологий (WebGL + TypeScript). Это означает, что поддержка разных платформ — относительно простая задача, мне не приходится иметь дело с платформенными графическими API (DirectX, OpenGL, Vulkan, Metal) и в основном игра существует в браузерной «песочнице». Это практически идеальная ситуация для кросс-платформенной поддержки. Тем не менее, меня постоянно удивляют и одолевают проблемы, связанные с отдельными платформами.

Веб

Хорошее

Если бы меня попросили выбрать платформу «первого класса» для Industry Idle, то это был бы веб. В процессе разработки я запускал игру в своём веб-браузере, поэтому поддержка веба реализовывалась «автоматически». Сама платформа не требует особой возни: можно запросто настроить конвейер автоматизированной сборки, выполняющий развёртывание на страницах Github/CloudFlare, которые по большей мере бесплатны.

Плохое

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

Ужасное

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

TL; DR: не особо много труда по поддержке, но не так много привлечённых игроков

Windows (Steam)

Хорошее

Steam — единственный магазин, в котором была выпущена игра. Я отправил заявку и в Epic Game Store, но так и не получил ответа — возможно, это и хорошо, ведь интеграция ещё одного SDK, скорее всего, не стоила бы приложенных усилий. На 2023 год Windows по-прежнему остаётся доминирующей платформой для геймеров. Примерно 99% всех десктопных игроков играют в Windows. Платформа имеет относительно стабильный API — Microsoft почти никогда не ломает обратную совместимость. Настраивать конвейер автоматизированной сборки относительно просто — я собираю версию для Windows на своём Linux-сервере.

Плохое

В качестве среды исполнения игра использует Electron. Однако для интеграции с Steam SDK (который написан на C++) я использовал несколько решений:  greenworks (уже не поддерживается), Node-API (при помощи node-addon-api; требует настройки кросс-платформенного тулчейна C++ и ручного написания привязок),  Koffi (модуль FFI для Node.JS, предоставляет уже скомпилированные двоичные файлы, но требует прописывать привязки вручную) и, наконец, steamworks.js (вызывает Steamworks через привязки Rust).

Ужасное

Относительно количества игроков проблем возникало довольно мало, но время от времени мне приходилось решать очень загадочные проблемы, например, с установленной старой версией Visual C++ Redistributable или с «урезанной» версией Windows, в которой отсутствовали некоторые DLL. К тому же многие игроки в Windows не особо разбираются в технике, что усложняло отладку. Но на самом деле жаловаться особо не приходится — процент людей, столкнувшихся с проблемами платформы, в Windows, вероятно, ниже всего.

TL; DR: отсутствие поддержки Windows недопустимо, но, к счастью, реализовать её относительно просто

macOS (Steam)

Хорошее

Когда я написал первую строку кода Industry Idle, я работал на Mac. Я давний пользователь Mac и перешёл на Windows, только углубившись в разработку игр. Пользователи Mac составляют лишь 1% от всех десктопных игроков, но часто люди приятно удивляются тому, что игра работает на Mac, и я получил множество писем с благодарностями по этому поводу. Ещё одно хорошее свойство системы заключается в том, что сборка x64 практически без проблем работает с Mac на Apple Silicon — у меня нет Apple Silicon Mac, поэтому игра имеет только сборку x64, но многие благодарственные письма я получил от владельцев Apple Silicon Mac, хотя на самом деле, наверно, им стоит поблагодарить Rosetta. Работа в режиме эмуляции — неидеальное решение, но игра настолько нетребовательна, что мощный Apple Silicon может с лёгкостью справиться с дополнительной нагрузкой в виде эмуляции.

Плохое

Mac — одна из самых проблематичных платформ: даже после того, как Electron решил большинство специфичных для платформы проблем, остаётся множество тонкостей:

  • Подписывание кода с hardened runtime практически обязательно.

  • Однако Steamworks SDK загружает dylib, которая требует множество entitlement exception. Они плохо задокументированы, так что удачи вам в поиске того, какие из них необходимы. И вам остаётся лишь надеяться, что Apple однажды не запретит эти исключения.

  • Подписав исполняемый файл, я должен отправить его на проверку. Старый API нотаризации очень медленный (процесс загрузки исполняемого файла на 200 МБ занимает от получаса до нескольких часов), склонен к произвольным вылетам и почти никогда не выдаёт осмысленных сообщений об ошибках. Новый «notarytool» существенно улучшил ситуацию, но всё равно добавляет десять минут к конвейеру сборки. Для сравнения: суммарно конвейер «Windows + Linux + macOS + загрузка в Steam» без подписывания кода и проверки занимает примерно 2–3 минуты.

  • Разумеется, описанный выше процесс необходимо выполнять на Mac (хотя уже появляется ограниченная экспериментальная поддержка без необходимости Mac), что крайне плохо для автоматизации сборки. Мне пришлось прописать в скрипте сборки кучу хаков наподобие security unlock-keychain, но у него всё равно время от времени возникают сбои.

  • И стоит помнить о том, что это почти идеальный сценарий: не требуется никакого портирования платформенных API (например, преобразования из DirectX/Vulkan в Metal).

Ужасное

Экономика поддержки Mac для инди-разработчиков совершенно непривлекательна. Mac практически необходим, а они дороги. Весь доход от платформы не покрывает и 10% затрат на самый дешёвый Mac Mini. К тому же существует ежегодный платёж разработчика в размере $100 за нотаризацию. К счастью, его можно использовать и для iOS. Кроме того, Apple более склонна к нарушению обратной совместимости. Иногда появляются требования новых версий macOS/XCode, для чего необходимо обновить операционную систему (это занимает 1–2 часа и временами заканчивается неудачей) и XCode (занимает два и больше часа; обычно я оставляю установку на ночь).

TL; DR: не стоит времени и денег, определённо не стоит всех мучений

Linux (в том числе и Steam Deck)

Хорошее

Linux нетребователен к оборудованию, он работает на чём угодно и бесплатен. На моей машине для разработки в виртуальной машине установлен Arch Linux для тестирования игры. Также для создания исполняемых файлов на моей машине для сборок установлен Ubuntu. А на сервере есть VPS с Debian. Linux очень легко автоматизировать.

Плохое

Linux очень насыщен, а операционные системы могут быть очень разными. Изначально я вообще не мог запустить игру. На самом деле, не запускалось даже пустое приложение Electron (из официального примера). Потратив несколько часов на гугление, я выяснил, что добавление аргумента --no-sandbox решает проблему для некоторых пользователей, но не для всех. Впрочем, этого следовало ожидать, ведь невозможно узнать, какие библиотеки установлены в операционной системе и какой они версии. Мне бы хотелось, чтобы Steam позволил указывать, что «поддержка Linux реализована по мере возможностей», но такого варианта нет — чтобы отправить сборку под Linux, я вынужден поставить флажок, что иногда приводит к ошибочным ожиданиям пользователей.

После выпуска Steam Deck я думал, что его поддержка будет автоматической, в конце концов, у меня ведь сборка для Linux, но всё оказалось не так. Выяснилось, что если игра не помечена явным образом (модераторами Valve), то Steam Deck использует сборку для Windows + Proton, даже если доступна версия для Linux. А версия для Linux используется с Steam Runtime — относительно ограниченным набором библиотек, которые разработчики могут применять как целевые. Это хорошее решение проблемы с огромным количеством библиотек Linux, но, к сожалению в этом наборе отсутствует множество библиотек для запуска Electron. Но стоит отдать Valve должное: компания быстро отреагировала, в конечном итоге решив проблему.

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

Ужасное

Пользователи Linux составляют меньше 1% от общего количества игроков, так что с точки зрения бизнеса усилия того не стоят. И эта платформа имеет наивысший процент игроков, сталкивающихся с платформенными проблемами — время, которое тратится на клиентскую поддержку, лишь ухудшает экономику. Кроме того, у меня нет Steam Deck, так что добавлять его поддержку не всегда просто: Valve не предоставляет образ SteamOS для тестирования. Поэтому невозможно выполнить сквозное тестирование кода, специфичного для Steam Deck (например, поддержку контроллера, запуск игры в полном экране, увеличение UI и так далее). Я пользовался HoloISO, но с переменным успехом.

TL; DR: экономика ещё хуже, чем для Mac, но, наверно, меньше возни

iOS

Хорошее

Базовый движок Industry Idle — это, по сути, мобильный движок, до Industry Idle я в основном делал мобильные игры. Однако Industry Idle в первую очередь рассчитана на десктопы, то есть для портирования на мобильные требуется изменение UI. В iOS игра работает в WkWebView с вспомогательным кодом, раскрывающим нативные API (наподобие Game Center). В общем случае оборудование и ПО iOS менее разнообразно по сравнению с Android, то есть после тестирования игры на моём старом iPhone 6 я могу быть практически уверен, что игра будет хорошо работать на большинстве устройств с iOS.

Базовая игра Industry Idle распространяется как free-to-play, к ней можно купить два пакета расширений (Expansion Pack) (единовременная покупка, не подписка), как и для Steam. Есть только одна необязательная реклама в формате «видео для вознаграждения», позволяющая удвоить офлайн-доход. В игре нет микротранзакций, я не люблю мобильные игры с кучей рекламы, которые активно подталкивают к микротранзакциям.

iOS по сравнению с Android — это более «элитная» мобильная платформа, поэтому в ней пакеты расширений купило больше игроков. Несмотря на то, что пользователи iOS составляют всего около 30% от всех мобильных игроков, она принесла примерно 50% от всего дохода на мобильных. Кроме того, приятный побочный эффект системы «огороженного сада» Apple заключается в том, что на iOS наименьший процент читеров.

Я знаю, что многие жалуются на App Review в iOS. Мне кажется, ситуация сильно улучшилась. Приложения проверяют довольно быстро (1–2 дня), а если проверяющий отклоняет обновление по бессмысленным причинам, то быстрый ответ обычно решает проблему. Например, однажды обновление отклонили за отсутствие кнопки «Восстановить покупку». В ответ я отправил проверяющему скриншот, показывающий, где найти эту кнопку, а также мягко указал ему на то, что эта кнопка была там с первого релиза, то есть более пятидесяти релизов назад. Обновление одобрили на следующий день. В момент первого релиза игра была отклонена за «копирование уже существующей игры». Оказалось, проверяющий AppStore посчитал, что я «спиратил» Steam-версию Industry Idle. В конечном итоге я создал на официальном сайте секретную веб-страницу, показав проверяющему, что именно я разработал Steam-версию. Релиз своевременно одобрили. То, что приложения AppStore проверяют живые люди — обоюдоострый меч. С одной стороны, люди совершают ошибки, что приводит к лишним неприятностям. С другой стороны, с живым человеком легко поговорить и решить проблемы. В отличие от AppStore, Google Play сильно автоматизирован и в нём очень сложно найти человека.

Плохое

WkWebView — единственный web view в iOS и его обновление привязано к обновлению iOS. Apple уже давно завершила поддержку iPhone 6, поэтому я вынужден использовать iOS 12 и довольно древний WkWebView. К счастью, у большинства игроков гораздо более новые iPhone, что помогает решить проблему.

Как и в случае разработки для macOS, при разработке для iOS требуется Mac, а также ежегодная плата разработчика в размере $100. Думаю, суммарный доход от iOS и macOS (95% которого получено от iOS) едва покрывает затраты на оплату и самый дешёвый Mac Mini. Кроме того, для тестирования, предположительно, нужен iPhone, то есть мы уйдём в минус. К счастью, у меня был старый Macbook и iPhone, поэтому деньги тратить не пришлось.

Как и macOS, iOS не очень подходит для автоматизации сборки. Частично это вызвано тем, что сборку мне приходилось делать на Mac, частично из-за нестабильности конвейера автоматизации. Fastlane позволяет экономить ужасно много времени, однако он иногда сбоит (требуется 2FA или сервер Apple находится офлайн) и требует ручного вмешательства. Из-за этого я не создаю бета-сборки для iOS и macOS.

Ужасное

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

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

TL; DR: 50% поддержка мобильных — это поддержка iOS

Android

Хорошее

В версии для Android используется встроенный WebView, и Google хорошо справляется с поддержанием его актуальности. Так как он не привязан к обновлениям операционной системы, больший процент игроков на Android имеет относительно новую версию. Однако того же нельзя сказать о самой операционной системе и оборудовании; подробнее я расскажу об этом ниже. Конвейер автоматизированной сборки Android (под управлением Fastlane) гораздо быстрее и стабильнее — он работает в Windows, Mac и Linux, а командная строка имеет первоклассную поддержку. Устройства Android обычно дешевле, к тому же я использую Android повседневно, так что здесь дополнительная экономия! Как говорилось выше, в Google Play используется множество автоматизированных проверок, поэтому если всё хорошо, контроль обновлений обычно происходит быстрее (несколько часов).

Плохое

Операционная система и оборудование Android — это настоящий хаос! Существует множество разного оборудования, работающего с разными версиями ОС, которые могут иметь странные изменения, внесённые производителями телефонов. С WebView обычно проблем не возникает, но нативные API очень запутаны — одинаковый API может вести себя очень по-разному на разных устройствах (например, когда появился display cutout API, он слабо поддерживался и у каждого производителя были собственные особенности). Моя стратегия проста: я тестирую игру на своём телефоне и надеюсь, что она будет хорошо работать на других устройствах.

К тому же у Android используется довольно агрессивная стратегия устаревания API. Google Play требует достаточно свежей targetSdkVersion и отклоняет обновление приложения, если один из сторонних SDK устарел. Это значит, что я должен постоянно запускать Android Studio и обновлять версии Android и SDK (а иногда и версии Kotlin с Gradle). Обычно проект отказывается компилироваться, из-за чего приходится тратить много часов на исправления и тестирование. Это случается не каждый день, но достаточно часто, чтобы раздражать. Для сравнения: после первого релиза игры мне пришлось, наверно, всего дважды открыть XCode и обновить нативный код на Swift.

Ужасное

Пользователи Android составляют примерно 70% от всех мобильных игроков, но доход примерно такой же, как и на iOS. Немногие люди покупают пакеты расширений и наибольший доход поступает от одной опциональной видеорекламы. Реализация рекламы в Android, похоже, довольно забагованная, потому что иногда она не появляется после переключения игры в фоновый режим и для её возврата требуется перезагрузка телефона. Мне на это жаловались пользователи! Однако мне так и не удалось разобраться в причинах, частично потому, что я не смог воссоздать баг на своём телефоне, частично потому, что хочу тратить время на разработку игры, а не на отладку какого-то недоработанного рекламного SDK.

TL; DR: остальные 50% поддержки мобильных — это поддержка Android

Заключение

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

© Habrahabr.ru