Files
citygen/server/README.md
T

74 lines
6.8 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Сервер симуляции
Из корня репозитория: `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-сборка и внешний
деплой требуют отдельной проверки в целевом окружении.