Элегантный способ симулировать большое количество объектов в игровом мире

33

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

В игре каждое существо имеет свое собственное тело, которое разделено на более мелкие части (туловище, ноги и т. Д.), И иногда эти части содержат органы, которые выполняют определенную функцию в теле. Является ли орган в настоящее время для какой-либо цели или активен, на самом деле никогда не ясно. В конце концов, у животного может быть пустой желудок, поэтому ему не нужно ничего переваривать. Было бы довольно нелепо проверять или моделировать каждый объект в каждом кадре и очень дорого, как только у вас появилось много существ в мире. Поэтому я думал о том, как разумно провести различие между объектами, которые необходимо обновить, и объектами, которые не нужно обновлять.

То, что я придумал, кажется, по крайней мере, хорошим решением. Он создает простую очередь / стек (важно, чтобы каждый элемент удалялся, как только он прочитан; порядок не имеет значения), называемый «стеком внимания», в котором находятся объекты, которые необходимо смоделировать. Объекты, которые требуют внимания, просто помещают себя в стек или помещают туда другие объекты. Эти объекты, вероятно, реализуют простой интерфейс с функцией simulate ().

Применительно к моему предыдущему примеру пищеварения это будет означать:

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

Предполагаемая проблема с этим - объекты на холостом ходу. Спящее животное является хорошим примером этого. Это можно сделать, как описано ранее, держа спящего животного в стопке и каждый раз проверяя, нужно ли ему просыпаться, но это кажется расточительным, поскольку это единственное, что делается. Чтобы сделать объекты на холостом ходу более эффективными, я планировал добавить своего рода расписание, в котором будут храниться задания, которые должны быть выполнены в определенное время. Если животное ложится спать, оно ставит работу по этому графику, который будет назначаться на определенное время после того, как животное ложится спать. Затем эта работа позаботится о том, чтобы снова поставить спящего животного на стек внимания. Теперь вы можете сказать, что спящее животное, которого нет в стеке внимания, может пропустить атаку, потому что его ИИ не моделируется,

Честно говоря, я не знаю, насколько это близко к элегантному решению этой проблемы из-за недостатка опыта. Я близок к чему-то полезному? Как это обычно делается, или у кого-нибудь есть какие-либо предложения или лучшие решения?

Марк Мюллер
источник

Ответы:

10

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

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

Хендрик Браммерманн
источник
Что, если что-то еще взаимодействует с объектом в это время? Например, спящее животное может быть разбужено ударным камнем. Если вы удалите график животных в этом случае?
Эмилиано
Это зависит от ситуации: если совершенное действие безвредно (например, просыпаться, когда уже не спишь), мы просто позволяем этому случиться. Но если действие использует некоторый ресурс, мы ищем в очереди ожидания и удаляем его.
Хендрик Браммерманн
14

Похоже на проблему с входами: у вас есть более 100 клавиш на клавиатуре, но вы не хотите проверять каждую клавишу на каждом кадре, так что вы делаете?

Два ответа: опрос или системные сообщения.

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

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

Ян Шрайбер
источник
10

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

Например:

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

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

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

wkerslake
источник
Да, игрок сможет заметить разницу, и есть несколько эффектов, которые это оказывает на игровой процесс, но на данный момент это больше «уловка» для развлечения. Вроде как система ран в Dwarf Fortress, которая также очень детальная, но незначительная. Но, как вы уже упомянули, работать над этим очень весело, и это мой главный фокус сейчас.
Марк Мюллер
9

У меня была похожая проблема в игре, над которой я работал несколько лет назад - моделирование объектов было сложным и не могло быть выполнено в деталях для каждого объекта в мире.

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

Skizz
источник
2

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

user2047
источник
1

Для этого есть шаблон дизайна. Я думаю, что это называется объектами базы данных?

По сути, вы держите одну «шаблонную» овцу, которая может представлять всех нестандартных овец в игровом мире, рисуете их одинаково, сохраняя уникальные данные в объекте шаблона, скажем, в виде таблицы местоположений и / или времени овец. -since-сдвига. Затем, когда вам нужно сделать овцу уникальной, вы можете создать конкретный экземпляр для отслеживания этой уникальной овцы.

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

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

Это похоже на использование делегата для анимации.

davenpcj
источник
3
Мухи, вы имеете в виду?
topright
0

Будет ли государственная машина работать? Животное находится, например, в спящем состоянии, в состоянии поедания, в состоянии бега и т. Д. Для каждого состояния вы связываете список активных органов. Таким образом, в каждом кадре вы посещаете каждое животное, включаете состояние, ищите список органов для этого состояния и выполняете обновление для каждого из органов.

Эрик Энгхайм
источник
Я думаю, что это усложнит ситуацию, потому что в животном должно произойти множество вещей. Например, если желудок что-то переваривает, это не значит, что сердце перестает биться или животное перестает ходить. Конечно, вы можете определить набор состояний, каждое из которых учитывает определенные функции, но количество состояний будет безумно огромным.
Марк Мюллер
В каждом состоянии может произойти несколько вещей, потому что вы сохраняете все активные органы в состоянии и выполняете каждый из них каждый кадр. Хотя многое из того, что происходит в вашей симуляции, похоже, соответствует переходам между состояниями. Например, Жевание -> Переваривание. Но, полагаю, вы правы в том, что у животного не может быть только одного состояния. Есть переходы состояний, происходящие, скажем, с конечностями, которые не связаны с переходами состояний, происходящими в пищеварительной системе. Но, может быть, это просто сложнее того, что у вас есть. Просто подумал, что это может быть что-то, чтобы рассмотреть.
Эрик Энгхейм