
BackPackSSS
Custom tiered backpacks with progression crafting, upgrade system and persistent storage — designed for survival servers.
Список изменений
BackPackSSS v1.9 → v1.9.1
Reported symptoms
- The upgrade recipes for backpacks do not behave correctly in the crafting recipe book.
- Players cannot craft the Good Backpack ("Medium", Tier 2) even with the correct materials.
Both symptoms trace back to a single root cause.
BUG-11 (Critical): ExactChoice NBT-lock on the upgrade recipes
File: BackPackSSS.java → registerRecipes()
Root cause
The Tier 2 and Tier 3 recipes used the center ingredient slot ('B') like this:
ItemStack centerItem = backpackManager.createBackpack(1); // freshly generated, no BP_ID yet
...
recipe.setIngredient('B', new RecipeChoice.ExactChoice(centerItem));
RecipeChoice.ExactChoice requires the item placed in the crafting grid to be byte-for-byte
NBT-identical to centerItem (via ItemStack.isSimilar). At the moment registerRecipes()
runs, centerItem only carries BP_TIER_KEY in its PersistentDataContainer — it has never
been opened, so it has no BP_ID_KEY yet.
The problem is BackpackListener#onInteract:
if (!pdc.has(BackpackManager.BP_ID_KEY, PersistentDataType.STRING)) {
UUID newId = UUID.randomUUID();
pdc.set(BackpackManager.BP_ID_KEY, PersistentDataType.STRING, newId.toString());
item.setItemMeta(meta);
}
The very first time a player right-clicks their Weak Backpack to open it (which is the normal
thing every player does), a random BP_ID_KEY is permanently stamped onto that specific
item's NBT. From that point on, the item can never be isSimilar() to the "clean" centerItem
used to register the recipe — every real, previously-used backpack in the world is now a
different NBT snapshot than the one the recipe was built from.
When that happens, Bukkit's own recipe matcher rejects the shape entirely before
BackpackListener#onPrepareCraft (the plugin's own tier-validation handler, which already only
checks BP_TIER_KEY and is correct) ever gets a chance to run:
- The crafting table shows no output at all → "cannot craft the Medium Backpack".
- The recipe-book auto-fill/highlight can't find any inventory item that satisfies the exact NBT requirement, so the upgrade recipe never lights up as craftable even when the player is holding a valid Weak Backpack → "recipe doesn't show/work in the recipe book".
In short: the plugin already had correct validation logic in onPrepareCraft(), but the
ExactChoice ingredient acted as a stricter gate in front of it that silently blocked
everything as soon as any backpack had been used once.
Fix
Replaced the ingredient with a plain MaterialChoice, matching the fallback branch the code
already used when centerItem was null:
recipe.setIngredient('B', new RecipeChoice.MaterialChoice(Material.BUNDLE));
Now Bukkit's matcher only checks "is this a Bundle in the center slot", and the existing
onPrepareCraft() logic (isBackpackTier(center, 1) / isBackpackTier(center, 2)) — which
correctly reads only BP_TIER_KEY and ignores the per-instance BP_ID_KEY — is what actually
decides whether the craft is valid and sets the result. A used backpack, a freshly crafted one,
or one obtained via /backpack give all now work identically as upgrade material. A plain
vanilla Bundle or wrong-tier backpack placed in the center slot still correctly produces no
result.
Files changed
BackPackSSS.java(registerRecipes()), Tier 2 and Tier 3 blocks.
Verification steps for testing
/backpack give 1 <player>→ craft is not required for this check.- Right-click the Weak Backpack to open it once (this stamps
BP_ID_KEY). - Place it in the center of a crafting table with Iron + Redstone around it.
- Confirm the Good Backpack (Tier 2 / "Medium") now appears as the output and can be taken.
- Confirm the recipe is discoverable and highlights correctly in the recipe book.
- Repeat for Tier 2 → Tier 3 with Shulker Shell + Diamond.
Version bumped: 1.9 → 1.9.1 (pom.xml, plugin.yml, config.yml header).
