Saltar al contenido principal

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.

API pública

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:

PropiedadTipoDescripción
DatabaseIMonsterDatabaseAcceso de solo lectura a la base de datos de monstruos/movimientos/objetos
BattleIBattleSystemEstado y eventos de la batalla
PlayerIPlayerDataEquipo, dinero, nombre y medallas del jugador
SaveSystemISaveSystemOperaciones de guardar y cargar
VersionstringCadena 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
El motor todavía no los dispara

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}");
Todavía no está conectado a los guardados del motor

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;
}
}
¿Sin experiencia con Zenject?

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​

AssetPropósito
MCESettingsAjustes 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
BattleConfigurationFileLos ajustes de batalla orientados al jugador: estilo de batalla y aceleración de las animaciones
BattleLauncherLa escena de batalla, la música de batalla salvaje y de entrenador y la IA de batalla por defecto
MonsterEntryDatos de especies de monstruos
MoveDefiniciones de movimientos (una clase concreta por movimiento)
WildEncountersSetTablas de encuentros, enlazadas desde el asset SceneInfo de cada mapa
BattleAIEstrategias 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óndeEventoSe dispara cuando
IBattleLauncherSubscribeToBattleLaunched, SubscribeToBattleToUnload, SubscribeToBattleEnded(Action<BattleResultParameters>)Se lanza una escena de batalla, está a punto de descargarse o termina la batalla
IBattleSystemOnBattleStarted, OnBattleEnded(bool playerWon)Reservados: la fachada del SDK los dispara cuando el motor llama a sus ganchos (todavía no conectados)
RosterOnRosterUpdatedCambian los monstruos de un equipo
QuestManagerOnQuestStarted, OnObjectiveProgressed, OnObjectiveChanged, OnQuestCompleted, OnQuestFailed, OnRewardsGrantedEl 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ónAlternativa
Cambiar la propia fórmula de dañoAgrega factores mediante habilidades, objetos, estados y movimientos (ScriptableObjects); la fórmula es de las ediciones Source y Studio
Agregar nuevos módulos de batallaLos módulos son componentes del motor (ediciones Source y Studio); reacciona mediante los eventos de IBattleSystem
Cambiar la física del movimientoAjusta la velocidad de paso y los tipos de tile en TileData
Cambiar cómo se ordena el bucle de batallaEdiciones Source y Studio
Modificar los diseños de la interfazSobrescribe prefabs (si están expuestos) o superpón tu propia interfaz
¿Necesitas más control?

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​

  1. Depende de interfaces, no de implementaciones. Usa IMonsterCaptureEngine, no clases concretas.
  2. Cancela las suscripciones a eventos. Quita siempre los manejadores en OnDisable o OnDestroy para evitar fugas de memoria.
  3. No guardes en caché datos obsoletos. Consulta el SDK cada vez que necesites datos actuales, sobre todo en IPlayerData.
  4. Usa la inyección de Zenject. Evita FindObjectOfType o los singletons para acceder a MCE.
  5. Consulta la referencia de la API. Las interfaces del SDK tienen documentación XML en cada miembro. Tu IDE mostrará los tooltips.