or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

audience-system.mdbooks-and-inventory.mdboss-bars.mdevents-and-interactivity.mdindex.mdnbt-data-components.mdresource-packs.mdsound-system.mdtext-components.mdtext-formatting.mdtitles-and-subtitles.mdtranslation-system.md

nbt-data-components.mddocs/

0

# NBT and Data Components

1

2

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.

3

4

## Capabilities

5

6

### Binary Tag Holder

7

8

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

9

10

```java { .api }

11

/**

12

* Holds NBT binary tag data with serialization support

13

*/

14

interface BinaryTagHolder extends Examinable {

15

/**

16

* Gets the binary tag data

17

* @return the binary tag

18

* @throws IOException if data cannot be read

19

*/

20

@NotNull BinaryTag get() throws IOException;

21

22

/**

23

* Gets the NBT data as a string representation

24

* @return the string representation

25

*/

26

String string();

27

28

/**

29

* Encodes a binary tag into a holder

30

* @param nbt the binary tag to encode

31

* @return new binary tag holder

32

*/

33

static BinaryTagHolder encode(BinaryTag nbt);

34

35

/**

36

* Creates a holder from an NBT string

37

* @param string the NBT string

38

* @return new binary tag holder

39

*/

40

static BinaryTagHolder of(String string);

41

42

/**

43

* Creates an empty binary tag holder

44

* @return empty holder

45

*/

46

static BinaryTagHolder empty();

47

}

48

```

49

50

### NBT Component Interface

51

52

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

53

54

```java { .api }

55

/**

56

* Base interface for components displaying NBT data

57

*/

58

interface NBTComponent<C extends NBTComponent<C, B>, B extends NBTComponentBuilder<C, B>>

59

extends BuildableComponent<C, B> {

60

61

/**

62

* Gets the NBT path expression

63

* @return the NBT path

64

*/

65

String nbtPath();

66

67

/**

68

* Gets whether to interpret NBT as text components

69

* @return true if should interpret as components

70

*/

71

boolean interpret();

72

73

/**

74

* Gets the separator for multiple NBT results

75

* @return the separator component or null

76

*/

77

@Nullable Component separator();

78

79

/**

80

* Sets the NBT path expression

81

* @param nbtPath the path

82

* @return component with new path

83

*/

84

C nbtPath(String nbtPath);

85

86

/**

87

* Sets whether to interpret NBT as components

88

* @param interpret whether to interpret

89

* @return component with new interpret setting

90

*/

91

C interpret(boolean interpret);

92

93

/**

94

* Sets the separator for multiple NBT results

95

* @param separator the separator or null

96

* @return component with new separator

97

*/

98

C separator(@Nullable ComponentLike separator);

99

}

100

```

101

102

### Block NBT Component

103

104

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

105

106

```java { .api }

107

/**

108

* Component displaying block NBT data

109

*/

110

interface BlockNBTComponent extends NBTComponent<BlockNBTComponent, BlockNBTComponent.Builder> {

111

/**

112

* Gets the block position

113

* @return the position

114

*/

115

Pos pos();

116

117

/**

118

* Sets the block position

119

* @param pos the new position

120

* @return component with new position

121

*/

122

BlockNBTComponent pos(Pos pos);

123

124

/**

125

* Creates a block NBT component

126

* @param nbtPath the NBT path

127

* @param pos the block position

128

* @return new block NBT component

129

*/

130

static BlockNBTComponent blockNBT(String nbtPath, Pos pos);

131

132

/**

133

* Block position for NBT access

134

*/

135

interface Pos extends Examinable {

136

/**

137

* Gets the X coordinate

138

* @return the X coordinate

139

*/

140

int x();

141

142

/**

143

* Gets the Y coordinate

144

* @return the Y coordinate

145

*/

146

int y();

147

148

/**

149

* Gets the Z coordinate

150

* @return the Z coordinate

151

*/

152

int z();

153

154

/**

155

* Creates a block position

156

* @param x the X coordinate

157

* @param y the Y coordinate

158

* @param z the Z coordinate

159

* @return new position

160

*/

161

static Pos of(int x, int y, int z);

162

163

/**

164

* Creates an absolute position

165

* @param x the X coordinate

166

* @param y the Y coordinate

167

* @param z the Z coordinate

168

* @return new absolute position

169

*/

170

static Pos absolute(int x, int y, int z);

171

172

/**

173

* Creates a relative position

174

* @param x the X offset

175

* @param y the Y offset

176

* @param z the Z offset

177

* @return new relative position

178

*/

179

static Pos relative(int x, int y, int z);

180

}

181

182

interface Builder extends NBTComponentBuilder<BlockNBTComponent, Builder> {

183

/**

184

* Sets the block position

185

* @param pos the position

186

* @return this builder

187

*/

188

Builder pos(Pos pos);

189

}

190

}

191

```

192

193

### Entity NBT Component

194

195

Component that displays NBT data from entities matching a selector.

196

197

```java { .api }

198

/**

199

* Component displaying entity NBT data

200

*/

201

interface EntityNBTComponent extends NBTComponent<EntityNBTComponent, EntityNBTComponent.Builder> {

202

/**

203

* Gets the entity selector

204

* @return the selector string

205

*/

206

String selector();

207

208

/**

209

* Sets the entity selector

210

* @param selector the new selector

211

* @return component with new selector

212

*/

213

EntityNBTComponent selector(String selector);

214

215

/**

216

* Creates an entity NBT component

217

* @param nbtPath the NBT path

218

* @param selector the entity selector

219

* @return new entity NBT component

220

*/

221

static EntityNBTComponent entityNBT(String nbtPath, String selector);

222

223

interface Builder extends NBTComponentBuilder<EntityNBTComponent, Builder> {

224

/**

225

* Sets the entity selector

226

* @param selector the selector

227

* @return this builder

228

*/

229

Builder selector(String selector);

230

}

231

}

232

```

233

234

### Storage NBT Component

235

236

Component that displays NBT data from command storage.

237

238

```java { .api }

239

/**

240

* Component displaying command storage NBT data

241

*/

242

interface StorageNBTComponent extends NBTComponent<StorageNBTComponent, StorageNBTComponent.Builder> {

243

/**

244

* Gets the storage key

245

* @return the storage key

246

*/

247

Key storage();

248

249

/**

250

* Sets the storage key

251

* @param storage the new storage key

252

* @return component with new storage key

253

*/

254

StorageNBTComponent storage(Key storage);

255

256

/**

257

* Creates a storage NBT component

258

* @param nbtPath the NBT path

259

* @param storage the storage key

260

* @return new storage NBT component

261

*/

262

static StorageNBTComponent storageNBT(String nbtPath, Key storage);

263

264

interface Builder extends NBTComponentBuilder<StorageNBTComponent, Builder> {

265

/**

266

* Sets the storage key

267

* @param storage the storage key

268

* @return this builder

269

*/

270

Builder storage(Key storage);

271

}

272

}

273

```

274

275

### NBT Component Builder

276

277

Specialized builder interface for NBT components.

278

279

```java { .api }

280

/**

281

* Specialized builder for NBT components

282

*/

283

interface NBTComponentBuilder<C extends NBTComponent<C, B>, B extends NBTComponentBuilder<C, B>>

284

extends ComponentBuilder<C, B> {

285

286

/**

287

* Sets the NBT path expression

288

* @param nbtPath the path

289

* @return this builder

290

*/

291

B nbtPath(String nbtPath);

292

293

/**

294

* Sets whether to interpret NBT as components

295

* @param interpret whether to interpret

296

* @return this builder

297

*/

298

B interpret(boolean interpret);

299

300

/**

301

* Sets the separator for multiple NBT results

302

* @param separator the separator or null

303

* @return this builder

304

*/

305

B separator(@Nullable ComponentLike separator);

306

}

307

```

308

309

**Usage Examples:**

310

311

```java

312

import net.kyori.adventure.text.Component;

313

import net.kyori.adventure.nbt.api.BinaryTagHolder;

314

import net.kyori.adventure.key.Key;

315

316

// Block NBT component showing a sign's text

317

Component signText = Component.blockNBT(

318

"front_text.messages[0]",

319

BlockNBTComponent.Pos.absolute(100, 64, 200)

320

);

321

322

// Entity NBT component showing player's health

323

Component playerHealth = Component.entityNBT(

324

"Health",

325

"@p" // Nearest player selector

326

);

327

328

// Storage NBT component from command storage

329

Component storedValue = Component.storageNBT(

330

"custom_data.score",

331

Key.key("myserver", "player_data")

332

);

333

334

// NBT component with interpretation and separator

335

Component inventoryDisplay = Component.blockNBT()

336

.nbtPath("Items[].tag.display.Name")

337

.pos(BlockNBTComponent.Pos.relative(0, -1, 0))

338

.interpret(true) // Interpret NBT as text components

339

.separator(Component.text(", "))

340

.build();

341

342

// Binary tag holder usage

343

String nbtString = "{id:\"minecraft:diamond_sword\",Count:1b}";

344

BinaryTagHolder holder = BinaryTagHolder.of(nbtString);

345

346

// Use in hover events

347

Component itemDisplay = Component.text("Diamond Sword")

348

.hoverEvent(HoverEvent.showItem(

349

Key.key("minecraft:diamond_sword"),

350

1,

351

holder

352

));

353

```

354

355

## NBT Path Expressions

356

357

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

358

359

### Basic Path Syntax

360

361

```java

362

// Simple field access

363

"Health" // Root field

364

"Inventory[0]" // Array element

365

"CustomName" // String field

366

367

// Nested field access

368

"tag.display.Name" // Nested object fields

369

"Items[0].tag.Damage" // Array element with nested field

370

"Attributes[{Name:\"generic.max_health\"}].Base" // Filtered array access

371

372

// Multiple results

373

"Inventory[].id" // All item IDs in inventory

374

"Effects[].Id" // All potion effect IDs

375

```

376

377

### Advanced Path Examples

378

379

```java

380

public class NBTPathExamples {

381

// Player data access

382

public static Component getPlayerLevel() {

383

return Component.entityNBT("XpLevel", "@s");

384

}

385

386

public static Component getPlayerGamemode() {

387

return Component.entityNBT("playerGameType", "@s");

388

}

389

390

// Inventory item display

391

public static Component getHeldItemName() {

392

return Component.entityNBT(

393

"SelectedItem.tag.display.Name",

394

"@s"

395

).interpret(true);

396

}

397

398

// Block data access

399

public static Component getChestContents(int x, int y, int z) {

400

return Component.blockNBT(

401

"Items[].tag.display.Name",

402

BlockNBTComponent.Pos.absolute(x, y, z)

403

).interpret(true)

404

.separator(Component.text(", "));

405

}

406

407

// Sign text access

408

public static Component getSignLine(int x, int y, int z, int line) {

409

return Component.blockNBT(

410

"front_text.messages[" + line + "]",

411

BlockNBTComponent.Pos.absolute(x, y, z)

412

).interpret(true);

413

}

414

415

// Command storage access

416

public static Component getStoredPlayerName(String playerId) {

417

return Component.storageNBT(

418

"players." + playerId + ".name",

419

Key.key("myserver", "playerdata")

420

);

421

}

422

}

423

```

424

425

## Data Component Integration

426

427

### Modern Data Component System

428

429

```java

430

public class DataComponentIntegration {

431

// Item data component access

432

public static Component getItemName() {

433

return Component.entityNBT(

434

"SelectedItem.components.\"minecraft:item_name\"",

435

"@s"

436

).interpret(true);

437

}

438

439

public static Component getItemLore() {

440

return Component.entityNBT(

441

"SelectedItem.components.\"minecraft:lore\"[]",

442

"@s"

443

).interpret(true)

444

.separator(Component.newline());

445

}

446

447

// Custom data component

448

public static Component getCustomData(String path) {

449

return Component.entityNBT(

450

"SelectedItem.components.\"minecraft:custom_data\"." + path,

451

"@s"

452

);

453

}

454

455

// Enchantment data

456

public static Component getEnchantments() {

457

return Component.entityNBT(

458

"SelectedItem.components.\"minecraft:enchantments\".levels",

459

"@s"

460

);

461

}

462

}

463

```

464

465

### NBT Data Validation

466

467

```java

468

public class NBTValidator {

469

public static boolean isValidNBTPath(String path) {

470

// Basic NBT path validation

471

if (path == null || path.isEmpty()) {

472

return false;

473

}

474

475

// Check for valid characters and structure

476

return path.matches("^[a-zA-Z0-9_.\\[\\]{}\"':@-]+$");

477

}

478

479

public static boolean isValidSelector(String selector) {

480

// Basic entity selector validation

481

return selector != null &&

482

(selector.startsWith("@") || selector.matches("^[a-zA-Z0-9_-]+$"));

483

}

484

485

public static BinaryTagHolder sanitizeNBT(BinaryTagHolder holder) {

486

try {

487

BinaryTag tag = holder.get();

488

489

// Validate and sanitize NBT data

490

if (isValidNBTStructure(tag)) {

491

return holder;

492

} else {

493

return BinaryTagHolder.empty();

494

}

495

} catch (IOException e) {

496

return BinaryTagHolder.empty();

497

}

498

}

499

500

private static boolean isValidNBTStructure(BinaryTag tag) {

501

// Implement NBT structure validation

502

// Check for malicious or oversized data

503

return true; // Simplified

504

}

505

}

506

```

507

508

## Performance Considerations

509

510

### NBT Access Optimization

511

512

```java

513

public class NBTOptimization {

514

// Cache frequently accessed NBT paths

515

private static final Map<String, Component> NBT_CACHE = new ConcurrentHashMap<>();

516

517

public static Component getCachedNBT(String cacheKey, Supplier<Component> nbtSupplier) {

518

return NBT_CACHE.computeIfAbsent(cacheKey, k -> nbtSupplier.get());

519

}

520

521

// Batch NBT operations

522

public static List<Component> getBatchedBlockNBT(List<BlockNBTRequest> requests) {

523

return requests.parallelStream()

524

.map(req -> Component.blockNBT(req.path(), req.pos()))

525

.collect(Collectors.toList());

526

}

527

528

// Lazy NBT evaluation

529

public static Component createLazyNBT(String path, String selector) {

530

return Component.text("[Loading...]")

531

.hoverEvent(HoverEvent.showText(

532

Component.entityNBT(path, selector)

533

));

534

}

535

536

// Efficient NBT string building

537

public static String buildNBTString(Map<String, Object> data) {

538

StringBuilder nbt = new StringBuilder("{");

539

boolean first = true;

540

541

for (Map.Entry<String, Object> entry : data.entrySet()) {

542

if (!first) nbt.append(",");

543

nbt.append(entry.getKey()).append(":").append(formatNBTValue(entry.getValue()));

544

first = false;

545

}

546

547

nbt.append("}");

548

return nbt.toString();

549

}

550

551

private static String formatNBTValue(Object value) {

552

if (value instanceof String) {

553

return "\"" + value + "\"";

554

} else if (value instanceof Number) {

555

return value.toString();

556

} else if (value instanceof Boolean) {

557

return value.toString() + "b";

558

}

559

return "\"" + value + "\"";

560

}

561

}

562

```

563

564

## Best Practices

565

566

### NBT Path Design

567

- Use specific paths to avoid unnecessary data access

568

- Validate NBT paths before using them in components

569

- Consider client-side performance impact of complex NBT queries

570

- Cache frequently accessed NBT data

571

572

### Security Considerations

573

- Validate entity selectors to prevent unauthorized data access

574

- Sanitize NBT data from user input

575

- Limit NBT path complexity to prevent performance issues

576

- Use appropriate permissions for NBT component access

577

578

### Error Handling

579

- Handle missing NBT data gracefully

580

- Provide fallback values for optional NBT fields

581

- Log NBT access errors for debugging

582

- Use empty components when NBT data is unavailable

583

584

### Performance Optimization

585

- Batch NBT operations when possible

586

- Use caching for frequently accessed NBT data

587

- Avoid deeply nested NBT path expressions

588

- Consider using command storage for shared data