Files
citygen/README.md
T

11 KiB
Raw Blame History

Город сверху — генератор OSM и клиент-серверная симуляция

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

Эксплуатация и игровой слой

Для запуска через Docker Compose см. deploy/README.md. В комнате доступны казна, запасы еды, потребности населения, события и три ограниченных действия игроков. Подробности модели и настроек — server/README.md. Интерфейс оператора: /?admin.

Сетевая игра

Нужны Node.js 22+ и Rust stable (на Windows — установленный MSVC linker). Запускать команды из корня репозитория:

npm ci
npm run demo           # готовый город из локального образца OSM, без запросов к Overpass
npm run build
npm run server:dev     # http://localhost:3000/?play

В списке выберите Бальцерс, задайте ник и создайте комнату. Другие игроки входят в ту же комнату из списка. Кнопка «Создать город на сервере» открывает выбор области и запускает отдельную задачу генерации с прогрессом.

Можно экспортировать уже готовый мир и открыть только статику без симуляции:

npm run export-city -- world.json public/cities/my-city
# http://localhost:3000/?city=/cities/my-city/manifest.json

Экспорты не перезаписываются: новая версия города получает новый каталог. Настройки, API, ограничения LOD и описание сохранений находятся в server/README.md.

Проверки: npm run typecheck, npm test, npm run server:test, npm run server:load. Изменение протокола: npm run proto:generate.

Браузерный генератор для отладки

Выделяете на карте небольшой город или район → по данным OSM строится подробная карта с видом строго сверху: дороги реальной ширины с тротуарами и разметкой, парковки с машинами, деревья, и у каждого здания — этажи, комнаты, двери, окна, лестницы и мебель, нарисованные простыми геометрическими фигурами, как на плане квартиры.

В отладочном режиме всё работает в браузере: данные берутся из Overpass API, генерация идёт в Web Worker'ах, готовый мир сохраняется в IndexedDB.

Машины появляются только на парковках и в гаражах; вдоль улиц они не генерируются.

Запуск

Нужен Node.js 18+.

npm install
npm run dev        # http://localhost:5173/  (пересборка на лету)
npm run build      # сборка в dist/ — можно положить на любой статический хостинг
npm run typecheck

Для автоматических проверок сетевого клиента нужен Node.js 22+: npm test. Тесты проверяют таймауты, переключение серверов и отмену без обращения к сети.

Данные сначала запрашиваются у maps.mail.ru, затем у overpass-api.de и overpass.private.coffee. На каждый запрос отводится 45 секунд, включая загрузку ответа; после ошибки или таймаута используется следующий сервер. Лимит обработки запроса на стороне Overpass — 30 секунд. Кнопка «Отмена» прерывает запрос и ожидание перед повтором.

Без интернета можно проверить на образце: «Другие способы» → «Сгенерировать из выгрузки Overpass» → samples/balzers-2013.json (Бальцерс, Лихтенштейн, данные OSM 2013 года).

Генерация из файла без браузера (для отладки генератора):

npm run cli -- samples/balzers-2013.json 47.058 9.492 47.074 9.518 world.json

Управление

  • перетаскивание — сдвиг, колесо / щипок — масштаб, двойной клик — приблизить;
  • справа — этаж для всей карты (⌂ — крыши), PgUp/PgDn или [ ];
  • клик по зданию — карточка: вид, этажность (из OSM или оценка), квартиры, спальные места, свой переключатель этажей только для этого здания;
  • «Экспорт мира» в отладочном режиме — весь мир одним файлом .json.gz; export-city преобразует его в серверный тайловый формат.

Как устроена генерация

Overpass JSON ─► city.ts ──────────────► зоны, дороги, контуры зданий, деревья, парковки
                   │  classify.ts          вид здания (по тегам, POI внутри, landuse, площади) и этажность
                   ▼
              interior.ts (в воркерах) ─► этажи: сетка 0.5 м в осях здания
                   │  схема: секции с подъездами | коридор | простая раскладка
                   │  деление на комнаты по программе (м²), несколько попыток с оценкой
                   │  двери = остовное дерево по графу смежности, санузлы и спальни — тупики
                   │  вход с фасада к дороге, окна с шагом по типу здания
                   ▼
              furnish.ts + catalog.ts ──► мебель по правилам для каждого типа комнаты
                   ▼
              finalize.ts ──────────────► общие модели предметов, округление до 1 см
  • Сид здания = OSM-id ⊕ сид мира — один и тот же город всегда генерируется одинаково.
  • Многоквартирные дома — секционные: подъезд с лестницей (и лифтом от 5 этажей), площадка, 1–4 квартиры вокруг неё; на первом этаже — проход к входу, у домов с магазинами вместо квартир магазины со своими входами с улицы.
  • Офисы, школы, больницы, гостиницы — коридорная схема.
  • Дома, магазины, кафе, цеха, склады, храмы, гаражи — простая раскладка (у гаражных рядов — отдельные боксы с воротами).

Модель данных мира (src/types.ts)

Статические данные уже используются сервером; для дальнейшего игрового слоя предусмотрены:

Что Зачем потом
Door.rooms = [комната, комната | 'outside'] рёбра графа навигации внутри здания
Stairs (одно место на всех этажах, up/down), лифты переходы между этажами
Unit — квартира / магазин / офис с roomIds и beds домохозяйства и рабочие места для жителей
Prop.blocksMove, Prop.blocksSight, tags (sleep:2, sit:4, work, cook, storage…) коллизии, линия обзора, что агент может сделать с предметом
Wall с разрывами под двери и окна, Window коллизии и видимость (окна прозрачны для взгляда)
Road с шириной, тротуарами, oneway, слоями граф улиц для перемещения по городу
все объекты с id хранение состояния: открытая дверь, взятый предмет

Координаты — метры в локальной проекции вокруг центра области (x — восток, y — юг).

Ограничения MVP

  • Область до 25 км²; предупреждение о времени генерации — свыше 10 км². Скорость и расход памяти зависят от плотности застройки и этажности. Публичные серверы Overpass рассчитаны на умеренную нагрузку; для публичной игры понадобится своё зеркало или заранее нарезанные данные (например, экстракт Geofabrik → статические файлы).
  • Подвалы, мансарды, балконы, береговая линия морей пока не генерируются.
  • Нестандартные контуры (сильно изломанные) дают менее аккуратные планировки.

Данные и лицензии

Данные карты © участники OpenStreetMap, лицензия ODbL. Если вы распространяете сгенерированные миры, укажите «© OpenStreetMap contributors». Тайлы на экране выбора области — стандартные тайлы OSM по их правилам использования; поиск — Nominatim (не чаще раза в секунду).

Идеи частично подсказаны проектом KnoxMap; код написан с нуля.