You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
pdc.set(key, PersistentDataType.STRING, "I love tacos!");
43
+
```
44
+
45
+
[`ItemStack`](jd:paper:org.bukkit.inventory.ItemStack) however doesn't have this method and instead requires you to use its builder-style consumer:
46
+
47
+
```java
48
+
NamespacedKey key =...;
49
+
50
+
// For 1.20.4 and below, use 'new ItemStack(Material.DIAMOND)' instead
40
51
ItemStack item =ItemStack.of(Material.DIAMOND);
41
-
// ItemMeta implements PersistentDataHolder, so we can get the PDC from it
42
-
item.editMeta(meta -> {
43
-
meta.getPersistentDataContainer().set(key, PersistentDataType.STRING, "I love Tacos!");
52
+
item.editPersistentDataContainer(pdc -> {
53
+
pdc.set(key, PersistentDataType.STRING, "I love tacos!");
44
54
});
45
55
```
46
56
47
57
:::note
48
58
59
+
The [`ItemStack#editPersistentDataContainer()`](jd:paper:org.bukkit.inventory.ItemStack#editPersistentDataContainer(java.util.function.Consumer)) method on `ItemStack` is only available in 1.21.4+. For older versions, you need to access and modify the [`ItemMeta`](jd:paper:org.bukkit.inventory.meta.ItemMeta) instead.
60
+
For 1.16.5+, there's the [`ItemStack#editMeta()`](jd:paper:org.bukkit.inventory.ItemStack#editMeta(java.util.function.Consumer)) method though.
61
+
62
+
:::
63
+
64
+
:::note
65
+
49
66
It is considered good practice to reuse `NamespacedKey` objects. They can be constructed with either:
50
67
- A [`Plugin`](jd:paper:org.bukkit.plugin.Plugin) instance and a [`String`](jd:java:java.lang.String) identifier
51
68
- A [`String`](jd:java:java.lang.String) namespace and a [`String`](jd:java:java.lang.String) identifier
52
69
53
-
The first option is often preferred as it will automatically use the plugin's namespace; however, the second option can be used if you
54
-
want to use a different namespace or access the data from another plugin.
70
+
The first option is often preferred as it will automatically use the plugin's lowercased name as namespace; however, the second option can be used if you want to use a different namespace or access the data from another plugin.
55
71
56
72
:::
57
73
58
74
## Getting data
59
-
To get data from the PDC, you need to know the `NamespacedKey` and the `PersistentDataType` of the data.
75
+
To get data from the PDC, you need to know the `NamespacedKey` and the [`PersistentDataType`](jd:paper:org.bukkit.persistence.PersistentDataType) of the data.
76
+
Some API parts, such as Adventure's [`Component.text(String)`](https://jd.advntr.dev/api/latest/net/kyori/adventure/text/Component.html#text(java.lang.String)), require non-null values. In such cases, use the [`getOrDefault`](jd:paper:io.papermc.paper.persistence.PersistentDataContainerView#getOrDefault(org.bukkit.NamespacedKey,org.bukkit.persistence.PersistentDataType,C)) on the pdc instead of [`get`](jd:paper:io.papermc.paper.persistence.PersistentDataContainerView#get(org.bukkit.NamespacedKey,org.bukkit.persistence.PersistentDataType)), which is nullable.
Certain classes, like `ItemStack` or [`OfflinePlayer`](jd:paper:org.bukkit.OfflinePlayer), provide a read-only view of their PDC.
195
+
In contrast to `ItemStack`, `OfflinePlayer` does <u>not</u> provide any way to modify the underlying container.
196
+
This is because the `OfflinePlayer` is directly read from disk and would require a blocking file operation.
197
+
Mutable objects, like the [`PersistentDataHolder#getPersistentDataContainer()`](jd:paper:org.bukkit.persistence.PersistentDataHolder#getPersistentDataContainer()), generally need to be re-saved even without modification or monitored.
198
+
That's why it's better to use unmodifiable "views" for read-only operations.
String value = pdcView.getOrDefault(key, PersistentDataType.STRING, "<null>");
208
+
209
+
// Do something with the value
210
+
player.sendPlainMessage(value);
211
+
```
212
+
213
+
:::note
214
+
215
+
PDC-view support for `ItemStack` was only introduced in 1.21.1. For older versions, you need to use the `ItemMeta` instead.
216
+
217
+
:::
218
+
168
219
## Storing on different objects
169
220
170
221
:::caution
@@ -176,8 +227,21 @@ E.g. Placing an ItemStack as a Block (with a TileState) ***does not*** copy over
176
227
:::
177
228
178
229
Objects that can have a PDC implement the [`PersistentDataHolder`](jd:paper:org.bukkit.persistence.PersistentDataHolder) interface
179
-
and their PDC can be fetched with [`PersistentDataHolder#getPersistentDataContainer()`](jd:paper:org.bukkit.persistence.PersistentDataHolder#getPersistentDataContainer()).
230
+
and their PDC can be fetched with `PersistentDataHolder#getPersistentDataContainer()`.
- The persistent data container of an `ItemStack` has historically been accessed by
234
+
the `ItemStack`'s `ItemMeta`. This, however, includes the overhead of constructing the entire `ItemMeta`, which acts as a snapshot of the `ItemStack`'s data at the point of creation.
180
235
236
+
To avoid this overhead in 1.21.1+, ItemStack exposes a read-only view of its persistent data container at [`ItemStack#getPersistentDataContainer()`](jd:paper:org.bukkit.inventory.ItemStack#getPersistentDataContainer()).
237
+
Edits to the persistent data container can also be simplified in 1.21.4+ using `ItemStack#editPersistentDataContainer(java.util.function.Consumer)`.
238
+
The persistent data container available in the consumer is not valid outside the consumer.
239
+
```java
240
+
ItemStack itemStack =...;
241
+
itemStack.editPersistentDataContainer(pdc -> {
242
+
pdc.set(key, PersistentDataType.STRING, "I love tacos!");
243
+
});
244
+
```
181
245
- ##### [`Chunk`](jd:paper:org.bukkit.Chunk)
182
246
- `Chunk#getPersistentDataContainer()`
183
247
- ##### [`World`](jd:paper:org.bukkit.World)
@@ -190,33 +254,18 @@ and their PDC can be fetched with [`PersistentDataHolder#getPersistentDataContai
190
254
```java
191
255
Block block = ...;
192
256
if (block.getState() instanceof Chest chest) {
193
-
chest.getPersistentDataContainer().set(key, PersistentDataType.STRING, "I love Tacos!");
257
+
chest.getPersistentDataContainer().set(key, PersistentDataType.STRING, "I love tacos!");
0 commit comments