Cobblemon XP Overhaul
Introduction: Overview
A unified, configurable XP progression system for Minecraft players and Pokémon, covering captures, battles and team training.
What does the mod do?
Cobblemon XP Overhaul replaces the need for several overlapping XP systems with customizable rules for player progression and Pokémon training.
- Player XP for Pokémon captures and wins against wild Pokémon, NPC trainers and other players.
- Pokémon XP for captures and trainer-battle knockouts.
- Optional Exp All and Exp Share interactions.
- Lucky Egg, first-species, repeated-capture, Shiny, Alpha and rare Pokémon modifiers.
- The XP Flask stores a portion of the mod's player XP rewards for later Pokémon training.
- XP Flask preview using sneak + right-click (v2.1).
- Admin XP diagnostics using
/cxpo xp explain [player](v2.1). - English and French wiki; expanded in-game translations.
Requirements
| Component | Version |
|---|---|
| Minecraft | 1.21.1 |
| Cobblemon XP Overhaul | v2.1 documentation |
| Cobblemon | 1.8.2 to below 1.9.0 |
| OS Cobblemon Library | 1.3.0 or later — required |
| Fabric | Fabric Loader 0.17.2+, Fabric API, Fabric Language Kotlin, Cloth Config |
| NeoForge | 21.1.182+, Cloth Config client UI |
| Java | 21 |
How XP works
- Capture or battle — a supported event generates a reward.
- Calculate — level, reward type, bonuses and configuration determine XP.
- Split — the configured share of player XP can be stored in the XP Flask.
- Train — use the Flask on an owned Pokémon, or preview the transfer first.
The default capture Exp All is disabled and the XP Flask does not collect normal vanilla Minecraft XP. See progression, XP Flask and commands.
Installation and requirements
Getting started: Installation
Cobblemon XP Overhaul adds configurable experience rewards for captures and battles, with an XP Flask for Pokémon training.
Supported versions
| Component | Requirement |
|---|---|
| Minecraft | 1.21.1 |
| Cobblemon XP Overhaul | 2.1 |
| Cobblemon | 1.8.2 up to, but not including, 1.9.0, for Minecraft 1.21.1 |
| Loader | Fabric or NeoForge |
| OS Cobblemon Library | 1.3.0+, required |
| Java | 21 |
Fabric
Use the Fabric JAR with Fabric Loader 0.17.2+, Fabric API, Fabric Language Kotlin 1.13.6+, Cobblemon 1.8.2+ (below 1.9), OS Cobblemon Library 1.3.0+, and Cloth Config 15.0.140+. Mod Menu is optional.
NeoForge
Use the NeoForge JAR with NeoForge 21.1.182+, Cobblemon 1.8.2+ (below 1.9), OS Cobblemon Library 1.3.0+, and, for the client configuration UI, Cloth Config 15.0.140+. The build uses Kotlin for Forge. Never mix Fabric and NeoForge builds.
Installation
- Install Minecraft 1.21.1, a supported loader, and Cobblemon.
- Get the appropriate XP Overhaul build from CurseForge.
- Place the mod JAR and required dependencies, including OS Cobblemon Library, in the mods folder. Multiplayer servers and clients need the matching loader build.
- Start the game or server to generate the default files in
config/cobblemon_xp_overhaul/. - Catch a Pokémon and complete a battle to observe the rewards.
Use sneak + right-click on your summoned Pokémon while holding the XP Flask to preview a transfer without using XP. Read XP progression, XP Flask and configuration.
XP progression
Experience: XP Progression
Player XP (Minecraft experience bar) and Pokémon XP are configurable separately.
Player XP from captures
Capturing a Pokémon can grant player XP determined by a base value, captured level, global multiplier and bonuses. The default base is 4 and level multiplier is 0.2.
Capture modifiers can apply to:
- A species captured for the first time, or repeated captures of the same species
- Shiny, Alpha and special forms
- Legendary, Mythical and Ultra Beast Pokémon
- Lucky Egg bonuses, if enabled
The same species history is tracked per player. Shiny and Alpha multipliers are 1.0 by default, so they do not increase XP unless configured.
Player XP from battles
Victory rewards have separate profiles for wild, NPC trainer, and PvP battles. Each profile has its own enabled state, base XP, per-level multiplier and global multiplier. A minimum defeated Pokémon level can be configured.
Capture-triggered wild victories are skipped by default to prevent duplicate player rewards.
Pokémon XP from captures
Eligible party Pokémon can receive configurable capture XP. The mod distinguishes:
- Participants with
participantMultiplier(default 1.0). - Exp Share holders when Exp All is disabled, with
expShareMultiplier(default 0.5). - Exp All recipients when enabled, with
expAllMultiplier(default 0.35).
pokemon.capture.expAllEnabled defaults to false. With Exp All enabled, Exp Share holders can receive an optional additional 10% bonus. The captured Pokémon can also receive Exp All XP when allowCapturedPokemonWithExpAll is enabled.
Pokémon XP from trainer fights
During trainer battles, XP is awarded on eligible knockouts instead of being deferred until battle victory. This means eligible KO rewards can persist even after a later battle loss.
Lucky Egg
The player reward checks inventory or party-held Lucky Eggs according to the luckyEgg config. Pokémon capture XP checks the recipient's held Lucky Egg individually. Default lucky egg multiplier for applicable custom rewards is 1.5.
Inspect the last player XP calculation (v2.1)
Server operators can use /cxpo xp explain or /cxpo xp explain <player> to see the latest recorded player XP formula, bonuses and split between the player and the XP Flask. The diagnostic record is session-only. See commands.
See the full settings reference.
XP Flask
Training: XP Flask
The XP Flask (cobblemon_xp_overhaul:xp_flask) stores part of the player XP awarded by XP Overhaul itself, then converts it into Pokémon XP.
Crafting recipe
| Amethyst Shard | Bottle o' Enchanting | Amethyst Shard |
| Exp. Candy L | Exp. Share | Exp. Candy L |
| Lapis Lazuli | Bottle o' Enchanting | Lapis Lazuli |
This is a shaped 3 × 3 recipe injected when the server starts.
Charging and use
- Keep an XP Flask in your inventory, or equip one in the optional Accessories
xp_flaskslot. - Earn player XP through supported XP Overhaul capture or victory rewards.
- With the Flask feature enabled, part of those rewards goes into the Flask. The remainder goes to the Minecraft XP bar.
- Right-click a summoned Pokémon you own with the filled Flask to grant Pokémon XP.
New in v2.1: Hold Shift (sneak) and right-click your summoned Pokémon with the Flask to preview the XP transfer in chat. The preview displays the expected Pokémon XP, trainer XP cost, remaining stored trainer XP and estimated level change, or a reason the transfer is unavailable. It does not consume XP or modify the Pokémon. Use a regular right-click to apply the transfer.
Only up to the XP required to reach the next Pokémon level can be granted per use, before Cobblemon events. Any unused stored XP remains in the Flask. A tooltip shows how much converted Pokémon XP is available.
Default conversion
| Setting | Default | Meaning |
|---|---|---|
coreCaptureRatio | 0.25 | Redirect 25% of eligible player XP, rounded down |
transferMultiplier | 40.0 | Trainer XP to Pokémon XP factor |
transferEfficiency | 0.9 | Additional conversion factor |
enabled | true | Enable Flask processing |
The effective conversion factor is 40 × 0.9 = 36 Pokémon XP for each stored trainer XP, subject to integer rounding and the next-level limit.
Accessories support
When installed, a Flask equipped in its Accessories slot is selected before inventory Flasks. Without Accessories, inventory lookup still works.
Messages
Use trainerXpCore.messageMode as ACTION_BAR, CHAT or DISABLED. The showTrainerXpCoreMessages toggle also applies.
The preview is an estimate; the actual use recalculates the transfer when applied. Server administrators can inspect or adjust stored XP with Flask commands. Other mods can use the server-side API.
Configuration guide
Administration: Configuration
The mod creates two JSON files in config/cobblemon_xp_overhaul/:
| File | Purpose |
|---|---|
cobblemon_xp_overhaul-server.json | Capture and battle rewards, Lucky Eggs and XP Flask |
cobblemon_xp_overhaul-common.json | Action bar messages, queues and debug options |
Edit the configuration
- Start the instance or server once to generate the files.
- Back up the two JSON files.
- Edit the relevant keys. JSON does not accept comments or trailing commas.
- Run
/cxpo reloadwith permission level 2. - Test a capture or battle to confirm the result.
The Cloth Config screen offers a client UI for settings. For multiplayer balance changes, edit the authoritative server's files.
Example: Exp All
Set the existing pokemon.capture.expAllEnabled property:
"pokemon": {
"capture": {
"expAllEnabled": true,
"expAllMultiplier": 0.35,
"expShareBonusWithExpAllEnabled": false
}
}
This is a partial illustration of the nested structure, not a replacement for the complete server JSON.
Example: capture XP balancing
"player": {
"capture": {
"baseXp": 4,
"levelMultiplier": 0.2,
"globalMultiplier": 1.0
}
}
The mod normalizes invalid values and migrates certain older flat section names on reload. Malformed JSON can trigger safe defaults, so make backups before editing.
For troubleshooting player XP formulas in v2.1, use /cxpo xp explain [player] as an operator. This diagnostic is available without changing the JSON files.
For every exact key and default, use the full configuration reference.
Full configuration reference
All JSON settings: Settings
This page lists exact v2.1 JSON keys and defaults. Files are located in config/cobblemon_xp_overhaul/.
Server settings
File: cobblemon_xp_overhaul-server.json
player.capture
| JSON key | Default |
|---|---|
enabled | true |
baseXp | 4 |
levelMultiplier | 0.2 |
globalMultiplier | 1 |
luckyEggMultiplier | 1.5 |
minimumLevelForRewards.enabled | false |
minimumLevelForRewards.level | 20 |
player.battle
| JSON key | Default |
|---|---|
luckyEggMultiplier | 1.5 |
skipWildCaptureVictories | true |
minimumLevelForRewards.enabled | false |
minimumLevelForRewards.level | 20 |
player.battle.wild
| JSON key | Default |
|---|---|
enabled | true |
baseXp | 4 |
levelMultiplier | 0.17 |
globalMultiplier | 1 |
player.battle.trainer
| JSON key | Default |
|---|---|
enabled | true |
baseXp | 5 |
levelMultiplier | 0.19 |
globalMultiplier | 1 |
player.battle.pvp
| JSON key | Default |
|---|---|
enabled | true |
baseXp | 6 |
levelMultiplier | 0.21 |
globalMultiplier | 1 |
pokemon.capture
| JSON key | Default |
|---|---|
enabled | true |
baseXp | 24 |
levelMultiplier | 1.25 |
globalMultiplier | 1 |
participantMultiplier | 1 |
expShareMultiplier | 0.5 |
expAllMultiplier | 0.35 |
expAllEnabled | false |
expShareBonusWithExpAllEnabled | false |
allowCapturedPokemonWithExpAll | true |
luckyEggMultiplier | 1.5 |
luckyEgg
| JSON key | Default |
|---|---|
enabled | true |
checkPlayerInventory | true |
checkPartyHeldItemsForPlayerXp | true |
checkPokemonHeldItems | true |
trainerXpCore
| JSON key | Default |
|---|---|
enabled | true |
coreCaptureRatio | 0.25 |
transferMultiplier | 40 |
transferEfficiency | 0.9 |
showTrainerXpCoreMessages | true |
messageMode | "ACTION_BAR" |
player.capture.bonuses
| JSON key | Default |
|---|---|
firstSpeciesBonusEnabled | true |
firstSpeciesMultiplier | 1.5 |
repeatedSpeciesModifierEnabled | true |
repeatedSpeciesMultiplier | 0.75 |
repeatedSpeciesThreshold | 1 |
shinyMultiplier | 1 |
alphaMultiplier | 1 |
legendaryMultiplier | 1.2 |
mythicalMultiplier | 1.2 |
ultraBeastMultiplier | 1.2 |
specialFormMultiplier | 1 |
pokemon.capture.bonuses
| JSON key | Default |
|---|---|
firstSpeciesBonusEnabled | true |
firstSpeciesMultiplier | 1.5 |
repeatedSpeciesModifierEnabled | true |
repeatedSpeciesMultiplier | 0.75 |
repeatedSpeciesThreshold | 1 |
shinyMultiplier | 1 |
alphaMultiplier | 1 |
legendaryMultiplier | 1.2 |
mythicalMultiplier | 1.2 |
ultraBeastMultiplier | 1.2 |
specialFormMultiplier | 1 |
Common settings
File: cobblemon_xp_overhaul-common.json
messages.actionBar
| JSON key | Default |
|---|---|
showPlayerCapture | true |
showPlayerBattle | true |
showPokemonCapture | true |
showPokemonBattle | true |
showCategoryLabels | false |
queueEnabled | true |
queueSpacingTicks | 30 |
debug
| JSON key | Default |
|---|---|
enabled | false |
logToConsole | true |
sendToPlayer | false |
Validation and migration
- Negative XP values and most negative multipliers are clamped to zero.
luckyEggMultiplieris at least1.0;coreCaptureRatiois between0and1.queueSpacingTicks,repeatedSpeciesThreshold, and minimum reward level are at least1.trainerXpCore.messageMode:ACTION_BAR,CHAT,DISABLED.- Legacy root sections
playerCapture,playerBattle,pokemonCaptureare migrated to nested structures.
Learn how to edit safely in the configuration guide.
Commands and permissions
Administration: Commands
All commands below require permission level 2, typically a server operator.
| Command | Effect |
|---|---|
/cxpo reload | Reload both JSON config files |
/cxpo flask get | Show XP in the first usable Flask |
/cxpo flask set <amount> | Set stored XP to a nonnegative integer |
/cxpo flask add <amount> | Add a signed amount and clamp the stored XP to zero or more |
/cxpo xp explain | Explain your latest recorded player XP capture or victory calculation |
/cxpo xp explain <player> | Explain the latest recorded player XP calculation for the specified online player |
The full alias /cobblemonxpoverhaul supports the same subcommands.
/cxpo reload
/cxpo flask get
/cxpo flask set 250
/cxpo flask add -50
/cxpo xp explain
/cxpo xp explain Steve
XP calculation breakdown (v2.1)
The xp explain command displays the most recently recorded player XP calculation on the current server: its capture/wild/trainer/PvP source, eligible levels, base XP, scaling, applied multipliers, total calculated XP, XP kept by the player and XP redirected into the Flask. It also explains zero rewards and skipped captures when recorded.
Records exist only for the current server session, with a bounded memory of up to 256 tracked players. This is not a persistent history, and the command does not explain individual Pokémon XP rewards. If no record exists, it reports that no calculation was recorded.
Use the optional <player> argument to inspect another online player. From the console, specify a player explicitly; without an argument, the command requires an in-game player.
A Flask in the dedicated optional Accessories slot takes priority over a Flask in inventory.
See configuration and XP Flask.
Compatibility
Requirements: Compatibility
Versions and loaders
The source targets Minecraft 1.21.1, Cobblemon 1.8.2 up to but excluding 1.9.0, and builds for Fabric and NeoForge. Confirm the precise loader-specific release before installation.
Fabric: Loader 0.17.2+, Fabric API, Fabric Language Kotlin 1.13.6+, Cloth Config 15.0.140+, OS Cobblemon Library 1.3.0+ and Cobblemon 1.8.2–1.8.x.
NeoForge: NeoForge 21.1.182+, Cobblemon 1.8.2–1.8.x, OS Cobblemon Library 1.3.0+, with Cloth Config 15.0.140+ on clients using the settings screen. The build uses Kotlin for Forge.
OS Cobblemon Library is required on both loaders, not an optional compatibility mod. The mod uses the library's Pokémon party storage access.
Requirements come from the mod metadata and do not guarantee testing against every later release.
In-game language support
Version 2.1 expands the mod's in-game translations. The documentation website itself is available in English and French.
Optional integrations
| Mod | Integration |
|---|---|
| Accessories | Equippable XP Flask in the xp_flask slot; inventory fallback |
| Mod Menu | Optional Fabric entry to the settings screen |
| Radical Cobblemon Trainers (RCT) | Conditional level-cap compatibility when its expected API is available |
The RCT integration checks classes reflectively and does not require the mod. If its API cannot be resolved, the compatibility hook does not activate.
Multiplayer and limitations
Reward handling and API Flask application run on the server. Install matching game/loader versions across server and clients. Use server JSON for balance settings.
The XP Flask collects XP Overhaul player rewards, not vanilla XP sources. A regular use is limited to the next Pokémon level before Cobblemon events. Sneak + right-click previews the transfer without changing XP. Exp All is disabled by default.
See the FAQ and requirements.
FAQ and troubleshooting
Troubleshooting: FAQ
Why is my XP Flask empty?
It collects only player XP granted by XP Overhaul, not mining or regular mobs. Keep a Flask in your inventory or compatible Accessories slot, and verify trainerXpCore.enabled=true and coreCaptureRatio>0.
Why doesn't every Pokémon receive capture XP?
Check pokemon.capture.enabled, participation, Exp Share, and expAllEnabled (disabled by default). Cobblemon's normal eligibility rules can also apply.
Why do Shiny and Alpha catches give normal XP?
Their default capture multipliers are both 1.0. Increase shinyMultiplier and alphaMultiplier in the relevant bonus section if desired.
Why can't I use the reload command?
/cxpo reload requires operator permission level 2.
Can I check a Flask transfer before using it?
Yes, since v2.1. Hold Shift (sneak) and right-click your own summoned Pokémon with the Flask to preview the transfer in chat without spending XP. Use a regular right-click to apply it.
Can operators inspect XP calculations?
Yes. /cxpo xp explain [player] shows the last recorded player XP reward calculation from the current server session. It does not track Pokémon XP or persist across restarts. Permission level 2 is required.
Why does the Flask keep some stored XP?
Each application is capped to the amount needed for the next Pokémon level before Cobblemon's XP events run.
Why does the config revert?
Malformed JSON can trigger replacement with sanitized defaults. Check the logs and restore a backup. The common configuration exposes debug.enabled for diagnostic output.
Can other mods use the Flask on party or PC Pokémon?
Yes. The documented XP Flask API works on server-authoritative Cobblemon Pokémon objects. It is not an in-game PC button by itself.
Where is configuration saved?
In config/cobblemon_xp_overhaul/ as separate server and common JSON files. See configuration.
XP Flask developer API
Integration: Developer API
XP Overhaul v2.1 exposes a server-side integration API for previewing and applying Flask XP to a Cobblemon Pokémon object, including Pokémon from party or PC storage.
Example
import com.cobblemon.mod.common.pokemon.Pokemon;
import net.levelscraft7.cobblemonxpoverhaul.api.XpFlaskApi;
import net.levelscraft7.cobblemonxpoverhaul.api.XpFlaskPreview;
import net.levelscraft7.cobblemonxpoverhaul.api.XpFlaskResult;
import net.minecraft.server.level.ServerPlayer;
XpFlaskPreview preview = XpFlaskApi.preview(player, pokemon);
if (preview.canApply()) {
XpFlaskResult result = XpFlaskApi.apply(player, pokemon);
if (result.success()) {
// Refresh the calling mod's own UI.
}
}
Player-facing preview (v2.1): Sneak + right-click on a summoned owned Pokémon while holding the Flask shows the transfer estimate in chat. The public API below supports other server-side integrations.
preview never mutates player, Flask or Pokémon. apply locates the Flask again and recalculates the cost. Do not accept client-supplied XP amounts or levels as authoritative.
Optional dependency detection
Mod ID: cobblemon_xp_overhaul.
- Fabric:
FabricLoader.getInstance().isModLoaded("cobblemon_xp_overhaul") - NeoForge:
ModList.get().isLoaded("cobblemon_xp_overhaul")
Contracts and limitations
The API requires a ServerPlayer and a server-authoritative Pokemon. It checks equipped Accessories Flask first, then inventory. XP resides in the Flask's StoredTrainerXp custom data. One application uses at most the XP needed until the next level before Cobblemon events.
XpFlaskPreviewcontainsstatus,storedTrainerXp,availablePokemonXp,requiredPokemonXp,trainerXpCost,pokemonXpToGrant,currentLevel,resultingLevel, withcanApply()andwillLevelUp().XpFlaskResultcontainsstatus,consumedTrainerXp,grantedPokemonXp,previousLevel,resultingLevel,storedTrainerXpBefore,storedTrainerXpAfter, withsuccess().XpFlaskStatusvalues:SUCCESS,FEATURE_DISABLED,INVALID_PLAYER,INVALID_POKEMON,NO_FLASK_FOUND,EMPTY_FLASK,MAX_LEVEL,INSUFFICIENT_XP,NO_XP_REQUIRED,APPLICATION_FAILED.
For localization, use XpFlaskStatus.translationKey() instead of parsing displayed text. See admin commands.