Skip to content

Commit

Permalink
chore: update code snippets
Browse files Browse the repository at this point in the history
  • Loading branch information
Lulu13022002 committed Feb 3, 2025
1 parent 2949769 commit d7c09bd
Show file tree
Hide file tree
Showing 12 changed files with 71 additions and 67 deletions.
Binary file modified docs/paper/dev/api/assets/data-component-api-tree.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 2 additions & 2 deletions docs/paper/dev/api/custom-inventory-holder.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ public class MyInventory implements InventoryHolder {
this.inventory = plugin.getServer().createInventory(this, 9);

// Set the stone that we're going to be clicking.
this.inventory.setItem(0, new ItemStack(Material.STONE));
this.inventory.setItem(0, ItemStack.of(Material.STONE));
}

// A method we will call in the listener whenever the player clicks the stone.
Expand All @@ -115,7 +115,7 @@ public class MyInventory implements InventoryHolder {

// A method that will update the counter item.
private void updateCounter() {
this.inventory.setItem(8, new ItemStack(Material.BEDROCK, this.clicks));
this.inventory.setItem(8, ItemStack.of(Material.BEDROCK, this.clicks));
}

@Override
Expand Down
48 changes: 24 additions & 24 deletions docs/paper/dev/api/data-component-api.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -147,11 +147,11 @@ stack.resetData(DataComponentTypes.MAX_STACK_SIZE);
Some components are only flags and don't carry any sort of value:

```java
// Make the item unbreakable
stack.setData(DataComponentTypes.UNBREAKABLE);
// Make the item a glider to be used like elytra (combined with the equippable component)
stack.setData(DataComponentTypes.GLIDER);

// Remove the unbreakable flag
stack.unsetData(DataComponentTypes.UNBREAKABLE);
// Remove the glider flag
stack.unsetData(DataComponentTypes.GLIDER);
```

## Advanced usage with builders
Expand All @@ -161,57 +161,57 @@ Many data components have complex structures that require builders.
### Modifying prototype component values

```java
ItemStack itemStack = ItemStack.of(Material.DIAMOND_HELMET);
ItemStack helmet = ItemStack.of(Material.DIAMOND_HELMET);
// Get the equippable component for this item, and make it a builder.
// Note: Not all types have .toBuilder() methods
// This is the prototype value of the diamond helmet.
Equippable.Builder builder = itemStack.getData(DataComponentTypes.EQUIPPABLE).toBuilder();
Equippable.Builder builder = helmet.getData(DataComponentTypes.EQUIPPABLE).toBuilder();

// Make the helmet look like netherite
// We get the prototype equippable value from NETHERITE_HELMET
builder.assetId(Material.NETHERITE_HELMET.getDefaultData(DataComponentTypes.EQUIPPABLE).assetId());
// And give it a spooky sound when putting it on
builder.equipSound(Registry.SOUNDS.getKeyOrThrow(Sound.ENTITY_GHAST_HURT));
builder.equipSound(SoundEventKeys.ENTITY_GHAST_HURT);

// Set our new item
itemStack.setData(DataComponentTypes.EQUIPPABLE, builder);
helmet.setData(DataComponentTypes.EQUIPPABLE, builder);
```
This will create a diamond helmet that looks like a netherite helmet and plays a spooky ghast sound when equipped.

### Example: Written book

```java
ItemStack writtenBook = ItemStack.of(Material.WRITTEN_BOOK);
WrittenBookContent.Builder bookBuilder = WrittenBookContent.writtenBookContent("My Book", "AuthorName");
ItemStack book = ItemStack.of(Material.WRITTEN_BOOK);
WrittenBookContent.Builder builder = WrittenBookContent.writtenBookContent("My Book", "AuthorName");

// Add a page
bookBuilder.addPage(Component.text("This is a new page!"));
builder.addPage(Component.text("This is a new page!"));

// Add a page that shows differently for people who have swear filtering on
// Players who have disabled filtering, will see "I hate Paper!", while those with filtering on will see the "I love Paper!".
bookBuilder.addFilteredPage(
builder.addFilteredPage(
Filtered.of(Component.text("I hate Paper!"), Component.text("I love Paper!"))
);

// Change generation
bookBuilder.generation(1);
builder.generation(1);

// Apply changes
writtenBook.setData(DataComponentTypes.WRITTEN_BOOK_CONTENT, bookBuilder.build());
book.setData(DataComponentTypes.WRITTEN_BOOK_CONTENT, builder.build());
```

### Example: Cool sword

```java
ItemStack itemStack = ItemStack.of(Material.DIAMOND_SWORD);
itemStack.setData(DataComponentTypes.LORE, ItemLore.lore().addLine(Component.text("Cool sword!")).build());
itemStack.setData(DataComponentTypes.ENCHANTMENTS, ItemEnchantments.itemEnchantments().add(Enchantment.SHARPNESS, 10).build());
itemStack.setData(DataComponentTypes.RARITY, ItemRarity.RARE);
ItemStack sword = ItemStack.of(Material.DIAMOND_SWORD);
sword.setData(DataComponentTypes.LORE, ItemLore.lore().addLine(Component.text("Cool sword!")).build());
sword.setData(DataComponentTypes.ENCHANTMENTS, ItemEnchantments.itemEnchantments().add(Enchantment.SHARPNESS, 10).build());
sword.setData(DataComponentTypes.RARITY, ItemRarity.RARE);

itemStack.unsetData(DataComponentTypes.TOOL); // Remove the tool component
sword.unsetData(DataComponentTypes.TOOL); // Remove the tool component

itemStack.setData(DataComponentTypes.MAX_DAMAGE, 10);
itemStack.setData(DataComponentTypes.ENCHANTMENT_GLINT_OVERRIDE, true); // Make it glow!
sword.setData(DataComponentTypes.MAX_DAMAGE, 10);
sword.setData(DataComponentTypes.ENCHANTMENT_GLINT_OVERRIDE, true); // Make it glow!
```

## Matching items without certain data components
Expand All @@ -223,10 +223,10 @@ method.
For example, here we compare two diamond swords whilst ignoring their durability:

```java
ItemStack originalSword = new ItemStack(Material.DIAMOND_SWORD);
ItemStack damagedSword = new ItemStack(Material.DIAMOND_SWORD);
ItemStack originalSword = ItemStack.of(Material.DIAMOND_SWORD);
ItemStack damagedSword = ItemStack.of(Material.DIAMOND_SWORD);
damagedSword.setData(DataComponentTypes.DAMAGE, 100);

boolean match = damagedSword.matchesWithoutData(originalSword, Set.of(DataComponentTypes.DAMAGE), false);
logger.info("Do the sword match? " + match); // true
logger.info("Do the sword match? " + match); // -> true
```
4 changes: 2 additions & 2 deletions docs/paper/dev/api/entity-api/display-entities.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ its position in the corner of the block (this can be seen with the hitbox debug
```java
ItemDisplay display = world.spawn(location, ItemDisplay.class, entity -> {
// customize the entity!
entity.setItemStack(new ItemStack(Material.SKELETON_SKULL));
entity.setItemStack(ItemStack.of(Material.SKELETON_SKULL));
});
```

Expand Down Expand Up @@ -181,7 +181,7 @@ making the display spin indefinitely:

```java
ItemDisplay display = location.getWorld().spawn(location, ItemDisplay.class, entity -> {
entity.setItemStack(new ItemStack(Material.GOLDEN_SWORD));
entity.setItemStack(ItemStack.of(Material.GOLDEN_SWORD));
});

int duration = 5 * 20; // duration of half a revolution (5 * 20 ticks = 5 seconds)
Expand Down
4 changes: 2 additions & 2 deletions docs/paper/dev/api/event-api/custom-events.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ description: A guide to show you how to add custom events to your plugin.

# Custom Events

Creating custom events is a great way to add functionality to your plugin.
Creating custom events is a great way to add functionality to your plugin.
This will allow other plugins to listen to your custom events and add functionality to your plugin.

## Creating a custom event
Expand Down Expand Up @@ -85,7 +85,7 @@ public class ExamplePlugin extends JavaPlugin {
PaperIsCoolEvent coolEvent = new PaperIsCoolEvent(Component.text("Paper is cool!"));
coolEvent.callEvent();
// Plugins could have changed the message from inside their listeners here. So we need to get the message again.
// This event structure allows for other plugins to change the message to their taste.
// This event structure allows for other plugins to change the message to their taste.
// Like, for example, a plugin that adds a prefix to all messages.
Bukkit.broadcast(coolEvent.getMessage());
}
Expand Down
4 changes: 2 additions & 2 deletions docs/paper/dev/api/event-api/handler-lists.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -45,9 +45,9 @@ public class ExampleListener implements Listener {
handlerList.unregister(this);
// ...
}

// Or:

public ExampleListener() {
// Access the handler list through the static getter
HandlerList handlerList = PlayerJoinEvent.getHandlerList();
Expand Down
6 changes: 3 additions & 3 deletions docs/paper/dev/api/folia-support.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ description: How to support both Folia and Paper within your plugin.

![](/img/folia.png)

[Folia](https://github.com/PaperMC/Folia) is a fork of Paper, which is currently maintained by the PaperMC team.
[Folia](https://github.com/PaperMC/Folia) is a fork of Paper, which is currently maintained by the PaperMC team.
It adds the ability to split the world into regions as outlined [here](/folia/reference/overview) in more depth.

# Checking for Folia
Expand All @@ -28,7 +28,7 @@ private static boolean isFolia() {

## Schedulers

In order to support Paper and Folia, you must use the correct scheduler. Folia has different types of schedulers
In order to support Paper and Folia, you must use the correct scheduler. Folia has different types of schedulers
that can be used for different things. They are:

- [Global](#global-scheduler)
Expand All @@ -47,7 +47,7 @@ GlobalRegionScheduler globalScheduler = server.getGlobalRegionScheduler();
```

### Region scheduler
The region scheduler will be in charge of running tasks for the region that owns a certain location. Do not use this scheduler for
The region scheduler will be in charge of running tasks for the region that owns a certain location. Do not use this scheduler for
operations on entities, as this scheduler is tied to the region. Each entity has its [own scheduler](#entity-scheduler)
which will follow it across regions. As an example, let's say I want to set a block to a beehive:
```java
Expand Down
28 changes: 14 additions & 14 deletions docs/paper/dev/api/pdc.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -34,11 +34,11 @@ which is the object you want to store the data on. The third is the data itself.
// Create a NamespacedKey
NamespacedKey key = new NamespacedKey(pluginInstance, "example-key");

ItemStack item = new ItemStack(Material.DIAMOND);
ItemStack item = ItemStack.of(Material.DIAMOND);
// ItemMeta implements PersistentDataHolder, so we can get the PDC from it
ItemMeta meta = item.getItemMeta();
meta.getPersistentDataContainer().set(key, PersistentDataType.STRING, "I love Tacos!");
item.setItemMeta(meta);
item.editMeta(meta -> {
meta.getPersistentDataContainer().set(key, PersistentDataType.STRING, "I love Tacos!");
});
```

:::info
Expand Down Expand Up @@ -92,9 +92,9 @@ The PDC supports a wide range of data types, such as:
// Storing a list of strings in a container by verbosely creating
// a list data type wrapping the string data type.
container.set(
key,
PersistentDataType.LIST.listTypeFrom(PersistentDataType.STRING),
List.of("a", "list", "of", "strings")
key,
PersistentDataType.LIST.listTypeFrom(PersistentDataType.STRING),
List.of("a", "list", "of", "strings")
);

// Storing a list of strings in a container by using the api
Expand Down Expand Up @@ -134,7 +134,7 @@ public class UUIDDataType implements PersistentDataType<byte[], UUID> {

@Override
public byte[] toPrimitive(UUID complex, PersistentDataAdapterContext context) {
ByteBuffer bb = ByteBuffer.wrap(new byte[Long.BYTES * 2]);
ByteBuffer bb = ByteBuffer.allocate(Long.BYTES * 2);
bb.putLong(complex.getMostSignificantBits());
bb.putLong(complex.getLeastSignificantBits());
return bb.array();
Expand Down Expand Up @@ -183,13 +183,13 @@ and their PDC can be fetched with <Javadoc name={"org.bukkit.persistence.Persist
- `Entity#getPersistentDataContainer()`
- ##### <Javadoc name={"org.bukkit.block.TileState"}>`TileState`</Javadoc>
- This is slightly more complicated, as you need to cast the block's state to something that extends `TileState`.
This does not work for all blocks, only those that have a tile entity.
This does not work for all blocks, only those that have a block entity.
```java
Block block = ...;
if (block.getState() instanceof Chest chest) {
chest.getPersistentDataContainer().set(key, PersistentDataType.STRING, "I love Tacos!");
chest.update();
}
Block block = ...;
if (block.getState() instanceof Chest chest) {
chest.getPersistentDataContainer().set(key, PersistentDataType.STRING, "I love Tacos!");
chest.update();
}
```
- ##### <Javadoc name={"org.bukkit.structure.Structure"}>`Structure`</Javadoc>
- `Structure#getPersistentDataContainer()`
Expand Down
4 changes: 2 additions & 2 deletions docs/paper/dev/api/recipes.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ public class TestPlugin extends JavaPlugin {
@Override
public void onEnable() {
NamespacedKey key = new NamespacedKey(this, "WarriorSword");
ItemStack item = new ItemStack(Material.DIAMOND_SWORD);
ItemStack item = ItemStack.of(Material.DIAMOND_SWORD);

ShapedRecipe recipe = new ShapedRecipe(key, item);
recipe.shape(" A ", "AAA", " B ");
Expand Down Expand Up @@ -70,7 +70,7 @@ public class TestPlugin extends JavaPlugin {
@Override
public void onEnable() {
NamespacedKey key = new NamespacedKey(this, "WarriorSword");
ItemStack item = new ItemStack(Material.DIAMOND_SWORD);
ItemStack item = ItemStack.of(Material.DIAMOND_SWORD);

ShapelessRecipe recipe = new ShapelessRecipe(key, item);
recipe.addIngredient(3, Material.DIAMOND);
Expand Down
5 changes: 5 additions & 0 deletions docs/paper/dev/api/registries.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,11 @@ final Enchantment enchantment = enchantmentRegistry.getOrThrow(TypedKey.create(
RegistryKey.ENCHANTMENT, Key.key("minecraft:sharpness"))
);

// Same as above, but using the instance's method
final Enchantment enchantment = enchantmentRegistry.getOrThrow(
RegistryKey.ENCHANTMENT.typedKey(Key.key("minecraft:sharpness"))
);

// Same as above, but using generated create method
// available for data-driven registries or "writable" ones
// (those bound to a lifecycle event in RegistryEvents).
Expand Down
12 changes: 6 additions & 6 deletions docs/paper/dev/api/roadmap.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ description: Outlines the future intents and plans of the Paper project.
# Roadmap

Paper offers a rich API with a wide range of features that can help you unlock the full potential of your server.
However, in order to make room for new features and improvements, some of the older APIs will be phased out. This page
is intended to document any future API changes that are planned or possible deprecations that may be coming up.
However, in order to make room for new features and improvements, some of the older APIs will be phased out. This page
is intended to document any future API changes that are planned or possible deprecations that may be coming up.

## Future plans

Expand Down Expand Up @@ -61,7 +61,7 @@ public void exampleMethod(); // Example deprecated method
In addition to being marked as `@Deprecated`, API may be marked as `forRemoval` with a given
[`@ApiStatus.ScheduledForRemoval`](https://javadoc.io/doc/org.jetbrains/annotations/latest/org/jetbrains/annotations/ApiStatus.ScheduledForRemoval.html) version.
API scheduled for removal should only occur within major release versions of Minecraft.
It is highly recommended you migrate away from API scheduled for removal.
It is highly recommended you migrate away from API scheduled for removal.

It should be noted, that API scheduled for removal will be given adequate time to allow plugin developers to migrate
away from said API.
Expand All @@ -85,13 +85,13 @@ therefore it may be scheduled for removal.

### Duplicate API

Since Paper used to downstream Spigot, it can occasionally include APIs added by Spigot that clash with what Paper already has.
Typically, Paper will deprecate Spigot’s API in favor of their own API.
Since Paper used to downstream Spigot, it can occasionally include APIs added by Spigot that clash with what Paper already has.
Typically, Paper will deprecate Spigot’s API in favor of their own API.

However, in cases where upstream offers a more powerful API, Paper’s may be deprecated instead.

### Obsolete API
Paper strives to improve on APIs that may already be included. There may be some cases where we have built new
Paper strives to improve on APIs that may already be included. There may be some cases where we have built new
APIs to offer as a replacement to another.

Obsolete API is expected for function for the far future and may not be scheduled for removal
Expand Down
19 changes: 9 additions & 10 deletions docs/paper/dev/api/scheduler.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ Every game runs something called a game loop ,which essentially executes all the
A single execution of that loop in Minecraft is called a 'tick'.

In Minecraft, there are 20 ticks per second or in other words, one tick every 50 milliseconds. This means that the game loop is executed
20 times per second. A tick taking more than 50ms to execute is the moment when your server starts to fall behind on
20 times per second. A tick taking more than 50ms to execute is the moment when your server starts to fall behind on
its work and lag.

A task that should run after 100 ticks will run after 5 seconds (100 ticks / 20 ticks per second = 5 seconds). However,
Expand All @@ -30,14 +30,14 @@ seconds.

Every method of the scheduler that takes a delay or period uses ticks as a unit of time.

Converting from human units to ticks and back is as simple as:
- `ticks = seconds * 20`
Converting from human units to ticks and back is as simple as:
- `ticks = seconds * 20`
- `seconds = ticks / 20`

You can make your code more readable by using the
<Javadoc name={"java.util.concurrent.TimeUnit"} project={"java"}>`TimeUnit`</Javadoc>
enum, e.g. to convert 5 minutes to ticks and back:
- `TimeUnit.MINUTES.toSeconds(5) * 20`
enum, e.g. to convert 5 minutes to ticks and back:
- `TimeUnit.MINUTES.toSeconds(5) * 20`
- `TimeUnit.SECONDS.toMinutes(ticks / 20)`

You can also use the `Tick` class from Paper to convert between human units and ticks, e.g. to convert 5 minutes to ticks:
Expand Down Expand Up @@ -83,7 +83,7 @@ your server's performance.

:::warning

**Large portions of the Bukkit API are not safe to use from within asynchronous tasks**. If a method changes or
**Large portions of the Bukkit API are not safe to use from within asynchronous tasks**. If a method changes or
accesses the world state, it is not safe to be used from an asynchronous task.

:::
Expand Down Expand Up @@ -112,16 +112,15 @@ You can either implement it in a separate class, e.g.:
public class MyRunnableTask implements Runnable {

private final MyPlugin plugin;

public MyRunnableTask(MyPlugin plugin) {
this.plugin = plugin;
}

@Override
public void run() {
this.plugin.getServer().broadcast(Component.text("Hello, World!"));
}

}
```
```java
Expand Down Expand Up @@ -214,7 +213,7 @@ public class CustomRunnable extends BukkitRunnable {
}
```

This simply adds a potion effect until the entity dies.
This simply adds a potion effect until the entity dies.

#### Using a delay of 0 ticks

Expand Down

0 comments on commit d7c09bd

Please sign in to comment.