Shalter Games
Документация для разработчиков игр
Bot API Открыть Shalter

Игры в Shalter

Игра — одна HTML-страница с JavaScript. Её можно написать прямо в приложении, отправить в любой чат карточкой «▶ Играть», а рекорды игроков Shalter сохранит сам — общие и отдельно для каждого чата. Хостинг не нужен.

Что такое игра

Обычная веб-страница: HTML, CSS и JavaScript, можно canvas, WebGL, звук. Она запускается в изолированном окне — без доступа к аккаунту, cookie и сайту Shalter, — а с приложением общается через объект window.Shalter. Его вставлять не нужно: он уже есть, когда страница загрузилась.

Быстрый старт

  1. Shalter → Настройки → Игры → «Создать игру» (или меню «Игры» → «Мои игры»).
  2. Напишите название, выберите эмодзи и вставьте код — в редакторе уже есть рабочий пример.
  3. «▶ Запустить» — проверить, «Сохранить» — готово. Галочка «Показывать в каталоге» — игра будет видна всем.

Пример игры

Мини-игра «попади в мишень»: 20 секунд, за каждое попадание — очко.

<!doctype html>
<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width,initial-scale=1,user-scalable=no">
  <style>
    body { margin:0; height:100vh; background:#1e1e2e; color:#fff; font-family:system-ui; user-select:none }
    #t { position:absolute; width:90px; height:90px; border-radius:50%; background:#ff6b6b }
  </style>
</head>
<body>
  <h2>Очки: <span id="s">0</span> · ⏱ <span id="time">20</span></h2>
  <div id="t"></div>
  <script>
    let score = 0, left = 20;
    const t = document.getElementById("t");
    const move = () => {
      t.style.left = Math.random() * (innerWidth - 90) + "px";
      t.style.top = 80 + Math.random() * (innerHeight - 170) + "px";
    };
    t.onpointerdown = () => {
      score++;
      document.getElementById("s").textContent = score;
      Shalter.score(score); // текущий счёт
      move();
    };
    const timer = setInterval(() => {
      left--;
      document.getElementById("time").textContent = left;
      if (left === 0) {
        clearInterval(timer);
        t.remove();
        Shalter.gameOver(score); // конец игры — рекорд сохранится
      }
    }, 1000);
    move();
  </script>
</body>
</html>

Как игру отправить в чат

  • Скрепка → «Кубик и игры» → «🎮 Игры» → у игры кнопка «В чат».
  • Командой: /game змейка (или /игра 2048). Просто /game — открыть каталог.
  • Ботом: метод Bot API sendGame — см. Игры и боты.

В чате появится карточка с кнопками «▶ Играть» и «🏆 Рекорды». Рекорды этой карточки — общие для участников чата.

Счёт и рекорды

Shalter.score(points);    // текущий счёт — по ходу игры (можно часто)
Shalter.gameOver(points); // конец игры: рекорд сохранится, если он лучше прежнего

Сохраняется лучший результат игрока — в общей таблице и в таблице чата, откуда открыли игру.

Игрок, тема, чат

ПолеЧто внутри
Shalter.player{ id, name } — кто играет.
Shalter.theme{ dark, accent } — тёмная ли тема приложения и цвет акцента (например, #3390ec).
Shalter.chat{ id } — чат, откуда открыли игру, или null.
Shalter.versionВерсия SDK (сейчас 1).
if (Shalter.theme.dark) document.body.classList.add("dark");
document.querySelector("h1").textContent = `Привет, ${Shalter.player.name}!`;

Таблица рекордов

const best = await Shalter.getBest();                    // лучший результат игрока
const top = await Shalter.getLeaderboard({ limit: 10 }); // [{ position, name, score, isMe }]
const all = await Shalter.getLeaderboard({ chat: false }); // общая таблица, а не этого чата

Поделиться, вибрация, закрыть

Shalter.share();                 // «🎮 Игра: мой результат — N! Сможешь больше?» + карточка игры в чат
Shalter.share("Я прошёл уровень 5!"); // свой текст
Shalter.vibrate(40);             // вибрация на телефоне, мс
Shalter.close();                 // закрыть игру

Сохранения

localStorage работает как обычно: прогресс, настройки, уровни. Данные хранятся отдельно для каждой игры и каждого устройства.

Токен Game API

Настройки → «Игры» → у игры кнопка «🔑» (или в редакторе игры «🔑 API-токен»). Токен показывается один раз — сохраните его. Новый токен отзывает прежний. Все запросы — с заголовком:

Authorization: Bearer game_ВАШ_ТОКЕН
Токен — как пароль от игры. Держите его на своём сервере, не вставляйте в код самой игры: его увидит любой игрок.

Все методы

Адрес: https://shalter.ru/api/game-api/<метод>. Ответ — JSON с полем ok.

МетодПараметрыЧто делает
GET /getGame—Игра и статистика.
POST /updateGamecode, title, description, emoji, isPublicОбновить переданные поля. Код — до 512 КБ.
GET /getStats—{ plays, players, topScore }.
GET /getScoreschatId?, limit? (до 100)Таблица рекордов: общая или чата.
POST /setScoreuserId, score, chatId?, force?Записать результат. Без force — только если лучше прежнего.
POST /deleteScoreuserIdУдалить результаты игрока.
curl -H "Authorization: Bearer game_ВАШ_ТОКЕН" https://shalter.ru/api/game-api/getStats

Рекорды без накрутки

Счёт из браузера игрок может подделать. Для честных рекордов игра отправляет ход партии на ваш сервер, сервер сам считает очки и записывает их через setScore. А Shalter.gameOver() в игре тогда не вызывайте. Накрученный результат исправляется так же: setScore с force: true.

// Node.js, ваш сервер
await fetch("https://shalter.ru/api/game-api/setScore", {
  method: "POST",
  headers: { Authorization: `Bearer ${process.env.GAME_TOKEN}`, "Content-Type": "application/json" },
  body: JSON.stringify({ userId, score, chatId }),
});

Выкладка из репозитория

Держите игру в git и выкладывайте одной командой (например, в GitHub Actions после каждого коммита):

node -e '
fetch("https://shalter.ru/api/game-api/updateGame", {
  method: "POST",
  headers: { Authorization: "Bearer " + process.env.GAME_TOKEN, "Content-Type": "application/json" },
  body: JSON.stringify({ code: require("fs").readFileSync("game.html", "utf8") }),
}).then(r => r.json()).then(console.log)'

Игры и боты

Бот может отправить карточку игры в чат методом Bot API (токен бота, документация Bot API):

curl -X POST -H "Authorization: Bearer ТОКЕН_БОТА" -H "Content-Type: application/json" \
  -d '{"chatId":"c_…","gameId":"builtin-snake"}' https://shalter.ru/api/bot-api/sendGame

Можно отправлять встроенные, публичные и свои игры (своей считается игра владельца бота).

Ограничения

  • Код игры — до 512 КБ (картинки — data: URL или со своего сайта по https).
  • Игра работает в песочнице: без доступа к cookie, аккаунту и страницам Shalter.
  • Сеть — только к внешним сайтам по https (свой сервер, CDN).
  • До 50 своих игр на аккаунт.

Встроенные игры

gameIdИгра
builtin-2048🔢 2048
builtin-snake🐍 Змейка
builtin-flappy🐦 Shalter Bird

Вопросы по играм и API — в поддержку: напишите @hugo в Shalter.