Skip to content

Commit 4a0ac84

Browse files
authored
feat: datapack discovery lifecycle API docs (#631)
1 parent b973984 commit 4a0ac84

File tree

4 files changed

+195
-2
lines changed

4 files changed

+195
-2
lines changed

astro.config.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -229,14 +229,18 @@ export default defineConfig({
229229
collapsed: true,
230230
items: ["paper/dev/entity-teleport", "paper/dev/display-entities"],
231231
},
232+
{
233+
label: "Lifecycle API",
234+
collapsed: true,
235+
items: ["paper/dev/lifecycle", "paper/dev/lifecycle/datapacks"],
236+
},
232237
"paper/dev/data-component-api",
233238
"paper/dev/pdc",
234239
"paper/dev/menu-type-api",
235240
"paper/dev/custom-inventory-holder",
236241
"paper/dev/scheduler",
237242
"paper/dev/plugin-messaging",
238243
"paper/dev/plugin-configurations",
239-
"paper/dev/lifecycle",
240244
"paper/dev/registries",
241245
"paper/dev/dialogs",
242246
"paper/dev/recipes",
@@ -405,6 +409,7 @@ export default defineConfig({
405409
"/paper/dev/api/command-api/misc",
406410
"/paper/dev/api/component-api",
407411
"/paper/dev/api/entity-api",
412+
"/paper/dev/api/lifecycle",
408413
"/paper/dev/api/event-api",
409414
"/paper/dev/misc",
410415
"/paper/contributing",
Lines changed: 178 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,178 @@
1+
---
2+
title: Datapack discovery
3+
description: A guide to including datapacks in your plugin and registering them with the lifecycle API.
4+
slug: paper/dev/lifecycle/datapacks
5+
version: 1.21.4+
6+
sidebar:
7+
badge:
8+
text: Experimental
9+
variant: danger
10+
---
11+
12+
import { FileTree } from "@astrojs/starlight/components";
13+
14+
:::danger[Experimental]
15+
16+
The datapack discovery API is currently experimental and may change in the future.
17+
18+
:::
19+
20+
The lifecycle API grants developers much more direct access to modifying some of the core parts of the server.
21+
One such core aspect are **datapacks**. No more asking users to download your datapack alongside the plugin — you
22+
can now include the datapack in your plugin JAR and load it yourself!
23+
24+
:::note
25+
26+
This feature requires you to have a basic understanding of the [Lifecycle API](/paper/dev/lifecycle),
27+
the datapack format (which you can look up in the [Minecraft wiki](https://minecraft.wiki/w/Data_pack)), and
28+
requires you to use a [`paper-plugin.yml` plugin](/paper/dev/getting-started/paper-plugins).
29+
30+
:::
31+
32+
## The datapack discovery lifecycle event
33+
The [`LifecycleEvents.DATAPACK_DISCOVERY`](jd:paper:io.papermc.paper.plugin.lifecycle.event.types.LifecycleEvents#DATAPACK_DISCOVERY) lifecycle
34+
event allows developers to add, check for, and even remove datapacks which are about to be loaded by the server.
35+
36+
:::tip
37+
38+
The following code examples are assumed to be executed inside a `PluginBootstrap`'s `bootstrap(BootstrapContext context)` method.
39+
They are also assumed to already be inside an event handler, resulting in a structure like this:
40+
41+
```java title="CustomPluginBootstrap.java" showLineNumbers
42+
@NullMarked
43+
public class CustomPluginBootstrap implements PluginBootstrap {
44+
45+
@Override
46+
public void bootstrap(BootstrapContext context) {
47+
context.getLifecycleManager().registerEventHandler(LifecycleEvents.DATAPACK_DISCOVERY.newHandler(
48+
event -> {
49+
// All code is contained here.
50+
}
51+
));
52+
}
53+
}
54+
```
55+
56+
:::
57+
58+
### Retrieving all currently discovered datapacks
59+
For the sake of simplicity, let's start with the most basic operation: Retrieving discovered data packs.
60+
For this, we can use the following simple code:
61+
62+
```java showLineNumbers startLineNumber=8
63+
context.getLogger().info("The following datapacks were found: {}",
64+
String.join(", ", event.registrar().getDiscoveredPacks().keySet())
65+
);
66+
```
67+
68+
This might yield the following log output:
69+
70+
```
71+
[00:26:12 INFO]: [PaperDocsTestProject] The following datapacks were found: file/bukkit, minecart_improvements, paper, redstone_experiments, trade_rebalance, vanilla
72+
```
73+
74+
This resulted in a few more datapacks than one might expect. Primarily, at the time of writing, the experimental `minecart_improvements`, `redstone_experiments`,
75+
and `trade_rebalance` datapacks. The datapack discovery does not care about whether a datapack should be enabled or not. It simply **looks for** datapacks that
76+
the server *could* enable.
77+
78+
### Removing discovered datapacks
79+
You can very easily prevent datapacks from being discovered by calling [`DatapackRegistrar#removeDiscoveredPack(String name)`](jd:paper:io.papermc.paper.datapack.DatapackRegistrar#removeDiscoveredPack(java.lang.String))
80+
on the datapack's name.
81+
82+
To remove the above-mentioned, experimental datapacks, you could the following code:
83+
84+
```java showLineNumbers startLineNumber=8
85+
// The names of the datapacks we want to remove.
86+
final Set<String> datapacksToRemove = Set.of("minecart_improvements", "redstone_experiments", "trade_rebalance");
87+
88+
datapacksToRemove.forEach(
89+
// Iterate through every datapack and remove it from the discovered packs.
90+
datapack -> event.registrar().removeDiscoveredPack(datapack)
91+
);
92+
93+
// The logging line from before.
94+
context.getLogger().info("The following datapacks were found: {}",
95+
String.join(", ", event.registrar().getDiscoveredPacks().keySet())
96+
);
97+
```
98+
99+
This would, as expected, remove the entries from being logged (and thus discovered):
100+
```
101+
[00:35:39 INFO]: [PaperDocsTestProject] The following datapacks were found: file/bukkit, paper, vanilla
102+
```
103+
104+
## Registering custom datapacks
105+
The main use case of the datapack register lifecycle event is the adding of plugin included datapacks. And Paper makes this pretty simple:
106+
You have to include your datapack in the plugin's JAR file, as already mentioned. This **does not** mean including the datapack zip.
107+
This means including the **source files**, which makes it very convenient to work with in a dev environment.
108+
109+
:::tip
110+
111+
This section assumes that you already have a working datapack. If you do not have one, but still want to play around with datapack inclusion in your plugin,
112+
you can check out [Vanilla Tweaks](https://vanillatweaks.net) for their data packs.
113+
114+
:::
115+
116+
### Including the datapack in your plugin
117+
Before you can let the server know about your datapack, you must first include it. For this, you can just add it to your **plugins src/main/resources** folder.
118+
The datapack should have at least one extra folder (so don't dump all the contents into the `resources` root). For this example, it will be located under
119+
**resources/custom_datapack**, but you can rename this second folder to any name you want to. If you have done everything correctly, you should have a folder structure,
120+
which looks similar to this:
121+
122+
<FileTree>
123+
- src/main/resources
124+
- custom_datapack
125+
- pack.mcmeta
126+
- data/
127+
</FileTree>
128+
129+
Build your plugin and verify that there is a `custom_datapack` folder in the root of your plugin's JAR file.
130+
131+
### Discovering the datapack
132+
To discover the datapack, you must call the [`DatapackRegistrar#discoverPack(URI uri, String id)`](jd:paper:io.papermc.paper.datapack.DatapackRegistrar#discoverPack(java.net.URI,java.lang.String))
133+
method. The uri should point to **your datapack's folder in your JAR**. This can be achieved simply by calling
134+
`getClass().getResource("/custom_datapack").toURI()`. **The preceding slash is very important**. The id can be set to
135+
whatever you want to identify your datapack with. The final name of the loaded pack will be `<YourPluginName>/<id>`.
136+
137+
Code example:
138+
139+
```java showLineNumbers startLineNumber=8
140+
try {
141+
// Retrieve the URI of the datapack folder.
142+
URI uri = Objects.requireNonNull(getClass().getResource("/custom_datapack")).toURI();
143+
// Discover the pack. Here, the id is set to "provided", which indicates to a server owner
144+
// that your plugin includes this data pack (as the name is prefixes with the plugin name).
145+
event.registrar().discoverPack(uri, "provided");
146+
} catch (URISyntaxException | IOException e) {
147+
throw new RuntimeException(e);
148+
}
149+
```
150+
151+
### Verifying that the datapack loaded correctly
152+
You can verify that a datapack loaded simply by executing the command `/datapack list enabled`.
153+
154+
Alternatively, you can check for the loaded status of your datapack during normal execution
155+
of your plugin. For example, a simple check inside your plugin's `onLoad` method might look like this:
156+
157+
```java title="CustomJavaPlugin.java" showLineNumbers
158+
public final class CustomJavaPlugin extends JavaPlugin {
159+
160+
@Override
161+
public void onLoad() {
162+
Datapack pack = this.getServer().getDatapackManager().getPack(getPluginMeta().getName() + "/provided");
163+
if (pack != null) {
164+
if (pack.isEnabled()) {
165+
this.getLogger().info("The datapack loaded successfully!");
166+
} else {
167+
this.getLogger().warn("The datapack failed to load.");
168+
}
169+
}
170+
}
171+
}
172+
```
173+
174+
If everything has gone correctly, the console should contain output similar to this:
175+
```
176+
[01:10:12 INFO]: [PaperDocsTestProject] Loading server plugin PaperDocsTestProject v1.0-DEV
177+
[01:10:12 INFO]: [PaperDocsTestProject] The datapack loaded successfully!
178+
```
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
---
2+
title: Lifecycle API
3+
tableOfContents: false
4+
---
5+
6+
import PageCards from "/src/components/PageCards.astro";
7+
8+
<PageCards />

src/content/docs/paper/dev/api/lifecycle.md renamed to src/content/docs/paper/dev/api/lifecycle/lifecycle.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
---
22
title: Lifecycle API
3-
description: A guide to Paper's Lifecycle API.
3+
description: An introduction to Paper's Lifecycle API.
44
slug: paper/dev/lifecycle
5+
sidebar:
6+
label: Introduction
57
---
68

79
The lifecycle API can be used for lifecycle-related registration. It is currently used by the

0 commit comments

Comments
 (0)