This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
Expendable Backpacks is a Paper/Spigot plugin for Minecraft 1.21.1+ featuring eight backpack tiers with progressive storage capacity (9-54 slots). The plugin includes a unique Enderpack system for shared storage across multiple backpack instances.
Core Technologies:
- Java 21
- Paper API 1.21.10
- Gradle build system with Shadow plugin
- Google Java Style (enforced via Checkstyle)
- SpotBugs with FindSecBugs for static analysis
# Build the plugin (runs tests, checkstyle, spotbugs)
./gradlew build
# Build without running tests
./gradlew assemble
# Run only tests
./gradlew test
# Run only checkstyle
./gradlew checkstyleMain checkstyleTest
# Run only spotbugs
./gradlew spotbugsMain spotbugsTest
# Create release JAR (removes version suffix)
./gradlew release
# Clean build directory
./gradlew cleanThe final plugin JAR is located at build/libs/ExpendableBackpacks-<version>.jar after building.
Set up a local test server:
- Place the built JAR in
test-server/plugins/ - Start the Paper server from the
test-server/directory - The plugin data will be stored in
test-server/plugins/ExpendableBackpacks/
Note: There are currently no unit tests in this project. All testing is manual via the test server.
The plugin uses a UUID-based storage model where each backpack instance has a unique identifier stored in its PersistentDataContainer. This is critical for understanding how the system works:
-
BackpackManager (
storage/BackpackManager.java) - Central storage controller- Maintains in-memory cache of loaded inventories (
Map<UUID, Inventory>) - Handles YAML serialization/deserialization (
backpacks.yml) - Auto-saves backpack contents when modified
- Handles inventory resizing during upgrades
- Maintains in-memory cache of loaded inventories (
-
BackpackItem (
items/BackpackItem.java) - Item factory and validator- Creates backpack items with custom player head textures
- Stores UUID and tier level in NBT data (PersistentDataContainer)
- Provides utility methods:
isBackpack(),getBackpackUUID(),getBackpackTier() - Supports cloning (same UUID) and upgrading (preserves UUID, changes tier)
Enderpacks are special backpacks that enable shared storage across multiple physical items:
- Multiple Enderpack items can share the same UUID
- When opened, all Enderpacks with the same UUID access the same inventory
- Cloning recipe: 1 Enderpack + 1 Ender Pearl → 2 Enderpacks (same UUID)
- Implementation:
BackpackCraftingListenerdetects cloning recipes and preserves UUID
Eight tiers defined in BackpackTier enum with progression:
- Dirt (9 slots) - downgrade tier
- Leather (9 slots) - starting tier
- Copper (18 slots)
- Iron (27 slots)
- Gold (36 slots)
- Diamond (45 slots)
- Netherite (54 slots) - uses smithing table
- Enderpack (27 slots) - special shared storage
Upgrade Mechanism:
- Crafting table upgrades: Surround backpack with 8x upgrade material
- Smithing table: Diamond → Netherite (uses upgrade template)
- UUID is preserved during upgrades
- BackpackManager automatically resizes inventory when tier changes
The plugin uses multiple specialized listeners:
- BackpackInteractionListener - Handles right-click to open backpacks, auto-saves on close
- BackpackCraftingListener - Processes upgrade recipes, manages UUID preservation, handles Enderpack cloning
- BackpackSmithingListener - Handles Netherite upgrade via smithing table
- BackpackProtectionListener - Prevents backpacks from being placed inside other backpacks (inception protection)
- BackpackGuideGUI - Interactive GUI showing all recipes and tier information
Initialization (onEnable):
- Initialize BackpackItem factory (static initialization with plugin instance)
- Create BackpackManager and load all backpacks from YAML
- Register all crafting recipes via BackpackRecipes
- Register event listeners
- Register commands and tab completers
Shutdown (onDisable):
- BackpackManager saves all loaded inventories to YAML
- All backpack data persists across server restarts
This project enforces Google Java Style with strict quality checks:
- Checkstyle: Google Java Style with 100-character line limit, no warnings allowed (
maxWarnings = 0) - SpotBugs: Static analysis with FindSecBugs security plugin
- Javadoc: Required for all protected/public classes and methods
- Naming conventions:
- Variables containing "UUID" require
@SuppressWarnings("checkstyle:AbbreviationAsWordInName") - Exposed fields/methods require
@SuppressWarnings("EI_EXPOSE_REP")or"EI_EXPOSE_REP2"
- Variables containing "UUID" require
When adding new backpack features:
- Always preserve UUIDs when modifying existing backpacks
- Immediately save to YAML when creating new backpack instances
- Use BackpackItem factory methods (never construct ItemStacks directly)
- Add proper checks in BackpackProtectionListener if introducing new backpack types
The plugin uses plugin.yml for metadata and commands. Version is auto-injected during build via Gradle's processResources task:
expand( NAME: rootProject.name, VERSION: version, PACKAGE: rootProject.group )Override version at build time: ./gradlew build -Pver=x.y.z