Items
Build items with modern material names on every version, identify custom items reliably and store item data.
Items.of(bloom) returns the item service. It needs the bloom-items module.
Building items
Items items = Items.of(bloom);
ItemStack sword = items.builder("DIAMOND_SWORD")
.name("&dBlossom Blade")
.lore("&7Owner: &f{owner}", "&7Forged under falling petals.")
.placeholders(Placeholder.of("owner", player.getName()))
.enchant("sharpness", 5) // modern key; "DAMAGE_ALL" works too
.flags(ItemFlagKey.HIDE_ENCHANTS)
.unbreakable(true)
.glow()
.build();
player.getInventory().addItem(sword);Names and lore use the plugin's text format (see Messaging) and render white and
non-italic unless you colour them, on every version. enchant accepts modern keys (sharpness) and legacy Bukkit
names (DAMAGE_ALL); enchantments a server does not know are skipped with a warning.
| Method | Needs |
|---|---|
name, lore, addLore, amount, enchant, glow, placeholders, format, meta | nothing |
flags | ITEM_FLAGS (1.8+) |
unbreakable | UNBREAKABLE_ITEMS |
customModelData | CUSTOM_MODEL_DATA (modern) |
data, customId | PERSISTENT_DATA_CONTAINER or ITEM_NBT_TAGS |
glow() uses the native enchantment glint on modern Paper. On 1.8 it adds a hidden enchantment; on 1.7.10, which has
no item flags, that enchantment is visible in the tooltip.
Material names
Write modern (1.13+) names everywhere. On legacy servers Bloom maps them to the old material and data value with
a built-in table of more than 200 entries: coloured wool, glass, terracotta and carpet, dyes, woods, stone variants,
flowers, heads, fish and renamed items. Legacy names and NAME:DATA are accepted too.
Items items = Items.of(bloom);
ItemStack wool = items.create("RED_WOOL", 16).orElseThrow(IllegalStateException::new); // WOOL:14 on 1.8
ItemStack head = items.builder("PLAYER_HEAD").build(); // SKULL_ITEM:3 on 1.8
boolean hasCopper = items.exists("COPPER_INGOT"); // false on 1.8, true on modern Paper
// Your own keys, for items that differ between versions:
items.materials().register("SHOP_ICON", "AMETHYST_SHARD", "DIAMOND", 0);
ItemStack icon = items.builder("SHOP_ICON").name("&dShop").build();Ambiguous names follow their modern meaning on every server: MELON is the block (MELON_BLOCK on 1.8) and MAP
is the empty map. Potions, spawn eggs and banners changed how they store their type and are not mapped; build them
with meta(...) for each version you support.
Custom items
Items items = Items.of(bloom);
CustomItem ruby =
items.define("ruby", items.builder("RED_DYE").name("&cRuby").glow());
player.getInventory().addItem(ruby.create(3));
if (ruby.matches(inHand)) { // checks persistent data, not the name: look-alikes with the same name don't match
player.sendMessage("That's a real ruby.");
}
Optional<CustomItem> any = items.match(inHand); // which custom item is this, if any?Custom ids live in the item's persistent data under your plugin's namespace (its lowercase name), so items keep them
when renamed in an anvil, stored in chests or carried across restarts. Ids use lowercase letters, digits, ., _
and -.
Item data
Items items = Items.of(bloom);
ItemStack tagged = items.setData(stack, "upgrade-level", "3"); // returns a copy
int level = Integer.parseInt(items.getData(tagged, "upgrade-level").orElse("0"));
ItemStack plain = items.removeData(tagged, "upgrade-level");All data methods return a copy; the original stack is unchanged.
Serialization
Items items = Items.of(bloom);
String stored = items.serialize(stack); // "paper:..." on modern servers, "bukkit:..." on legacy servers
ItemStack restored = items.deserialize(stored);Use this to keep items in a database or config. The format depends on the platform family (Paper's byte format on modern servers, Bukkit object streams on legacy servers), and items cannot move between the two families.
Version-specific features
ItemBuilder builder = Items.of(bloom).builder("STICK").name("&6Magic wand");
if (bloom.has(Capability.CUSTOM_MODEL_DATA)) {
builder.customModelData(4201); // resource-pack model on modern servers
}
return builder.build();