Skip to content

Выводы исследования: оба лимита структурные ​

Лимит онлайн-игроков = 255 (жёсткое ограничение разрядности протокола) ​

РасположениеСодержание
src/network/network_type.h:21static const uint MAX_CLIENTS = 255;
src/network/network_type.h:54ClientPoolIDTag : PoolIDTraits<uint16_t, MAX_CLIENTS + 1, 0xFFFF>
src/network/core/network_game_info.cppclients_max / companies_max передаются через Send_uint8 / Recv_uint8 в SerializeNetworkGameInfo (строки 251-296) и десериализации (строки 422-432)
src/table/settings/network_settings.ini:241network.max_clients (SLE_UINT8, max = MAX_CLIENTS, по умолч. 25)
src/network/network_server.cpp:360Проверка при подключении _network_clients_connected < MAX_CLIENTS

Вывод: 255 — это уже предел поля uint8 протокола. Для его превышения необходимо изменить clients_max и связанные поля на uint16 — это изменит протокол client↔server, UDP-широковещательные рассылки и протокол Game Coordinator, что является внешним изменением протокола (в рамках форка оба конца могут играть, но совместимость с публичным списком серверов пострадает).

Лимит количества компаний = 15 (жёсткое ограничение формата хранения владельца тайла) ​

РасположениеСодержание
src/company_type.h:25CompanyIDTag : PoolIDTraits<uint8_t, 0xF, 0xFF> → MAX_COMPANIES = CompanyID::End().base() = 15
src/tile_map.h:195SetTileOwner: SB(_m[tile].m1, 0, 5, owner.base()) — владелец тайла хранится только в 5 битах (младшие 5 бит _m[].m1)
src/company_type.h:30-33OWNER_TOWN{0x0F}, OWNER_NONE{0x10}, OWNER_WATER{0x11}, OWNER_DEITY{0x12}, OWNER_END{0x13} используют то же байтовое пространство, что и ID компаний

Вывод: Owner и CompanyID — один и тот же тип, поле владельца тайла имеет только 5 бит (значения 0-31), из которых 15-18 заняты специальными владельцами. Таким образом, реальный лимит компаний 15 определяется форматом массива карты — для его увеличения требуется расширить хранение владельца тайла (все 8 бит m1 или изменить структуру _m) и мигрировать константы OWNER_*, что включает полную конвертацию сохранений и рост памяти карты, являясь крупным рефакторингом формата (поэтому OpenTTD upstream не делал этого много лет).

Варианты решений ​

ВариантИзмененияСовместимостьРекомендация
A. Оставить как естьНетПолная совместимость сохранений/протокола/координатора✅ Рекомендуется: 255 клиентов / 15 компаний уже значительно превышает оригинал для многопользовательской игры
B. Клиент → протокол uint16Сериализация/десериализация network_game_info.cpp изменить на Send_uint16/Recv_uint16; MAX_CLIENTS поднять до 4095; max_clients в network_settings.ini изменить на SLE_UINT16; поле в settings_type.h изменить на uint16; ширина отображения в console_cmds.cpp:1056Играбельно в рамках форка; несовместимо с публичным координатором/старыми клиентамиОпционально, если действительно нужно >255 клиентов
C. Компании → рефакторинг формата тайловРасширение поля владельца тайла + миграция констант OWNER_* + полная конвертация сохраненийИзменение формата сохранений (одноразовая конвертация)Не рекомендуется для краткосрочной реализации

Что уже предоставлено ​

  • Данный проектный документ (с точными файлами/строками);
  • Опциональный патч option-clients-uint16.diff (полные изменения для варианта B, не применён, доступен для git apply).

Вывод: «Расширение» обоих лимитов по сути является обновлением формата/протокола, а не настройкой; при сохранении совместимости сохранений и публичной сети текущие 255/15 являются пределом. Если допустимы затраты на совместимость, варианты B/C реализуются как описано выше.