Saltar al contenido principal

IA de batalla

MCE usa un patrón de estrategia conectable para la IA de batalla. Cada IA es un ScriptableObject BattleAI, y las integradas están diseñadas para encadenarse: cada estrategia intenta hacer lo suyo y cede la decisión a su IA de Fallback cuando no puede.

La máquina de estados de la batalla

La IA nunca conduce la batalla: responde una sola pregunta, "qué haría este entrenador ahora", y el bucle de la batalla decide cuándo preguntar. Esa separación es lo que permite que cualquier batalla use una estrategia distinta sin tocar el flujo de turnos.

Arquitectura​

BattleAI (namespace OpenMon.MCE.Battle.AI) tiene dos cosas que responder:

  1. RequestPerformAction: el turno del combatiente. La IA responde con una BattleAction, una pequeña estructura que describe qué hacer: el combatiente (BattlerType e Index), el Type de acción (Move, Switch, Item o Run), si se debe activar la forma Mega (TriggerMegaForm) y los Parameters numéricos (qué movimiento y qué objetivo, qué objeto, qué monstruo).
  2. RequestNewMonster: qué monstruo del equipo enviar tras un debilitamiento.

También tiene dos ganchos opcionales, OnBattlerFainted y OnBattleEnded (la IA de ML los usa para las recompensas).

Una cadena son simplemente assets que apuntan a assets:

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

Cada eslabón examina la situación; si se cumple su condición, responde; si no, consulta a su fallback. RandomBattleAI es el final de toda cadena: no tiene fallback.

Estrategias de IA integradas​

Todas se crean desde Assets > Create > MCE > Battle > AI > ....

AssetQué haceAjustes
RandomBattleAIElige una acción aleatoria entre un movimiento aleatorio y cambiar a un monstruo aleatorio. Pensada como el último recurso.--
PerformRandomMoveEjecuta un movimiento aleatorio, o recurre al fallback si no hay ninguno disponible.Fallback
PerformEffectiveMoveEjecuta el movimiento dañino efectivo más potente que tiene: todo lo que supere el umbral cuenta como efectivo; entre los movimientos efectivos prefiere los de varios objetivos y luego los de más potencia. Recurre al fallback cuando no hay ningún movimiento efectivo o falla la tirada de probabilidad.EffectivenessThreshold (por defecto 1), Chance (0-1), Fallback
SwitchToEffectiveMonsterCambia a un miembro del equipo que tenga un movimiento efectivo, con algo de aleatoriedad. También elige qué monstruo enviar tras un debilitamiento.EffectivenessThreshold, SwitchingChance (0-1), Fallback
UseBattleItemsUsa objetos de batalla bajo ciertas condiciones (objetos curativos por debajo de un umbral de HP, objetos listados); en caso contrario recurre al fallback.UseIfAvailable, UseOnOwnIfAvailable, HPThreshold, HPHealItems, Fallback
MegaOrGigaIfCanPide la acción a su fallback y luego la marca para cambiar a la forma Mega o giga si el combatiente puede.Fallback
IfWildWithRunChanceRunSi el monstruo es salvaje y su especie tiene probabilidad de huir, huye cuando la tirada tiene éxito; en caso contrario pasa la decisión.Fallback
MLBattleAIDeja que decida un cerebro entrenado con ML-Agents (ver abajo).AgentPrefab, Fallback

Elegir la IA de una batalla​

Cada equipo de una batalla está controlado por una BattleAI:

  • Para los encuentros normales (combates salvajes y de entrenador lanzados por los nodos de CommandGraph SingleWildFight, DoubleWildFight y SingleTrainerFight) el asset BattleLauncher usa su campo Default AI. Apúntalo a la cabeza de la cadena que quieras.
  • Para dar a una batalla su propia estrategia, usa un BattleTemplate (Create > MCE > Battle > Template): su array AIs contiene una BattleAI por equipo, junto a los equipos, personajes, mochilas y el resto de parámetros de la batalla. El nodo FightFromTemplate la lanza.
  • Desde código, BattleLauncher.LaunchBattle(...) toma directamente el array de IAs.

Ejemplos de cadenas (la IA que asignas al BattleLauncher o a la plantilla es la primera de la lista):

Fácil (Ruta 1)​

PerformRandomMove → RandomBattleAI

Media (puzle de gimnasio)​

MegaOrGigaIfCan → PerformEffectiveMove → PerformRandomMove → RandomBattleAI

Difícil (Campeón)​

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

Escribir tu propia IA (ediciones Source y Studio)​

Crea una subclase de BattleAI, implementa los dos métodos abstractos y dale a tu clase un [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);
}

El ayudante protegido GenerateActionForMove(...) construye la BattleAction (ranura de movimiento y objetivo válido) para un Move elegido, y el estático GetEnemies(battleManager, type) devuelve los combatientes rivales que están luchando. Consulta la API de BattleManager para ver el módulo que es dueño de las IAs.

Integración con ML-Agents​

MCE incluye una IA experimental basada en ML-Agents.

MLBattleAI​

Usa Unity ML-Agents para tomar decisiones con una red neuronal entrenada.

  • Dificultad: variable (depende del entrenamiento)
  • Caso de uso: entrenadores de final de juego, IA competitiva, investigación
  • Configuración: requiere el paquete com.unity.ml-agents y el define de scripting MCE_ML_AGENTS; el código de ML vive en su propio ensamblado (OpenMon.MCE.ML)

Para cada combatiente, la IA genera un MCEAgent a partir de su Agent Prefab, escribe un vector de observaciones (el código documenta 630 enteros: el escenario, los estados de ambos bandos, los cuatro combatientes activos y el resto del equipo, cada combatiente descrito por especie, forma, nivel, IV/EV, habilidad, HP, estado, movimientos y PP, objeto equipado, niveles de estadística y estados volátiles) y pide al cerebro decisiones discretas que traduce a una BattleAction. Las recompensas se dan cuando un monstruo se debilita (una fracción de -10 cuando se debilita uno propio, una fracción de +100 cuando se debilita un oponente). Elegir qué monstruo enviar tras un debilitamiento no se aprende: va al Fallback.

Entrenar la IA​

El entrenamiento corre FUERA de Unity, con las herramientas estándar de ML-Agents. MCE te da el agente, las observaciones y las recompensas; el modelo entrenado lo producís vos.

  1. Instala la parte de Python en un entorno virtual: pip install mlagents
  2. Escribe una configuración para el comportamiento que declara tu prefab de agente, siguiendo la referencia de configuración de ML-Agents
  3. Ejecuta mlagents-learn <tu-configuración>.yaml --run-id=<un nombre> y pulsa Play en Unity cuando diga que espera
  4. Supervísalo con tensorboard --logdir results
  5. Exporta el modelo entrenado (archivo .onnx)
  6. Asigna el modelo al prefab de tu agente

El repositorio del motor guarda envoltorios para estos pasos (MLAgentsInstall.ps1, RunMLTraining.ps1, ViewMLResults.ps1 y MLAgentsConfig/) en su carpeta raíz. Son herramientas de quien mantiene el motor y NO forman parte de ningún paquete, así que no están en lo que recibiste: los pasos de arriba son los que hay que seguir.

Dependencia de ML-Agents

ML-Agents es un paquete aparte con sus propias dependencias de Python. El sistema de batalla central de MCE funciona sin él. Instala ML-Agents solo si planeas usar una IA basada en redes neuronales.

Pautas de dificultad de la IA​

DificultadCadena de IADónde usarla
Muy fácilSolo RandomBattleAIEncuentros salvajes
FácilPerformRandomMoveRutas iniciales, jóvenes
MediaPerformEffectiveMove (consciente de los tipos)Entrenadores de gimnasio, rivales
DifícilMega + objetos + cambios + movimientos efectivosLíderes de gimnasio, Alto Mando
NeuronalMLBattleAI con un modelo entrenadoCompetitivo, modos de desafío

Buenas prácticas​

  1. Ajusta la IA al contexto narrativo. Un cazabichos cualquiera no debería jugar como el Campeón.
  2. Prueba la IA contra equipos de jugador de nivel similar. Una IA desequilibrada se siente injusta.
  3. Construye las cadenas con las estrategias pequeñas. Son más fáciles de mantener que una única IA monolítica.
  4. Termina siempre una cadena con RandomBattleAI (o PerformRandomMove respaldada por ella) para que la IA nunca se quede sin respuesta.
  5. No optimices en exceso la IA de los primeros entrenadores. Los jugadores necesitan aprender el sistema antes de enfrentarse a oponentes inteligentes.