Skip to main content

Evolution System

MCE supports 37 evolution types through a polymorphic command pattern. Each evolution type is a concrete class that inherits from EvolutionData and defines its own trigger conditions. This guide covers all built-in evolution types and how to configure them.

evolution chain

Every form carries a LIST of evolutions, and each one is asked whether its condition holds. The first that says yes wins, which is how a single species can branch.

How Evolution Works​

Evolution is managed by the EvolutionManager, which checks for evolution conditions at key moments:

  • After leveling up (in battle or via rare candy).
  • After using an item on a monster.
  • After a trade completes.
  • At specific game events (friendship threshold reached, location entered, etc.).

When conditions are met, the EvolutionAnimation plays and the MonsterInstance transforms into the target species, keeping its nickname, IVs, EVs, friendship, and other personal data.

Configuring Evolution​

On a MonsterEntry ScriptableObject, each per-form entry (DataByFormEntry) holds an Evolutions list of EvolutionData entries (serialized polymorphically via [SerializeReference]). Each entry specifies:

  1. The evolution type (which concrete class to use).
  2. The target species (TargetSpecies, a MonsterEntry reference).
  3. The target form (TargetForm, for form-specific evolutions).
  4. Type-specific parameters (level threshold, item to use, etc.).

Built-In Evolution Types​

Level-Based​

TypeDescriptionParameters
EvolveByLevelEvolves at a specific levelTargetLevel
EvolveByLevelAtSpecificTimeEvolves at a level during a time of dayTargetLevel, EvolvingTimes
EvolveByLevelWhenAttackIsHigherThanDefenseEvolves at a level when Attack > DefenseTargetLevel
EvolveByLevelWhenDefenseIsHigherThanAttackEvolves at a level when Defense > AttackTargetLevel
EvolveByLevelWhenAttackEqualsDefenseEvolves at a level when Attack = DefenseTargetLevel
EvolveByLevelWhenSpecificGenderEvolves at a level if specific genderTargetLevel, Gender
EvolveByLevelWithSceneTagEvolves at a level in a specific locationTargetLevel, CompatibleTags
EvolveByLevelWithSceneTagAtSpecificTimeLevel + location + timeTargetLevel, CompatibleTags, EvolvingTimes
EvolveToRandomSpeciesByLevelEvolves into the target or a second species (random) at a levelTargetLevel, OtherSpecies

Friendship-Based​

TypeDescriptionParameters
EvolveByFriendshipEvolves when friendship reaches thresholdTargetFriendship
EvolveByFriendshipAtSpecificTimeFriendship + time of dayTargetFriendship, EvolvingTimes
EvolveByFriendshipWithMoveOfTypeFriendship + knows a move of a specific typeTargetFriendship, Type

Item-Based​

TypeDescriptionParameters
EvolveOnItemUseEvolves when a specific item is used on itItemToUse
EvolveOnItemUseAtSpecificTimeItem + time of dayItemToUse, EvolvingTimes
EvolveOnItemUseOnSpecificGenderItem + specific genderItemToUse, Gender
EvolveOnItemUseWithSceneTagItem + specific locationItemToUse, CompatibleTags
EvolveOnLevelUpHoldingItemAny level up while holding an itemItemToHold
EvolveOnLevelUpHoldingItemAtSpecificTimeLevel up + held item + timeItemToHold, EvolvingTimes

Trade-Based​

TypeDescriptionParameters
EvolveWhenTradedEvolves upon being traded(none)
EvolveWhenTradedHoldingItemEvolves when traded while holding an itemItemToHold
EvolveWhenTradedWithMonsterEvolves when traded for a specific speciesOtherMonster

Move-Based​

TypeDescriptionParameters
EvolveOnLevelUpWhenAMoveHasBeenLearntLevel up if knows a specific moveMove
EvolveOnLevelUpWhenAMoveHasBeenLearntWithSceneTagMove + locationMove, CompatibleTags
EvolveToRandomFormOnLevelUpWhenAMoveHasBeenLearntMove known, personality-based form resultMove, OtherForm, PersonalityThreshold
EvolveByUsingMoveXTimesEvolves after using a specific move X timesMove, TargetCounter

Condition-Based​

TypeDescriptionParameters
EvolveOnLevelUpWithOtherMonInPartyLevel up with a specific species in the partyOtherSpecies, OtherForm
EvolveOnLevelUpWhenConditionHasLevelLevel up when monster conditions reach set levelsConditions
EvolveByEvolutionCounterEvolves when its evolution counter reaches a targetTargetCounter

Battle Condition-Based​

TypeDescriptionParameters
EvolveByCriticalHitCounterEvolves after landing X critical hits in a single battleTargetCounter
EvolveByDefeatingRivalsEvolves after defeating enough rivals (counter-based)TargetCounter, Item
EvolveByRecoilDamageBasedOnGenderEvolves after taking recoil damage, gender-specific targetTargetDamage (+ per-gender species/form)

Special​

TypeDescriptionParameters
SplitEvolutionByLevelSplit evolution: the evolving monster also spawns a second monster into an empty party slot (requires a compatible ball)TargetLevel, OtherSpecies, OtherForm, CompatibleBalls

Setting Up an Evolution Chain​

Here is a complete example of a three-stage evolution chain:

Stage 1: Flameleon (Dex #152)​

On the Flameleon MonsterEntry, add one evolution:

  • Type: EvolveByLevel
  • Target Species: Blazeking
  • Target Level: 16

Stage 2: Blazeking (Dex #153)​

On the Blazeking MonsterEntry, add two evolutions (branching):

  • Evolution 1:
    • Type: EvolveByLevel
    • Target Species: Infernarch
    • Target Level: 36
  • Evolution 2:
    • Type: EvolveOnItemUse
    • Target Species: Infernarch (Mega Form)
    • Item To Use: Fire Stone

Stage 3: Infernarch (Dex #154)​

No evolutions (final stage). Leave the Evolutions array empty.

Form Changes vs Evolution​

Not all transformations are evolutions. MCE distinguishes between:

MechanismPermanent?Creates New Instance?Example
EvolutionYesNo (same instance, new species)Flameleon evolving into Blazeking
Form ChangeDependsNo (same instance, same species)Seasonal form, battle-only form
Item-Based FormReversibleNoChangeFormOnItemUse, ChangeBetweenMultipleFormsOnItemUse

Form changes use ChangeFormOnItemUse or ChangeBetweenMultipleFormsOnItemUse instead of evolution data. These toggle the active DataByFormEntry index without changing the species.

Creating Custom Evolution Types (Source and Studio Editions)​

If you have the Source or Studio edition, you can create new evolution types:

  1. Create a new class that inherits from TargetSpeciesAndFormEvolutionData:
[Serializable]
public class EvolveWhenLowHP : TargetSpeciesAndFormEvolutionData
{
[Range(0f, 1f)]
public float HPThreshold = 0.5f;

public override bool CanEvolveAfterLevelUp(MonsterInstance monster,
DayMoment currentTime,
PlayerCharacter playerCharacter,
out bool consumeHeldItem)
{
consumeHeldItem = false;
uint maxHP = MonsterMathHelper.CalculateStat(monster, Stat.Hp, null);
float hpRatio = (float)monster.CurrentHP / maxHP;
return monster.AllowEvolution(this) && hpRatio <= HPThreshold;
}

public override bool CanEvolveAfterBattleThroughExtraData(MonsterInstance m,
DayMoment t, out bool c) { c = false; return false; }
public override bool CanEvolveWhenUsingItem(MonsterInstance m, DayMoment t,
Item i, PlayerCharacter p, out bool c) { c = false; return false; }
public override bool CanEvolveWhenTrading(MonsterInstance m, DayMoment t,
MonsterInstance o, PlayerCharacter p, out bool c) { c = false; return false; }
}
  1. Because the Evolutions list is [SerializeReference], your subclass appears automatically in the Inspector's polymorphic type picker — no registration step is needed.
  2. Add it to the species' per-form Evolutions list and configure the parameters.
Serialization

Custom evolution types must be [Serializable] and use [SerializeField] for their parameters. MCE uses Unity's polymorphic serialization ([SerializeReference]) for the evolution array, so your custom types will serialize and deserialize correctly.

Triggering Evolution Manually​

In some cases, you may want to trigger an evolution check programmatically (e.g., from a CommandGraph node or a custom script):

// Source and Studio editions only — manually trigger level-up evolution check.
// EvolutionManager is a ScriptableObject bound through Zenject
// (MCE > Dependency Injection > Evolution Manager installer) — inject it.
[Inject] private EvolutionManager evolutionManager;

monster.ExtraData.NeedsLevelUpEvolutionCheck = true;
StartCoroutine(evolutionManager.TriggerEvolutionsAfterLevelUp(
new[] { monster }, playerCharacter, false));

The EvolutionManager will check all applicable evolution data entries on the monster's species and trigger the first one whose conditions are met.

Best Practices​

  1. Test evolution chains end-to-end. Walk through every possible evolution path.
  2. Avoid circular evolution chains. A evolving into B evolving into A creates infinite loops.
  3. Set appropriate level thresholds. Early monsters should evolve around level 16-20, later ones around 30-40.
  4. Use branching evolutions sparingly. They add gameplay depth but can confuse players if there are too many branches.
  5. Validate the database. Open the OpenMon Hub → Database tab → Validate Database to ensure all evolution target species exist in the database.