#paper
32998 messages · Page 33 of 33 (latest)
Expected behavior
When a chunk is unloaded and ChunkUnloadEvent#setSaveChunk(false) is called, entities should not be saved.
Observed/Actual behavior
I noticed when the chunk unloads, and reloads... the previous entities are there, along with a new batch of entities.
For example im standing in a chunk that spawned 4 pigs.
When I log out/in... there's a new batch of pigs along with the pigs from the last chunk generation. Each time I do this, more and more piggies.
<img width="966" height="620" alt="Image" src="https://github.com/user-attachments/assets/f0199c3c-42be-468f-b68f-f159797603fb" />
Steps/models to reproduce
simple listener:
@EventHandler
public void onChunkUnload(ChunkUnloadEvent event) {
event.setSaveChunk(false);
}
Plugin and Datapack List
[09:41:21 INFO]: ℹ Server Plugins (10):
[09:41:21 INFO]: Paper Plugins (5):
[09:41:21 INFO]: - CorePlugin, SkBee, SkBriggy, SkNMS, StressTestBots
[09:41:21 INFO]: Bukkit Plugins (5):
[09:41:21 INFO]:...
Block chunks, entity chunks and POI chunks are different concepts. To block entity saving you would need to listen to https://jd.papermc.io/paper/26.1.2/org/bukkit/event/world/EntitiesUnloadEvent.html and remove those mobs
actually I'm not sure it's worth fixing it before mojang given this would break datapack changing the nested loot table and expecting it to work for those mobs and the warning is harmless.
I just don't see the use case given this will be exposed through the environmental attributes api and the tag can already be checked as well. The other isInDaylight method should probably be deprecated too given the meaning seems to have diverged across the time.
Expected behavior
When a player is teleported to a different world during the PlayerJoinEvent, settings like the worldborder should be correctly updated to the client for the target world.
Observed/Actual behavior
There is a desynchronization between the client and the server regarding the world border. When a player logs in and gets teleported to a different world on join, the server correctly updates the border internally, but the client only updates partially.
From the player's perspective, the world border center and size appears to be the old targeted world's one, producing issue like making it seem as though the player is outside the border or running against an invisible wall. Running /worldborder center outputs the correct coordinates, confirming the server recognizes the right center.
Switching to a different world and returning resolves the desynchronization completely.
Steps/models to reproduce
Prepare a server with at least two different worlds (e.g., w...
The issue is also present on lower minecraft versions like 1.21.11
its because this got reverted
<img width="2683" height="521" alt="Image" src="https://github.com/user-attachments/assets/a72dcd13-bcfc-4746-8ae3-82f72f15bcf4" />
And issue is PlayerList#placeNewPlayer
// calls PlayerJoinEvent
....
player.sentListPacket = true;
player.suppressTrackerForLogin = false; // Paper - Fire PlayerJoinEvent when Player is actually ready
((ServerLevel)player.level()).getChunkSource().chunkMap.addEntity(player); // Paper - Fire PlayerJoinEvent when Player is actually ready; track entity now
// CraftBukkit end
//player.refreshEntityData(player); // CraftBukkit - BungeeCord#2321, send complete data to self on spawn // Paper - THIS IS NOT NEEDED ANYMORE
this--->this.sendLevelInfo(player, serverLevel);
// CraftBukkit start - Only add if the player wasn't moved in the event
if (player.level() == serverLevel && !serverLevel.players().contains(player)) {
serverLevel.addNewPlay```...
Keeping in mind that teleporting the player on join has always caused weird issues and side effects all around, the only supported way of changing the spawn location is by changing it in the AsyncPlayerSpawnLocationEvent, but given that the surrounding logic accounts for such thing this might just be valid
Oh thanks, didn't know the event exist.
@Lulu13022002 i add a way to expose the environment key for use in the copy of WorldCreator... if its better wait for the other PR for expose that info then you can rollback this change... but i feel this PR is ready for the first goal about create worlds with custom environments.
Fixes PaperMC/Paper#11208.
Uses the vanilla translatable shutdown message when no custom shutdown message is configured, while keeping custom shutdown messages configurable via bukkit.yml.
This is not a rich message
Fair point, I reverted that part and kept the existing legacy parsing. The PR now only changes the default to null and uses the vanilla translatable shutdown message as the fallback when no custom shutdown message is configured.
Is your feature request related to a problem?
Yes.
So I wrote a datapack, which pulls my world's lowest Y to -256.
After many attempts and asking a few AIs to help me with figuring out lava, lava kept pooling around -54Y.
Turns out Mojang hardcoded this value.
I reported it as a bug, and it was closed saying "request a feature, this isn't a bug"
Which I find funny, they give us the control in a datapack to go down to -2032Y, but our caves will be full of lava.
My bug MC-307994
Someone commented stating another bug MC-237017
This one (same issue as mine) remains open, so that's good news that its not closed, but bad news is in 5 years it hasn't been fixed.
Describe the solution you'd like.
In net.minecraft.world.level.levelgen.NoiseBasedChunkGenerator:
<img width="1020" height="237" alt="Image" src="https://github.com/user-attachments/assets/3bc715c0-b04d-45c7-bb2e-e7d3737a74b0" />
This is the hardcoded value. Id love to see a config option for this, or another alternative...
Minecraft gives us the ability in data packs to modify the min Y of a world.
Unfortunately when dropping the Y to a lower value, caves with always be flooded with lava.
This is due to a hardcoded lava level.
I reported it as a bug, and it was closed saying "request a feature, this isn't a bug"
Which I find funny, they give us the control in a datapack to go down to -2032Y, but our caves will be full of lava.
My bug MC-307994
Someone commented stating another bug MC-237017
This one (same issue as mine) remains open, so that's good news that it's not closed, but bad news is in 5 years it hasn't been fixed. It's also confirmed.
Rather than hardcoding the lava level at a strict -54, this PR aims to take the min Y of the noise settings and add 10.
So min Y being -64, it still results in -54.
If a datapack (such as mine) drops it to -256, the result will be -246.
I have tested this on my own server with said datapack, and works perfectly.
Ref issue #13878...
This really feels like this falls into the annoying "maybe makes sense but I'm not entirely sure it should be our job to make this, especially as we have no idea who might be surprised by it"
This really feels like this falls into the annoying "maybe makes sense but I'm not entirely sure it should be our job to make this, especially as we have no idea who might be surprised by it"
I totally get what you mean, I've just run out of ideas on how to make this work.
Only alternative I currently have is my own patch for myself.
I just do wonder how many others have run into this issue and it's gone unmentioned.
I can't think of any negative side effects from this, nor any alternative, but I'm all ears.
negative side effects would be a datapack gen setting applying in a way it didn't in the past, which will impact generation for new chunks, etc
negative side effects would be a datapack gen setting applying in a way it didn't in the past, which will impact generation for new chunks, etc
Yeah that's fair.
Let's use this scenario (before this PR).
Say I wrote a datapack that pulls Y down to -128.
Old chunk is going to be -64
New chunk is going to be -128
Lava is going to flood the new chunk's caves from -54 downwards.
No one can use new deeper caves. Total waste ... sad face.
Post PR:
Same as above, but caves won't be flooded, player will be able to go down to newer, lower levels, happy face!
Only pitfall is players will be able to jump out of the new chunk since the old chunk didn't go down to that new level.
Datapacks that alter things like this typically shouldn't be put into old worlds, but we all know things happen.
I really wish Mojang didn't hardcode this in the first place. its so odd its not part of the datapack like everything else.
Sent an enquiry to mojang about it, will see what they say
Sent an enquiry to mojang about it, will see what they say
Thank you. I look forward to hearing about that :)
Ideally this is configurable in the datapack like the sea level, but doing it before mojang will cause issue if we do not match their fixes perfectly.
Before this change, the Bukkit ItemStack passed to the event is constructed from a Bukkit Material, which relies on the Bukkit mapping from blocks to items being the same as the Minecraft mapping from blocks to items.
However, it is not the same.
For example, new ItemStack(Material.POTATOES) does not give an ItemStack of type Material.POTATO as it should.
So a flower pot block created as new FlowerPotBlock(Blocks.POTATOES, properties) will crash the server.
After this change, the Bukkit ItemStack passed to the event is constructed from the Minecraft ItemStack, which relies on the Minecraft mapping from blocks to items being correct.
Hi, i see the archive repo and 1.21.4 says its not the final stable version, so i think its expected in the README only show to 1.21.3
For now in draft as mache is not released yet.
I don't think this check does anything, players are not added the tracked list if their attribute is zero or less, same for the source.
This is a WAI since custom spear allow to dismount without doing damage/knockback so it's not related at all.
This is a WAI since custom spear allow to dismount without doing damage/knockback so it's not related at all.
Hello, I don’t quite understand this situation.
Some servers use boats or minecarts to display mobs or build mob farms. Even when players do not have permission to attack entities, they can still use spear charges to dismount mobs from vehicles.
Is there currently any proper way to prevent this behavior? Or would it be better to create a feature request for something like a SpearChargeDismountEvent?
Is your feature request related to a problem?
When the attack event caused by SpearCharge is cancelled, the entity will still dismount from boat and minecart.
https://github.com/PaperMC/Paper/issues/13583
Many players trap various mobs inside minecarts and boats for display purposes, and some mob farms also rely on this mechanic. However, SpearCharge can now bypass protection in these areas; while it cannot deal damage to the mobs, it is able to force them to dismount.
Describe the solution you'd like.
Added SpearChargeDismountEvent, which provides access to the SpearCharge attacker. Region protection plugins can perform fine-grained permission checks to allow or prevent the dismount event
Describe alternatives you've considered.
Or make EntityDismountEvent able to capture the attacker, if an attacker exists.
Other
No response
Expected behavior
EntityDamageByEntityEvent should getAttackCooldown correctly
Observed/Actual behavior
Attack with hand is always 0.1, and attack with sword is always 0.039999995
Steps/models to reproduce
@EventHandler
public static void onEntityDamageByEntityEvent(EntityDamageByEntityEvent event) {
if (event.getDamager() instanceof Player player) print(player.getAttackCooldown());
}
Plugin and Datapack List
test plugin only
Paper version
Paper 26.1.2-63
since Paper 26.1.2-55 after #13856
Other
No response
Expected behavior
Bukkit.getBukkitVersion() and Server.getBukkitVersion() functions are supposed to return the current version of Bukkit API which is implemented by server software (here Paper-server). For instance 26.1.2 or 26.1.2-SNAPSHOT or 26.1.2-R0.1-SNAPSHOT.
In all former versions (before 26.1.2), it worked perfectly. Example: 1.19.4-R0.1-SNAPSHOT
Observed/Actual behavior
For 26.1.2 servers, the version number returned is the server one: 26.1.2.build.63-stable instead of the API one.
Steps/models to reproduce
Two possibilities:
- Invoke the
Bukkit.getBukkitVersion()in a plugin - Type
/versionin the console. The Bukkit API version number is shown afterImplementing API versionstring.
Plugin and Datapack List
BlockLocker, CMILib, DecentHolograms, Essentials, EssentialsAntiBuild, EssentialsChat, EssentialsSpawn, GroupManager, Multiverse-Core, Multiverse-Inventories, Multiverse-Portals, PlaceholderAPI, pvparena, Residence, Vault, WorldEdit, WorldGuard
##...
That change was for reset correctly the attack strength what its used in the getAttackCooldown method, the reset is being in the attack what is before the EntityDamageByEntityEvent now.
26.1.2.build.63-stable instead of the API one.
I don't really get what you're saying, 26.1.2.build.63-stable is the API version, it's io.papermc.paper:paper-api:26.1.2.build.63-stable
There isn't a bukkit API version and hasn't for a decade, the API and the Server are versioned together, we no longer use SNAPSHOT releases; We're not semver compliant and that was never something that was garaunteed
That means developing a specific way to parse it and compare it if I need to provide specific version features.
You can use https://jd.papermc.io/paper/26.1.2/io/papermc/paper/ServerBuildInfo.html#minecraftVersionId() or https://jd.papermc.io/paper/26.1.2/org/bukkit/Bukkit.html#getMinecraftVersion() for alternative representation if you want, that would be kept with what mojang is providing
That means developing a specific way to parse it and compare it if I need to provide specific version features.
You can use https://jd.papermc.io/paper/26.1.2/io/papermc/paper/ServerBuildInfo.html#minecraftVersionId() or https://jd.papermc.io/paper/26.1.2/org/bukkit/Bukkit.html#getMinecraftVersion() for alternative representation if you want, that would be kept with what mojang is providing
Both methods are not available in common Bukkit API, for instance they don't exist in Spigot.
Paper has hardforked from spigot over a year ago so this is not the Paper team's concern
There isn't a bukkit API version and hasn't for a decade, the API and the Server are versioned together, we no longer use SNAPSHOT releases; We're not semver compliant and that was never something that was garaunteed
During many years Spigot and Paper returned the same result when a Bukkit API method was called. This was useful and make possible interoperability between server software. That's how an API is supposed to work.
Now, if it's a design choice and not a bug, I respect that. I was here to report what I thought was an issue, not to impose anything.
That event feels overly specific, but I don't mind having a generic EntityStabEvent with toggles for damage, knockback and dismount along the attacker.
Maybe something like this:
if (!event.getAttacker().hasPermission("plugin.dismount")) {
event.getActions().remove(Action.DISMOUNT);
}
Leaving this longer messages for those interested in more details:
During many years Spigot and Paper returned the same result when a Bukkit API method was called.
Bukkit died in 2014.
For years, Paper was based on Spigot, so it did whatever Spigot did.
When Paper split from Spigot at 1.21.4, it became possible for Spigot and Paper to have different classes/methods entirely or to have same-named methods return different values. If a developer wishes to support the 95+% of modern servers running Paper and also the under 5% of servers on Spigot, they should be writing code to handle each, because there are deviations (sometimes significant!).
Minecraft 26.1 was a major versioning shift in MC, making it a great time to also properly adjust the versioning values you get from the API:
Considering the last R1.0 was on MC 1.6.4, dropping the R0.1 bit is reasonable. Including build numbers is great, because sometimes an API method appears later on than the first working builds, so a pl...
That event feels overly specific, but I don't mind having a generic EntityStabEvent with toggles for damage, knockback and dismount along the attacker. Maybe something like this:
if (!event.getAttacker().hasPermission("plugin.dismount")) {
event.getActions().remove(Action.DISMOUNT);
}
that can be a thing for EntityLungeEvent or that event its to early?
That change was for reset correctly the attack strength what its used in the
getAttackCooldownmethod, the reset is being in the attack what is before the EntityDamageByEntityEvent now.
It works fine in Paper 26.1.2-54 , must be something wrong in Paper 26.1.2-55 I guess
That event feels overly specific, but I don't mind having a generic EntityStabEvent with toggles for damage, knockback and dismount along the attacker. Maybe something like this:
if (!event.getAttacker().hasPermission("plugin.dismount")) {
event.getActions().remove(Action.DISMOUNT);
}
So long as I can obtain the attacker, I don't mind what the event is called.^_^
It works fine in Paper 26.1.2-54 , must be something wrong in Paper 26.1.2-55 I guess
Like say in Paper 26.1.2-55 the reset of that cooldown is called now before that event (for parity with a pvp mechanic related to https://github.com/PaperMC/Paper/issues/13838), you can maybe use other events for that value like PrePlayerAttackEntityEvent
Using the following listener, the logged loot table currently matches the default loot table of the entity, not the actual loot table used:
@EventHandler
public void onEntityDeath(EntityDeathEvent event) {
if (event.getEntity() instanceof Mob mob) {
this.getSLF4JLogger().warn("Entity {} died with loot table: {}", mob.getName(), mob.getLootTable());
}
}
During my test, the Pig I modified did drop rotten flesh despite the console printing entities/pig loot table
[02:11:45 INFO]: roro1506_HD issued server command: /data merge entity 62185aec-e858-4945-a41a-6e21107085b7 {DeathLootTable:"minecraft:entities/zombie"}
[02:11:45 INFO]: [roro1506_HD: Modified entity data of Pig]
[02:11:47 WARN]: [Paper-Test-Plugin] Entity Pig died with loot table: minecraft:entities/pig
This PR fixes this issue
[16:12:32 INFO]: roro1506_HD issued server command: /data merge entity c3c71d92-632f-49d3-a682-fd062b85f884 {DeathLootTable:"minecra```...
Tested with /summon pig ~ ~ ~ {DeathLootTable:"minecraft:entities/zombie"} and the entity in event show the loot table to being use.
Also for the cancel state the entity keep the loottable.
Missing override annotation
I wonder why this method is even called when the event is cancelled maybe check it before?
Didn't put it initially since that annotation is also missing on some other places, but will add it
The other place this method is used is for chested horse, which requires some special handling specifically when the event is cancelled, see https://github.com/PaperMC/Paper/blob/main/paper-server/patches/sources/net/minecraft/world/entity/animal/equine/AbstractChestedHorse.java.patch#L11
Sure you can add it to the other place as well.
It does the same check like here just not as an early return?
Umm right, had a brainfart here. Perhaps some residue of past handling. You'd prefer only calling the method when the event isn't cancelled?
Yes can then simplify the method to not take the event, you should also probably check shouldDropLoot before resetting the loot table since that path only ran after this check.
Expected behavior
No WARM
Observed/Actual behavior
WARNING: A terminally deprecated method in sun.misc.Unsafe has been called
WARNING: sun.misc.Unsafe::objectFieldOffset has been called by org.joml.MemUtil$MemUtilUnsafe (file:/X:/MinecraftServer/libraries/org/joml/joml/1.10.8/joml-1.10.8.jar)
WARNING: Please consider reporting this to the maintainers of class org.joml.MemUtil$MemUtilUnsafe
WARNING: sun.misc.Unsafe::objectFieldOffset will be removed in a future release
Steps/models to reproduce
Start Server
Use JDK 25
Plugin and Datapack List
No have
Paper version
ver
[18:46:07 INFO]: Checking version, please wait...
[18:46:08 INFO]: This server is running Paper version 1.21.11-132-ver/1.21.11@c5eb079 (2026-05-11T11:43:09Z) (Implementing API version 1.21.11-R0.1-SNAPSHOT)
You are running the latest version
Previous version: 1.21.11-131-6d5b910 (MC: 1.21.11)
Other
Can you are add this update to papermc 1.21.11?
Can you are Fix this?
Can you are Fix? Crash Server
This is not neither an error nor a crash
2186e1e Fix BlockRecieveGameEvent destination block - electronicboy
5c917da [ci skip] Fixed accidently test plugin changes - electronicboy
I originally did this before the hard-fork in PR #10314
Completely forgot about it until now, figured I would redo it with the requested changes
could this use the generator, to generate the enum automatically from NoiseGeneratorSettings
this also seems to miss the END and NETHER world types
But they're also valid world types in vanilla so maybe they should be included here as well
No, not easily and this type should be deprecated later once a more proper world gen api exists.
Expected behavior
No errors in the console
Observed/Actual behavior
I'm just flying around the world and this error appears in the console:
<img width="1090" height="330" alt="Image" src="https://github.com/user-attachments/assets/0fb12b60-7f4e-4f18-8e47-8ff148c20384" />
Steps/models to reproduce
- Enable Anti-Xray
- Join the server
- Load chunks
- View the console
Plugin and Datapack List
[03:25:10 INFO]: ℹ Server Plugins (61):
[03:25:10 INFO]: Paper Plugins (1):
[03:25:10 INFO]: - PlugManX
[03:25:10 INFO]: Bukkit Plugins (60):
[03:25:10 INFO]: - AntiHealthIndicator, AuraSkills, AutoMessage, BanItem, BigDoors, BookExploitFix, BreweryX, ChatSpy, Citizens, CommandAPI
[03:25:10 INFO]: CoreProtect, CustomCrafting, DeluxeMenus, dtlTraders, dynmap, Dynmap-Towny, EasyPayments, Essentials, EssentialsProtect, EssentialsSpawn
[03:25:10 INFO]: FastAsyncWorldEdit, GoldEconomy, GSit, HeadDatabase, ImageFrame, Interactions, Kostyl, KostylTWO, LicuhaDe, LiteBans
[03:2...
The issue here is that world types aren't a thing anymore, these are just templates, effectively; said template used for the end/nether and the others are applied to the overworld.
Not really sure I like the surfacing of this stuff as a result of that, the underlying concept of a world type no longer exists, this is just trying to marry an outdated deprecated concept with it's replacement cousin which works differently in a sense
(The real way to go about this would be to just expose the key being used, if people want to check those against the default templated types that's their thing, but tying this to an enum in the era of registries is pretty flawed in the long run, and pretty sure this is already broken today given datapacks can define this stuff?
Expected behavior
The firework should always use the data from the new item.
Observed/Actual behavior
The old firework data is retained. Note that this only occurs when updating the firework's item, i.e. setting an item on a firework that already has an item.
Steps/models to reproduce
Use Firework#setItem on a firework entity that already has an item set. Can be done at any time during its life.
Here's a small example that should summon a green firework, but summons a red one instead.
ItemStack first = ItemStack.of(Material.FIREWORK_ROCKET);
first.setData(DataComponentTypes.FIREWORKS, Fireworks.fireworks()
.addEffect(FireworkEffect.builder()
.withColor(Color.RED)
.build()));
ItemStack second = ItemStack.of(Material.FIREWORK_ROCKET);
second.setData(DataComponentTypes.FIREWORKS, Fireworks.fireworks()
.addEffect(FireworkEffect.builder()
.withColor(Color.GREEN)
.build()));
location.getWorld().spawn(location, Firework.```...
What is the status on this?
This PR closes https://github.com/PaperMC/Paper/issues/13890 and also handle a few things i notice when check the class...
- setItem set the item but also use any previous ItemMeta for set the item again, the PR just remove the use of ItemMeta in setItem because currently its not necesary (thanks Components)
- the helper method
applyFireworkEffectwas removed because that logic its only necesary forsetFireworkMeta - a cleanup of comments and imports
I make a few tests for this changes...
The issue reported where the second item was ignored
final Location location = player.getLocation().clone().add(0, 1, 0);
ItemStack first = ItemStack.of(Material.FIREWORK_ROCKET);
first.setData(DataComponentTypes.FIREWORKS, Fireworks.fireworks()
.addEffect(FireworkEffect.builder()
.withColor(Color.RED)
.build()));
ItemStack second = ItemStack.of(Material.FIREWORK_ROCKET);
second.setData(DataComponentTypes.FIREWORKS, Fireworks.fireworks()
.addEffect(F```...
Confirmed like you say the setItem use the previous item and mess with the final item being used.. also use unnecesary logic from the ItemMeta.
i make a PR for handle this https://github.com/PaperMC/Paper/pull/13891
I would argue then that this is more a temporary solution for people to be able to detect the different types and being able to create CAVES, FLOATING_ISLANDS and DEBUG from WorldCreator while a better more improved system can be made
I've made commits now to add a method to get the key and re-deprecated the getWorldType(), but I think the added world types should be kept for creating new worlds until said better system is made
This technically breaks the api but basically we have the data component api now and that app is scuffed so I think this is fine
I think obsolete is more appropriate until the item data component is not experimental
I think obsolete is more appropriate until the item data component is not experimental
hmm and the notice about use components api can be a <b>note<b> in the method o can just remove that mention?
The key is also a temporary measure ultimately the registry needs to be exposed and I don't think it's worth doing it rn. But the method should indeed stay deprecated.
apiNote is fine, also check ThrownPotion and other similar entities using item meta so it's consistent.
apiNote is fine, also check ThrownPotion and other similar entities using item meta so it's consistent.
Okay but i prefer make a new one for the ThrownPotion for keep the original intention of this PR (the fix of the issue and Firework Entity)
Did you figure it out a way to get that empty tag? I see the vanilla issue got closed.
Did you figure it out a way to get that empty tag? I see the vanilla issue got closed.
nope... unless any with the issue can tell the "history" of the world for even get that empty tag i dont see a way to get.. so im close this...
Related to a comment this PR set obsolete the use of PotionMeta in Potion entities, also remove the use of them in the "Craft" classes because are not necesary.
I test this PR with the follow cases...
For use a ItemMeta and set to the potion
final Location location = player.getLocation().clone().add(0, 1, 0);
ItemStack first = ItemStack.of(Material.LINGERING_POTION);
first.editMeta(PotionMeta.class, meta -> {
meta.addCustomEffect(new PotionEffect(PotionEffectType.REGENERATION, 10 * 20, 10), true);
});
final LingeringPotion entitySpawned = location.getWorld().spawn(location, LingeringPotion.class, entity -> {
entity.setPotionMeta(((PotionMeta) first.getItemMeta()));
});
PotionMeta meta = entitySpawned.getPotionMeta();
player.sendMessage(meta.toString());
Set the ItemMeta but use the item
final Location location = player.getLocation().clone().add(0, 1, 0);
ItemStack first = ItemStack.of(Material.LINGERING_POTION);
first.editMeta(PotionMeta.```...
Expected behavior
users not being able to set
level-name=
and it leading to creation of a world with empty string as a name, leading to plugin errors, because there was an assumption that world name is not an empty string.
Observed/Actual behavior
level-name=
results in creation of the world in the server root directory.
level-name=../
will attempt to create the world in the parent directory and
level-name=/home/someuser/world
will create it on the absolute path
all cases are likely to break plugin configs relying on the world name
### Steps/models to reproduce
1. start a clean server
2. set `level-name=` in server-properties
3. see all the world files dumped in the server root directory
### Plugin and Datapack List
n/a
### Paper version
n/a (present in vanilla, [bug report](https://report.bugs.mojang.com/servicedesk/customer/portal/2/MC-308240))
### Other
_No response_
Input for world names has never really be sanitized, you can create a world with name such as ../../rootworld and it will be in the parent dir. Usually this kinda is the case of just don't do it. If a malicious attacker has access to your server.properties or configuring of worlds, your server is gone either ways.
Back here because I found the Statistics api. Statistics can be edited using an OfflinePlayer instance. This might be due to their api being a bit more exposed than the player.dat file, but it just creates an empty file for them if they didn't have one already. This makes me think the best implementation for this is to just create the .dat file when a dev edits a player's PDC. Like with stats, the write operation can happen when a value is changed.
Stack trace
https://api.mclo.gs/1/raw/HMf1QmP
Plugin and Datapack List
my own plugin
Actions to reproduce (if known)
I wrote these
builder.base(DialogBase.builder(Component.text("选择存档", NamedTextColor.WHITE))
.canCloseWithEscape(false)
.body(List.of(
// DialogBody.plainMessage(Component.text("这是一条测试信息")),
// DialogBody.plainMessage(Component.text("这是一条测试信息2"))
DialogBody.item(new ItemStack(Material.DIAMOND))
// .description(DialogBody.plainMessage(Component.text("钻石一个")))
// .height(1)
// .showDecorations(true)
// .width(1)
// .showTooltip(true)
.build()```...
For reference, the issue its ItemStack not works in that phase of the server start, vanilla internally use other "type" of ItemStack for that phase what its current not available in Paper.
Expected behavior
A PlayerInteractEvent with action = LEFT_CLICK_AIR must be triggered
Observed/Actual behavior
PlayerInteractEvent is not being triggered
Steps/models to reproduce
/attribute @p minecraft:entity_interaction_range base set 10
https://youtu.be/NhFysJaVHiA
Plugin and Datapack List
none
Paper version
the second-to-last one; it doesn't make sense
Other
This can be fixed by adding the same check as in hitEntity, but replacing entity with block and entityInteractionRange with blockInteractionRange.
else if (gameType != GameType.CREATIVE && result.getHitBlock() != null && origin.toVector().distanceSquared(result.getHitPosition()) > this.player.blockInteractionRange() * this.player.blockInteractionRange()) {
CraftEventFactory.callPlayerInteractEvent(this.player, Action.LEFT_CLICK_AIR, this.player.getInventory().getSelectedItem(), InteractionHand.MAIN_HAND);
}
Fixs https://github.com/PaperMC/Paper/issues/13895 where the LEFT_CLICK_AIR action is fired based in the block range but not in the entity range.
Yep looks like a duplicate of that issue, if can answer in that if the issue is still present in 26.1.2 can be good.
Adds a new event that is called when a player selects an item in a bundle.
This pretty much enables listening for scrolling above an item. Here are some usage examples for this event:
https://github.com/user-attachments/assets/0b4b5a16-7a2a-42de-8b47-37ed68246c2c
https://github.com/user-attachments/assets/982c8ae8-c2c8-4898-bd69-a1a5458b2e37
Add a comment why this is needed
(And maybe open a MJ bug)
Added in 0115042. I'm unsure whether this is a bug or behavior intended by Mojang, given how differently creative mode inventory actions are handled.
Expected behavior
The server should automatically convert names for keys regarding feature seeds in paper-world.yml configurations in each world folder from their 1.21.11 format to their 26.1.2 format, respectively.
Observed/Actual behavior
When upgrading the server from 1.21.11 to 26.1.2, some feature seeds can not be deserialized from the paper-world configuration file because the name of the key of the feature seed is different across the versions. This causes an error like this to be shown for each feature seed that can't be deserialized:
[14:59:04] [Server thread/ERROR]: [MapSerializer] Could not deserialize key minecraft:pale_forest_flowers into net.minecraft.core.Holder<net.minecraft.world.level.levelgen.feature.ConfiguredFeature<?, ?>> at [feature-seeds, features]: Missing holder in ResourceKey[minecraft:root / minecraft:worldgen/configured_feature] with key ResourceKey[minecraft:worldgen/configured_feature / minecraft:pale_forest_flowers]
Steps/models to reproduce...
I think it may be better to view this as an inventory event? As then you can instead act on a slot in an inventory so this can be better used in inventory guis.
Also, exposing the previous selected slot would be nice.
What's the actual purpose of these?
I feel your pain. After spending a lot of time digging into this, it's clear that the "bridge" the developers mentioned in the commit has indeed collapsed for all of us.
Since it seems we're left to "cross this bridge" on our own without any one-click fix or config toggle from the server side, I've found a workaround. For those of you using mineflayer, you can simulate the missing epsilon by slightly adjusting the client-side physics.
Just add this to your bot's spawn/init logic:
if (bot.physics) {
bot.physics.playerHalfWidth = 0.302; // Restores the tiny gap needed to jump
}
It's a "client-side band-aid" for a "server-side wound," but it works. Until (or if) the devs decide to prioritize our experience over "pixel-perfect" collisions, this is the way.
Just a heads-up for everyone implementing this workaround:
If the Paper devs eventually decide to revert these changes and restore the epsilon, this client-side fix might cause slight "over-padding" (making the bot feel slightly wider than normal), which could potentially interfere with very tight navigation.
To keep your code maintainable, I suggest making this a configurable toggle in your bot's settings rather than a hardcoded value:
const usePaperCollisionFix = true; // Set to false if the server is updated/fixed
if (bot.physics) {
bot.physics.playerHalfWidth = usePaperCollisionFix ? 0.302 : 0.3;
}
This way, you can quickly switch back to vanilla physics without hunting through your code if the server-side "improvement" is ever undone.
How does this compare to vanilla? Generally this prolly won't be fixed because we prefer vanilla behavior.
Inventory event does make more sense as the supertype for this event: PlayerBundleItemSelectEvent now inherits InventoryEvent. Added slot and previous index/item fields.
Why modifying the line just to add the FQN?
Why modifying the line just to add the FQN?
This doesn't match any removed lines, are tou sure this is needed?
I moved the line below the Paper additions, as specified in the comment
That was unintentional, reverted in 7804af6
But you're not actually moving it if you'll look at the patch, you're just inserting the additions before it, so there's no need for this comment
Can this also be made cancellable? Also, move most of this logic to craft event factory.
Note you'll need to resend the item
Removed in a0ded529266c6fccdbd8fe96e9b8169042432fac
What's the actual purpose of these?
An option to set the List gamemode independently of the normal gamemode, similar to the Player List Name
That's the what but not the why - to disable spectator italics, or something else? Using the wrong game mode in player data for the client it belongs to has a whole bunch of bad side effects
I now moved all of the firing logic to the craft event factory; not sure how the logic could have been split up.
I am having a similar issue with the following stack trace:
`---- Minecraft Crash Report ----
// There are four lights!
Time: 2026-05-21 18:19:38
Description: Exception in server tick loop
java.lang.RuntimeException: Failed to migrate world storage for world_nether
at io.papermc.paper.world.PaperWorldLoader.getWorldInfoAndData(PaperWorldLoader.java:65)
at io.papermc.paper.world.PaperWorldLoader.loadInitialWorld(PaperWorldLoader.java:150)
at io.papermc.paper.world.PaperWorldLoader.loadInitialWorlds(PaperWorldLoader.java:139)
at net.minecraft.server.MinecraftServer.loadLevel(MinecraftServer.java:650)
at net.minecraft.server.dedicated.DedicatedServer.initServer(DedicatedServer.java:382)
at net.minecraft.server.MinecraftServer.runServer(MinecraftServer.java:1301)
at net.minecraft.server.MinecraftServer.lambda$spin$0(MinecraftServer.java:304)
at java.base/java.lang.Thread.run(Thread.java:1474)
Caused by: java.io.IOException: Refusing to overwrite existing migrated file ./world/dim`...
@Whatnoww You need check the worlds before to migrate because world and world_nether has the DIM-1 directory.. you need first (with the backup) remove the DIM-1 from the world and try again the migration
Im going to close this because based in https://github.com/PaperMC/Paper/issues/13863 its an issue where worlds to migrate share the same DIM directory.
Exists a PR https://github.com/PaperMC/Paper/pull/13872 for make more clear this error.
Thanks for your help, removing DIM-1 from under the world worked just fine.
This most likely will not be accepted. Using this for client hacks isn't something that is nicely able to be supported esp for the future.
i find myself in need of an event like this but for a different reason, im building a progression system and would have liked to grant skill xp when a player repaired items in an anvil. Using InventoryClickEvent as said above is very unreliable (lets say the bottom inventory cant hold the item and the click type is shift click, i would need to test the entire inventory, for example) and has the possibility for false flags. a dedicated use event would be really nice.
PrepareAnvilEvent can't be used for this either since it only gets fired when the anvil recalculates stuff (at which point the result slots are empty if the anvil is used)
Is your feature request related to a problem?
related to #13575
The grindstone and the anvil are the only workbenches who don't have a 'use' event related to their 'PrepareResultEvent' event.
e.g. PrepareSmithingEvent has SmithItemEvent, PrepareItemEnchantEvent has EnchantItemEvent, etc.
I require this functionality to be able to award skill xp for a progression system, for example.
Describe the solution you'd like.
Add GrindstoneItemEvent, (and AnvilUseEvent #13575), so that these actions can be properly detected,
or a more generic CompleteResultEvent, that would apply to all PrepareResultEvent events, when a result is completed.
Describe alternatives you've considered.
Listening to the InventoryClickEvent, but this requires hacky prediction of whether the item will actually leave the result slot.
Other
No response
I don't think there was never any migration for removed configured features? I always thought the expectation was for you to just remove the invalid ones upon updating, this was previously also reported in #8277 which was closed as WAI
Please use the discord server for support next time, there is currently not enough to go off of here.
I'm leaning towards this being WAI, chunks and entities are no longer saved in the same spot so the API also shouldn't pretend that they are, is the EntitiesUnloadEvent missing anything that you'd need to solve your issue?
af0969f Fix some hunk comments pretending to include mojan... - lynxplay
I don't think this is the best way to resolve this, it would seem better to me to update the check in readModernModifications to avoid setting FORMAT_CHANGED to true if both the original renderer and the new renderer are default ones
More like a QoL update
Wouldn't this just be addRotation?
Which, fair addition, I am just not very happy with the method name and parameters, they look to be copying internals one to one and seem very clunky.
Unable to reproduce this issue with the steps you have provided, this issue is likely caused by one of your many plugins other than the ones you've already rules out.
I am unable to reproduce any of the behaviors you've mentioned, and since you also have not provided any other information than that there's really nothing we can do here. What you're describing does sound like what some naive lag "fixing" plugins might cause, but you claim you're only running essentials, so, yeah
Please re-test with just moonrise like Lulu asked if you still can
Wouldn't this just be
addRotation? Which, fair addition, I am just not very happy with the method name and parameters, they look to be copying internals one to one and seem very clunky.//edit: Might not have said this nicely, there is obviously a different in the method as ServerPlayer makes use of those booleans to send the relative update packet instead. This is purely about naming of the API method.
if renamed to addRotation, the relative parameters will look more confusing, or you mean method like addRotation(yaw, pitch)?
I'd prefer just keep it. I added a note, which may be better
The paste has expired and the reporters account is also deleted, if this still happens in the current version then feel free to make a new issue.
Would you have any suggestions for how the administrator check could be improved in this case?
I'm leaning towards this being WAI, chunks and entities are no longer saved in the same spot so the API also shouldn't pretend that they are, is the EntitiesUnloadEvent missing anything that you'd need to solve your issue?
I forgot to reply to masmc, but yah that event works fine, thanks.
Maybe can be good add a message for notice comes from the config?
because the error just says cannot serialize and before of that the dimension....
I don't know how to install moonrise and I think it's a bit much to get me to install other software to test a bug. I've included a full description and the world download so anyone can replicate it, as long as the world download still gives the same result on paper then there is no more information required from me.
Yeah, use PrePlayerAttackEntityEvent.
The cooldown is computed before the damage is now, which is proper.
The key that the server says cannot be deserialized is found in the paper-world.yml config before upgrading, and disappears after upgrading, so it is correct that they are getting removed. However, upon checking the paper-world.yml after upgrading, I found many keys with similar names to the ones that got removed, many of which just have the word "patch_" removed from the beginning of the key (ex: minecraft:patch_pumpkin -> minecraft:pumpkin). I cannot say for certain that the old and the new keys with similar names are used for the same thing when generating the world, but if they are, Im not sure changing feature seeds is healthy for the world...
Also, I counted 25 keys that could not be deserialized and got removed, and the server only regenerated 22 keys after the 25 keys got removed, so three keys were completely removed from the config
The past issue was marked as WAI as the error is kinda expected when stuff doesn't miss, there isn't any real means of automating the upgrades of this stuff too well, so it kinda falls by the wayside; That stuff is all backed off of Mojang's registries, and given that this is all basically generation stuff which doesn't get serialised, there is no migration logic inside of vanilla at all, and nothing we have to hook.
Is your feature request related to a problem?
I currently have 27 worlds loaded on my Paper instance, but aside from the three main worlds, the rest are archive worlds in past 10 years. The three main worlds run on local high-speed NVMe SSD storage, while the archive worlds are mounted to the world path via Samba/CIFS from a slow HDD NAS on the local network since my players only visit these worlds during nostalgia events, there is no player activity on them at other times.
Due to the NAS's heavy workload (continuous backups, deduplication, compression, and checksumming) and the fact that it runs on HDDs, its I/O performance is poor. Although Paper's chunk system handles these slow read operations effectively, preventing them from affecting the game server itself, the operation to save level.dat still runs on the server thread. This causes the server to experience a spike in lag every so often (when you have a lots worlds, it will keep and continuously). Although these spikes las...
Adds documentation for the optional paper-generator project in CONTRIBUTING.md.
Changes
Documented the existence and purpose of the optional paper-generator module
Added instructions for enabling the project through paper-generator.settings.gradle.kts
This helps contributors better understand the development setup and optional project configuration available within the Paper repository.
Expected behavior
I expect to see the speed not reset when the ender pearls are dropped.
Observed/Actual behavior
I see that when I flip the ender pearl, the speed is reset, although it shouldn't be.
Steps/models to reproduce
when a player goes forward or flies on elites and throws an ender pearl forward or throws an ender pearl into a vortex charge on elites, his speed slows down and he hovers in the air for a while or just stops on the ground, that is, slows down
Plugin and Datapack List
No
Paper version
26.1.2-65
Other
there is an example of the Pearl Momentum Fix plugin, but the problem is that because of it, players have a bug that sometimes they can just jump or take off on the spot, this should not happen, but the description of the plugin is correct and it needs to be done because the plugin does not cope with it.
while documenting the generator, you should also document how to add things to it, when it’s useful and how to run it so that the changes you made get generated in the source
Expected behavior
When opening a villager merchant menu for a player using the Paper API, I expected the villager's reputation-based trade behavior to work the same as when the player normally interacts with that villager.
For example, discounts or price changes caused by villager reputation should be applied to the trades shown in the merchant menu.
Observed/Actual behavior
When opening the merchant menu using MenuType.MERCHANT.builder(), the villager's reputation-based trade behavior does not appear to work.
The menu opens successfully, but the trades do not reflect the villager's reputation data for the player.
Code used:
MenuType.MERCHANT.builder()
.merchant(villager)
.checkReachable(false)
.build(player)
.open();
### Steps/models to reproduce
**Steps/models to reproduce**
```markdown
1. Start a Paper server with a plugin that opens a villager merchant menu using the Paper menu API.
2. Get or spawn a villager with trades.
3. Give the player a reputa...
Well the logic for reputation is when you interact with the villager (before create the inventory to show), in the case of the MenuType you directly build the inventory then that step are ignored (like in HumanEntity#openMerchant)
Not sure for my if was intended or not... if its not intended then a fix can be call that method in HumanEntity#openMerchant and the CraftMenu#openMerchantMenu (used by the open() method in the MenyType API)
It would require more than that since the api allows several players to open same merchant, but most probably this needs a separate option to show the personalised costs
It would require more than that since the api allows several players to open same merchant, but most probably this needs a separate option to show the personalised costs
a little confuse if consider the builder require pass a Player to assign not?
Talking in discord about the Villager and the inventory this PR handle a behaviour noticed in https://github.com/PaperMC/Paper/issues/13905 where the methods to open inventory related to Villager ignore the update price for reputation or hero of the village, the only "breaking" change here is if user dont expect to get that change of prices, but just need use https://jd.papermc.io/paper/26.1.2/org/bukkit/inventory/MerchantRecipe.html#setIgnoreDiscounts(boolean) for make clear dont wanna updates in the prices.
Thanks @Y2Kwastaken and @masmc05 for the help with the Inventory behaviour.
In case this was an issue when the API was added time ago i make https://github.com/PaperMC/Paper/pull/13906 with a change for make villager change the prices unless the recipe deny that..
@amownyy if wanna test the PR include a JAR with the change.
Yea seems fine
<img width="448" height="131" alt="Image" src="https://github.com/user-attachments/assets/d469dd92-2370-4809-a39d-f521bfb17112" />
There are currently no events that supply the blocks used in the creation of a golem which can be incredibly annoying to detect manually, the aim of this PR is to solve that by introducing an event exposing the blocks before a golem is spawned in.
Currently the only way to get the entities loot on death is using EntityDeathEvent#getDrops, but that also includes drops from things like chest horses, boat chests, blocks held by enderman, etc.
If you only want to mutate that entities loot table you have to manually handle every edge case which is painful to say the least.
EntityLootGenerateEvent is intended to solve the gap.
That doesn't really answer the question - to disable spectator italics, or something else? Using the wrong game mode in player data for the client it belongs to has a whole bunch of bad side effects
Yes, most likely to disable the spectator format.
Stack trace
Plugin and Datapack List
Only have plugin!
pl
[10:28:58 INFO]: ℹ Server Plugins (43):
[10:28:58 INFO]: Paper Plugins (4):
[10:28:58 INFO]: - AdvancedServerList, MCKotlin-Paper, paper-language-kotlin, surf-serverbrand-customizer
[10:28:58 INFO]: Bukkit Plugins (39):
[10:28:58 INFO]: - ActionGlass, AnarchySpawn, AntiCheatAddition, AntiLoggedInFromAnotherLocation, AttackCooldownRemover, AttributeSwapFixer, BlockChat, BlockReports, Bunnysquad, BushRehab
[10:28:58 INFO]: LHTab, Milk, NewJoinMessages, NoChatLagServer, NoSleep, OtherBedRegen, OxygenGamemodeLock, packetevents, ProtocolLib, ReducedDebugInfo
Actions to reproduce (if known)
Can I add the repair update to papermc 1.21.11?
Moonrise is a big problem
Some cheating clients, such as PacketFly, can also experience the same crash
Paper version
ver
[10:29:28 INFO]: Checking version, please wait...
[10:29:28 INFO]: This server is running Paper version 1.21.11-132-ver/1.21.11@c5eb079 (2026-05-11T11:...
This is a problem with Moonrise
and
#132
2026/5/11 19:43:09
c5eb0790f199da6c38d0a650e1e5cd5415b28185
Fork friendly byte buf correctly
paper-1.21.11-132.jar
The release is completely unrelated
The symptoms are simple
A certain core of the CPU is running at 100% lag
[10:33:45 INFO]: UUID of player StoodMusic58914 is d1793670-3689-3b2a-8b70-c5ecabd45331
[10:33:50 WARN]: [ca.spottedleaf.moonrise.patches.chunk_system.level.entity.EntityLookup] Entity uuid already exists: 64b08d5b-9cec-4a20-8cf9-53dfb04c815e, mapped to Skeleton['Skeleton'/9295, uuid='64b08d5b-9cec-4a20-8cf9-53dfb04c815e', l='ServerLevel[world]', x=-196.50, y=79.92, z=301.35, cpos=[-13, 18], tl=0, v=false], can't add Skeleton['Skeleton'/29296, uuid='64b08d5b-9cec-4a20-8cf9-53dfb04c815e', l='ServerLevel[world]', x=-196.50, y=79.92, z=301.35, cpos=[-13, 18], tl=0, v=false]
Moonrise crashes again after entering the same chunk
Need a crash log, otherwise it's useless
Also looking at your list of plugins, it's just awful.
kill @e
kill @e
kill @e
kill @e
kill @e
kill @e
[10:44:05 INFO]: UUID of player SM_Games is 6adde1b9-ac7d-37a4-8c21-a58b5dd98e0b
kill @e
kill @e
kill @e
kill @e
kill @e
kill @e
kill @e
[10:44:07 INFO]: Killed 31 entities
kill @e
kill @e
kill @e
[10:44:07 INFO]: Killed 718 entities
[10:44:07 INFO]: Killed 573 entities
kill @e
kill @e
kill @e
kill @e
kill @e
kill @e
kill @e
kill @e
kill @ekill @e
kill @e
kill @e
kill @e
kill @e
kill @e
[10:44:10 INFO]: Killed 28432 entities
kill @ekill @e
[10:44:10 INFO]: Killed 28449 entities
kill @e
[10:44:10 INFO]: Expected whitespace to end one argument, but found trailing data
kill @ekill @e<--[HERE]
kill @e
kill @e
kill @e
kill @e
[10:44:11 INFO]: Killed 14545 entities
kill @e
[10:44:11 INFO]: Killed 10364 entities
kill @e
kill @e
kill @e
kill @e
kill @e
kill @e
kill @e
kill @e
[10:44:13 INFO]: [+] SM_Games joined the server.
Welcome to SM.SMP
kill @e...
Yes
I used entity cleaning to restore the issue
I hope papermc 1.21.11 can fix this issue
Updated to the support series of papermc 1.21.11
kill @e
kill @e
kill @e
kill @e
kill @e
kill @e
[10:44:05 INFO]: UUID of player SM_Games is 6adde1b9-ac7d-37a4-8c21-a58b5dd98e0b
kill @e
kill @e
kill @e
kill @e
kill @e
kill @e
kill @e
[10:44:07 INFO]: Killed 31 entities
kill @e
kill @e
kill @e
[10:44:07 INFO]: Killed 718 entities
[10:44:07 INFO]: Killed 573 entities
kill @e
kill @e
kill @e
kill @e
kill @e
kill @e
kill @e
kill @e
kill @e
kill @e
kill @e
kill @e
kill @e
kill @e
kill @e
[10:44:10 INFO]: Killed 28432 entities
kill @Ekill @e
[10:44:10 INFO]: Killed 28449 entities
kill @e
[10:44:10 INFO]: Expected whitespace to end one argument, but found trailing data
kill @Ekill @e<--[HERE]
kill @e
kill @e
kill @e
kill @e
[10:44:11 INFO]: Killed 14545 entities
kill @e
[10:44:11 INFO]: Killed 10364 entities
kill @e
kill @e
kill @e
kill...
Thanks for the issue report, but this is most likely some kind of performance issue and not a bug.
It looks like you are repeatedly running the @e selector. This is incredibly bad for performance, as it will iterate through all entities on the server every single time
If you need further help, please use the #paper-help channel on our discord server for support with this.
I was thinking: would it maybe be a good addition for the event to expose a getSelectionDelta / getScrollDirection method to simplify the GUI scrolling handling? I'm guessing this event will mainly be used for GUI-related stuff anyway.
It does it in the other constructor where the namespace is derived from a plugin, but not when it is a string. It just runs String#toLowerCase on the namespace and key parameters, using the Locale.ROOT parameter.
The other constructor is doing that because the plugin name can be not lowercase which is valid usage. Here this is masking invalid inputs without the developer properly considering side effects
How is it valid usage because of the namespace being lowercase? The key in the other constructor is made lowercase automatically, so I thought this would be acceptable.
How is it valid usage because of the namespace being lowercase? The key in the other constructor is made lowercase automatically, so I thought this would be acceptable.
It is made lowercase automatically when supplying an input because you do not control the input directly. Most plugins have a uppercase letter in their name somewhere which is a valid thing, and it would be a breaking change if every author would have to change this in order to use NamespacedKey. When specifying the namespace manually, you are in control, so this is no longer an issue and the correct requirements are enforced
because you do not control the input directly
You do though? I was talking about the key, not the namespace. You directly control the key, but it is still made lowercase. Should this change be removed?
When specifying the namespace manually, you are in control
I haven't been talking about the namespace, I've been talking about the key.
In both scenarios, you have full control over the key, but it is still changed to be made lowercase when the plugin class is specified. I also made the namespace string be lowercase because I though it'd be weird to throw errors for a capitalized namespace but not for a capitaized key.
I mean, we cannot really remove it now as it already exists in the plugin constructor of NS without breaking backwards compatibility. that bit of the namespaced key constructor was inherited from spigot,
I agree with the above comments tho. Manually and quietly changing the key to lowercase seems only harmful when developers should very much be forced to use correct casing for these inputs.
There's currently no event that fires when a creeper's swell level changes, and there's currently no way to stop a creeper from swelling. CreeperIgniteEvent does not fire when a creeper primes due to proximity, EntityExplodeEvent only fires at the end of swelling, and GenericGameEvent of type GameEvent.PRIME_FUSE doesn't allow for cancelling and doesn't fire for individual swell steps.
The proposed CreeperSwellEvent fires whenever a creeper's internal swell level changes, and it also differentiates different reasons for the swell: PRIMED (proximity or ignition), FALL_DAMAGE (falling from a height), or CUSTOM (plugin adjusting swell).
Fixes #12620
There's currently no event that fires when a creeper's swell level changes, and there's currently no way to stop a creeper from swelling. CreeperIgniteEvent does not fire when a creeper primes due to proximity, EntityExplodeEvent only fires at the end of swelling, and GenericGameEvent of type GameEvent.PRIME_FUSE doesn't allow for cancelling and doesn't fire for individual swell steps.
The proposed CreeperSwellEvent fires whenever a creeper's internal swell level changes, and it also differentiates different reasons for the swell: PRIMED (proximity or ignition), FALL_DAMAGE (falling from a height), or CUSTOM (plugin adjusting swell).
Fixes #12620
-
Why wouldn't the client reflect the unswelling if cancelled, as it does if you back off from a creeper?
-
I see you're firing a swell event on cancelled explosion. Bizarre edge case question: What happens if someone is always cancelling explosion events and then cancels that specific post-cancel swell event as well? Will the creeper be continuously trying to explode?
After reading your reply, I noticed a bug that would let a primed creeper's swell level to continue to change even if the event was cancelled. It happened because cancelling the event set the final swell change to 0, so the vanilla logic kicked in and continued to increment the swell level. Now, the tick function will instead check for a nonzero swellDir to decide whether or not to fire the event and handle its cancellation state.
- Why wouldn't the client reflect the unswelling if cancelled, as it does if you back off from a creeper?
The client does render an unswell, but it seems like the client is only programmed to render a full swell in one direction. For example, if I use this code in a plugin to only allow a creeper to swell half-way:
@EventHandler
public void onCreeperSwell(CreeperSwellEvent event) {
if (event.getCurrentSwell() + event.getFinalSwellChange() > event.getMaxSwell()/2)
event.setCancelled(true);
}
the client still sees the...
Expected behavior
ItemStack.getItemMeta() should work safely when called from multiple virtual threads concurrently.
Observed/Actual behavior
CraftMetaItem.updateFromPatch() throws NullPointerException at line 547 because ImmutableCollections$SetN.contains() receives a null argument. This happens when multiple virtual threads call getItemMeta() concurrently (via a plugin's async processor).
The UI still renders after a retry, so it's non-fatal but produces log spam.
Steps/models to reproduce
- Have a plugin that creates/accesses ItemStacks on virtual threads (or any async thread pool)
- Multiple threads call ItemStack.getItemMeta() concurrently
- NPE in updateFromPatch
Plugin and Datapack List
ℹ Server Plugins (43):
Paper Plugins (1):
- FancyHolograms
Bukkit Plugins (42): - 3DManeuverGear, AdvancedReplay, AlonsoLevels, AneCustomToast, AntiPopup, BrickThrower, Economy, ExtraSpecialItems, FakeBedWars, FakeExItems
FakeRush, FakeServer, Gen-Splitter, Item...
minimum reproduction? These operations are not thread safe
Were paper-server/patches/sources/org/apache/logging/log4j/core/appender/AsyncAppender.java.patch or paper-server/patches/sources/org/apache/logging/log4j/core/appender/AsyncAppenderEventDispatcher.java.patch intended?
No something in my unpick died. I'll force push over in a bit.
Fixed in latest pre release
I could maybe see a use case for being able to set one part of the rotation relative and the other absolute, which wouldn't be possible with just an addRotation(yaw, pitch) method. I'm not immediately a fan of the current proposed method since I dislike having ambiguous boolean parameters in methods, something like a setRotation(Something.relative(2f), Something.absolute(90f)) could fix that.
From: https://github.com/PaperMC/Paper/issues/12986#issuecomment-3217402824
Hi, any updates? I've come up with another fix: let projectiles force-load the chunk they're in. Once that chunk can tick, thedespawn-timehas enough time to remove the projectile. For safety, we could cap how many chunks a single projectile can load. Does that sound feasible to you?
I have come up with a different solution plugin-wise. Since World.getEntities and World.getEntitiesByClass return all accessible entities, we can loop through all entities and exclude the ones that are ticking.
This code will remove all entities in non-ticking chunks, which is not good, but this could be a starting point if you are still having this issue
(I also have not benchmarked it at all)
for (final var bWorld : Bukkit.getWorlds()) {
if (bWorld.getPlayers().isEmpty()) {
continue;
}
final var list = bWorld.getEntities();
final var chunksToLoad = new LongArraySet();
for (final var entity : list) {
if (entity```...
If there's no issue on the current version then I don't exactly see why this should change, I tested it on 1.21.11 and 26.1.2 and it works fine on both for me.
Given that this doesn't really document what the generator actually does and how to use it, and there seems to be some undisclosed LLM usage, I am inclined to just close this.
Is there any chance of this getting fixed any time soon? It is a major bypass for protection plugins :/
I added this to my own Paper fork, figured it was nice API for others to use too
The import and maybe add the Precondition for null
i think you can add the import here.
I also added this to my own Paper fork, and again figured it was nice API for others to use too
Preconditions.checkArgument(entity != null, "entity cannot be null");
im not sure about the name also based in NMS this is not the full logic for consider its a critical (fullStrengthAttack in NMS) so maybe you can mention in the docs...
I can add the fullStrengthAttack logic too if you want?
it would defo make more sense in the way I use this API in my own project to also account for that
hmm i fell can be good expose that
not sure I know what you mean by that ngl xd
this is to support node 24 - https://github.blog/changelog/2025-09-19-deprecation-of-node-20-on-github-actions-runners/
I can update the actions in the other workflows but some of them are no longer being updated, and need a replacement, like https://github.com/marketplace/actions/close-pull-request.
Hi, this changes was already proposed in https://github.com/PaperMC/Paper/pull/13222
Thanks for your interest in contributing in paper, unfortunately I'll have to close this since doc's PR already covers this :)
I kinda know, the likelyhood that this will be accepted is slim, but this PR adds per player Quick Actions & Pause Menu Additions by hijacking the default Quick Actions & Custom Options dialogs and adding it to the corresponding Tag.
I would have rather wanted to add 2 extra pre packaged dialogs, but I couldn't find out how to do that.
example usage:
@EventHandler
public void onPlayerDialog(PlayerDialogsReceiveEvent event) {
getLogger().info("Setting Dialog");
event.setPauseMenuAdditions(Dialog.create(builder -> builder.empty()
.base(DialogBase.builder(Component.text(event.getConnection().getProfile().getName() + "'s Pause Menu")).build())
.type(DialogType.notice())
));
event.setQuickAction(Dialog.create(builder -> builder.empty()
.base(DialogBase.builder(Component.text(event.getConnection().getProfile().getName() + "'s Quick Actions")).build())
.type(DialogType.notice())```...
Can be good expose the fullStrengthAttack in the API.
under what scenario did you test it?
I would have rather wanted to add 2 extra pre packaged dialogs, but I couldn't find out how to do that.
You can register them in bootstrap. Just add the dialogs in registry events then reference them in corresponding tag in the tags pre flatten events
Tested with fabric 26.1.2 and Moonrise version: https://modrinth.com/mod/moonrise-opt/version/G0OgMSn1
Vanilla/Fabric 26.1.2 without Moonrise works.
This variable totalEntityAge seems always being saved, but only loads if entity is LivingEntity.
I believe there was a reason not to load it when it was tickCount, but since we have separated that, I don't see a reason why we don't load it anytime.
despawnTime could behave better on some projectiles (like wither skull) after this.
It seems to have been done kinda on purpose in https://github.com/PaperMC/Paper/pull/12077#discussion_r1949547475 to not break the API, now this is indeed weird for the config value.
Also this is added code by us so can just remove the if statement here.
I don't think that's the right keys too, the closest thing to how WorldType is used rn seems to be WorldPreset in internal for example doing WorldCreator.ofKey(NamespacedKey.fromString("abc")).type(WorldType.FLOATING_ISLANDS).createWorld()
log the following message: "Failed to parse level-type floating_islands, defaulting to minecraft:normal"
It was working in my testing, I'll take another look later
If statement is now removed.
I think we could keep the old API behavior.
bukkitEntity.getTicksLived now returns totalEntityAge , we can make it returns tickCount for non-LivingEntity.
However, I think a better approach, is to add new API, so dev can get both tickCount and totalEntityAge.
One for total age; One for ticked times since it's loaded.
Is your feature request related to a problem?
This event would make it possible to know whether a spear has caused an entity to be dismounted.
Describe the solution you'd like.
A new event that is fired when a spear stab attack happens so that plugin developers can know when vehicles will be dismounted as a result of the spear attack.
Describe alternatives you've considered.
Looking at the VehicleExitEvent and getting data from the Entity's last damage event to check if it was attacked using a spear (DamageType).
Other
No response
Any reason to not just set expToDrop to 0 in skipDropExperience?
then the API changes are not needed and the added wasExperienceConsumed check can be removed as well
Is your feature request related to a problem?
I know chunks are updated on load. But I need to convert 1.14/1.17 worlds to .slime format with AdvancedSlimePaper on 26.1.2, and ASP reads from disk, discarding old chunks. Without forceUpgrade (not implemented in 26.1) and without saving the world, how do I get the updated chunks to disk? i make custom fork plugin from originale source code of Slime-World-Manager native 26.1.2 this is why i need this features if is possible
Describe the solution you'd like.
a input for start bat who convert and upgrade old block from 1.14 to 26.1.2
Describe alternatives you've considered.
--force-upgrade --erase-cache nogui
Other
No response
That's a bit weird to create a new Mutable instance just for this check can you inline this logic.
Should clone all the mutable items.
That event is now called with the same entity/pusher for the player which feels weird.
Generally changing the damage source is still a vanilla break, for example if the wind burst explosion touch a projectile like a floating fireball, the owner will be set unlike before.
I think getSoundPitch is better, don't really need to copy internal here especially since it's not only used for mob's voice.
10a73fe Add and clarify Attribute#getDefaultValue (#13345) - Warriorrrr
976 does not match world version 4790
a workaround could be using chunky to perhaps load all those chunks, which would cause them to get converted and then saving the world.
Make sure to set the radius to the radius of the world or bigger and enable force-load-existing-chunks in chunky’s config file
Is your feature request related to a problem?
Yes.
Plugins may need to associate information collected during the handshake phase with the player that later reaches AsyncPlayerPreLoginEvent, PlayerLoginEvent, or PlayerJoinEvent.
Currently, the only common identifier available in the early stages of the connection process is the remote IP address. However, IP addresses are not a reliable way to correlate a specific connection, as multiple connections can originate from the same address.
As a result, it is difficult for plugins to reliably determine which handshake belongs to which login attempt.
Describe the solution you'd like.
Expose a stable connection identifier (for example, getConnectionId()) that is available throughout the entire connection lifecycle.
The identifier should remain the same from the initial handshake until the connection is either closed or the player fully joins the server.
Ideally, it would be accessible from events such as:
- PlayerListPingEven...
This would be a really useful feature if it got added to Paper, because I’ve run into this exact issue while writing plugins too.
Tried move those worlds to local HDD and there doesn't seem to be any significant improvement.
Since they are "archive" worlds, you can set chunks.auto-save-interval to -1 in paper-world.yml to disable auto save.
Btw, player data saving is also always on server thread. It operates 3 files once for each player, that's heavier than level data auto save.
This doesn't makes sense if the entity is not spawned yet it shouldn't have a SpawnReason. DEFAULT would imply the entity spawned without a specified reason. I think the method should just be nullable if it's the only case this happens.
Replaces https://github.com/PaperMC/Paper/pull/8525
Both wither skulls and carved pumpkins fired a BlockDispenseEvent twice if they didn't spawn a mob.
This is possibly a behavior change, but as usual, it's actually a bug fix so the behavior before was wrong.
In general if the dispense action fails completely no event occur (i.e the item is not dispensed nor consumed), the event is only triggered for the action that will succeed (that is partially true currently but should be better now).
Also moved fluid pickup game event after the event for taking liquid in bucket since the event is cancellable.
Previously summoned trident would only dealt 2 damage points instead of the usual 8 like in vanilla.
This adds a few new thread checks to Paper and replaces some AsyncCatcher calls with more specific checks using the TickThread class. This enforces against operations like opening/closing inventories async, or trying to kill an entity async for example.
3580fa4 Use internal block to item conversion for flower p... - MartijnMuijsers
i'd say this event is now feature-complete pretty much (bump)
I'm going ahead closing this, it's better to draft the API in the issue first but anything extending the transform event can't be used in the current state. Only the variant change not the entity type and the PigZapEvent is a bad example mostly redundant with the parent event.
Could easily be expanded to the wither if you don't mind having a slightly more generic EntityConstructEvent.
Should document the fact that this also include required air/empty blocks to spawn the entity.
Could easily be expanded to the wither if you don't mind having a slightly more generic EntityConstructEvent.
oh good point ill do that
Is your feature request related to a problem?
Yes. Currently, server administrators can only configure entity tracking ranges globally via the Spigot/Paper configuration files. For plugin developers, this blanket approach is highly limiting. There is no existing API method to modify these visibility distances dynamically or target specific, individual entities.
Describe the solution you'd like.
I would love to see an API implementation that allows developers to override the standard tracking range categories on a case-by-case basis per entity. This would allow us to drastically extend the view distance of important custom entities (like boss mobs or markers) or reduce it for performance optimizations without impacting the rest of the server.
Describe alternatives you've considered.
Adjusting global settings is the only current workaround, but it forces a choice between overall server performance and specific gameplay features.
Other
A similar concept was previous...
Since they are "archive" worlds, you can set
chunks.auto-save-intervalto -1 in paper-world.yml to disable auto save.Btw, player data saving is also always on server thread. It operates 3 files once for each player, that's heavier than level data auto save.
Its still need to save since players will play a while on archived worlds.
Furthermore, adjusting the auto-save interval doesn't seem to solve the problem; it just makes it happen less frequently.
The javadoc comments for AreaEffectCloud#setRadiusPerTick and AreaEffectCloud#setParticle had some issues
Set chunks.auto-save-interval to -1 should disable level data saving and chunks auto save, if there's no other plugins trying to save or unload the worlds. Chunks will still save on unload. Level data saves on shutdown. Both can be saved by /save-all or World.save().
There are cases that some chunk data have to syncLoad on server thread, mostly poi searching, can be triggered by for example using eye of ender / entity AI. It may be alleviated by increasing region file cache.
About the async issue.. Mojang does have a async saving logic for other level data (maps, raids, etc.), however for level.dat it's on server thread though it does not require much changes for async. There's no reason, maybe Mojang thinks it's a crucial file. However, Their file operations is not atomicly, so it's possible to leave no level.dat file if the process get terminated.
Add configuration for these new options
f34e0a0 Some blonks - Owen1212055
89050a2 Some blonks - Owen1212055
b538e4a Some blonks - Owen1212055
5b67591 connection - Owen1212055
56e1e6e proj - Owen1212055
e425132 creaking, diff drop is intentional - Owen1212055
c583963 raid - Owen1212055
99b9a98 team - Owen1212055
e18dfb9 fireball - Owen1212055
ac37551 bucketable - Owen1212055
015810d rabbit - Owen1212055
02d0eeb frog - Owen1212055...
349e884 Make world better a little better imo - Owen1212055
54387d3 fix convertTo method not being resolved in Abstrac... - Warriorrrr
Reapply Patch #1279
Spigot 1.13 checks if any field (which are manually copied from the ItemStack's "tag" NBT tag) on the ItemMeta class of an ItemStack is set.
We could just check if the "tag" NBT tag is empty, albeit that would break some plugins. The only general tag added on 1.13 is "Damage", and we can just check if the "tag" NBT tag contains any other tag that's not "Damage" (https://minecraft.gamepedia.com/Player.dat_format#Item_structure) making the
hasItemStackmethod behave as before.Returns true if getDamage() != 0 or has damage tag or other tag is set.
In Paper 1.20.4 there was still this patch: https://github.com/PaperMC/Paper-archive/blob/ver/1.20.4/patches/server/0221-Don-t-call-getItemMeta-on-hasItemMeta.patch, probably just did not survive the component rewrite
Netty does not guarantee that a write future listener will run before later packets are queued for write. This can cause packets send after the compression packet to not be compressed even though the client expects them to be compressed. When using nio/epoll the write future is often completed right after the write is ran so this race condition doesn't really happen, however I do suspect there might be cases where it can rarely happen (like kernel buffers being full)
However if you implement io uring support you'll notice that this race condition constantly happens. This is is due to the future being resolved way "later" due to the split in submission / completion queue in io uring. This explains why previous attempts to adding io uring support in Paper had issues with compression https://github.com/PaperMC/Paper/pull/9141
This pr fixes it by actually setting up the compression right after writing the compression packet.
tdlr: fixes login compression errors that are rare with...
Is your feature request related to a problem?
I wanna get the SpawnCategory for the EntityType and dont wanna summon an entity for get the SpawnCategory
Describe the solution you'd like.
A EntityType#getSpawnCategory
Describe alternatives you've considered.
Use paperweight.userdev for allow me to use the Craft class to convert to NMS EntityType get the Category and convert to Bukkit like this.
public static SpawnCategory getSpawnCategory(final EntityType entityType) {
return org.bukkit.craftbukkit.util.CraftSpawnCategory.toBukkit(CraftEntityType.bukkitToMinecraft(entityType).getCategory());
}
Other
No response
This is the continuation of https://github.com/PaperMC/Paper/pull/13465 for context.
Can you make a documentation pr too?
I also was investigating on this issue and made a similar fix to yours, although I handled it with the PacketSenderListener:
+ this.connection
+ .send(
+ new ClientboundLoginCompressionPacket(this.server.getCompressionThreshold()),
+ PacketSendListener.thenRun(() -> {
+ this.connection.setupCompression(this.server.getCompressionThreshold(), true);
+ this.connection.send(new ClientboundLoginFinishedPacket(gameProfile));
+ })
+ );
Something I wanted to note, is that Mojang seems to have created a Netty adapter that does literally nothing at Connection#configurePacketHandler L681.
I have the ~unconfirmed~ suspicion that this handler, considering its name, was made by Mojang to probably delay the packet sending enough to let the compression/decompression handlers be registered, which apparently io_uring is outspeeding. A more...
ca5e948 Fix override of new item for Firework entity (#138... - Doc94
20938c7 Set Obsolete the use of PotionMeta in Potion entit... - Doc94
76d2ac7 [ci skip] Fix AreaEffectCloud doc comments (#13926... - 99-i
Allow to fetch it in the configuration phase after PlayerConnectionInitialConfigureEvent for other events taking only the connection.
This is similar to #13552
Given this already break since 1.20.6, i'm not sure the damage exclusion is really needed now (which will break things again).
To complement the work done by Beanes in https://github.com/PaperMC/Paper/pull/13929, this PR implements io_uring transport to Paper, including its version of Unix Domain socket support.
As such, this PR depends on https://github.com/PaperMC/Paper/pull/13929 being merged first, as currently Minecraft seems to rely on a hacky workaround to hide a race condition while setting up compression.
I do agree that Paper might not get a huge boost from io_uring, since it won't handle as many active connections as Velocity, but Folia will most definitely get a significant improvement from this. And with this not being a region-related feature, it is more suitable have it on Paper and let Folia get it downstream.
This also relies on removing the synchronization in Connection#disconnect from the netty threads, as it will trigger Netty's deadlock prevention in the form of io.netty.util.concurrent.BlockingOperationException.
This used to be part of Paper, but was removed in https://github.com...
77201db Apply & rebuild feature patches not dependent on M... - Warriorrrr
Given this already break since 1.20.6, i'm not sure the damage exclusion is really needed now (which will break things again).
We could replace this damage check with iterating over DataComponentPatch#entrySet() and comparing against the ItemStack's prototype. But I feel like just checking the damage value is enough — what do you think?
for (final Map.Entry<DataComponentType<?>, Optional<?>> entry : this.handle.getComponentsPatch().entrySet()) {
if (!Objects.equals(this.handle.getPrototype().get(entry.getKey()), entry.getValue().orElse(null))) {
return true;
}
}
return false;
Expected behavior
The KeyedBossBar created via Bukkit#createBossBar(NamespacedKey) to be the same instance via Bukkit#getBossBar(NamespacedKey)
Observed/Actual behavior
In CraftServer#createBossBar(NamespacedKey), a new CustomBossEvent is created as well as a new CraftKeyedBossBar. However, the CraftKeyedBossBar is not stored on the newly created CustomBossEvent
So when using CraftServer#getBossBar(NamespacedKey) it grabs the CustomBossEvent, then calls #getBukkitEntity provided in a patch.
This patch method checks to see if a boss bar exists on the CustomBossEvent, if it does returns it, if it does not creates a new one then sets the boss bar field to this new instance.
Steps/models to reproduce
NamespacedKey key = new NamespacedKey("test");
KeyedBossBar bar1 = Bukkit.createBossBar(key);
KeyedBossBar bar2 = Bukkit.getBossBar(key);
if (bar1 == bar2) {
// Wont ever be the case
} else {
// Will always be the case
}
Plugin and Datapack List
[00:59:26```...
Seems fair to me, just a bit sad entity type is not a proper registry yet.
Should probably check the unknown type as always.
The entity should be alive in the event like the other calls.
I would rather not use a label marker since it makes code less readable generally
radius and fire are mutable in the event and should take effect below
Can probably call EntityUnleashEvent here with the LEASHED_GONE reason. (also check if this can occur after the other event since that's cancellable too)
It looks like other fusing entity are just defused without explosion and not removed actually.
i test with PrimedTnt for reference and the behaviour its just skip to discard, unless i miss other entity?
Yeah... well in other cases the "cancel" its ignored when its related to LEASHED_GONE so not sure if need move that call
Stack trace
Description: Exception in server tick loop
java.lang.RuntimeException: Failed to encode Minecraft Component: empty[style={color=gray,clickEvent=SuggestCommand[command=/hsay test]}, siblings=[literal{hsay test}[style={color=red,underlined}], translation{key='command.context.here', args=[]}[style={color=red,italic}]]]; Disallowed chat character: ''
at io.papermc.paper.adventure.WrapperAwareSerializer.lambda$deserialize$0(WrapperAwareSerializer.java:28)
at com.mojang.serialization.DataResult$Error.getOrThrow(DataResult.java:287)
at io.papermc.paper.adventure.WrapperAwareSerializer.deserialize(WrapperAwareSerializer.java:28)
at io.papermc.paper.adventure.WrapperAwareSerializer.deserialize(WrapperAwareSerializer.java:13)
at io.papermc.paper.adventure.PaperAdventure.asAdventure(PaperAdventure.java:185)
at net.minecraft.commands.Commands.finishParsing(Commands.java:445)
at net.minecraft.commands.Commands.performCommand(Commands.java:373)
at net.minecraft.commands.```...
Could easily be expanded to the wither if you don't mind having a slightly more generic EntityConstructEvent.
done & updated this branch to main again
This is the only exception actually since primed tnt doesn't really have defused form (well I guess it would be the tnt block but you get), But I think it makes more sense to mimic the creeper or minecart tnt here this also means not duplicating the logc here as well.
f53a804 drop previous block from sulfur cube after swap - Lulu13022002
I meant cancelling the prime event will prevent its removal.
* Called just before an {@link Entity} spawns due to a pattern of blocks being constructed (golems, the wither, etc.)
Missing a blank line before return tag
Also for all your note we have an apiNote tag if needed but I feel this could just be part of the description like the other note above.
I would say "required for this construction" instead of "used" since that also include air blocks again.
I modify the logic for rollback fuse and other states when its cancel.
Based in how works in vanilla change that "breaks" the current behaviour... like we talked i open a MOJIRA for know if is intended MC-308659
Include Event Damager when Sulfur Cube apply contact damage to entities, this keep the behaviour where DamageSource can not has the source of damage if the definition of contact_damage not include that.
3ec423f Call EntityDamageByEntityEvent for SulfurCube's co... - Doc94
2c1ecae merge hot floor and campfire damage cause to conta... - Lulu13022002
If a world that players are in gets unloaded/reset, they end up spawning in the overworld at the same coordinates they were at.
This can cause players die suffocate in walls or fall to their death
There is no easy way to detect if a player spawn location has had its world changed, this patch fixes that by tracking if the world was determined to be invalid.
I added a constructor overload in-case some plugin author is manually creating AsyncPlayerSpawnLocationEvent instances for some reason.
I also removed boolean[] invalidPlayerWorld = {false}; local variable as it wasn't used for anything, let me know if you want it back.
Also apologies that this isn't in per-file patch format, I could not get it working correctly.
I'll run the one bash command to auto do this once we get to the rc releases :sweat:
Thanks anyway <3
Expected behavior
You should not receive the error message Height limit for building is 319 when standing on a shulker box with high latency and opening and closing it a few times.
Observed/Actual behavior
When you have high latency towards the server, stand on a shulker box and open and close it a few times pretty quickly, you'll see the action bar Height limit for building is 319 appear in red.
Steps/models to reproduce
- Produce a situation in which you have high latency towards the server. A Linux command like
sudo tc qdisc add dev <interface> root netem delay 1000msshould be able to achieve that if you're not local-hosting. - Stand on a shulker box
- Open and close said shulker box a few times while standing still on it
Plugin and Datapack List
No plugins or datapacks were installed during my testing
Paper version
26.1.2-69
Other
No response
I encountered this issue 2 days ago and it seems related to internal teleports triggered by main hand interactions, in 26.1 snap 8 this if statement now has an else that triggers the message vs in 26.1 snap 7 where it did not have that.
If you want attribute swapping on your server, this exists. https://modrinth.com/plugin/attribute-swap-fixer
Marking a comment as low quality because the plugin it advises literally just edits the Paper config to toggle the attribute swapping config entry.
[10:10:55 ERROR]: [PluginRemapper] Encountered exception remapping plugins
java.util.concurrent.CompletionException: java.lang.RuntimeException: Failed to remap plugin jar 'plugins[C]CosmeticsCore_1.3.11.jar'
at java.base/java.util.concurrent.CompletableFuture.wrapInCompletionException(CompletableFuture.java:323) ~[?:?]
at java.base/java.util.concurrent.CompletableFuture.encodeThrowable(CompletableFuture.java:359) ~[?:?]
at java.base/java.util.concurrent.CompletableFuture.completeThrowable(CompletableFuture.java:364) ~[?:?]
at java.base/java.util.concurrent.CompletableFuture$UniApply.tryFire(CompletableFuture.java:670) ~[?:?]
at java.base/java.util.concurrent.CompletableFuture$Completion.run(CompletableFuture.java:503) ~[?:?]
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1090) ~[?:?]
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:614) ~[?:?]...
@1CHENYAOXIN0712 please do try to take over existing issues for your own help. Update your server to latest Paper and visit the support discord if you need help on that.
Description
This PR adds a maximum size limit to the ServerboundDebugSubscriptionRequestPacket codec.
Debug subscription packets are known to be abused by hack clients, in local testing, one client was able to fully occupy at least one Netty IO thread on a high-end system without triggering Paper's packet limiter.
<img width="1400" height="750" alt="image" src="https://github.com/user-attachments/assets/a7982f38-03f6-49c9-994e-0b96d0f63d8c" />
Fix
Requests containing more than 64 subscriptions are now rejected and disconnect the client with a DecoderException to avoid excessive CPU usage and memory alloc.
The max size should be changed once Mojang adds more subscriptions in DebugSubscriptions.
I think we should set the value in the configuration settings and disable it by default
I think we should set the value in the configuration settings and disable it by default
Could you clarify when this limit would need to be disabled or changed? The current vanilla debug subscription count is 16, so 64 seems safe above the expected value while still preventing abusive decode sizes.
I am not sure Paper's global configuration is guaranteed to be loaded before this codec is initialized.
Its the basic thing can be exposed meanwhile Archetype data values can be exposed (like ExplosionData)
Adds a few methods for batch registering & unregistering recipes to save on a LOT of tick time (and bandwidth when players are online) when compared to doing tons of add/remove recipe calls.
Also adds a hasRecipe method to avoid converting a bukkit recipe when its unnecessary.
In order to do this I extracted the creation of the minecraft recipe classes from the existing CraftRecipe#addToRecipeManager method to a new CraftRecipe#toMinecraftRecipe method, for use by the new methods. I also extracted the conversion of the bukkit recipe classes to the craft recipe classes to CraftRecipe.
In terms of performance improvements I was implementing this solution manually for a plugin I work on here: https://github.com/pylonmc/rebar/pull/827 where you can see the differences
Given this is a debug feature, I believe having it limited by default is fine.
General making exploit fixes opt-in somewhat defeats their purpose imo
Thank you for your PR! Yeah, this does not need to be configurable.
Expected behavior
Even while a Paper server is under severe load, all world and player inventory saving operations should occur simultaneously, eliminating the possibility for duplication exploits by exploiting failed saving on either end.
Observed/Actual behavior
A severe lag machine created by another player on this Paper server at the time caused player data to stop saving while the world chunks remained active. This allowed items to be dropped, the player to disconnect, and the inventory, enderchest, all player data in general, to roll back upon rejoining, resulting in duplicated items.
Steps/models to reproduce
Put a Paper server under severe load (using a lag machine).
Rejoin the server quickly. If the lag is of the right type, the world chunks will remain active while player data fails to save, resulting in inventory and enderchest rollbacks.
Plugin and Datapack List
<img width="975" height="107" alt="Image" src="https://github.com/user-attachmen...
The player ENTIRELY was getting reverted. Inventory, enderchest, position, facing rotation, etc
or...?
Used to be, but it's been a year, now, so probably not.
77202ea move a bunch of stuff out of unsafe - Lulu13022002
Probably server just run out of storage.
We can't really take third-party issue reports like this. It is up to the server owner to reproduce this without plugins, to provide logs, to ensure they are on the latest 26.1 version, etc.
Going to close this issue for that reason. I would recommend talking to the server owner about the issue instead.
Expected behavior
Info per lo sviluppatore:
Su Paper 26.1.2-66 l'evento io.papermc.paper.event.player.PlayerScoreboardChangedEvent non è disponibile, quindi il Glow usa il fallback task (ogni 40 tick). Il plugin funziona correttamente. Verificare se Paper ha introdotto l'evento in un build successivo al 66 per poter eliminare il warn.
Observed/Actual behavior
Steps/models to reproduce
no comment
Plugin and Datapack List
no comment
Paper version
no comment
Other
No response
There is no such thing as a PlayerScoreboardChangedEvent in Paper, and there never has been. So yes, of course that is not available - it does not exist.
AI hallucination?
Also please keep the issue tracker in English.
For further support, please use the Discord server.
After investigating the issue further, it occurs when thread A modifies the itemmeta and thread B calls ItemStack#clone()#getItemMeta(). While this is certainly not supported behavior, it might be good for you to know.
My suggestion is to either include a synchronization mechanism of the underlying components/data patch, or to throw an concurrency exception to avoid such cryptic errors in the future. Unfortunately I don't have time to create a PR myself
implementing concurrency checks is generally non trivial expecially in such complex legacy systems, these data structures are not thread safe and it's on the caller to be weary of what they're doing when using concurrency
lgtm, too often are plugins doing unsafe stuff snd introducing race conditions
I think that else in line 1388 should be like "else if(this.awaitingPositionFromClient == null) {". there is definitely no reason to send a build height warning when just awaiting a teleport. we had some complaints from users about this message when clicking somewhere while being teleported.
Done in a86dff66c161b8594b4d09155aed2d97d59e57f8 as part of a larger rewrite.
Fixed in a86dff66c161b8594b4d09155aed2d97d59e57f8 as part of a larger rewrite.
Don't merge until the branch is updated to the latest RC
Hi,
Like the CONTRIBUTION file says
When submitting PRs to dev branches, please coordinate with the dev team in Discord or open an issue before starting work to ensure it's an area we want to accept changes for.
This type of changes are going to be make by the team later.
I opened this cuz of a similar PR in the past for a dev branch too which had no issues whatsoever with being merged
Just exposes getWeaponItem to the API
We have Block#isReplaceable but we don't have any way of checking if its replaceable with a fluid, this just exposes that as well.
Expected behavior
Setting up a very fast redstone clock linked to a notebook yeilds a conistent beat from the noteblock, see video for reference
Observed/Actual behavior
Setting up a very fast redstone clock linked to a notebook yeilds an onconsistent beat with a tiny barely noticiable pause from the noteblock, see video for reference
Steps/models to reproduce
I'm not entire sure what is causing this but you can run the same test as me to figure hopefully figure it out
Plugin and Datapack List
Paper Plugins: CustomDiscs, emotecraft, PunisherX, SkBee
Bukkit Plugins: AdminCommands, AFKPlus, AntiVillagerLag, AuthMe, AxiomPaper, BedrockBreaker, Chunky, ChunkyBorder, CommandAPI, CoreProtect, craftableinvframes, CustomAnvil, CustomJoinMessages, DebugStick, DiscordSRV, dynmap, EarthquakePlugin, EasyArmorStands, ElytraEssentials, EntityDetection, GSit, HarvestHelper, HeadDB, HelpCommand, HiddenAr...
That just seems like server lag/unstable TPS. If the server isn't running perfectly at 20 TPS, you will get this behaviour with contraptions like this. I am not able to reproduce this issue myself on a well-performing server.
Generally though: We can't really take third-party issue reports like this. It is up to the server admin to reproduce this without plugins, to provide logs, etc. If you have no access to the server, an issue report is of little use as you can't provide the required details or test things.
Especially with plugins like Skript that could do anything.
Please bring up the issue to the admin of the server instead.
@Malfrador the TPS is very stable and I am able to provode logs or anything that may be requested, please reopen this issue
Are you able to reproduce this without any plugins?
@Malfrador I have tried and no, and I want to emphasize that this hasn't always been an issue on the server, we are also not too sure how long ago this started
Then its a plugin issue, not a Paper issue.
Try a binary search with your plugins to find the offending plugin.
For further support, please use the Discord server.
@Malfrador thanks for the help, couple last questions
do you have any insights as to which plugins could be potentioally causing this?
and what red flags should we look for in the server logs to see why this is happening if that's possible?
for anyone wondering or having a similar issue: none of the plugins/datapacks mentioned in the post caused lag or redstone beat skip. There was an audible lag due to high ping. Rhett has a very specific storage system that might relay on ignore-occluding-blocks setting. While setting it to false provides more vanilla-like experince, disabling it might cause perfomance issues.
Noticed this javadoc was incorrect while doing the #13914 PR
111bdc0 improve state handling when capturing blocks - Lulu13022002
According to minecraft source code (Verified Version : 26.1.2), this condition is not a hard requirement.
Minecraft checks if the given block is a Bed (like done here) BUT it doesn't need it, it checks it to ensure the new data for the block (marked as occupied)
This is becoming a inactive PR but I believe this is a great adding so, if no one is taking it, I might re-do it but I believe the guy who have done this PR just doesn't have notifications
canBeReplaced(Fluid) is just equivalent to state.canBeReplaced() || !state.isSolid() with two exceptions for end blocks. So i'm not sure this is really needed, the fluid parameter is not even used currently.
AbstractArrow will now have both getWeapon and getWeaponItem methods and the item should definitely not be null when empty (and probably not a mirror).
Problem
Some plugins, Slimefun, or its addons, for example, provide even higher enchantment levels compared with the vanilla enchantments. And players can craft the crossbow with a higher enchat level. Thus, it can create a long projectile item list in CrossbowItem#draw (EnchantmentHelper#processProjectileCount).
Unlike the projectile size limit in CODEC, the exception throwing under these constructors will not be caught; it crashes the server instead.
example error:
<img width="2515" height="962" alt="ba1f61b2eaa97c1669851643c2b6aa9f" src="https://github.com/user-attachments/assets/71cc1d5a-b5bc-4089-8153-5961bcf13e01" />
Fix
So it's better to use a soft limit here to prevent the server crash caused by the hard throw.
Not sure whether we still need to keep the warning message.
not sure about this change... for example the ChargedProjectiles throw was added by Paper but in 26.2 now its a thing added by Mojang (with a more high limit)
not sure about this change... for example the ChargedProjectiles throw was added by Paper but in 26.2 now its a thing added by Mojang (with a more high limit)
Yeah, did a quick check, you are right. However, in 26.2, Mojang used stream limit + warning to handle the item list with the size bigger than 1024, so it will not throw if the call is from CrossbowItem#tryLoadProjectiles (Like in the above error).
I thought that most captures of this would generally occur within the bounds of API (unless they're messing with NMS in which case, not really our problem, as such), approved as a "better than crashing"
canBeReplaced(Fluid) is just equivalent to state.canBeReplaced() || !state.isSolid() with two exceptions for end blocks. So i'm not sure this is really needed, the fluid parameter is not even used currently.
I would argue for intuitiveness this is still a good addition, no developer that doesn't check or already know the NMS logic is going to intuitively know/guess that a block can be replaced by fluids if either block.isReplaceable() or !block.isSolid(), and if Minecraft ever does add blocks with more complex behavior (such as using the fluid parameter) then it would be automatically handled.
AbstractArrow will now have both getWeapon and getWeaponItem methods and the item should definitely not be null when empty (and probably not a mirror).
I'll switch it to return a copy & empty if its not present
In case anyone is wondering why I removed this line, now MC will automatically do this whenever a recipe is added to the recipe manager so it was a double call for no reason
I encountered the same error. If we absolutely must register a dialog box with ItemStack during the Bootstrap phase, perhaps we should use another method to solve it.
70eaed6 Soft limit projectile list size (#13954) - Dreeam-qwq
This PR start with just add the reason for the NAUSEA effect in the Potent Sulfur lake but i notice many places where a Cause was not set.. then i try to add all the missing cases.
Noticed by @Lulu13022002 currently you can give effects to Wither or EnderDragon by using /effects command this is caused by the method used in that command calling the custom method for add the Cause and ignore the override in that entities... this PR add the overload for that method but still allow set the effect using the API (PLUGIN cause)
This PR its related to https://github.com/PaperMC/Paper/pull/13955 with a suggestion from lulu, where can be good expose the source entity related to a effect.
Expected behavior
The speed effect should be removed once the player is no longer wearing boots with Soul Speed.
Observed/Actual behavior
The speed effect remains active for the entire session regardless of surface, does not reset on death, but is removed upon reconnecting to the server.
Steps/models to reproduce
- Have two pairs of boots enchanted with Soul Speed - one nearly broken and one with full durability
- Equip the nearly broken boots and start running on soul sand while rapidly swapping between the two pairs
- Once the boots break, the speed effect persists for the entire session and applies on any surface
Plugin and Datapack List
ℹ Server Plugins (0):
Paper version
This server is running Paper version 26.1.2-70-ver/26.1.2@70eaed6 (2026-06-14T10:18:21Z) (Implementing API version 26.1.2.build.70-stable)
You are running the latest version
Other
No response
Yes. minecraft:water_bucket and minecraft:lava_bucket triggers PlayerBucketEmptyEvent and PlayerBucketFillEvent, but minecraft:powder_snow_bucket not. It should also be triggered there, because the Minecraft mechanics for emptying and filling buckets is the same.
I had the same problem here...
Any updates?
Is your feature request related to a problem?
Jjd
Describe the solution you'd like.
Ydud
Describe alternatives you've considered.
Hhd
Other
No response
Hey @lynxplay this still hasn't been addressed and we’re on the last RC
Expected behavior
Translatable components being resolved server-side.
Observed/Actual behavior
Translatables are not processed in any way.
Steps/models to reproduce
Dialog dialog = Dialog.create(builder -> builder.empty()
.base(DialogBase.builder(Component.translatable("mytranslation.colorful")).build())
.type(DialogType.notice())
);
player.showDialog(dialog);
Plugin and Datapack List
- test
Paper version
This server is running Paper version 26.1.2-70-ver/26.1.2@70eaed6 (2026-06-14T10:18:21Z) (Implementing API version 26.1.2.build.70-stable)
You are running the latest version
Other
No response
384ff98 fix contract of ItemContainerContents#contents - Lulu13022002
This doesn't makes sense, the todo was more about figuring out in which case this would happens and if it's only for plugin badly creating the event, then that logic should be removed.
This should only edit the existing override instead of expanding it, so it will conflict if it changes later
This should only edit the existing override instead of expanding it, so it will conflict if it changes later
Okay, then i use the final method (with all values) for avoid any strange bypass unless plugin make the call...
if this only happen with plugins then what do you think about replace this with...
if (this.oldEffect == null && this.newEffect == null) {
throw new IllegalStateException("The event not has any effect, this can be caused by a plugin");
}
return this.oldEffect == null ? this.newEffect.getType() : this.oldEffect.getType();
This PR fixes the waterBlocks argument precondition which required the minimum amount to be 2 instead of 1.
af55c9d Fix Geyser particle options waterBlocks... - Privatech38
Thanks I think the other particle could have those preconditions as well, the only reason it doesn't explode rn is because they never got through the codec.
In the constructor maybe but really it's internal anyway so I don't it's even needed.
yeah the issue with constructor its the IDE still warning for in the method unless i add this check in the constructor and the method.. then better keep here.
This PR just mention a MOJIRA ticket for this what Paper fix (confirmed today by Mojang Triage...)
https://mojira.dev/MC-308790
Thanks if you want to open a follow up for the dripleaf (if it's not there already) too feel free.
1daadd5 Prevent EnderDragon and Wither from rece... - Doc94
ca8eb49 Mention MOJIRA issue for correct stacktr... - Doc94
Expected behavior
Items should not be removed
Observed/Actual behavior
Items are removed
Steps/models to reproduce
In the PlayerInteractEvent listener, you need to update the item in the player's hand, and in the BlockPlaceEvent listener, you need to cancel the event. Since the block isn't being placed, the item shouldn't be removed, but it is being removed.
Plugin and Datapack List
none
Paper version
latest 26.1.2
Other
public final class TestPlugin extends JavaPlugin implements Listener {
@Override
public void onEnable() {
this.getServer().getPluginManager().registerEvents(this, this);
}
@EventHandler
public void interact(PlayerInteractEvent event) {
Player player = event.getPlayer();
PlayerInventory inventory = player.getInventory();
ItemStack itemInMainHand = inventory.getItemInMainHand();
player.getInventory().setItemInMainHand(itemInMainHand);
}
@EventHandler
public void place(BlockPlaceEvent event) {
event.setCancelled(true);
}
}
Yea, as said, modifying the item in the players hand is generally going to desync the servers logic, it's not viable or tenable to track what weird interactions people are doing with inventories inside of those events; This is a quirky area but really works as expected
73744d6 Update Javadoc configuration - jpenilla
80d1098 Expose Entity Source for EntityPotionEff... - Doc94
This PR has some conflicts with the current main branch. Does it need to be rebased?
This seems to be patched by Mojang in 26.2, should this be backported to old versions?
Yes, the possibilities conceived by the community but not incorporated by the manufacturers. And here’s yet another case of “It’s not a bug, it’s a feature (request).” Since I’m currently struggling with the challenges of extending the range of values below -64 (also a datapack with Y = -256), I came across a fix for Fabric by warior456. Helpfully, this fix includes a value defined via a configuration file, adjustable to BELOW_SEA_LEVEL, ABOVE_BOTTOM, and ABSOLUTE. I’d love to see similar flexibility for Paper.
In my datapack, I set the sea level to 0 right away and ran into a pretty ugly glitch in the way the horizon is displayed. But that's another story...
Not against a config option, etc; Just can't really support a behavior change in something as core as chunk generation which isn't opt-in
Expected behavior
Thrown ender pearls should behave identically to vanilla (they should not respawn after being deleted and the thrower relogging), and there should be no warnings about duplicate versions of them in the console.
Observed/Actual behavior
If a player has a stasis chamber set up with one or more pearls and the server restarts, whenever that player joins the server, the following warning appears in the console - one for each pearl:
[15:37:48 WARN]: [ca.spottedleaf.moonrise.patches.chunk_system.level.entity.EntityLookup] Entity uuid already exists: 33bcecaa-0f27-467e-bab0-9f966e633f5b, mapped to ThrownEnderpearl['Thrown Ender Pearl'/153, uuid='33bcecaa-0f27-467e-bab0-9f966e633f5b', l='ServerLevel[world]', x=-14.43, y=111.18, z=-15.71, cpos=[-1, -1], tl=0, v=true], can't add ThrownEnderpearl['Thrown Ender Pearl'/155, uuid='33bcecaa-0f27-467e-bab0-9f966e633f5b', l='```...
Just to add - this was not an issue in 1.21.11. It started happening after updating to 26.1.2.
2dc3641 Limit max size of subscription codec (#13943) - HaHaWTH
Expected behavior
No exceptions, commands should work
Observed/Actual behavior
NoClassDefFoundError
Steps/models to reproduce
run any spark command like: /spark
Plugin and Datapack List
[20:55:57 INFO]: ℹ Server Plugins (1):
[20:55:57 INFO]: Paper Plugins:
[20:55:57 INFO]: - Worlds
[20:56:01 INFO]: There are 3 data pack(s) enabled: [vanilla (built-in)], [paper (built-in)], [file/bukkit (world)]
[20:56:01 INFO]: There are no more data packs available
Paper version
[20:56:15 INFO]: This server is running Paper version 26.2-22-dev/26.2@1142778 (2026-06-18T11:51:25Z) (Implementing API version 26.2.build.22-alpha)
You are running the latest version
Previous version: 26.1.2-65-fd45f4b (MC: 26.1.2)
Other
[spark] Exception occurred whilst executing a spark command
java.lang.NoSuchMethodError: 'net.kyori.adventure.text.BuildableComponent net.kyori.adventure.text.TextComponent$Builder.build()'
at me.lucko.spark.paper.common.comman```...
Can a player without OP permissions exploit this? If so, why is this debug feature allowed for players without OP permissions?
Expected behavior
Nether file should have been generated in the dimensions directory
<img width="746" height="214" alt="Image" src="https://github.com/user-attachments/assets/bd97350b-bce6-43ab-8e8d-b1e9a2b0c52b" />
Observed/Actual behavior
Only created Overworld and The End files. It also skips The Nether during server startup. Either loading an existing world, or a brand new world.
Vanilla creates the world no problem.
Steps/models to reproduce
Create a brand new world in Paper Minecraft version 26.1.x
Plugin and Datapack List
BlueMap
DiscordSRV
Paper version
This server is running Paper version 26.2-23-dev/26.2@250ea42 (2026-06-18T19:00:47Z) (Implementing API version 26.2.build.23-alpha)
You are running the latest version
Previous version: 26.1.2-71-2dc3641 (MC: 26.1.2)
(26.1.2 also has the same issue.)
Other
No response
Hi, i cannot replicate this.
Please check the paper global config if the enable-nether is disabled.
Hi,
The Nether fortunately now works, I didn't know it was disabled since I never edited that file.
Thanks so much for the help.
I completely understand your point. It’s just this: Doesn’t the ability to change parameters like min_y, sea_level, height, etc., in the datapacks practically necessitate - or even require - changes to core mechanisms like chunk generation? It simply doesn’t make any sense to be able to set the depth to as low as -2032 blocks if the only result is a lava pool that might be 1978 blocks deep.
But ultimately, this is a “bug” that Mojang hasn't really addressed since version 1.18.
Can a player without OP permissions exploit this? If so, why is this debug feature allowed for players without OP permissions?
This works on the netty level, permissions are not checked yet when decoding packets.
For some reason PaperItemContainerContents was passing null and not an empty ItemStack in its returned output, even though its marked as nonnull & when creating an ItemContainerContents null is not permitted, this just corrects that.
Timings is terminally deprecated and can't be enabled so there's no use keeping this around, I also removed it from unused code for completeness
Just a small nit but this comment seems to be outdated as well (maybe the if can be just removed?)
Doesn’t the ability to change parameters like min_y, sea_level, height, etc., in the datapacks practically necessitate - or even require - changes to core mechanisms like chunk generation?
Yes, but the nature here is that when mojang added this stuff they used the existing defaults, you didn't login to the server one day and your sea/lava levels suddenly transformed and all of a sudden you had a world with the ocean at two different levels.
I'm not against something being added here, but it needs to be deactivated by default so that it doesn't change the output for peoples worlds during a random patch release, nor do we really want to be involved in adding custom options directly into datapacks themselves
It's unused code so doesn't really matter either way, though a small cleanup never hurts
Noticed in Discord the method getWorldContainer was marked Obsolete in 26.1 but only in Server class the Bukkit reference was not updated.
I cleaned the method, I think the method was just not updated since the beta (4a2bc3299ae1e07e3cea92160824f205f6242677) and at this time it makes sense given the method called didn't send the update so they have to do it manually.
1a6b910 Fix ItemContainerContents containing nul... - JustAHuman-xD
19d83f9 Add missing obsolete on Bukkit.getWorldC... - Doc94
Does these need anything else done to it?
This doesn't seems to work?
Got the following " [net.minecraft.server.network.config.PrepareSpawnTask] Serialization errors:
ServerPlayer['Lulu13022002'/100, uuid='74442095-f151-4e35-aeb9-b5142a9926ab', l='ServerLevel[world]', x=-10.54, y=77.00, z=6.93, cpos=[-1, 0], tl=0, v=true](Lulu13022002 at -10.540502490895227,77.0,6.933107692844611): Failed to decode value '{Slot:0b,components:{"minecraft:attribute_modifiers":[{amount:5.0d,id:"minecraft:kenny",operation:"add_multiplied_base",type:"minecraft:nameplate_distance"}]},count:1,id:"minecraft:stone"}".
It looks like this class doesn't do the distinction between the old and the new format of component like AttributesRenameFix.
Closes #13941
As far as I can tell this line being there doesn't make a lot of sense and is likely a leftover, see https://github.com/PaperMC/Paper/issues/13941#issuecomment-4642200340 for mcsrc links for comparing.
Before, this line was an else for a statement that checked the height, but after the changes in that snapshot it's now an else for the this.awaitingPositionFromClient == null && level.mayInteract(this.player, pos) check, which is wrong since neither of those have anything to do with reaching max height.
Expected behavior
As far as I can tell, this repository did not used to proxy Maven Central. Perhaps this changed recently in relation to PaperMC's switch to JFrog Artifactory Israeli software. I don't know.
If this is intended, I would expect it to be documented. The repository is recommended for all starting plugin developers, and taking over Maven dependency resolution for central artifacts is surely unexpected behavior.
If it is not intended, well, you could save a lot of bandwith and resource usage by not proxying Maven Central. Some of my project's builds are failing with corrupted central artifacts, maybe because your repository is not handling the load, though I am unsure.
Observed/Actual behavior
The maven-public repository path proxies Maven Central. For example, take the following jar. It is resolved by the PaperMC repository instance, despite being an artifact located on Maven Central.
https://repo.papermc.io/repository/maven-public/org/slf4j/slf4j-a...
It's a good practice to cache stuff in own repositories so stuff like CI can be faster and more reliable, including paper's CI of building and publishing paper builds, api and dev bundle. This is also true for a majority of other repositories I've seen, that's why it's recommended https://docs.gradle.org/current/userguide/best_practices_dependencies.html#use_content_filtering
Appreciate the comment but this is not what I opened the issue for.
Yes, this is intended behavior and predates our move to Artifactory by many years.
Seems fair can you just mention MC-308669 or the other related bug?
d64eec6 Use a concurrent cache in CraftRegistry - electronicboy
Problem
CraftRegistry lazily populates its backing cache on every get() call, so a plain HashMap was being both read and written without any synchronization.
Registries are not main-thread-only in practice — we fully expect plugins to resolve registry entries off the main thread. Building an ItemStack, looking up an Enchantment, or resolving a BlockType/ItemType from an async task all funnel through CraftRegistry#get, and since get() mutates the cache on first lookup, those "reads" race against each other.
Under concurrent access a HashMap can corrupt its internal table on a put()-triggered resize, leading to torn/null reads and — specific to this cache — duplicate wrapper instances for the same registry entry, which breaks identity assumptions both plugins and CraftBukkit make about registry constants.
Change
- Switch
cacheto aConcurrentHashMap. - Collapse the
get()-then-put()sequence into a single atomiccomputeIfAbsen...
13f9986 fail fast for out of bound access in LimitedRegion - Lulu13022002
I made the method nullable in 13f9986. Pretending the entity spawned is a no go.
done in 13f9986cd09fd391f48d8c1a482f800850259017 without mangling the sound.
Pull request overview
This PR hardens CraftRegistry#get for off-main-thread access by making its lazy cache population thread-safe, addressing unsafe concurrent reads/writes to a plain HashMap when plugins build ItemMeta asynchronously.
Changes:
- Replace the backing cache with a
ConcurrentHashMap. - Use
computeIfAbsentto atomically load and cache registry entries. - Make
lockReferenceHoldersvolatileto ensure cross-thread visibility from theget()path.
💡 <a href="/PaperMC/Paper/new/dev/26.2?filename=.github/instructions/*.instructions.md" class="Link--inTextBlock" target="_blank" rel="noopener noreferrer">Add Copilot custom instructions</a> for smarter, more guided reviews. <a href="https://docs.github.com/en/copilot/customizing-copilot/adding-repository-custom-instructions-for-github-copilot" class="Link--inTextBlock" target="_blank" rel="noopener noreferrer">Learn how to get started</a>.
The new concurrent cache behavior (ConcurrentHashMap + computeIfAbsent) isn’t covered by tests. Since this method is explicitly meant to be safe off the main thread, it would be good to add a regression test that calls CraftRegistry#get concurrently (same key + many threads) and asserts no exceptions and that all threads observe the same instance.
only one I'd ponder on is making food/potion a more general "consume" thing, rather than explict types, especially with componentisation efforts, not sure how well having seperate causes makes sense
I feel that this falls into that annoying area of "that ship has already sailed", if we wanted to restrict this it would
- need to be on a proper release
- Have a warning
- have a carve out
26.x makes this honestly much better of a situation now that the folder layout is more sane in Paper; it's worth noting that this was always understood to me as basically being the save folder, and so it's really not a concern that it can be saved out of tree, if anything that smells like a part baked feature
only one I'd ponder on is making food/potion a more general "consume" thing, rather than explict types, especially with componentisation efforts, not sure how well having seperate causes makes sense
only FOOD/POTION_DRINK? what about MILK?
but if its better deprecate that in favor of CONSUMABLE i can change if wanna...
Expected behavior
Log "test" on enable
Observed/Actual behavior
Log "null" on enable
Steps/models to reproduce
public final class Test extends JavaPlugin {
@Override
public void onEnable() {
final ItemStack item = ItemStack.of(Material.SULFUR_CUBE_BUCKET);
final NamespacedKey key = new NamespacedKey(this, "test");
item.editMeta(meta -> meta.getPersistentDataContainer().set(key, PersistentDataType.STRING, "test"));
final String value = item.getItemMeta().getPersistentDataContainer().get(key, PersistentDataType.STRING);
getLogger().info(value);
}
}
Plugin and Datapack List
[06:57:26 INFO]: ? Server Plugins (1):
[06:57:26 INFO]: Paper Plugins:
[06:57:26 INFO]: - Test
[06:57:43 INFO]: There are 3 data pack(s) enabled: [vanilla (built-in)], [file/bukkit (world)], [paper (built-in)]
[06:57:43 INFO]: There are no more data packs available
Paper version
[06:57:51 INFO]: This server is run...
org.bukkit.craftbukkit.inventory.CraftMetaEntityTag#ENTITY_TAGGABLE_MATERIALS needs to be updated.
A "workaround" for the PDC can be just directly use the method in the ItemStack and avoid use ItemMeta.
ex.
public final class Test extends JavaPlugin {
@Override
public void onEnable() {
final ItemStack item = ItemStack.of(Material.SULFUR_CUBE_BUCKET);
final NamespacedKey key = new NamespacedKey(this, "test");
item.editPersistentDataContainer(persistentDataContainer -> persistentDataContainer.set(key, PersistentDataType.STRING, "test"));
final String value = item.getPersistentDataContainer().get(key, PersistentDataType.STRING);
getLogger().info(value);
}
}
Is your feature request related to a problem?
There's two reasons:
- It's shorter than
item.getType().asItemType()andblock.getType().asBlockType(). - With the new
ItemTypeandBlockTypeAPI, it seems only logical, that the "legacy"Materialclass will be deprecated and removed at some point. So adding these methods and having developers use them could add to these developers' plugins longevity.
Describe the solution you'd like.
A method getItemType() on ItemStack and a method getBlockType().
The implementation would either be getType().asItemType() and getType().asBlockType(), or better, ItemStack and Block could just carry an ItemType or BlockType instance.
The second option would make even more room for truly custom items.
Describe alternatives you've considered.
Unnecessary field for this issue
Other
No response
@Owen1212055 should look better now, even reduced the patch size
Merged manually in daf505c4908f38de46c81d7cfc38e663eb05703c.
Fixed in daf505c4908f38de46c81d7cfc38e663eb05703c.
Fixed in daf505c4908f38de46c81d7cfc38e663eb05703c.
8507233 migrate old tag more properly from entity_data - Lulu13022002
Fixed in daf505c4908f38de46c81d7cfc38e663eb05703c, variant is no longer part of the entity tag/bucket entity tag.
This is indeed planned as part of https://github.com/orgs/PaperMC/projects/6/views/1?pane=issue&itemId=12583571, all the method taking/returning a Material will take an ItemType/BlockType instead. But ItemType still need to move away from item meta.
Spark Profile
a
Description of issue
[20:47:29 ERROR]: Illegal ChunkMap::addEntity for world SkyPvP: ServerPlayer['nEmanuel730'/3510685, uuid='32ff97a2-b139-3a54-ba40-1b77c5b02a35', l='ServerLevel[SkyPvP]', x=-36.24, y=128.62, z=-99.14, cpos=[-3, -7], tl=0, v=false, removed=UNLOADED_WITH_PLAYER](nEmanuel730 at -36.24086246742672,128.61693492105303,-99.13728069429358)
java.lang.Throwable: null
at net.minecraft.server.level.ChunkMap.addEntity(ChunkMap.java:955) ~[paper-1.21.10.jar:1.21.10-85-d98142e]
at net.minecraft.server.players.PlayerList.placeNewPlayer(PlayerList.java:281) ~[paper-1.21.10.jar:1.21.10-85-d98142e]
at net.minecraft.server.network.config.PrepareSpawnTask$Ready.spawn(PrepareSpawnTask.java:313) ~[paper-1.21.10.jar:1.21.10-85-d98142e]
at net.minecraft.server.network.config.PrepareSpawnTask.spawnPlayer(PrepareSpawnTask.java:139) ~[paper-1.21.10.jar:1.21.10-85-d98142e]
at net.minecraft.server.network.ServerConfigurationPa...
Outdated Paper and refusal to fill out the template.
Expected behavior
When using the World#spawn method to spawn a slime (e.g. player.getWorld().spawn(player.getLocation(), Slime.class), it spawns the slime like it does with any other entity.
Observed/Actual behavior
When the aforementioned method is used to spawn a slime, it raises the following exception:
[20:20:57 INFO]: Thatsmusic99 issued server command: /spawnslime
[20:20:57 ERROR]: Command exception: /spawnslime
org.bukkit.command.CommandException: Unhandled exception executing command 'spawnslime' in plugin PlaygroundPlugin v1.0-SNAPSHOT
at org.bukkit.command.PluginCommand.execute(PluginCommand.java:47) ~[paper-api-26.2.build.29-alpha.jar:?]
at io.papermc.paper.command.brigadier.bukkit.BukkitCommandNode$BukkitBrigCommand.run(BukkitCommandNode.```...
43f4dcd Handle slime class rewrite in RegionAccessor#spawn - Warriorrrr
Expected behavior
While player is tempting animal with food.
Cow cow = EntityMoveEvent.getEntity(); <-- animal
cow.getTarget() <--- returns Player object of player that's doing the tempting
Observed/Actual behavior
cow.getTarget(); is not a Player object
but EntityTargetLivingEntityEvent.getTarget() correctly returns a targeting player
I'm guessing this is due to my observation, which is that cow re-targets the player every two ticks or so.
Steps/models to reproduce
- Use MWE plugin: https://github.com/kacpermajkowski/AnimalTargetIssueMWE
- Use commands on the server:
- /gamerule spawn_mobs false
- /gamerule spawn_monsters false
- (multiple times if needed, to be sure no other cows are present) /minecraft:kill @e
- Spawn a Cow
- Take wheat in your hand and make the Cow follow you
- What you see is that checking Mob.getTarget() in EntityMoveEvent returns a non-Player object, and at the same time EntityTargetLivingEntityEvent.getTarget() returns a Pla...
Expected behavior
LivingEntity.getRemoveWhenFarAway() returns false for Cow, false nametagged Zombie, true for regular Zombie
Since the documentation states:
"Returns if the living entity despawns when away from players or not.
By default, animals are not removed while other mobs are.
Returns:
true if the living entity is removed when away from players"
then it follows that for any entity that keeps existing after all players are farther than 128 blocks the method returns false, otherwise true.
Observed/Actual behavior
LivingEntity.getRemoveWhenFarAway() returns 'true' for Cow, 'true' for regular Zombie
So the logical conclusion I pointed out in expected behaviour section is not met.
Steps/models to reproduce
use LivingEntity.getRemoveWhenFarAway() in any context e.g. EntityMoveEvent and test on Cow and Zombie.
Plugin and Datapack List
datapack list
[22:17:45 INFO]: There are 3 data pack(s) enabled: [vanilla (built-in)], [file/bukkit (world)], [...
This is mostly intended in the sense that the target is never set by MC for this interaction and the event is called in TemptGoal#canUse but maybe the javadoc can be improved here.
I don't know honestly, maybe there is some mismatch between "tempting" and "target", but I'm currently using animal.getBrain().getMemory(MemoryModuleType.TEMPTING_PLAYER); for Brain-using Animals, and ```NMS.Mob.goalSelector.getAvailableGoals().stream()
.filter(w -> w.getGoal() instanceof TemptGoal && w.isRunning())
.map(w -> {
try {
return w.getGoal().player;
} catch (IllegalAccessException e) {
return null;
}
})
.filter(Objects::nonNull)
.findFirst()
I think the javadoc is just super outdated here, for record the original impl removed the removeWhenFarAway check: 4dadf0e2b5ecb7a2644e2feb71e3a7ab1194ec84 and the method got mangled later since MC evolved around.
Currently I'm suing this function, but I'm not really familiar with NMS and I'm not sure if this covers all the bases as to what makes the mob "despawnable".
private boolean isNmsMobDespawnable(Mob nms) {
return !nms.persistenceRequired &&
!nms.requiresCustomPersistence() &&
!nms.getType().getCategory().isPersistent();
}
Spark Profile
Not possible to spark this early on, visual vm screenshot below
Description of issue
For a world that is 500gb for example world migration just takes so long
<img width="1533" height="525" alt="Image" src="https://github.com/user-attachments/assets/f952e610-f124-4e6a-8418-71daafcf14ef" />
shouldn't it just be renaming a few folders? why does it have to parse and check attributes for millions of files
Plugin and Datapack List
N/A
Server config files
N/A
Paper version
26.1.2 76d2ac758cb3abe75aceefa88207443768f585c6
Other
No response
The migration logic spins up a copy-on-write FS in a temporary directory to prevent your world from possibly being left corrupted if the server dies during the migration.
Spinning up that COW FS on large large folders sadly is not very fast but I don't think paper should remove such precautions and possibly leave worlds in a broken state if the server process fails during the process.
I have added some built in commands such as ping, seen, playtime and invsee
I think this is essential for servers that dont want to install a sophisticated plugin for this, and rather have it included into Paper. It is also very lightweight and minimal but effective.
We are not interested in these kinds of gameplay utility commands in paper :+1:
Best left to plugins :)
I have encountered this bug when upgrading my server as well, this also affects other plugins than Spark on my end.
This is my version: This server is running Paper version 26.2-30-dev/26.2@43f4dcd (2026-06-21T19:43:11Z) (Implementing API version 26.2.build.30-alpha)
You are running the latest version
Previous version: 26.1.2-64-2186e1e (MC: 26.1.2)
Yes, this is going to impact many plugins. It's being looked at.
If wanna make a follow you can check the report in adventure (https://github.com/PaperMC/adventure/issues/1431)
Is your feature request related to a problem?
A plugin I work on for a server has entity claims. Previously, just listening for entity damage and entity interact events was fine, but with sulfur cubes neither of those seem to be called when you punch them while they have a block.
Describe the solution you'd like.
Adding a cancellable event to sulfur cube punching.
Describe alternatives you've considered.
Raycasting during the arm swing animation to reset velocity. This has some issues such as stopping a cube entirely if it's already moving, along with being bypassable since some members use freecam.
Other
No response
The PrePlayerAttackEntityEvent should be called but I think it's fair to expect the EntityKnockbackEvent to be called as well.
the knockback ignore the whole logic from other entities then for that the knockback event its ignored... not sure if can be managed in a easy way... also the move of the sulfur cube from contact calls playerPush and that its ignored for any event... (not sure if can be consider a knockback....)
The PrePlayerAttackEntityEvent should be called but I think it's fair to expect the EntityKnockbackEvent to be called as well.
didn't see PrePlayerAttackEntityEvent when i looked for stuff, that works thank you
Expected behavior
The connection throttle cleanup (every 200 connections) should remove only entries older than connectionThrottle milliseconds from the tracker map.
Observed/Actual behavior
The cleanup at ServerHandshakePacketListenerImpl, line 97 in the applied source, removes every entry because the predicate compares a raw System.currentTimeMillis() timestamp against the connectionThrottle config value (typically a few thousand ms):
throttleTracker.values().removeIf(time -> time > connectionThrottle);
time is a stored System.currentTimeMillis() value (~1.7×10¹²), and connectionThrottle is something like 4000. The condition 1700000000000 > 4000 is always true, so the entire map is wiped on every cleanup cycle.
Should be:
throttleTracker.values().removeIf(time -> currentTime - time > connectionThrottle);
(The currentTime local is already in scope — it's declared a few lines above at line 79.)
Steps/models to repr...
Expected behavior
When crouch placing an armour stand on top of a Redstone ore block, the block should activate/deactivate allowing for a random timer that can be observed.
Observed/Actual behavior
Doing the same in 26.1.2 no longer works. The Redstone ore block remains unlit. I have tested on Paper, Purpur, Fabric and Vanilla. It works in both Vanilla and on a Fabric server, but not on Paper or Purpur
Steps/models to reproduce
Place a Redstone ore block - Crouch place an armor stand on top - the ore block should light up. When it deactivates it should activate again since an entity is on top of it
Plugin and Datapack List
Tested with no plugins or data packs to confirm the issue still exists. Also removed and refreshed all config files to rule out changes that may have been made
Paper version
[22:36:49] This server is running Paper version
26.1.2-72-ver/26.1.2@1a6b910 (2026-06-19T13:08:47Z)
(Implementing API version 26.1.2.build.72-stable)
You a...
Expected behavior
When a plugin updates sign text using either the Component-based SignSide#line(int, Component) API or the String-based SignSide#setLine(int, String) API, and then calls sign.update(true, true), online players should visually see the updated sign text without needing to disconnect and reconnect.
Observed/Actual behavior
The sign state updates server-side. Reading the lines back immediately after sign.update(true, true) shows the new text.
However, online players do not visually see the updated sign text. I tested this with two different connected clients, and both clients continued seeing the old sign text after running the test command.
If a player disconnects and reconnects, the updated sign text becomes visible. This happens with both Component-based updates and String-based updates.
Steps/models to reproduce
- Start a Paper server.
- Install a small test plugin with the command below.
- Place a sign and look directly at it....