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 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:
RequestPerformAction: el turno del combatiente. La IA responde con unaBattleAction, una pequeña estructura que describe qué hacer: el combatiente (BattlerTypeeIndex), elTypede acción (Move,Switch,ItemoRun), si se debe activar la forma Mega (TriggerMegaForm) y losParametersnuméricos (qué movimiento y qué objetivo, qué objeto, qué monstruo).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 > ....
| Asset | Qué hace | Ajustes |
|---|---|---|
| RandomBattleAI | Elige una acción aleatoria entre un movimiento aleatorio y cambiar a un monstruo aleatorio. Pensada como el último recurso. | -- |
| PerformRandomMove | Ejecuta un movimiento aleatorio, o recurre al fallback si no hay ninguno disponible. | Fallback |
| PerformEffectiveMove | Ejecuta 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 |
| SwitchToEffectiveMonster | Cambia 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 |
| UseBattleItems | Usa 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 |
| MegaOrGigaIfCan | Pide la acción a su fallback y luego la marca para cambiar a la forma Mega o giga si el combatiente puede. | Fallback |
| IfWildWithRunChanceRun | Si 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 |
| MLBattleAI | Deja 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,DoubleWildFightySingleTrainerFight) el assetBattleLauncherusa 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 unaBattleAIpor equipo, junto a los equipos, personajes, mochilas y el resto de parámetros de la batalla. El nodoFightFromTemplatela 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-agentsy el define de scriptingMCE_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.
- Instala la parte de Python en un entorno virtual:
pip install mlagents - Escribe una configuración para el comportamiento que declara tu prefab de agente, siguiendo la referencia de configuración de ML-Agents
- Ejecuta
mlagents-learn <tu-configuración>.yaml --run-id=<un nombre>y pulsa Play en Unity cuando diga que espera - Supervísalo con
tensorboard --logdir results - Exporta el modelo entrenado (archivo
.onnx) - 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.
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
| Dificultad | Cadena de IA | Dónde usarla |
|---|---|---|
| Muy fácil | Solo RandomBattleAI | Encuentros salvajes |
| Fácil | PerformRandomMove | Rutas iniciales, jóvenes |
| Media | PerformEffectiveMove (consciente de los tipos) | Entrenadores de gimnasio, rivales |
| Difícil | Mega + objetos + cambios + movimientos efectivos | Líderes de gimnasio, Alto Mando |
| Neuronal | MLBattleAI con un modelo entrenado | Competitivo, modos de desafío |
Buenas prácticas
- Ajusta la IA al contexto narrativo. Un cazabichos cualquiera no debería jugar como el Campeón.
- Prueba la IA contra equipos de jugador de nivel similar. Una IA desequilibrada se siente injusta.
- Construye las cadenas con las estrategias pequeñas. Son más fáciles de mantener que una única IA monolítica.
- Termina siempre una cadena con
RandomBattleAI(oPerformRandomMoverespaldada por ella) para que la IA nunca se quede sin respuesta. - No optimices en exceso la IA de los primeros entrenadores. Los jugadores necesitan aprender el sistema antes de enfrentarse a oponentes inteligentes.