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
- El Runtime principal tiene cero dependencias externas de los modulos Online o Importer.
- Las funciones online son opcionales mediante el simbolo de scripting define
MCE_ONLINE. - El codigo de Editor esta estrictamente separado del Runtime mediante limites de
.asmdef. - 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:
| Assembly | Ubicacion | Proposito | Referencias |
|---|---|---|---|
OpenMon.MCE.Runtime | Core/Runtime/ | Sistemas principales del juego | Solo libs base |
OpenMon.MCE.Editor | Core/Editor/ | Herramientas de editor | Runtime + UnityEditor |
MCE.Online.Runtime | MCE_Online/Runtime/ | Redes con Nakama | Runtime + Nakama SDK |
MCE.Online.Editor | MCE_Online/Editor/ | Herramientas de editor online | Online Runtime + UnityEditor |
MCE.EssentialsImporter.Editor | MCE_EssentialsImporter/Editor/ | Pipeline de importacion | Runtime + KaitaiStruct |
MCE.Runtime.Tests | Core/Tests/Runtime/ | Tests principales | Runtime + 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
| Installer | Registra |
|---|---|
GameFlowInstaller | Servicios principales del flujo de juego |
PlayerCharacterInstaller | PlayerCharacter, servicios de personaje |
BattleLauncherInstaller | BattleLauncher, punto de entrada de batalla |
GridInstaller | GridController, datos de tiles |
SceneInfoInstaller | SceneInfo, metadatos de escena |
WorldDatabaseInstaller | WorldDatabase, datos globales de mapas |
TileDataInstaller | Datos de tipos de tiles |
GlobalGridManagerInstaller | Navegacion entre mapas |
SavegameInstaller | SavegameManager, serializacion |
EvolutionManagerInstaller | EvolutionManager |
Convenciones
- Los bindings son
.AsSingle().Lazy()por convencion (instancia unica, creada en el primer uso). [Inject]se usa en metodosConstruct(), no en constructores.- El patron
DialogManager.Factoryse 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] privatesobre campos publicos.- Separar
Runtime/yEditor/tras limites de.asmdef. - Conventional Commits:
feat:,fix:,docs:,refactor:.
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
- Cree sus clases en
Runtime/SuSistema/. - Cree un installer para inyeccion de dependencias.
- Anade el installer al contexto de escena o proyecto apropiado.
- Si necesita datos de guardado, extienda
SavableObject. - Si tiene herramientas de editor, cree clases en
Editor/SuSistema/.
Modificar un sistema existente
- Lea el codigo existente y comprenda las dependencias del modulo.
- Verifique si el cambio puede hacerse via configuracion o extension en lugar de modificacion.
- Si modifica, siga los patrones existentes en el modulo.
- Actualice los tests para cubrir el cambio.
- 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.