Кроссплатформенная разработка
Одна игра, один человек, шесть платформ: хорошие, плохие, злые
Это практически идеальный сценарий, когда речь идет о кроссплатформенной поддержке. Тем не менее, меня постоянно удивляют и беспокоят проблемы, связанные с конкретными платформами.
Недавно компания Valve объявила, что Counter-Strike 2 больше не будет поддерживать macOS. Как инди-разработчик, выпустивший игру с поддержкой macOS, я сначала удивился решению Valve. Но, вспомнив свой собственный путь поддержки шести платформ, я думаю, что могу понять точку зрения Valve.
Я считаю, что полезно записать некоторые из моих «извлеченных уроков», которые, надеюсь, помогут другим инди-разработчикам выбрать, какие платформы поддерживать. Немного предыстории: моя собственная игра Industry Idle в основном построена на веб-технологиях (WebGL + TypeScript). Это означает, что поддержка различных платформ сравнительно проста — мне не приходится иметь дело с графическими API, специфичными для конкретной платформы (DirectX, OpenGL, Vulkan, Metal), и я в основном живу внутри браузерной песочницы. Это практически идеальный сценарий, когда речь идет о кроссплатформенной поддержке. Тем не менее, меня постоянно удивляют и беспокоят проблемы, связанные с конкретными платформами.
Web
Хорошо
Если бы меня попросили выбрать «первоклассную» платформу для 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 более или менее «просто работает» на Apple Silicon Mac — у меня нет Apple Silicon, и игра имеет только сборку x64, но несколько писем со «спасибо» я получил от владельцев Apple Silicon — думаю, они действительно должны благодарить Rosetta. Работа в режиме эмуляции не совсем идеальна, но игра работает даже на слабых машинах, так что мощный Apple Silicon легко справится с ней даже с учетом накладных расходов на эмуляцию.
Плохо
Mac — одна из самых проблемных платформ. Даже после того, как Electron справился с большинством специфических для платформы проблем, остается множество:
- Подписание кода с использованием Hardened Runtime практически обязательно.
- Однако Steamworks SDK загружает dylib, которая требует исключительных прав доступа. Это не очень хорошо документировано, так что удачи вам в выяснении, каких именно. И скрестим пальцы, что Apple в один прекрасный день не запретит эти исключения.
- После подписания исполняемого файла необходимо заверить его нотариально. Старый API для нотариального заверения занимает целую вечность (для исполняемого файла размером 200 МБ — от 30 минут до нескольких часов), дает случайные сбои и почти никогда не выдает осмысленных сообщений об ошибках. Новый «notarytool» значительно улучшен, но все еще добавляет 10 минут к конвейеру сборки. Для сравнения, весь конвейер «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 (занимает 2+ часа, я обычно просто оставляю его на ночь).
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 (например, поддержка контроллеров, запуск игры в полноэкранном режиме, увеличение размера пользовательского интерфейса и т.д.), невозможно тестировать в сквозном режиме. Я использовал HoloISO с ограниченным успехом.
TL;DR: Экономия еще хуже, чем на Mac, но раздражения, возможно, меньше.
iOS
Хорошо
Основной движок Industry Idle на самом деле является мобильным — до Industry Idle я в основном делал игры для мобильных устройств. Однако Industry Idle — это игра для настольных компьютеров, а значит, перенос на мобильные устройства требует довольно серьезной корректировки пользовательского интерфейса. На iOS игра работает в пользовательском WkWebView с некоторым связующим кодом, который открывает нативные API (например, Game Center). Аппаратное и программное обеспечение iOS в целом менее разнообразно по сравнению с Android, поэтому после тестирования игры на моем устаревшем iPhone 6 у меня есть большая уверенность, что игра будет отлично работать на большинстве других iOS-устройств.
Базовая игра Industry Idle — free-to-play, а два пакета расширений можно приобрести (одноразовая покупка, не подписка) — так же, как и в Steam. В игре есть только одна опциональная вознаграждающая реклама, которая позволяет игроку удвоить оффлайн-доход за счет просмотра рекламы. В игре нет микротранзакций — мне не нравятся мобильные игры, которые изобилуют рекламой или очень назойливо предлагают микротранзакции.
iOS, как правило, является более «премиальной» мобильной платформой по сравнению с Android, а это значит, что больше игроков приобретают пакеты расширений по сравнению с Android. Несмотря на то, что на iOS приходится лишь около 30% всех мобильных игроков, она приносит около 50% всех мобильных доходов. Также приятным побочным эффектом «огороженного сада» Apple является то, что на iOS самый низкий процент читеров.
Я знаю, что было много жалоб на App Review на iOS. На мой взгляд, ситуация значительно улучшилась. Время рассмотрения сравнительно небольшое (1-2 дня), и если рецензент отклоняет обновление по нелепым причинам, то быстрый ответ обычно решает проблему. Например, однажды обновление было отклонено из-за отсутствия кнопки «Восстановить покупку». В ответ я сообщил рецензенту, где можно найти эту кнопку, приложив скриншот, а также мягко указал на то, что эта кнопка была там с самого первого релиза, то есть более 50 релизов назад. Обновление было одобрено на следующий день. При первоначальном выпуске игра была отклонена по причине «копирования существующей игры». Оказалось, что рецензент App Store посчитал, что я «пирачу» Steam-версию Industry Idle. В итоге я разместил на официальном сайте секретную веб-страницу, на которой сообщил рецензенту, что я действительно являюсь разработчиком Steam-версии. Релиз был своевременно одобрен. То, что в App Store есть люди-рецензенты, — это обоюдоострый меч. С одной стороны, люди допускают ошибки, что вызывает ненужное раздражение. С другой стороны, можно легко поговорить с человеком и решить все вопросы. По сравнению с Google Play, где очень много машин и очень трудно найти человека для решения проблемы.
Плохо
WkWebView
— единственный разрешенный веб-просмотр на 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 Server не работает) и требует ручного вмешательства. Из-за этого я не создаю бета-сборки iOS и macOS.
Злит
Мобильные устройства — это совсем другая платформа по сравнению с десктопами. Несмотря на то, что у них очень большая аудитория, для ее охвата обычно требуется платное привлечение пользователей (т.е. трата денег на покупку рекламы). У меня нулевой маркетинговый бюджет: многие игроки узнают об игре на других платформах, многие присоединяются к ней через друзей (сарафанное радио), а однажды был всплеск загрузок, который, как я могу предположить, был связан с редакцией или алгоритмом App Store. Поскольку мне ничего об этом не говорили, я не могу это подтвердить.
Отсутствие назойливой рекламы и назойливых микротранзакций обеспечивает хороший опыт игры на мобильных устройствах. Однако это означает, что доходы от мобильной версии ничтожны: они составляют лишь малую часть от доходов настольных версий, хотя количество игроков гораздо выше.
TL;DR: 50% поддержки мобильных устройств — это поддержка iOS.
Android
Хорошо
В версии для Android используется встроенный WebView, и Google прилагает все усилия для поддержания его в актуальном состоянии. Поскольку он не привязан к обновлению ОС, больший процент игроков на Android имеет относительно свежую версию. Однако то же самое нельзя сказать о самой операционной системе и аппаратном обеспечении, к которому я перейду позже. Автоматизированный конвейер сборки Android (на базе Fastlane) гораздо быстрее и стабильнее — он работает на Windows, Mac и Linux, и все через командную строку. Устройства на базе Android обычно дешевле в приобретении — я использую Android в качестве повседневного телефона, так что это дополнительная экономия для меня! Как уже упоминалось, в Google Play используется большое количество машинных проверок, поэтому проверка обновлений происходит быстрее (в течение нескольких часов), если все прошло успешно.
Плохо
ОС Android и аппаратное обеспечение — это сплошной хаос! Существует множество различных аппаратных средств, каждое из которых может работать под управлением различных версий ОС, которые могут иметь странные настройки от производителей. WebView в целом работает нормально, но нативные API очень запутаны — один и тот же API может вести себя очень по-разному на разных устройствах (например, когда только появился API для выреза дисплея, он был плохо принят, и у каждого производителя были свои причуды). Моя стратегия проста: я тестирую на своем телефоне и скрещиваю пальцы, надеясь, что это будет работать и на других устройствах.
Кроме того, Android имеет относительно агрессивную стратегию устаревания API. Google Play требует относительно свежей версии targetSdkVersion
и отклоняет обновление приложения, если один из SDK сторонних разработчиков устарел. Это означает, что мне приходится постоянно запускать Android Studio и обновлять версии Android и SDK (иногда также версии Kotlin и Gradle). Обычно проект не компилируется, что означает несколько часов исправлений и тестирования. Это происходит не каждый день, но достаточно часто, чтобы раздражать. Для сравнения, с момента выпуска проекта мне пришлось открыть XCode и обновить нативный Swift-код всего два раза.
Злит
На Android приходится 70% всех мобильных игроков, но доходы примерно такие же, как и на iOS. Мало кто приобретает пакеты расширений, а основной доход приносит единственная и необязательная видеореклама с вознаграждением. На самом деле реализация рекламы на Android, скорее всего, глючная, поскольку она часто не появляется после фонового режима вплоть до жесткого перезапуска — я получал жалобы от пользователей по этому поводу! Однако мне так и не удалось выяснить причину этого — отчасти потому, что я не смог воспроизвести это на своем телефоне, а отчасти потому, что я хотел бы потратить свое время на работу над игрой, а не на отладку какого-то глючного рекламного SDK.
TL;DR: Другие 50% поддержки мобильных устройств — это поддержка Android
Заключение
Я благодарен вам за то, что вы дочитали до конца мою длинную тираду о поддержке платформ в инди-компании, и надеюсь, что это поможет вам в принятии решений — я знаю, что для своей следующей игры я точно сделаю лучший выбор. Говоря о разработке игр, редко упоминают скучные детали, но они имеют огромное значение для выпуска продукта и могут отнять много сил. На самом деле, помимо работы по поддержке платформ, большая часть моего времени уходит на поддержку клиентов, управление сообществом, проверку и бан читеров, а также обслуживание серверов. Настолько, что работа над моей новой игрой сильно затянулась. Мне еще предстоит найти оптимальный баланс, но я стараюсь делать все возможное.