Перейти к основному содержимому

ИИ сражений

MCE использует для ИИ сражений подключаемый паттерн «стратегия». Каждый ИИ — это ScriptableObject BattleAI, а встроенные рассчитаны на объединение в цепочки: каждая стратегия пытается сделать одно своё дело и передаёт решение своему ИИ Fallback, когда не может.

Конечный автомат сражения

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

Архитектура​

BattleAI (пространство имён OpenMon.MCE.Battle.AI) должен ответить на два вопроса:

  1. RequestPerformAction -- ход бойца. ИИ вызывает обратно с BattleAction — небольшой структурой, описывающей, что делать: боец (BattlerType и Index), Type действия (Move, Switch, Item или Run), нужно ли активировать форму Mega (TriggerMegaForm) и числовые Parameters (какой приём и какая цель, какой предмет, какой монстр).
  2. RequestNewMonster -- какого монстра из команды выпустить после потери сознания.

У него также есть два необязательных хука, OnBattlerFainted и OnBattleEnded (ИИ на ML использует их для наград).

Цепочка — это просто ассеты, указывающие на ассеты:

MegaOrGigaIfCan  ──Fallback──▶  SwitchToEffectiveMonster  ──Fallback──▶  PerformEffectiveMove  ──Fallback──▶  PerformRandomMove  ──Fallback──▶  RandomBattleAI

Каждое звено оценивает ситуацию; если условие выполнено, оно отвечает, иначе спрашивает своё запасное звено. RandomBattleAI — конец любой цепочки: у него нет запасного звена.

Встроенные стратегии ИИ​

Все они создаются через Assets > Create > MCE > Battle > AI > ....

АссетЧто делаетНастройки
RandomBattleAIВыбирает случайное действие из случайного приёма и смены на случайного монстра. Предназначен как последнее запасное звено.--
PerformRandomMoveПрименяет случайный приём или передаёт решение дальше, если приёмов нет.Fallback
PerformEffectiveMoveПрименяет самый мощный эффективный приём, наносящий урон: всё, что выше порога, считается эффективным; среди эффективных предпочитает приёмы по нескольким целям, затем более мощные. Передаёт решение, когда эффективного приёма нет или проверка шанса не удалась.EffectivenessThreshold (по умолчанию 1), Chance (0-1), Fallback
SwitchToEffectiveMonsterМеняет на члена команды, у которого есть эффективный приём, с некоторой долей случайности. Также выбирает, какого монстра выпустить после потери сознания.EffectivenessThreshold, SwitchingChance (0-1), Fallback
UseBattleItemsИспользует боевые предметы при определённых условиях (лечебные предметы ниже порога HP, перечисленные предметы); иначе передаёт решение дальше.UseIfAvailable, UseOnOwnIfAvailable, HPThreshold, HPHealItems, Fallback
MegaOrGigaIfCanЗапрашивает действие у запасного звена, затем помечает его для перехода в форму Mega или giga, если боец может.Fallback
IfWildWithRunChanceRunЕсли монстр дикий и у его вида есть шанс убежать, убегает при успешной проверке; иначе передаёт решение дальше.Fallback
MLBattleAIПозволяет решать обученному «мозгу» ML-Agents (см. ниже).AgentPrefab, Fallback

Выбор ИИ для сражения​

Каждой командой сражения управляет один BattleAI:

  • Для обычных встреч — диких сражений и сражений с тренерами, запускаемых узлами CommandGraph SingleWildFight, DoubleWildFight и SingleTrainerFight, — ассет BattleLauncher использует своё поле Default AI. Укажите в нём начало нужной цепочки.
  • Чтобы дать сражению собственную стратегию, используйте BattleTemplate (Create > MCE > Battle > Template): его массив AIs содержит по одному BattleAI на команду рядом с командами, персонажами, сумками и остальными параметрами сражения. Узел FightFromTemplate запускает его.
  • Из кода BattleLauncher.LaunchBattle(...) принимает массив ИИ напрямую.

Примеры цепочек (ИИ, который вы назначаете в BattleLauncher или шаблон, — первый в списке):

Лёгкий (Маршрут 1)​

PerformRandomMove → RandomBattleAI

Средний (головоломка зала)​

MegaOrGigaIfCan → PerformEffectiveMove → PerformRandomMove → RandomBattleAI

Сложный (Чемпион)​

MegaOrGigaIfCan → UseBattleItems (HP below 25%) → SwitchToEffectiveMonster → PerformEffectiveMove → PerformRandomMove → RandomBattleAI

Написание собственного ИИ (редакции Source и Studio)​

Создайте подкласс BattleAI, реализуйте два абстрактных метода и добавьте классу [CreateAssetMenu]:

using System;
using System.Collections;
using System.Collections.Generic;
using OpenMon.MCE.Battle;
using OpenMon.MCE.Battle.AI;
using OpenMon.MCE.Configuration;
using UnityEngine;

[CreateAssetMenu(menuName = "MyGame/AI/Always Struggle", fileName = "AlwaysStruggle")]
public class AlwaysStruggle : BattleAI
{
[SerializeField] private BattleAI Fallback;

public override IEnumerator RequestPerformAction(MCESettings settings, BattleManager battleManager,
BattlerType type, int inBattleIndex,
Action<BattleAction> callback)
{
// Ask the next link of the chain, then adjust what it answered.
BattleAction action = default;
yield return Fallback.RequestPerformAction(settings, battleManager, type, inBattleIndex,
answer => action = answer);
callback(action);
}

public override int RequestNewMonster(MCESettings settings, BattleManager battleManager,
BattlerType type, int inBattleIndex, List<Battler> forbiddenBattlers) =>
Fallback.RequestNewMonster(settings, battleManager, type, inBattleIndex, forbiddenBattlers);
}

Защищённый вспомогательный метод GenerateActionForMove(...) строит BattleAction (слот приёма и допустимую цель) для выбранного Move, а статический GetEnemies(battleManager, type) возвращает сражающихся бойцов противоположной стороны. О модуле, которому принадлежат ИИ, см. API BattleManager.

Интеграция с ML-Agents​

MCE включает экспериментальный ИИ на основе ML-Agents.

MLBattleAI​

Использует Unity ML-Agents для принятия решений с помощью обученной нейронной сети.

  • Сложность: переменная (зависит от обучения)
  • Применение: тренеры конца игры, соревновательный ИИ, исследования
  • Настройка: требуется пакет com.unity.ml-agents и define скриптинга MCE_ML_AGENTS; код ML находится в собственной сборке (OpenMon.MCE.ML)

Для каждого бойца ИИ создаёт MCEAgent из его Agent Prefab, записывает вектор наблюдений (в коде задокументировано 630 целых чисел: сценарий, статусы обеих сторон, четыре активных бойца и остальная команда, причём каждый боец описывается видом, формой, уровнем, IV/EV, способностью, HP, статусом, приёмами и PP, удерживаемым предметом, ступенями характеристик и изменчивыми статусами) и просит «мозг» о дискретных решениях, которые переводит в BattleAction. Награды выдаются, когда монстр теряет сознание (доля -10, когда падает свой, доля +100, когда падает противник). Выбор монстра для выпуска после потери сознания не обучается: он передаётся в Fallback.

Обучение ИИ​

Обучение выполняется ВНЕ Unity, стандартными средствами ML-Agents. MCE даёт агента, наблюдения и награды; обученную модель вы создаёте сами.

  1. Установите питоновскую часть в виртуальном окружении: pip install mlagents
  2. Напишите конфигурацию для поведения, которое объявляет префаб вашего агента, следуя справочнику по конфигурации ML-Agents
  3. Запустите mlagents-learn <ваша-конфигурация>.yaml --run-id=<имя> и нажмите Play в Unity, когда появится сообщение об ожидании
  4. Следите за процессом через tensorboard --logdir results
  5. Экспортируйте обученную модель (файл .onnx)
  6. Назначьте модель префабу вашего агента

В репозитории самого движка эти шаги обёрнуты скриптами (MLAgentsInstall.ps1, RunMLTraining.ps1, ViewMLResults.ps1 и MLAgentsConfig/), лежащими в его корневой папке. Это инструменты сопровождающего, и они НЕ входят ни в один пакет, то есть их нет в том, что вы получили: следуйте шагам выше.

Зависимость от ML-Agents

ML-Agents — отдельный пакет со своими зависимостями Python. Базовая боевая система MCE работает без него. Устанавливайте ML-Agents, только если планируете использовать ИИ на основе нейронных сетей.

Рекомендации по сложности ИИ​

СложностьЦепочка ИИГде использовать
Очень лёгкаяТолько RandomBattleAIДикие встречи
ЛёгкаяPerformRandomMoveРанние маршруты, юнцы
СредняяPerformEffectiveMove (учёт типов)Тренеры залов, соперники
СложнаяMega + предметы + смена + эффективные приёмыЛидеры залов, Elite Four
НейросетеваяMLBattleAI с обученной модельюСоревнования, режимы испытаний

Рекомендации​

  1. Подбирайте ИИ под сюжетный контекст. Случайный ловец жуков не должен играть как Чемпион.
  2. Тестируйте ИИ против команд игрока схожего уровня. Несбалансированный ИИ кажется несправедливым.
  3. Собирайте цепочки из небольших стратегий. Их проще поддерживать, чем один монолитный ИИ.
  4. Всегда завершайте цепочку RandomBattleAI (или PerformRandomMove, подкреплённым им), чтобы ИИ никогда не остался без ответа.
  5. Не перестарайтесь с оптимизацией ИИ для ранних тренеров. Игрокам нужно освоить систему, прежде чем встречаться с умными противниками.