Generation Streets: Как я делал игру на основе карты реального мира
Ковырял я, значит, OpenStreetMap, чтобы отрендерить велосипедную карту с лесными тропинками. И параллельно практиковался в игрострое. И в какой-то момент щёлкнуло: «А что, если...». Собственно, результат на картинке.
Конечно, картинка далека от идеала, но во многих населённых пунктах места довольно узнаваемы. После сборки самой первой версии без текстур и декораций я долго просто летал по городу и разглядывал местность. Поэтому, когда меня спрашивают «чем это отличается от Google Street View», я всегда теряюсь, что же ответить.
Поведаю небольшую историю о создании игры.
Планета OSM
Первый вопрос, который встал — как обрабатывать исходные данные. Исходник планеты OpenStreetMap весит порядка 50 гигабайт, и всю планету надо было разбить на тайлы. А потом конвертировать каждый тайл в удобный мне формат.
Эксперименты с postgis-базой не привели ни к чему хорошему: работало, но крайне медленно и как-то неуклюже. В какой-то момент я понял, что база данных мне вообще не нужна: при обработке фрагмента территории мне никогда не потребуется обращаться к данным из другой территории.
Так что, обзаведясь ёмким SSD, я начал нарезку планеты двумя программами из пакета osmctools: osmconvert и osmfilter. Для расчёта координат конкретных тайлов пришлось написать маленькую вспомогательную утилитку (их потом было написано ещё немало).
В результате я получил исходники тайлов, но ведь их надо ещё обрабтать, как минимум, отрезать лишнюю геометрию, что в случае с мультиполигонами непростая задача. Решением был бы gdal, но я упёрся в еще одну задачку: здания, находящиеся на стыке тайлов, хорошо бы не резать пополам, а хранить целиком в одном из соседних.
Поэтому я воспользовался gdal только для «умного чтения» исходника OSM и преобразования геометрии в легко читаемый формат WKT, а сохранялку в нужный мне формат с сохранением формы зданий написал самостоятельно с использованием библиотеки libgeos.
Следующая задача — упаковка тайлов. Их общее число равно 4^Z, где Z — масштаб. В моём случае четырнадцатый, итого 4^14 = 268 миллионов тайлов. Тот факт, что большинство тайлов попадёт на океан или на пустые территории, не сильно скрашивает картину. Казалось бы, взять и упаковать, на лету сжав каким-нибудь gzip-ом, в чём проблема-то? А проблема в том, что тайлы будут подгружаться по сети. И тащить из сети 100-мегабайтный архив ради парочки тайлов не самое оптимальное решение.
А решение было найдено следующее: тайлы упаковываются в зигзагообразном порядке, клиенты будут загружать их через HTTP Range в нужном им масштабе и количестве. Просто и эффективно.
Рельеф
OSM не хранит данные о рельефе, за ним пришлось обращаться к сервису Viewfinderpanoramas, автор которого удобно скомпоновал карту высот ASTER GDEM и SRTM. Нарезка на тайлы производилась аналогично геоданным, для перепроецирования растровых изображений использовалась утилита gdalwarp. Тайлы в 11-м масштабе имеют размер 256х256, с учётом ребра соседнего тайла 257х257, а для вычисления бесшовных нормалей добавлен еще один ряд и столбец по периметру, итого 259х259. Негусто, но в целом достаточно.
Генерирование геометрии
Тут ничего особенного, сплошная рутина. Из интересностей — угадывание высоты здания по площади основания (если высота здания не указана явно). Проект ещё в разработке, детализация будет повышаться по мере доработки новых слоев.
А где игра-то?
Строго говоря, игровой процесс сделан для галочки. Я сознательно не стал вкладывать в него много сил, поскольку понимаю, что главное здесь — возможность рассматривать домики и летать вокруг. Вряд ли кто-то решил бы вложиться такого рода проект ради игрового процесса, ровно как и отказываться от него из-за примитивности геймплея. Возможно, я ошибаюсь.
Музончик
Не упущу возможность похвалиться первой (ладно, не первой, но первой, за которую не стыдно) пробой в музыкальном оформлении. Трек для трейлера записан в Linux MultiMedia Studio с использованием встроенных инструментов и свободных банков SF2.
Что дальше?
В планах доработать рендерер, встроить в игру редактор для уточнения данных на местности, ну и потихонечку открывать исходники: сначала исходники инструментария для обработки данных, а потом и всего рендерера в целом. Так что, думаю, уже в следующем году желающие смогут воспользоваться всеми моими наработками.
Ну а кто хочет полетать в своем городе уже сейчас, ранний доступ Steam к вашим услугам. Загрузить можно практически любую точку планеты, кроме Северного полюса и Антарктиды.
Такие дела. Спасибо за внимание.