Когда инженеры впервые сталкиваются с автоматизацией игр, они обычно начинают искать аналог Selenium или Playwright для GameDev.
Логика кажется очевидной:
- для веба есть Selenium;
- для мобильных приложений есть Espresso и XCUITest;
- значит для игр тоже должен существовать какой-то стандартный инструмент.
На практике такого инструмента до сих пор не существует.
За время работы над несколькими игровыми проектами я заметил, что большинство решений в конечном итоге сводятся к двум фундаментальным моделям:
- Engine Integration
- Visual Validation
Практически все остальные подходы являются вариацией одной из них или комбинацией обеих.
Почему GameDev оказался в другой ситуации
Веб-автоматизация опирается на DOM.
Мобильная автоматизация опирается на accessibility frameworks.
У автоматизации существует стандартизированный способ взаимодействия с приложением. Она может найти элемент, получить его состояние и выполнить действие.
Игры устроены иначе.
Они могут использовать Unity, Unreal, собственный движок или полностью кастомный UI-фреймворк. Для внешнего инструмента игра часто выглядит просто набором пикселей.
Нет единого протокола взаимодействия.
Нет универсального дерева элементов.
Нет стандарта, который одинаково работал бы между разными проектами.
Именно поэтому индустрия до сих пор не получила свой Selenium.
Модель №1. Engine Integration
Первая модель строится вокруг прямого взаимодействия с игрой.
Для этого создаётся специальный слой интеграции:
- HTTP API;
- WebSocket;
- RPC;
- Debug Commands;
- собственный Automation Driver.
Вместо взаимодействия через экран автоматизация получает доступ к внутреннему состоянию игры.
Например:
GetPlayerState()
GetQuestStatus()
GetInventory()
GetObjectProperty()
Подобный подход обычно оказывается:
- быстрее;
- стабильнее;
- проще в поддержке;
- легче в отладке.
Но требует инвестиций со стороны команды разработки.
Для небольших студий подобные инвестиции часто оказываются слишком дорогими.
Почему крупные команды часто приходят к собственным решениям
На рынке существуют готовые инструменты.
Например, AltTester для Unity.
Для небольших Unity-команд это может быть хорошей отправной точкой, позволяющей быстро получить работающую автоматизацию без серьёзных изменений в проекте.
Однако по мере роста проекта требования начинают выходить за рамки поиска объектов.
Появляется необходимость:
- читать внутреннее состояние игры;
- получать диагностическую информацию;
- интегрироваться с внутренними сервисами;
- работать с игровыми механиками;
- управлять тестовыми сценариями.
В этот момент собственный слой интеграции часто начинает давать больше возможностей, чем универсальный инструмент.
Особенно если проект существует несколько лет и над ним работают десятки или сотни инженеров.
Модель №2. Visual Validation
Вторая модель работает с визуальным представлением игры.
Для этого используются:
- screenshot testing;
- visual regression testing;
- image comparison;
- OCR;
- распознавание объектов на экране.
Visual Validation отвечает на вопрос:
Правильно ли игра выглядит для игрока?
Такие проверки позволяют находить:
- проблемы рендеринга;
- визуальные артефакты;
- исчезнувшие объекты;
- ошибки интерфейса;
- некорректное отображение контента.
Visual Validation особенно важна в играх, поскольку значительная часть пользовательского опыта связана именно с визуальным представлением.
Engine и Visual — не конкурирующие подходы
После знакомства с двумя моделями возникает естественный вопрос:
Какой подход лучше?
На практике это часто оказывается неправильным вопросом.
Engine Integration и Visual Validation решают разные задачи.
Они не являются альтернативами друг другу.
Они проверяют разные аспекты качества продукта.
Engine Integration отвечает на вопрос:
Правильно ли работает игра?
Например:
- может ли персонаж подобрать артефакт;
- начисляется ли опыт;
- корректно ли работает квест;
- правильно ли рассчитывается экономика;
- меняется ли состояние игрового мира.
Engine-тесты работают с логикой и состоянием системы.
Visual Validation отвечает на вопрос:
Правильно ли выглядит игра?
Например:
- корректно ли отрисована сцена;
- отображаются ли объекты;
- не съехал ли интерфейс;
- корректно ли работают визуальные эффекты.
Visual-тесты работают с представлением системы.
Именно поэтому один подход не заменяет другой.
Герой может успешно подобрать артефакт с точки зрения игровой логики, но модель может не отображаться на экране.
И наоборот — сцена может выглядеть идеально, но награда может не начисляться или квест может не завершаться.
Зрелая архитектура автоматизации
Во многих успешных проектах постепенно появляется разделение ответственности между несколькими слоями.
Engine Driver
Предоставляет доступ к внутреннему состоянию игры.
GetPlayerState()
GetObjectProperty()
GetQuestStatus()
Test Harness / Cheats
Отвечает за подготовку тестовых сценариев и игровых состояний.
SetPlayerLevel()
GrantCurrency()
UnlockCharacter()
TriggerEvent()
ResetAccount()
Visual Validation Layer
Отвечает за проверку визуального результата.
- screenshot comparison;
- visual regression;
- UI validation;
- layout validation.
Каждый слой решает свою задачу и может развиваться независимо от остальных.
Почему всё сводится именно к этим двум моделям
На самом деле в автоматизации игр нет принципиально новых идей.
Те же фундаментальные подходы давно существуют в вебе, мобильной разработке и других областях.
Разница заключается не в самих подходах.
Разница заключается в отсутствии единого стандарта.
Веб пришёл к DOM.
Мобильные платформы пришли к accessibility frameworks.
GameDev пока не пришёл к общему протоколу взаимодействия между автоматизацией и игрой.
Поэтому большинство решений в конечном итоге строятся вокруг двух базовых идей:
- получить доступ к внутреннему состоянию игры;
- проверить её визуальное представление.
На мой взгляд, именно поэтому спустя столько лет индустрия так и не получила единый “Selenium для игр”.
Проблема не в отсутствии инструментов или идей.
Проблема в том, что игры одновременно являются и сложными программными системами, и визуальными продуктами.
И для проверки этих двух аспектов качества по-прежнему требуются разные подходы.