Обновить

Создание процедурной карты шестиугольников при помощи коллапса волновой функции

Уровень сложностиПростой
Время на прочтение11 мин
Охват и читатели15K
Всего голосов 81: ↑81 и ↓0+103
Комментарии28

Комментарии 28

Думал поиграть получиться, но не нет.

У меня тоже ссылка не работает. Пишет, что устройство или браузер не соответствует требованиям.

Пробовал на разных браузерах. Но на работе у меня Win8.1ю Дома попробую на Win10.

Если у кого получилось зайти в демку - напишите, что требуется.

Я просто с мобильного телефона открыл - получилось через chrome

тоже пишет WebGPU is not available on your device or browser.
хотя на странице https://get.webgl.org/ пишет Your browser supports WebGL и кубик крутится

Аналогичный случай. Кубик крутится, шарик вертится. А демка не открывается.

Обалденно классная разработка. Спасибо за интересную статью! :)

Великолепие! Спасибо большое за красивое решение и отличный результат

Тема генерации тайловых карт не раскрыта в плане приближения к реальным ландшафтам:

  1. Как обеспечить, что горы не будут группироваться в сплошные массивы, а будут образовывать хребты и отроги?

  2. Как обеспечить, что реки будут стекать с гор и возвышенностей (водоразделов), а не пересекать их?

  3. Как обеспечить, что реки будут сливаться, а не разделяться? Но возможно образование рукавов и стариц.

  4. Как обеспечить, что реки будут впадать в моря (можно и в озера, но при этом должны и вытекать из них), а не прерываться или заканчиваться в чистом поле?

  5. Как обеспечить, что дороги будут соединять города/посёлки/святилища/шахты и т.д., а не обрываться и не закольцовываться?

  6. Как обеспечить более-менее оптимальную схему дорог с учетом проходимости ландшафта?

  7. И т.д.

Твик вероятностей «первого тайла» при помощи не только Перлина :)

Поясните, пожалуйста.

Вероятность на то и вероятность, что вероятно всё, даже самое невероятное :)

Как используя процедурную тайловую генерацию объединить три города дорогами по схеме "звезда"?

Тут, скорее, надо с другой стороны танцевать:

  1. Сначала сгенерить крупнокалиберную географию - моря, реки, хребты, отроги.

  2. Затем сгенерить карты высот на основе удаления от гор-морей (и учитывать, что реки должны течь с уменьшением высоты или по равнине). Зашумить карты высот хоть Перлином, хоть еще как. Лишь бы рядом с реками не находились более низкие участки.

  3. Потом сгенерить ландшафты и биомы на свободных клетках с учетом высот и удалений от гор/рек/морей. Т.е. это та же самая тайловая генерация, но высота будет играть роль регулятора вероятности.

  4. Потом поставить города недалеко от рек и морей. Шахты у гор и в болотах, капища в лесах и холмах, руины везде.

  5. Соединить города дорогами. Но не напрямую, в через систему перекрестков между ними (почти по Торричелли - выбирается некая точка между тремя городами и соединяется с городами, потом ищется вариант подешевле). Стоимость дорог учитывает ландшафт (на равнине дёшево, в лесах, холмах и болотах дорого, в горах крайне дорого). Это делается уже не тайловой генерацией, а поверх готового поля. Самые дорогие дороги можно исключить, но так, чтобы на нарушить связности.

Вот как-то так.

Выполняется коллапс ячейки с наибольшим количеством ограничений. Выбираем ячейку с наименьшим количеством оставшихся вариантов (самой низкой энтропией). Случайно выбираем одно из её допустимых состояний.

…вот к этой случайности подмешиваем вот это вот:

Сначала сгенерить крупнокалиберную географию - моря, реки, хребты, отроги

…да и хоть вот это вот:

Потом поставить города недалеко от рек и морей. Шахты у гор и в болотах, капища в лесах и холмах, руины везде.

В результате кварталы начнут раскидываться не абы как, а преимущественно привязанными к центру города (которые посчитали более умным алгоритмом, построенным на принципах логистики или даже хоть внутримировой экономики), а вокруг них уже коллапс обстроит преимущественно город — но не забывая о том, что через город может протекать не только центральная река, а часть кварталов может быть за лесом, в качестве пригорода.

Вероятность на то и вероятность, что вероятно всё, даже самое невероятное :)

Ага! Случайный коллапс в квартал и образование забытой Древними Богами деревушки посреди нигде :)

Всё так, всё так :) :) :)

Эх ... Даже в WarLords-2 захотелось поиграть :)

Города, руины, дороги, сложные ландшафты. Влияние ландшафта на характеристики юнитов.

И очень похожие на сгенерированные WFC карты. Хотя, быть такого не может. Игрушка старая - ей более 30 лет. А WFC получил распространение несколько лет назад.

Я тут немного освежил память по поводу п.5:

На карте с расположенными объектами строится сеть Штейнера. Вернее, её подобие. Потому что настоящая сеть Штейнера строится на непрерывной поверхности с Евклидовой метрикой, а нам придется работать на дискретной гексагональной метрике. Да еще в условиях переменной стоимости прокладки дорог.

Первое обстоятельство, само по себе, не сильно усложняет проблему нахождения перекрёстков. Просто найти тайл, включающий точку Торричелли (если такая есть) и уточнить его симплекс-методом.

Но вот второе обстоятельство, в условиях сложного ландшафта, делает эту задачу нетривиальной:

  1. Найденный тайл может содержать реку. Построить Т-образный мост на картинке можно, но на практике это лишено всякого смысла.

  2. Найденный тайл может находиться в заливе или озере. Тогда никакой симплекс-метод не улучшит суммарную стоимость прокладки дорог. Да и где виданы дорожные развязки над водой?

  3. Найденный тайл может находиться в окружении такого сложного ландшафта, что симплекс-метод, в лучшем случае, поможет слегка улучшить стоимость прокладки дорог (локальный минимум), но не найдет наилучшего способа (глобальный минимум).

Навскидку, пример для последнего случая:

Точка Торричелли находится в лесу внутри подковообразного хребта. Симплекс-метод определяет, что выбор тайла у основания подковы позволит укоротить два пути по лесу за счет удлинения одного пути по лесу. Но оптимальный способ прокладки дорог может заключаться в огибании хребта с внешней стороны подковы. Потому что там нет лесов вообще - одни равнины. Да и через горы прорубаться не надо. Пути получатся длиннее, но дешевле.

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

Но это еще не учитывает, что стоимость самих дорог может зависить не только от ландшафта, но и от качества. Например, к руинам дороги можно не прокладывать специально. Либо протоптать тропинку, стоимость которой околонулевая, а скорость передвижения - низкая (но выше, чем по бездорожью).

Чисто математически, в рамках исследования динамических систем, аттракторов в фазовых пространствах, основная идея устойчивой генерации пазлов в иерархии устойчивых циклов. То есть весь пазл разбивается на замкнутые траектории, а потом они объединяются и плитки пересечения траекторий работают как якоря. Проблема «последней плитки» переносится в комбинаторику минимального замкнутого цикла, а эта комбинаторика компактнее.

Терминология тут не совсем популярная, наполовину я ее генерирую в процессе, иногда нахожу решения у других. Вообще Дмитриев и Кузнецов глубоко исследовали перемежающиеся циклы состояний динамических систем, а вот теорема разрешимости в явном виде была сформулирована Марковым и с тех пор прогресса в ее обобщениях нет (никому не нужно было, пока не выяснилось, что все что нам нужно это внимание)

Очень креативно!

У волновых функций такая же проблема, что и у сверточных сетей - локальность. Влияние "через клетку" не учитывается. Например, на одном тайле заканчивается река, на соседнем она продолжается, на следующем тайле опять заканчивается, что в физическом мире является абсурдом. Мы уже перешли через эту стадию, от генеративных сетей к механизму внимания, когда каждый токен может соотноситься с любым другим, не обязательно с соседним.

Я уже писал выше, что река не может "заканчиваться" иначе, чем впадением в море.

Так же как и дороги не могут прерываться, кроме как на объектах, которые они соединяют.

Петли дорог и рек на равнинах - тоже могут возникнуть в некоторых случаях.

достаточно задать направление реки в тайле, чтобы реки не могли заканчиваться слепо

Да, направление - первое, что приходит на ум. Но вряд ли его одного будет достаточно.

Ну так это тайлы из предлагаемой реализации.

Для реки это может быть исток или затока. Или залив моря.

У дороги это может быть участок, непосредственно примыкающий к поселению или каким-либо руинам. Не рисовать же на самих тайлах построек различные способы подведения дорог. Тем более, что деревья и постройки не помещаются тайлами, а помещаются поверх них следующим слоем. Т.е. на этом огрызке дороги может сверху располагаться куча щебня, бывшая храмом местного божка.

Так о чем я и говорю. Я привел только грубый пример с концами рек в конструкции 3x1. Пример может быть сложнее - кольцевая река, когда река просто течет по кругу, переливаясь сама в себя. Или разделяется, а потом сливается. Тайтлы соединены без ошибок, но образуют нелепую конструкцию. Решений два - либо обучить движок физическим законам - дать понимание высот и физики рек, либо поступить, поступили в энкодерах - обучить движок на наборе правильных карт, чтобы он заучил не только соседние тайтлы, но и дальние взаимосвязи. Иначе будут получаться "шесть пальцев". Это уже будет не коллапс волновой функции (вчерашняя технология), а современный энкодер.

Если начинать генерацию реки с истока (якорный тайл), то закольцовки не будет. Собственно, направление, даже если его явно не задавать, уже будет реализовано при этом.

Разделяться на рукава река может. Только, ненадолго. Вот это уже сложнее реализовать. И в устье реки, обычно, разбиваются на множество рукавов.

А еще есть старицы - тупиковые застойные участки на месте бывшего русла.

Если начинать генерацию реки с истока (якорный тайл), то закольцовки не будет. Собственно, направление, даже если его явно не задавать, уже будет реализовано при этом.

Вопрос не в рукавах и мегаостровах на несколько тайлов, а в том, что соединившись 2 рукава не отменяют необходимости течь дальше к морю, а при случайной генерации это не запрещено получается. (два поворота после развилки и прямой участок между ними)
Но опять же лечится направлением течения. Ну увеличится число перекрестков, но кажется не смертельно. Хотя если это основание степени, то может и смертельно.

Да, теперь понятно. Ни один из рукавов, по-отдельности, не запрещает появление прямого участка. А на самом деле он может соединить эти рукава "встречь".

Ну и точно так же возможно соединение встречь двух рек.

Так что, без указания направления течения не обойтись. Но это увеличит число тайлов с реками. Так вместо одного тайла с Т-образным слиянием/разделением рек (4 тайла с учетом поворотов) появятся 4 тайла с разными направлениями течения. А с учетом поворотов и отражений - 24.

Вообще горы как универсальный пластырь для проблем генерации - это прекрасно

На примере вот что заметил, я в графике не силен, но почему то размытие появляется и на удаленных тайлах и на ближних, как будто в фокусе центральная часть только, это так задумано? Просто из моих скудных знаний о композиции и детализации в рисунках, как будто бы так не должно быть. Опять же с мобильного chrome заходил, может это тоже роляет. А статья зачетная, спасибо!

Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации