Публикация игр в Игротеке

Версия документа: 28.10.2026. Для разработчиков и ИИ. Использование документации и клиентских примеров разрешено: разрешение на интеграцию.

1. Нужно ли переделывать каждую игру?

Нет. Обычная HTML5/WebGL-игра может работать без SDK, если не зависит от чужой платформы и поддерживает изолированное окно. SDK нужен для профиля игрока, сохранений, рекламы и рейтингов. Игру под Яндекс SDK, другой портал или собственный backend необходимо адаптировать в местах этих вызовов. Один общий адаптер подходит только играм с одинаковым API: адаптер DroneBash нельзя просто вставить в произвольный Unity-проект.

2. Что подготовить

  1. Рабочую браузерную сборку, а не исходный Unity-проект и не EXE/APK.
  2. Файл запуска index.html и все его JS/WASM/DATA/StreamingAssets рядом по относительным путям.
  3. Обложку PNG/JPEG/WebP до 8 МиБ — она загружается отдельно в кабинете.
  4. Название, описание, жанр; список изменений необязателен.
  5. Реально поддерживаемые устройства: компьютер, мобильные или оба варианта; для мобильной игры — вертикальную или горизонтальную ориентацию; число игроков; PS4/PS5 либо отсутствие геймпада. Вертикальная обложка загружается по желанию.
  6. Необязательную тему MP3/OGG/WAV до 30 МиБ для страницы игры. Музыка игрового процесса входит в саму сборку, это разные настройки.

3. Структура ZIP и ограничения

В корне ZIP должен находиться index.html, а не внешняя папка проекта. Пример:

index.html
Igroteka/igroteka-sdk.js
Build/game.loader.js
Build/game.data.br
Build/game.framework.js.br
Build/game.wasm.br
StreamingAssets/...
TemplateData/...

Путь запуска в кабинете: index.html. Допускается другой существующий HTML-путь внутри ZIP.

ZIP: до 512 МиБ по текущей настройке портала. Распакованные файлы: суммарно до 1 ГиБ и в пределах квоты студии; один файл до 512 МиБ; максимум 10 000 записей архива. Квота студии задаётся владельцем отдельно. Портал запрещает выход из папки, символьные ссылки, дубликаты путей и серверные исполняемые файлы. Не включайте PHP, секреты, исходники, Library, Temp, файлы Unity DoNotShip, .meta. .htaccess из игры не применяется. Разрешены веб-ресурсы HTML/JS/CSS/WASM/DATA/BR/GZ/JSON, изображения, аудио/видео, шрифты и некоторые служебные бинарные расширения; полный актуальный список проверяет сервер при загрузке.

Портал передаёт архив частями по 1 МиБ. До конца «Обработки» не закрывайте вкладку. После обрыва используйте сброс незавершённой загрузки в том же черновике и выберите ZIP заново. Уже подключённая версия останется на месте.

4. Главное ограничение: изолированное окно

Игра запускается в iframe с sandbox="allow-scripts allow-pointer-lock", без allow-same-origin. Даже при размещении на том же домене window.origin внутри игры может быть "null". Так портал отделяет загруженные игры от аккаунтов и своих данных.

Нельзя рассчитывать на прямой доступ к parent.document, cookies портала, localStorage, IndexedDB, Cache Storage, service worker или авторизации через прямой fetch к API. Не пытайтесь снять sandbox. Используйте SDK: он передаёт ограниченные запросы родительской странице через postMessage. Реальный идентификатор игры выбирает портал по iframe; нельзя подменить его параметром SDK.

Ресурсы внутри ZIP загружайте относительно страницы игры. Не прописывайте /Build/, localhost, E:\..., IP сервера или полный домен. Для внешних ресурсов отдельно проверяйте HTTPS и CORS для изолированного контекста. Не добавляйте секретные ключи в JS или Unity-сборку.

5. Подключение SDK

Возьмите актуальный клиент из sdk/igroteka-sdk.js на портале либо из example-game.zip. Положите его в Igroteka/ и подключите перед логикой игры:

<script src="Igroteka/igroteka-sdk.js"></script>
<script src="game.js"></script>

В опубликованном /builds/... SDK сам определяет корень портала. Код игры должен использовать только разрешённые методы. Полный SDK также содержит методы аккаунта для оболочки портала, но внутри sandbox они не являются интерфейсом авторизации игры. Вход выполняется через профиль портала.

6. Загрузка и сохранение прогресса

const sdk = window.IgrotekaSDK;
let state;
let loaded = false;
async function startGame() {
  await sdk.init();
  const slot = await sdk.load();
  state = slot.payload ? JSON.parse(slot.payload) : {schema: 1, score: 0};
  loaded = true;
  // Теперь можно показать игровое меню и разрешить действия.
}
async function saveGame() {
  if (!loaded) throw new Error('Прогресс ещё не загружен');
  await sdk.save(JSON.stringify(state));
  await sdk.flush();
}

Пример использует JSON. Если ваша старая игра сохраняла Base64(JSON UTF-8), декодируйте именно этот формат и предусмотрите миграцию. Нельзя сначала записать значения по умолчанию, а затем читать сервер. При ошибке load остановите сохранения и предложите повторить загрузку; ошибка связи не означает пустой прогресс.

Лимит сохранения 256 КиБ. SDK ведёт очередь и ревизии сам. Не придумывайте revision вручную. При конфликте или смене аккаунта остановите запись и перезапустите игру с загрузкой актуальных данных. Не перезаписывайте сервер старой копией автоматически. Сохраняйте после значимых действий; одного unload недостаточно, браузер может оборвать запрос.

У гостя прогресс хранит родительский портал в браузере, у авторизованного игрока — сервер. В предпросмотре и модерации используется временное сохранение, рекламные награды не выдаются. Предпросмотр не доказывает работу постоянного облачного прогресса: это нужно проверить отдельно на опубликованной тестовой игре.

7. Завершение игры

Обычный выход ждёт очереди SDK. Если Unity передаёт снимок прогресса с задержкой, используйте протокол согласованного выхода из example-game.zip: igroteka:exit-capability, igroteka:prepare-exit, igroteka:exit-ready. Проверяйте event.source===parent и ожидаемый origin портала. Подтверждайте тот же id только после сохранения. Портал ждёт ответ до 3,5 секунды; сохраняйте регулярно заранее.

8. Реклама

pauseGame();
try {
  const ad = await sdk.showRewarded({placement: 'extra_life'});
  if (ad.rewarded === true) { grantExtraLife(); await saveGame(); }
} finally { resumeGame(); }

pauseGame/grantExtraLife/resumeGame — функции вашей игры, не готовые функции SDK. Для обычного показа используйте showInterstitial. Возвращаются shown, rewarded, reason, test. Не выдавайте награду по таймеру, при закрытии окна, ошибке, блокировке или отсутствии провайдера. В предпросмотре rewarded=false. Реальная монетизация требует подключённой и одобренной рекламной сети; техническое событие не является подтверждённым доходом.

9. Unity WebGL

  1. Соберите целевую платформу Web/WebGL с включёнными нужными сценами.
  2. Настройте canvas на размеры контейнера и проверьте портрет/альбом. Не закрепляйте игровой интерфейс за единственным размером экрана.
  3. Отключите Data Caching для браузерной сборки, предназначенной для sandbox, либо используйте загрузчик с проверенным отказоустойчивым обходом постоянного кэша.
  4. Проверяйте доступ к IndexedDB/PlayerPrefs: он может отсутствовать. Постоянные сохранения делайте через SDK.
  5. Brotli/Gzip поддерживаются порталом при корректных расширениях .br/.gz. Проверяйте ответы сервера и MIME в Network.
  6. Подключите свой C# ↔ JavaScript мост для init/load/save/рекламы. Не копируйте имена callback-объектов из другой игры без проверки.
  7. У DroneBash адаптер sdk/unity-adapter.js требует существующий YandexGamesBridge и конкретные Unity callbacks. Он не универсален. У «Коробок» свой адаптер.
  8. Удалите загрузку внешнего Яндекс SDK и замените все вызовы зависимых сервисов: сохранения, реклама, профиль, покупки, таблицы результатов. Неподключённые функции не имитируйте успешными.
  9. Игра должна загружаться и играть в настоящем предпросмотре кабинета, а не только в Unity Editor или отдельной вкладке.

Ошибка DroneBash с Cache Storage исправлена для известного Unity 6 loader на сервере портала и в её сборке. Это совместимость с конкретной сигнатурой, а не обещание исправить любой загрузчик автоматически. Для новой версии Unity снова выполняйте тесты.

10. Устройства, звук и геймпад

Выбор флага PS4/PS5 не добавляет управление в игру: реализуйте его и проверьте мышь одновременно с подключённым контроллером. Для HTML5 используйте Gamepad API; портал передаёт настройки поддерживаемому клиентскому runtime. Вибрация, гироскоп и адаптивные триггеры зависят от браузера и устройства и не гарантируются.

Мобильная версия должна иметь сенсорное управление, безопасные отступы и выбранную ориентацию. Музыку запускайте после пользовательского действия, учитывайте скрытие вкладки и паузу рекламы. Возможность полного экрана определяется браузером. Сетевой мультиплеер требует собственной работающей реализации; флаг в кабинете её не создаёт.

11. Публикация по шагам

  1. Зарегистрируйтесь на портале и создайте профиль студии с контактным email.
  2. Создайте новую игру; заполните описание, жанр и параметры устройств/игроков/геймпадов.
  3. Отдельно загрузите обложку и при желании тему страницы.
  4. На вкладке «Сборка и проверка» выберите ZIP, укажите index.html и дождитесь конца «Обработки».
  5. Откройте предпросмотр: компьютер, мобильный портрет, альбом. Проверьте старт, игровой процесс, звук и выход.
  6. Сохраните черновик и отправьте на модерацию. Пока идёт проверка, удаление заблокировано. После принятия модератором отозвать версию нельзя.
  7. При возврате прочитайте пункты отчёта и вложения. Исправьте игру/описание, загрузите новую сборку и отправьте повторно.
  8. Одобрение публикует игру автоматически. Каталог обновляется без ручной перезагрузки; другие открытые страницы могут увидеть обновление при следующем опросе.
  9. Обновления делайте отдельным черновиком существующего проекта. Текущая опубликованная версия остаётся доступной до одобрения замены.

12. Проверка перед модерацией

13. Диагностика

Не загружается .data/.wasm: проверьте пути, регистр, ответы HTTP, Content-Encoding и стартовый HTML. Ошибка window.caches: проверьте Unity Data Caching и изоляцию. Ошибка load: не записывайте пустой прогресс. Ошибка ZIP: проверьте структуру и расширения. Ошибка частей: сбросьте временную загрузку и повторите. Награда отсутствует в предпросмотре: это ожидаемо.

При обращении приложите ID проекта/версии, браузер и устройство, шаги воспроизведения, текст ошибок Console/Network и обезличенный скриншот. Не присылайте cookies, CSRF, пароль, ключ БД или секретное кодовое слово владельца.

Быстрое продолжение в открытой вкладке

Портал сохраняет только один приостановленный iframe. Другая игра, перезагрузка страницы, смена аккаунта или закрытие вкладки сбрасывают эту сессию. Это не замена сохранению прогресса. Для Unity используется pauseMainLoop/resumeMainLoop экземпляра createUnityInstance; при отсутствии поддержки выполняется обычный выход. Другие движки могут определить window.IgrotekaSession с асинхронными pause() и resume(). pause() должен остановить симуляцию, таймеры и собственный звук, resume() — продолжить. Игры с сетевыми матчами должны учитывать разрыв связи и не обещать сохранение матча.

Мобильная ориентация и вертикальная обложка

В «Устройства и управление» выберите мобильные устройства или оба варианта, затем вертикальную или горизонтальную ориентацию. Выбор обязателен при отправке мобильной игры на проверку. Он сообщается модератору и задаёт начальную ориентацию мобильного предпросмотра. Сам игровой движок должен корректно обрабатывать размер окна; настройка портала не переделывает интерфейс игры автоматически. В редакторе можно отдельно загрузить вертикальную обложку PNG/JPEG/WebP до 8 МБ (высота больше ширины, рекомендуем 600 × 900). На телефоне в вертикальном положении эта обложка используется как фон выбранной игры на главной и на странице информации об игре. При повороте телефона в горизонтальное положение применяется горизонтальная обложка, при обратном повороте — вертикальная. Карточки на главной и в поиске всегда используют горизонтальную обложку. На компьютере также применяется горизонтальная обложка. Загрузка вертикальной обложки необязательна. Изменения проходят модерацию вместе с версией игры. Поле «Что изменилось в этой версии» необязательно.

Действия геймпада

Если заявлена поддержка PS4/PS5, заполните в кабинете действия используемых кнопок и стиков: например, «Прыжок» для ✕, «Стрелять» для R2, «Движение» для левого стика. Неиспользуемые поля оставьте пустыми. Хотя бы одно действие обязательно при отправке новой версии на модерацию. Схема сохраняется вместе с версией и публикуется после её одобрения.

Названия описывают уже реализованное управление: портал не создаёт логику прыжка или стрельбы. В Unity привяжите свои Input Actions к стандартным элементам Gamepad (buttonSouth для ✕, buttonEast для ○, buttonWest для □, buttonNorth для △). При переназначении в портале сохраняется соответствие физической кнопки виртуальной кнопке, которую читает игра через установленный controller-runtime. Для стиков поддерживаются обмен местами, чувствительность, мёртвая зона и инверсия. Проверяйте сборку в предпросмотре: клавиатурное управление или собственные чтения ввода, обходящие runtime портала, автоматически не переназначаются. Системная PS и тачпад доступны только если их события отдаёт браузер.

Реклама перед запуском

Портал может показать подходящую оплаченную обычную рекламу перед новым запуском игры. При возобновлении приостановленной игры этого показа нет. Внутриигровые перерывы, баннеры и награды требуют вызовов SDK. Используйте актуальный SDK: платный показ подтверждается периодическими сигналами видимости. Награда выдаётся только при rewarded === true.