Cobblemon Economy is a server-focused economy and shop system for Cobblemon on Fabric. It provides NPC shops, dual currencies, persistent storage, and reward hooks for captures and battles.
Website: https://ryvexam.fr
- Dual currencies: PokeDollars and PCO
- NPC shopkeepers with GUI-based shops (buy and sell)
- Per-world config and SQLite storage (config, DB, logs, skins)
- Dynamic quantity selection in shops (middle click)
- Item definitions support component syntax (enchantments, datapack items)
- Loot crates via dropTable or Minecraft loot tables
- Command execution items - sell commands instead of items (e.g., crate keys, effects, shoutouts)
- Purchase limits per item with optional cooldowns
- Auto-downloaded shopkeeper skins from server
- Transaction logging to file
- Capture, discovery, and battle rewards with multipliers
- Raid den battle rewards (separate configurable PokeDollar amount)
- Fossil revival rewards for shiny/radiant/legendary/paradox Pokémon
- Quest board interface (client custom screen, non-SGUI)
- Optional integrations: YAWP protection flag and Star Academy grading
- Optional CobbleDollars and Impactor bridge compatibility
Player:
/balor/balance/pco/pay <player> <amount>
Admin (permission level 2):
/eco reload/eco shop list/eco shop get <id>/eco quest list/eco questnpc list/eco questnpc get <id>/eco questboard list/eco questboard open <id>/eco questboard bind <id>/eco questboard unbind/eco skin <name>/eco item/balance <player> <add|remove|set> <amount>/pco <player> <add|remove|set> <amount>
Config path: world/config/cobblemon-economy/config.json
Shops path: world/config/cobblemon-economy/shops.json
Milestones path: world/config/cobblemon-economy/milestone.json
Quests path: world/config/cobblemon-economy/quests.json
Quest NPCs path: world/config/cobblemon-economy/quest_npcs.json
Legacy compatibility: if shops.json is missing, shops are still loaded from config.json and migrated automatically.
Milestone rules:
- File missing: defaults are generated.
- Empty file: defaults are used and saved.
- Keys are unique-capture counts (strings), values are rewards in PokeDollars.
Global settings:
main_currency(cobeco,cobbledollars,impactor; defaultcobeco)startingBalancestartingPcobattleVictoryRewardraidDenVictoryReward(defaults tobattleVictoryRewardif missing)capture_event_base_reward(defaults tobattleVictoryRewardif missing; reward for a first valid capture, and reused as the base for fossil revive special payouts)capture_multi_reward(defaults to0; reward for repeat non-special captures of an already known species)- Special captures (
shiny,radiant,legendary/mythical,paradox) still usecapture_event_base_rewardmultiplied by their configured special multiplier. battleVictoryPcoRewardbattleTowerCompletionPcoBonus(small extra PCO reward on Battle Tower wins)capture_shiny_multipliercapture_radiant_multipliercapture_legendary_multipliercapture_paradox_multiplierenableProfiling(logs slow operations when true)profilingThresholdMs(minimum ms to log)
Legacy compatibility:
- Old keys like
captureReward,capture_reward,newDiscoveryReward,special_capture_reward_ignores_pokedex_history,normal_capture_reward_requires_new_pokedex_entry,shinyMultiplier,radiantMultiplier,legendaryMultiplier, andparadoxMultiplierare still detected for migration. - On the next config rewrite, Cobblemon Economy saves
capture_event_base_reward,capture_multi_reward, and the explicit multiplier key names above.
Shop definition fields:
titlecurrency(POKEorPCO)skin(filename without extension)skinModel(optional:steveoralex, defaultsteve)isSellShop(true to let players sell)linkedShop(optional)linkedShopIcon(optional item id)items
Item definition fields:
type-"item"(default) or"command"id- Required stable identifier for every entry- for
type: "item": use the real item ID - for
type: "command": use an internal key such asserver:vote_key
- for
name- Display namepricenbt(legacy NBT string)dropTable(array of item ids)lootTable(minecraft loot table id)components(data components for items, written as normal JSON)enchantments(shorthand, no escaping needed)lore(shorthand, list of lines)unbreakable(shorthand, boolean)customModelData(shorthand, integer)glint(shorthand, boolean fake enchant shine)buyLimit(optional)buyCooldownMinutes(optional, 0 means lifetime limit)sellLimit(optional)sellCooldownMinutes(optional, 0 means lifetime limit)command- Command string fortype: "command"(use%player%placeholder)displayItem- Custom display configuration for command items:material- Item ID to displaydisplayname- Custom name shown in shopenchantEffect- Boolean for enchantment glint
Item limit rules:
- Missing
buyLimitorbuyLimit <= 0: unlimited. buyLimit > 0and missingbuyCooldownMinutes: lifetime limit.buyLimit > 0andbuyCooldownMinutes = 0: lifetime limit.buyLimit > 0andbuyCooldownMinutes > 0: limit resets every N minutes.- Missing
sellLimitorsellLimit <= 0: unlimited. sellLimit > 0and missingsellCooldownMinutes: lifetime limit.sellLimit > 0andsellCooldownMinutes = 0: lifetime limit.sellLimit > 0andsellCooldownMinutes > 0: limit resets every N minutes.
Example shop:
{
"shops": {
"my_shop": {
"title": "My Shop",
"currency": "POKE",
"items": [
{ "id": "minecraft:diamond", "name": "Diamond", "price": 1000 },
{ "id": "minecraft:diamond_sword[minecraft:enchantments={levels:{'minecraft:sharpness':5}}]", "name": "Sharpness V", "price": 5000 },
{ "id": "academy:booster_pack[academy:booster_pack='base']", "name": "Booster Pack", "price": 100 },
{ "id": "minecraft:chest", "name": "Mystery Box", "price": 500, "dropTable": ["minecraft:diamond", "cobblemon:rare_candy"] },
{ "id": "minecraft:chest", "name": "Dungeon Loot", "price": 1000, "lootTable": "minecraft:chests/simple_dungeon" },
{ "id": "cobblemon:rare_candy", "name": "Rare Candy", "price": 50, "buyLimit": 3, "buyCooldownMinutes": 1200 }
]
}
}
}Item limit only:
{ "id": "cobblemon:rare_candy", "name": "Rare Candy", "price": 50, "buyLimit": 3, "buyCooldownMinutes": 1200 }You never have to write escaped JSON like "{\"levels\":{...}}". Pick whichever style you prefer.
1. Shorthand fields (simplest):
{
"id": "minecraft:diamond_sword",
"name": "Champion Blade",
"price": 5000,
"enchantments": { "sharpness": 5, "unbreaking": 3, "mending": 1 },
"lore": ["Reward of the Champion", "Untradeable"],
"unbreakable": true
}enchantments also accepts a list: ["sharpness 5", "unbreaking 3"].
Names without a namespace are treated as minecraft:, and a missing level means 1.
2. Real JSON in components (full control, any component):
{
"id": "minecraft:diamond_sword",
"name": "Sharpness V",
"price": 5000,
"components": {
"minecraft:enchantments": { "levels": { "minecraft:sharpness": 5 } },
"minecraft:custom_name": { "text": "Sharpness V", "color": "gold" },
"academy:booster_pack": "base"
}
}3. Vanilla /give syntax on the id (use single quotes so JSON stays clean):
{ "id": "minecraft:diamond_sword[minecraft:enchantments={levels:{'minecraft:sharpness':5}}]", "name": "Sharpness V", "price": 5000 }Notes:
- Component names without a namespace are treated as
minecraft:. - If the same component is set in several ways,
componentswins over the shorthand fields, which win over the inline id syntax. - Old configs using escaped strings (
"minecraft:enchantments": "{\"levels\":{\"minecraft:sharpness\":5}}") keep working. - The shorthands also work on
type: "command"entries to decorate the GUI icon.
Command execution item (sells a command instead of an item):
{
"id": "server:vote_key",
"type": "command",
"command": "crate key give vote 1 %player%",
"price": 100,
"buyLimit": 1,
"buyCooldownMinutes": 1440,
"displayItem": {
"material": "supplementaries:key",
"displayname": "Vote Crate Key",
"enchantEffect": true
}
}Command item note:
idis still mandatory for command entries because the config loader and limit tracking use it as the entry key.
Mixed shop example (items + loot tables + commands):
{
"shops": {
"mixed_shop": {
"title": "MIXED SHOP",
"currency": "POKE",
"items": [
{ "id": "cobblemon:poke_ball", "name": "Poké Ball", "price": 200 },
{ "id": "minecraft:chest", "name": "Dungeon Loot", "price": 1000, "lootTable": "minecraft:chests/simple_dungeon" },
{
"type": "command",
"command": "effect give %player% minecraft:regeneration 300 1",
"price": 300,
"displayItem": {
"material": "minecraft:potion",
"displayname": "Regeneration Potion (5min)",
"enchantEffect": true
}
}
]
}
}
}- Place PNGs in
world/config/cobblemon-economy/skins/. - Use
/eco skin <name>to get a Skin Setter. - In
shops.jsonandquest_npcs.json, you can setskinModeltosteveoralexfor arm model type.
- Config:
world/config/cobblemon-economy/config.json - Milestones:
world/config/cobblemon-economy/milestone.json - Database:
world/config/cobblemon-economy/economy.db - Transactions:
world/config/cobblemon-economy/transactions.log - Skins:
world/config/cobblemon-economy/skins/
- Cobblemon (required): capture, pokedex, battle victory, and fossil events come from Cobblemon's event bus.
- Cobblemon Raid Dens (optional): raid completion is read from
com.necro.raid.dens.common.events.RaidEvents(RAID_BATTLE_START/RAID_END). - Battle Tower-like systems (optional): no hard dependency; tower wins are detected from battle actor metadata, entity IDs/tags, and explicit
tour_de_combatNPC tag. - YAWP: flag
melee-npc-cobecocontrols shopkeeper vulnerability. - Star Academy: optional grading integration when the
academymod is present. - CobbleDollars: optional compatibility bridge support.
- Impactor: optional compatibility bridge support.
Quest event notes:
raid_winobjectives use Raid DensRAID_ENDwhen the Raid Dens mod is available, with fallback detection from Cobblemon battle events when it is not.tower_winobjectives rely on tower actor detection; for custom NPC towers, tag NPCs withtour_de_combat(Tower Tagger from/eco item) to guarantee detection.
Currency backend behavior (main_currency):
cobeco: Cobblemon Economy database is authoritative for PokeDollars.cobecomirrors balances to CobbleDollars and Impactor accounts when those mods are installed, and bridges their API transactions into CobEco.cobbledollars: Cobblemon Economybalanceoperations use CobbleDollars player balance (online players).impactor: Cobblemon Economybalanceoperations use Impactor primary account balance.
If placeholder-api is installed, Cobblemon Economy exposes balance placeholders for tablists/scoreboards.
Use the placeholder format required by your tablist plugin (often %namespace:placeholder% or {namespace:placeholder}).
Available placeholders (recommended namespace: cobeco):
cobeco:balancecobeco:balance_symbolcobeco:pcocobeco:pco_symbol
Alternate namespaces also registered for compatibility:
cobblemon_economy:*cobblemon-economy:*
./gradlew buildJar output: build/libs/ (use the remapped jar).
Discord: https://discord.gg/zxZXcaTHwe
Thanks to Rikunji for their contributions to the project.