Skip to content

Commit ed6bf06

Browse files
fix: misc improvements (#535)
* Cleanup data components page * Fixup small mistake * Fix minor spelling * Small changes * Apply suggestions from code review --------- Co-authored-by: Matouš Kučera <mk@kcra.me>
1 parent 12382fb commit ed6bf06

File tree

1 file changed

+79
-68
lines changed

1 file changed

+79
-68
lines changed
Lines changed: 79 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -1,142 +1,150 @@
11
---
22
slug: /dev/data-component-api
3-
description: A guide to the ItemStack DataComponentAPI
3+
description: A guide to the ItemStack data component API.
44
---
55

66
# Data Component API
77

88
:::danger[Experimental]
9-
The DataComponent API is currently experimental, and is additionally subject to change across versions.
9+
10+
The data component API is currently experimental, and is additionally subject to change across versions.
11+
1012
:::
1113

12-
The Data Component API provides a version-specific, programmatic interface for accessing and manipulating item data that is otherwise not representable by the `ItemMeta` API. Through this API, you can read and write properties of an item—called "data components"—in a stable and object-oriented manner.
14+
The data component API provides a version-specific interface for accessing and manipulating item data that is otherwise not representable by the `ItemMeta` API.
15+
Through this API, you can read and modify properties of an item, so called data components, in a stable and object-oriented manner.
16+
1317

1418
## Introduction
1519

16-
### What is a Data Component?
20+
### What is a data component?
1721
A data component represents a piece of data associated with an item. Vanilla items can have properties such as custom model data, container loot contents, banner patterns, or potion effects.
22+
1823
### Structure
1924
![Component Structure](assets/data-component-api-tree.png)
20-
See implementation [here](#example-cool-sword)
25+
For implementation details, [click here](#example-cool-sword).
2126

22-
#### The Prototype (Default Values)
27+
#### The prototype (default values)
2328
Items come with an initial set of components that we call the prototype.
2429
These components are defined on the `ItemType` of the `ItemStack`. They control the base behavior
2530
of the item, representing a brand new item without any modifications.
2631

2732
The prototype gives items their initial properties such as if they are food, a tool, a weapon, etc.
2833

29-
#### The Patch
34+
#### The patch
3035
The patch represents the modifications made to the item. This may include giving it a custom name,
3136
modifying the enchantments, damaging it, or adding to the lore. The patch is applied ontop of the prototype,
3237
allowing us to make modifications to an item.
3338

34-
The patch also allows for removing components that were previously in the prototype, this is shown by
39+
The patch also allows for removing components that were previously in the prototype. This is shown by
3540
the `minecraft:tool` example in red. We are removing this component, so this sword item will no longer
36-
break cobweb / other sword blocks faster.
41+
break cobweb or other sword blocks faster.
3742

3843
We can also add new components, as seen from the new `minecraft:enchantment_glint_override` component, which
39-
allows us to make it appear with a glint.
44+
allows us to make it appear as if it were enchanted.
4045

4146

42-
## Differences Compared to `ItemMeta`
47+
## Differences compared to `ItemMeta`
4348

44-
The `ItemMeta` API provides methods to modify `ItemStack`s in a hierarchical manner, such `CompassMeta` allowing you to modify the components of a `minecraft:compass`.
45-
While `ItemMeta` is still very useful, it does not properly represent this new prototype/patch relationship that Minecraft items now use.
49+
The `ItemMeta` API provides methods to modify `ItemStack`s in a hierarchical manner, such as `CompassMeta`, which allows you to modify the components of a `minecraft:compass`.
50+
While `ItemMeta` is still very useful, it does not properly represent the prototype/patch relationship that Minecraft items use.
4651

47-
### Key Differences
52+
### Key differences
4853

49-
#### Expanded Data Model
50-
The Data Component API exposes a much broader and more detailed set of item properties than `ItemMeta`.
51-
DataComponents allow the entire component to be modified in a fashion that better represents how Minecraft does item modifications.
54+
#### Expanded data model
55+
The data component API exposes a much broader and more detailed set of item properties than `ItemMeta`.
56+
Data components allow the entire item to be modified in a fashion that better represents how Minecraft does item modifications.
5257

53-
#### Version-Specific
54-
The Data Component API is designed to adapt to version changes. The Data Component API may experience breaking changes on version updates as Minecraft makes changes to components.
58+
#### Version-specific
59+
The data component API is designed to adapt to version changes. The data component API may experience breaking changes on version updates as Minecraft makes changes to components.
5560
Backwards compatibility is not promised.
5661

57-
Because ItemMeta is represented in a different format, breaking changes made to components by Mojang may not result in breaking changes to `ItemMeta`.
62+
Because `ItemMeta` is represented in a different format, breaking changes made to components by Mojang may not result in breaking changes to `ItemMeta`.
5863

59-
#### Builders and Immutability
64+
#### Builders and immutability
6065
Many complex data components require a builder approach for construction and editing. All data types that are returned by the api are also immutable, so they will not directly modify the component.
6166

62-
#### Patch-Only
63-
ItemMeta represents the patch of an ItemStack only. This means that you cannot get the original properties (prototype) of the ItemStack, such as its default
67+
#### Patch-only
68+
`ItemMeta` only represents the patch of an `ItemStack`. This means that you cannot get the original properties (prototype) of the `ItemStack`, such as its default
6469
durability or default attributes.
6570

66-
#### No Snapshot
67-
Currently, ItemMeta represents a *Snapshot* of an ItemStack's patched map.
71+
#### No snapshots
72+
Currently, `ItemMeta` represents a **snapshot** of an `ItemStack`'s patched map.
6873
This is expensive as it requires the entire patch to be read, even values that you may not be using.
6974

70-
The DataComponent API integrates directly with `ItemStack`. Although conceptually similar, the Data Component API focuses on explicit, strongly typed data retrieval and updates without this additional overhead.
75+
The data component API integrates directly with `ItemStack`. Although conceptually similar, the data component API focuses on explicit, strongly typed data retrieval and updates without this additional overhead.
7176

7277
### When should I use `DataComponents` or `ItemMeta`?
73-
#### `ItemMeta`
74-
- Simple changes to `ItemStacks`
75-
- Keep the most version compatibility with your plugin
76-
#### `DataComponent`
77-
- More complicated `ItemStack` modifications
78+
79+
You would want to use `ItemMeta` if you:
80+
- Are doing only simple changes to `ItemStack`s
81+
- Want to keep cross-version compatibility with your plugin
82+
83+
You would want to use data components if you:
84+
- Want more complicated `ItemStack` modifications
7885
- Do not care about cross-version compatibility
7986
- Want to access default (prototype) values
80-
- Want to remove components from an ItemStack's prototype
87+
- Want to remove components from an `ItemStack`'s prototype
88+
8189

82-
## Basic Usage
83-
The DataComponent API will fetch values according to the behavior seen in game. So, if the patch removes the `minecraft:tool` component,
90+
## Basic usage
91+
The data component API will fetch values according to the behavior seen in game. So, if the patch removes the `minecraft:tool` component,
8492
trying to get that component will return null.
8593

86-
### Getting a Default (Prototype) value
94+
### Retrieving a prototype value
8795

8896
```java
8997
// Get the default durability of diamond sword
9098
int defaultDurability = Material.DIAMOND_SWORD.getDefaultData(DataComponentTypes.MAX_DAMAGE)
9199
```
92100

93-
### Checking for a Data Component
101+
### Checking for a data component
94102

95103
```java
96104
// Check if this item has a custom name data component
97105
boolean hasCustomName = stack.hasData(DataComponentTypes.CUSTOM_NAME);
98-
System.out.println("Has custom name? " + hasCustomName);
106+
logger.info("Has custom name? " + hasCustomName);
99107
```
100108

101-
### Getting a Valued Data Component
109+
### Reading a valued data component
102110

103111
```java
104-
// Suppose we want to read the damage (durability) of an item
112+
// The damage of an item can be null, so we require a null check
105113
Integer damageValue = stack.getData(DataComponentTypes.DAMAGE);
106114
if (damageValue != null) {
107-
System.out.println("Current damage: " + damageValue);
115+
logger.info("Current damage: " + damageValue);
108116
} else {
109-
System.out.println("This item doesn't have a damage component set.");
117+
logger.info("This item doesn't have a damage component set.");
110118
}
111119

112-
// Return the max stack size, which will always be present either on the patch or the prototype
120+
// Certain components, like the max stack size, will always be present on an item
113121
Integer maxStackSize = stack.getData(DataComponentTypes.MAX_STACK_SIZE);
114122
```
115123

116-
### Setting a Valued Data Component
124+
### Setting a valued data component
117125

118126
```java
119127
// Set a custom model data value on this item
120-
stack.setData(DataComponentTypes.CUSTOM_MODEL_DATA, CustomModelData.customModelData()
121-
.addFloat(0.5f)
122-
.addFlag(true)
123-
.build()
124-
);
128+
stack.setData(DataComponentTypes.CUSTOM_MODEL_DATA, CustomModelData.customModelData()
129+
.addFloat(0.5f)
130+
.addFlag(true)
131+
.build()
132+
);
125133
```
126134

127-
### Removing or Resetting a Data Component
135+
### Removing or resetting a data component
128136

129137
```java
130-
// Remove an existing component (e.g., tool)
138+
// Remove an existing component (e.g. tool)
131139
stack.unsetData(DataComponentTypes.TOOL);
132140

133-
// Reset a component to the default (prototype value) for its item type (e.g., max stack size)
141+
// Reset a component to the default (prototype) value for its item type (e.g. max stack size)
134142
stack.resetData(DataComponentTypes.MAX_STACK_SIZE);
135143
```
136144

137-
### Non-Valued Data Components
145+
### Non-valued data components
138146

139-
Some components are only flags, and dont carry any sort of value:
147+
Some components are only flags and don't carry any sort of value:
140148

141149
```java
142150
// Make the item unbreakable
@@ -146,11 +154,11 @@ stack.setData(DataComponentTypes.UNBREAKABLE);
146154
stack.unsetData(DataComponentTypes.UNBREAKABLE);
147155
```
148156

149-
## Advanced Usage with Builders
157+
## Advanced usage with builders
150158

151159
Many data components have complex structures that require builders.
152160

153-
### Modifying pre-existing (prototype) component values
161+
### Modifying prototype component values
154162

155163
```java
156164
ItemStack itemStack = ItemStack.of(Material.DIAMOND_HELMET);
@@ -168,10 +176,9 @@ builder.equipSound(Registry.SOUNDS.getKeyOrThrow(Sound.ENTITY_GHAST_HURT));
168176
// Set our new item
169177
itemStack.setData(DataComponentTypes.EQUIPPABLE, builder);
170178
```
171-
This will create a diamond helmet that looks like a netherrite helmet when equipped, but plays a spooky
172-
ghast sound when equipped.
179+
This will create a diamond helmet that looks like a netherite helmet and plays a spooky ghast sound when equipped.
173180

174-
### Example: Written Book
181+
### Example: Written book
175182

176183
```java
177184
ItemStack writtenBook = ItemStack.of(Material.WRITTEN_BOOK);
@@ -181,9 +188,9 @@ WrittenBookContent.Builder bookBuilder = WrittenBookContent.writtenBookContent("
181188
bookBuilder.addPage(Component.text("This is a new page!"));
182189

183190
// Add a page that shows differently for people who have swear filtering on
184-
// For people who have filtering off, hate will be shown, while those with filtering on will see love.
191+
// Players who have disabled filtering, will see "I hate Paper!", while those with filtering on will see the "I love Paper!".
185192
bookBuilder.addFilteredPage(
186-
Filtered.of(Component.text("I hate Paper!"), Component.text("I love paper!"))
193+
Filtered.of(Component.text("I hate Paper!"), Component.text("I love Paper!"))
187194
);
188195

189196
// Change generation
@@ -193,29 +200,33 @@ bookBuilder.generation(1);
193200
writtenBook.setData(DataComponentTypes.WRITTEN_BOOK_CONTENT, bookBuilder.build());
194201
```
195202

196-
### Example: Cool Sword
203+
### Example: Cool sword
204+
197205
```java
198206
ItemStack itemStack = ItemStack.of(Material.DIAMOND_SWORD);
199207
itemStack.setData(DataComponentTypes.LORE, ItemLore.lore().addLine(Component.text("Cool sword!")).build());
200208
itemStack.setData(DataComponentTypes.ENCHANTMENTS, ItemEnchantments.itemEnchantments().add(Enchantment.SHARPNESS, 10).build());
201209
itemStack.setData(DataComponentTypes.RARITY, ItemRarity.RARE);
202210

203-
itemStack.unsetData(DataComponentTypes.TOOL); // Remove the cool component
211+
itemStack.unsetData(DataComponentTypes.TOOL); // Remove the tool component
204212

205213
itemStack.setData(DataComponentTypes.MAX_DAMAGE, 10);
206214
itemStack.setData(DataComponentTypes.ENCHANTMENT_GLINT_OVERRIDE, true); // Make it glow!
207215
```
208216

209-
## Matching Items Without Certain Data Components
217+
## Matching items without certain data components
218+
219+
When comparing items, you sometimes want to ignore certain values. For this, we can use the
220+
<Javadoc name="org.bukkit.inventory.ItemStack#matchesWithoutData(org.bukkit.inventory.ItemStack,java.util.Set)">`ItemStack#matchesWithoutData`</Javadoc>
221+
method.
210222

211-
Ignore certain properties when comparing items:
212-
For example, ignoring damage.
223+
For example, here we compare two diamond swords whilst ignoring their durability:
213224

214225
```java
226+
ItemStack originalSword = new ItemStack(Material.DIAMOND_SWORD);
215227
ItemStack damagedSword = new ItemStack(Material.DIAMOND_SWORD);
216228
damagedSword.setData(DataComponentTypes.DAMAGE, 100);
217-
ItemStack originalSword = new ItemStack(Material.DIAMOND_SWORD);
218229

219230
boolean match = damagedSword.matchesWithoutData(originalSword, Set.of(DataComponentTypes.DAMAGE), false);
220-
System.out.println("Match ignoring damage? " + match);
221-
```
231+
logger.info("Do the sword match? " + match); // true
232+
```

0 commit comments

Comments
 (0)