SDK для разработчиков
Как подключить нашу игру к платформе. Один скрипт даёт облачные сохранения, таблицы рекордов и достижения. Игроку не нужен отдельный вход: он один для всей платформы.
Подключение
Добавьте скрипт в index.html игры и дождитесь инициализации:
<script src="/sdk.js"></script>
const sdk = await GamePlatform.init();
sdk.player.authorized // false — гость
sdk.player.name // имя игрока
sdk.lang // 'ru'
Игра работает в iframe, и каждый вызов SDK передаётся странице платформы через postMessage. Если открыть игру саму по себе, SDK перейдёт в автономный режим: игрок будет гостем, сохранения пойдут в localStorage, а таблицы рекордов будут недоступны. Это удобно при локальной разработке.
Игрок и сохранения
Сохранение — это произвольный JSON-объект размером до 200 КБ. Гостю оно сохраняется в браузере. Когда гость входит в аккаунт, сохранение переносится в облако, если там ещё пусто.
const save = await sdk.player.getData(); // весь объект
const { level } = await sdk.player.getData(['level']);
await sdk.player.setData({ level: 3, coins: 120 }); // запись откладывается на ~1,5 с и склеивается
await sdk.player.setData(data, true); // true — записать сразу
// Числовая статистика (до 100 ключей)
await sdk.player.incrementStats({ wins: 1 }); // → { wins: 12, ... }
await sdk.player.setStats({ bestTime: 93 });
const stats = await sdk.player.getStats();
// Предложить войти (окно поверх игры, без перезагрузки)
const { authorized } = await sdk.auth.openDialog();
sdk.on('auth', ({ player }) => { /* игрок вошёл */ });
Таблицы рекордов
Таблицы описываются в манифесте игры (см. «Публикация»). В зачёт идёт лучший результат игрока. Записывать результаты могут только вошедшие игроки, а читать таблицы могут все.
await sdk.leaderboards.setScore('score', 4200, 'необязательная строка до 128 символов');
const { entries, userRank } = await sdk.leaderboards.getEntries('score', {
top: 10, // до 20
includeUser: true, // добавить игрока и соседей, если он не в топе
around: 3, // до 10
});
// entries[i] = { rank, score, formattedScore, extraData, player: { id, name, isMe } }
const me = await sdk.leaderboards.getPlayerEntry('score');
Достижения
Достижения тоже объявляются в манифесте. Платформа сама показывает уведомление и начисляет очки в общий рейтинг. Если гость получил достижение, оно выдаётся после входа.
await sdk.achievements.unlock('first_win'); // { new: true, achievement }
const list = await sdk.achievements.list(); // [{ key, title, unlocked, ... }]
Загрузка, пауза, реклама
sdk.game.ready(); // игра загрузилась — платформа убирает свой экран загрузки
sdk.game.gameplayStart(); // начался/закончился активный геймплей
sdk.game.gameplayStop();
sdk.on('pause', () => { /* выключить звук и остановить время */ });
sdk.on('resume', () => { /* продолжить */ });
const { rewarded } = await sdk.ads.showRewarded(); // выдать награду, если rewarded
await sdk.ads.showFullscreen();
Реклама пока не подключена. Ролик за вознаграждение заменяет короткая пауза, после которой награда выдаётся. Полноэкранная реклама не показывается совсем (shown: false). Когда монетизацию подключат, код игры менять не придётся.
Публикация
Каждая игра описывается манифестом в database/catalog/<slug>.json:
{
"slug": "my-game",
"title": "Моя игра",
"tagline": "Короткое описание для карточки",
"description": "Абзацы через пустую строку",
"controls": "Прыжок — пробел\nСтрельба — ЛКМ",
"genre": "arcade",
"accent": "#12b886",
"glyph": "🚀",
"cover": "icons/icon-512.png",
"orientation": "landscape",
"source": "games/my-game/dist",
"leaderboards": [{ "name": "score", "title": "Лучший счёт", "default": true }],
"achievements": [{ "key": "first_win", "title": "Первая победа", "description": "…", "icon": "🏆", "points": 10 }]
}
Если игра не использует SDK и хранит прогресс в своём localStorage, перечислите эти ключи в поле "storage": ["my-game.save.v1"]. Платформа сама сохранит их в аккаунте игрока и восстановит перед запуском.
Сборка — это папка или zip-архив с index.html в корне. Все пути в ней должны быть относительными, кроме /sdk.js.
php artisan catalog:sync # манифесты + сборки
php artisan game:import my-game path/to/build.zip --prune # выложить новую версию
Каждая сборка получает свою версию (хеш содержимого) и отдаётся по адресу /play/<slug>/<версия>/. Поэтому файлы кешируются навсегда, а игроки сразу получают новую версию.