Veliri. Дневник разработки 3
искусственный интеллект
Приветствую DTF. Я все еще продолжаю делать ММО игру.)
Расскажу про ток как устроен ИИ в моей игре. Конечно ИИ не является полноценным ИИ и это просто набор правил для описания поведения нпс в мире.
Так как я делаю игру в жанре privateer то мне важно симулировать “живой мир” где нпс не просто стоят на месте и ждут игроков, а чего-то делают, имеют какую то цель, общаются между собой и всячески могут взаимодействовать друг с другом. Ярким представителем такого мира для меня является мир космический рейнджеров 2и т.к. наши игры немного похожи то я сделал примерно так же.
Базовая реализация
Но прежде чем настраивать социальные связи в нпс над понять как это все работает. В интернет есть несколько статей на тему как делать ИИ в играх, но так как я знатный велосепидатор и не очень умный то сделал свою реализацию которая похожа на ИИ “на основе правил”, но это не точно.
В общем в основе моего алгоритма лежит бинарный граф из проверок и действий. Если нарисовать, то это выглядит так:
Проверки могут быть самые разнообразные начиная анализом боевой ситуации до проверки полный у бота трюм или можно еще копать. Например конфигурацию простейшего разведчика кодом:
а обрабатываются эти правила в контроллере который отрабатывает каждую секунду для каждого бота, контроллер состоит из рекурсивной функции до тех пор, пока не дойдем до действия.
Проверка выглядит так:
А действие это вызов функции api движка, иногда действия могут идти вместе с проверкой на реализацию этого действия (в данном случае если проверка успешна то мы вызываем метод FastMove() для того чтобы бот начал куда-то ехать, дальнейшие действия на себя уже берёт движок, типо расчет пути и физики, что уже не относится к ИИ с:).
Работу этих правил можно наблюдать в сессионной игре:
Для многих игр этого уже достаточно, но не для открытого мира и тут наступает самое интересное)
Экосистема
Для того чтобы имитировать жизнь в игре боты должны иметь какую то экосистему анализируя которую они будут корректировать свое поведение. В моем случае экосистемой выступает сеть баз которые постоянно потребляют ресурсы на постройку бойцов, защитников, турелей и тд, и спорные территории где идет постоянная война фракций. Базы и некоторые боты могут закидывать запросы в общую сеть где на них будут откликаться специальные боты.
Например: базе нужен пластик и база генерирует запрос о доставке ресурса “пластика”, этот запрос вычитывает бот “транспорт”, он смотри на какой базе есть излишки пластика, едет туда, забирает и доставляет на нужную базу.
В данном примере транспорт уже не просто рандомно шатается из точки А в точку Б, а имитирует какую то деятельность.
Для системы запросов в правилах ИИ есть свои методы проверки.
Например транспорт будет сидеть на базе пока не появится запрос который и заполнит ему информацию о том куда, откуда и что доставить (для хранения этой информации у бота есть своя память и на ее основе он будет уже корректировать свои действия).
Из выше описанного можно сделать несколько выводов:
бот имеет цикл жизни независимый от игрока, то есть после респауна он будет жить своей жизнь и выполнять какую то деятельность до тех пор пока не умрет
бот не появляются из неоткуда (за спиной С:), на каждого бота тратятся какой-то определенные ресурсы. (хотя генерация из неоткуда тоже допускается, чтобы не уйти в дедлок по ресурсам или сюжетные нпс или обосновано лором)
боты делятся по ролям, включая роль “универсал”, но если все будут универсалами то кол-во игровых ситуаций будет меньше.
Но этого тоже оказалось мало чтобы имитировать живой мир, он получился довольно стерильным, каждый занят своим делом ииии все…
Отношения
Для того чтобы боты начали имитировать страх хватило всего одной проверки анализа боевой ситуации, но этот анализ специально упрощен до 2х параметров хп и дпс, не учитывается броня, точность, снаряжение и тд. По сути нпс видит столько же сколько и игрок из-за чего боту может сначала казаться что он победит, а в итоге он начнет проигрывать. Каждый нпс имеет разный коэффициент страха. Например транспорт начнет убегать даже если он считает что немного сильнее, а боец будет стоять даже против более сильного противника.
Помимо страха у каждого бота есть “HatePoints” я уже писал когда-то о них ранее их цель заключалась в том чтобы приоритизировать цель по очкам ненависти. То есть по сути очки “агра”. Но теперь я расширил их функционал до полноценного отношения одного бота к другому (или игроку):
Это позволило ботам запоминать обидчиков и мстить им даже в мирных секторах.
Но не хватало ещё одного асоциального элемента который бы наводил суету в мирных секторах и вносил немного хаоса в происходящее вокруг.
Пираты, запросы и динамичное поведение
А для асоциального элемента нужно было сделать запросы с требованиями выкинуть груз или заплатить. Так я сделал “запросы” которые позволяли ботам общаться друг с другом.
Но запросы это не только диалоговые окошки, они влияют на поведение причём очень сильно. Дабы решить эту проблему я обвязал все правила всех ботов, родительским правилом и это позволило динамически изменять поведения бота без тонны конфигов и костылей с сохранением предыдущего состояни.
Выглядит это так:
Если мы имеем специальные правила поведения,то мы идем по ним, а если нет работаем в штатном режиме, все просто :)
И вот какие запросы для нпс я сделал:
Атака:
Запрос на совместное нападение на цель. Меняет поведение бота на поведение "Киллера" Пока цель не будет убита или они договорятся одним из правил "вымогательства"/"защиты" или киллер "испугается"
Вымогательства:
Требование отдать кредиты
Требование выкинуть груз
Защита:
Просьба о заключение перемирия, если инициатор слабее то может перерасти в вымогательство
Сопровождение, некоторые боты могут просить сопроводить их и в случае успеха ответчик поменяет своё поведение на поведение "Телохранителя"
Предложение, мир за деньги.
Предложение мир за груз из трюма
В игре эти сообщения выглядят как то так, снизу на панели уведомлений. Из-за реалтайма я не могу сделать полноценные диалоги т.к. у игрока не будет времени читать тексты, но полностью от них я тоже не смог отказаться =)
А для того чтобы в секторе всегда происходил какой-то экшон я ввёл 2 роли:
Пират: в основном занимается тем, что грабит мирные мехи.
Спецагент: путешествует по всему миру, занимается зачисткой пустоши и терроризирует ботов другой фракции.
Небольшой видос из жизни сектора:
Ну вот как то вот так оно и работает. ¯\_(ツ)_/¯