PokeLoot Weights¶
Lets staff set the drop chance of each item in Pixelmon PokeLoot chests. Pixelmon picks chest loot evenly from a flat list; this mod picks by weight from a config file instead.
What it does¶
- Replaces the item a PokeLoot chest gives with a weighted pick from
pokeloot_weights.json. Example: Master Ball at weight 1, Rare Candy at weight 40. - One table per chest type, using Pixelmon's own tier names:
| Tier | Chest |
|---|---|
tier1 |
Poke Ball chest |
tier2 |
Ultra Ball chest |
tier3 |
Master Ball chest |
ultraSpace |
Beast Ball chest |
- Hidden chests roll across tiers. By default the split is 51/34/15 (tier1/2/3), the same as Pixelmon, and it can be changed, including letting hidden chests reach the Beast Ball table.
- Everything else stays Pixelmon's: claim tracking, one-time or timed chests, the "found" chat line, the sound.
- Never touched: owner-set chests and special-event chests with custom drops.
- If anything goes wrong, the chest falls back to a normal Pixelmon drop, never an empty chest.
Server-side only.
How players use it¶
Players open PokeLoot chests as usual. Only the odds are different.
Staff guide¶
All commands need pokelootweights.command.admin (off by default; ops and console have it).
| Task | Command |
|---|---|
| Summary of every tier: entries, total weight, hidden split | /pokelootweights info |
| The 20 heaviest entries in a tier, with their real drop chance | /pokelootweights info <tier> |
| Roll a tier many times and compare to the expected chances | /pokelootweights simulate <tier> <trials> |
| Apply config changes | /pokelootweights reload |
Recipe to change a chance: edit the entry's weight in the JSON, run /pokelootweights reload,
then check it with /pokelootweights info <tier>. Reload warnings are shown in chat.
Configuration¶
config/pokelootweights/pokeloot_weights.json. /pokelootweights reload applies changes with
no restart.
{
"enabled": true,
"hidden-chest-tier-weights": { "tier1": 51, "tier2": 34, "tier3": 15, "ultraSpace": 0 },
"tiers": {
"tier3": {
"rolls": { "min": 1, "max": 2 },
"entries": [
{ "weight": 1, "item": { "id": "pixelmon:poke_ball",
"components": { "pixelmon:poke_ball": "master_ball" } } },
{ "weight": 40, "item": "pixelmon:rare_candy", "count": { "min": 1, "max": 3 } },
{ "weight": 0, "item": "pixelmon:ability_capsule" }
]
}
}
}
| Field | Meaning |
|---|---|
enabled |
Master switch. false leaves every chest to Pixelmon |
weight |
Relative within the tier, not a percent. Weight 3 in a tier totalling 60 is 5%. 0 keeps the entry in the file but it never drops |
item |
An item id, or {"id": ..., "components": {...}}, the same format as Pixelmon's pokechestdrops.json |
count |
Stack size, a number or {"min": n, "max": n}. Default 1 |
rolls |
How many items one chest gives. Default 1. Rolls are independent, so an item can repeat |
hidden-chest-tier-weights |
Which tier a hidden chest rolls from |
A bare string entry ("pixelmon:rare_candy") counts as weight 1, so a Pixelmon tier list can be
pasted straight in. Adding weight to one entry makes every other entry in that tier rarer.
If the file does not exist, the mod writes one when the server starts, from the server's current PokeLoot lists, every item at weight 1. That keeps the odds exactly as they were.
Data and storage¶
Only the config file.
Troubleshooting¶
| Symptom | Cause | Fix |
|---|---|---|
| Chests drop the old items | Config unreadable, so the mod stood down; or enabled is false |
Run /pokelootweights reload and read the warnings |
| One tier uses stock Pixelmon loot | That tier is missing or has no usable entries | Fix the tier. Other tiers keep working |
| An item never drops | Its id does not exist (entry skipped) or its weight is 0 | Check the reload warnings |
| Hidden chests never give Beast Ball loot | ultraSpace is 0 in hidden-chest-tier-weights |
Expected by default |
Boot lines that show it loaded:
PokeLootWeights: listening for PokeLoot drops.
PokeLootWeights: tier1 loaded with <n> entries, total weight <n>, 1-1 roll(s).
Maintainer notes¶
- The hook is Pixelmon's
PokeLootEvent.GetDropsonPixelmon.EVENT_BUS. It fires after Pixelmon has already picked a drop and before the player gets it, so every decline path keeps Pixelmon's pick. No mixin, no access transformer. Removing the jar restores stock behaviour. - Chests where
PokeChestTileEntity.isCustomDrop()is true are skipped. - The config loads on
ServerStartedEvent, becauseDropItemRegistry's lists only exist after datapacks load. - The permission node is mirrored into Bukkit at startup so it tab-completes in LuckPerms.
- On
main: the starting config came from the datapackpokechest_boss_raid_loot_table_adjustments. Itsdrops/pokechestdrops.jsonwas renamed to.bak-20260803-194915at cutover. The rest of that datapack (Ability Patch and Ability Capsule changes for raids and bosses) is still active and must stay. A full rollback means removing this mod and renaming the backup file back, then/reload. - The live
mainconfig was hand-tuned on the server (Beast Ball tier total 88 to 211). The deploy bundle still has the flat seed, so never push the bundle config over it. Bundle and live copy:manual_uploads/2026-08-03-pokeloot-weights/in the ops repo. scripts/convert_pokeloot_to_weighted.pyin the ops repo turns a Pixelmon drops file into this format.
Building¶
./gradlew build
Output: build/libs/pokelootweights-<version>.jar.
Full command, permission and config tables: Reference.