Understanding Minestom Tags System
Concept explanation of how Tags provide type-safe custom data storage using NBT
java (17+)
2025-11-03
minestom
tags
nbt
data
concepts
Description
Minestom’s Tags system provides a type-safe way to store custom data on entities, items, blocks, and other objects using NBT (Named Binary Tag) format. Tags are efficient, persistent, and allow you to attach custom properties without modifying core classes.
Key Concepts
What are Tags?
Tags are typed key-value pairs that can be attached to various objects:
- Entities: Store custom entity properties
- Items: Store item metadata and custom data
- Blocks: Store block state and custom properties
- Other objects: Any object implementing TagReadable/TagWritable
NBT Format
Tags use NBT (Named Binary Tag) format, which is:
- Efficient: Compact binary representation
- Persistent: Can be saved to disk
- Type-safe: Strong typing prevents errors
- Compatible: Works with Minecraft’s NBT system
Tag Types
- String: Text data
- Integer: Whole numbers
- Double: Decimal numbers
- Float: Floating point numbers
- Boolean: True/false values
- Byte/Short/Long: Various integer sizes
- Compound: Nested tag structures
- List: Arrays of tags
Tag Interfaces
- TagReadable: Objects that can read tags
- TagWritable: Objects that can write tags
- Most entities, items, and blocks implement both
Tag Lifecycle
- Create tag: Define tag with type and name
- Set tag: Store value on object
- Get tag: Retrieve value from object
- Check tag: Verify tag exists
- Remove tag: Delete tag from object
- Serialize: Tags are automatically serialized with objects
Persistence
- Tags are automatically saved with entities/items
- Survive server restarts (if configured)
- Can be exported/imported
- Compatible with Minecraft’s save format
Use Cases
- Entity properties: Store custom entity data (health, level, etc.)
- Item metadata: Store item-specific data (durability, enchantments)
- Block state: Store custom block properties
- Player data: Store player-specific information
- Game state: Track game-specific data
Benefits
- Type safety: Compile-time type checking
- Efficiency: Optimized NBT storage
- Persistence: Automatic saving/loading
- Flexibility: Store any type of data
- Compatibility: Works with Minecraft’s data format
Best Practices
- Use descriptive tag names (namespace them: “plugin:tag_name”)
- Store tags as static final fields for reuse
- Check for null when reading tags
- Use appropriate types (don’t store numbers as strings)
- Clean up unused tags
- Document tag usage in your code
- Consider tag size (large compounds can be expensive)
Code
// Creating tagsTag<String> nameTag = Tag.String("custom_name");Tag<Integer> levelTag = Tag.Integer("player_level");Tag<Double> balanceTag = Tag.Double("player_balance");Tag<Boolean> isVipTag = Tag.Boolean("is_vip");// Setting tags (on objects that implement TagWritable)Player player = // ... get playerif (player instanceof TagWritable writable) { writable.setTag(nameTag, "CustomPlayer"); writable.setTag(levelTag, 50); writable.setTag(balanceTag, 1000.0); writable.setTag(isVipTag, true);}// Reading tags (on objects that implement TagReadable)if (player instanceof TagReadable readable) { String name = readable.getTag(nameTag); // May return null Integer level = readable.getTag(levelTag); Double balance = readable.getTag(balanceTag); Boolean isVip = readable.getTag(isVipTag);}// Checking if tag existsif (player instanceof TagReadable readable) { if (readable.hasTag(levelTag)) { // Tag exists }}// Removing tagsif (player instanceof TagWritable writable) { writable.removeTag(levelTag);}// Using tags in custom entity classpublic class CustomEntity extends EntityLiving { private static final Tag<String> CUSTOM_DATA = Tag.String("custom_data"); private static final Tag<Integer> CUSTOM_LEVEL = Tag.Integer("custom_level"); public void setCustomData(String data) { setTag(CUSTOM_DATA, data); } public String getCustomData() { return getTag(CUSTOM_DATA); } public void setCustomLevel(int level) { setTag(CUSTOM_LEVEL, level); } public int getCustomLevel() { Integer level = getTag(CUSTOM_LEVEL); return level != null ? level : 0; }}// Tags persist across server restarts (if entity is saved)// Tags are automatically serialized with entity data// Tags use efficient NBT format for storage
Comments
No comments yet. Be the first to comment!
Please login to leave a comment.