Arquitectura del sistema de batalla
El sistema de batalla de MCE está construido sobre una arquitectura modular de componentes. El BattleManager está en un GameObject junto con 15 módulos especializados, cada uno responsable de un único aspecto del combate. Un BattleStateMachine impulsa el bucle de turnos, y todo el sistema se conecta mediante inyección de dependencias de Zenject.

Todo lo que hay en esa pantalla es un módulo distinto que informa: las dos barras de salud, el
menú de acciones, los sprites y su animación de entrada, y el orden de turnos que decidió quién mueve primero.
El BattleManager no es dueño de nada de eso directamente: pregunta a cada módulo por turno y el bucle
de la batalla decide qué viene después.
Descripción general de la arquitectura
BattleLauncher (ScriptableObject, loads the battle scene)
└─ BattleManager (orchestrator, on the battle scene's GameObject)
├─ BattleStateMachine (turn loop)
├─ BattleManagerBattlersModule (battler lookup, sprites, forms)
├─ BattleManagerHealthModule (HP, fainting)
├─ BattleManagerMovesModule (move execution)
├─ BattleManagerItemsModule (in-battle items)
├─ BattleManagerCaptureModule (catch mechanics)
├─ BattleManagerAIModule (enemy decisions)
├─ BattleManagerAnimationModule (intro and flow animations)
├─ BattleManagerAudioModule (music, SFX)
├─ BattleManagerStatusesModule (burn, poison, sleep, field effects...)
├─ BattleManagerBattlerStatsModule (stat stages)
├─ BattleManagerBattlerSwitchModule (party switching)
├─ BattleManagerRostersModule (party management)
├─ BattleManagerScenariosModule (weather, terrain, scenario setup)
├─ BattleManagerMegaModule (Mega Evolution)
└─ BattleManagerCharactersModule (trainer characters and sprites)
BattleManager
El BattleManager es el coordinador central. No contiene lógica de batalla propia, sino que delega en sus módulos. Sus responsabilidades son:
- Inicializar todos los módulos cuando empieza una batalla.
- Proporcionar un punto de referencia compartido para la comunicación entre módulos (cada módulo llega a sus hermanos a través de él).
- Recibir órdenes de la interfaz (acciones del jugador) y de la IA (acciones del enemigo).
- Señalizar los eventos de inicio y fin de la batalla.
El BattleManager implementa IBattleManager. Expone el BattleType (SingleBattle o DoubleBattle) y el EnemyType (Wild o Trainer) de la batalla en curso. Consulta la API de BattleManager para ver sus miembros.
BattleStateMachine
El BattleStateMachine es un único bucle de corrutina. En cada turno:
Update which battlers have fought
→ Request actions (the player's menu, the AI of every other roster)
→ Determine the order (move priority, then speed)
→ Perform the actions
→ After-turn callbacks (before and after the status countdown)
→ Status countdown (weather, burn, poison...)
→ Check and process fainted battlers (XP, replacements)
→ [next turn]
hasta IsBattleOver. Entonces reproduce la animación final, reparte el dinero del premio (o cobra el dinero de la derrota) y ejecuta los callbacks de fin de batalla. Cuando una batalla es autoritativa en el servidor (MCE Online), el turno lo resuelve el servidor en lugar de hacerlo localmente: el bucle envía las acciones y muestra lo que vuelve.
Análisis a fondo de los módulos de batalla
BattleManagerBattlersModule
Gestiona las instancias de Battler de ambos bandos. Un Battler extiende MonsterInstance con el estado en batalla:
- Niveles de estadísticas (
StatStage,BattleStatStage), nivel de crítico, sustituto, estados volátiles. - La lista de combatientes contra los que luchó, los objetos consumidos, el último movimiento que usó y que recibió.
- Estadísticas efectivas (base + IV + EV + naturaleza + niveles de estadística) mediante
MonsterMathHelper.
BattleManagerHealthModule
Gestiona todos los cambios de HP mediante ChangeLife (daño y curación, con la animación y el sonido del golpe), y la detección y procesamiento de los combatientes debilitados.
BattleManagerMovesModule
Ejecuta los movimientos (PerformMove): comprobaciones de precisión y evasión, los efectos del movimiento y su animación. El daño en sí lo calcula el propio movimiento (DamageMove) usando la fórmula de Movimientos.
BattleManagerItemsModule
Uso de objetos en batalla (objetos curativos, curas de estado, objetos X) consumidos de la mochila del jugador. Los entrenadores tienen su propia Bag.
BattleManagerCaptureModule
Captura de monstruos salvajes (TryCaptureMonster):
- Cálculo de la tasa de captura según la tasa de captura de la especie, el HP actual, el estado alterado y la bola (
BattleUtils.CalculateShakeProbability). - La animación de sacudida de la bola, con varias comprobaciones de sacudida antes de la captura o el escape.
- Agrega el monstruo capturado al equipo o al almacenamiento del jugador.
BattleManagerAIModule
Mantiene una estrategia BattleAI conectable por equipo:
- Recibe el estado actual de la batalla.
- Devuelve una
BattleAction(usar un movimiento, cambiar, usar un objeto, huir). - Consulta IA de batalla para ver las estrategias integradas y cómo encadenarlas o escribirlas.
BattleManagerStatusesModule
Gestiona todo tipo de estados:
- Estados alterados (uno a la vez por combatiente): quemadura, congelación, parálisis, veneno, veneno grave, sueño.
- Estados volátiles (
VolatileStatus, en un combatiente): confusión, retroceso, atrapado y más. - Estados de bando (
SideStatus) y estados globales (GlobalStatus) para efectos que cubren un lado del campo o todo él. El clima y el terreno de la batalla pertenecen al escenario (BattleManagerScenariosModule).
Cada estado aplica sus efectos en el momento correcto del turno mediante TriggerStatusesCountdown y los callbacks a su alrededor (p. ej., el daño por quemadura al final del turno, la parálisis antes de un movimiento).
BattleManagerBattlerStatsModule
Gestiona las modificaciones de niveles de estadística:
- Los niveles de estadística van de -6 a +6.
- Los niveles de Ataque, Defensa, Ataque especial, Defensa especial y Velocidad aplican un multiplicador: +1 = 1,5x, +2 = 2,0x, ... +6 = 4,0x y -1 = 0,67x, -2 = 0,5x, ... -6 = 0,25x. La precisión y la evasión usan su propia tabla.
- Las habilidades pueden reaccionar a los cambios de nivel (el
Battlerofrece los ganchosOnStatChangeyAfterStatChanged).
BattleManagerMegaModule
Soporte para la Megaevolución:
- Comprueba si la especie del combatiente tiene una forma Mega disponible (
CanSwitchToMegaForm). - Permite una Megaevolución por equipo y batalla.
- Reproduce el cambio de forma y aplica los datos de la forma Mega.
BattleManagerCharactersModule
Da a cada bando sus personajes: los sprites de entrenador (BattleTrainerSprite), el dinero del premio y el de la derrota. Consulta Sprites de espalda del entrenador y el lanzamiento para saber cómo se dibuja y se anima la espalda del jugador.
Ejemplo de flujo de batalla
Esto es lo que ocurre cuando el jugador selecciona "Fight" y elige un movimiento:
- Request actions -- El jugador elige un movimiento en el panel de movimientos mientras la IA elige por el otro equipo.
- Orden -- Todas las acciones se ordenan por prioridad del movimiento y después por Velocidad (el más alto va primero, con un desempate aleatorio).
- Ejecución del movimiento (para el combatiente más rápido):
- Comprobar la precisión: ¿acierta el movimiento?
- Calcular el daño (si es dañino):
((2*Level/5+2) * Power * Atk/Def) / 50 + 2 - Aplicar los factores: número de objetivos, clima, terreno, golpe crítico, tirada aleatoria (0,85-1,0), STAB, efectividad de tipo, estado y los añadidos de habilidades, objetos y estados de bando.
- Aplicar los efectos secundarios (cambios de estadísticas, estados alterados).
- Ejecución del movimiento (para el combatiente más lento, si sigue en pie).
- Callbacks de fin de turno y cuenta atrás de estados -- Daño de clima y de estados, efectos de objetos equipados, activación de habilidades.
- Procesamiento de debilitamientos -- Si un combatiente tiene 0 HP, se procesa el debilitamiento (dar XP/EV, comprobar la evolución) y se piden reemplazos.
Batallas salvajes frente a batallas de entrenador
| Aspecto | Batalla salvaje | Batalla de entrenador |
|---|---|---|
EnemyType | Wild | Trainer |
| Se puede capturar | Sí | No |
| Se puede huir | Sí, si ningún enemigo que luche es un alfa (CanPlayerRun) | No |
| Dinero de premio | No | Sí |
| IA | La IA por defecto del lanzador, salvo que la batalla traiga la suya | La misma |
| Revancha | Encuentro aleatorio | Con guion (CommandGraph) |
Torre de Batalla y entrenadores anónimos
La Battle Tower del menú de pausa (TowerController) ejecuta una progresión PvE interminable: valida el equipo del jugador contra un TowerRuleSet, lanza una batalla contra un oponente de IA generado mediante IBattleLauncher y, desde el propio callback de fin de esa batalla, aplica el resultado y vuelve a lanzar el siguiente combate, hasta que hay una derrota. Consulta la guía de Bases secretas y gimnasios de jugador para ver el flujo orientado al jugador y el equilibrio por defecto.
Los oponentes de la torre son anónimos: generados a partir de las referencias del equipo del jugador, no llevan CharacterData ni Bag. El sistema de batalla tolera a esos entrenadores en lugar de lanzar una excepción:
BattleManagerCharactersModuleprotege el conjunto de sprites de entrenador enemigo: unCharacterDatanulo significa que el equipo sigue luchando, solo que sin sprite de entrenador (y sin aportar dinero de premio).BattleManagerItemsModulesustituye unaBagvacía cuando la mochila del enemigo es nula, de modo que la IA recibe una mochila válida pero sin objetos.
Eso es lo que permite que un oponente generado, sin escena y sin identidad, luche exactamente como un entrenador creado a mano.
Configuración de la batalla
Dos capas configuran las batallas:
- El
BattleConfigurationFile(Create > MCE > Battle > Configuration) contiene los ajustes de batalla orientados al jugador: el Battle Style y el Battle Animation Speed Up (de 1 a 8). Se lee medianteBattleManager.Configurationy de él provieneBattleSpeed. - El asset
BattleLaunchercontiene la escena de batalla, la música de batalla salvaje y de entrenador y la Default AI.
Las reglas de dificultad de captura y de experiencia viven en el asset MCESettings y en los datos globales del juego.
Escuchar los eventos de batalla
Sin código fuente
El lanzador de batalla está enlazado en la inyección de dependencias y notifica cuando se lanza una batalla, está a punto de descargarse y termina:
[Inject] private IBattleLauncher battleLauncher;
battleLauncher.SubscribeToBattleLaunched(() => Debug.Log("Battle launched"));
battleLauncher.SubscribeToBattleEnded(result => Debug.Log($"Battle ended, won: {result.PlayerWon}"));
IBattleSystem (engine.Battle, con OnBattleStarted y OnBattleEnded) es el contrato propio del SDK, pero el motor todavía no lo alimenta: consulta IBattleSystem.
Con código fuente (ediciones Source y Studio)
Con acceso al código fuente puedes suscribirte mediante BattleManager.SubscribeToBattleInitialized y SubscribeToBattleFinished, o agregar tu propio módulo junto al BattleManager (consulta Internos de la batalla).