Fortuna давно бросает кубики, считает монеты и держит кампании в тонусе на серверах Discord. Но за кулисами бот разросся в одну большую программу, которая жонглировала всем разом — и швы уже начинали трещать. Поэтому мы сделали то, с чем рано или поздно сталкивается любой долгоживущий проект: пересобрали его с нуля.
Новая Fortuna отвечает быстрее, держится стабильнее под нагрузкой, проще в доработке для нас и готова расти вместе с вашим столом. Бóльшая часть этой работы прошла там, где вы её никогда не увидите, — и в этом весь смысл. Зато результат заметен везде, где вы на самом деле ею пользуетесь. Вот полная история того, что изменилось и почему это важно.
Изначальная Fortuna была построена по распространённой схеме: бот держит постоянное, всегда открытое соединение с Discord — то, что Discord называет gateway (шлюз), — и непрерывно слушает всё, что происходит на каждом сервере, куда его пригласили. Чтобы справляться с нагрузкой по мере роста, это соединение разбивали на несколько параллельных копий, называемых шардами (shards): каждый шард — отдельный работающий процесс, за которым нужно следить, перезапускать и поддерживать в рабочем состоянии.
Это работает, и работало годами. Но за этим стоят реальные издержки. Постоянно подключённый бот всё время потребляет память и держит состояние, даже когда никто не вводит команд. Каждый сервер, канал и участник, которых он видит, добавляли веса. Когда один шард спотыкался, это могла ощутить целая пачка серверов. А каждую новую функцию приходилось аккуратно вплетать в программу, которая и так делала десяток дел одновременно.
Нам хотелось чего-то более лёгкого. Чего-то, что делает работу, когда работа есть, помалкивает, когда её нет, и собрано из небольших частей, которые можно чинить или масштабировать по отдельности.
У современных Discord-ботов есть вариант получше для команд: вместо того чтобы держать соединение открытым и ждать, бот может позволить Discord вызывать его только тогда, когда кто-то действительно использует слэш-команду. Discord упаковывает команду, отправляет её одним защищённым веб-запросом, а бот отвечает. Никакого постоянного соединения, никакого веса в простое. Когда ничего не происходит, бот не потребляет почти ничего.
В этом и есть сердце нового дизайна. Мы разделили старый монолит на две сфокусированные части:
Представьте это как ресторан. Старая Fortuna была одним загнанным поваром, который пытался одновременно принимать заказы, управлять залом и крутиться на кухне. У новой Fortuna есть кухня, которая мгновенно вспыхивает, как только приходит заказ (fortuna-http), и один внимательный администратор у входа, высматривающий гостей с улицы (fortuna-gateway). Каждый делает своё дело хорошо, и ни один не тормозит другого.
Разговоры об архитектуре — это хорошо, но вот что вы на самом деле заметите на своём сервере.
Более шустрые ответы. Поскольку командное ядро делает одно дело и не таскает за собой балласт простоя, оно отвечает быстро и стабильно. Команде приходится меньше стоять в очереди.
Лучшая надёжность. Две части независимы. Если помощнику для чат-бросков нужен перезапуск, ваши слэш-команды продолжают работать, даже не моргнув. Проблемы остаются локализованными, а не расходятся волной по всему боту.
Стабильнее под давлением. Stateless-ядро не набирает вес по мере того, как добавляются серверы и игроки. Загруженные вечера ведут себя куда больше похоже на спокойные.
Более быстрые улучшения. С чистым модульным ядром мы можем добавлять и чинить функции, не задевая всё вокруг. Новые команды встают на место аккуратно, а значит, обновления доходят до вас быстрее.
Пересборка — это ещё и шанс выпустить то, что мы давно хотели добавить. Новая Fortuna приносит увесистую порцию функций:
/lc для участников и /mod_lc для модераторов, чтобы управлять балансами. Награды и звания остаются в рамках вашего сообщества./config собирает все серверные настройки в одном месте, чтобы каждое сообщество могло подстроить Fortuna под свой стиль игры./handouts — так, как и положено хорошему виртуальному столу./checkin упрощает отметку явки и помогает держать группу в строю.Всё это соседствует с тем, что Fortuna всегда делала хорошо: богатые броски кубиков (и через слэш-команды, и набором бросков прямо в чат), ежедневная награда, звания, магазин и всё остальное.
Одно из самых заметных улучшений качества жизни встроено прямо в новое ядро: полная локализация. Теперь Fortuna говорит на всех языках Discord — более тридцати локалей — и автоматически выбирает нужный на основе настроек Discord каждого пользователя. Названия команд, описания и ответы приходят на родном языке игрока, с разумной цепочкой запасных вариантов, чтобы никто никогда не упёрся в отсутствующий перевод. Играет ли ваш стол на португальском, английском, испанском, французском, японском или на чём угодно между ними — Fortuna встречает каждого там, где он есть.
Если вам нравятся технические детали — вот несколько решений, которыми мы гордимся; а если нет, этот раздел можно спокойно пропустить.
Каждый запрос команды от Discord криптографически проверяется с помощью подписей Ed25519 прежде, чем Fortuna что-либо сделает, так что бот отвечает только на подлинные, неподделанные запросы. Командное ядро работает на Bun с лёгким фреймворком Hono; помощник для чат-бросков — это небольшая статически скомпилированная программа на Go, простаивающая с крошечным следом. Оба поставляются в виде чистых контейнерных образов, что делает развёртывания быстрыми и воспроизводимыми. А ещё мы подключили нормальный мониторинг ошибок, чтобы, когда что-то всё-таки идёт не так, мы об этом узнавали и могли быстро починить — при этом тщательно следя за тем, чтобы никогда не логировать ничего чувствительного.
Общий движок кубиков — та же проверенная математика, что питает и другие наши инструменты, так что бросок означает ровно то же самое, делаете ли вы его в Discord или где угодно ещё в экосистеме.
Ничего из этого не меняет духа Fortuna. Это всё тот же дружелюбный бот, который бросает ваши кубики и держит вашу кампанию в порядке. Изменился фундамент под ним: более лёгкий, более стабильный и построенный так, чтобы мы могли и дальше делать его лучше, не путаясь у вас под ногами.
Добавьте Fortuna на свой сервер, попробуйте новые команды и расскажите нам, что хотели бы увидеть дальше. Кубики готовы, когда готовы вы.