Процедурно порождая массивную вселенную - PullRequest
2 голосов
/ 16 декабря 2011

Я создаю текстовую игру и пытаюсь реализовать процедурную генерацию мира.

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

Each universe is a Galaxy[10][10][10] (arbitrary number at the moment),
each galaxy is a randomly sized SolarSystem[50-150][50-150][50-150],
each SolarSystem is a randomly sized CelestialBody[5-20][5-20][5-20].

Все это затем будет записано в файл данных для последующего чтения.

Глядя на это сейчас, если я не ошибаюсь, для этого потребуются (((ClassSize ^ 3) ^ 3) ^ 3) байты, которые невозможно сохранить, даже если ClassSize был всего 4 байта.

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

Мой вопрос: как я могу создать мир такого масштаба более эффективно?

Ответы [ 2 ]

9 голосов
/ 16 декабря 2011

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

Когда вы заполняете свой генератор одним и тем же значением каждый раз, случайные числа будут одинаковыми каждый раз. Так что, если мой уникальный случайный идентификатор игрока равен 654156475, то добавьте этот идентификатор в генератор юниверса, когда я загружу игру, и генератор будет каждый раз генерировать одну и ту же юниверс. Другой игрок получит другую вселенную, потому что его семя отличается от моего.

См. Раздел "1008 * видеоигр" в этой статье , чтобы получить краткий обзор использования этой техники в играх.

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

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

5 голосов
/ 16 декабря 2011

Сделав что-то похожее на то, что вы описали много-много лет назад (тогда, когда на ПК было два 5,25-дюймовых дисковода гибких дисков), я бы не выделил всю игру в памяти. Вы должны разбить ее, чтобы игра загружала частьВселенная, в которой находится игрок, скажем, в трехмерных блоках 10x10x10. Когда бродяги игры пересекают границу загруженного пространства, запишите это пространство на диск и прочитайте в пространстве, в которое они переместились.

...