Senior Unity-разработчик
Одна кодовая база. Все платформы, где она должна работать.
Семь лет разрабатываю на Unity для десктопа, мобильных платформ и веба. Я спроектировал SDK и стандарты разработки, которые вывели 100+ проектов на 30+ платформ. Производительность я считаю условием выпуска, а не задачей, которую оставляют на потом.
Платформы
Платформы, на которые я выпускал проекты или добавлял поддержку в SDK: магазины приложений и консоли, веб-площадки и игры в мессенджерах.
В цифрах
- 7+ лет с Unity: десктоп, мобильные платформы и веб
- 100+ проектов портировано, переписано и выпущено
- 30+ платформ из одной кодовой базы
- 300+ игр работают на SDK, который я спроектировал
- 100+ внешних разработчиков используют его в продакшене
- 2 млн+ установок у самого успешного проекта
Направления работы
Пять направлений, и по каждому есть подтверждённый результат
Общая задача одна: снизить стоимость выпуска игры на площадки, под которые её не проектировали, и сохранить производительность после переноса.
-
Кроссплатформенный выпуск
Беру готовый проект на Unity и довожу его до состояния, в котором он работает, продаётся и проходит модерацию на площадках, под которые его не проектировали: Android, Steam, WebGL и консоли, а также мобильные браузеры на iPhone, самая требовательная цель для Unity. Одна кодовая база и один пайплайн сборки вместо отдельной ветки под каждый магазин, которая устаревает сразу после слияния.
-
Производительность, которую видно в цифрах
Профилирование идёт первым шагом, а не последним. Размер сборок ниже на 20-50 % за счёт пайплайна импорта на AssetPostprocessor; на слабых iPhone частота кадров выросла с 20 до 45 после смены стратегии сжатия текстур. Нижняя граница в 30 FPS и время до играбельного состояния менее пяти секунд: это условия выпуска, а не пожелания.
-
Архитектура и инструменты для команды
Модульные пакеты с реальными границами сборок, внедрение зависимостей через полноценный composition root, генераторы кода на Roslyn и редакторные инструменты, которые убирают целые классы ошибок. Я делаю не только то, что видит игрок, но и то, с чем команда работает каждый день.
-
Жизнь игры после релиза
Облачные сохранения и состояние игрока, которое переживает закрытую вкладку. События и сезонный контент без новой сборки. Каталоги покупок и понятный сценарий для игрока, чья покупка не дошла. Этот слой я писал сам в виде небольшого бэкенда и запускал его в продакшене, а там, где готовый сервис подходил лучше, работал с GamePush, PlayFab, XSolla и LiveOps-консолями самих платформ. Этот опыт прежде всего учит различать, когда такое решение стоит писать, а когда взять готовое.
-
Стандарты, по которым может работать команда
Стандарты разработки, процедуры ревью и онбординг, написанные из производственного опыта, а не по статье в блоге. Я координировал 10+ разработчиков, участвовал в найме и отвечал за то, что уходит в QA, а что возвращается на доработку.
Избранные проекты
Шесть проектов и шесть разных подтверждений
Приложение, которое я в одиночку довёл до продакшена; SDK, на котором работают 300+ игр; открытый движок ландшафта с читаемым кодом; и три порта, каждый из которых ломался в своём месте. Остальное, включая проекты, где я ошибся, и выводы, которые я из них сделал, собрано на двух страницах ниже.
-
Приложение
LockInGoals
ЗадачаМелкие ежедневные задачи постоянно проигрывали крупным, а трекеры из магазинов решают это, оставляя себе и данные, и синхронизацию, и контроль над дальнейшим развитием. Кроме того, после трёх лет работы в чужих кодовых базах мне нужна была собственная библиотека компонентов в актуальном состоянии.
РешениеС нуля до продакшен-сборки под Android на Unity за два месяца. Состояние построено на CRDT, поэтому экспорт с одного устройства объединяется с данными на другом без сервера-арбитра и без потери изменений по принципу последней записи. Ни аккаунта, ни сервера, ни разрешения на доступ в сеть. Импорт, экспорт и восстановление работают через Android Storage Access Framework, а не через доступ ко всей файловой системе; автосохранение идёт в фоне, ручное сохранение доступно всегда, все пользовательские строки вынесены в таблицу локализации, а необработанная ошибка выводит на экран сбоя с описанием проблемы вместо закрытия приложения.
РезультатПользуюсь приложением каждый день с момента выпуска; интерфейс адаптируется под любую платформу, куда собирает Unity. Из этого проекта выросла переиспользуемая часть: CRDT-хранилище и библиотека компонентов. Она снова в актуальном состоянии.
-
Продукт
MirraSDK
ЗадачаКаждая новая платформа означала удалить один вендорский SDK, импортировать другой и переписать под него все вызовы. Две недели работы разработчика на проект, и так на каждый магазин, каждый раз с риском что-нибудь сломать.
РешениеМодульный пакет на C#: единый слой интерфейсов над рекламой, платежами, облачными сохранениями, аналитикой и API платформ, а сменные реализации поставляются отдельными UPM-пакетами. Три генератора кода на Roslyn сканируют проект и связывают реализации с интерфейсами при перекомпиляции, так что выбор платформы сводится к выпадающему списку в окне редактора. Вспомогательный модуль на NodeJS и TypeScript определяет площадку в рантайме, и именно это позволяет одной WebGL-сборке обслуживать сразу несколько площадок.
РезультатИнтегрирован в 300+ выпущенных игр, используется 100+ внешними разработчиками. Подключение новой платформы сократилось с нескольких дней до нескольких часов.
-
Открытый код
Transvoxel
ЗадачаMarching cubes оставляет видимые швы на стыках разных уровней детализации. Поэтому воксельный ландшафт обычно либо работает на одном разрешении и расходует избыточную память, либо показывает трещины на границах. Мне нужен был ландшафт, который можно изменять на ходу и при этом видеть на километр вперёд.
РешениеЧистая модульная реализация алгоритма Transvoxel Эрика Ленгьеля для Unity: бесшовная триангуляция уровней детализации по полю плотности под управлением октодерева, на модели потоков, распределяющей работу между CPU и GPU. Скульптинг, материалы, дальность прорисовки, число уровней детализации и размер вокселя задаются в реальном времени: мир перестраивается прямо во время движения ползунка. Демонстрация ландшафта, которая ради смены параметра требует перезапуска, ничего не демонстрирует.
Результат240 FPS в реальном времени, 10 000 метров ландшафта перед игроком, гибридная схема потоков CPU и GPU. Опубликовано на GitHub под лицензией MIT.
-
Порт
Solar Smash
ЗадачаПроект передали мне, чтобы вывести его на веб-площадки. Интерфейс был рассчитан на одно соотношение сторон, до платных элементов приходилось добираться, а аналитики и монетизации, без которых проект не может развиваться, в нём не было.
РешениеПереработал интерфейс вокруг платных элементов, чтобы покупка была осознанным действием, а не результатом поиска. Устранил накопившиеся утечки памяти и проблемы стабильности, найденные в профайлере, и подключил игру к MirraSDK: реклама, платежи, облачные сохранения и API платформ. Firebase и GameAnalytics отправляют одни и те же события, чтобы их можно было сверить, Adjust сводит доход от рекламы и покупок в одном отчёте, а на Android-магазинах монетизацию обеспечивает Yandex Mediation со своим набором адаптеров.
РезультатВыпущено на 20+ платформах. Доработанная сборка в итоге вышла и в Google Play, а не осталась только веб-версией, ради которой всё начиналось.
-
Порт
Minetap
ЗадачаВесь код лежал во взаимозависимых UPM-пакетах, а основной проект только связывал их между собой. Выглядит как модульность, ведёт себя как монолит: границы, по которой можно работать, нет, а правка внутри пакета не видна остальным.
РешениеРаботал с существующей структурой, а не переписывал её. Убрал старую монетизацию, оптимизировал ассеты и геймплей сначала под веб как под самую требовательную платформу, и подключил MirraSDK, чтобы платформенный слой перестал быть отдельной работой под каждый магазин. Для Android понадобилось то, что Unity не покрывает, поэтому Java-мосты я написал сам: нативная отправка ссылки и подключение аккаунта RuStore.
РезультатСтабильный выпуск более чем на 10 платформах: Google Play и RuStore, CrazyGames и Yandex Games. На альтернативных Android-магазинах более 50 тысяч установок.
-
Оптимизация
Pocket Zone
ЗадачаСборка занимала более 500 МБ оперативной памяти сразу при запуске, а бюджет кадра уходил в Update-циклы, которым нечего было выполнять. В браузере на телефоне это не медленная игра, а игра, которая не открывается.
РешениеПричины нашёл в профайлере, а не при чтении кода: локализация выполняла подстановку строк внутри горячих циклов, а несколько Update-циклов работали вхолостую. Async-задачи пришлось убрать полностью, потому что веб однопоточный, и заменить их корутинами. Затем я переработал интерфейс так, чтобы одна сборка работала и в портретной, и в альбомной ориентации при любом размере окна: в браузере, где окно меняют мышью, это обязательное требование.
РезультатВыпущено на 20+ платформах, более 100 тысяч игроков на самой успешной из них. Игроки исходной сборки в Google Play начали спрашивать, почему веб-версия выглядит лучше.
Можно проверить
SDK открыт, поэтому верить на слово не нужно
MirraSDK опубликован как открытая организация на GitHub. Структура репозиториев и есть архитектура: один основной пакет, по репозиторию на каждую реализацию, каждая поставляется отдельным UPM-пакетом. Разделение на интерфейсы и реализации видно снаружи, не читая ни строчки кода.
- SDK5, основной пакет: реклама, платежи, аналитика, сохранения и API платформ за единым слоем интерфейсов
- Шесть реализаций рекламы: AdMob, AppLovin, Appodeal, CAS, LevelPlay и Yandex Mobile Ads
- Реализации платформ для CrazyGames, Playgama, RuStore и OneStore, а также XSolla для платежей
- Боевой WebGL-шаблон для Unity 2021 - 6 и пример проекта, где на каждую интеграцию своя ветка
Коммиты там под рабочим аккаунтом romanlee17, а не под личным: в SDK5 этому аккаунту принадлежат 108 из 132 коммитов. Я проектировал и сопровождал SDK до апреля 2026 года, когда ушёл из компании, поэтому всё, что датировано позже, ко мне отношения не имеет.
Стек
Технологии, с которыми работаю
Сгруппировано по назначению. Без процентов владения: разработка слишком широкая область, чтобы сводить её к одной цифре.
Движок и язык
- Unity
- C#
- IL2CPP
- Addressables
- AssetBundles
- StreamingAssets
- UPM
- Семантическое версионирование
Графика и интерфейсы
- URP
- BiRP
- ShaderGraph
- HLSL
- Compute-шейдеры
- UI Toolkit
- UnityEngine.UI
- IMGUI
- Процедурная генерация мешей
Архитектура и инструменты
- VContainer
- UniTask
- Генераторы кода Roslyn
- Редакторные инструменты
- AssetPostprocessor
- Unity Test Runner
Бэкенд и LiveOps
- Свой бэкенд облачных сохранений и LiveOps
- GamePush
- PlayFab
- XSolla
- LiveOps-консоли платформ
- Firebase
- GameAnalytics
- Adjust
Монетизация и магазины
- AdMob
- Yandex Mediation
- AppLovin
- LevelPlay
- Appodeal
- Clever Ads Solutions
- Покупки Google Play
- Google Play Console
- Консоли RuStore и OneStore
Профилирование и отладка
- Unity Profiler
- Memory Profiler
- Frame Debugger
- Инструменты браузера
- Eruda
- Android Studio
- Logcat
- adb
Платформы и технологии вне движка
- WebGL
- Android
- Java
- NodeJS
- TypeScript
- Python
- ASP.NET Core
- Docker
- Git
Опыт
Откуда берутся эти результаты
-
Апрель 2026 - настоящее время
Удалённо, Минск, Беларусь
Независимый Unity-разработчик, Собственные проекты
Собственные проекты на Unity, сделанные в одиночку: Android-приложение с нуля до продакшен-сборки за два месяца и шесть репозиториев с открытым кодом, включая многопоточный движок ландшафта на алгоритме Transvoxel.
- LockInGoals, трекер привычек и показателей на Unity без аккаунта, сервера и разрешения на доступ в сеть. CRDT-хранилище объединяет экспорт с одного устройства с данными на другом, импорт и экспорт идут через Storage Access Framework, интерфейс адаптируется от телефона до десктопа, все строки вынесены в таблицу локализации, а необработанная ошибка выводит экран сбоя вместо закрытия приложения. Внутреннее тестирование в Google Play на моём аккаунте разработчика.
- Transvoxel, открытая реализация алгоритма Эрика Ленгьеля с бесшовными уровнями детализации по полю плотности под управлением октодерева на гибридной схеме CPU и GPU, а также MeshOutline, EventAggregator, ConsoleContainer, Wireframes и IncrementalGenerator как отдельные открытые пакеты для Unity.
-
Апрель 2023 - апрель 2026
Удалённо, Лимасол, Кипр
Lead Unity-разработчик, MirraGames
Повышение через полгода после выхода в компанию: к тому моменту разработчики уже сами приносили мне свои задачи. Формально никто мне не подчинялся: это была ответственность за работу и за стандарт, а не административное руководство. Говорю об этом прямо, потому что именно это обычно и хотят уточнить, когда видят позицию Lead.
- Координировал 10+ разработчиков, выпускавших 100+ проектов на 30+ платформ: Google Play, RuStore, OneStore, CrazyGames, Yandex Games, GameDistribution и Nintendo Switch. Срок до первой релизной сборки сократился с двух и более недель до одной недели на проект.
- Спроектировал MirraSDK, модульный пакет для Unity, в котором реклама, платежи, облачные сохранения, аналитика и API платформ скрыты за единым слоем интерфейсов, а три генератора кода на Roslyn связывают реализации при перекомпиляции. Интегрирован в 300+ выпущенных игр, используется 100+ внешними разработчиками; подключение новой платформы сократилось с нескольких дней до нескольких часов. Довёл его от внутреннего инструмента до лицензируемого продукта и представлял на конференциях WN.
- Android-релизы в Google Play, RuStore и OneStore: Yandex Mediation, AdMob, Appodeal, AppLovin, LevelPlay и Clever Ads Solutions за слоем SDK, Firebase, GameAnalytics и Adjust на одних и тех же событиях, покупки Google Play и Java-плагины для API платформ, которые Unity не покрывает.
- Вёл LiveOps все три года: написал небольшой бэкенд облачных сохранений и LiveOps и запускал его в продакшене, встроил батчинг запросов в сам SDK, чтобы расходы на инфраструктуру оставались предсказуемыми, а события, сезонный контент и попадание в подборки вёл через GamePush, PlayFab, XSolla и консоли самих платформ там, где готовый сервис подходил лучше.
- Написал стандарты, по которым работала команда: ветки, коммиты, удаление сторонних SDK, порты и схемы управления на консолях. Первую сборку каждого проекта проверял сам и по этим стандартам решал, уходит ли она в QA.
- Отбирал кандидатов и вёл найм. После одного неудачного найма добавил в процесс небольшое оплачиваемое задание по нашим реальным стандартам: портфолио показывает, что человек сделал, но не то, как он работает внутри чужих договорённостей.
-
Октябрь 2022 - апрель 2023
Удалённо, Лимасол, Кипр
Senior Unity-разработчик, MirraGames
Пришёл в компанию с конкретной задачей: сделать так, чтобы проекты, уже вышедшие на Android, iOS и в Steam, работали, продавались и проходили модерацию в браузере.
- Портировал проекты объёмом от 50 до 250 МБ на WebGL с использованием IL2CPP, Addressables и Brotli, заменяя то, что не работает в однопоточном браузере: async-задачи на корутины и UniTask, Zenject на VContainer, FMOD на независимую от частоты кадров обёртку над Unity AudioClips, а Linear URP на Gamma и Built-in Render Pipeline там, где требовалась поддержка iPhone.
- Собрал пайплайн импорта на AssetPostprocessor, уменьшивший размер сборок на 20-50 %, и поднял частоту кадров на слабых iPhone в браузере с 20 до 45 за счёт смены стратегии сжатия текстур, а не вырезания контента.
- Удерживал нижнюю границу в 30 FPS и время до играбельного состояния менее пяти секунд как условия выпуска, проверяя это в Unity Profiler, Memory Profiler и инструментах браузера на реальных устройствах, а не на десктопе.
-
Июнь 2019 - сентябрь 2022
Удалённо, Белград, Сербия, частичная занятость
Unity-разработчик, TeamGZ
Частичная занятость параллельно с учёбой на маркетинге, в команде из разработчиков, 3D-художников и звукорежиссёров. Код я писал наравне с остальными разработчиками, а работа со страницами в магазинах досталась мне как раз потому, что параллельно я учился на маркетолога.
- Реализовал контроллер от первого лица, систему стрельбы и логику миссий для серии The Dead Zone и привёл существующий код к общим системам, на которых команда собирала следующие проекты.
- Довёл третью часть до 1,5 млн установок против 100 и 700 тысяч у двух предыдущих, за счёт работы со страницей в магазине, а не закупки трафика.
- Вёл ASO и A/B-тесты обложек в Google Play, рисовал обложки сам, что дало около 20 % прироста установок, и лично отвечал на отзывы игроков.
- В одиночку сделал Five Nights at Dr. Livesey's, проект на волне тренда, который набрал 100 тысяч загрузок за первую неделю без закупки трафика.
- Вместе с командой выпустил серию в Steam и на альтернативных Android-магазинах и интегрировал AdMob и покупки Google Play по всему каталогу.
-
Февраль 2021 - апрель 2021
Удалённо, Минск, Беларусь, частичная занятость
Junior Unity-разработчик, ИП Янушко А. И.
Игровые интерфейсы и редакторные инструменты; работа совмещалась с учёбой.
- Собирал игровой интерфейс по готовым макетам на Unity UI и TextMeshPro и писал редакторные расширения, чтобы убрать из этой работы рутину.
- Интегрировал SQLite для сохранений и локализации, работал с командой через Trello и BitBucket.
-
Сентябрь 2018 - февраль 2019
Удалённо, Минск, Беларусь, частичная занятость
Frontend-разработчик, Weblico
Лендинги под ключ в небольшой студии, которая делала их на заказ.
- Верстал лендинги на HTML, CSS, JavaScript и PHP, а также на WordPress и Tilda, по макетам, сделанным вместе с коллегой.
- Отвечал за адаптивность, скорость загрузки, поведение на разных устройствах и поисковую оптимизацию каждого проекта.
-
2018 - 2022
Минск, Беларусь
Бакалавр, маркетинг, Белорусский государственный технологический университет
Дипломная работа: AR-приложение на Unity под Android, позволяющее примерить керамику в интерьере до покупки. Дополнительно сертификат по веб-технологиям от университетской программы.
Рассматриваю Senior-позиции по Unity
Нахожусь в Минске и готов приступить сейчас: удалённо из любой точки мира, переезд в США или Канаду при визовой поддержке либо офис в Минске. Интересует кроссплатформенный выпуск, производительность на мобильных платформах, а также архитектура и инструменты, на которые команда опирается каждый день. Если это близко к вашей задаче, быстрее всего написать на почту.