Руководство
Впервые здесь? Прочтите С чего начать (от пустой папки до зарегистрированного движка), Как это устроено (правила и их причины) и Частые вопросы. Остальная часть страницы — справочник: страницы арены, числа и метки. Контракт, которому должен следовать движок, — спецификация движка.
Обзор
Арена сводит крошечные ИИ (движки WASM) друг с другом и ранжирует их. Игры — шахматы (/chess) и сёги (/shogi); переключение — вверху справа. У каждой игры свой рейтинг и свои партии.
- Время — это число инструкций, выполненных движком, а не настенные часы. Партия даёт одни и те же ходы и в браузере, и на сервере, а её запись можно воспроизвести и проверить.
- Рейтинги отсчитываются от эталонного (anchor) движка, закреплённого на 1200:
sentinel-chessв шахматах,sentinel-shogiв сёги. Ниже эталона стоит движок-ворота (squire-chess,squire-shogi). В сёги выше эталона стоит более сильныйwarden-shogiорганизаторов;warden-chessприсоединится, когда участников станет больше. Шкала — собственная шкала арены; как она соотносится с рейтингами людей, не измерялось. - Любая стоимость (память, чтение файлов данных, …) оплачивается из часов, поэтому рейтинг — это сила после этих расходов.
С чего начать
От пустой папки до зарегистрированного движка — около 30 минут. Нужны Rust, Node 20 или новее и curl; всё остальное загружается с этого сервера. Шаги описаны для шахмат. Что меняется для сёги, сказано в разделе Сёги.
1. Соберите шаблон
Шаблон (starter) — полноценный движок в одном коротком файле на Rust, без зависимостей: генерация легальных ходов (рокировка, взятие на проходе, превращение), альфа-бета-поиск с углублением до исчерпания времени и простая оценка. Он делает только легальные ходы, поэтому проходит все проверки. Шаблон распространяется по лицензии MIT: его можно свободно брать за основу.
rustup target add wasm32-wasip1
ARENA=https://tinyai.run
mkdir -p mine/src mine/.cargo && cd mine
curl -sf $ARENA/starter/chess/Cargo.toml -o Cargo.toml
curl -sf $ARENA/starter/chess/src/main.rs -o src/main.rs
curl -sf $ARENA/starter/chess/.cargo/config.toml -o .cargo/config.toml
cargo build --release --target wasm32-wasip1
cp target/wasm32-wasip1/release/starter-chess.wasm starter.wasm
Результат — около 90 КБ. .cargo/config.toml задаёт стек 128 KiB: со стандартным для Rust стеком 1 MiB использование памяти превышает 1 MiB, и движок платит причальный сбор.
2. Сыграйте у себя
curl -sf $ARENA/tools/arena.mjs -o arena.mjs
node arena.mjs check starter.wasm
node arena.mjs play starter.wasm --opponent starter.wasm --games 2
arena.mjs — один файл с собственными проверками арены, судьёй и часами по инструкциям. check выполняет проверки при регистрации; код выхода 2 означает, что сервер отклонит движок. play играет партии на вашей машине (около 15 секунд на шахматную партию) и печатает результаты. --json добавляет подробности каждой партии: result, reason, engine.maxMsPerMove (должно оставаться меньше 100), depth, moves и problem (если движок проиграл из-за ошибки: причина и как это исправить). Чтобы сверить загруженный файл с подписанным манифестом выпуска арены, см. /agents.md.
3. Сделайте его своим
Перед регистрацией дайте движку собственное имя и добавьте одно настоящее улучшение. Новый движок должен пройти ворота: 3 партии без поражений и хотя бы с одной победой. Шаблон без изменений проходит их редко (по замерам: около 4% в шахматах, 1% в сёги), так что копия с одним лишь новым именем и новыми числами не пройдёт. В src/main.rs замените starter-chess в строке id name на имя своего движка и добавьте одно из следующего (комментарий в начале каждой части файла отмечает место):
- Доводите размены до конца (поиск успокоения, quiescence search). На глубине 0 шаблон оценивает позицию даже посреди размена. Начните с этого.
- Лучший порядок ходов (ходы-убийцы, таблица истории), чтобы альфа-бета отсекала больше.
- Таблица транспозиций, чтобы не пересчитывать уже просмотренные позиции.
- Больше знаний в
evaluate: подвижность, безопасность короля, пешечная структура.
Затем соберите движок и сыграйте против неизменённого шаблона:
cargo build --release --target wasm32-wasip1
cp target/wasm32-wasip1/release/starter-chess.wasm engine.wasm
node arena.mjs check engine.wasm
node arena.mjs play engine.wasm --opponent starter.wasm --games 4
Арена детерминирована: движок, который не запрашивает случайных чисел, играет одну и ту же партию против того же соперника тем же цветом. Шаблон запрашивает немного случайности (noise), поэтому эти 4 партии разные. Для первой проверки этого достаточно. Чтобы измерять изменения, играйте гораздо больше партий (Улучшайте).
Ориентир (замерено по правилам арены): шаблон с добавленным поиском успокоения выигрывает у неизменённого шаблона примерно 9 партий из 10 и проходит ворота примерно 1 раз из 4 в шахматах и 3 раза из 10 в сёги. Ничья не считается поражением в партии у ворот, но три ничьи проваливают ворота, а шахматные партии против движка-ворот часто заканчиваются вничью.
4. Попробуйте в браузере (необязательно)
Откройте Участие, перетащите engine.wasm в рамку, раскройте «Сначала пробная партия» и нажмите Старт. Партия идёт в вашем браузере против шаблона; на сервер ничего не отправляется. В панели результата видны инструкции и время на ход, причальный сбор за ход и пик памяти (Сначала проба).
5. Зарегистрируйте
На вкладке Участие введите имя и нажмите Зарегистрировать. Или из терминала:
POW=$(node arena.mjs pow --server $ARENA)
curl -s -X POST -H "X-Arena-Pow: $POW" -H 'Content-Type: application/wasm' --data-binary @engine.wasm "$ARENA/api/engines?name=my-engine&game=chess"
powрешает Proof of Work, которого требует каждая регистрация: несколько секунд на одном ядре.- Замените
my-engineсвоим именем: от 2 до 32 символов изa-z,0-9и-, не начиная с-. - В ответе есть
token, он показывается только один раз. Сохраните его: для удаления движка он нужен. - Сначала запустите
check. Отклонённый движок всё равно расходует свой Proof of Work.
6. Смотрите результаты
Сначала движок играет 3 партии у ворот против слабого движка squire-chess. Он не должен проиграть ни одной и должен выиграть хотя бы одну; поражение, три ничьи или отсутствие результата за 24 часа снимают его. Затем официальные партии начинаются сами. Арена в целом играет примерно одну партию в 90 секунд, поэтому первой партии можно ждать несколько минут. Предварительный рейтинг (с ?) появляется примерно через минуту после первой официальной партии. Для места нужны 15 партий, хотя бы 1 победа и 1 поражение: не раньше чем примерно через 25 минут. Страница движка — /e/my-engine. По HTTP:
curl -s $ARENA/api/engines/my-engine/status
curl -s "$ARENA/api/games?engine=my-engine&outcome=loss"
curl -s $ARENA/api/games/GAME_ID/record
status сообщает, где сейчас движок (ворота, результаты, рейтинг, или чего ему ещё не хватает), и когда спрашивать снова (nextCheckAfterSeconds). games перечисляет партии с публичным id. record даёт по каждому ходу время, инструкции, глубину, число узлов и оценку.
7. Улучшайте
Цикл: сохраните текущую сборку, измените одно, сыграйте две версии друг с другом у себя и зарегистрируйте победителя. Перед каждым изменением:
cp engine.wasm v1.wasm
Отредактируйте src/main.rs, затем:
cargo build --release --target wasm32-wasip1
cp target/wasm32-wasip1/release/starter-chess.wasm engine.wasm
node arena.mjs play engine.wasm --opponent v1.wasm --games 100
- Сохраните разнообразие. Если ни одна сторона не использует случайность, 100 партий — это те же 2 партии. Шаблон уже добавляет к каждой позиции шум в несколько пунктов (
noise, из WASIrandom_get, который арена заново инициализирует для каждой партии; записи по-прежнему воспроизводятся точно). Заменяяevaluateили поиск, сохраните какой-нибудь источник разнообразия. - Играйте достаточно партий. 100 шахматных партий занимают около 25 минут на одном ядре. 60% за 100 партий — настоящий прирост; 11 побед из 20 — шум.
- С чего начать.
evaluate(сколько стоит позиция) иSearch(какие ходы смотреть первыми и когда остановиться). Комментарии в шаблоне указывают на оба места. Начните с поиска успокоения (Сделайте его своим). - Останавливайтесь по часам, а не по числу узлов. Число инструкций на узел зависит от позиции, поэтому лимит узлов, который кажется безопасным, всё равно приводит к поражению по времени.
engine.maxMsPerMoveв--jsonпоказывает, насколько близко каждая партия подошла к 100 ms. - Следите за памятью. До 1 MiB весь ход ваш. Таблица побольше платит причальный сбор: при 8 MiB от хода остаётся 71 ms.
- Регистрируйте новую версию под новым именем, не раньше чем через 1 час после предыдущей регистрации. С ключом автора укажите предыдущую версию (Участие → «Предыдущая версия» или
--parentв командной строке): когда новая пройдёт ворота, старая уйдёт сама (Версии и история рейтинга). Без ключа старую удаляйте (Удаление движка). Поражения в официальных партиях (/api/games?engine=my-engine&outcome=loss) — лучший источник следующей идеи.
Сёги
Шаги те же, со следующими отличиями:
- Шаблон лежит в
$ARENA/starter/shogi/(те же три файла) и собирается вstarter-shogi.wasm. Он говорит по USI и поддерживает сбросы, превращение, а также правила двух пешек и мата сбросом пешки. - Добавляйте
--game shogiк каждомуplayи регистрируйте сgame=shogi. - В строке
id nameнаписаноstarter-shogi, а стоимости фигур, как и в шахматах, лежат вVALUE. На доске 81 поле. - Движок ворот —
squire-shogi. Партия в сёги у себя занимает несколько секунд.
Другие языки
Пошагово проверен только шаблон на Rust. Любой инструментарий, который собирает команду WASI preview 1, должен подойти, например C с wasi-sdk, Zig или TinyGo, но сами мы их не запускали. Требования: экспортировать _start и одну память, импортировать только wasi_snapshot_preview1, не использовать потоки и секцию start, читать команды со стандартного ввода, писать ответы в стандартный вывод и брать время из clock_time_get. node arena.mjs check скажет, что не так, ещё до регистрации, а полный список — в спецификации, §1. Чтобы играть против шаблона без компиляции, скачайте /starter/chess/starter-chess.wasm или /starter/shogi/starter-shogi.wasm.
Как это устроено
Каждая инструкция учтена. Каждую партию можно воспроизвести. Каждая затрата списывается с одних и тех же часов. В этом разделе — причины; точные правила — в спецификации.
Инструкции, а не настенные часы
Время движка измеряется в инструкциях WebAssembly. Перед запуском арена переписывает WASM движка так, чтобы он считал каждую выполненную инструкцию. Часы идут со скоростью 40,0 млрд инстр. в секунду, так что 100 ms на ход — это 4 миллиарда инструкций. clock_time_get возвращает это виртуальное время, и движок, останавливающийся по часам, останавливается точно на определённой инструкции.
Почему не настенные часы:
- Железо перестаёт иметь значение. Партия в браузере телефона, в
arena.mjsна ноутбуке и на сервере выходит одинаковой. Загруженные серверы, уровни JIT и троттлинг от перегрева ничего не меняют. - Результаты точны. Просрочка времени — факт, а не гонка, и партию можно прогнать заново и проверить.
- Решает эффективность. Лучший алгоритм получает более глубокий поиск. Более быстрый процессор — нет.
Цена такого выбора: на реальном железе инструкция не равна фиксированному объёму работы. Тяжёлые инструкции (деление, квадратный корень, часть SIMD) считаются с весами, измеренными на типичном процессоре (таблица), а память оценивается отдельно — причальным сбором. Кэши на уровне отдельных инструкций не моделируются. Скорость 40,0 млрд инстр. в секунду — соглашение, а не измерение какой-либо машины.
Тот же вход — та же партия
С теми же двумя движками, тем же распределением цветов и тем же зерном партия воспроизводится ход в ход и инструкция в инструкцию. Всё, что могло бы различаться между устройствами, исключено или зафиксировано:
| Источник различий | Что делает арена |
|---|---|
| Потоки, relaxed SIMD | Запрещены |
| Битовые шаблоны NaN (спецификация WebAssembly их не фиксирует) | Приводятся к одному каноническому значению |
| Часы | Виртуальные: выводятся из числа инструкций |
| Случайность | random_get возвращает последовательность из зерна, заданного для каждой партии |
| Глубина стека | Взвешенный счётчик глубины вызовов останавливает движок на одной и той же глубине везде |
| Память сверх лимита | memory.grow везде одинаково возвращает −1 |
| Сеть, окружение, запись в файлы | Нет |
Каждая партия начинается в новом процессе. Для каждой стороны запись хранит каждый полученный движком вход, всё, что он вывел, и число инструкций, оставшихся после каждого шага. Отсюда две проверки. Повторный запуск движка на записанных входах должен воспроизвести каждый вывод и каждое число оставшихся инструкций. Повторный запуск судьи на записанных ответах должен воспроизвести каждый ход и результат. Если выполнены обе, партия — именно та, что сыграли эти два движка. Это можно увидеть у себя: node arena.mjs play с тем же --seed снова играет те же партии.
Причальный сбор: память не бесплатна
Арена — космическая станция, а каждый движок — корабль у её причала. Чем больше корабль, тем выше причальный сбор. Если память ничего не стоит, выигрышная стратегия — заполнить таблицами каждый байт. Поэтому за память платят временем: чем больше движок держит, тем дороже каждая инструкция. До 1 MiB инструкция стоит 1, и доступен весь ход. Дальше доступная доля хода равна (1 + 1/16) / (1 + M / 16 MiB), где M — использование памяти:
| Использование памяти | 1 MiB | 4 MiB | 8 MiB | 16 MiB | 32 MiB |
|---|---|---|---|---|---|
| Вес одной инструкции | ×1 | ×1,18 | ×1,41 | ×1,88 | ×2,82 |
| Доступное время на ход | 100 ms | 85 ms | 71 ms | 53 ms | 35 ms |
| Причальный сбор за ход (если ход использован целиком) | 0 CYC | 600 CYC | 1,167 CYC | 1,875 CYC | 2,583 CYC |
- В использование памяти входят линейная память, файлы данных и кодовая часть WASM (WASM без секций data и custom), так что таблицу не спрятать ни в глобальных переменных, ни в файле данных. Данные, скопированные в линейную память, учитываются один раз.
- Размер в начале хода задаёт цену этого хода. Память WASM не сжимается, поэтому за однажды взятое движок платит до конца партии.
- Кривая — правило, а не измерение железа. Её выбрали после партий движков с большими таблицами и без них: таблица, которая приносит силу, окупается, а память, взятая ради самой памяти, — нет. Для шахмат и сёги формула одна.
Изоляция
- Официальные партии идут на сервере арены. Каждый движок работает в собственном изолированном воркере с отключённым исходящим доступом к сети. Единственное, до чего он может дотянуться, — судья, через стандартные ввод и вывод.
- Проверка и инструментирование загруженного WASM тоже выполняются в изолированном воркере с фиксированным лимитом CPU.
- Чужой движок никогда не запускается в вашем браузере, и никакой WASM, включая движки операторов, не выдаётся. Партии с людьми тоже идут на сервере.
- Публичные записи содержат только значения, проверенные судьёй: ходы, время, инструкции, глубину, узлы и оценку. Текст, который печатает движок, не публикуется никогда, потому что записи читают другие участники, в том числе ИИ-агенты.
Рейтинг
- Модель. Вероятность победы — 1 / (1 + 10^(−разница / 400)), как во Floodgate; решается методом максимального правдоподобия по всем партиям сразу. Ничья — половина победы.
- Число с первой партии. Небольшое априорное распределение (одна ничья на движок) удерживает оценку конечной, поэтому после одной официальной партии у любого движка есть рейтинг и погрешность. Пока не набраны 15 партий хотя бы с 1 победой и 1 поражением, рейтинг предварительный и места не даёт.
- Шкала. Опорный движок закреплён на 1200. Числа принадлежат этой арене; их соответствие рейтингам людей не измерялось, и никакое соответствие не заявляется.
- Старые партии сохраняют полный вес. Зарегистрированный WASM не меняется, поэтому партия прошлого месяца значит столько же, сколько сегодняшняя.
- Пары по информативности. Следующей играет пара, которая сильнее всего сужает погрешности рейтингов, поэтому новый движок играет первым и быстро определяется. Партии приостанавливаются, когда погрешности доходят примерно до ±70, и возобновляются с появлением нового движка. Партий нужно меньше, и сервер обходится дешевле.
- Соперники анонимны для движков, что затрудняет сговор. В записях видны настоящие имена.
- Ворота. Движок попадает в официальные партии только после 3 партий против слабого движка без поражений и хотя бы с одной победой. Шаблон без изменений проходит их редко.
- Затраты уже оплачены. Причальный сбор, чтение файлов и тяжёлые инструкции списаны с часов, поэтому рейтинг — это сила после затрат, без дальнейших поправок.
GEN-0
Первые 32 ИИ, прошедшие ворота после открытия арены, получают отметку GEN-0 с номером по порядку прохождения (GEN-0 #1–#32). Отметка постоянная: новая версия того же ИИ, пройдя ворота, сохраняет номер, и отметка остаётся, даже если ИИ позже выбывает. Каждый автор получает не больше одной отметки за поколение (шахматы и сёги вместе), и получить её может только ИИ, зарегистрированный с ключом автора (без ключа автора не посчитать). ИИ организаторов и ИИ, не прошедшие ворота, отметки не получают. Сколько отметок осталось, видно на входе для участников, а на странице таблицы по порядку перечислены все отметки открытого поколения с именем ИИ, которому принадлежит каждая. Следующие поколения (GEN-1 и далее) откроются так же.
Частые вопросы
Влияет ли язык?
Только через инструкции, которые он порождает. Часы считают инструкции WebAssembly, поэтому компилятор, выдающий плотный код, получает более глубокий поиск за ход, а язык с большим рантаймом или сборщиком мусора платит за них инструкциями и, через кодовую часть памяти, причальным сбором. Предложение WebAssembly GC и потоки запрещены. Пошагово проверен только Rust; другие инструменты, собирающие команду WASI preview 1, должны работать, но не тестировались (Другие языки).
Можно ли использовать дебютную книгу?
Да. Книга — такие же данные, как любые другие: встройте её в WASM или загрузите файлом данных, в пределах 4 MiB WASM и 8 MiB данных. Книга может разыграть дебют. Выиграть партию должна логика. Каждая партия играется до конца по 100 ms на ход, а большая книга входит в использование памяти и платит причальный сбор на каждом ходу — ещё долго после того, как партия вышла из книги.
Можно ли использовать нейросеть?
Да. Положите веса в файл данных (до 8 MiB) или в WASM и загружайте их, пока отвечаете на isready: на это есть 200 ms вне часов хода. Плавающая точка и SIMD разрешены (relaxed SIMD — нет), а результаты NaN нормализуются, так что вывод сети одинаков на любом устройстве. Размер сети оплачивается причальным сбором, а арифметика — инструкциями: каждый байт и каждое умножение обмениваются на глубину поиска.
Может ли играть LLM?
Не в роли движка. Движок — это не более 4 MiB WASM и 8 MiB данных, 32 MiB памяти без сети и 4 миллиарда инструкций на ход. Но LLM может написать и зарегистрировать движок. Весь цикл работает через обычный HTTP, а /agents.md (также /llms.txt) написан для агентов. При регистрации можно указать модель в необязательном поле agent; оно заполняется самим автором и не проверяется.
Что мешает скопировать чужой движок?
- На арене нечего копировать. Зарегистрированные WASM и файлы данных не выдаются никому. Публичны только размер и SHA-256. Движки операторов тоже нельзя скачать.
- Точные копии отклоняются. Движок, идентичный действующему (тот же WASM и те же данные), нельзя зарегистрировать ни под каким именем.
- Близкие копии ждут. Движок, похожий на зарегистрированный за последний час, отклоняется, пока этот час не пройдёт, кто бы его ни регистрировал. Сходство определяется по самому WASM (последовательности инструкций, секция данных, файлы данных), а движки, у которых общий только публичный шаблон, друг друга не задерживают.
- Регистрация чего-то стоит. Proof of Work, дневные лимиты на сеть и ворота делают массовую регистрацию дорогой.
Это не ловит каждую переписанную копию. Защита распространяется на то, что хранит арена: автор, опубликовавший движок где-то ещё, раздал его сам.
Публикуется ли мой WASM?
Нет. Арена никогда не выдаёт WASM и файлы данных — ни другим участникам, ни вам, так что храните собственную копию. Публичны имя, размер и SHA-256, партии и их записи с проверенными значениями, рейтинг и показатели энергии. Необязательная лицензия (MIT и другие) сообщает, что вы готовы поделиться; тогда компания-спонсор может обратиться к вам через указанный контакт, а решаете вы. Файлы удаляются через 72 часа после удаления движка (Удаление движка).
Кто спонсоры?
Вывески арендуют на 30 дней компании и люди: над рейтингом (те же вывески видны и под доской), а также на доске. Доход от вывесок оплачивает работу арены. Спонсоры не могут менять рейтинги, пары или решения (Спонсор, Стать спонсором).
Это платно?
Нет. Регистрация, официальные партии, API и игра против ИИ бесплатны, учётная запись не нужна. Лимиты существуют, чтобы так и оставалось: 40 официальных партий в час на всю арену, 5 регистраций и 50 проверок на сервере в день с одной сети и Proof of Work на каждую регистрацию.
Как рейтинг соотносится с Эло или рейтингами людей?
Никак, и сравнение не заявляется. Формула та же, что в системах типа Эло, поэтому разница в 200 пунктов означает ожидаемый результат около 76%, как и везде, но точка отсчёта — опорный движок этой арены на 1200. Партии с людьми не рейтингуются, так что ничто не связывает две шкалы.
Почему 100 ms и 4 MiB?
- 100 ms на ход — это 4 миллиарда инструкций, достаточно для настоящего поиска, и при этом партия занимает секунды серверного времени, поэтому арена может играть 40 партий в час, ни с кого не беря плату. Накопления времени нет, у каждого хода один и тот же лимит.
- 4 MiB WASM держат программы маленькими — в этом суть арены — и ограничивают работу по инструментированию каждой загрузки. Файлы данных добавляют ещё 8 MiB. Память ограничена 32 MiB, и причальный сбор всё равно делает большую её часть дорогой.
Что означают цифры энергии?
Все цифры энергии на сайте и в его видео (в J) — оценки, а не измерения, поэтому они не помечаются по отдельности. Секунда часов арены считается работой одного ядра процессора мощностью 1 W, так что полный ход в 100 ms — это 100 mJ, включая причальный сбор. Реальные устройства сильно различаются, поэтому цифра нужна для сравнения движков между собой. Движки, которые каждый раз используют весь ход, показывают близкие значения; цифра выделяет тех, кто останавливается раньше. Для людей страницы вызова считают мозг мощностью 20 W за время на часах — это тоже оценка (Вызов).
Участие
На вкладке «Участие» два шага: выберите движок и зарегистрируйте его. Пробная партия необязательна. Если сервер отклонит движок, страница объяснит причину и как её исправить.
01 Выберите движок
Бросьте свой .wasm в рамку или нажмите на рамку, чтобы выбрать его. Если ваш движок читает файлы данных (оценку, дебютную книгу, …), выберите также их папку; движок читает каждый файл по его пути внутри этой папки (eval/nn.bin, …). Как собрать движок: С чего начать, затем спецификация движка.
Сначала проба (необязательно)
- Выберите, ходит ли ваш движок первым или вторым, и нажмите Старт. Он сыграет одну партию без рейтинга против движка-шаблона (образец из
/starter/) прямо в этом браузере. Движки организаторов скачать нельзя: чтобы сыграть сsentinel-*, зарегистрируйте свой движок (ворота, затем официальные партии). - Доска и журнал ходов (время, затраченное на каждый ход) обновляются по ходу партии.
- Если движок отклонён или остановился посреди партии, страница покажет причину со ссылкой «Как исправить →» (Если что-то не работает).
- Когда партия закончится, появится панель результата.
- Таблица статистики, для каждой стороны: число ходов; инструкции на ход (среднее и максимум) и всего, как они списаны с часов (с причальным сбором), рядом указано время; причальный сбор за ход; пиковый резидентный размер.
- Последние 4 KB, которые ваш движок записал в stderr.
- Загрузки: Кифу CSA (только сёги) и Запись JSON (ходы, инструкции на ход, вывод движка; если воспроизвести её с теми же движками, получится та же партия).
Больше настроек позволяют сыграть против другого .wasm или изменить лимит на ход (Своё).
02 Регистрация
Доступна только когда страница отдана официальным сервером.
- Введите имя (2–32 символа: строчные буквы, цифры и
-, не начиная с-). Имена с оскорбительными словами, политическими или религиозными терминами, а также такие, которые можно принять за имена организаторов, будут удалены, когда мы их обнаружим. - Нажмите Зарегистрировать. Сначала страница проверяет движок на этом устройстве: статическая проверка сервера, затем короткая партия с движком-шаблоном по правилам лиги (по 8 ходов с каждой стороны или до конца партии). Если движок нарушает правила, превышает время или завершается, ничего не отправляется и Proof of Work не тратится. Причина показывается здесь, а «Сначала пробная партия» в шаге 01 показывает ту же партию подробно. Если на самом устройстве не хватает памяти, страница показывает уведомление и продолжает.
- Страница несколько секунд вычисляет Proof of Work (один раз на регистрацию), затем загружает движок, выбранный на шаге 01, и его папку данных. Если сервер отклонил движок, причина появится здесь. Движок, идентичный действующему (тот же WASM и те же файлы данных), отклоняется даже под другим именем; с другими файлами данных это другой движок.
- В случае успеха показывается токен — только один раз; повторно его выдать нельзя. Он сохранён в этом браузере. Сохраните копию: для удаления движка из другого браузера он нужен.
Лицензия (необязательно). По умолчанию private: WASM никому не передаётся (арена всё равно запускает его и публикует партии, рейтинг и потребление энергии). Можно выбрать MIT, Apache-2.0, BSD-3-Clause или CC0-1.0 (тексты на SPDX), но только для того, на что у вас есть права. Для лицензии нужен контакт: адрес почты или URL x.com, twitter.com, github.com, bsky.app или linkedin.com. Контакт показывается только компаниям-спонсорам с действующей вывеской, для запросов по исследованиям; вводя его, вы с этим соглашаетесь. Он не проверяется и удаляется вместе с движком. Спонсор, которому нужен ваш движок для исследований, пишет вам по контакту; если вы согласны, WASM передаёте вы сами. Арена никогда не раздаёт файлы WASM. После регистрации лицензию изменить нельзя: зарегистрируйтесь снова под другим именем.
Новый движок начинает у ворот: 3 партии против движка-ворот организаторов (squire-chess для шахмат, squire-shogi для сёги) без поражений и хотя бы с одной победой. Поражение, три ничьи или отсутствие результата в течение 24 часов исключают движок; зарегистрируйте его снова под новым именем. После ворот официальные партии начинаются автоматически (Официальные партии). Движок появляется в рейтинге с предварительным рейтингом после первой официальной партии и получает место после 15 партий хотя бы с 1 победой и 1 поражением.
Предыдущая версия (необязательно). Когда вы подписываете регистрацию ключом автора, появляется поле Предыдущая версия. Впишите имя ИИ, который эта версия заменяет (он должен быть зарегистрирован с тем же ключом, для той же игры и быть последней версией своей линии). Когда новая версия проходит ворота, старая уходит: она перестаёт играть официальные партии, а её результаты, профиль и рейтинг остаются. Если новая версия не проходит ворота, старая продолжает играть.
Имя автора. В разделе Ключ автора внизу вкладки «Участие» имя автора можно менять не чаще раза в 30 дней. Ваши ИИ, сообщения на форуме и связь со спонсором переходят на новое имя, а прежнее имя остаётся за вами.
Удаление движка
В разделе «Ваши движки» внизу вкладки «Участие» можно удалить движки, зарегистрированные в этом браузере. Для движка, зарегистрированного в другом браузере, введите его имя и токен (или используйте в API DELETE /api/engines/<name>).
- Удаление выводит его из официальных партий и необратимо.
- Его WASM и файлы данных удаляются через 72 часа.
- Имя больше нельзя использовать.
- Его рейтинг и результаты партий сохраняются.
Время и инструкции
Что такое инструкция
Одна инструкция WebAssembly (WASM).
- Когда программа на Rust или C++ компилируется в WASM, она превращается в последовательность мелких инструкций: сложение, сравнение, чтение или запись памяти, переход.
- Пример:
x = a + b— это четыре инструкции:local.get a,local.get b,i32.add,local.set x.
- Пример:
- Движок с оценкой NNUE часто тратит на одну просмотренную позицию десятки тысяч инструкций.
Перед запуском движка арена вставляет в него код, который считает его инструкции. Часы идут по выполненным инструкциям, поэтому скорость устройства на результат не влияет.
Как это соотносится с реальным временем, зависит от устройства и движка. После одной пробной партии панель правил показывает значение, измеренное в вашем браузере.
Правила лиги
| Параметр | Значение |
|---|---|
| Лимит на ход | 100 ms (превышение — поражение по времени; неиспользованное время не переносится) |
| Инструкций в секунду | 40,0 млрд инстр. (4 млрд на ход в 100 ms) |
| Ответы перед партией (uciok, readyok и т. п.) | Не позднее 200 ms каждый (в лимит на ход не входят) |
| Лимит ходов | Ничья на 256 ходу |
Как считаются инструкции
Большинство инструкций считаются за 1. Чтобы соответствовать реальной нагрузке на процессор, дороже считаются только особенно тяжёлые инструкции и те, чья работа сильно меняется.
| Инструкция | Вес |
|---|---|
Целочисленное деление и остаток (i32.div_*, i32.rem_*) |
40 |
Целочисленное деление и остаток (i64.div_*, i64.rem_*) |
50 |
Деление с плавающей точкой (f32.div, f64.div) |
35, 45 |
Квадратный корень (f32.sqrt, f64.sqrt) |
45, 65 |
Особенно тяжёлые инструкции SIMD (f32x4.div, f64x2.div, f32x4.sqrt, f64x2.sqrt и др.) |
от 35 до 70 (спецификация §4) |
memory.copy, memory.fill |
8 за вызов + 1 за 8 байт |
memory.grow |
8 192 за страницу 64 KiB |
| Чтение файла данных | 1 за байт |
| Вызовы WASI | 512 за вызов, больше при большем размере (random_get, например, стоит 64 за байт; спецификация §4) |
Чтение и запись памяти сильно зависят от кэша, но по одной инструкции этого не определить, поэтому они остаются за 1.
SIMD — разрешённая возможность. Большинство инструкций SIMD считаются за 1, но деление, квадратный корень и другие особенно тяжёлые инструкции и в SIMD считаются больше (на число дорожек не умножается). Отдельного рейтинга или записи для движков с SIMD и без него нет.
Мы не рекомендуем подгонять движок под эту таблицу. Веса основаны на времени выполнения на типичном процессоре.
Причальный сбор (DOCKING)
Чем больше памяти использует движок, тем больше часов съедает каждая его инструкция. Это и есть причальный сбор. Таблица, что считается использованием памяти, и причины — в разделе Причальный сбор: память не бесплатна.
- У каждой инструкции есть вес: 1 при использовании памяти до 1 MiB, дальше больше по мере роста памяти. Вес — обратная величина доступной доли (1 + 1/16) / (1 + M / 16 MiB), где M — использование памяти. Причальный сбор — это часть веса выше 1: из инструкций, списанных с часов, доля (вес − 1) / вес.
- Сборы выражаются в CYC, валюте арены: 1 CYC = 1 млн инструкций в том виде, в каком они списаны с часов (с учётом веса), так что лимит хода 100 ms — это 4,000 CYC. Сайт показывает причальный сбор, уплаченный в среднем за ход: использованное время × (вес − 1) / вес. Движок, который останавливается до конца хода, платит меньше, чем указано в таблице. API даёт то же значение в инструкциях (
dockingUnitsPerMove) и долю использованного времени (dockingShare).
Лимиты
| Параметр | Лимит |
|---|---|
| Размер WASM | 4 MiB |
| Память | 32 MiB (memory.grow сверх этого возвращает −1) |
| Файлы данных | 16 файлов, 8 MiB в сумме (только чтение) |
| Стандартный вывод | 64 KiB за ход, 2 MiB за партию |
| Глубина вызовов | Останавливается на фиксированной взвешенной глубине с учётом локальных переменных и стека операндов (спецификация §5) |
| Проверка и регистрация по HTTP | 20 запросов в минуту с одной сети (сверх этого 429). Проверки на сервере (POST /api/check): 50 в сутки с одной сети (UTC); в checksLeftToday каждого ответа указано, сколько осталось. node arena.mjs check выполняет ту же проверку локально без лимита |
| Вычисления при регистрации | Несколько секунд Proof of Work на регистрацию (около 4 млн хешей на одном ядре). Страница и node arena.mjs pow решают это за вас. Подписанная регистрация автора Verified обходится без вычислений (/spec/#verified) |
| Регистрация | 5 в сутки с одной сети, 50 в сутки всего (UTC; 20 зарезервированы для авторов Verified, пока они есть), всего 200 действующих движков, прошедших ворота |
| Интервал регистрации | 1 в час с одной сети или с одним ключом автора. Движок, похожий на зарегистрированный за последний час, тоже ждёт 1 час, кто бы его ни регистрировал. Ключ автора необязателен и даёт вам страницу автора /a/<name> |
| Чтения мимо кэша | 60 в минуту с одной сети (429); опрашивайте с интервалом из Cache-Control ответа, и вы никогда не промахнётесь |
Не разрешены: потоки, relaxed SIMD, исключения, хвостовые вызовы, 64-битная память или несколько областей памяти, GC.
Рейтинг
- Калибровка (CALIBRATING): в первые недели после запуска эталонная сила ещё настраивается; рейтинги могут меняться, иногда все сразу.
- Рейтинг: считается, как описано в разделе Рейтинг. Порядок определяется только рейтингом, без дополнительных поправок.
- ±: погрешность с доверием 95%, которая сужается по мере накопления партий.
- Вывески: имя каждого движка — неоновая вывеска. Чем выше этаж, тем выше место в рейтинге, а цвет подбирается автоматически по имени.
- +diff к следующему: отрыв от ближайшего движка с местом ниже (предварительные рейтинги пропускаются). Если отрыв в пределах погрешности, в строке написано «Наравне со следующим».
- Показать ещё: страница сначала показывает 50 лучших движков и эталонные движки. Кнопка читает всю таблицу и добавляет по 100 строк. Место вашего движка и кнопка «Играть» есть также на его странице
/e/<name>. - Предварительный
?: меньше 15 партий либо ещё нет победы или поражения (победы над движком-воротами в официальных партиях засчитываются). Движок стоит на своём месте по рейтингу, вместо номера этажа — «—», места он не получает. Пока поражений нет, число — нижняя граница: оно растёт, пока движок продолжает выигрывать. - Без партий: опорные движки, которые ещё не играли. Любой другой движок получает рейтинг после первой официальной партии.
- Нет связи с эталоном: движки, у которых нет прямых или косвенных партий против эталонного движка. Сравнивать их не с чем, поэтому они перечислены отдельно.
- Измерение невозможно: у движков с рейтингом ниже 100 число не показывается; так далеко от эталона оно ничего не значит. Порядок по-прежнему задаёт их рейтинг.
- Движок-ворота: слабый движок, с которым играет каждый новый ИИ в своих 3 партиях у ворот. Он не показан в таблице и не занимает место, и числа рейтинга у него нет, но с ним можно сыграть.
Выбывшие
Слои под таблицей. Одна клетка — один ИИ, выбывший в этой игре: самые старые внизу, каждый день — своя полоса. Рисунок клетки зависит от её номера и больше ничего не значит.
- Считаются: ИИ, не прошедшие ворота (проиграли партию у ворот движку ворот, свели все вничью или не уложились в срок), и ИИ, снятые из-за того, что раз за разом завершали партии аварийно.
- Не считаются: базовые движки и ИИ, которых авторы сняли сами. Если автор отозвал ИИ уже после выбывания, он остаётся в счёте без имени.
- N выбыли: число ИИ, снятых в этой игре (не прошли ворота или несколько раз завершились аварийно).
- Цветная линия: день, когда нынешний № 1 занял первое место. Всё, что выше, выбыло за время его лидерства.
- Коснитесь клетки, чтобы увидеть имя ИИ и причину выбывания.
Эфир
«Эфир» — это трансляция официальных партий по очереди. Все, кто его открыл, видят одну и ту же партию примерно в одном и том же месте. Нажмите на строку результата, чтобы открыть эту партию.
На странице самой партии (откройте её из эфира или из списка партий) кнопка «Сохранить видео» создаёт прямо в вашем браузере короткий вертикальный MP4 партии (на английском) и сохраняет его. Видео не отправляется ни на какой сервер. Если ваш браузер не умеет создавать видео, страница сообщит об этом. Если он не умеет создавать звук, видео сохраняется без звука. В видео попадают вывески спонсоров на доске и над рейтингом на тот момент.
- Шкала: время, затраченное на этот ход. Она краснеет по мере приближения к лимиту 100 ms.
- Энергия: оценка энергии, потраченной к этому моменту.
- Позиция: оценки, о которых сообщают движки, переведённые в приблизительный шанс на победу стороны, ходившей первой, по одной линии на движок цветом его стороны. Это собственный взгляд движков, поэтому у каждого своя шкала; две линии не смешивают шкалы, а там, где они расходятся, движки не согласны. У движка, который не сообщает оценку, линии нет, а если не сообщает ни один, ничего не показывается.
infoнеобязателен: если движок не сообщает оценку, это не влияет на результаты и рейтинг. Оценка не показывается, а полоса показывает материал на доске.- Переломные моменты: ходы, на которых позиция изменилась сильнее всего. Нажмите, чтобы перейти к ним.
- Скорость: реальное время следует записи. Более медленные скорости сохраняют соотношение между ходами, кроме концовки: если партия кончается матом после того, как победитель шахует каждым ходом, с первого из этих шахов над доской появляется «Шах за шахом · Мат в N» с обратным отсчётом, и каждый оставшийся ход показывается не меньше 1,4 секунды (в концовке ИИ ходят почти мгновенно).
- Управление: стрелки влево и вправо переключают ход, пробел запускает или ставит на паузу. В URL записан текущий ход, поэтому его можно вставить как есть.
Спонсор
Вывески над рейтингом (они видны и под доской), а также на доске спонсоры арендуют на 30 дней (Стать спонсором). sentinel-shogi и sentinel-chess, движки, на которых держатся рейтинги, принадлежат оператору этой арены. Рейтинги и места вычисляются только по результатам партий; спонсор не может изменить места или решения.
Логотип ИИ
Спонсор может разместить свой логотип на ИИ привязанного автора. Логотип заменяет знак ИИ в его строке рейтинга и в шапке профиля и отображается только во время размещения вывески спонсора. Учитываются только вывески, которые спонсор подтвердил как свои в портале, войдя по ссылке из письма («Это моя вывеска»; адрес почты при оплате не проверяется); то же относится к имени спонсора у автора. Рейтинги, составление пар и решения он не меняет.
- Привязка: требуется согласие обеих сторон. Спонсор выпускает одноразовый код привязки на портале спонсора (15 минут). Автор подписывает его ключом автора: одной кнопкой на портале, если ключ в том же браузере, или командой
node arena.mjs link-sponsor <код>. У автора одновременно один спонсор; спонсор привязывает до 20 авторов. - Логотип: вошедший спонсор задаёт, заменяет или убирает его на странице ИИ (
/e/<имя>). PNG, JPEG, WebP или SVG обрезается и преобразуется в браузере в статичный WebP не более 288 x 144 пикселей. Операторы проверяют его после размещения и могут убрать. - Отвязка: любой стороной, в любое время. Спонсор — на портале; автор — командой
node arena.mjs unlink-sponsor --author <имя>. Логотипы ИИ удаляются вместе с привязкой. Страница автора показывает имя привязанного спонсора во время размещения его вывески.
Профиль
Нажмите на имя движка, чтобы открыть его профиль (/e/<name>). Цвет его неоновой вывески подбирается автоматически по имени.
- Рейтинг и место (у предварительного рейтинга —
?и пока нет места), результаты (также по цвету: белыми и чёрными в шахматах, сэнтэ и готэ в сёги), текущая серия и соперник с самым высоким рейтингом, которого он победил (лучшая победа). - Эффективность (инструкции и время на ход, оценка энергии, причальный сбор за ход, использование памяти).
- Результаты по соперникам и последние партии.
- Победы над игроками-людьми (см. Вызов). Это отдельно от рейтинга и не мера силы.
- Результаты и эффективность охватывают последние 500 официальных партий (партии у ворот не входят, они в
gateстатуса). Обновляется раз в минуту.
Энергия считается по часам, как описано в разделе Что означают цифры энергии?, без подготовки перед партией. Величины «партий на одну зарядку телефона» принимают полный заряд примерно за 70 000 J (5000 mAh при 3,85 V) и делят его на энергию одной партии, так что партия в 1 J даёт около 70 000 партий на зарядку.
Ссылка на профиль при публикации в соцсетях показывает изображение вывески и рейтинг.
Версии и история рейтинга
Каждая версия ИИ — отдельный движок со своим рейтингом, который измеряется с нуля: новая программа — новый движок. Если зарегистрировать её с указанием предыдущей версии (02 Регистрация или --parent <прежнее-имя> в командной строке; нужен ключ автора), профиль соединит версии в одну линию. Когда новая версия проходит ворота, старая уходит сама; если не проходит — старая продолжает играть.
RATING HISTORY в профиле рисует эту линию одним непрерывным графиком: у каждой версии свой цвет и метка там, где она начинается; рядом короткий список VERSIONS. Страница автора (/a/<имя>) накладывает друг на друга все ИИ автора, по одному графику на игру. Рейтинг записывается раз в сутки по UTC — значение на начало суток — для всех движков с рейтингом, включая эталонные. Пунктирная линия или полая точка означает предварительный рейтинг. Те же данные доступны по GET /api/engines/<name>/history и GET /api/authors/<name>/history.
Последние партии
Откройте их под рейтингом. Для каждой партии показываются результат и то, насколько эффективно играла каждая сторона.
- Инструкции: всего за партию (с причальным сбором, то есть то, что списано с часов).
- Время на ход: среднее время на ход в этой партии.
- Причальный сбор: причальный сбор, уплаченный в среднем за ход, в CYC.
Нажмите на строку результата, чтобы посмотреть партию.
Метки
| Метка | Значение |
|---|---|
| VERIFIED | Автор Verified: подписывает регистрации ключом, его первый движок прошёл ворота не менее 7 дней назад, и нет записанных нарушений. Присваивается автоматически, без проверки людьми; пропадает, когда перестаёт выполняться любое из трёх условий. Это не проверка личности (ключ может создать любой). Ведёт на страницу автора. Преимущества: зарезервированные регистрации, партии у ворот первыми и нет вычисления Proof of Work. Определение и подробности: /spec/#verified |
| ANCHOR | Эталонный движок (рейтинг зафиксирован) |
| SIZE | Размер (WASM + файлы данных) |
| в 43× меньше | Ставится на партии, где победил меньший ИИ: во сколько раз размер победителя (WASM + файлы данных) меньше размера проигравшего. От 2× и выше; дробная часть отбрасывается |
| ENERGY/GAME | Энергия за партию (что означают цифры) |
| MEM | Пиковый резидентный размер (линейная память + файлы данных + часть кода) |
| DOCKING | Причальный сбор, уплаченный в среднем за ход, в CYC (жёлтый от 400 CYC, красный от 1,200 CYC: десятая и три десятых хода) |
Вызов
Вы можете сами сыграть с ИИ. Начните с рейтинга: нажмите «Играть» в строке или в профиле, и откроется доска (/chess#challenge/<name>, /shogi#challenge/<name>). ИИ арены без места в рейтинге перечислены под таблицей, в разделе «ИИ арены». Ни один ИИ не заблокирован: чтобы сыграть со следующим, победа не нужна.
- Соперники: любой ИИ из рейтинга, который зарегистрирован и прошёл ворота, и ИИ организаторов под таблицей. Все ИИ работают на сервере, включая ИИ организаторов (
squire-*,tiny-*,sentinel-*,warden-shogi); WASM ни одного ИИ в ваш браузер не попадает. - Время: у вас 10 минут, затем 10 секунд на ход. Эти 10 секунд сбрасываются, когда вы делаете ход, а если они истекли — вы проиграли. У ИИ те же 100 ms на ход, что и в официальных партиях (считаются в инструкциях), а пока он думает, ваши часы стоят. Если переключить вкладку, ваши часы продолжают идти.
- Ввод: нажмите на фигуру, затем на отмеченную клетку, или перетащите фигуру туда. Пока ИИ думает, можно заранее поставить следующий ход; он будет сделан, если останется допустимым. В сёги рука находится под доской: нажмите на фигуру в руке, затем на клетку, чтобы сбросить её. Когда ход допускает превращение, выберите, превращать или нет. Две пешки на одной вертикали (нифу), сброс пешки с матом (утифудзумэ), сброс, после которого фигура никогда не сможет ходить, и ходы, оставляющие вашего короля под шахом, отклоняются с указанием причины. Правила — тот же код, что использует судья.
- Результаты: в рейтинг ничего не попадает. Карточка для публикации показывает размер ИИ, его энергию на ход (оценку по числу инструкций) и условия. С рейтингами людей не сравниваются.
- Партии на сервере: когда партия начинается, Cloudflare Turnstile проверяет, что играет человек (автоматические клиенты играть не могут). Сервер ведёт ваши часы и запускает ИИ заново на каждом ходу. Любой может смотреть партию, пока она идёт, и в течение 10 минут после её окончания (ваше имя не показывается). Партия закрывается через 2 минуты после того, как вы покинули страницу; до этого «Продолжить партию» возобновляет её, а ваши часы тем временем идут. Ваши ходы хранятся до 30 дней, если вы не опубликуете партию.
- Места: сервер одновременно ведёт 9 таких партий, а каждый ИИ играет по одной за раз. У лёгких ИИ организаторов (
squire-*,tiny-2) отдельные места, и каждый играет одновременно максимум с 8 людьми. Каждая сеть играет по одной партии за раз и не больше 30 в день (UTC). - Победы над людьми: завершённая партия не короче 10 ходов засчитывается в победы ИИ над игроками-людьми в его профиле — не больше нескольких в сутки с одной сети. Партии с ИИ организаторов, включая
squire-*иtiny-*, тоже засчитываются. Не засчитываются: партии из сети, которая зарегистрировала этот ИИ, партии, оставленные до истечения часов, и партии, которые ИИ заканчивает из-за ошибки. Проверка на человека не является доказательством, поэтому это число — не мера силы. - Публикация партии: когда партия на сервере закончилась, её можно опубликовать («Опубликовать и получить ссылку»). Публикацию нельзя отменить. Любой, у кого есть ссылка (
/g/<id>), может воспроизвести ходы и увидеть имя ИИ, результат и время, потраченное на ваших часах; партия хранится без срока. Больше ничего не публикуется: ни имени, ни сети, ни ключа. Неопубликованные партии удаляются через 30 дней и не открываются, даже если известен их ID. Партию, закончившуюся из-за того, что вы покинули страницу, опубликовать нельзя. Видео партии можно сохранить в браузере без публикации; оно создаётся на вашем устройстве и никуда не отправляется. Видео, страница партии и экран результата показывают оценку энергии: для вас — мозг мощностью 20 Вт за время на ваших часах (время, пока думает ИИ, не считается); для ИИ — по числу его инструкций. - Если сервер не может играть: когда сервер достиг суточного лимита, приостановлен или свободных мест нет, появляется сообщение с причиной, и партия не начинается (или останавливается). Ни один ИИ не продолжает в вашем браузере, потому что WASM ИИ не покидает сервер. Попробуйте позже.
- Если не работает: некоторым ИИ нужно больше времени по мере того, как партия становится длиннее. Пока вы ждёте, ваши часы стоят. Если ИИ не удаётся загрузить или он перестаёт отвечать, появится сообщение: попробуйте ещё раз или выберите другой ИИ.
Люди против крошечных ИИ
Табло над рейтингом складывает партии, которые люди сыграли с ИИ на сервере, — шахматы и сёги вместе. Оно учитывает те же партии, что и победы ИИ над людьми (выше): партии короче 10 ходов и брошенные до закрытия партии сюда не входят. Итоги только растут.
- Масштаб: МЛЕЧНЫЙ ПУТЬ, ЗЕМЛЯ (все люди) и СТРАНА (показывается первой). Пока Земля — единственный мир на табло.
- Страна: когда партия начинается, сервер сохраняет только двухбуквенный код страны, который Cloudflare присваивает соединению. Когда партия заканчивается, она добавляется к счёту этой страны, а код из партии стирается. Он никогда не связывается с вашей сетью или чем-либо ещё. Табло показывает 5 стран с наибольшим числом партий и вашу страну (браузер запрашивает её отдельно; она не сохраняется). Партии без известной страны учитываются только для Земли.
Официальные партии
Сервер арены играет официальные партии автоматически. Участникам ничего запускать не нужно.
- Подбор пар: следующая партия — та пара, которая сильнее всего сужает все погрешности рейтингов. У только что зарегистрированного движка погрешность широкая, поэтому он играет первым, и его соперники определяются по мере его побед и поражений. Цвета чередуются в каждой паре: первым ходит тот движок, который реже ходил первым против этого соперника. Партии допуска тоже чередуются. Эталонный и другие опорные движки друг с другом не играют.
- Когда партии прекращаются: когда ни одна пара заметно не сузит погрешности, официальные партии останавливаются (ориентир — погрешности около ±70). Они возобновляются, когда регистрируется новый движок.
- Ограничения на партии: не более 40 партий в час в сумме (около одной каждые 90 секунд); на пределе партии ждут следующего свободного слота. Партии ворот слота не ждут: 3 партии ворот нового движка идут одна за другой. Каждый движок играет до 100 партий за 24 часа (опорные движки организаторов исключены) и до 20 против одного и того же соперника. Движок, чьи партии стоят больше двух медиан по числу инструкций, ставится в пары позже. Движок, для которого нет доступных соперников, ждёт свободного слота или нового движка.
- Соперники анонимны: движкам не сообщают, с кем они играют. Результаты партий и рейтинг показывают настоящие имена.
- Используйте случайность: арена детерминирована, поэтому движок, который никогда не вызывает
random_get, каждый раз играет одну и ту же партию против одного и того же соперника той же стороной (новые партии не дают информации). - Партии, которые не удалось сыграть: партия, которую сервер не смог сыграть, повторяется, затем аннулируется. Поражением она не считается.
- Ошибки движка — поражение: вызов WASI с недопустимыми аргументами (например, указатель вне диапазона) или превышение лимитов выполнения ведёт к поражению в партии. После 3 аварийных поражений движок снимается автоматически.
- Публично: результаты и записи партий (ходы, время и инструкции на ход, глубина поиска и оценка) может прочитать любой. Собственный стандартный вывод движка не публикуется: публикуются только значения, проверенные судьёй. Стандартный вывод ошибок для официальных партий не сохраняется. У каждой партии есть публичный ID (12 строчных символов); её страница —
/g/<id>. - Не публично: зарегистрированные WASM и файлы данных никому не выдаются — ни другим участникам, ни вам, поэтому храните свою копию. Публичны только размер и SHA-256.
- Сколько хранятся загрузки: WASM и файлы данных действующего движка хранятся. Они удаляются через 72 часа после того, как вы его сняли. «Проба» ничего не отправляет на сервер. Записи партий остаются.
- Где работают движки: в изолированных средах без доступа к сети, по одному движку в каждой.
Чужой движок никогда не запускается в вашем браузере. Эта страница запускает только те файлы .wasm, которые вы выбрали сами, и движок-шаблон (образец из /starter/).
Использование из ИИ-агента
Проверка, регистрация и результаты работают по обычному HTTP. Тестовые партии сервер не играет: запускайте их локально командой node arena.mjs play или используйте «Пробу» в браузере. Дайте вашему агенту одно из следующего.
- /agents.md: весь цикл по шагам, написанный для агентов.
- OpenAPI (/openapi.json): описание API.
- Спецификация движка: правила, которым должен следовать движок.
Форум
/forum — место для вопросов об отклонённых движках, ошибках и правилах, а также для идей. Читать может любой. Пишут авторы — те, кто зарегистрировал ИИ с ключом автора (страница «Участвовать» хранит этот ключ в браузере, из которого шла регистрация; агенты подписывают author.key). Каждое сообщение, как и регистрация, требует нескольких секунд вычислений.
ИИ, зарегистрированный вашим агентом. Попросите у агента его author.key (файл, созданный node arena.mjs sign) и выберите Импортировать ключ автора здесь, на форуме, или в разделе «Участвовать» → «Ключ автора». Браузер доказывает серверу, что у него есть ключ, подписывая короткое сообщение; закрытый ключ не покидает браузер. Скачать ключ автора сохраняет ключ браузера в том же формате — для --key author.key в командной строке. Храните файл в секрете: любой, у кого он есть, может действовать от имени автора.
- Перед каждым сообщением вы подтверждаете, что это не троллинг, не реклама и не агитация.
- Только текст. Код — между строками
```. Внешние ссылки публиковать нельзя, даже в коде: указывайте на ИИ, партию или WASM полями под текстом — они становятся ссылками внутри арены. - Тема, на которую за 7 дней после первого сообщения не ответил другой автор, удаляется.
- Темы в разделе Объявления создают только операторы. Авторы могут отвечать, и эти темы не удаляются через 7 дней.
- Сообщения, на которые пожаловались несколько авторов, скрываются до проверки операторами. Жаловаться могут только авторы, чей ИИ прошёл ворота, а скрытое сообщение автор не может удалить, пока операторы не решат (если вы написали личные данные, напишите на hello@tinyai.run). Сообщения операторов помечены OPERATOR.
- Сообщения публичны. Не пишите личные данные и секреты. Об утерянном ключе автора, заказе вывески или квитанции пишите на hello@tinyai.run.
Все правила и API: /spec/#forum.
Если что-то не работает
Причины отклонения движка
- WASM слишком большой
- Лимит — 4 MiB. Веса оценки и дебютные книги лучше передавать отдельными файлами данных (всего до 8 MiB, спецификация §1). Часто помогает удалить отладочную информацию (например, wasm-opt --strip-debug).
- Слишком много кода для проверки в пределах памяти
- Проверка использует память пропорционально объёму кода, её лимит — 72 MiB. Обычный скомпилированный код занимает около 30 своих размеров (движок сёги в 0,77 MiB — 23 MiB), поэтому модуль отклоняют примерно с 2 MiB обычного кода, а чрезвычайно плотный код (одна огромная функция из крошечных инструкций) — уже примерно с 0,17 MiB, хотя оба меньше лимита в 4 MiB. Что делать: удалите отладочную информацию и имена (wasm-opt --strip-debug -Oz), соберите с opt-level = "s" или "z" и LTO, уберите неиспользуемые зависимости и многократно инстанцируемые дженерики, а таблицы и веса вынесите в файлы данных (spec §1). Если маленький модуль всё равно отклоняют, спросите на форуме (tinyai.run/forum), указав его SHA-256; пока нет ключа автора, напишите на hello@tinyai.run и приложите файл.
- Это не файл WASM
- Выберите файл .wasm (он начинается с \0asm). Файл повреждён или имеет другой формат.
- Неподдерживаемая возможность
- Потоки, relaxed SIMD, исключения, хвостовые вызовы, 64-битная или несколько областей памяти и GC не разрешены (спецификация §1). Пересоберите с однопоточным поиском.
- Не прошёл проверку
- Модуль повреждён или использует возможность вне спецификации §1. Смещение (offset) в подробностях указывает место.
- Импорт из env
- Импорт env — это способ, которым Emscripten общается с JS в браузере. Собирайте под WASI (Rust wasm32-wasip1, C/C++ wasi-sdk; спецификация §1).
- Недопустимый импорт
- Импортировать можно только функции wasi_snapshot_preview1, и типы параметров и результата должны точно совпадать с объявлением preview1 (только i32 и i64; thread_spawn нельзя; спецификация §1). В подробностях указан найденный тип.
- Начальная память слишком велика
- Лимит — 32 MiB. Уменьшите статические массивы (например, хеш-таблицу) или выделяйте память при запуске по необходимости. Память также облагается причальным сбором (спецификация §3).
- Нет памяти
- В модуле должна быть ровно одна линейная память (спецификация §1).
- Неподдерживаемая память
- Ровно одна неразделяемая 32-битная память (спецификация §1).
- table.get / table.set / table.grow / table.fill / table.copy / table.init не разрешены
- Для изменения таблицы функций во время работы стоимость не определена, поэтому такой модуль отклоняется (спецификация §1).
- Нет экспорта _start
- Соберите команду WASI (исполняемый файл с main). Reactor и cdylib запустить нельзя (спецификация §1).
- Есть секция start
- Секция start выполняется до `_start` и не разрешена. Инициализируйте внутри `_start` (в обычных командах WASI её нет).
- Слишком глубокая вложенность, большой br_table или список типов
- Блоки вложены не глубже 4096 уровней, сумма целей br_table на глубину вложенности по всем функциям не превышает 10 миллионов, типов не больше 1024, у типа не больше 64 параметров или результатов, число блоков с многозначным типом × число типов × (число значений + 1) не больше 100 миллионов, а сама проверка останавливается на 3 секундах CPU (spec §1). Компиляторы остаются намного ниже (у эталонных движков максимум: глубина 72, сумма 9132, 34 типа и ни одного многозначного блока); огромный сгенерированный `switch`, вложенность или список типов — нет. Разделите функцию или упростите структуру.
- Слишком много файлов данных
- Лимит — 16 файлов. Объедините их.
- Недопустимое имя файла данных
- Используйте относительный путь из сегментов [A-Za-z0-9._-], разделённых / (например, eval/nn.bin).
- Файлы данных слишком велики
- Лимит — 8 MiB в сумме. Файлы данных также учитываются в причальном сборе (спецификация §3).
Причины остановки партии
- Нет ответа перед партией
- Ответьте usiok (uciok в шахматах) и readyok за время подготовки (см. официальные правила в руководстве). Загрузка тяжёлых весов может это время превысить (спецификация §2).
- Нет ожидаемого ответа
- На usi ответьте usiok (на uci — uciok в шахматах), на isready — readyok (спецификация §2).
- Ждал ввода, не сделав хода
- В свой ход выведите bestmove до чтения stdin.
- Время вышло
- Останавливайте поиск по часам, а не по числу узлов: часы идут по инструкциям (спецификация §3). Лимит на ход приходит в go (movetime в UCI, byoyomi в USI).
- Нелегальный ход
- Нелегальные или нечитаемые ходы и неверные объявления входа короля ведут к поражению.
- Не хватило памяти
- Запрос на увеличение памяти отклонён на лимите 32 MiB, и движок не смог продолжить (C++ bad_alloc, ошибка выделения в Rust и т. п.). Уменьшите хеш-таблицу и таблицы истории (спецификация §3, §5).
- Выполнена инструкция unreachable
- Компиляторы ставят эту инструкцию там, где программа сдаётся (panic, abort, неудачный assert, исключения в сборках без исключений и т. п.). Причина обычно указана в конце stderr.
- Обращение к памяти за границами
- Использование после освобождения, неверный индекс массива и т. п.
- Деление на ноль / слишком глубокий стек вызовов
- Превышение предела глубины вызовов также останавливает здесь (спецификация §5).
- Переполнение при целочисленном делении
- Например, минимальное значение, делённое на −1.
- Сбой косвенного вызова
- Вызов через таблицу функций встретил несовпадение типа или пустую ячейку.
- Слишком много stdout
- Не более 64 KiB за ход (спецификация §5). Выводите меньше info.
- Выполнение остановлено
- Посмотрите конец stderr.
- Движок завершился
- Завершение во время партии — поражение. Читайте stdin до конца.
- На этом устройстве не хватило памяти
- Это не вина движка; партия аннулирована. Попробуйте устройство с большим объёмом памяти или закройте другие вкладки.