суббота, 1 августа 2015 г.

Не, не выйдет ничего

Итак, я окончательно закопался со своим "невероятно изменчивым миром".
Напомню, что изначальная идея состоит в том, чтобы сделать что-то похожее на Майнкрафт, но отличающееся от него тем, что мир не является чем-то статичным, а изменяется так, что создается ощущение, будто ты находишься в таком месте, где все имеет свои последствия и изменения в одном месте так или иначе немного, но влияют на все остальное. Как - вопрос количества "законов" в этой природе.
Начал я, как было рассказано ранее, с двухмерной плоскости, которая представляла собой некую не очень точную (в силу растянутости у полюсов) развертку поверхности круглой планеты. Плоскость была разбита на квадраты 16х8 с очень хитрой целью. Дело в том, что для меня показалось важным смоделировать так же поток энергии от ближайшей звезды, но, конечно, не абсолютно точно, так как это точно не успевало бы обрабатываться с той скоростью, которая нужна. А вот 16х8 показалось идеальным размером. Дело в том, что одно полушарие, которое освещено сейчас, таким образом сотоит из 8х8 блоков, и они точно делятся на две части в любом направлении. И здесь можно найти зону, в которую лучи падают почти перпендикулярно, то есть, экватор, в котором сейчас полдень и приходит больше всего энергии, места, где солнце уже не в зените или, если смотреть с экватора в сторону полюса, более "тропический" климат. И, конечно, полярные шапки, куда ее поступает меньше всего. Далее я считаю, что блоки, в которых никого нет в данный момент, можно не "уточнять". То есть, достаточно обработать 16х8 блоков, но.
На планете кто-то есть, кто может ее наблюдать и трогать своими грязными руками. Это игроки. Изначально предполагается, что можно уметь в мультиплеер. То есть, точек, в которых может кто-то быть, много.
Чтобы зоны вокруг игроков "уточнить", применялся простой алгоритм пересечения круга (некоего радиуса восприятия игроком) и квадрата, то есть "блока". В случае пересечения считалось, что игрок "чувствует" блок и алгоритм рекурсивно спускался глубже, на уровень своей структуры 8х8, проверяя каждый внутренний блок на предмет пересечения уже с кругом радиусом в 8 раз меньше. Так достигалось постепенное увеличение точности при приближении к игроку. В минимальном радиусе обрабатываются уже конкретные единичные блоки. Все выглядит офигенно просто, но. Рост количества вычислений с ростом числа игроков, которые находятся далеко друг от друга - линейный. Однако, есть плюс - алгоритм обхода "тиками" сервера, как мне кажется, довольно легко рассыпается по отдельным потокам, лишь с учетом блокировок, которые неизбежны при влиянии соседнего блока на текущий обрабатываемый.
Для тестирования производительности применялся довольно-таки простой, но, в то же время, очень нужный изначально алгоритм постепенного "сглаживания" некоего значения между блоками. Нужный он потому, что он неплохо изображает из себя, например, растекание кубометра воды по плоскости, хотя он и предельно упрощен. Также на нем я заткнулся в одну задачу, которая также принципиально важна вообще для идеи.
Задача следующая, состоит из двух частей:
1) Игрок удаляется от блока, из-за чего точность в этом месте должна снизиться. Необходимо "свернуть" всю информацию, которая обрабатывалась перед этим с высоким разрешением в виде, скажем 8х8 блков, в одно значение, которое сохранится теперь в одном "верхнем" блоке, так, чтобы после ее обработки можно было выполнить вторую часть.
2) Игрок возвращается. Нужно снова увеличить разрешение, сделав из одного значения снова 8х8. При этом должно быть максимально достигнуто ощущение, что все обрабатывалось как раньше.
Скажу сразу, наскоком изобрести "правдоподобное" не удалось.
Далее попытался перейти в 3D, для более удобного рассматривания результатов. То что делалалось на плоскости, стало сложнее. Хотя я не сделал все структуры трехмерными (и рисовал просто "пластинку" верхнего словя), и даже не перешел к поиску способа впихнуть все вышеописанное в трехмерность, у меня уже возникла проблема, как передать клиенту только то, что он и правда может увидеть. То есть, нужен рейтрейсинг/рейкастинг или какой угодно еще алгоритм. Причем, видимо, он должен работать на сервере, чтобы не гонять лишние данные по сети. Либо, второй вариант, нужно найти все, что обрабатывалось из-за него сервером и передать всю эту кучу блоков-подблоков, а он уже пусть там сам разбирается. Тут, кстати, несколько решений пришло в голову, начиная с простого обхода некоторой зоны вокруг игрока с загрузкой только того, что "обработано", до запихивания ссылок на каждый обрабатываемый блок прямо в объект игрока для передачи прямо сейчас (он кажется проще и делает меньше дополнительных "обходов"). Оба варианта, скажем так, будут "тестироваться". Пока что тестируется второй. Однако, все равно не ясно пока, как просто и дешево потом в клиенте избавляться от "невидимого", а также более "крупных" блоков при получении мелких.

Но, в целом, создается впечатление, что со всем таким не справится даже топовое железо.

Комментариев нет:

Отправить комментарий