Герои научились продавать излишний лут + разбор того как это реализовано
Привет всем, последние несколько недель я занимался прототипированием некоторых компонентов ИИ, улучшая поведение агентов в игре. Подход имеет в основе метод "job givers", который включает в себя кастомный планировщик задач похожий на GOAP. Само улучшение пока небольшое, но в будущем на его основе я буду строить другие поведения для агентов. Вкратце уже рассказывал как это работает в предыдущих постах. Сейчас будет немного подробностей и совсем немного кода.
В приведенной выше демонстрации (скорость симуляции увеличена) агенты охотятся на монстров, собирают добычу, а затем продают излишки добычи кузнецу.
Как это работает?
Примерно так работают агенты в игре. По сути они просто ждут заказов, потом просят планировщик выбрать наиболее важный, ездят по рельсам проложенным системой навигации выполняя задания на месте назначения (как правило все задания это проигрывание анимации с некоторым результатом). Также агентам помогают разные структуры поиска для быстрого нахождения близких предметов на карте, обхода препятствий и других задач.
Для прокладки маршрута у нас используется классический A* с эвристикой. В качестве структуры для поиска пути используется плотная регулярная сетка (dense navigation grid) у которой можно менять размер ячеек (в основном это для отладки).
Помимо собственно поиска пути который по сути прокладывает рельсы от точки A к цели, агенты также должны уметь обходить динамические препятствия. Для этого есть несколько стратегий, часть из которых у меня уже реализованы. Самые популярные общие варианты решений – это перестройка пути (полного или частичного) и "рулевое управление" (steering). Суть рулевого управления в том чтобы к основному вектору движения (forward vector) добавить корректирующий вектор (repulsion) который будет отталкивать агента от препятствий которые возникли на пути. Отталкивающий вектор обычно обратно пропорционален расстоянию или квадрату расстояний до всех препятствий на пути к цели (можно использовать скалярное произведение с forward vector).
Кроме поиска пути система ИИ также нуждается в быстром поиске объектов на карте. Для этого у меня используется другая сетка регионов (spatial grid) которая запоминает какие объекты находятся в каких регионах. Для поиска в такой сетке нам нужно просто вычислить координаты региона и перебрать все сущности внутри него и во всех регионах в некотором радиусе. Похожий метод используется например в RimWorld. Внутри регионов можно например хранить номера сущностей (id), их AABB (для пересечения) и маску слоев.
На примере внизу – визуализация того что хранится в такой сетке для каждого слоя (1 = препятствия, 2 = существа, 4 = предметы, 8 = структуры), каждая сущность при этом может раcсполагаться на нескольких слоях одновременно (для этого в маске слоев нужно присвоить бит этого слоя единице).
Поиск радиусе в сущностей с помощью сетки регионов может выглядеть так:
Из других деталей ИИ, у нас есть множество ролей для наших агентов, каждая из которых обладает собственным набором возможных вариантов поведения. Каждый из этих вариантов поведения генерирует серию задач для агентов, таких как блуждание, исследование карты, отдых, торговля, сбор лута, создание предметов, охота на монстров и так далее. Эти задания могут генерироваться периодически или ситуативно, а также "выталкивать" друг друга из очереди задач героя. Например задача отдыха выталкивает все незаконченные задачи исследования карты и охоты чтобы получить новые заказы следующим утром.
Между тем, каждый агент оснащен "персональным планировщиком", который, по сути, планирует, отменяет или перетасовывает задания, основываясь на данных, которые агент наблюдает.
В настоящее время правила планировщика жестко закодированы, но я подумываю о том, чтобы попробовать другие методы для повышения его эффективности в будущем. Одна из возможностей – это интеграция нейронных сетей используя WGSL рантайм для ONNX (определенно не в альфа-версии). Нейронная сеть, в данном контексте, могла бы определить, должен ли агент выбрать бегство или бой, принимая во внимание такие переменные, как характеристики агента, мощь противника или другие уникальные черты.
Кстати если кому интересно, у проекта появился англоязычный дискорд: