RE:NODE

Руководства14 мин чтения

Assetto Corsa Server Manager: чемпионаты

Как вести лигу в Assetto Corsa: чемпионаты в Server Manager, очки и классы, закрытый entry list, регистрация, реверсивная решётка, пит-окна и файлы результатов.

0 прочтений

Обычный acServer понятия не имеет, что такое чемпионат. Он запускает сессии, которые вы настроили, крутит их по кругу, если попросить, и пишет по одному JSON-файлу с результатами на каждую сессию - а таблица, очки и то, кто в какой машине едет, уже чья-то чужая забота. Этим «кем-то» обычно оказывается Assetto Corsa Server Manager (ACSM) - бесплатный веб-интерфейс, который собирает server_cfg.ini и entry_list.ini для каждого этапа, сам запускает acServer, забирает результаты и превращает их в таблицу очков с классами, командами, регистрацией и штрафами. Если не хочется держать ещё одну программу, ту же лигу можно вести на двух конфигурационных файлах и таблице, и в этом руководстве разобраны оба пути: через Server Manager и через настройки под ним, которые нужно понимать в любом случае.

Если базовый сервер ещё не настроен, начните с руководства по серверу Assetto Corsa - там по ключам разобраны server_cfg.ini, сессии, порты и модовый контент. Здесь мы считаем, что всё это уже работает, и переходим к тому, как неделю за неделей гонять один и тот же состав пилотов.

Что обычный acServer даёт лиге, а чего не даёт#

Всё, что лиге нужно от самой игры, уже есть - просто оно не связано между собой.

  • Результаты. В конце каждой сессии acServer пишет JSON-файл в папку results, в имени которого дата, время и тип сессии - что-то вроде 2026_10_7_20_45_RACE.json. В нём каждая машина, каждый круг, лучшие круги, итоговое время и контакты, которые зафиксировал сервер.
  • Закреплённые слоты. entry_list.ini с GUID у каждой записи и LOCKED_ENTRY_LIST=1 даёт каждому пилоту свою машину, ливрею и место на решётке.
  • Инструменты баланса. BALLAST и RESTRICTOR для каждой записи, а MAX_BALLAST_KG в server_cfg.ini задаёт потолок.
  • Форматы гонок. Практика, квалификация и гонка подряд, плюс вторая гонка с реверсивной решёткой и обязательное пит-окно - всё задаётся в конфиге.

Чего у него нет, так это памяти. Между гоночными вечерами ничего не переносится: ни очки, ни success ballast, ни запись о том, что пилота наказали на прошлой неделе. Любой инструмент для чемпионатов, включая ACSM, - это слой, который читает файлы результатов, хранит состояние между этапами и пишет новые конфиги перед следующим. Если это понимать, искать проблемы гораздо проще: почти любая беда в лиге - это сбой на одном из этих трёх шагов.

Коротко об Assetto Corsa Server Manager#

ACSM - это один бинарник на Go с интерфейсом в браузере. Изначально его сделали Emperor Servers и выложили в открытый доступ на GitHub. Оригинальный репозиторий теперь заархивирован и доступен только для чтения, так что вы запускаете законченную программу, а не что-то, что будет меняться у вас под ногами. Для игры, которая не менялась годами, это скорее плюс, но значит и то, что ошибки в основной ветке исправлять никто не будет, а вся новая работа идёт в форках.

То, что вы настраиваете, лежит в config.yml рядом с бинарником:

config.yml
steam:  install_path: assetto  executable_path: acServerhttp:  hostname: 0.0.0.0:8772  session_key: generate-a-long-random-string  server_manager_base_URL: https://league.example.comstore:  type: boltdb  path: server_manager.dbaccounts:  admin_password_override:server:  audit_logging: true  performance_mode: false  persist_mid_session_results: false
ПараметрЧто делает
http.hostnameАдрес и порт веб-интерфейса. 8772 - значение по умолчанию
http.session_keyШифрует сессии входа. Задайте своё случайное значение
server_manager_base_URLИспользуется в ссылках в сообщениях чемпионата и в регистрации
store.typeboltdb хранит всё в одном файле; json пишет по файлу на каждый этап
store.pathГде лежат эти данные. Именно этот файл нужно бэкапить
admin_password_overrideАварийный сброс пароля admin
audit_loggingЗаписывает, какой пользователь что запустил, остановил или удалил
performance_modeОтключает live timing ради экономии CPU

Первый вход - пользователь admin с паролем servermanager, и сменить его вас заставят сразу. Если потом пароль потеряется, впишите временное значение в admin_password_override, перезапустите программу, войдите с ним и задайте новый. Заведите отдельную учётную запись для каждого стюарда, а не делитесь одним админским входом: журнал аудита полезен только тогда, когда имена в нём что-то значат.

Важно, где всё это работает. ACSM сам запускает и останавливает acServer, поэтому хочет быть главным над процессом. Это подходит для машины, которой вы управляете сами, - своего компьютера или выделенного сервера, где вы открываете 9600 TCP и UDP, 8081 TCP и веб-порт. На игровой панели процессом управляет сама панель, так что на практике там работает файловый подход, описанный ниже: панель запускает acServer, а вы между этапами меняете два конфигурационных файла.

Собираем чемпионат: классы, очки и этапы#

Чемпионат в ACSM - это список классов, список участников и список этапов. Каждый этап - это трасса, конфигурация, последовательность сессий и время старта; когда вы запускаете этап, ACSM пишет конфиг под него, запускает сервер и по окончании сессий прикрепляет результаты к чемпионату.

Классы

Класс - это набор машин плюс собственная таблица очков. Монокубку нужен один класс. Мультиклассовой гонке на выносливость - GT3 и GT4 на одной трассе - нужен отдельный класс на каждую категорию со своим зачётом: это единственный честный способ считать очки там, где медленный класс никогда не выиграет в абсолюте.

Очки

По умолчанию стоит таблица Формулы 1, и каждое поле можно изменить для каждого класса:

ПолеПо умолчаниюЗа что начисляет
Places25, 18, 15, 12, 10, 8, 6, 4, 2, 1Очки за место на финише в классе
Best lap0Бонус за быстрейший круг гонки
Pole position0Бонус за первое место в квалификации
Collision with driver0Вычет очков за каждый контакт машин
Collision with environment0Вычет очков за каждый контакт со стеной
Cut track0Вычет очков за каждую засчитанную срезку
Second race multiplier1Множитель очков для второй гонки с реверсивной решёткой

Вычеты за столкновения и срезки выглядят заманчиво, но обычно это ошибка. Сервер считает каждое касание, в том числе то, где в вас въехал кто-то другой, так что автоматические вычеты наказывают пострадавших так же охотно, как виновников. Оставьте их на нуле, а инциденты разбирайте через стюардов. Небольшой бонус за лучший круг - нормально; большой награждает тех, кто за два круга до финиша заезжает в боксы за свежей резиной вместо того, чтобы гоняться.

Равенство очков разрешается по countback: выше тот, у кого больше побед, затем больше вторых мест и так далее - так и так принято в большинстве лиг. Пропишите это в регламенте, чтобы в последнем этапе никто не удивлялся.

Этапы

Добавляйте этапы в порядке календаря и задавайте каждому полную последовательность сессий: практика, квалификация, гонка и вторая гонка, если вы их проводите. Этап можно скопировать и поменять только трассу - так длительность сессий и помощники остаются одинаковыми весь сезон. Меняйте что-то одно между сезонами, а не между этапами.

Entry list для лиги#

Именно entry list решает, выглядит лига организованной или нет. Заполнить его можно тремя способами.

Фиксированный список. Вы сами добавляете каждого пилота: его SteamID64 в качестве GUID, машину, ливрею и команду. При закрытом entry list никто другой не займёт его слот, и он всегда появляется в одной и той же машине. Работы больше всего, проблем меньше всего.

Открытый набор. Чемпионат принимает всех, кто заходит, и автоматически добавляет их в список участников. Если включить сохранение, машина и ливрея, с которыми пилот зашёл впервые, закрепляются за ним на сезон. Это подходит для публичной серии «по четвергам» с меняющимся составом и не подходит для лиги с листом ожидания.

Форма регистрации. ACSM может опубликовать страницу регистрации, где пилоты указывают имя, Steam GUID, команду, желаемую машину и ливрею - при желании с дополнительными вопросами и защитой reCAPTCHA, которые настраиваются в разделе championships файла config.yml. Заявки можно принимать автоматически или одобрять вручную. Одобренные пилоты попадают в список участников с уже заполненным GUID, и это убирает самый ошибкоопасный шаг - копирование семнадцатизначных чисел из сообщений в Discord.

Какой бы способ вы ни выбрали, под ним продолжают действовать правила базового сервера:

  • Количество записей и MAX_CLIENTS не должны превышать число боксов на трассе. Решётка на 32 машины не влезет на трассу с 24 боксами, и выглядит это как сломанная сессия, а не как понятная ошибка.
  • Каждая MODEL должна быть в списке машин этапа, а каждый SKIN - существовать в папке skins этой машины на сервере, иначе сервер подставит другое или откажет в записи.
  • У пилотов должна быть одна и та же версия каждой модовой машины и трассы. Опубликуйте список контента со ссылками на скачивание до первого этапа - в статье контент Assetto Corsa, Content Manager и модовые трассы рассказано, как упаковать его так, чтобы люди его действительно поставили.

Балласт и рестриктор

Применять их можно двумя способами. Фиксированный баланс - значение на запись, заданное на весь сезон: класс новичков или гандикап для ветерана. Success ballast меняется от этапа к этапу: лидер чемпионата везёт 30 кг, второй - 20 кг и так далее. Обычный acServer не знает, кто лидирует, поэтому success ballast означает правку entry list перед каждым этапом, и редактирование участников этапа в ACSM делает это быстрым. Держите MAX_BALLAST_KG выше самого большого значения, которое будете использовать, иначе сервер молча обрежет его.

Рестриктор - это урезание мощности в процентах, и ощущается он иначе, чем балласт: балласт мешает на торможении и в поворотах, рестриктор - на прямых. Для выравнивания разных машин используйте рестриктор; чтобы притормозить пилота, который просто быстрее, балласт мягче на трассах с длинными прямыми.

Форматы гонок: реверсивная решётка, пит-окна и гоночные уикенды#

Большинство форматов лиги - это несколько ключей в server_cfg.ini, которые ACSM показывает как поля формы:

cfg/server_cfg.ini
[SERVER]LOCKED_ENTRY_LIST=1PICKUP_MODE_ENABLED=0MAX_BALLAST_KG=100REVERSED_GRID_RACE_POSITIONS=8RACE_PIT_WINDOW_START=10RACE_PIT_WINDOW_END=20RACE_EXTRA_LAP=0QUALIFY_MAX_WAIT_PERC=120[RACE]NAME=RaceLAPS=25WAIT_TIME=90IS_OPEN=0
КлючЧто делает
REVERSED_GRID_RACE_POSITIONS0 - без второй гонки; N - вторая гонка с реверсом первых N; -1 - реверс всего пелотона
RACE_PIT_WINDOW_START / _ENDДиапазон кругов (или минут в гонке на время), в котором нужно сделать обязательный пит-стоп
RACE_EXTRA_LAP1 добавляет круг после окончания таймера в гонке на время
QUALIFY_MAX_WAIT_PERCСколько сервер ждёт пилотов на круге после конца квалификации, в процентах от лучшего круга
IS_OPEN0 закрывает гонку для опоздавших; 1 пускает их; 2 пускает до момента за 20 секунд до старта

Реверсивная решётка - классический формат из двух гонок: спринт по итогам квалификации, затем вторая гонка с реверсом первой восьмёрки. Ставьте вместе с ней Second race multiplier меньше 1 - обычно 0.5, - чтобы гонка-лотерея не решала судьбу титула.

Пит-окно превращает спринт в гонку стратегий и ближе всего к обязательному пит-стопу из того, что есть в обычном сервере. Пилот, не заехавший в боксы в пределах окна, получает штраф в конце. Объясните это на брифинге перед гонкой - кто-нибудь всегда забывает.

В ACSM есть ещё гоночные уикенды (race weekends): цепочка сессий, которые можно проводить в разное время - квалификация в среду, гонки в четверг, - где решётка каждой сессии строится по результатам одной из предыдущих, с фильтрами вроде реверса или разделения пелотона. Это то, что нужно, когда решётка больше числа боксов и квалификацию надо разбить на две гонки, или когда люди не могут выделить один длинный вечер.

Гоночный вечер#

Порядок действий, при котором вечер проходит спокойно:

  1. До вечера. Убедитесь, что список контента окончательный, entry list совпадает с одобренными пилотами, а конфигурация трассы на этапе выбрана правильно. Запустите этап за час с открытой практикой, чтобы проблемы вылезли до того, как соберётся решётка.
  2. За тридцать минут. Опубликуйте имя сервера, пароль и напоминание о версиях контента. Большинство неудачных подключений - ошибки checksum из-за чьего-то устаревшего мода.
  3. Во время квалификации. Следите в live timing за пилотами, у которых нет времени. Если кого-то нет на этом этапе, скорее всего он застрял на ошибке подключения, а не опаздывает.
  4. Во время гонки. Один стюард наблюдает, никто больше не трогает управление. Админские команды в чате - /admin с паролем администратора, затем /kick, /next_session, /restart_session - для аварийных случаев, а не для подправки результатов.
  5. После гонки. Дайте файлу результатов записаться. Не останавливайте сервер в ту же секунду, как лидер пересёк черту: результаты пишутся, когда сессия заканчивается, после RACE_OVER_TIME.

На последнем пункте организаторы попадаются постоянно. Сервер, остановленный посреди сессии, ничего за эту сессию не запишет. Экспериментальная опция ACSM persist_mid_session_results пытается от этого защитить, принудительно переключая сессию перед остановкой, но надёжнее привычка давать сессиям заканчиваться самим.

Результаты, штрафы и апелляции#

JSON с результатами - единственный источник правды. ACSM автоматически импортирует его в чемпионат, когда этап заканчивается, а ещё файл результатов можно импортировать вручную - так спасают гонку, которую по ошибке провели вне чемпионата или на другом сервере.

Штрафы применяются в окне результатов как добавленное время или потерянные позиции, и очки после этого пересчитываются. Определите порядок работы стюардов до начала сезона:

  • Срок подачи протестов, например 24 часа после гонки, с обязательной ссылкой на момент в реплее.
  • Небольшая коллегия, а не один человек, и никого из участников инцидента.
  • Фиксированная шкала штрафов - пять секунд за мелкий контакт, которого можно было избежать, эквивалент drive-through за серьёзный, - чтобы решения были последовательными, а не личными.

Храните копию каждого исходного файла результатов даже после применения штрафов. Если решение отменят, пересчитывать лучше от оригинала, а не от цепочки правок. Человеческая сторона этого подробнее разобрана в статье правила сервера, модерация и команда, а в ивентах и турнирах на игровом сервере - общий подход к организованным вечерам.

Вариант на файлах

Без ACSM лига - это три папки и порядок действий. Держите по паре server_cfg.ini и entry_list.ini на каждый этап, названных по этапу, и перед вечером копируйте нужную пару в cfg/. После гонки заберите JSON из results, перенесите финишный порядок в таблицу со своей системой очков и правилом countback, примените там штрафы и обновите entry list следующего этапа с учётом success ballast. Это больше ручной работы и вполне рабочий вариант для лиги на двенадцать машин, и у него есть одно настоящее преимущество: конфиг каждого этапа и каждый результат - это обычный файл, который вы сможете прочитать и через десять лет.

Так же лига работает и на сервере под управлением панели. На RE:NODE вы правите оба файла в редакторе в браузере или загружаете пару файлов этапа по SFTP, скачиваете папку результатов из файлового менеджера и перезапускаете сервер из консоли. Запись в Schedules может в заданное время перезапустить сервер с новой последовательностью сессий, а бэкап можно сделать вручную прямо перед гоночным вечером. Если же нужен именно веб-интерфейс ACSM, это задача для машины, где процессы запускаете вы сами.

Бэкапы и сохранность сезона#

Незаменимая часть лиги невелика, и именно поэтому её забывают копировать:

  • server_manager.db (или папка JSON-хранилища) - все чемпионаты, участники, этапы и результаты в ACSM.
  • config.yml, включая session key; его потеря разлогинит всех, но данные не пропадут.
  • Папка results от acServer - запасной вариант на случай, если база данных когда-нибудь повредится.
  • Ваш список контента с точными версиями и ссылками.

Бэкапьте это после каждого этапа, а не раз в неделю. Сезон - это один файл, который меняется раз в неделю: его проще всего на свете защитить и мучительнее всего восстанавливать по памяти. В статье бэкапы, которые действительно восстанавливаются объясняется, почему одна проверка восстановления перед сезоном стоит больше любого числа непроверенных копий.

Решение проблем#

Этап запустился, но в чемпионате нет результатов. Сессию остановили до её окончания, и файл результатов не записался. Загляните в папку results; если файл там есть, импортируйте его вручную.

Пилот числится в чемпионате дважды. Один раз он зашёл с другого аккаунта Steam, или открытый набор добавил его раньше вас. Объедините записи: оставьте один GUID и удалите дубликат до следующего этапа, потому что очки не следуют за именем.

Пилотов кикает сразу после подключения. Закрытый entry list с несовпадающим GUID, несуществующая ливрея или ошибка checksum. Лог сервера назовёт причину.

Решётка короче entry list. MAX_CLIENTS или число боксов на трассе меньше количества участников. Используйте гоночный уикенд с разделённой квалификацией.

Вторая гонка не начинается. REVERSED_GRID_RACE_POSITIONS равен 0, или после RACE_OVER_TIME в гонке не осталось кругов. Проверяйте значение в сгенерированном server_cfg.ini, а не в форме.

Веб-интерфейс недоступен. Веб-порт не открыт, или hostname привязан к localhost. Как проверять порты по одному, рассказано в статье порты игровых серверов; чтение консоли - о том, как найти в логе строку с адресом, к которому он привязался.

FAQ#

Поддерживается ли ещё Assetto Corsa Server Manager?

Оригинальный открытый репозиторий заархивирован и доступен только для чтения. Программа по-прежнему работает, потому что сервер Assetto Corsa годами не менялся, но исправления и новые функции появляются только в форках сообщества.

Можно ли вести чемпионат без Server Manager?

Да. Держите пару конфигов на каждый этап, читайте JSON-файлы результатов после каждой гонки и считайте очки в таблице. На каждый этап уходит больше времени, зато хостить это гораздо проще - то, что нужно небольшой лиге на сервере под управлением панели.

Как не дать посторонним занимать слоты лиги?

Впишите SteamID64 каждого пилота в поле GUID его записи и поставьте LOCKED_ENTRY_LIST=1. Добавьте ещё и пароль на вход, чтобы сервер не заполнялся людьми, которых потом всё равно кикнет.

Зачем нужен множитель второй гонки?

Он масштабирует очки за вторую гонку с реверсивной решёткой. Значение 0.5 даёт половину очков: реверсивная гонка сохраняет смысл, но удачный результат в ней не перевешивает полноценную основную гонку.

Стоит ли автоматически снимать очки за столкновения?

Обычно нет. Сервер считает каждый контакт независимо от того, кто виноват, поэтому автоматические вычеты наказывают и того, в кого врезались, и того, кто врезался. Разбор стюардами по реплеям честнее.

Где хранятся результаты гонок?

В папке results на сервере, по одному JSON-файлу на сессию. Server Manager импортирует их в свою базу данных, но исходные файлы стоит хранить как бэкап и как след для проверки.


Комментарии

Полностью анонимно: без аккаунта, без почты, без cookie. Мы храним имя, которое вы ввели, текст и время - больше ничего. Количество ссылок ограничено, разметка не отображается.

0/2000