Generation Streets: Как я делал игру на основе карты реального мира

Ковырял я, значит, OpenStreetMap, чтобы отрендерить велосипедную карту с лесными тропинками. И параллельно практиковался в игрострое. И в какой-то момент щёлкнуло: «А что, если...». Собственно, результат на картинке.

RTX off, RTX on (на самом деле это всего лишь мой рендерер)
RTX off, RTX on (на самом деле это всего лишь мой рендерер)

Конечно, картинка далека от идеала, но во многих населённых пунктах места довольно узнаваемы. После сборки самой первой версии без текстур и декораций я долго просто летал по городу и разглядывал местность. Поэтому, когда меня спрашивают «чем это отличается от Google Street View», я всегда теряюсь, что же ответить.

Поведаю небольшую историю о создании игры.

Планета OSM

Первый вопрос, который встал — как обрабатывать исходные данные. Исходник планеты OpenStreetMap весит порядка 50 гигабайт, и всю планету надо было разбить на тайлы. А потом конвертировать каждый тайл в удобный мне формат.

Эксперименты с postgis-базой не привели ни к чему хорошему: работало, но крайне медленно и как-то неуклюже. В какой-то момент я понял, что база данных мне вообще не нужна: при обработке фрагмента территории мне никогда не потребуется обращаться к данным из другой территории.

Так что, обзаведясь ёмким SSD, я начал нарезку планеты двумя программами из пакета osmctools: osmconvert и osmfilter. Для расчёта координат конкретных тайлов пришлось написать маленькую вспомогательную утилитку (их потом было написано ещё немало).

Визуализация тайлов в Geofabrik's Tile Calculator
Визуализация тайлов в Geofabrik's Tile Calculator

В результате я получил исходники тайлов, но ведь их надо ещё обрабтать, как минимум, отрезать лишнюю геометрию, что в случае с мультиполигонами непростая задача. Решением был бы gdal, но я упёрся в еще одну задачку: здания, находящиеся на стыке тайлов, хорошо бы не резать пополам, а хранить целиком в одном из соседних.

Поэтому я воспользовался gdal только для «умного чтения» исходника OSM и преобразования геометрии в легко читаемый формат WKT, а сохранялку в нужный мне формат с сохранением формы зданий написал самостоятельно с использованием библиотеки libgeos.

Следующая задача — упаковка тайлов. Их общее число равно 4^Z, где Z — масштаб. В моём случае четырнадцатый, итого 4^14 = 268 миллионов тайлов. Тот факт, что большинство тайлов попадёт на океан или на пустые территории, не сильно скрашивает картину. Казалось бы, взять и упаковать, на лету сжав каким-нибудь gzip-ом, в чём проблема-то? А проблема в том, что тайлы будут подгружаться по сети. И тащить из сети 100-мегабайтный архив ради парочки тайлов не самое оптимальное решение.

А решение было найдено следующее: тайлы упаковываются в зигзагообразном порядке, клиенты будут загружать их через HTTP Range в нужном им масштабе и количестве. Просто и эффективно.

Generation Streets: Как я делал игру на основе карты реального мира

Рельеф

OSM не хранит данные о рельефе, за ним пришлось обращаться к сервису Viewfinderpanoramas, автор которого удобно скомпоновал карту высот ASTER GDEM и SRTM. Нарезка на тайлы производилась аналогично геоданным, для перепроецирования растровых изображений использовалась утилита gdalwarp. Тайлы в 11-м масштабе имеют размер 256х256, с учётом ребра соседнего тайла 257х257, а для вычисления бесшовных нормалей добавлен еще один ряд и столбец по периметру, итого 259х259. Негусто, но в целом достаточно.

Генерирование геометрии

Тут ничего особенного, сплошная рутина. Из интересностей — угадывание высоты здания по площади основания (если высота здания не указана явно). Проект ещё в разработке, детализация будет повышаться по мере доработки новых слоев.

Скриншот снят где-то в Самаре
Скриншот снят где-то в Самаре
А этот — в Праге
А этот — в Праге

А где игра-то?

Строго говоря, игровой процесс сделан для галочки. Я сознательно не стал вкладывать в него много сил, поскольку понимаю, что главное здесь — возможность рассматривать домики и летать вокруг. Вряд ли кто-то решил бы вложиться такого рода проект ради игрового процесса, ровно как и отказываться от него из-за примитивности геймплея. Возможно, я ошибаюсь.

Музончик

Не упущу возможность похвалиться первой (ладно, не первой, но первой, за которую не стыдно) пробой в музыкальном оформлении. Трек для трейлера записан в Linux MultiMedia Studio с использованием встроенных инструментов и свободных банков SF2.

Трейлер с авторской музыкой

Что дальше?

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

Ну а кто хочет полетать в своем городе уже сейчас, ранний доступ Steam к вашим услугам. Загрузить можно практически любую точку планеты, кроме Северного полюса и Антарктиды.

Такие дела. Спасибо за внимание.

9999
50 комментариев

такс такс
в этой компутерной игре можно воссоздать школу
по скользкой дорожке идете!

104
Ответить

Сделать школу уровнем для контры/кваки было норм ещё когда я в школе учился.

1
Ответить

Мир хрущевок - охрененно.

29
Ответить

Хрущворлд

7
Ответить

Скриншот снят где-то в Самаре.Эх, узнаю Самару

7
Ответить

Ну нифига ж себе, два почти одинаковых проекта выпущены почти одновременно. Хотя идея не такая уж неповторимая, я был крайне удивлен, когда узнал, что на момент начала разработки не было почти ничего подобного (были импортёры в Блендеры и всякие Юнити, но это для единичных городов).

1
Ответить