Evolution System
MCE supports 30+ 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.
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, the Evolutions array holds one or more EvolutionData entries. Each entry specifies:
- The evolution type (which concrete class to use).
- The target species (
MonsterEntryreference). - The target form (optional, for form-specific evolutions).
- Type-specific parameters (level threshold, required item, etc.).
Built-In Evolution Types
Level-Based
| Type | Description | Parameters |
|---|---|---|
EvolveByLevel | Evolves at a specific level | RequiredLevel |
EvolveByLevelAtSpecificTime | Evolves at a level during a time of day | RequiredLevel, TimeOfDay |
EvolveByLevelWhenAttackIsHigherThanDefense | Evolves at a level when Attack > Defense | RequiredLevel |
EvolveByLevelWhenDefenseIsHigherThanAttack | Evolves at a level when Defense > Attack | RequiredLevel |
EvolveByLevelWhenAttackEqualsDefense | Evolves at a level when Attack = Defense | RequiredLevel |
EvolveByLevelWhenSpecificGender | Evolves at a level if specific gender | RequiredLevel, Gender |
EvolveByLevelWithSceneTag | Evolves at a level in a specific location | RequiredLevel, SceneTag |
EvolveByLevelWithSceneTagAtSpecificTime | Level + location + time | RequiredLevel, SceneTag, TimeOfDay |
EvolveToRandomSpeciesByLevel | Evolves into a random species from a list at a level | RequiredLevel, PossibleTargets[] |
Friendship-Based
| Type | Description | Parameters |
|---|---|---|
EvolveByFriendship | Evolves when friendship reaches threshold | RequiredFriendship |
EvolveByFriendshipAtSpecificTime | Friendship + time of day | RequiredFriendship, TimeOfDay |
EvolveByFriendshipWithMoveOfType | Friendship + knows a move of a specific type | RequiredFriendship, MoveType |
Item-Based
| Type | Description | Parameters |
|---|---|---|
EvolveOnItemUse | Evolves when a specific item is used on it | RequiredItem |
EvolveOnItemUseAtSpecificTime | Item + time of day | RequiredItem, TimeOfDay |
EvolveOnItemUseOnSpecificGender | Item + specific gender | RequiredItem, Gender |
EvolveOnItemUseWithSceneTag | Item + specific location | RequiredItem, SceneTag |
EvolveOnLevelUpHoldingItem | Level up while holding an item | RequiredLevel, HeldItem |
EvolveOnLevelUpHoldingItemAtSpecificTime | Level + held item + time | RequiredLevel, HeldItem, TimeOfDay |
Trade-Based
| Type | Description | Parameters |
|---|---|---|
EvolveWhenTraded | Evolves upon being traded | (none) |
EvolveWhenTradedHoldingItem | Evolves when traded while holding an item | HeldItem |
EvolveWhenTradedWithMonster | Evolves when traded for a specific species | RequiredPartner |
Move-Based
| Type | Description | Parameters |
|---|---|---|
EvolveOnLevelUpWhenAMoveHasBeenLearnt | Level up if knows a specific move | RequiredMove |
EvolveOnLevelUpWhenAMoveHasBeenLearntWithSceneTag | Move + location | RequiredMove, SceneTag |
EvolveToRandomFormOnLevelUpWhenAMoveHasBeenLearnt | Level + move, random form result | RequiredMove, PossibleForms[] |
EvolveByUsingMoveXTimes | Evolves after using a specific move X times in battle | RequiredMove, TimesRequired |
Condition-Based
| Type | Description | Parameters |
|---|---|---|
EvolveOnLevelUpWithOtherMonInParty | Level up with a specific species in the party | RequiredPartyMember |
EvolveOnLevelUpWhenConditionHasLevel | Level up when a game condition has reached a level | Condition, ConditionLevel |
EvolveByEvolutionCounter | Evolves after evolving X other monsters | RequiredCount |
Battle Condition-Based
| Type | Description | Parameters |
|---|---|---|
EvolveByCriticalHitCounter | Evolves after landing X critical hits in a single battle | CriticalHitsRequired |
EvolveByDefeatingRivals | Evolves after defeating X rival trainers | RivalsRequired |
EvolveByRecoilDamageBasedOnGender | Evolves after taking recoil damage (gender-specific) | Gender, RecoilThreshold |
Special
| Type | Description | Parameters |
|---|---|---|
NincadaEvolution | Special dual-evolution (creates two monsters from one) | SecondSpecies |
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 - Required Level:
16
Stage 2: Blazeking (Dex #153)
On the Blazeking MonsterEntry, add two evolutions (branching):
- Evolution 1:
- Type:
EvolveByLevel - Target Species:
Infernarch - Required Level:
36
- Type:
- Evolution 2:
- Type:
EvolveOnItemUse - Target Species:
Infernarch (Mega Form) - Required Item:
Fire Stone
- Type:
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:
| Mechanism | Permanent? | Creates New Instance? | Example |
|---|---|---|---|
| Evolution | Yes | No (same instance, new species) | Flameleon evolving into Blazeking |
| Form Change | Depends | No (same instance, same species) | Seasonal form, battle-only form |
| Item-Based Form | Reversible | No | ChangeFormOnItemUse, 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 Tier)
If you have the Source tier, you can create new evolution types:
- Create a new class that inherits from
EvolutionData:
[Serializable]
public class EvolveByStepCount : EvolutionData
{
[SerializeField] private int requiredSteps = 10000;
public override bool CheckEvolution(MonsterInstance monster, EvolutionContext context)
{
return context.TotalStepsWithMonster >= requiredSteps;
}
}
- Register your evolution type with the
EvolutionManagerso it appears in the Inspector dropdown. - Add it to a
MonsterEntry's evolution array and configure the parameters.
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 tier only
EvolutionManager.TriggerEvolutionCheck(monsterInstance, EvolutionTrigger.LevelUp);
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
- Test evolution chains end-to-end. Walk through every possible evolution path.
- Avoid circular evolution chains. A evolving into B evolving into A creates infinite loops.
- Set appropriate level thresholds. Early monsters should evolve around level 16-20, later ones around 30-40.
- Use branching evolutions sparingly. They add gameplay depth but can confuse players if there are too many branches.
- Validate with Asset Validation. Run
MCE > Tools > Asset Validationto ensure all evolution target species exist in the database.