PokeBadges
A standalone Gym Badge progression system for Minecraft, designed for Cobblemon, Pixelmon, servers, adventure maps and progression-focused modpacks.
Distribution pages may temporarily show an earlier public release until v2.0 is published.
What does PokeBadges do?
PokeBadges turns Gym Badges into persistent progression instead of simple collectible items. Players store badges in a dedicated Badge Box, track completion by region, keep historical backup data and can recover missing progress when server rules allow it.
- Dedicated Badge Box with a custom progression interface.
- Support for Kanto, Johto, Hoenn, Sinnoh, Unova, Kalos, Galar and Paldea.
- Badge metadata including region, Gym Leader, Gym type, order and obtained date.
- Persistent current progress plus historical backup progress.
- Server commands for awarding, auditing, restoring and clearing badge progress.
- Public server-side Java API for mod and server integrations.
- Server-side event callbacks for badge and region progression.
- Fabric and NeoForge support on Minecraft 1.21.1.
Supported regions
| Region | Generation | Badge Box support |
|---|---|---|
| Kanto | 1 | β |
| Johto | 2 | β |
| Hoenn | 3 | β |
| Sinnoh | 4 | β |
| Unova | 5 | β BW1 / BW2 selectable |
| Kalos | 6 | β |
| Galar | 8 | β |
| Paldea | 9 | β |
Compatibility
| Component | Requirement |
|---|---|
| Minecraft | 1.21.1 |
| Java | 21+ |
| Fabric Loader | 0.18.4+ |
| Fabric API | Required on Fabric |
| NeoForge | 21.1.x |
| Architectury API | 13.0.8+ |
| Accessories | Optional |
| Curios | Optional |
| Environment | Client + Server |
Progress model
- ObtainA badge exists as a normal PokeBadges item.
- RegisterDepositing or awarding the badge records it in the player's Badge Box.
- BackupThe first recorded timestamp is also kept in historical backup data.
- CompleteFinishing every required slot in a region triggers region completion.
Installation
Install PokeBadges on both the server and every client that needs to use the Badge Box interface.
Fabric
- PokeBadges for Fabric.
- Fabric Loader 0.18.4 or newer.
- Fabric API.
- Architectury API 13.0.8 or newer.
- Java 21 or newer.
NeoForge
- PokeBadges for NeoForge.
- NeoForge 21.1.x.
- Architectury API 13.0.8 or newer.
- Java 21 or newer.
Optional integrations
Accessories and Curios are optional. When present, PokeBadges can detect an equipped Badge Box through those systems. No external PokΓ©mon mod is declared as a hard dependency.
Opening the Badge Box
The Fabric default key is B. The normal keybind flow requires the player to own a Badge Box in the main hand, off hand, inventory, Curios slot or Accessories slot.
The physical Badge Box item can also be used directly. Server integrations may open the interface through /pokebadges open or the public API, depending on the server configuration.
Keep the same PokeBadges version on server and client. The interface and networking are part of the mod, so PokeBadges is not a server-only installation.
Badge Box
The Badge Box is the central interface for viewing current Gym Badge progress and navigating each supported region.
Main page
The main page displays the player's total badge progress and one navigation button for every supported region. Region buttons expose per-region progress and completion state.
Region pages
Each region page shows its active badge slots. Missing badges are rendered as silhouettes, while obtained badges display their normal item appearance.
Badge tooltips can include the region, active order, Gym Leader, Gym type, whether the badge has been obtained and the stored acquisition timestamp.
Current progress and historical backup
PokeBadges stores two related datasets for every player:
| Dataset | Purpose |
|---|---|
| Current Badge Box | The badges currently counted as the player's active progression. |
| Historical backup | Badges previously registered by the player, used for audit and restore operations. |
Removing a badge through the public remove operation only removes it from current progress. Its historical backup remains available. Full administrative clear commands remove both current and backup data for their scope.
Unova mode
Unova has two selectable badge sets:
black_white_1for Black / White 1.black_white_2for Black / White 2.
Only the selected set counts as active region progression. Disabled Unova badges can optionally be hidden from the creative tab.
Withdrawal rules
Badges can only be withdrawn from the Badge Box when both lock_badges_in_badge_box=false and strict_badge_mode=false. The default configuration keeps Badge Box badges locked.
Commands
PokeBadges provides player utilities plus permission-level 2 administration commands.
Player commands
/pokebadges infoShows the active server configuration relevant to Badge Box behavior.
/pokebadges openOpens the Badge Box through the external-open path. Whether a physical Badge Box is required is controlled by external_open_requires_badge_box.
/pokebadges backupRestores badges that exist in historical backup but are missing from current progress. The default cooldown is 30 seconds.
/pokebadges missing [region]Lists missing active badges globally or for one region.
/pokebadges progressShows current and backup progression for the executing player.
Admin commands
/pokebadges progress <player>Shows progression for another player. Requires permission level 2.
/pokebadges reloadReloads the server configuration from disk. Requires permission level 2.
/pokebadges admin audit <player>Compares current progression with historical backup and reports differences.
/pokebadges admin restore <player>Restores missing current badges from the player's historical backup.
/pokebadges admin open <targets>Opens the Badge Box for one or more players through the external-open path.
/pokebadges admin award <targets> <badge>Directly registers a badge in current progress and historical backup. This is the progression-safe command for integrations and staff rewards.
/pokebadges give <targets> <badge>Gives the physical badge item to player inventory. It does not directly register Badge Box progression.
/pokebadges give_region <targets> <region>Directly awards every active badge in the selected region to the target players.
/pokebadges clear <targets>Clears all current and historical backup badge data for the target players.
/pokebadges clear_region <targets> <region>Clears current and historical backup data for one region.
Accepted badge IDs
Badge arguments accept either the full identifier such as pokebadges:toxic_unova_badge or the short path toxic_unova_badge. Command suggestions use the shorter form.
Configuration
PokeBadges uses separate server and client configuration files under the dedicated config/pokebadges folder.
Server configuration
config/pokebadges/pokebadges-server.cfg
Older installs using world/serverconfig/pokebadges-server.cfg are detected when the new file does not exist and are migrated into the current config location.
Default server configuration
// PokeBadges server config
lock_badges_in_badge_box=true
strict_badge_mode=false
backup_command_cooldown_seconds=30
unova_badge_set=black_white_2
hide_disabled_unova_badges_in_creative_tab=false
external_open_requires_badge_box=false
| Setting | Default | Behavior |
|---|---|---|
lock_badges_in_badge_box | true | Prevents players from withdrawing badges after storage. |
strict_badge_mode | false | Treats Badge Box progression as permanent trophy progression and prevents withdrawal. |
backup_command_cooldown_seconds | 30 | Cooldown for the player /pokebadges backup command. Minimum is 0. |
unova_badge_set | black_white_2 | Selects the active eight-badge Unova set. Valid values are black_white_1 and black_white_2. |
hide_disabled_unova_badges_in_creative_tab | false | Hides the inactive Unova set from creative inventory when enabled. |
external_open_requires_badge_box | false | Controls whether commands and integration APIs need the player to physically own a Badge Box. |
Client configuration
config/pokebadges/pokebadges-client.cfg
// PokeBadges client config
badge_discovery_popups=true
badge_discovery_popups controls the custom first-time badge registration popup. The legacy config/pokebadges-client.cfg location is migrated automatically.
Use /pokebadges reload after editing the server configuration. Client popup settings are local to each client.
Integration API
PokeBadges v2 exposes a small public server-side API so other mods and server systems can work with Badge Box progression without touching saved data directly.
Public entry point
net.levelscraft7.pokebadges.api.PokeBadgesApi
All API methods operate on a server-side ServerPlayer.
| Method | Return type | Purpose |
|---|---|---|
openBadgeBox(player) | boolean | Opens the full Badge Box. Returns false if server rules require a physical Badge Box and the player does not have one. |
awardBadge(player, badgeId) | BadgeOperationResult | Adds the badge to current progress and historical backup. |
hasBadge(player, badgeId) | BadgeOperationResult | Returns SUCCESS when the player currently owns the badge. |
removeBadge(player, badgeId) | BadgeOperationResult | Removes the badge from current progress while keeping historical backup. |
restoreBadge(player, badgeId) | BadgeOperationResult | Restores a badge from historical backup into current progress. |
getOwnedBadges(player) | Set<ResourceLocation> | Returns current owned badge IDs. |
getBackupBadges(player) | Set<ResourceLocation> | Returns historical backup badge IDs. |
isRegionCompleted(player, regionId) | BadgeOperationResult | Returns SUCCESS when every active badge slot in the region is complete. |
Example: award a badge
import net.levelscraft7.pokebadges.api.BadgeOperationResult;
import net.levelscraft7.pokebadges.api.PokeBadgesApi;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.server.level.ServerPlayer;
ResourceLocation toxicBadge = ResourceLocation.fromNamespaceAndPath(
"pokebadges",
"toxic_unova_badge"
);
BadgeOperationResult result = PokeBadgesApi.awardBadge(player, toxicBadge);
if (result == BadgeOperationResult.SUCCESS) {
// Badge Box progression was updated successfully.
}
Example: check a region
ResourceLocation kanto = ResourceLocation.fromNamespaceAndPath("pokebadges", "kanto");
boolean completed = PokeBadgesApi.isRegionCompleted(player, kanto)
== BadgeOperationResult.SUCCESS;
Operation results
| Result | Meaning |
|---|---|
SUCCESS | The operation succeeded. |
ALREADY_OWNED | The badge is already present in current progress. |
UNKNOWN_BADGE | The supplied ID does not resolve to a PokeBadges badge. |
UNKNOWN_REGION | The supplied region ID is invalid. |
NOT_OWNED | The player does not currently own the requested badge or the region is incomplete. |
NOT_IN_BACKUP | The requested badge cannot be restored because historical backup does not contain it. |
INVALID_PLAYER | The supplied server player is invalid. |
FAILED | The operation was rejected for another rule, including a badge disabled by the active Unova mode. |
Integration rules
- Use
PokeBadgesApiinstead of reading or modifyingBadgeBoxSavedDatadirectly. - Badge IDs are normal Minecraft
ResourceLocationitem IDs. - Region IDs use the
pokebadgesnamespace, for examplepokebadges:kanto. - API award, remove and restore operations emit the corresponding public event callbacks.
Server-side Events
Integrations can subscribe to lightweight PokeBadges callbacks without depending on loader-specific event buses.
Registration class
net.levelscraft7.pokebadges.api.event.PokeBadgesEvents
| Registration method | Event |
|---|---|
registerBadgeAwarded(...) | BadgeAwardedEvent |
registerBadgeRemoved(...) | BadgeRemovedEvent |
registerBadgeRestored(...) | BadgeRestoredEvent |
registerRegionCompleted(...) | RegionCompletedEvent |
Example listener
import net.levelscraft7.pokebadges.api.event.PokeBadgesEvents;
AutoCloseable badgeListener = PokeBadgesEvents.registerBadgeAwarded(event -> {
var player = event.player();
var badgeId = event.badgeId();
var region = event.region();
var source = event.source();
long obtainedAt = event.obtainedAt();
// Your integration logic here.
});
// Call badgeListener.close() when your integration unloads.
Event payloads
| Event | Fields |
|---|---|
BadgeAwardedEvent | player, badgeId, region, source, obtainedAt |
BadgeRemovedEvent | player, badgeId, region, source |
BadgeRestoredEvent | player, badgeId, region, source, obtainedAt |
RegionCompletedEvent | player, regionId, region, source |
Action sources
BadgeActionSource tells integrations where the progression change originated:
MANUAL_DEPOSIT
COMMAND
API
RESTORE
ADMIN
UNKNOWN
Every registration method returns an AutoCloseable. Keep that handle and close it when your integration unloads to remove the listener cleanly.
FAQ
Common behavior and integration questions for players, pack authors and server administrators.
The B key does nothing
The normal keybind requires a Badge Box somewhere the server can detect it: main hand, off hand, inventory, Curios or Accessories. Also verify that the key has not been rebound or conflicted with another mod.
Can a server open the Badge Box without giving the item?
Yes. By default external_open_requires_badge_box=false, so /pokebadges open, admin external opens and PokeBadgesApi.openBadgeBox can open the interface without the physical item. Set the option to true to enforce ownership.
What is the difference between give and award?
/pokebadges give gives the physical badge item. /pokebadges admin award records progression directly in the player's Badge Box and backup.
Why can a badge not be removed from the Badge Box?
The default server config has lock_badges_in_badge_box=true. Withdrawal is only available when both the lock option and strict mode are disabled.
A player lost badges after a problem. What should staff do?
- Run
/pokebadges admin audit <player>. - If historical backup contains missing progress, run
/pokebadges admin restore <player>. - Use
admin awardonly when a badge must be granted independently of backup history.
Does PokeBadges require Cobblemon or Pixelmon?
No hard dependency is declared for either project. PokeBadges is built as a standalone badge progression layer and is designed to fit PokΓ©mon-focused environments.
Where should integrations hook progression?
Use PokeBadgesApi for writes and checks, then subscribe to PokeBadgesEvents when your mod needs to react to progression changes. Avoid writing directly to internal SavedData classes.