Implement tiled multiplayer city simulation and scaling stages
This commit is contained in:
1 parent
3d4b29fedf
commit
3b1fcd996a
53 files changed
+7354
-13
No files matched your search
@@ -0,0 +1,73 @@
|
||||
# Сервер симуляции
|
||||
|
||||
Из корня репозитория: `npm run server:dev`, затем открыть
|
||||
`http://localhost:3000/?play`. Нужны Node.js 22+ и Rust stable с системным
|
||||
компилятором/linker. Обёртка также находит локальную установку в `.tools/`.
|
||||
|
||||
`axum` обслуживает клиент, каталог, очередь генерации и бинарный WebSocket.
|
||||
Каждая активная комната владеет отдельным `bevy_ecs::World` в своём потоке.
|
||||
Симуляция работает на 10 Гц, репликация — на 5 Гц. Один реальный шаг
|
||||
соответствует шести игровым секундам при скорости ×1.
|
||||
|
||||
Жители идут по дорожному графу между ближайшими к дому и работе узлами
|
||||
утром и возвращаются вечером. Если в OSM нет подходящих домов/рабочих мест,
|
||||
используются демонстрационные маршруты по связным дорогам. Интерьерная
|
||||
геометрия, двери, лестницы и слоты загружаются по области наблюдения;
|
||||
детальный поиск пути на этаже учитывает стены, проёмы и мебель. Перемещение
|
||||
жителей между этажами и использование мебели относятся к игровому слою.
|
||||
|
||||
Далёкие маршруты обновляются раз в десять реальных секунд. Положение при
|
||||
подписке вычисляется точно из календаря. AOI ограничен 2×2 км, снимок —
|
||||
1000 жителями по умолчанию; клиент увеличивает LOD при переполнении. Плотные области
|
||||
показывают стабильную выборку жителей. Репликация ограничена 90 КБ/с на
|
||||
клиента с запасом 180 КБ на начальный снимок; пропущенные дельты объединяются.
|
||||
|
||||
Ник уникален в комнате, сессия выдаётся сервером. Пауза и скорости 1/2/4
|
||||
принимаются большинством более половины подключённых игроков. Голосование
|
||||
длится 20 с; интервал предложений игрока — 30 с. Владелец и привилегии
|
||||
создателя отсутствуют. Создание ограничено одним запросом с IP в минуту.
|
||||
|
||||
Снимки Protobuf кодируются и записываются отдельным ограниченным по очереди
|
||||
потоком, атомарно заменяются и ротируются; голоса и подключения
|
||||
не сохраняются. При старте восстанавливается каталог комнат, `World`
|
||||
загружается при первом подключении. Изменившийся манифест блокирует
|
||||
восстановление с понятной ошибкой. Новые экспорты содержат SHA-256 тайлов
|
||||
и навигационного индекса; существующий каталог города не перезаписывается.
|
||||
|
||||
Переменные окружения:
|
||||
|
||||
- `CITYGEN_BIND`: `127.0.0.1:3000`.
|
||||
- `CITYGEN_CITIES`: `public/cities`; `CITYGEN_SAVES`: `data/rooms`.
|
||||
- `CITYGEN_MAX_ROOMS`: 5; `CITYGEN_AGENTS`: 1000, максимум 1000000.
|
||||
- `CITYGEN_MAX_VISIBLE`: 1000, максимум 5000; `CITYGEN_SIM_THREADS`: до четырёх CPU по умолчанию, общий пул ECS на процесс.
|
||||
- `CITYGEN_EMPTY_TIMEOUT`: 300 с; `CITYGEN_SAVE_INTERVAL`: 60 с.
|
||||
- `CITYGEN_KEEP_SNAPSHOTS`: 3.
|
||||
- `CITYGEN_MAX_GENERATION_KM2`: 25; `CITYGEN_MAX_BUILDINGS`: 10000.
|
||||
- `CITYGEN_GENERATION_WORKERS`: 2; `CITYGEN_GENERATION_QUEUE`: 8.
|
||||
- `CITYGEN_GENERATION_TIMEOUT`: 600 с.
|
||||
- `CITYGEN_OSM_FIXTURE`: путь к локальной выгрузке Overpass для офлайн-проверки очереди; по умолчанию используется Overpass API.
|
||||
|
||||
Очередь запускает TS-генератор отдельным Node-процессом. `CreateCity` и
|
||||
`CityJob` из общей схемы передаются по HTTP как `application/x-protobuf`.
|
||||
Каталог и создание комнаты используют JSON. Задания очереди не переживают
|
||||
перезапуск; готовые города и снимки комнат сохраняются на диске.
|
||||
|
||||
`/health` проверяет доступность; `/metrics` отдаёт число игроков/комнат,
|
||||
тик, время последнего и максимального шага, число сущностей и байты очереди рассылки каждой
|
||||
комнаты в формате Prometheus. Медленные тики и ошибки снимков идут в stderr.
|
||||
При Ctrl+C сервер останавливает комнаты с сохранением.
|
||||
|
||||
Проверки: `npm run server:test`, `npm run server:load`. Второй стенд использует
|
||||
миллион жителей, 4096 синтетических маршрутов и 30 небольших областей
|
||||
наблюдения, включая кодирование полных снимков как верхнюю оценку трафика.
|
||||
Он не моделирует RTT, диск, браузеры или плотную толпу в одной точке. Отдельный
|
||||
интеграционный тест подключает 30 настоящих WebSocket-клиентов к 1000 жителей.
|
||||
|
||||
Настоящая нагрузка на выбранный город: запустить `npm run server:release` с
|
||||
`CITYGEN_AGENTS=1000000`, затем `npm run server:bots -- http://localhost:3000 balzers-demo 20`.
|
||||
Боты создают комнату, подключаются, подписываются на 30 областей, адаптируют
|
||||
LOD и выводят трафик, выборку длительности тиков и ошибки соединений.
|
||||
|
||||
Dockerfile подготавливает приложение для одного сервера. Каталоги городов
|
||||
и `data/` необходимо подключать постоянными томами. Docker-сборка и внешний
|
||||
деплой требуют отдельной проверки в целевом окружении.
|
||||
Reference in new issue
Block a user