Trainer management and battle API for Cobblemon.
This API was developed as foundation for the Radical Cobblemon Trainers mod and as replacement for the discontinued dependency CobblemonTrainers for Minecraft >= 1.21 and Cobblemon >= 1.6.
Yet it is designed as independent library to provide a subset of similar features for everyone to use.
RCTBattleAI):Check out the repository for an example.
Optional
Optional
Terms for using, modifying and redistributing this product.
19.04.2026 · Modrinth
As of version 0.15.0-beta, RCTApi may only be redistributed under the terms of the MCOML License.
Fixed:
Screenshots and images from the original Modrinth page.

Published versions and original Modrinth files.
19.04.2026 · 1 045 838 downloads
As of version 0.15.0-beta, RCTApi may only be redistributed under the terms of the MCOML License.
Fixed:
19.04.2026 · 85 125 downloads
As of version 0.15.0-beta, RCTApi may only be redistributed under the terms of the MCOML License.
Fixed:
17.04.2026 · 4 952 downloads
As of version 0.15.0-beta, RCTApi may only be redistributed under the terms of the MCOML License.
Fixed:
17.04.2026 · 1 619 downloads
As of version 0.15.0-beta, RCTApi may only be redistributed under the terms of the MCOML License.
Fixed:
21.03.2026 · 926 396 downloads
As of version 0.15.0-beta, RCTApi may only be redistributed under the terms of the MCOML License.
Added:
BattleInstance: Associates a TrainerNPC with a PokemonBattle and the LivingEntity it was attached to at the start of that battleTrainerNPC#getBattleInstances(): Retrieves a list of all active BattleInstances the trainer is attending toChanged:
battleTheme property to assign a custom resource location (falls back to battle.pvn.default if unset). Refer to the docs for more infoFixed:
BATTLE_STARTED event receiving null instead of the BattleState as parameterRemoved:
TypeChart#getEffectiveness()21.03.2026 · 11 626 downloads
As of version 0.15.0-beta, RCTApi may only be redistributed under the terms of the MCOML License.
Added:
BattleInstance: Associates a TrainerNPC with a PokemonBattle and the LivingEntity it was attached to at the start of that battleTrainerNPC#getBattleInstances(): Retrieves a list of all active BattleInstances the trainer is attending toChanged:
battleTheme property to assign a custom resource location (falls back to battle.pvn.default if unset). Refer to the docs for more infoFixed:
BATTLE_STARTED event receiving null instead of the BattleState as parameterRemoved:
TypeChart#getEffectiveness()14.02.2026 · 955 280 downloads
Fixed:
14.02.2026 · 16 656 downloads
Fixed:
13.02.2026 · 794 downloads
Added:
Debug#setActive(int) static method to configure active debug contexts (not recommended to activate in release builds)PokemonPropertiesModelConverter: Convert PokemonModel to PokemonProperties (thanks Gito)Changed:
Debug utility (now works with contexts instead of levels, combine with | for multiple)Fixed:
Commander ability with DondozoPokemonModel(Pokemon) constructor copying wrong properties13.02.2026 · 159 downloads
Added:
Debug#setActive(int) static method to configure active debug contexts (not recommended to activate in release builds)PokemonPropertiesModelConverter: Convert PokemonModel to PokemonProperties (thanks Gito)Changed:
Debug utility (now works with contexts instead of levels, combine with | for multiple)Fixed:
Commander ability with DondozoPokemonModel(Pokemon) constructor copying wrong properties18.01.2026 · 266 426 downloads
Added:
BattleFormatProvider (functional) interfaceChanged:
BattleState#getFormat() and BattleContext#getFormat() to BattleFormatProviderBattleFormat enum now implements BattleFormatProvider (method signature remains unchanged)BattleRulesadjustNPCLevels property: Decide if npc pokemon levels should be adjusted according to the adjustLevel value of the battle format (the default battle formats do not adjust levels)adjustPlayerLevels property: Decide if player pokemon levels should be adjusted according to the adjustLevel value of the battle format (the default battle formats do not adjust levels)healPlayers property: Decide if player pokemon should be healed at the start of a battleBattleManager#startBattle(...) (and overloads) now accept a BattleFormatProvider instead of a (rctapi) BattleFormat as argument (old overloads still exist but are deprecated)BattleState and BattleContext now accept a BattleFormatProvider in their constructors instead of a (rctapi) BattleFormat (old overloads still exist but are deprecated)Fixed:
stellar leading to battle failures if evaluated defensively on the player side18.01.2026 · 14 752 downloads
Added:
BattleFormatProvider (functional) interfaceChanged:
BattleState#getFormat() and BattleContext#getFormat() to BattleFormatProviderBattleFormat enum now implements BattleFormatProvider (method signature remains unchanged)BattleRulesadjustNPCLevels property: Decide if npc pokemon levels should be adjusted according to the adjustLevel value of the battle format (the default battle formats do not adjust levels)adjustPlayerLevels property: Decide if player pokemon levels should be adjusted according to the adjustLevel value of the battle format (the default battle formats do not adjust levels)healPlayers property: Decide if player pokemon should be healed at the start of a battleBattleManager#startBattle(...) (and overloads) now accept a BattleFormatProvider instead of a (rctapi) BattleFormat as argument (old overloads still exist but are deprecated)BattleState and BattleContext now accept a BattleFormatProvider in their constructors instead of a (rctapi) BattleFormat (old overloads still exist but are deprecated)Fixed:
stellar leading to battle failures if evaluated defensively on the player side27.12.2025 · 320 023 downloads
Added:
BattleState#isPaticipating(Trainer): Reports if trainer is participating in the associated battleChanged:
RCTBattleAIConfig#switchBias to 0.5 (value is now a bit more impactful, other biases will most likely get reworked in a similar manner)Ally Switch or Trick) and other minor adjustments to move selection logicFixed:
First Impression in arbitrary turns (should only be used in first turn)Explosion) when on their last pokemonBlock as trapped, rather than the targetgimmicks property of pokemon (tera, dynamax, gmax) not getting applied in battle27.12.2025 · 36 483 downloads
Added:
BattleState#isPaticipating(Trainer): Reports if trainer is participating in the associated battleChanged:
RCTBattleAIConfig#switchBias to 0.5 (value is now a bit more impactful, other biases will most likely get reworked in a similar manner)Ally Switch or Trick) and other minor adjustments to move selection logicFixed:
First Impression in arbitrary turns (should only be used in first turn)Explosion) when on their last pokemonBlock as trapped, rather than the targetgimmicks property of pokemon (tera, dynamax, gmax) not getting applied in battle11.12.2025 · 899 936 downloads
Fixed:
Removed:
11.12.2025 · 15 195 downloads
Fixed:
Removed:
05.12.2025 · 31 815 downloads
Fixed:
05.12.2025 · 4 353 downloads
Fixed:
04.12.2025 · 2 379 downloads
Fixed:
04.12.2025 · 671 downloads
Fixed:
24.11.2025 · 513 027 downloads
Changed:
Pokemon#clone() invocations with Pokemon#copyFrom() (this might have been the cause for some battle related issues)24.11.2025 · 8 226 downloads
Changed:
Pokemon#clone() invocations with Pokemon#copyFrom() (this might have been the cause for some battle related issues)22.11.2025 · 28 017 downloads
Changed:
1.722.11.2025 · 3 268 downloads
Changed:
1.726.09.2025 · 269 443 downloads
Fixed:
26.09.2025 · 11 919 downloads
Fixed:
09.09.2025 · 25 689 downloads
Changed:
Fixed:
09.09.2025 · 3 878 downloads
Changed:
Fixed:
05.07.2025 · 422 577 downloads
Fixed:
05.07.2025 · 55 339 downloads
Fixed:
17.06.2025 · 349 691 downloads
Changed:
17.06.2025 · 8 541 downloads
Changed:
14.06.2025 · 5 574 downloads
Changed:
Fixed:
14.06.2025 · 688 downloads
Changed:
Fixed:
10.06.2025 · 7 120 downloads
Changed:
Fixed:
10.06.2025 · 1 343 downloads
Changed:
Fixed:
03.06.2025 · 67 498 downloads
Fixed:
03.06.2025 · 1 498 downloads
Fixed:
02.06.2025 · 2 479 downloads
Fixed:
UnsupportedOperationException when attempting to start a battle02.06.2025 · 293 downloads
Fixed:
UnsupportedOperationException when attempting to start a battle02.06.2025 · 180 downloads
Fixed:
NullPointerException because "moveset" is null)02.06.2025 · 66 downloads
Fixed:
NullPointerException because "moveset" is null)02.06.2025 · 2 547 downloads
Changed:
BATTLE_STARTED_PRE event to intercept battles started by this apigimmicks property to PokemonModel: Allows to enable and define a terastalization type (tera), as well as to activate dyna- and gigantamax (dynamax and gmax), latter two require the mega showdown mod to work02.06.2025 · 771 downloads
Changed:
BATTLE_STARTED_PRE event to intercept battles started by this apigimmicks property to PokemonModel: Allows to enable and define a terastalization type (tera), as well as to activate dyna- and gigantamax (dynamax and gmax), latter two require the mega showdown mod to work24.05.2025 · 124 202 downloads
Important: This version may break compatibility with mods that rely on an older version of this api (< 0.12.0-beta). This could be the case if mods happen to parse trainers from JSON (i.e. with GSON) or use #getName() (see #55 - 59). There shouldn't be any issues otherwise.
To update be sure to configure your GsonBuilder instances with RCTApi#configureGsonBuilder(GsonBuilder) or simply use a builder provided by RCTApi#gsonBuilder().
Changed:
RCTBattleAIBattleEffects (former PokeContext) utility class for the battle aiFixed:
RCTBattleAI (e.g. battle error if trainer pokemon dies of entry hazards)Text#getComponent() now returns a component with an empty string (instead of the language key itself), this should fix issues with fallback mechanics if certain texts do not have a translation defined (e.g. trainer names)24.05.2025 · 1 829 downloads
Important: This version may break compatibility with mods that rely on an older version of this api (< 0.12.0-beta). This could be the case if mods happen to parse trainers from JSON (i.e. with GSON) or use #getName() (see #55 - 59). There shouldn't be any issues otherwise.
To update be sure to configure your GsonBuilder instances with RCTApi#configureGsonBuilder(GsonBuilder) or simply use a builder provided by RCTApi#gsonBuilder().
Changed:
RCTBattleAIBattleEffects (former PokeContext) utility class for the battle aiFixed:
RCTBattleAI (e.g. battle error if trainer pokemon dies of entry hazards)Text#getComponent() now returns a component with an empty string (instead of the language key itself), this should fix issues with fallback mechanics if certain texts do not have a translation defined (e.g. trainer names)13.05.2025 · 85 647 downloads
Important: This version may break compatibility with mods that rely on an older version of this api (< 0.12.0-beta). This could be the case if mods happen to parse trainers from JSON (i.e. with GSON) or use #getName() (see #55 - 59). There shouldn't be any issues otherwise.
To update be sure to configure your GsonBuilder instances with RCTApi#configureGsonBuilder(GsonBuilder) or simply use a builder provided by RCTApi#gsonBuilder().
Added:
RCTApi#configureGsonBuilder(GsonBuilder)RCTApi#gsonBuilder()Text utility type for translatable text, which can be parsed from a JSON object with literal and/or translatable fields, or directly from a string, which serves as the literal valuePokemonModel#nickname property (will be ignored if literal is not set)TrainerModel#name propertyChanged:
PokemonModel#getName() from String to Text (potential breaking change)Trainer#getName() from String to Text (potential breaking change)TrainerModel#getName() from String to Text (potential breaking change)TrainerNPC#getName() from String to Text (potential breaking change)TrainerPlayer#getName() from String to Text (potential breaking change)13.05.2025 · 2 670 downloads
Important: This version may break compatibility with mods that rely on an older version of this api (< 0.12.0-beta). This could be the case if mods happen to parse trainers from JSON (i.e. with GSON) or use #getName() (see #55 - 59). There shouldn't be any issues otherwise.
To update be sure to configure your GsonBuilder instances with RCTApi#configureGsonBuilder(GsonBuilder) or simply use a builder provided by RCTApi#gsonBuilder().
Added:
RCTApi#configureGsonBuilder(GsonBuilder)RCTApi#gsonBuilder()Text utility type for translatable text, which can be parsed from a JSON object with literal and/or translatable fields, or directly from a string, which serves as the literal valuePokemonModel#nickname property (will be ignored if literal is not set)TrainerModel#name propertyChanged:
PokemonModel#getName() from String to Text (potential breaking change)Trainer#getName() from String to Text (potential breaking change)TrainerModel#getName() from String to Text (potential breaking change)TrainerNPC#getName() from String to Text (potential breaking change)TrainerPlayer#getName() from String to Text (potential breaking change)05.05.2025 · 24 123 downloads
Changed:
RCTBattleAIRCTBattleAIConfig and BattleRules (thanks Gitoido)Deprecated:
TypeChart#getEffectiveness(ElementalType, ElementalType, ElementalType, Ability)05.05.2025 · 2 000 downloads
Changed:
RCTBattleAIRCTBattleAIConfig and BattleRules (thanks Gitoido)Deprecated:
TypeChart#getEffectiveness(ElementalType, ElementalType, ElementalType, Ability)12.04.2025 · 159 422 downloads
Added:
BattleManager#startBattle() with UUID return type as replacement for BattleManager#start()nickname property for PokemonModelsChanged:
RCTBattleAI move and switch evaluations (e.g. better awareness of shedinjas wonderguard) and other tweaksname of a TrainerNPC is unset or empty it will now fall back to the display name of the entity the trainer is attached toFixed:
RCTBattleAI attempting to choose various illegal actions, causing battles to softlock in certain situations and other issues (e.g. switching out against pokemon with "arena trap" or while "mean look" is active)Deprecated:
BattleManager#start() and helper methodsRemoved:
BattleEndCommandCommandsContextRCTApiCommandsBattleState#BattleState(PokemonBattle, BattleRules)RCTApi#getInstance()RCTApi#init(TrainerRegistry, BattleManager)RCTApi#initInstance(String, TrainerRegistry)RCTApi#initInstance(String, TrainerRegistry, BattleManager)12.04.2025 · 4 080 downloads
Added:
BattleManager#startBattle() with UUID return type as replacement for BattleManager#start()nickname property for PokemonModelsChanged:
RCTBattleAI move and switch evaluations (e.g. better awareness of shedinjas wonderguard) and other tweaksname of a TrainerNPC is unset or empty it will now fall back to the display name of the entity the trainer is attached toFixed:
RCTBattleAI attempting to choose various illegal actions, causing battles to softlock in certain situations and other issues (e.g. switching out against pokemon with "arena trap" or while "mean look" is active)Deprecated:
BattleManager#start() and helper methodsRemoved:
BattleEndCommandCommandsContextRCTApiCommandsBattleState#BattleState(PokemonBattle, BattleRules)RCTApi#getInstance()RCTApi#init(TrainerRegistry, BattleManager)RCTApi#initInstance(String, TrainerRegistry)RCTApi#initInstance(String, TrainerRegistry, BattleManager)29.03.2025 · 54 844 downloads
Changed:
JTO classes29.03.2025 · 4 149 downloads
Changed:
JTO classes20.03.2025 · 48 703 downloads
Fixed:
20.03.2025 · 1 839 downloads
Fixed:
15.03.2025 · 48 229 downloads
Fixed:
15.03.2025 · 1 239 downloads
Fixed:
05.02.2025 · 201 241 downloads
Fixed:
PokemonModel when using Cobblemon Pokemon class constructor (thanks Gitoido)05.02.2025 · 5 126 downloads
Fixed:
PokemonModel when using Cobblemon Pokemon class constructor (thanks Gitoido)28.01.2025 · 26 514 downloads
Fixed:
28.01.2025 · 1 199 downloads
Fixed:
26.01.2025 · 3 836 downloads
Added:
BattleState#isEndForced(): checks if battle was forcefully ended (i.e. draw)Changed:
Events#BATTLE_ENDED now fired after a battle was unregistered from the BattleManager and also if a battle was forcfully endedFixed:
26.01.2025 · 721 downloads
Added:
BattleState#isEndForced(): checks if battle was forcefully ended (i.e. draw)Changed:
Events#BATTLE_ENDED now fired after a battle was unregistered from the BattleManager and also if a battle was forcfully endedFixed:
24.01.2025 · 3 953 downloads
Fixed:
24.01.2025 · 249 downloads
Fixed:
22.01.2025 · 2 848 downloads
Added:
BattleManager#of(PokemonBattle), BattleManager#queryToEnd(PokemonBattle) and BattleManager#tick()Fixed:
22.01.2025 · 539 downloads
Added:
BattleManager#of(PokemonBattle), BattleManager#queryToEnd(PokemonBattle) and BattleManager#tick()Fixed:
21.01.2025 · 1 299 downloads
Added:
BATTLE_ENDEDBATTLE_STARTEDTRAINER_REGISTREDTRAINER_UNREGISTREDEventContext shared between the TrainerRegistry and BattleManager of an RCTApi service (but distinct of those from other services)BattleManager#getStates() to retrieve all active battle statesCommandsContext to allow registration of commands for different contexts without interfering with each otherChanged:
BattleManager instances are handled (now distinct for each registered RCTApi service)BattleManager#end(UUID, boolean) overload to forcefully end battlesFixed:
Removed:
GEN_9_ROYAL battle format for now (as it appears to not be implemented yet in Cobblemon)21.01.2025 · 433 downloads
Added:
BATTLE_ENDEDBATTLE_STARTEDTRAINER_REGISTREDTRAINER_UNREGISTREDEventContext shared between the TrainerRegistry and BattleManager of an RCTApi service (but distinct of those from other services)BattleManager#getStates() to retrieve all active battle statesCommandsContext to allow registration of commands for different contexts without interfering with each otherChanged:
BattleManager instances are handled (now distinct for each registered RCTApi service)BattleManager#end(UUID, boolean) overload to forcefully end battlesFixed:
Removed:
GEN_9_ROYAL battle format for now (as it appears to not be implemented yet in Cobblemon)07.01.2025 · 12 769 downloads
Fixed:
07.01.2025 · 1 413 downloads
Fixed:
07.01.2025 · 179 downloads
Added:
RCTApi instances by id or in bulk (fallback to RCTApi#DEFAULT_INSTANCE)RCTApi#getInstance(String)RCTApi#getInstances()RCTApi#initInstance(String)RCTApi#initInstance(String, TrainerRegistry)RCTApi#initInstance(String, TrainerRegistry, BattleManager)Trainers from the TrainerRegistry by the original trainer (OT) of a given PokemonTrainerRegistry#getByOT(Pokemon)TrainerRegistry#getByOT(Pokemon, Class<T>)Deprecated:
RCTApi#init() use new methods instead (see #16)07.01.2025 · 74 downloads
Added:
RCTApi instances by id or in bulk (fallback to RCTApi#DEFAULT_INSTANCE)RCTApi#getInstance(String)RCTApi#getInstances()RCTApi#initInstance(String)RCTApi#initInstance(String, TrainerRegistry)RCTApi#initInstance(String, TrainerRegistry, BattleManager)Trainers from the TrainerRegistry by the original trainer (OT) of a given PokemonTrainerRegistry#getByOT(Pokemon)TrainerRegistry#getByOT(Pokemon, Class<T>)Deprecated:
RCTApi#init() use new methods instead (see #16)30.12.2024 · 6 079 downloads
Fixed
30.12.2024 · 680 downloads
Fixed
30.12.2024 · 258 downloads
Added
RCTApiCommands.register(String) allows to register RCTApi commands with a different prefixTrainerRegistry#getId(LivingEntity) retrieves the trainer id for any given LivingEntityChanged
battle command now supports entity selectors30.12.2024 · 78 downloads
Added
RCTApiCommands.register(String) allows to register RCTApi commands with a different prefixTrainerRegistry#getId(LivingEntity) retrieves the trainer id for any given LivingEntityChanged
battle command now supports entity selectors23.12.2024 · 6 766 downloads
Fixed
battle.pvn)23.12.2024 · 594 downloads
Fixed
battle.pvn)09.12.2024 · 540 downloads
Fixed
PokemonEntityMixin with event handler (which also fixed a crash caused by that mixin on startup)09.12.2024 · 107 downloads
Fixed
PokemonEntityMixin with event handler (which also fixed a crash caused by that mixin on startup)09.12.2024 · 218 downloads
Added
RCTBattleAIConfig, SelfdotGen5AIConfig, StrongBattleAIConfig and registered corresponding JTO parsers (rct, sd5 and cbl)JTO (json to object) flexible parser systemRemoved
AIType enum (TrainerModel.ai is now defined as JTO<BattleAI>)09.12.2024 · 136 downloads
Added
RCTBattleAIConfig, SelfdotGen5AIConfig, StrongBattleAIConfig and registered corresponding JTO parsers (rct, sd5 and cbl)JTO (json to object) flexible parser systemRemoved
AIType enum (TrainerModel.ai is now defined as JTO<BattleAI>)09.12.2024 · 72 downloads
Changed
RCTBattleAI adjustments/fixes: improved switch evaluation + trainers now actually consider the use of (mostly healing) itemsFixed
RCTBattleAI and switch instructions potentially causing softlocks as well as some other corner cases that could cause a battle failure (this might not fixed all issues but it appeared rather stable now during my testings)09.12.2024 · 55 downloads
Changed
RCTBattleAI adjustments/fixes: improved switch evaluation + trainers now actually consider the use of (mostly healing) itemsFixed
RCTBattleAI and switch instructions potentially causing softlocks as well as some other corner cases that could cause a battle failure (this might not fixed all issues but it appeared rather stable now during my testings)03.12.2024 · 217 downloads
Added
03.12.2024 · 336 downloads
Added