Повышенная точность ии сталкер что это
Предполагается, что читатель этой статьи знаком с языком LUA и основами объектно-ориентированного программирования.
Постановка задачи
Итак, мы хотим, чтобы дружественные NPC наконец начали приносить пользу. Для этого научим их лечить ГГ во время боя. Распишем по пунктам:
1. Нужно добавить дружественным NPC ветку в диалоге с просьбой присматривать за ГГ и лечить его, если в этом возникнет необходимость.
2. Добавить NPC модель поведения, реализующую выполнение этой просьбы.
2.1. NPC должен действовать согласно этой модели только если ГГ находится недалеко от него.
2.2. NPC не должен далеко отходить от ГГ во время боя.
2.3. Если здоровье ГГ упало ниже определённой отметки, NPC должен подойти/подбежать и вылечить ГГ.
Что потребуется для реализации
Нам придётся изменять диалоги для некоторых NPC, для этого нужно будет изменить файлы config\gameplay\character_dialogs.xml (диалоги для всех NPC), config\localization.ltx и config\system.ltx (подробнее см. статью BAC9-FLCL или Fr3nzy). Мы изменим диалоги для всех NPC, но для неподходящих NPC диалог будет отсекаться с помощью предусловия. Потребуется также добавить файлы с текстами диалогов и функции для проверки условий, используемых в диалогах.
Для включения новой модели поведения NPC нужно будет внести изменения в скрипты scripts\modules.script (регистрация моделей поведения) и scripts\xr_motivator.script (для установки высокого приоритета нашей модели). Модификации файла xr_logic.script, в котором происходит установка общих моделей поведения, не потребуется, так как мы будем активировать нашу схему поведения при выборе определённой ветки в диалоге.
Теперь решим, какие условия и операторы нам понадобятся.
1. Состояние главного героя. Если оно ниже определённого порога, то условие станет истинным. Назначим ему идентификатор property_actor_is_wounded и эвалуатор evaluator_actor_is_wounded. Далее я буду указывать идентификатор и эвалуатор в скобках через запятую.
2. Находится ли NPC достаточно близко, чтобы вылечить ГГ (property_ready_to_heal, evaluator_ready_to_heal).
3. Есть ли у NPC аптечки (property_has_medkit, evaluator_has_medkit).
4. Не отошёл ли NPC слишком далеко от ГГ или ГГ от NPC (property_faraway, evaluator_faraway).
5. Находится ли ГГ достаточно близко, чтобы имело смысл помогать ему (property_near_enough, evaluator_near_enough).
1. Лечить ГГ (act_heal, action_heal).
2. Подбежать к ГГ на дистанцию, достаточную для лечения (act_run_to_actor, action_run_to_actor).
3. Крикнуть, что аптечки кончились (act_no_medkit, action_no_medkit).
4. Подобраться поближе к ГГ, чтобы быть под рукой (act_stay_close, action_stay_close).
Реализация
Я буду писать эту статью параллельно с разработкой мода, указывая все найденные ошибки. Надеюсь, это поможет другим моддерам. Чтобы отделить результаты тестирования от описания процесса разработки мода, я буду выделять свои комментарии другим шрифтом.
Диалоги
В этом моде будет всего один диалог, и довольно простой, поэтому начнём с него. Создаём файл config\gameplay\dialogs_need_help.xml. Чтобы не возиться с идентификаторами текстов, попробуем обойтись без них. Начнём с простой тестовой версии:
Добавляем строку с идентификатором этого диалога в config\gameplay\character_dialogs.xml:
Дописываем имя файла диалога в config\system.ltx в секцию dialogs. Осталось создать функцию i_am_friend. Наш скрипт с моделью поведения будет называться scripts\actor_need_help.script, заодно пропишем там и диалоговые функции.
При первом тестировании я заменил game_object.friend на game_object.neutral, чтобы не искать друзей по всей карте.
Тестируем, что у нас получилось.
Диалог работает, но вместо текста – набор значков, оказалось, я написал текст в кодировке CP866 (DOS), нужно поменять её на CP1251. Так, теперь текст в порядке.
Выбранный подход к созданию диалога оказался удачным.
Обратите внимание, вместо идентификатора текста можно вписать сам текст. Это усложнит локализацию, но уменьшит время создания диалогов.
Теперь нам понадобятся функции проверки наличия аптечек у NPC, проверки активации схемы поведения, активации/деактивации схемы поведения. Добавляем их в наш скрипт-файл.
Первый вариант скрипта я не буду приводить, чтобы не увеличивать и так большую статью. Окончательный вариант смотрите в конце статьи. Дальше по тексту идёт простейший работающий вариант.
Теперь у нас должно быть два варианта начальной фразы для активной и неактивной схемы. Придётся экспериментировать.
Вот первый проверенный вариант:
Кроме того, при тестах первых вариантов, выяснилось, что всегда выбирается вариант диалога с просьбой о помощи. То есть схема поведения не активируется.
Как оказалось, в качестве параметров в функции передаются не объекты ГГ и NPC, а объекты говорящего в данный момент персонажа и его собеседника. То есть, если фраза принадлежит NPC, то первый параметр будет объектом для NPC, а не для ГГ. Поэтому я изменил названия параметров и переписал функции.
Итак, все проблемы решены. Файл диалога принял следующий вид (config\gameplay\dialogs_need_help.xml):
Функции, поддерживающие работу диалога, теперь выглядят так (файл scripts\actor_need_help.script):
И в файл config\gameplay\character_dialogs.xml добавлены строки:
В результате получился работающий диалог, но NPC выглядит просто как ходячая аптечка. В окончательном варианте, я добавил некоторые «человеческие» реакции. Да и сама модель поведения пока отсутствует - вместо неё стоят заглушки. Исправим это.
Модель поведения
Начнём создание модели поведения с разработки эвалуаторов. Эвалуатор должен представлять собой объект класса унаследованного от класса property_evaluator.
Возьмём для начала эвалуатор evaluator_faraway, определяющий, что NPC находится слишком далеко от ГГ. Этот эвалуатор требуется для того, чтобы NPC не отходил слишком далеко от ГГ и мог в случае надобности быстро подбежать к нему и оказать помощь.
Объявляем класс эвалуатора:
Определяем функцию инициализации (в LUA это аналог конструктора объекта):
Ключевое слово super служит для вызова конструктора базового класса. Член st будет хранить ссылку на таблицу состояния нашей модели поведения.
Теперь нужно определить функцию evaluate(), ради которой и создавался эвалуатор. По-видимому всё просто, нужно проверить расстояние от NPC до ГГ и вернуть true, если это расстояние больше определённого значения. Но давайте подумаем. Когда эвалуатор возвратит true, заработает оператор, заставляющий NPC подойти поближе к ГГ, то есть расстояние моментально уменьшится и эвалуатор начнёт возвращать false, что приведёт к переходу NPC под управление игрового ИИ. ИИ может опять решить удалиться от ГГ, что приведёт к повторному срабатыванию эвалуатора. В результате возникнет замкнутый цикл, и NPC будет крутиться на одном месте (на самом деле этот цикл рано или поздно разорвётся из-за изменения игровой ситуации, но лучше вообще избежать его).
Можно использовать разные пути для решения этой проблемы. Попробуем сделать так: будем использовать два расстояния, эвалуатор сработает при достижении первого и будет оставаться активным, пока расстояние не станет меньше второго.
Эвалуатор готов, но нужно как-то его протестировать. Поэтому давайте создадим минимальную модель поведения из одного условия и одного оператора. Нам нужен оператор, перемещающий NPC поближе к ГГ. Объявляем класс action_stay_close, унаследованный от action_base, и определяем его конструктор.
Оператор должен содержать функции initialize(), execute() и, возможно, finalize().
Функция initialize() вызывается при начала работы оператора, то есть в момент, когда планировщик ставит этот оператор в первую позицию плана.
Функция execute() периодически вызывается во время выполнения оператора. Частота вызовов, по-видимому, зависит от расстояния от NPC до ГГ.
Функция настройки планировщика.
Добавим функции активации/деактивации схемы поведения.
Изменим диалоговые функции-заглушки.
Добавим в функцию xr_motivator.addCommonPrecondition() следующие строки, чтобы заблокировать стандартные схемы поведения.
Для того чтобы снизить нагрузку на процессор, используем property_evaluator_const, который всегда возвращает одно и тоже значение. В результате тестирования выяснилось, что не все NPC подчиняются нашей схеме поведения. Причины этого пока не ясны, требуется дополнительное тестирование и очень желательна помощь разработчиков (хотя бы для того чтобы узнать как выяснить какой оператор действует в данный момент на NPC).
Создаем мод
В этом разделе мы сделаем мод, позволяющий сказать дружественно настроенному NPC, чтобы он лечил главного героя во время боя.
Подробный разбор файла actor.ltx
max_item_mass = 999 ; Стоит указывать значения меньше параметра max_walk_weight (см.выше).
jump_speed = 60 ; Высота прыжка. Не указывайте астрономические значения. Гл. герой всё равно не улетит в космос ))
crouch_coef = 1 ; Скорость ползагия "очень сидя" (Ctrl + Shift по умолчанию)
climb_coef = 2 ; Вроде присев (Ctrl)
run_coef = 3 ; Обычный бег с параметром консоли "g_always_run" равным 1
sprint_koef = 4 ; спринт
run_back_coef = 3 ; бег назад
walk_back_coef = 2 ; ходьба назад с клавишей Shift
air_control_param = 1 ; контроль полёта. Выгоден при высоких значениях jump_speed, т.к. можно быстро перемещаться по карте
walk_accel = 17 ; неизвестный параметр
pickup_info_radius = 5 ;радиус, в котором над предметами выводятся их названия при нажатии клавиши "F".
Далее параметры 3d и т.п. смотрим поэтому дальше.
camera_height_factor = 0.85 ; определяет высоту взгляда. Увеличиваем и игрок станет зрительно выше
disp_base = 0 ;угол (в градусах) разлета пуль, когда актер стоит на месте
disp_aim = 0
disp_vel_factor = 0 ;на сколько увеличится дисперсия при скорости в 10 м/с (не обязательно при беге)
disp_accel_factor = 0 ;еще на сколько увеличится, если актер бежит (+ скорость)
disp_crouch_factor = 0 ;уменьшение если актер сидит
disp_crouch_no_acc_factor = 0 ;уменьшение если актер сидит + no acceleration
Чтобы уменьшить размер прицела можно сделать так.
Дальше увидим секцию [actor_immunities_gd_***] (вместо *** нужный ранг)
Чтобы увеличить живучесть - меняем значение ниже.
burn_immunity = 0.0
strike_immunity = 0.0
shock_immunity = 0.0
wound_immunity = 0.0
radiation_immunity = 0.0
telepatic_immunity = 0.0
chemical_burn_immunity = 0.0
explosion_immunity = 0.0
fire_wound_immunity = 0.0
Дальше видим [actor_condition]
И настройка в лучшую сторону будет таковой:
satiety_v = 0 ;скорость уменьшения сытости со временем
radiation_v = 1 ;скорость уменьшения радиации
satiety_power_v = 1 ;увеличение силы при уменьшении сытости
satiety_health_v = 1 ;увеличение здоровья при уменьшении сытости
satiety_critical = 0 ;критическое значения сытости (в процентах от 0..1) когда здоровье начинает уменьшаться
radiation_health_v = 0 ;уменьшение здоровья при воздействии радиации
morale_v = 1 ;скорость восстановления морали
psy_health_v = 1 ;скорость восстановления psy-здоровья
alcohol_v = -1
health_hit_part = 0 ;процент хита, уходящий на отнимание здоровья
power_hit_part = 0 ;процент хита, уходящий на отнимание силы
max_power_leak_speed = 0 ;накопление усталости (макс граница, до которой восстанавливается сила) в секунду игрового времени
max_walk_weight = 1000 ; Вес, при котором игрок не может двигаться. Указать можно любое значение.
bleeding_v = 0 ;потеря крови при номинальной ране в секунду
wound_incarnation_v = 1 ;скорость заживления раны
min_wound_size = 0 ;минимальный размер раны, после которого она считается зажившей
min_wound_size,satiety_v,satiety_power,satiety_health,satiety_critical,alcohol_v можно было и не настраивать, если вам нужно бессмертие
Будем настраивать выносливость.
Назодим строку "jump_power"
Меняем так, чтобы игрок никогда не уставал, разве что если нацепит на себя 5 огненных шаров ))
jump_power = 0 ;умешьшение силы с прыжком без учета веса ноши
jump_weight_power = 0 ;умешьшение силы с прыжком с учетом веса ноши, для максимального допустимого веса
overweight_jump_k = 1 ;коэффициент влияние перегрузки прыжок с весом (умножается на jump_weight_power)
stand_power = 0
walk_power = 0 ;умешьшение силы за секнду во время ходьбы без учета веса ноши
walk_weight_power = 0 ;умешьшение силы за секнду во время ходьбы с учетом веса ноши, для максимального допустимого веса
overweight_walk_k = 1 ;коэффициент влияние перегрузки ноши (умножается на walk_weight_power)
accel_k = 1;коэффициент на бег (умножается walk_power, walk_weight_power)
sprint_k = 1 ;коэффициент на "sprint" бег (умножается walk_power, walk_weight_power)
Значения с комментом "коофициент" и значениями более 1 (необязательно) рекомендую менять на 1.
limping_health_begin = 0 ;порог здоровья меньше которого актер начинает хромать
limping_health_end = 0;порог здоровья больше которого актер перестает хромать
limping_power_begin = 0 ;порог силы меньше которого актер начинает хромать
limping_power_end = 0 ;порог силы больше которого актер перестает хромать
cant_walk_power_begin = 0 ;порог силы меньше которого актер не может двигаться
cant_walk_power_end = 0 ;порог силы больше которого актер сможет двигаться
cant_sprint_power_begin = 0 ;порог силы меньше которого актер не может бежать в спринте
cant_sprint_power_end = 0 ;порог силы больше которого актер сможет бежать в спринте
Дальше идут кости, работающие в 3d, и их тоже можно менять, чтобы уменьшить уязвимость, но пока их настройка не столь нужна. Я лишь скажу, что нужно настраивать 1 (первый) параметр. Чем меньше, тем лучше.
Модели (или схемы) поведения в Сталкере
В наборе скриптов Сталкера предусмотрена возможность объединять операторы и условия в модели поведения. Модель поведения – это набор логически связанных операторов и условий, служащих для выполнения определённой задачи. Так скрипт xr_kamp представляет собой модель поведения, состоящую из двух операторов и двух условий.
Первый параметр функции load_scheme задает имя файла скрипта, второй параметр – это название модели поведения, третий параметр – тип модели поведения (возможны следующие значения: stype_stalker – модель поведения NPC, stype_mobile – модель поведения монстра, stype_item – «модель поведения» физического объекта, stype_heli – модель поведения вертолёта, stype_restrictor – «модель поведения» области пространства). Скрипты для моделей поведения разных типов пишутся по-разному. Мы будем рассматривать только модели поведения NPC.
Внимание! Для успешной работы модели поведения её скрипт должен содержать функцию add_to_binder, выполняющую настройку планировщика.
Активация/деактивация модели поведения
Некоторые модели поведения применимы в любых ситуациях (например, реакция на попадание пули в NPC или реакция на появление врага). Такие модели должны активироваться/деактивироваться в функциях enable_generic_schemes()/disable_generic_schemes() скрипта xr_logic. В случае с моделью поведения actor_need_help это будет выглядеть так:
1. Создаём функции set_actor_need_help и disable_scheme в нашем скрипте actor_need_help. Эти функции будут отвечать за активацию и деактивацию нашей модели поведения.
'2. Добавляем следующую строку в скрипт xr_logic.script после строки if stype == modules.stype_stalker then в функции enable_generic_schemes():
3. Добавляем следующую строку в скрипт xr_logic.script после строки if stype == modules.stype_stalker then в функции disable_generic_schemes():
Если же модель поведения предназначена только для использования в определённых ситуациях, то достаточно выполнить шаг 1 и использовать созданные функции по мере надобности. Например, активируя эту схему через диалог с NPC (как мы и сделаем в нашем моде).
Внимание! Я максимально упростил функции активации/деактивации модели поведения. Чтобы полностью разобраться с ними, посмотрите скрипты xr_combat, xr_kamp и другие подобные.
Приоритеты моделей поведения
Некоторые модели поведения настолько важны, что должны срабатывать в любой ситуации (например, реакция на попадание пули). Для этого в скрипте xr_motivator предусмотрена функция addCommonPrecondition(action), в эту функцию можно добавить одно из условий нашей модели поведения, чтобы другие модели поведения не могли сработать при выполнении этого условия (здесь есть свои тонкости, но мы рассмотрим их позже). Предположим, что у нас есть модель поведения actor_need_help, заставляющая NPC подбежать к ГГ и вылечить его. Пусть за проверку здоровья ГГ отвечает условие с идентификатором actor_need_help.property_actor_is_wounded. Значит, если мы хотим, чтобы NPC подбегал к ГГ, не обращая внимание ни на что другое, то нужно добавить следующую строчку в функцию addCommonPrecondition(action):
Эта строчка запретит выполнение всех других действий, если условие с идентификатором actor_need_help.property_actor_is_wounded станет истинным (в нашем случае это будет означать, что ГГ сильно ранен).
Конкретное значение здоровья ГГ, при котором он считается сильно раненным, будет определять эвалуатор этого условия.
История
Подход к решению проблемы игрового ИИ, выбранный создателями S.T.A.L.K.E.R. (далее буду писать просто "Сталкер"), был впервые применён в 1957 году Гербертом Саймоном (Herbert Simon) и Алленом Ньюэллом (Allen Newell) в программе GPS (General Problem Solver или Универсальный Решатель Задач).
Суть этого подхода заключается в том, что сначала задача представляется в виде набора условий, набора операторов, изменяющих эти условия, и описания начального и конечного состояний. Затем осуществляется поиск последовательности операторов, переводящей начальное состояние системы в конечное.
В Сталкере подсистема поиска последовательности операторов называется планировщик.
S.T.A.L.K.E.R.: Зов Припяти "Повышенный ИИ НПС. "
Медик (xr_medic.script)
Теперь NPC могут лечить раненых друзей и нейтралов, если у них есть аптечка, также NPC может себя лечить сам, если ранен больше, чем наполовину (опять же, если есть аптечка). Лечение происходит в спокойной обстановке при отсутствии врага.
Использование аптечек и бинтов
НПС в состоянии скушать аптечку, если у него мало здоровья, или бинт, если кровотечение.
Менеджер оружия
Скрипт, управляет выбором оружия НПС. Теперь НПС способен определить лучшее оружие;
В зависимости от противника, расстояния до него, количества патронов в магазине выбирает более подходящее оружие.
Например, издалека будет стрелять со снайперской винтовки, вблизи переключится на автомат или пистолет, если есть, если кончаются патроны, может достать другую пушку и т.д.
Перезарядка оружия
НПС перезаряжают оружие после боя, если нужно.
Стрельба с подствольных гранатометов
Если НПС стал счастливым обладателем винтовки с подстволом,
будет его использовать, но только если это безопасно для него самого, ну и своих будет стараться не задеть.
Удар в лицо
НПС дубасит прикладом всех врагов, которым не повезет оказаться поблизости.
Перевязка
Если НПС получит в бою ранение, то, оказавшись в укрытии, он достанет бинт и использует его по назначению.
Напяливание аддонов
НПС могут прикреплять к своему оружию аддоны: оптический прицел, глушитель, гранатомет.
По своим не стрелять
Если на линии огня оказался друг, НПС прекращает огонь и меняет позицию.
Анти-весёлая панихида (модифицированный xr_kamp.script)
NPC, находящиеся на отдыхе (у костра, например) могут оттаскивать в сторону трупы людей и животных;
из-за ограничений движка делают это не всегда, к сожалению. Но такие ситуации редки.
ЯндексДирект
Дать объявление
автор не обижайся ибо я незнаю кто ты!
Если не удаётся скачать (появляются непонятные символы), попробуйте нажать на ссылке правой клавишей мыши и выбрать "Сохранить как. " или "Сохранить объект как. "
GSC ответили про ИИ в S.T.A.L.K.E.R. 2
На стриме у канала TheWolfstalker, GSC Game World ответили на вопрос про ИИ в S.T.A.L.K.E.R. 2: Heart of Chernobyl и почему он выглядел максимально болванистым в сравнении с прошлыми играми серии.
S.T.A.L.K.E.R. 2 выйдет 28 апреля 2022 года эксклюзивно на Xbox Series X|S и PC. Для новой консоли Xbox игра станет консольным эксклюзивом и будет доступна по подписке Game Pass в день релиза. На Xbox Series X заявлена поддержка 4К Ultra HD и технология Ray Tracing.
на счет тупых врагов в кинематографе согласен ,главное игра не осталась бы "кинематографичной" - нужен разум ботам,а не способность видеть сквозь стены и ваншотить за километр с пм'а
А чего все так к ИИ привязались? В трейлере нам по факту постановку показали, скорее всего герой там был просто бессмертен. Цепляться к ИИ в трейлере это конечно верх ума. Но постановка конечно не очень удачная.
чувак, я встречал кадров, которые по этому трейлеру сказали, что геймдизайн кал.
Ого, жесткие типы, можешь дать им на анализ трейлеры киберпанка? Интерестно было бы услышать их мнение.
Всегда найдётся человек который пройдёт эту сцену из трейлера ещё быстрее и даже не поцарапавшись
лучше дать таким трейлер какого нить первого MGS, или первого Resident Evil (тот самый 96ого года), чисто из академического интереса что эти диванные умы смогут сказать.
Отмазка уровень бог. Главное, предзаказ оформите, а там уже сами выкрутите как-нибудь. Где-то мы это уже проходили. В прошлом году.
Маркетолог 80 уровня. Ждём презентацию с минимальны уровнем кинематографичности ИИ.
тут не согласен, для трейлеров практически всегда гг в режиме бога, а боты тупы как щепки
Предзаказ в 2021? после Киберпанка? да ты экстремал, я погляжу.
Ну по трейлеру реально судить глупо. До релиза ещё есть время, будет и нормальная демонстрация геймплея где мы и увидим поведение ИИ. А предзаказывают игры всегда дурачки, в независимости от всего. Лично я не любитель играть в лотерею.
сейчас в современных играх нет умного ИИ,со времен FEAR я ни разу не встречал ИИ который реально был умным,везде однообразные тупорылые болванчики,которые стоят на месте и тупо ждут пока их убьет ГГ. и думать что в сталкер2 будут ИИ на уровне FEAR это тупо,И будет обычным как в обычных играх,ничего особенного
да в фир враги тоже не ахти, у них не ИИ а просто сильно заскриптованое поведение, выведи их из корридоров и они сразу обалванятся
Любой не-нейро ИИ - это набор скриптов.
Та эт кто-то где-то высрал однажды что в фир великий ИИ и все начали за этим кем-то повторять. По факту - обычный ИИ. Как сейчас помню. Враги по кд рашат и это мега удобно. Не нужно их искать. Они сами к тебе идут, а ты их отстреливаешь без особых проблем. Действительно - очень удобно.
В ФЕАР ИИ не умный. Там просто было много ухищрений и трюков, чтобы он КАЗАЛСЯ умным. Например, переговоры по рации. Когда ты прячешься в коридорчике и обнаруживаешь себя, они кричат по рации "В КОРИДОРЕ", если ты начинаешь стрелять из-за шкафа, они кричат "ЗА ШКАФОМ" и т.д. То есть, для них было записано много вариантов таких переговоров, из-за чего они казались наблюдательными.
Или бои: большинство уровней это два-три коридора, которые соединены между собой хитрым образом. Когда ты вбегаешь в один из них, часть ботов просто тупо в тебя палит из одного коридора, тогда как остальные идут в незанятые места, создавая иллюзию скоординированных действий по атаке с разных сторон. Но подобным образом враги могут действовать почти в любом шутане.
Я давным-давно читал где-то статью с примерами действий ИИ из первого сталкер и FEAR, и нескольких других игр - ну типа сравнивали. Вывод статьи однако тебе не понравится: - ИИ сталкера действует примерно такими же схемами, как ИИ в FEAR. разница только в том, что бои FEAR происходят в закрытых пространствах и потому косяков действий ИИ геймер не замечает. А в сталкере пространство открытое и потому косяки действий ИИ заметить проще. Но в целом в огромном количестве игр ИИ такой же как в FEAR - ты просто этого не замечаешь.
На самом деле ИИ FEAR состоит из набора рандомных действий, которые рандомно включаются у каждого конкретного бота - ИИ сам не понимает, для чего и что он делает в бою. Плюс немного скриптов для особых ситуаций в бою. Но игроку такие действия визуально кажутся умными. Но это умелая обманка. Просто разработчики гении, а сам ИИ глуп как пробка.
Кстати, в ARMA 3 интеллект ботов очень умный, ибо все ИИ действия осознаны, а не рандомны. В отличие от FEAR. Печально, что никто этого не замечает. И даже не вспоминают ARMA3, когда речь заходит про ИИ.
А по факту ии останется таким же тупым, просто прикрутят вх для ботов и ваншоты с пол карты на макс сложности. Прошлые части играли, знаем.
В прошлых частях ИИ был настолько забагованным, что был способен на такие выкрутасы, какие профессиональным спецназовцам и не снились. Так что я буду только рада, если в новом сталкаче будет такой же.
ИИ в Сталкере
Как видно, этот способ решения проблем не подходит для шутера, так как ситуация в игре может меняться непредсказуемым образом и построенный план решения (последовательность операторов) станет неприменимым к текущей ситуации. Поэтому планировщик запускается каждый раз при непредвиденном развитии событий и создаёт новую последовательность действий (операторов).
Условия в игре тоже вычисляются динамически. Для этого используются специальные объекты – эвалуаторы. Эвалуатор должен содержать метод evaluate(), возвращающий true, если условие выполняется и false в противном случае. Операторы также представлены как объекты. Планировщик вызывает метод initialize() при начале работы оператора, затем он периодически вызывает метод execute().
Например, можно создать эвалуатор для условия NPC голоден, и привязать к этому условию оператор поесть.
Планировщик будет периодически проверять это условие (вызывать метод evaluate() эвалуатора), и если оно выполняется, инициализирует и будет выполнять оператор поесть до тех пор, пока условие не станет ложным.
К сожалению, в большей части скриптов все возможности планировщика не используются.
Разбор настройки и работы планировщика на примере скрипта xr_kamp
Рассмотрим скрипт xr_kamp, заставляющий сталкеров сидеть у костра и рассказывать анекдоты. Настройка планировщика осуществляется в функции add_to_binder. Параметры функции: object – объект, для которого настраивается планировщик (в нашем случае это сталкер), ini, scheme, section – инициализационный файл, название схемы действий, секция ини-файла (эти параметры будут подробно разобраны в части по созданию мода), storage – таблица для хранения текущих параметров схемы действий.
Разберём, что делает эта функция.
Сначала получаем планировщик для текущего объекта (object):
Затем присваиваем идентификаторы операторов и условий элементам массива. Это сделано просто для удобства.
Идентификаторы могут иметь любое целочисленное значение, главное, чтобы они были уникальными, то есть не использовались для других операторов и условий.
Для каждого идентификатора условия создадим соответствующий эвалуатор и добавим его в планировщик. В данном случае это условия: закончить ли посиделки около костра? и пришёл ли я на своё место у костра?.
Теперь создадим оператор сидеть около костра, рассказывать анекдоты, жевать колбасу и т.д.. Можно было бы реализовать эти действия как набор разных операторов, выбором которых занимался бы планировщик, но автор скрипта решил сделать один сложный оператор.
Задаем предусловия для этого оператора. Планировщик выберет этот оператор при выполнении всех условий. Всё это значит примерно следующее: я могу сидеть у костра, если:
аномалий поблизости нет,
выполняются другие важные условия (игрок не собирается со мной поговорить, я не собираюсь никого бить по морде, я не ранен, я не собираюсь стрелять по вертолёту),
я уже нахожусь около костра.
Скажем планировщику, что он должен ожидать от выполнения этого оператора. В данном случае после выполнения этого оператора условие закончить ли посиделки около костра? должно стать истинным. То есть если условие стало истинным, планировщик прекратит выполнение оператора.
Создание оператора завершено. Добавим его в планировщик.
Эта строчка не имеет отношения к работе планировщика. Если коротко, то она позволяет объекту получать уведомления об определённых событиях (смерть NPC – вызывается метод death_callback(), попадание пули в NPC – вызывается метод hit_callback() и т.д.)
Создаем оператор, отвечающий за доставку NPC к его месту у костра.
Добавляем предусловия, как и для предыдущего оператора.
Единственное отличие – последнее условие. Этот оператор будет выполняться только если NPC ещё не находится на своем месте у костра, то есть если функция evaluator_on_position.evaluate() возвращает false.
В результате выполнения этого действия условие на своём ли я месте у костра? должно стать истинным.
Создание оператора завершено. Добавляем его к планировщику.
Осталось ещё одна задача. Нужно запретить планировщику активировать оператор alife, тот самый оператор, который заставляет NPC болтаться по карте, отстреливать собачек и в конце концов попадать в аномалию. Впрочем, отстрелом врагов занимается другой оператор с идентификатором stalker_ids.action_combat_planner.
Для этого мы получаем оператор alife:
И добавляем к его предусловиям следующее: условие закончить ли посиделки у костра? должно быть истинным.
Итак, мы настроили планировщик. Посмотрим как всё это будет работать.
В некоторый момент времени гулаг, в который попал NPC, назначает ему работу: сидеть у костра. В результате условие закончить ли посиделки у костра? становится ложным. Планировщик видит это изменение и пытается выработать последовательность операторов, после выполнения которой, условие бы стало истинным и NPC снова бы вернулся к выполнению высокоприоритетного оператора alife. Для выполнения этой задачи подходит оператор посиделки у костра, но для него не выполняется условие я на своем месте у костра. Поэтому планировщик создаёт план из двух операторов: дойти до костра и посиделки у костра. Если во время выполнения одного из операторов возникнет непредвиденная ситуация (появится враг, главный герой начнёт приставать с вопросами и т.п.), то планировщик скорректирует план, добавив оператор для устранения этой непредвиденной ситуации.
Как видно, система ИИ в Сталкере обладает весьма большой гибкостью, что мы и продемонстрируем при создании мода.
Читайте также: