11 KiB
Город сверху — генератор OSM и клиент-серверная симуляция
Добавлен серверный режим по плану: подготовленные города, комнаты до 30 наблюдателей, жители по расписанию, общий календарь и голосования, сохранения и очередь генерации. Браузерный генератор ниже остаётся режимом отладки.
Сетевая игра
Нужны 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; код написан с нуля.