Ваша игра запускается локально и вы готовы связать её с платформой. Здесь начинается самая коварная часть пути: подключение SDK выглядит как одна строчка <script>, но именно в этой строчке ошибается большинство разработчиков — потому что почти все русскоязычные туториалы, статьи и ответы нейросетей до сих пор показывают загрузчик, который Яндекс уже не использует. Игра при этом работает: SDK инициализируется, реклама показывается, данные сохраняются. А модерация возвращает отказ.
В этой главе — правильное подключение, инициализация без гонок, порядок вызовов, который ждёт платформа, локальная разработка через официальный прокси и способ проверить всё это своими глазами до отправки на модерацию.
Зачем SDK вообще нужен
Без SDK игру не опубликуют: требование 1.1 прямо обязывает встроить SDK Яндекс Игр, а загрузка его из неофициального источника или инициализация с ошибками входит в список типовых причин отказа. Но дело не только в формальности. Через SDK работает всё, что отличает игру на платформе от html-страницы: сохранения игрока на сервере, реклама, покупки, лидерборды, язык интерфейса, определение устройства и события паузы, которые платформа шлёт вашей игре, когда показывает рекламу поверх неё.
Иными словами, SDK — это не «фича, которую можно добавить потом». Это точка входа, вокруг которой строится жизненный цикл игры.
Правильное подключение скрипта
Актуальная документация описывает два варианта — и выбор между ними определяется тем, где физически лежат файлы игры.
Игра залита архивом в Консоль разработчика (обычный случай)
<!-- Yandex Games SDK -->
<script src="/sdk.js"></script>Относительный путь. Никакого домена, никакой версии в URL. Файл раздаёт сама платформа рядом с вашим index.html.
Игра интегрируется через свой домен или iframe
<script src="https://sdk.games.s3.yandex.net/sdk.js"></script>Абсолютный путь применяется только в этом сценарии — документация формулирует это однозначно: на своём домене используйте https://sdk.games.s3.yandex.net/sdk.js вместо относительного /sdk.js.
Частая ошибка
Если в вашем коде, туториале или сгенерированном ответе нейросети встречается https://yandex.ru/games/sdk/v2 — это устаревший загрузчик. Его нет в текущей документации (проверено в сентябре 2026 года). Запрос по этому адресу пока отвечает 200 OK, поэтому игра будет работать, и вы ничего не заметите до отказа модерации: требование 1.19.1 обязывает использовать актуальный загрузчик, а debug-панель на старом покажет IF вместо IT. Дата отключения старого URL не объявлена — рассчитывать на него не стоит.
| Где размещена игра | Тег скрипта |
|---|---|
| Архив загружен в Консоль (игра на серверах Яндекса) | <script src="/sdk.js"></script> |
| Свой домен / интеграция через iframe | <script src="https://sdk.games.s3.yandex.net/sdk.js"></script> |
| Любой случай | https://yandex.ru/games/sdk/v2 |
Есть ещё две формы того же самого — асинхронная и динамическая, если вам важен порядок загрузки:
<script async src="/sdk.js" onload="initSDK()"></script>const script = document.createElement('script');
script.src = '/sdk.js';
script.async = true;
script.onload = initSDK;
document.head.appendChild(script);Важно
Скачивать sdk.js и класть его в архив игры не нужно — документация запрещает это прямо. Файл должен подтягиваться с платформы, иначе вы получите замороженную версию SDK и претензию по источнику загрузки. По этой же причине не стоит проксировать его через свой CDN.
Инициализация
YaGames.init() возвращает промис с объектом SDK. Скрипт /sdk.js должен быть подключён до того, как этот вызов произойдёт.
let ysdk = null;
async function initSDK() {
try {
ysdk = await YaGames.init();
console.log('SDK готов');
} catch (err) {
// Локальный запуск без прокси, сбой сети, блокировщик — игра
// всё равно должна стартовать, просто без платформенных функций.
console.warn('SDK недоступен, работаем автономно:', err);
ysdk = null;
}
}Единственный документированный параметр инициализации — signed:
// Покупки проверяются на клиенте (значение по умолчанию)
const ysdk = await YaGames.init();
// Покупки и данные игрока подписываются для проверки на вашем сервере
const ysdk = await YaGames.init({ signed: true });{ signed: true } нужен, только если у вас есть свой бэкенд, который будет проверять подпись. Для офлайн-игры с сохранениями в облаке Яндекса это лишнее.
Осторожно
Никогда не делайте старт игры зависимым от успешной инициализации SDK. Если промис отклонится (нет сети, ошибка платформы, вы открыли index.html двойным кликом), игра с обязательным await перед игровым циклом просто не запустится — а «игра не запускается / зависает экран загрузки» это одна из самых частых причин отказа (требование 1.14). Оборачивайте init() в try/catch и деградируйте до локального режима.
Порядок вызовов, который ждёт платформа
Само по себе подключение SDK — половина дела. Модерация проверяет ещё и то, в какой момент жизненного цикла вы вызываете методы. Правильная последовательность:
| Шаг | Что делаете | Зачем |
|---|---|---|
| 1 | Подключаете /sdk.js в <head> | SDK должен быть доступен до init() |
| 2 | await YaGames.init() | Получаете объект ysdk |
| 3 | Подписываетесь на game_api_pause / game_api_resume | Платформа сама показывает рекламу на старте |
| 4 | Загружаете ресурсы игры | Спрайты, звуки, уровни |
| 5 | ysdk.features.LoadingAPI?.ready() | Сигнал «игра готова», требование 1.19.2 |
| 6 | GameplayAPI?.start() / ?.stop() вокруг геймплея | Разметка игровых сессий |
Шаг 3 — тот, который пропускают чаще всего. Платформа автоматически показывает полноэкранную рекламу на старте всех игр. У этого показа нет коллбэков: вы не можете его отменить, отследить его конец через showFullscreenAdv или узнать о нём иначе, чем через события. Если ваша игра начинает играть музыку сразу после загрузки — звук будет накладываться на рекламный ролик, а это нарушение требования 4.7 (звук и геймплей должны быть остановлены на время рекламы).
async function boot() {
await initSDK(); // из примера выше
ysdk?.on('game_api_pause', () => {
audio.muteAll();
game.pause();
});
ysdk?.on('game_api_resume', () => {
audio.unmuteAll();
game.resume();
});
await loadAssets();
showMainMenu();
// Всё загружено, экранов загрузки нет, интерфейс кликабелен
ysdk?.features.LoadingAPI?.ready();
}
boot();Обратите внимание на ?. перед features.LoadingAPI — так пишет сама документация. Состав объекта features не гарантирован, и жёсткий вызов ysdk.features.LoadingAPI.ready() может упасть с исключением, обрушив запуск игры. Отписаться от события можно симметричным ysdk.off('game_api_pause', handler).
LoadingAPI.ready() обязателен по требованию 1.19.2, и Яндекс отдельно перечисляет два разных отказа: «Game Ready не используется совсем» и «Game Ready работает некорректно» — второй означает, что метод вызван не в тот момент. Вызывайте его тогда, когда все ресурсы загружены, все элементы интерактивны и на экране не осталось прелоадеров. Не в DOMContentLoaded и не сразу после init(). Подробнее о разметке геймплея через GameplayAPI — в отдельной главе.
Локальная разработка: sdk-dev-proxy
Относительный путь /sdk.js не резолвится, когда вы открываете файл с диска. Для локального запуска есть официальный npm-пакет:
# Если игра — статические файлы в папке
npx @yandex-games/sdk-dev-proxy -p ./dist
# Если у вас уже поднят свой dev-сервер
npx @yandex-games/sdk-dev-proxy -h http://localhost:3000Прокси поднимает HTTPS-адрес, подставляет настоящий sdk.js и открывает игру в контексте платформы. Поддерживается параметр ?game_url=https://localhost, домен — только localhost.
Важно понимать границы: локально вы проверяете, что код не падает и логика работает. Реальную рекламу, авторизацию Яндекс ID, серверные сохранения игрока и настоящий каталог покупок даёт только режим черновика — игра запускается по своему настоящему адресу на yandex.ru/games, но видна лишь вам.
Проверка через debug-панель
Это тот самый шаг, который экономит неделю на цикле отказов. Добавьте к URL игры параметр debug-mode=16:
https://yandex.ru/games/app/XXXXXX?debug-mode=16Тот же режим открывается кнопкой «Открыть с debug-панелью» в Консоли разработчика. На панели найдите индикатор загрузчика:
| Индикатор | Значение |
|---|---|
IT | Актуальный загрузчик — так и должно быть |
IF | Старый загрузчик — нарушение требования 1.19.1 |
W | Ожидание инициализации |
Если видите IF — вернитесь к тегу <script>. Скорее всего там прописан yandex.ru/games/sdk/v2. Отдельная деталь, которая сбивает с толку: панель по-прежнему сообщает версию как v2, хотя в URL загрузчика никакого сегмента версии больше нет. Ориентируйтесь на IT/IF, а не на строку версии.
TypeScript-типы
Если проект на TypeScript, официальные типы ставятся отдельным пакетом:
npm install --save @types/ysdkimport type { SDK, Player } from 'ysdk';
let ysdk: SDK | null = null;
let player: Player | null = null;Типы дают автодополнение по всему API — и заодно работают как страховка от устаревших вызовов: если вы напишете метод, которого в текущем SDK нет, компилятор скажет об этом раньше модератора.
Как заставить Claude Code писать актуальный код
Модели обучены на большом массиве старых статей и репозиториев, поэтому Claude Code по умолчанию склонен предложить именно yandex.ru/games/sdk/v2 — просто потому, что так написано в тысячах примеров. Лечится это не спорами в чате, а файлом CLAUDE.md в корне проекта: он подхватывается автоматически в каждой сессии.
## Яндекс Игры — актуальные правила SDK (проверено 09.2026)
- SDK подключается ТОЛЬКО как `<script src="/sdk.js"></script>`.
Абсолютный `https://sdk.games.s3.yandex.net/sdk.js` — исключительно для своего домена.
URL `https://yandex.ru/games/sdk/v2` использовать запрещено: старый загрузчик, требование 1.19.1.
- Не скачивать sdk.js в репозиторий и не проксировать его.
- `YaGames.init()` принимает только `{ signed }`.
- `ysdk.features.LoadingAPI?.ready()` обязателен — вызывать после загрузки всех ресурсов.
- Всегда подписываться на `game_api_pause` / `game_api_resume`.
- Любой вызов SDK — через опциональную цепочку, игра должна работать и без SDK.Совет
Заведите такой файл до того, как попросите Claude Code написать первую строчку интеграции. Правило, добавленное задним числом, не перепишет уже сгенерированный код — придётся отдельно просить пройтись по проекту. И проверяйте результат в debug-панели: CLAUDE.md снижает вероятность ошибки, но не отменяет проверку.
Что дальше
SDK подключён, инициализирован и виден в debug-панели как актуальный. Следующий обязательный шаг — сохранения: объект игрока, разница между setData и setStats, лимиты запросов и работа с гостем, который не авторизовался. Это требование 1.9 и одна из самых частых причин отказа, так что откладывать её на потом не стоит.