Saltar al contenido principal

Vision general de la arquitectura

Esta guia es para usuarios del nivel Source que tienen acceso al codigo fuente completo de MCE en C#.

Este documento cubre la jerarquia de modulos, estructura de assemblies, patrones de inyeccion de dependencias y los sistemas clave en tiempo de ejecucion que componen el Monster Capture Engine.

Jerarquia de modulos

MCE esta organizado en modulos que siguen una arquitectura en capas:

Assets/
OpenMon/
Core/
Runtime/ # Motor principal (REQUERIDO)
Initialization/ # Inicio del motor, asistente de primer uso
Monster/ # MonsterInstance, Roster, evolucion, cria
MonsterDatabase/ # Definiciones ScriptableObject (especies, movimientos, objetos, habilidades)
Battle/ # BattleManager, 15+ modulos, maquina de estados, IA
Characters/ # MCECharacterController, PlayerCharacter, seguidores
Actors/ # Sistema de actores, scripting visual CommandGraph
World/ # GridController, GlobalGridManager, tiles, encuentros
Saves/ # SavegameManager, SavableObject, GameVariables
Player/ # GlobalGameData, estado del jugador
UI/ # Todos los controladores y vistas de UI
Quests/ # Sistema de misiones (objetivos, recompensas, seguimiento)
SDK/ # Interfaces de API publica
GameFlow/ # Gestion de estado del juego
Configuration/ # Configs ScriptableObject
Rendering/ # Shaders URP, hora del dia, clima
Audio/ # AudioManager, BGM/SE/ME
Localization/ # Soporte multiidioma
Badges/ # Seguimiento de medallas
Input/ # Abstraccion de entrada
MonsterDex/ # Seguimiento del dex (visto/capturado)
Animation/ # Utilidades de animacion
Shaders/ # Archivos fuente de shaders
Editor/ # Herramientas exclusivas del editor
ArtGenerator/ # Generacion de sprites con IA
MonsterCreator/ # Asistente de creacion de monstruos
Tools/ # Explorador de BD, Editor de Tabla de Tipos, validadores
Followers/ # Herramientas de hojas de sprites de seguidor
Actors/ # Editor de CommandGraph
Callbacks/ # Utilidades de callbacks del editor

Reglas de dependencia

  1. El Runtime principal tiene cero dependencias externas de los modulos Online o Importer.
  2. Las funciones online son opcionales mediante el simbolo de scripting define MCE_ONLINE.
  3. El codigo de Editor esta estrictamente separado del Runtime mediante limites de .asmdef.
  4. Las interfaces del SDK en Runtime/SDK/ son la superficie de API publica para usuarios de nivel DLL.

Estructura de assemblies

MCE usa Assembly Definitions de Unity para imponer limites de compilacion:

AssemblyUbicacionPropositoReferencias
OpenMon.MCE.RuntimeCore/Runtime/Sistemas principales del juegoSolo libs base
OpenMon.MCE.EditorCore/Editor/Herramientas de editorRuntime + UnityEditor
MCE.Online.RuntimeMCE_Online/Runtime/Redes con NakamaRuntime + Nakama SDK
MCE.Online.EditorMCE_Online/Editor/Herramientas de editor onlineOnline Runtime + UnityEditor
MCE.EssentialsImporter.EditorMCE_EssentialsImporter/Editor/Pipeline de importacionRuntime + KaitaiStruct
MCE.Runtime.TestsCore/Tests/Runtime/Tests principalesRuntime + NUnit

Por que importan las Assembly Definitions

  • Aislamiento de compilacion: Los cambios en codigo de Editor no recompilan Runtime.
  • Imposicion de dependencias: El compilador impide que Runtime referencie APIs de Editor.
  • Eliminacion en build: Los assemblies de Editor se excluyen de los builds del jugador.
  • Aislamiento de tests: Los assemblies de test pueden referenciar internos sin exponerlos en produccion.

Inyeccion de dependencias (Zenject)

MCE usa Zenject (Extenject) con el patron de installer para inyeccion de dependencias.

Patron Installer

Cada subsistema tiene su propio installer que registra bindings:

public class BattleLauncherInstaller : MonoInstaller
{
[SerializeField] private BattleLauncher battleLauncherPrefab;

public override void InstallBindings()
{
Container.Bind<IBattleLauncher>()
.To<BattleLauncher>()
.FromComponentInNewPrefab(battleLauncherPrefab)
.AsSingle()
.Lazy();
}
}

Installers principales

InstallerRegistra
GameFlowInstallerServicios principales del flujo de juego
PlayerCharacterInstallerPlayerCharacter, servicios de personaje
BattleLauncherInstallerBattleLauncher, punto de entrada de batalla
GridInstallerGridController, datos de tiles
SceneInfoInstallerSceneInfo, metadatos de escena
WorldDatabaseInstallerWorldDatabase, datos globales de mapas
TileDataInstallerDatos de tipos de tiles
GlobalGridManagerInstallerNavegacion entre mapas
SavegameInstallerSavegameManager, serializacion
EvolutionManagerInstallerEvolutionManager

Convenciones

  • Los bindings son .AsSingle().Lazy() por convencion (instancia unica, creada en el primer uso).
  • [Inject] se usa en metodos Construct(), no en constructores.
  • El patron DialogManager.Factory se usa para instanciacion de UI en tiempo de ejecucion.
  • Los installers con alcance de escena manejan servicios por escena.
  • Los installers con alcance de proyecto (en ProjectContext) manejan servicios globales.

Puntos de inyeccion

public class SomeManager : MonoBehaviour
{
// Field injection (for MonoBehaviours)
[Inject] private IMonsterDatabase database;

// Method injection (preferred for explicit dependencies)
[Inject]
public void Construct(IBattleSystem battle, IPlayerData player)
{
this.battle = battle;
this.player = player;
}
}

Sistemas clave en tiempo de ejecucion

Flujo de MCEInitialization

MCEInitialization es lo primero que se ejecuta cuando el juego inicia:

1. Configuracion de pantalla (resolucion, orientacion)
2. Cargar bases de datos (monstruos, movimientos, objetos, habilidades)
3. Descargar datos de localizacion (si son remotos)
4. Ejecutar asistente de primer uso (si es necesario)
5. Inicializar subsistemas (gestor de guardado, audio, entrada)
6. Senalizar listo
7. Cargar menu principal o continuar juego guardado

Este es un MonoBehaviour en un GameObject persistente que sobrevive las cargas de escena.

Sistema de monstruos

El modelo de datos de monstruos:

MonsterEntry (ScriptableObject - definicion de especie)
|-- Estadisticas base, tipos, habilidades
|-- DataByFormEntry[] (sobreescrituras por forma)
|-- EvolutionData[] (rutas de evolucion)
|-- Listas de movimientos (nivel, MT, huevo, tutor)

MonsterInstance (runtime - monstruo individual)
|-- Referencia de especie (MonsterEntry)
|-- Nivel, XP
|-- IVs[6], EVs[6]
|-- Naturaleza
|-- HP actual, Estado
|-- MoveSlot[4] (con PP)
|-- Amistad, datos de OT
|-- Indice de forma

Roster (equipo de hasta 6 MonsterInstances)
MonsterStorage (cajas de PC)

Sistema de batalla

Consulte Internos de batalla para el analisis profundo.

Sistema de mundo

GlobalGridManager (navegacion entre mapas)
|-- GridController (cuadricula por escena)
|-- Cuadricula TileData (colision, tipo por tile)
|-- Zonas EncounterTile
|-- SceneInfo (metadatos)

MCECharacterController (movimiento)
|-- PlayerCharacter (entrada + encuentros)
|-- ActorCharacter (movimiento IA de NPC)

Sistema de guardado

SavegameManager
|-- MCESavesSerializer (lectura/escritura JSON)
|-- SavableObject[] (objetos guardables registrados)
|-- GameVariables (estado global)

Estilo de codigo

La base de codigo sigue estas convenciones:

  • Indentacion de 4 espacios, llaves en nueva linea.
  • PascalCase para tipos publicos, metodos, propiedades.
  • camelCase para campos privados y variables locales.
  • [SerializeField] private sobre campos publicos.
  • Separar Runtime/ y Editor/ tras limites de .asmdef.
  • Conventional Commits: feat:, fix:, docs:, refactor:.
Campos serializados

Nunca renombre campos serializados sin un plan de migracion. Las escenas y prefabs dependen de los nombres de campos serializados. Use [FormerlySerializedAs("oldName")] para renombrar.

Extender el motor

Anadir un nuevo sistema

  1. Cree sus clases en Runtime/SuSistema/.
  2. Cree un installer para inyeccion de dependencias.
  3. Anade el installer al contexto de escena o proyecto apropiado.
  4. Si necesita datos de guardado, extienda SavableObject.
  5. Si tiene herramientas de editor, cree clases en Editor/SuSistema/.

Modificar un sistema existente

  1. Lea el codigo existente y comprenda las dependencias del modulo.
  2. Verifique si el cambio puede hacerse via configuracion o extension en lugar de modificacion.
  3. Si modifica, siga los patrones existentes en el modulo.
  4. Actualice los tests para cubrir el cambio.
  5. Documente el cambio en los mensajes de commit.

Consideraciones de rendimiento

  • Las busquedas en base de datos son O(1) por numero de dex, O(n) por nombre. Almacene en cache las busquedas por nombre si se llaman frecuentemente.
  • Los modulos de batalla se inicializan una vez por batalla, no por turno. La creacion de modulos no es una ruta critica.
  • Los Tilemaps tienen un techo de rendimiento alrededor de 200x200 tiles. Divida los mapas mas grandes.
  • La serializacion de guardado es sincrona en el hilo principal. Mantenga los tamanos de datos de guardado razonables.
  • La ejecucion de CommandGraph esta basada en coroutines. Los grafos complejos con muchos nodos son buenos para scripting de eventos pero no deberian usarse para logica por frame.