API pública
La API pública se incluye en las ediciones Indie, Pro, Source y Studio (Starter la mantiene cerrada); el código fuente C# completo solo está en Source y Studio. Esta guía explica la superficie de API pública estable que puedes usar para interactuar con MCE y extenderlo desde tus propios scripts C# sin acoplar el código de juego a los internos.
La estabilidad es una promesa sobre un NOMBRE. Todo lo demás puede cambiar entre versiones.
El namespace del SDK
MCE expone su API pública mediante el namespace OpenMon.MCE.SDK. Contiene interfaces limpias que dan acceso a los subsistemas del motor sin acoplar tu código a las implementaciones internas.
IMonsterCaptureEngine
El punto de entrada principal. Todas las demás interfaces se alcanzan a través de esta:
using OpenMon.MCE.SDK;
public class MyGameManager : MonoBehaviour
{
[Inject] private IMonsterCaptureEngine engine;
private void Start()
{
Debug.Log($"MCE Version: {engine.Version}");
Debug.Log($"Monsters in DB: {engine.Database.MonsterCount}");
Debug.Log($"Player name: {engine.Player.PlayerName}");
}
}
Propiedades:
| Propiedad | Tipo | Descripción |
|---|---|---|
Database | IMonsterDatabase | Acceso de solo lectura a la base de datos de monstruos/movimientos/objetos |
Battle | IBattleSystem | Estado y eventos de la batalla |
Player | IPlayerData | Equipo, dinero, nombre y medallas del jugador |
SaveSystem | ISaveSystem | Operaciones de guardar y cargar |
Version | string | Cadena de versión del motor MCE |
IMonsterDatabase
Consulta monstruos, movimientos, habilidades, objetos y tipos:
IMonsterDatabase db = engine.Database;
// Get a monster by dex number (National Dex; the parameter is a uint)
MonsterEntry flameleon = db.GetMonster(152u);
// Get a monster by name
MonsterEntry sparkbit = db.GetMonster("Sparkbit");
// Get all monsters
IReadOnlyList<MonsterEntry> allMonsters = db.GetAllMonsters();
// Get a move
Move thunderbolt = db.GetMove("Thunderbolt");
// Get all moves
IReadOnlyList<Move> allMoves = db.GetAllMoves();
// Get type effectiveness. Types are ScriptableObjects fetched from the database
// (there is no MonsterType enum), so look them up by name first:
MonsterType electric = db.GetAllTypes().FirstOrDefault(t => t.name == "Electric");
MonsterType water = db.GetAllTypes().FirstOrDefault(t => t.name == "Water");
float effectiveness = db.GetTypeEffectiveness(electric, water);
// Returns 2.0 (super effective)
// Get all types
IReadOnlyList<MonsterType> types = db.GetAllTypes();
// Get total count
int count = db.MonsterCount;
IBattleSystem
El contrato del SDK para el estado y los eventos de la batalla:
IBattleSystem battle = engine.Battle;
// Is a battle in progress?
if (battle.IsInBattle) { /* ... */ }
// Subscribe to battle events
battle.OnBattleStarted += HandleBattleStarted;
battle.OnBattleEnded += HandleBattleEnded; // bool playerWon
IsInBattle, OnBattleStarted y OnBattleEnded los alimentan ganchos del motor (BattleSystemFacade.NotifyBattleStarted / NotifyBattleEnded) que el motor actual no llama, así que permanecen inactivos. Observa las batallas mediante el lanzador de batalla: consulta el Patrón 1 y las notas de IBattleSystem.
IPlayerData
Accede al estado actual del jugador:
IPlayerData player = engine.Player;
// Player's monster team
Roster roster = player.PlayerRoster;
int teamSize = roster.RosterSize;
MonsterInstance firstMonster = roster[0];
// Player's money, as of the last save (the live balance is in the bag)
int money = player.Money;
// The name of the player's CharacterData asset
string name = player.PlayerName;
// Player's badge count
int badges = player.BadgeCount;
ISaveSystem
El contrato del SDK para guardar y cargar:
ISaveSystem saves = engine.SaveSystem;
saves.Save(1);
saves.Load(1);
bool hasData = saves.HasSaveData(1);
saves.DeleteSave(1);
saves.OnSaved += (slot) => Debug.Log($"Saved to slot {slot}");
saves.OnLoaded += (slot) => Debug.Log($"Loaded from slot {slot}");
En el motor actual engine.SaveSystem no está conectado a SavegameManager: Save y Load solo generan peticiones que nada atiende, y los eventos nunca se disparan. El motor guarda carpetas con nombre (consulta la guía del Sistema de guardado). Para conservar tus propias banderas y contadores con el guardado del jugador, usa variables de juego en GlobalGameData (consulta el Patrón 3).
Inyección de dependencias
MCE usa Zenject (Extenject) para la inyección de dependencias. Para acceder a las interfaces del SDK en tus scripts, usa el atributo [Inject]:
using Zenject;
using OpenMon.MCE.SDK;
public class MyCustomFeature : MonoBehaviour
{
// IMonsterCaptureEngine is the only SDK interface bound in DI
// (see SDKInstaller). Reach the subsystems through its properties.
[Inject] private IMonsterCaptureEngine engine;
private IMonsterDatabase database;
private IBattleSystem battle;
private void Awake()
{
// engine is injected before Awake/Start runs
database = engine.Database;
battle = engine.Battle;
}
}
Si eres nuevo en la inyección de dependencias, esta es la versión sencilla: agrega [Inject] sobre un campo privado IMonsterCaptureEngine y Zenject lo rellenará automáticamente. No necesitas llamar a GetComponent ni a FindObjectOfType. El campo se rellenará antes de que se ejecute Start(), y las demás interfaces del SDK cuelgan de él (engine.Database, engine.Battle, engine.Player, engine.SaveSystem).
Si tu script no es un MonoBehaviour gestionado por Zenject, puedes resolver manualmente:
var engine = ProjectContext.Instance.Container.Resolve<IMonsterCaptureEngine>();
Opciones configurables desde el Inspector
Muchos sistemas de MCE exponen su configuración mediante el Inspector de Unity sin necesidad de código:
Configuración con ScriptableObjects
| Asset | Propósito |
|---|---|
MCESettings | Ajustes de todo el juego: la probabilidad de encuentro por tipo (TileEncounterChance), la probabilidad de shiny salvaje, la regla de experiencia, la duración de un día de juego, los globos de emoción |
BattleConfigurationFile | Los ajustes de batalla orientados al jugador: estilo de batalla y aceleración de las animaciones |
BattleLauncher | La escena de batalla, la música de batalla salvaje y de entrenador y la IA de batalla por defecto |
MonsterEntry | Datos de especies de monstruos |
Move | Definiciones de movimientos (una clase concreta por movimiento) |
WildEncountersSet | Tablas de encuentros, enlazadas desde el asset SceneInfo de cada mapa |
BattleAI | Estrategias de IA, encadenadas mediante su Fallback |
Configuración de componentes
La mayoría de los componentes de MCE exponen sus ajustes clave en el Inspector:
- MCECharacterController / PlayerCharacter: la velocidad de un paso en segundos por tile, el personaje o monstruo que se muestra.
- EncounterTile: el tipo de encuentro del tile.
- SceneInfo (y su
SceneInfoAsset): nombre del mapa, música, región, clima, encuentros. - Actor y sus subclases: las ranuras de CommandGraph (al activarse, bucle, interactuar, a demanda).
Eventos y callbacks
MCE no usa campos UnityEvent en sus componentes; lanza eventos y callbacks normales de C# a los que te suscribes desde tus scripts. Los más útiles:
| Dónde | Evento | Se dispara cuando |
|---|---|---|
IBattleLauncher | SubscribeToBattleLaunched, SubscribeToBattleToUnload, SubscribeToBattleEnded(Action<BattleResultParameters>) | Se lanza una escena de batalla, está a punto de descargarse o termina la batalla |
IBattleSystem | OnBattleStarted, OnBattleEnded(bool playerWon) | Reservados: la fachada del SDK los dispara cuando el motor llama a sus ganchos (todavía no conectados) |
Roster | OnRosterUpdated | Cambian los monstruos de un equipo |
QuestManager | OnQuestStarted, OnObjectiveProgressed, OnObjectiveChanged, OnQuestCompleted, OnQuestFailed, OnRewardsGranted | El evento de misión correspondiente |
PlayerEmotes (estático) | Played(string balloonName) | El jugador local muestra un globo de emoción |
Para ejecutar tu propio C# desde un grafo, escribe un nodo personalizado (siguiente sección).
Extender MCE sin código fuente
Patrón 1: oyente de eventos
Crea un MonoBehaviour que escuche eventos de MCE y dispare tu propia lógica. El lanzador de batalla está enlazado en DI y avisa cuando termina una batalla:
using OpenMon.MCE.Battle;
public class AchievementTracker : MonoBehaviour
{
[Inject] private IBattleLauncher battleLauncher;
private int battlesWon;
private void OnEnable() => battleLauncher.SubscribeToBattleEnded(OnBattleEnded);
private void OnDisable() => battleLauncher.UnsubscribeFromBattleEnded(OnBattleEnded);
private void OnBattleEnded(BattleResultParameters result)
{
if (!result.PlayerWon) return;
battlesWon++;
if (battlesWon >= 100)
UnlockAchievement("Battle Master");
}
}
Patrón 2: consulta a la base de datos
Usa la API de la base de datos para construir funciones personalizadas:
public class TypeMatchupHelper : MonoBehaviour
{
[Inject] private IMonsterCaptureEngine engine;
private IMonsterDatabase database;
private void Awake()
{
database = engine.Database;
}
public List<MonsterType> GetWeaknesses(MonsterType type)
{
var weaknesses = new List<MonsterType>();
foreach (var attackType in database.GetAllTypes())
{
if (database.GetTypeEffectiveness(attackType, type) > 1f)
weaknesses.Add(attackType);
}
return weaknesses;
}
}
Patrón 3: integración con el guardado
Conserva tus propias banderas y contadores en el guardado del jugador almacenándolos como variables de juego en GlobalGameData, el mismo almacén que usa CommandGraph. Se guardan, cargan y reinician con todo lo demás:
using OpenMon.MCE.Player;
// The marker interface IPlayerDataReceiver is what makes the player's data
// (GlobalGameData, Roster, CharacterData...) injectable into a class.
public class AchievementCounters : MonoBehaviour, IPlayerDataReceiver
{
[Inject] private GlobalGameData globalGameData;
public void CountBattleWon()
{
int won = globalGameData.GetVariable<int>("battlesWon");
globalGameData.SetVariable("battlesWon", won + 1);
}
}
La variable debe existir en el titular (defínela en las variables de juego del asset GlobalGameData). Consulta la guía del Sistema de guardado.
Patrón 4: un nodo de CommandGraph personalizado
Para disparar tu propio C# desde el scripting visual, escribe un nodo. Un nodo es una pequeña clase [Serializable] en tu propio ensamblado que deriva de SingleExecutionPathCommandNode; el editor lo lista en el menú Create Command del grafo bajo el último segmento de su namespace:
using System;
using System.Collections;
using OpenMon.MCE.Actors.CommandGraph;
namespace MyGame.Events
{
[Serializable]
public class AwardAchievement : SingleExecutionPathCommandNode
{
[UnityEngine.SerializeField] private string AchievementId;
protected override IEnumerator Run(CommandParameterData parameterData,
Action<CommandParameterData> callback)
{
MyAchievements.Unlock(AchievementId);
yield break;
}
}
}
El nodo aparece entonces como Create Command / Events / AwardAchievement. Consulta la API de CommandGraph para ver el contexto (CommandParameterData) que puede leer un nodo.
Lo que no puedes hacer sin código fuente
| Limitación | Alternativa |
|---|---|
| Cambiar la propia fórmula de daño | Agrega factores mediante habilidades, objetos, estados y movimientos (ScriptableObjects); la fórmula es de las ediciones Source y Studio |
| Agregar nuevos módulos de batalla | Los módulos son componentes del motor (ediciones Source y Studio); reacciona mediante los eventos de IBattleSystem |
| Cambiar la física del movimiento | Ajusta la velocidad de paso y los tipos de tile en TileData |
| Cambiar cómo se ordena el bucle de batalla | Ediciones Source y Studio |
| Modificar los diseños de la interfaz | Sobrescribe prefabs (si están expuestos) o superpón tu propia interfaz |
Si la API pública te resulta demasiado limitada para tu proyecto, considera pasar a la edición Source. Incluye todo el código fuente C# y la documentación de la arquitectura para una personalización profunda.
Referencias de ensamblados
Para referenciar tipos de MCE en tus scripts, tu definición de ensamblado (.asmdef) debe referenciar:
{
"references": [
"OpenMon.MCE.Runtime"
]
}
Si no usas definiciones de ensamblado, los tipos de MCE están disponibles globalmente mediante la DLL.
Buenas prácticas
- Depende de interfaces, no de implementaciones. Usa
IMonsterCaptureEngine, no clases concretas. - Cancela las suscripciones a eventos. Quita siempre los manejadores en
OnDisableoOnDestroypara evitar fugas de memoria. - No guardes en caché datos obsoletos. Consulta el SDK cada vez que necesites datos actuales, sobre todo en
IPlayerData. - Usa la inyección de Zenject. Evita
FindObjectOfTypeo los singletons para acceder a MCE. - Consulta la referencia de la API. Las interfaces del SDK tienen documentación XML en cada miembro. Tu IDE mostrará los tooltips.