CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/maven-net-kyori--adventure-api

A serverside user interface library for Minecraft: Java Edition

Pending
Overview
Eval results
Files

nbt-data-components.mddocs/

NBT and Data Components

NBT (Named Binary Tag) data handling with serialization support and integration with Minecraft's data component system. Adventure provides comprehensive NBT support for complex data structures.

Capabilities

Binary Tag Holder

Interface for holding and managing NBT binary tag data with serialization support.

/**
 * Holds NBT binary tag data with serialization support
 */
interface BinaryTagHolder extends Examinable {
    /**
     * Gets the binary tag data
     * @return the binary tag
     * @throws IOException if data cannot be read
     */
    @NotNull BinaryTag get() throws IOException;
    
    /**
     * Gets the NBT data as a string representation
     * @return the string representation
     */
    String string();
    
    /**
     * Encodes a binary tag into a holder
     * @param nbt the binary tag to encode
     * @return new binary tag holder
     */
    static BinaryTagHolder encode(BinaryTag nbt);
    
    /**
     * Creates a holder from an NBT string
     * @param string the NBT string
     * @return new binary tag holder
     */
    static BinaryTagHolder of(String string);
    
    /**
     * Creates an empty binary tag holder
     * @return empty holder
     */
    static BinaryTagHolder empty();
}

NBT Component Interface

Base interface for components that display NBT data from various sources.

/**
 * Base interface for components displaying NBT data
 */
interface NBTComponent<C extends NBTComponent<C, B>, B extends NBTComponentBuilder<C, B>> 
    extends BuildableComponent<C, B> {
    
    /**
     * Gets the NBT path expression
     * @return the NBT path
     */
    String nbtPath();
    
    /**
     * Gets whether to interpret NBT as text components
     * @return true if should interpret as components
     */
    boolean interpret();
    
    /**
     * Gets the separator for multiple NBT results
     * @return the separator component or null
     */
    @Nullable Component separator();
    
    /**
     * Sets the NBT path expression
     * @param nbtPath the path
     * @return component with new path
     */
    C nbtPath(String nbtPath);
    
    /**
     * Sets whether to interpret NBT as components
     * @param interpret whether to interpret
     * @return component with new interpret setting
     */
    C interpret(boolean interpret);
    
    /**
     * Sets the separator for multiple NBT results
     * @param separator the separator or null
     * @return component with new separator
     */
    C separator(@Nullable ComponentLike separator);
}

Block NBT Component

Component that displays NBT data from a block at a specific position.

/**
 * Component displaying block NBT data
 */
interface BlockNBTComponent extends NBTComponent<BlockNBTComponent, BlockNBTComponent.Builder> {
    /**
     * Gets the block position
     * @return the position
     */
    Pos pos();
    
    /**
     * Sets the block position
     * @param pos the new position
     * @return component with new position
     */
    BlockNBTComponent pos(Pos pos);
    
    /**
     * Creates a block NBT component
     * @param nbtPath the NBT path
     * @param pos the block position
     * @return new block NBT component
     */
    static BlockNBTComponent blockNBT(String nbtPath, Pos pos);
    
    /**
     * Block position for NBT access
     */
    interface Pos extends Examinable {
        /**
         * Gets the X coordinate
         * @return the X coordinate
         */
        int x();
        
        /**
         * Gets the Y coordinate
         * @return the Y coordinate
         */
        int y();
        
        /**
         * Gets the Z coordinate
         * @return the Z coordinate
         */
        int z();
        
        /**
         * Creates a block position
         * @param x the X coordinate
         * @param y the Y coordinate
         * @param z the Z coordinate
         * @return new position
         */
        static Pos of(int x, int y, int z);
        
        /**
         * Creates an absolute position
         * @param x the X coordinate
         * @param y the Y coordinate
         * @param z the Z coordinate
         * @return new absolute position
         */
        static Pos absolute(int x, int y, int z);
        
        /**
         * Creates a relative position
         * @param x the X offset
         * @param y the Y offset
         * @param z the Z offset
         * @return new relative position
         */
        static Pos relative(int x, int y, int z);
    }
    
    interface Builder extends NBTComponentBuilder<BlockNBTComponent, Builder> {
        /**
         * Sets the block position
         * @param pos the position
         * @return this builder
         */
        Builder pos(Pos pos);
    }
}

Entity NBT Component

Component that displays NBT data from entities matching a selector.

/**
 * Component displaying entity NBT data
 */
interface EntityNBTComponent extends NBTComponent<EntityNBTComponent, EntityNBTComponent.Builder> {
    /**
     * Gets the entity selector
     * @return the selector string
     */
    String selector();
    
    /**
     * Sets the entity selector
     * @param selector the new selector
     * @return component with new selector
     */
    EntityNBTComponent selector(String selector);
    
    /**
     * Creates an entity NBT component
     * @param nbtPath the NBT path
     * @param selector the entity selector
     * @return new entity NBT component
     */
    static EntityNBTComponent entityNBT(String nbtPath, String selector);
    
    interface Builder extends NBTComponentBuilder<EntityNBTComponent, Builder> {
        /**
         * Sets the entity selector
         * @param selector the selector
         * @return this builder
         */
        Builder selector(String selector);
    }
}

Storage NBT Component

Component that displays NBT data from command storage.

/**
 * Component displaying command storage NBT data
 */
interface StorageNBTComponent extends NBTComponent<StorageNBTComponent, StorageNBTComponent.Builder> {
    /**
     * Gets the storage key
     * @return the storage key
     */
    Key storage();
    
    /**
     * Sets the storage key
     * @param storage the new storage key
     * @return component with new storage key
     */
    StorageNBTComponent storage(Key storage);
    
    /**
     * Creates a storage NBT component
     * @param nbtPath the NBT path
     * @param storage the storage key
     * @return new storage NBT component
     */
    static StorageNBTComponent storageNBT(String nbtPath, Key storage);
    
    interface Builder extends NBTComponentBuilder<StorageNBTComponent, Builder> {
        /**
         * Sets the storage key
         * @param storage the storage key
         * @return this builder
         */
        Builder storage(Key storage);
    }
}

NBT Component Builder

Specialized builder interface for NBT components.

/**
 * Specialized builder for NBT components
 */
interface NBTComponentBuilder<C extends NBTComponent<C, B>, B extends NBTComponentBuilder<C, B>> 
    extends ComponentBuilder<C, B> {
    
    /**
     * Sets the NBT path expression
     * @param nbtPath the path
     * @return this builder
     */
    B nbtPath(String nbtPath);
    
    /**
     * Sets whether to interpret NBT as components
     * @param interpret whether to interpret
     * @return this builder
     */
    B interpret(boolean interpret);
    
    /**
     * Sets the separator for multiple NBT results
     * @param separator the separator or null
     * @return this builder
     */
    B separator(@Nullable ComponentLike separator);
}

Usage Examples:

import net.kyori.adventure.text.Component;
import net.kyori.adventure.nbt.api.BinaryTagHolder;
import net.kyori.adventure.key.Key;

// Block NBT component showing a sign's text
Component signText = Component.blockNBT(
    "front_text.messages[0]", 
    BlockNBTComponent.Pos.absolute(100, 64, 200)
);

// Entity NBT component showing player's health
Component playerHealth = Component.entityNBT(
    "Health", 
    "@p"  // Nearest player selector
);

// Storage NBT component from command storage
Component storedValue = Component.storageNBT(
    "custom_data.score",
    Key.key("myserver", "player_data")
);

// NBT component with interpretation and separator
Component inventoryDisplay = Component.blockNBT()
    .nbtPath("Items[].tag.display.Name")
    .pos(BlockNBTComponent.Pos.relative(0, -1, 0))
    .interpret(true)  // Interpret NBT as text components
    .separator(Component.text(", "))
    .build();

// Binary tag holder usage
String nbtString = "{id:\"minecraft:diamond_sword\",Count:1b}";
BinaryTagHolder holder = BinaryTagHolder.of(nbtString);

// Use in hover events
Component itemDisplay = Component.text("Diamond Sword")
    .hoverEvent(HoverEvent.showItem(
        Key.key("minecraft:diamond_sword"), 
        1, 
        holder
    ));

NBT Path Expressions

NBT path expressions allow precise selection of data from NBT structures:

Basic Path Syntax

// Simple field access
"Health"           // Root field
"Inventory[0]"     // Array element
"CustomName"       // String field

// Nested field access  
"tag.display.Name"       // Nested object fields
"Items[0].tag.Damage"    // Array element with nested field
"Attributes[{Name:\"generic.max_health\"}].Base"  // Filtered array access

// Multiple results
"Inventory[].id"         // All item IDs in inventory
"Effects[].Id"           // All potion effect IDs

Advanced Path Examples

public class NBTPathExamples {
    // Player data access
    public static Component getPlayerLevel() {
        return Component.entityNBT("XpLevel", "@s");
    }
    
    public static Component getPlayerGamemode() {
        return Component.entityNBT("playerGameType", "@s");
    }
    
    // Inventory item display
    public static Component getHeldItemName() {
        return Component.entityNBT(
            "SelectedItem.tag.display.Name",
            "@s"
        ).interpret(true);
    }
    
    // Block data access
    public static Component getChestContents(int x, int y, int z) {
        return Component.blockNBT(
            "Items[].tag.display.Name",
            BlockNBTComponent.Pos.absolute(x, y, z)
        ).interpret(true)
         .separator(Component.text(", "));
    }
    
    // Sign text access
    public static Component getSignLine(int x, int y, int z, int line) {
        return Component.blockNBT(
            "front_text.messages[" + line + "]",
            BlockNBTComponent.Pos.absolute(x, y, z)
        ).interpret(true);
    }
    
    // Command storage access
    public static Component getStoredPlayerName(String playerId) {
        return Component.storageNBT(
            "players." + playerId + ".name",
            Key.key("myserver", "playerdata")
        );
    }
}

Data Component Integration

Modern Data Component System

public class DataComponentIntegration {
    // Item data component access
    public static Component getItemName() {
        return Component.entityNBT(
            "SelectedItem.components.\"minecraft:item_name\"",
            "@s"
        ).interpret(true);
    }
    
    public static Component getItemLore() {
        return Component.entityNBT(
            "SelectedItem.components.\"minecraft:lore\"[]",
            "@s"
        ).interpret(true)
         .separator(Component.newline());
    }
    
    // Custom data component
    public static Component getCustomData(String path) {
        return Component.entityNBT(
            "SelectedItem.components.\"minecraft:custom_data\"." + path,
            "@s"
        );
    }
    
    // Enchantment data
    public static Component getEnchantments() {
        return Component.entityNBT(
            "SelectedItem.components.\"minecraft:enchantments\".levels",
            "@s"
        );
    }
}

NBT Data Validation

public class NBTValidator {
    public static boolean isValidNBTPath(String path) {
        // Basic NBT path validation
        if (path == null || path.isEmpty()) {
            return false;
        }
        
        // Check for valid characters and structure
        return path.matches("^[a-zA-Z0-9_.\\[\\]{}\"':@-]+$");
    }
    
    public static boolean isValidSelector(String selector) {
        // Basic entity selector validation
        return selector != null && 
               (selector.startsWith("@") || selector.matches("^[a-zA-Z0-9_-]+$"));
    }
    
    public static BinaryTagHolder sanitizeNBT(BinaryTagHolder holder) {
        try {
            BinaryTag tag = holder.get();
            
            // Validate and sanitize NBT data
            if (isValidNBTStructure(tag)) {
                return holder;
            } else {
                return BinaryTagHolder.empty();
            }
        } catch (IOException e) {
            return BinaryTagHolder.empty();
        }
    }
    
    private static boolean isValidNBTStructure(BinaryTag tag) {
        // Implement NBT structure validation
        // Check for malicious or oversized data
        return true; // Simplified
    }
}

Performance Considerations

NBT Access Optimization

public class NBTOptimization {
    // Cache frequently accessed NBT paths
    private static final Map<String, Component> NBT_CACHE = new ConcurrentHashMap<>();
    
    public static Component getCachedNBT(String cacheKey, Supplier<Component> nbtSupplier) {
        return NBT_CACHE.computeIfAbsent(cacheKey, k -> nbtSupplier.get());
    }
    
    // Batch NBT operations
    public static List<Component> getBatchedBlockNBT(List<BlockNBTRequest> requests) {
        return requests.parallelStream()
            .map(req -> Component.blockNBT(req.path(), req.pos()))
            .collect(Collectors.toList());
    }
    
    // Lazy NBT evaluation
    public static Component createLazyNBT(String path, String selector) {
        return Component.text("[Loading...]")
            .hoverEvent(HoverEvent.showText(
                Component.entityNBT(path, selector)
            ));
    }
    
    // Efficient NBT string building
    public static String buildNBTString(Map<String, Object> data) {
        StringBuilder nbt = new StringBuilder("{");
        boolean first = true;
        
        for (Map.Entry<String, Object> entry : data.entrySet()) {
            if (!first) nbt.append(",");
            nbt.append(entry.getKey()).append(":").append(formatNBTValue(entry.getValue()));
            first = false;
        }
        
        nbt.append("}");
        return nbt.toString();
    }
    
    private static String formatNBTValue(Object value) {
        if (value instanceof String) {
            return "\"" + value + "\"";
        } else if (value instanceof Number) {
            return value.toString();
        } else if (value instanceof Boolean) {
            return value.toString() + "b";
        }
        return "\"" + value + "\"";
    }
}

Best Practices

NBT Path Design

  • Use specific paths to avoid unnecessary data access
  • Validate NBT paths before using them in components
  • Consider client-side performance impact of complex NBT queries
  • Cache frequently accessed NBT data

Security Considerations

  • Validate entity selectors to prevent unauthorized data access
  • Sanitize NBT data from user input
  • Limit NBT path complexity to prevent performance issues
  • Use appropriate permissions for NBT component access

Error Handling

  • Handle missing NBT data gracefully
  • Provide fallback values for optional NBT fields
  • Log NBT access errors for debugging
  • Use empty components when NBT data is unavailable

Performance Optimization

  • Batch NBT operations when possible
  • Use caching for frequently accessed NBT data
  • Avoid deeply nested NBT path expressions
  • Consider using command storage for shared data

Install with Tessl CLI

npx tessl i tessl/maven-net-kyori--adventure-api

docs

audience-system.md

books-and-inventory.md

boss-bars.md

events-and-interactivity.md

index.md

nbt-data-components.md

resource-packs.md

sound-system.md

text-components.md

text-formatting.md

titles-and-subtitles.md

translation-system.md

tile.json