Это последняя глава руководства и единственная, которую имеет смысл открывать регулярно — перед каждой сборкой архива. Всё, что разбиралось по отдельности, здесь собрано в один список с номерами требований, чтобы проверка занимала час, а не неделю ожидания после отказа.
Порядок разделов совпадает с порядком работы: от сборки к SDK, дальше к тому, что видит и слышит игрок, потом к монетизации, промоматериалам и черновику.
Совет
Скопируйте этот список в CHECKLIST.md в корне проекта. Часть пунктов Claude Code проверит прямо по исходникам: «пройдись по CHECKLIST.md, отметь, что можно проверить статически по коду, и покажи найденные нарушения». Подключение /sdk.js, обработчик contextmenu, playsinline у видео, подписка на game_api_pause, try/catch вокруг вызовов SDK, отладочные console.log — всё это видно в коде.
Сборка и архив
- Архив в формате ZIP, в корне ровно один
index.html(пункт 1.22). - Содержимое до сжатия не больше 100 МБ (пункт 1.21).
- В названиях файлов и папок нет пробелов и кириллических символов (пункт 1.22).
- В коде нет абсолютных URL, ссылающихся на серверы S3 Яндекса (пункт 1.7).
- Работа игры не зависит от URL, на котором она открыта (пункт 1.18).
- Из сборки убраны отладочные логи, тестовые кнопки и надписи вроде «в разработке» или «trial version».
- Все внешние хосты добавлены на вкладке CSP с обоснованием: без путей, портов и IP-адресов, только
httpsиwss. - Основной объём данных игры лежит в архиве, а не грузится с внешнего хоста; ошибка подключения показывается игроку понятно и с предложением решения.
SDK и жизненный цикл
- SDK подключён строкой
<script src="/sdk.js"></script>— относительным путём для игры, залитой архивом (пункт 1.1). - На debug-панели (
debug-mode=16) лоадер показываетIT, а неIF(пункт 1.19.1). -
YaGames.init()вызывается только после загрузки скрипта; ошибка инициализации не вешает игру. -
ysdk.features.LoadingAPI?.ready()вызывается, когда все ресурсы загружены и интерфейс интерактивен (пункт 1.19.2). - Индикатор Game Ready на debug-панели зелёный, время вызова разумное — таймаут 90 секунд не выбирается.
-
GameplayAPI?.start()и?.stop()расставлены по документированным моментам, если разметка геймплея используется (пункт 1.19.3). - Подписка на
game_api_pauseиgame_api_resumeесть и работает. - Каждый вызов SDK обёрнут в
try/catchили.catch(); необработанных отклонений промисов нет.
Интерфейс и управление
- Правый клик и долгое нажатие по игровой области не открывают системное контекстное меню (пункты 1.6.1.8, 1.6.2.7).
- Видео воспроизводится встроенным плеером, а не системным:
playsinline, свои элементы управления (пункты 1.6.1.6, 1.6.2.5). - YouTube-плеер не встроен (пункт 3.9).
- При отсутствии WebGL игра не показывает уведомление об этом (пункт 1.6.1.7).
- Нет экранов-тупиков: с любого экрана можно вернуться в меню или начать заново (пункт 1.14).
- Игра не ломается при изменении размера окна и повороте экрана (пункты 1.14, 1.15).
- Управление полностью описано в игре или в поле «Как играть» (пункт 2.2).
- Авторизация — только через Яндекс ID, сторонней регистрации нет (пункт 1.2).
- Диалог входа открывается по осознанному нажатию кнопки, с понятной выгодой; сам при старте не всплывает (пункт 1.2.1).
- Гость играет полноценно, и его прогресс сохраняется (пункт 1.2.2).
Мобильные устройства
- Страница не прокручивается, нет браузерного скроллбара и pull-to-refresh (пункт 1.10.2).
- Масштабирование щипком отключено, интерфейс не уезжает под «чёлку» и жестовую полосу.
- Кнопки достаточно крупные для пальца, между ними есть зазор.
- Canvas учитывает
devicePixelRatio— картинка не мылит на ретине. - Ориентация в черновике совпадает с поведением игры; при выборе «Портретная» или «Альбомная» заглушку рисует SDK, своя не нужна.
- Игра запускается на заявленных платформах: браузеры из пункта 1.20.1, Android 5.0+ и iOS 9.0+ (пункт 1.20.3), Android TV — если заявлена платформа ТВ (пункт 1.20.4).
Звук и фокус
- Звук останавливается при сворачивании окна браузера или приложения (пункт 1.3).
- Звук останавливается при переключении на другую вкладку (пункт 1.3).
- Звук останавливается в браузерном меню выбора вкладок (пункт 1.3).
- Звук и геймплей встают на паузу на время interstitial и rewarded (пункт 4.7).
- Стартовая полноэкранная реклама платформы не перекрывается вашей музыкой: игра стартует после
game_api_resume. - Игровой цикл останавливается вместе со звуком, а
deltaTimeпосле возврата ограничен сверху.
Сохранения
- Прогресс сохраняется сразу после действия игрока или по кнопке и переживает F5 и смену ориентации экрана (пункт 1.9).
- Сохранения работают и у гостя, и у авторизованного игрока.
-
setData()вызывается не из игрового цикла; частые изменения склеиваются таймером. - Уложились в лимиты: 200 КБ на игрока для
setData, 10 КБ для числовых данныхsetStats. - Уложились в частоту:
getPlayer()— 20 запросов за 5 минут,setData/getData— 100 за 5 минут,setStats/getStats/incrementStats— 60 за 1 минуту. -
flushпередаётся вторым аргументомsetData(data, flush); никакогоplayer.flush()в коде нет. - Если формат данных менялся — миграция написана, проверена на реальном старом сохранении и не падает на неполных данных.
- После кнопки Clear cloud data на debug-панели игра корректно запускается с нуля.
- Если механика предполагает прохождение уровней — есть сохранение прогресса; если игра на рекорд — сохраняется рекорд (пункт 2.6).
Реклама
- Реклама показывается только через SDK Яндекс Игр, сторонних сетей и статичных баннеров нет (пункт 4.1).
- Кастомных RTB-баннеров нет (пункт 4.6.2).
- Рекламные блоки не модифицированы и не имитируются собственными окнами (пункт 1.16).
-
onClose(wasShown)обработан: игра продолжается одинаково приtrueиfalse. - Награда за rewarded выдаётся в
onRewarded, а не вonClose. - Кнопка rewarded нажимается по желанию игрока, из текста понятно, что будет реклама и что за неё дадут (пункты 4.5, 4.5.1).
- Награда — дополнительный бонус, без неё игру можно продолжать (пункт 4.5.2).
- Полноэкранная реклама вызывается после действия игрока, а не по таймеру, оторванному от действий.
- Задержка между действием и показом рекламы — около 0,33 секунды, точно не больше 2 секунд.
- Внутренний прогресс сохраняется после перехода по рекламе и возврата обратно (пункт 4.2).
- После покупки «отключить рекламу» рекламы действительно нет, включая sticky-баннер.
Покупки
- Платежи проходят только через SDK (пункт 1.4).
- Метод консумирования подключён;
getPurchases()вызывается при каждом запуске (пункт 1.13.1). - Название и иконка портальной валюты берутся из SDK, а не захардкожены — проверено моком валюты на debug-панели (пункт 1.13.2).
- Прогресс с покупками хранится на сервере и доступен с разных устройств (пункт 1.13.3).
- Стоимость показана цифрами с указанием портальной валюты (пункт 1.13.4), а изображение, название и состав покупки соответствуют тому, что игрок получает (пункт 1.13.5).
- Список покупок в игре совпадает с Консолью (пункт 1.13.6).
- Товар начисляется до консумирования, а не после.
- Покупки проверены под аккаунтом из списка логинов для тестовых покупок.
Лидерборды
- Используется актуальный API
ysdk.leaderboards.*, а не устаревшийysdk.getLeaderboards(). - Техническое название в коде совпадает с названием в Консоли (иначе 404).
-
setScoreне бьётся в лимит 1 запрос в секунду; отправляется только улучшение результата. - Ошибка
LEADERBOARD_PLAYER_NOT_PRESENTобработана как нормальная ситуация, а не как сбой. - Для типа
timeзначение передаётся в миллисекундах;scoreне отрицательный. - Игра полностью играбельна без авторизации и без лидерборда.
Локализация
- Язык определяется через
ysdk.environment.i18n.langна старте, а не в процессе игры (пункт 2.14). - Индикатор
文на debug-панели зелёный: I18N is used. - Автоопределение реализовано, даже если язык в игре один и текстов почти нет.
- Есть запасной язык:
ruдляbe,kk,uk,uz;enдля остальных. - Каждый язык из поля «Игра переведена на» реально поддержан — проверено через SDK mocks ⚒️; значимые для геймплея тексты переведены (пункт 8.2.3).
- Длинные строки не обрезаются и не выезжают за кнопки; в шрифте есть нужные символы.
Производительность и завершённость
- Худший кадр в геймплее держится ниже 30 мс на среднем устройстве, а не только на вашем; профиль снят с замедлением CPU.
- Нет утечек: после десяти минут игры память не растёт бесконечно.
- В консоли нет ошибок и предупреждений ни при запуске, ни в процессе игры (пункт 1.14).
- Игра завершена: тексты читаемы, графика на месте, управление работает, персонажи не застревают в текстурах (пункт 1.15).
- Основное содержание проходится дольше 10 минут; для викторин — не меньше 100 неповторяющихся вопросов (пункт 2.9).
- Игра соответствует хотя бы одному критерию наличия игровых механик (пункт 2.4).
- Интерактивного ИИ в игре нет; заранее сгенерированные ассеты допустимы (пункт 1.23).
Промоматериалы
- Иконка 512 × 512, PNG.
- Обложка 800 × 470, PNG.
- Обложка на витрину 1560 × 520, PNG или JPG — необязательно, но влияет на заполненность карточки.
- Скриншоты: 16 × 9 для альбомной ориентации, 9 × 16 для портретной, 1280–2560 px по длинной стороне, JPEG или 24-разрядный PNG, минимум по 2 на каждую выбранную платформу.
- Реальный геймплей занимает не менее 70 % площади скриншота (пункт 5.1.1.2).
- Горизонтальное видео: 16 : 9, MP4, высота от 400 px, длительность до 28 секунд, вес до 100 МБ.
- На материалах нет рамок и скруглённых углов (пункт 8.3.3), нет статус-бара, бейджей и рейтинга Яндекс Игр (пункт 8.3.4).
- Название игры одинаково на всех материалах и внутри игры (пункт 5.1.3).
- Материалы не переиспользованы из другой вашей игры и отражают суть игры (пункт 8.3.2).
Поля черновика
- Название: до 50 символов, с заглавной буквы, без капса (пункт 8.2.1), уникально в каталоге на каждом языке (пункт 5.12).
- В названии нет слов «бесплатно», «лучшая», «топ», «free», «best» и подобных (пункт 8.2.2).
- «Об игре» — 100–1000 символов, «Как играть» — 100–1000 символов.
- «Описание для SEO» — 50–160 символов, не дублирует другие поля.
- «Короткое описание» — до 70 символов, с заглавной буквы, без слов «бесплатная» и «на русском языке».
- Категорий не больше двух, и геймплей им соответствует (пункт 2.3).
- Тегов не больше 20; ключевые слова — нижний регистр через запятую, до 100 символов на поле.
- Возрастной рейтинг соответствует содержанию (пункт 2.7).
- Поддерживаемые платформы выбраны честно; при выборе iOS заполнен Apple Team ID.
- Включена опция «Игра использует облачные сохранения», если используются
setData()иsetStats(). - Комментарий разработчика заполнен, если в игре есть нестандартные решения (до 2048 символов).
- Отсроченная публикация включена только если у вас действительно есть план на дату.
Юридическая и организационная часть
- Договор заключён — по единой лицензионной схеме в Консоли или через РСЯ. Без него кнопка отправки бесполезна.
- У вас есть права на всю графику, музыку, звуки и шрифты в игре, включая ассеты из бесплатных библиотек с их лицензиями.
- В игре и материалах нет ссылок на внешние ресурсы: сайты, сторы, соцсети вне разрешённых условий (пункт 8.4.2).
- Ссылки на ваши другие игры сделаны через SDK и не прерывают игровой процесс (пункт 8.4.1).
- Игра загружается в новый черновик с новым ID, а не поверх ранее опубликованной другой игры (пункт 1.24).
- Учтено ограничение: единовременно не больше двух заявок на публикацию новых игр (обновления не считаются).
Осторожно
Этот раздел — не юридическая консультация. Налоги, статус самозанятого, права на заказные ассеты и работа с соавторами лежат вне технического чек-листа, и разбираться с ними лучше до релиза, а не после первой выплаты.
Финальный прогон
Последние двадцать минут перед отправкой — в режиме черновика, с открытой debug-панелью и открытой консолью браузера.
- Открыть игру и ничего не трогать: дождаться стартовой рекламы, убедиться в тишине поверх ролика.
- Проверить три индикатора: лоадер
IT, Game Ready зелёный,文зелёный. - Нажать Clear cloud data, пройти первый запуск как новый игрок, затем уровень и F5.
- Вызвать interstitial дважды подряд: при
wasShown === falseигра продолжается так же. - Посмотреть rewarded до конца и закрыть досрочно — награда только в первом случае.
- Включить режим черепахи и проверить поведение при сетевых ошибках.
- Переключить вкладку, свернуть окно — звук замолкает, цикл встаёт.
- Открыть игру на телефоне и на десктопе, убедиться, что консоль чистая.
Важно
Если игра была на проверке больше 100 дней назад, при отправке появится предупреждение, что требования могли измениться. Не игнорируйте его: часть пунктов этого чек-листа со временем изменит номера или формулировки. Просматривать историю изменений требований дешевле, чем узнавать о новом пункте из письма с отказом.
Что дальше
Формально — ничего: чек-лист пройден, архив собран, кнопка нажата. Дальше начинается то, чего в руководстве быть не может, — ваша игра и её игроки. Публикация ничего не гарантирует: ни трафика, ни дохода, ни одобрения с первой попытки. Но она даёт обратную связь — метрики, отзывы, замечания модерации, — а это единственное сырьё, из которого получается вторая версия, заметно лучше первой.