StadMagicОбзорАренаМирыРейтингДокументыКоманда

Как играть: руководство автора бота

Здесь описано, как зарегистрировать команду, подключиться к арене и написать клиент, который управляет коврами и собирает золото. Поля игрового запроса и ответа с полными примерами приведены в [справочнике игрового API](api.md); на сайте Hub эти страницы доступны в разделе «Документация».

1. Создать команду и получить токен

1. Откройте страницу Hub и перейдите в `/register`.

2. Введите уникальное имя команды (1–48 печатных символов). Сравнение уникальности не зависит от регистра: `MyBot` и `mybot` считаются одинаковыми.

3. Hub создаст случайный токен и покажет его один раз. Сохраните его в безопасном месте, например в переменной окружения или локальном файле, который исключён из Git.

4. Используйте этот токен в заголовке `X-Auth-Token` каждого запроса к игровой арене.

Токен не выбирается игроком и не является именем команды. Это секретный ключ доступа и стабильный идентификатор команды между разными аренами. Потерянный токен нельзя восстановить из сайта; зарегистрируйте новую команду, если секрет утерян. Имя можно изменить с помощью уже выданного токена, но смена имени не меняет сам токен или статистическую идентичность команды.

Не передавайте токен в URL, не коммитьте его, не печатайте в логах и не отдавайте браузерному JavaScript. В публичной среде используйте HTTPS. API отклоняет отсутствие токена и токен, которого нет в реестре, ответом `401 Unauthorized`.

Пример безопасной локальной настройки:


export DATS_PLAYER_TOKEN='сюда-вставьте-выданный-токен'

2. Найти арену и начать игру

На главной странице Hub показаны текущий мир и адрес активной арены. Арена меняется после завершения запуска; перед началом новой сессии проверяйте актуальный URL. Подключение — обычный HTTP POST к единственному игровому endpoint:


POST http://<адрес-активной-арены>/play/magcarp/player/move

X-Auth-Token: <выданный-токен>

Content-Type: application/json

Первый запрос токена создаёт команду и её флот. Чтобы запросить начальное состояние без команды, можно отправить `{"transports":[]}`. После этого возьмите ID ковров из `transports` ответа. ID непрозрачные и стабильные при респавне; не выводите их из имени или токена самостоятельно.

Игровой API объединяет наблюдение и управление: каждый POST принимает один пакет ускорений и возвращает полный актуальный снимок мира для вашей команды. Отдельного игрового GET нет. В ответе нет номера тика, поэтому планируйте частоту по серверному шагу 200 мс. Для пакета с хотя бы одной командой сервер принимает не более одного запроса на команду за игровой тик; лишний запрос получит `429`. Не делайте немедленный retry на `429` — дождитесь следующего интервала.

Удобный цикл бота:

1. Прочитать из ответа размеры мира, параметры ковров и список сущностей.

2. Для каждого живого ковра выбрать управляющий вектор.

3. Отправить один JSON-пакет со всеми рассчитанными командами.

4. Использовать возвращённый снимок как вход следующего цикла; обрабатывать сетевые ошибки и смену арены.

Короткий пример вызова из Python (пакет `requests`):


import os

import requests



arena = "http://127.0.0.1:8080"  # брать актуальный адрес из Hub

token = os.environ["DATS_PLAYER_TOKEN"]

headers = {"X-Auth-Token": token, "Content-Type": "application/json"}



state = requests.post(

    arena + "/play/magcarp/player/move",

    headers=headers,

    json={"transports": []},  # первый вызов: создать флот и получить ID

    timeout=2,

).json()



commands = [

    {"id": carpet["id"], "acceleration": {"x": 0, "y": 0}}

    for carpet in state["transports"] if carpet["status"] == "alive"

]

state = requests.post(

    arena + "/play/magcarp/player/move",

    headers=headers,

    json={"transports": commands},

    timeout=2,

).json()

Пример показывает только формат обмена и не задаёт стратегию управления. Серверный тик равен 200 мс; ограничение частоты и обработку ошибок см. выше.

3. Команда и ковры

Команда — игрок, идентифицируемый выданным токеном. Её флот содержит число ковров, заданное конфигурацией мира (обычно 5, в отдельных режимах 1 или 10). Новый токен создаёт новый флот. В ответе поле `name` — публичное имя команды, `points` — её текущий общий счёт, а `transports` содержит каждый отдельный ковер.

Поля собственного ковра:

| Поле | Смысл |

|---|---|

| `id` | Стабильный ID, используемый в командах; сохраняется при респавне. |

| `x`, `y` | Текущая позиция центра в координатах арены. |

| `velocity: {x, y}` | Вектор скорости. Длина вектора — скорость, направление — курс движения. |

| `selfAcceleration: {x, y}` | Последнее эффективное ускорение, заданное командой и ограниченное максимумом. |

| `anomalyAcceleration: {x, y}` | Суммарная сила аномалий в текущей точке; это внешнее воздействие, а не команда вашего бота. |

| `maxAccel`, `maxSpeed` | Лимиты приходят на верхнем уровне ответа и действуют на каждый ковер. |

| `status` | `alive` или `dead`. |

| `health` | Сейчас только индикатор жизни: 100 у живого, 0 у погибшего; убывающей шкалы HP нет. |

| `deathCount` | Сколько раз этот ковер погиб в текущем запуске арены. |

Положение — это `x,y`; три полезных вектора динамики — `velocity`, `selfAcceleration` и `anomalyAcceleration`. Модуль вектора ускорения ограничивается `maxAccel`, а модуль скорости после физического шага — `maxSpeed`. Команда задаёт ускорение, а не мгновенную скорость или координату назначения.

Если в запросе пропустить ковер либо его `acceleration`, сервер продолжит применять последнюю принятую команду. Для явного прекращения управляющей тяги отправьте нулевой вектор. Нулевая команда не означает мгновенную остановку: сохранённая скорость и внешние силы продолжают двигать ковер.

4. Мир и его сущности

Координаты и карта

`mapSize.x` и `mapSize.y` задают размеры арены. Начало координат `(0,0)` — нижний левый угол; `x` растёт вправо, `y` вверх. Все расстояния и скорости заданы в условных игровых единицах. Тик всегда равен 0,2 секунды. Активные профили и подробные настройки можно посмотреть на странице Hub `/worlds`; полный список профилей хранится в `assets/worlds.json`.

За пределами прямоугольника `0 ≤ x ≤ mapSize.x`, `0 ≤ y ≤ mapSize.y` ковер погибает. Проверяется координата центра. Граница сама по себе ещё не смерть; выход за неё — смерть.

Монеты (`bounties`)

Каждая монета сообщает `x`, `y` и `points`. При пересечении пути ковра с зоной сбора монета засчитывается, даже если центр ковра не совпал с центром монеты: сервер проверяет расстояние от центра монеты до всего отрезка движения ковра за тик. Порог в текущей настройке равен `2 × transportRadius`; для стандартного радиуса 5 это 10 игровых единиц.

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

Аномалии (`anomalies`)

Аномалия движется с постоянным на данный момент вектором `velocity`. Её параметры:

Внутри `effectiveRadius` аномалия добавляет силу к общей внешней силе ковра. Несколько воздействий векторно складываются. Модуль силы конкретной аномалии постоянен внутри зоны, а направление радиальное; результирующая сила меняется при движении относительно центра и других аномалий. Синяя/отталкивающая аномалия имеет отрицательный `strength`, красная/притягивающая — положительный.

Касание ядра уничтожает ковер; условие учитывает радиус ковра. Область действия силы шире смертельного ядра и сама по себе не означает гибель.

Противники (`enemies`)

`enemies` — плоский массив чужих ковров, а не массив команд. Элемент содержит координаты `x`,`y`, `velocity`, `status`, `health` и совместимые поля `killBounty`,`shieldLeftMs`. В текущей модели атаки и щиты не исполняются игровым API; не рассчитывайте на бой или защиту этими механизмами.

5. Физика, сбор золота и гибель

Для каждого тика сервер применяет схему Эйлера. В упрощённой записи:


V_next = clamp_length(V_now × friction + (A_command + W_anomalies) × 0.2, maxSpeed)

P_next = P_now + V_next × 0.2

`friction` зависит от профиля мира и не возвращается в игровом ответе. Значение меньше 1 уменьшает скорость на каждом тике; ближе к 1 — дольше сохраняет инерцию. Сервер сначала ограничивает командный вектор до `maxAccel`, складывает его с силами аномалий, обновляет и ограничивает скорость, затем позицию.

Ковер может погибнуть из-за любого из условий:

При гибели теряется заданный миром процент личного золота погибшего ковра; общий счёт уменьшается на ту же сумму. При включённом `enable_respawn` сервер возрождает ковер в безопасной случайной точке, сбрасывает скорость и ускорение, но сохраняет его ID и счётчик гибелей. При отключённом респавне ковер остаётся `dead`; если погиб весь флот, API вернёт `400 player_destroyed` и этот токен не сможет продолжить текущий запуск. В мирах с респавном первый спавн всё равно создаётся.

6. Технический цикл клиента

7. Формат и реальные ограничения

У запроса есть поля `id`, `acceleration`, а также совместимые `activateShield` и `attack`. Последние два поля сейчас не реализованы и игнорируются. Ответ содержит ряд исторических настроек боя и щита, однако наличие этих полей не означает наличия соответствующей механики. Единственное активное действие текущего игрового API — управляющее ускорение ковров.

Полный JSON-контракт, таблица кодов HTTP и copy-paste `curl` находятся на странице [Игровой API](api.md). Веб-приложение Hub также публикует эти два руководства в меню «Документация».