This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
Upgrades is a BentoBox addon (Paper/Bukkit plugin) that lets island players purchase upgrades using Vault economy. It hooks into BentoBox GameMode addons (BSkyBlock, AcidIsland, CaveBlock, SkyGrid, AOneBlock) and optionally integrates with the Level and Limits addons.
Upgrades runs within the BentoBox system as a plugin/addon to it. For coding, testing, and other patterns, it can and should draw on what other addons and BentoBox itself does. So the wider code base should be utilized when needed. This can be found at https://bentobox.world (GitHub) and the CI system is in https://ci.bentobox.world (CodeMC).
# Build (produces JAR in target/)
mvn clean package
# Run all tests
mvn test
# Run a single test class
mvn test -Dtest=UpgradesAddonTest
# Run a specific test method
mvn test -Dtest=UpgradesAddonTest#testOnEnableJava 21 is required. The surefire plugin is configured with --add-opens flags so tests work with MockBukkit.
UpgradesAddon — Main entry point extending BentoBox's Addon. Lifecycle:
onLoad: loads config, createsSettingsonEnable: iterates all non-disabled GameMode addons, registersPlayerUpgradeCommandin each, createsUpgradesManager, hooks optional soft-deps (Level, Limits, Vault), instantiates and registers allUpgradeobjectsonDisable: async-saves all cachedUpgradesDatato DB
UpgradesManager — Resolves upgrade tiers per-world by merging global defaults with game-mode-specific overrides from Settings. Every public method takes a World to look up the active GameModeAddon name and apply the right tier config.
Settings — Parses config.yml into typed tier maps. Per-upgrade-type maps exist in two layers: default (global) and custom (per game mode). UpgradesManager merges them on each lookup.
Upgrade (abstract) — Base class for all upgrade types. Key contract:
updateUpgradeValue(user, island)— called each time the panel opens; must populateplayerCacheviasetUpgradeValues()andsetOwnDescription()canUpgrade(user, island)— checks island level and Vault balance; override and callsuperdoUpgrade(user, island)— withdraws Vault cost, increments level inUpgradesData; override and callsuperisShowed(user, island)— returnstrueby default; override to hide when maxed out
Concrete subclasses: RangeUpgrade, BlockLimitsUpgrade, EntityLimitsUpgrade, EntityGroupLimitsUpgrade, CommandUpgrade.
UpgradesData — BentoBox DataObject (table UpgradesData) storing a Map<String, Integer> of upgrade name → current level per island (uniqueId = island UUID). Levels start at 1 (first call to getUpgradeLevel inserts 1 via putIfAbsent).
Panel / PanelClick — BentoBox Panel API GUI. Panel.showPanel() iterates registered upgrades, calls updateUpgradeValue, and builds panel items. PanelClick handles the click → canUpgrade → doUpgrade flow.
- Player runs
/[gamemode] upgrades→PlayerUpgradeCommand→ opensPanel - Panel calls
upgrade.updateUpgradeValue()for each registered upgrade (populates per-user cache) - Player clicks an item →
PanelClick.onClick()→upgrade.canUpgrade()→upgrade.doUpgrade()→ panel reopens
- Island upgrade data is memory-cached in
UpgradesAddon.upgradesCache(Map<islandUniqueId, UpgradesData>) and saved async on disable or island uncache. - Per-user
UpgradeValues(islandLevel req, moneyCost, upgradeValue) are stored inUpgrade.playerCache(Map<UUID, UpgradeValues>) and are stale between panel opens. - Soft dependencies (Level, Limits, Vault) are each guarded by
isLevelProvided(),isLimitsProvided(),isVaultProvided(). Block/Entity Limits upgrades are only registered if Limits is present. - Permission-based max level overrides: upgrades check player permissions (e.g.
[gamemode].island.maxrange.[n]) to cap upgrades, taking the highest permission value found. - Tier configs support formula strings for
islandMinLevel,vaultCost, andupgradevalues that can reference%level%,%islandlevel%, and%numberofmembers%.
- Extend
Upgrade, implementupdateUpgradeValue()and overridedoUpgrade()/canUpgrade()/isShowed()as needed - Register an instance via
UpgradesAddon.registerUpgrade()inonEnable() - Add any new config sections to
Settingsand expose them viaUpgradesManager - Add locale keys to
src/main/resources/locales/en-US.yml
When you need to inspect source code for a dependency (e.g., BentoBox, addons):
- Check local Maven repo first:
~/.m2/repository/— sources jars are named*-sources.jar - Check the workspace: Look for sibling directories or Git submodules that may contain the dependency as a local project (e.g.,
../bentoBox,../addon-*) - Check Maven local cache for already-extracted sources before downloading anything
- Only download a jar or fetch from the internet if the above steps yield nothing useful
Prefer reading .java source files directly from a local Git clone over decompiling or extracting a jar.
In general, the latest version of BentoBox should be targeted.
Related projects are checked out as siblings under ~/git/:
Core:
bentobox/— core BentoBox framework
Game modes:
addon-acidisland/— AcidIsland game modeaddon-bskyblock/— BSkyBlock game modeBoxed/— Boxed game mode (expandable box area)CaveBlock/— CaveBlock game modeOneBlock/— AOneBlock game modeSkyGrid/— SkyGrid game modeRaftMode/— Raft survival game modeStrangerRealms/— StrangerRealms game modeBrix/— plot game modeparkour/— Parkour game modeposeidon/— Poseidon game modegg/— gg game mode
Addons:
addon-level/— island level calculationaddon-challenges/— challenges systemaddon-welcomewarpsigns/— warp signsaddon-limits/— block/entity limitsaddon-invSwitcher//invSwitcher/— inventory switcheraddon-biomes//Biomes/— biomes managementBank/— island bankBorder/— world border for islandsChat/— island chatCheckMeOut/— island submission/votingControlPanel/— game mode control panelConverter/— ASkyBlock to BSkyBlock converterDimensionalTrees/— dimension-specific treesdiscordwebhook/— Discord integrationDownloads/— BentoBox downloads siteDragonFights/— per-island ender dragon fightsExtraMobs/— additional mob spawning rulesFarmersDance/— twerking crop growthGravityFlux/— gravity addonGreenhouses-addon/— greenhouse biomesIslandFly/— island flight permissionIslandRankup/— island rankup systemLikes/— island likes/dislikesLimits/— block/entity limitslost-sheep/— lost sheep adventureMagicCobblestoneGenerator/— custom cobblestone generatorPortalStart/— portal-based island startpp/— pp addonRegionerator/— region managementResidence/— residence addonTopBlock/— top ten for OneBlockTwerkingForTrees/— twerking tree growthUpgrades/— island upgrades (Vault)Visit/— island visitingweblink/— web link addonCrowdBound/— CrowdBound addon
Data packs:
BoxedDataPack/— advancement datapack for Boxed
Documentation & tools:
docs/— main documentation sitedocs-chinese/— Chinese documentationdocs-french/— French documentationBentoBoxWorld.github.io/— GitHub Pages sitewebsite/— websitetranslation-tool/— translation tool
Check these for source before any network fetch.
world.bentobox:bentobox→~/git/bentobox/src/