#paper

1 messages · Page 23 of 1

rustic folioBOT
rustic folioBOT
rustic folioBOT
rustic folioBOT
#

Oh I see, thanks for the suggestion, I have it already fixed in our paper
fork and decided to upstream the change :)

Blue Bandit @.***> schrieb am Fr., 25. Apr. 2025, 05:22:

B1ue-Bandit left a comment (PaperMC/Paper#12475)
https://github.com/PaperMC/Paper/pull/12475#issuecomment-2829288104

No no, you're right. Your fix would be a welcome change, I was just
suggesting a workaround for the time being but I probably should've said
that


Reply to this email directly, view it on GitHub
https://github.com/PaperMC/Paper/pull/12475#issuecomment-2829288104, or
unsubscribe
https://github.com/notifications/unsubscribe-auth/AOKAS7ZC5RUGCWKQD5LJYW323GTAZAVCNFSM6AAAAAB32PN2VWVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDQMRZGI4DQMJQGQ
.
You are receiving this because you authored the thread.Message ID:
@.***>

rustic folioBOT
rustic folioBOT
rustic folioBOT
rustic folioBOT
#

This PR adds a keyStream() API to registries, to stream the registered keys, rather than the registered values.

While it's theoretically possible to map the existing Stream back to the key, having this in API is more direct/performant, and generally just more convenient due to not needing a local variable storing the registry.

Eg, if I wanted to get all the painting keys in a Stream prior to this, it'd be:

Registry<Art> paintingRegistry = RegistryAccess.registryAccess().getRegistry(RegistryKey.PAINTING_VARIANT);

paintingRegistry.stream().map(paintingRegistry::getKey).toList();

With this PR, it'd be:

RegistryAccess.registryAccess().getRegistry(RegistryKey.PAINTING_VARIANT).keyStream().toList();

toList being used as a simple example method so that it's not just creating a stream.

#

I understand why it is not a priority and why this logging system is a mess inherited from mojang.

I think there are some quick actions that could help without having to refactor the whole logging system:

  • Documentation: how to set log level for a plugin (almost a copy paste from my issue comment)
  • Documentation: remove the wrong -Dpaper.log-level= parameter explanation at the start of System properties section.
  • Code: Reroute the plugin.getLogger() to "PluginName" instead of log4j root "" logger to avoid confusing developers with different behaviors between provided loggers.

The correct solution is to make a simple logger for minecraft (writes lines to a file, zips said files) instead of relying on huge (and in the past, dangerous) frameworks like log4j

rustic folioBOT
#

Is your feature request related to a problem?

With new release cadence from mojang updating your server to new minecraft version is unsustainable, you need to do it every quarter while even core updates themself are taking much longer (there are already 1.21.6 snapshots and 1.21.5 is still in early beta), not even talking about plugins that breaks now much more often due to less backward compatibility in bukkit api. And I dont want to receive all that hate that comes out of using outdated software.

Describe the solution you'd like.

So my proposion are LTS versions. They will receive bugfixes even after new version is released, but no feature-backports (unless user PRs). The next planned LTS version gets its LTS title (and previous LTS becomes outdated) not the day it releases out of beta, but after quarter or so to provide time for bug catching.

The first LTS could be 1.21.4.

Describe alternatives you've considered.

Other

No response

#

plugins that breaks now much more often due to less backward compatibility in bukkit api

Bukkit api has very good backwards compatibility, excluding what's annotated as experimental.
Almost always it's due to plugins using nms to compensate lack of api in spigot or lack of that api in old versions, which in most cases paper had an api with good backwards compatibility. The better solution is to ask plugin developers to use less nms when possible, even with the cost of removing support of spigot or older versions.

#

Java experience shows us that backporting bugfixes is easy, and that makes sense, bugfixes are almost always consist of one line of code change and multiple hours of research that you dont need to redo for backporting. And users will still use old versions, because not a lot have time to make the same work every quarter. Just this versions they use will have bugs that they will step on.

#

This is a resource question and our teams limited resources are better spend improving the server software instead of maintaining one or more legacy versions for users that do not want to put in the effort of updating.
We maintain 1.21.4 for now as .5 is experimental and have generally given a grace period for the most recent legacy version when it comes to e.g. exploit fixes.

To prevent any potential reply of yours to further imply our team of unpaid volunteers needs to do more work because some server administrators do not want work on updating the servers, I have locked this conversation.

rustic folioBOT
#

I am semi uncertain on the naming "effective locale".
I know this mirrors velocity's API, however in the context of velocity, it being "effective" makes sense, given that all of velocity's messages are using the global translator to be resolved.

This differs drastically on backend servers like paper, where basically none of the messages sent are actually translated on the server side beyond plugin messages. Command feedback, server system messages, etc are all not translated on the server but instead resolved by the client itself.
Given I don't have an immediate better idea for the naming, nor am I sure this change in naming is 100% needed, I'll throw this at the rest of team/contributors.

#

Well, javadocs are a nice tool. But they are generally a second resort and do not save us from poorly named methods.
A user looking for a way to force a locale will still run into Player#setEffectiveLocale and just not read those docs until already hammering their head into a wall as to why it isn't working.

#

Well, javadocs are a nice tool. But they are generally a second resort and do not save us from poorly named methods. A user looking for a way to force a locale will still run into Player#setEffectiveLocale and just not read those docs until already hammering their head into a wall as to why it isn't working.

I mean, I agree. But then again, there are no better name suggestions yet. And I think it makes sense to mention it regardless

rustic folioBOT
rustic folioBOT
rustic folioBOT
#

Stack trace

On my anarchy Minecraft server, Jonarchy.com, when a certain player joins and loads certain chunks, the server starts spamming this error:

[10:04:52 ERROR]: Current Thread: Server thread
[10:04:52 ERROR]: Stack:
[10:04:52 ERROR]: com.mojang.serialization.Decoder$5.decode(Decoder.java:121)
[10:04:52 ERROR]: com.mojang.serialization.MapDecoder$4.decode(MapDecoder.java:94)
[10:04:52 ERROR]: com.mojang.serialization.MapDecoder$4.decode(MapDecoder.java:94)
[10:04:52 ERROR]: com.mojang.serialization.codecs.RecordCodecBuilder$Instance$3.decode(RecordCodecBuilder.java:247)
[10:04:52 ERROR]: com.mojang.serialization.codecs.RecordCodecBuilder$Instance$5.decode(RecordCodecBuilder.java:322)
[10:04:52 ERROR]: com.mojang.serialization.MapDecoder$4.decode(MapDecoder.java:94)
[10:04:52 ERROR]: com.mojang.serialization.codecs.RecordCodecBuilder$Instance$5.decode(RecordCodecBuilde...

rustic folioBOT
rustic folioBOT
rustic folioBOT
rustic folioBOT
rustic folioBOT
rustic folioBOT
#

Is your feature request related to a problem?

It's pretty well known now why terms like "blacklist" and "whitelist" (be they used together or just one of them, like is the case with PaperMC) are pretty problematic, they associate "white" with "good/allow" and, by extension, "black" with "bad/block/ban", as well as just being proxies to what the lists actually do, which is allow or block/ban.

Describe the solution you'd like.

Simply change whitelist to allowlist!

Describe alternatives you've considered.

"allowlist" is the more standard alternative to "whitelist", not really any alternative I can see.

Other

No response

rustic folioBOT
#

Is your feature request related to a problem?

Currently, Bukkit provides the method PluginLoader#createRegisteredListeners as public API. With the deprecation of plugin loaders this method has been moved to PaperEventManager#createRegisteredListeners but there isn't any way to access it from the API, as it's an internal class. This technically breaks Bukkit compatibility but i guess that was a given with the deprecation of PluginLoader.

Describe the solution you'd like.

It would be useful to put createRegisteredListeners back in public API (in whichever class would be the most convenient) as it allows access to the event listener method parsing logic that is us...

#

Expected behavior

・paper-1.21.4-226.jar

Item_Modifier wiki
The vanilla Minecraft wiki states that the lore statement in the datapack's item_modifier can be written as a component type, but paperMC's console log indicates that it must be a string type, and the item_modifier does not take effect.
How to write the lore statement for components

Currently, only the String type is valid, so "translate" and "score" cannot be used.
example:1{ "functions": [ { "function": "minecraft:set_components", "components": { "minecraft:lore": [ "Hello", "World!!" ] } } ] }

Observed/Actual behavior

The vanilla Minecraft wiki seems to recommend using component types.
Therefore, I thought that paperMC should also change its specifications to match the specifications of vanilla Minecraft so that it can be enabled in component typ...

rustic folioBOT
rustic folioBOT
rustic folioBOT
rustic folioBOT
rustic folioBOT
rustic folioBOT
#

Expected behavior

All items drop as usual upon death.

Observed/Actual behavior

Any items in shulkers in the inventory are dropped instead, and none of the items which weren't in the shulkers drop.
The shulkers themselves also aren't dropped.

Steps/models to reproduce

Die to a wither or a ghast in any liquid, in any dimension, with a shulker containing items
video demonstration: https://www.youtube.com/watch?v=-C_oqoJb3Qk

Plugin and Datapack List

No plugins or datapacks.

Paper version

This server is running Paper version 1.21.4-226-ver/1.21.4@a838a88 (2025-04-17T19:20:57Z) (Implementing API version 1.21.4-R0.1-SNAPSHOT)
You are running the latest version

Other

This bug seems to occur if the player is flying while they die as well.

rustic folioBOT
#

I can replicate this just fine in vanilla. I'd argue this is vanilla behaviour.
The player dies to the direct hit of a Fireball, which deals 6 damage.
The fireball then explodes, breaking the dropped items of the player, which deletes the drops and breaks the shulker boxes into their contained items.

Can you please retest this on vanilla?

rustic folioBOT
#

Hmm, i thought this was left for the team and generally this will be better handled once checkstyle is in, there's some other things that could be improved if you want:

  • capital letter / dot after description / doc tag consistency
  • not linking to deprecated methods/types if possible
  • move code example of getChunkAt(long) into @ code tag
  • changing <code></code> to its tag
  • moving deprecated methods to a default method for short methods like setTicksPerAmbientSpawns
rustic folioBOT
rustic folioBOT
rustic folioBOT
#

Expected behavior

Hide nametag

Observed/Actual behavior

Nametag always visibility

Steps/models to reproduce

Log in to the server
We write commands:
/team add hide
/team modify hide nametagVisibility never
Join the team
/team join hide
Nametag is not hiding

Plugin and Datapack List

CustomNameplates
PlaceholderAPI

Paper version

Paper 1.21.5 Build #41

Other

[CustomNameplates] An error occurred when reading packets
java.lang.IllegalArgumentException: Can not set final net.minecraft.world.scores.Team$Visibility field net.minecraft.network.protocol.game.ClientboundSetPlayerTeamPacket$Parameters.nametagVisibility to java.lang.String
at java.base/jdk.internal.reflect.FieldAccessorImpl.throwSetIllegalArgumentException(FieldAccessorImpl.java:228) ~[?:?]
at java.base/jdk.internal.reflect.FieldAccessorImpl.throwSetIllegalArgumentException(FieldAccessorImpl.java:232) ~[?:?]
at java.base/jdk.internal.reflect.MethodHandleObjectFieldAccess...

rustic folioBOT
#

To avoid having this PR linger too much, I haven't been able to find a team member that is in favour of pulling this.
I'll be closing this PR due to such low interest on our side to expose an event at this low context.

I want to add that
a) this is purely due to the nature of the event. The PR is really well crafted, everyone in here was nothing but great at discussing this.
b) I (and I think the team) generally agree with the annoyance that causes such an idea to exist, which is "there is so many events, I don't wanna listen to all of those". I don't know how a solution to such an issue could look rn, but there might be one that we can discuss/come up with in a feature request issue or something. If we can find a way to e.g. ease registration for event listeners for a set of events, that might be something (just throwing out ideas tho).

Again, thank you for the super well crafted PR and super nice discussion + fast feedback implementation.
I hope the points above...

rustic folioBOT
rustic folioBOT
#

What you are doing is slightly solving the issue, but we can make it better here.

Fundamentally what it is doing is scanning ALL block entities nearby, and THEN checking the actual podium location.

What we should instead do is something as simple as this.

@Nullable
    public BlockPattern.BlockPatternMatch findExitPortal() {

        BlockPos location = EndPodiumFeature.getLocation(this.origin);
        {
            int i1 = this.level.getHeightmapPos(Heightmap.Types.MOTION_BLOCKING, location).getY();

            for (int i2 = i1; i2 >= this.level.getMinY(); i2--) {
                BlockPattern.BlockPatternMatch blockPatternMatch1 = this.exitPortalPattern.find(this.level, new BlockPos(location.getX(), i2, location.getZ()));
                if (blockPatternMatch1 != null) {
                    if (this.portalLocation == null) {
                        this.portalLocation = blockPatternMatch1.getBlock(3, 3, 3).getPos();
                    }

          ...
#

I would really appreciate if this was configurable.

I have some item data that I really do not want the client to receive, ever. For example, exact equipment of some boss mobs. While it does not matter for PvP, fully sending item data for entities would allow players to cheat very easily in PvE encounters in my case.

Additionally I currently rely on item obfuscation to hide custom attributes from clients (as the attribute registry is not synced). With item obfuscation no longer being active in all cases, I would need to implement a custom solution to this.

Personally, just a boolean to turn it on/off for entities would be fine, as the breakages it currently causes do not matter for my usecase.

rustic folioBOT
rustic folioBOT
#

Expected behavior

If a player "starts mining" by left click then looks onto a block, BlockDamageEvent,BlockBreakProgressUpdateEvent etc should be called

Observed/Actual behavior

If a player "starts mining" by left click then looks onto a block, BlockDamageEvent,BlockBreakProgressUpdateEvent etc are not triggered

https://github.com/user-attachments/assets/14ab8255-97c4-482b-b252-84a69421d177

Steps/models to reproduce

  1. place block
  2. listen for BlockDamageEvent
  3. Mine before looking onto block

Plugin and Datapack List

> datapack list
[11:42:35 INFO]: There are 10 data pack(s) enabled: [vanilla (built-in)], [file/bukkit (world)], [file/nexo_custom_blocks (world)], [file/nexo_music_discs (world)], [paper (built-in)], [file/nexo_custom_armor (world)], [file/AprilEvent_DP (world)], [file/oraxen_jukebox (world)], [file/oraxen_expansion (world)], [file/carpentry (world)]
[11:42:35 INFO]: There are no more data packs available
> pl
[11:42:35 INFO]: ℹ Server Plu...
rustic folioBOT
#

Hey, @Owen1212055! Thanks a lot for your input. I Will take another look at the code today, and profile it accordingly, just to have a solid basis on how to analyze the before and after.

One thing bothered me, though, but I might not be grasping the purpose behind it entirely.
The first block gets the maxY and minY at the portals supposed location, which is the origin, correct? That was something that was being done before, I believe it was the second block of code in the original version, before I altered it my local fork. I found that to be not really that efficient, since callind find() multiple times, even when just doing it in a single column, proved to be less efficient than checking all blockentities in the chunk around the origin, and calling find() only if the instance of the blockentity being evaluated is really an instance of the End Podium block. Then, performance went up exponentially.

The second block would then try to prevent offsets bigger than that chunk, but ...

rustic folioBOT
#

This is a vanilla client bug. There is absolutely nothing we can do here.
The client incorrectly believes it is breaking that same block still and does not inform the server via a START_DESTROY_BLOCK player action packet. For all intends and purposes, the client is breaking that block the entire time.

The client also does not send break updates either. The only reason the client is allowed to break the block once finished is because it sends a stop_destroy_block action and the start time happened, well, whenever it originally started.
The server receives 0 info to work with here.

rustic folioBOT
#

Stack trace

[21:37:49] [Paper Watchdog Thread/ERROR]: --- DO NOT REPORT THIS TO PAPER - THIS IS NOT A BUG OR A CRASH  - 1.21.5-42-02d20ff (MC: 1.21.5) ---
[21:37:49] [Paper Watchdog Thread/ERROR]: The server has not responded for 10 seconds! Creating thread dump
[21:37:49] [Paper Watchdog Thread/ERROR]: ------------------------------
[21:37:49] [Paper Watchdog Thread/ERROR]: Server thread dump (Look for plugins here before reporting to Paper!):
[21:37:49] [Paper Watchdog Thread/ERROR]: ------------------------------
[21:37:49] [Paper Watchdog Thread/ERROR]: Current Thread: Server thread
[21:37:49] [Paper Watchdog Thread/ERROR]: 	PID: 52 | Suspended: false | Native: false | State: WAITING
[21:37:49] [Paper Watchdog Thread/ERROR]: 	Stack:
[21:37:49] [Paper Watchdog Thread/ERROR]: 		java.base@21.0.6/jdk.internal.misc.Unsafe.park(Native Method)
[21:37:49] [Paper Watchdog Thread/ERROR]: 		java.base@21.0.6/java.util.concurrent.locks.LockSupport.park(LockSupport.java:221)
[21:37:4...
rustic folioBOT
rustic folioBOT
rustic folioBOT
#

Stack trace

---- Minecraft Crash Report ----
// Don't do that.

Time: 2025-04-21 14:44:50
Description: Exception in server tick loop

org.spongepowered.configurate.serialize.SerializationException: [entities, spawning, monster-spawn-max-light-level] of type java.lang.Integer: java.lang.NumberFormatException: For input string: "default"
at org.spongepowered.configurate.serialize.NumericSerializers.parseNumber(NumericSerializers.java:346)
at org.spongepowered.configurate.serialize.NumericSerializers.lambda$static$9(NumericSerializers.java:254)
at org.spongepowered.configurate.serialize.FunctionScalarSerializer.deserialize(FunctionScalarSerializer.java:40)
at org.spongepowered.configurate.serialize.ScalarSerializer.deserialize(ScalarSerializer.java:115)
at org.spongepowered.configurate.objectmapping.ObjectMapperImpl.load0(ObjectMapperImpl.java:64)
at org.spongepowered.configurate.objectmapping.ObjectMapperImpl.load(ObjectMapperImpl.java:48)
at org.spongepowered.configurate....

#

Paper version
[18:52:00 INFO]: This server is running Paper version 1.21.4-226-ver/1.21.4@a838a88 (2025-04-17T19:20:57Z) (Implementing API version 1.21.4-R0.1-SNAPSHOT)
You are 1 version(s) behind
Download the new version at: https://papermc.io/downloads/paper
Previous version: git-Paper-17 (MC: 1.20)

You are certainly not running 1.21.4 ^ you were running 1.20, which you downgraded to. But yea, see the config file. Worst case, can always delete the config and have the server recreate it + you changing the values back.

rustic folioBOT
#

After reading my previous message, I thought that perhaps it was badly phrased.
To simplify, I profiled that version you suggested above before moving to the one in the pull request. That version is the obvious first improvement, yes. Changing the order of those 2 blocks of code.

And it does improve performance, but not to the extent where I felt satisfied. Calling find() on every block in that column at the origin was still very expensive.

That is why I chose to try something further beyond: to get every block in the chunk revolving the origin, so that we can check whether the block is an instance of the End Podium block. Then, and only then, if it is, we call find().

This reduced the time needed to "find" the portal immensely. I don't know why, but iterating over the blocks in the surrounding chunck was much faster than calling find() on every block in the central column.

I believe that your suggestion will achieve the same performance if there is some check of whether it ...

rustic folioBOT
#

Paper version
[18:52:00 INFO]: This server is running Paper version 1.21.4-226-ver/1.21.4@a838a88 (2025-04-17T19:20:57Z) (Implementing API version 1.21.4-R0.1-SNAPSHOT)
You are 1 version(s) behind
Download the new version at: https://papermc.io/downloads/paper
Previous version: git-Paper-17 (MC: 1.20)

You are certainly not running 1.21.4 ^ you were running 1.20, which you downgraded to. But yea, see the config file. Worst case, can always delete the config and have the server recreate it + you changing the values back.

oh, I didn't change it so that's probably a bug but yeah thanks anyways!

rustic folioBOT
#

The biggest thing is that for most people these portals should be at the normal position, that being zero zero so for most servers there is an immediate improvement. Otherwise being this aggressive for optimizations that are based on the fact of— “I don’t know why but it’s faster” — isn’t really a great maintenance factor.

I’d rather just have those diffs moved to get the performance improvement for people who have normal portals, where the vanilla behavior is used.

rustic folioBOT
#

Ok, so we are on the same wavelength regarding the fact that most times the portal will be at the (0,0) location, or origin, at any given Y coordinate. I agree.

And then I need to ask:

  • What is a reasonable "offset" that we should account for? If you tell me it is, for example, the chunk around the origin, then the second block of code (that one which iterates over i and i1) can disappear, because the first block of code already prefetches the chunk from cache (1 time cache access, no more). In the version in my PR, that is.

This would significantly simplify the code. Please tell me what you think.

(There are, of course, the cases in which the portal might be located in the boundary of the chunk, that will most probably require another cache access, but those are subject to happen regardless of the chosen offset limit).

rustic folioBOT
rustic folioBOT
#

Expected behavior

it takes damage

Observed/Actual behavior

not taking damage

Steps/models to reproduce

@EventHandler
    public void onEndermanHit(EndermanEscapeEvent event){
        event.setCancelled(true);
    }

shoot an arrow to the enderman, it won't teleport away, but also won't take damage

Plugin and Datapack List

Just a test plugin with the code above

Paper version

This server is running Paper version 1.21.4-225-main@0767902 (2025-04-11T21:49:39Z) (Implementing API version 1.21.4-R0.1-SNAPSHOT)
You are 2 version(s) behind
Download the new version at: https://papermc.io/downloads/paper
Previous version: 1.21.4-211-6ea4202 (MC: 1.21.4)

Other

No response

rustic folioBOT
rustic folioBOT
#

Sounds great to me. I am going to take a look at this PR today, and here's my idea of how to achieve the performance boost without changing too much:

  • First, we exchange the positions of the 2 blocks of code, as you have stated above (let us check the (0,0) column first);

  • Then, let us add a small check before the line that calls the find() method, in the first block of code. This "if" condition will ensure that we only call that method in a block that is an instance of the EndPortalBlockEntity ("find()" is the key reason for the performance decrease);

-> Finally, we could tweak the indexes in the second, more general check, as there are a lot of severely overlapping chunks being checked sequentially, which is slow. But, as you have stated, this is an ocasion that might not even be common enough to warrant changes. Let me know if you'd prefer to keep it as is.

Once you approve this order of events, I will start modifying the code. Is this ok?

rustic folioBOT
#

I'm not sure if the note about endermen taking damage if the event is cancelled was ever really true, in the original commit (https://github.com/PaperMC/Paper/commit/b4ece1619ff313bf22809ba52b191eacfdc2d027) there's nothing really indicating it.

I played around a bit with adding a damage call upon a cancelled event and got some varied results, while they do do damage, arrows just bounce off and tridents go straight through, this is because of both of them are hardcoded to not run any of their damage follow-up code if the hit entity is an enderman.

rustic folioBOT
#

I'm not sure if the note about endermen taking damage if the event is cancelled was ever really true, in the original commit (b4ece16) there's nothing really indicating it.

I played around a bit with adding a damage call upon a cancelled event and got some varied results, while they do do damage, arrows just bounce off and tridents go straight through, this is because of both of them are hardcoded to not run any of their damage follow-up code if the hit entity is an enderman.

it did do damage in old versions, at least 1.12.2

rustic folioBOT
#

I am able to reproduce this on 1.21.4 with the provided data pack.
However, the issue seems to be fixed on 1.21.5 and the data pack loads without errors there and the loot tables and item modifiers are working fine.

I am going to close this for now, as it seemingly is fixed - though I couldn't explain what went wrong here in the first place. Paper does not intentionally change those things.

In case you are able to reproduce this issue on 1.21.5 in the future, feel free to comment and the issue can be re-opened.

rustic folioBOT
rustic folioBOT
rustic folioBOT
#

Okay, I just went through a bit of a rabbit hole with this bug.
I'd argue this is not vanilla behavior, there has been a bug report on Mojira about this exact thing that's been open since 2016, it doesn't actually seem to be intentional, especially since it's been marked as confirmed.
Here's the link to the report: https://bugs.mojang.com/browse/MC/issues/MC-109083
This is a bug that is upstream from vanilla.
I was however wrong about the exact method to reproduce the bug, it's really just being hit directly by a ghast fireball or wither skull and dying.

rustic folioBOT
#

I am in general not really sure about this change.

As collision stuff like this kinda gets yucky.. especially when I feel like there may be multiple hard colliding entities in a hanging entities hitbox that can be causing it to break. Passing this context as a field is also... not 100%. So the order is "undefined" here.

Additionally this is skipping all of the additional checks in the hard collision checks, such as the canCollideWith etc checks.

Quite frankly, I am just not sure if it is worth exposing this.

#

This is a rather extensive refactor for something that otherwise has been left for a very long time. It may be nice to first have a PR to fix the parsePending issue you have described.

The issue is that this is a pretty extensive looking factor for code that otherwise has not been touched in ages, so making sure that the behavior here is the same is tricky realistically.

rustic folioBOT
rustic folioBOT
rustic folioBOT
#

Expected behavior

Custom trial spawner should drop key with custom item name and tags.

Observed/Actual behavior

A generic vault key is dropped instead.

Steps/models to reproduce

Locate any custom structure from Dungeons and Taverns that uses custom trial spawners to obtain a key

Plugin and Datapack List

Image

Image

Paper version

Paper version 1.21.5-54-main@835b955

Other

https://modrinth.com/datapack/dungeons-and-taverns

rustic folioBOT
#

I feel like there may be multiple hard colliding entities in a hanging entities hitbox that can be causing it to break. Passing this context as a field is also... not 100%. So the order is "undefined" here

yeah i mentioned that we might want to add a getRemovers method which returns a list in the original pr description.

though given this is pretty hacky and its not really a huge issue i will be closing this PR.

rustic folioBOT
rustic folioBOT
#

I pretty much agree with owen here. This game of "only a command or the API can change something, I need an event for this" feels like quite the endless.
Especially around defaultgamemode, which does two very different things between the API call (which sets it on every loaded world) and the command, which only sets it on the primary world data.

Same can be said about #12471 to some degree, tho at least there it is per world and difficult might be an actually useful concept compared to default game mode :skull:

rustic folioBOT
#

@Owen1212055 Sorry, I didn't really understand you. This doesn't affect people using the crafting table:

  • Remainder is calculated only when the craft can happen — in vanilla, only when there is a recipe —> vanilla behaviour under this PR
  • Event used to override result slot — craft can occur, BUT no recipe exists —> PR returns default remainder (taking away how many items were consumed) rather than the slot contents (resulting in duplication)

It does not make it seem like "there was a craft even though there wasn't". The PR only modifies the remainder returned when recipe is null, not the whole logic behind it and crafting?

rustic folioBOT
#

I did not add that second check to the overall code. That check already exists in the second block of code of the suggestion you provided, which means it is already part of the version currently being made available by PaperMC.

Look:

'''

ChunkPos chunkPos = new ChunkPos(this.origin);

    for (int i = -8 + chunkPos.x; i <= 8 + chunkPos.x; i++) {
        for (int i1 = -8 + chunkPos.z; i1 <= 8 + chunkPos.z; i1++) {
            LevelChunk chunk = this.level.getChunk(i, i1);

            for (BlockEntity blockEntity : chunk.getBlockEntities().values()) {
                if (blockEntity instanceof TheEndPortalBlockEntity) {
                    BlockPattern.BlockPatternMatch blockPatternMatch = this.exitPortalPattern.find(this.level, blockEntity.getBlockPos());
                    if (blockPatternMatch != null) {
                        BlockPos pos = blockPatternMatch.getBlock(3, 3, 3).getPos();
                        if (this.portalLocation == nu...
rustic folioBOT
#

Maybe also on the names, but I don't think we have proper guidelines for that. Stuff like isIncludeEntities is a bit off, I think we usually do shouldIncludeEntities or includesEntities... or just includeEntities if it's clear it's a getter, this needs more input

You’re totally right here. IntelliJ suggest these when I wrote it, and I wasn't too sure about it, but after you said that, it makes sense to remove "is"

#

Why only allow 2 to 99 though? 🤔

+ Preconditions.checkArgument(item.getAmount() > 1 && item.getAmount() <= 99, "ItemStack amount must be between 1 and 99 but was %s", item.getAmount());

Did I miss some context reading through this or would this indeed fail single items now?

ehhh... true i missing an = because i just test the big numbers and not the normal ItemStack with 1 unit...
PR for fix that... https://github.com/PaperMC/Paper/pull/12505

rustic folioBOT
#

Stack trace

https://mclo.gs/sGXRPhu

Plugin and Datapack List

Paper Plugins (10):
Characters, CityBuild, Commander, Economist, goPaintAdvanced, Protect, RedProtect, ServiceIO, Tweaks, Worlds
Bukkit Plugins (1):
FastAsyncWorldEdit

There are 3 data pack(s) enabled: [vanilla (built-in)], [file/bukkit (world)], [paper (built-in)]
There are no more data packs available

Actions to reproduce (if known)

Occurred randomly

Paper version

This server is running Paper version 1.21.5-54-main@835b955 (2025-05-01T01:47:51Z) (Implementing API version 1.21.5-R0.1-SNAPSHOT)

Other

No response

rustic folioBOT
rustic folioBOT
#

I tested using a new world generated 1.20.4 on paper (which also had the issue at the time before updating to 1.20.5) and after locating a dungeon (I tested with a cave dungeon and a shrine dungeon) and getting a key from the trial spawner would result in a getting a key that does not work on the dungeon's respective vault

Transfer my world and plugins directly to spigot and going through the steps again will cause the spawner to drop the correct key for the dungeon's vault

rustic folioBOT
#

After much profiling and careful analysis, I have obtained the following performance results:

Without background tasks running on the PC:
https://spark.lucko.me/ItQ2aKC7vh?hl=527 -> Using the original version

With background tasks running on the PC, namely VS Code configured to index and build a Gradle project (Paper, in this case), so it is expected to see performance decreases (this was intentional, as to test the behaviour of the fix under stress):

https://spark.lucko.me/6rUTpkwc77?hl=1168 -> Using the original version
https://spark.lucko.me/T8ItEo4IQz?hl=2035 -> Simply inverting the order of the code blocks (@Owen1212055 's suggestion)
https://spark.lucko.me/MGgTApuUGQ?hl=1567 -> Original version with the index tweaks present in the current version of the PR (this version actually doesn't work, since the more general check is unable to find the portal and skipped to the more precise check, which means I will go back to using the indexing of the original version)
ht...

rustic folioBOT
rustic folioBOT
rustic folioBOT
rustic folioBOT
rustic folioBOT
rustic folioBOT
#

We are very close! Now the last group of changes I will be doing here is going to be for "diff reduction". Basically when we make patches we want to make sure the diff is as small as possible. Here for example is what I have rewritten. Basically, we extract the bottom part of the method into a separate method and simply call it above. This allows us to keep those same changes, but avoids the large diff noise that it caused.

Feel free to copy and paste this in, squash and rebuild and see the new patch diff. (Notice it also gets rid of that name collision from moving the loop up!)

Does that all make sense?


    @Nullable

    public BlockPattern.BlockPatternMatch findExitPortal() {

        ChunkPos chunkPos = new ChunkPos(this.origin);



        // Paper start

        BlockPattern.BlockPatternMatch originSearch = findExitPortalExitAroundOrigin();

        if (originSearch != null) {

            return orig...
rustic folioBOT
rustic folioBOT
rustic folioBOT
#
[PaperMC/Paper] New branch created: fix/add-missing-spaces
rustic folioBOT
#

Stack trace

java.lang.IndexOutOfBoundsException: Index 0 out of bounds for length 0
	at java.base/jdk.internal.util.Preconditions.outOfBounds(Preconditions.java:100) ~[?:?]
	at java.base/jdk.internal.util.Preconditions.outOfBoundsCheckIndex(Preconditions.java:106) ~[?:?]
	at java.base/jdk.internal.util.Preconditions.checkIndex(Preconditions.java:302) ~[?:?]
	at java.base/java.util.Objects.checkIndex(Objects.java:365) ~[?:?]
	at java.base/java.util.ArrayList.get(ArrayList.java:428) ~[?:?]
	at org.bukkit.event.entity.EntityTransformEvent.<init>(EntityTransformEvent.java:24) ~[paper-api-1.21.4-R0.1-SNAPSHOT.jar:?]
	at org.bukkit.craftbukkit.event.CraftEventFactory.callEntityTransformEvent(CraftEventFactory.java:624) ~[paper-1.21.4.jar:1.21.4-226-a838a88]
	at net.minecraft.world.entity.monster.Slime.remove(Slime.java:249) ~[paper-1.21.4.jar:1.21.4-226-a838a88]
	at net.minecraft.world.entity.Entity.discard(Entity.java:631) ~[paper-1.21.4.jar:1.21.4-226-a838a88]
	at org.bukkit.cr...
#

So, I am a bit conflicted on if this is actually best described as a percentage to the end users.
All experience orbs have the ability to merge, the value more describes the amount of clusters formed.

If I read 2.5% there, the only thing I can get from that is that 100/2.5 = 40 which, uh? The percentage does not really convey any actually useful information. Could you maybe elaborate a bit on what the 2.5% is supposed to represent?
As said, the docs description "The percentage of XP orbs that merge in the given radius" is not really true, 100% of orbs can merge. I guess it describes creating 40 2.5% large clusters?

rustic folioBOT
#

hi. but i do not call remove slime. i mean, i call remove on Mob interface, but thats the full list. i never touch just slime, but this error comes only slime. anyway, i can fix this in my codes thx to your advice, but still strange.

Thats the full code of remove:
@EventHandler(priority = EventPriority.LOWEST)
public void unloadChunk(ChunkUnloadEvent event) {
GarbageCollector.clearMobs(event.getChunk().getEntities(),true);
}

public static int clearMobs(Entity [] inEnts)
{
int numDel = 0;
for (Entity ents : inEnts) {
boolean isremove = false;
if (ents instanceof Enemy && !(ents instanceof EnderDragon))
if (!isMobOnDefField((Enemy) ents))
isremove = true;
if (ents instanceof Ambient)
isremove = true;
if (ents instanceof Item)
isremove = true;
if (ents instanceof TextDisplay)
isremove = true;
i...

#

Well a Slime is a Mob so yea. Calling .remove() on an already removed entity is generally invalid.
We could create a protection against this, tho I am not too sure we want to as that is a pretty sensitive bit of code.

The above lines look good yes 👍
I'll close the issue for now, if the above does not fix it, feel free to write here and I'll reopen it for further investigations.

rustic folioBOT
rustic folioBOT
rustic folioBOT
rustic folioBOT
#

This PR make a few improvements in the dump commands added in Paper.

  • dumplisteners
    • improvements in messages
    • use same logic for log error when failed to create file like dumpplugins
    • add copy-to-clipboard for copy the path of directory/files created
    • replace the use of deprecated setLenient in favor of the new stricness
    • change the extension of generated file to JSON
  • dumpplugins
    • improvements in messages
    • handle a possible error not catched if the directory cannot be created
    • add copy-to-clipboard for copy the path of directory/files created

not sure why IntelliJ dont really like the nullable annotations used from checkerframework

rustic folioBOT
rustic folioBOT
#

Hello @Owen1212055,

Thank you for your comment.

Regarding the vanilla behavior, I’d just like to point out that according to the second paragraph of the Hostility section on the official Minecraft Wiki, it states the following:

“A player's death causes zombified piglins to become neutral toward the player if the gamerule forgiveDeadPlayers (true by default) is true.”

This means the expected behavior is that Zombified Piglins should become neutral after a player’s death, provided the forgiveDeadPlayers gamerule is enabled — which it is by default. This was the rationale behind the proposed fix.

Of course, I’m happy to adapt the solution based on your guidance.

Thank you again for your time and review!

Best regards,
Guilherme Corvelo

Screenshot from 2025-05-02 18-30-08

rustic folioBOT
rustic folioBOT
#

Expected behavior

Previously serialized as HeroesOfTheVillage, RaidRenamesDataFix does not properly remap that field therefore we will need to make sure that this is renamed in data converter.

Observed/Actual behavior

Not properly remapped, throws error.

Example:
``
[02:56:35] [Server thread/ERROR]: Failed to parse saved data for 'SavedDataType[raids]': No key heroes_of_the_village in MapLike[{HeroesOfTheVillage:[[I;-1184423578,1540371192,-1842508460,-2073820130]],active:0b,center:[I;2572,63,9607],cooldown_ticks:0,group_count:7,groups_spawned:2,id:14,post_raid_ticks:0,raid_omen_level:1,started:1b,status:"ongoing",ticks_active:6106L,total_health:24.0f}]; No key heroes_of_the_village in MapLike[{HeroesOfTheVillage:[],active:0b,center:[I;13317203,83,471279],cooldown_ticks:0,group_count:7,groups_spawned:3,id:13,post_raid_ticks:0,raid_omen_level:1,started:1b,status:"ongoing",ticks_active:1106L,total_health:-24.0f}]; No key heroes_of_the_village in MapLike[{HeroesOfTheVillag...

#

This PR improves the Metrics class integration with bStats by ensuring correct GZIP compression and HTTP header handling, as well as minor code robustness and clarity:

Added the required Content-Encoding: gzip header to the HTTP request in sendData(), ensuring compliance with the bStats API expectations for compressed payloads.
Clarified GZIP stream handling in the compress() method with additional comments, making intent and correctness explicit for future maintainers.
Preserved all original comments and documentation for clarity and maintainability.
No logic or API changes outside of the above all changes are targeted and relevant to proper metrics submission. and all aims for fixing .

rustic folioBOT
#

Hello @Owen1212055,

Thank you again for the clarification.

Following your suggestion, I looked for an official Mojang bug report on this topic. I came across MC-148600, which specifically describes the issue where zombified piglins remain hostile even after the player dies — regardless of who dealt the killing blow.

This appears to align with the behavior I was addressing and seems to indicate that the current behavior might not be intended, or at the very least, not consistent with the gamerule forgiveDeadPlayers.

Best regards,
Guilherme Corvelo

rustic folioBOT
rustic folioBOT
rustic folioBOT
#

Spark Profile

https://spark.lucko.me/qcrSqlz3wE

Description of issue

when a player stands on a block that is being moved like a piston (e.g. a flying machine) the tps just drops like crazy. the hardware I run it on is no piece of junk either.

Plugin and Datapack List

Backuper, floodgate, Geyser-Spigot, LuckPerms, Multiverse-Core, Multiverse-Inventories, Multiverse-NetherPortals, Multiverse-Portals, OpenSit, PlasmoVoice, pv-addon-groups, ViaBackwards, ViaRewind, ViaVersion, Vinyls, VoidGen, WorldEdit

Server config files

server.properties:
#Minecraft server properties
#Fri May 02 22:12:55 PDT 2025
accepts-transfers=false
allow-flight=false
allow-nether=true
broadcast-console-to-ops=true
broadcast-rcon-to-ops=true
bug-report-link=
debug=false
difficulty=normal
enable-command-block=true
enable-jmx-monitoring=true
enable-query=false
enable-rcon=false
enable-status=true
enforce-secure-profile=false
enforce-whitelist=false
entity-broadcast-range-percentage=100
force...

rustic folioBOT
rustic folioBOT
rustic folioBOT
#

There is a lot of stuff depending on the despawn distance being 34. e.g. Creaking roaming distance and follow distance, redstone output, player spawning range. When setting the despawn distance to anything lower it will cause semi weird behaivour as the creaking will willingly move outside its despawn distance and etc. So i think we should either scale that stuff, Math.min it or add extra api for it. though leaving it half broken like this feels bad

rustic folioBOT
rustic folioBOT
#

There is a lot of stuff depending on the despawn distance being 34. e.g. Creaking roaming distance and follow distance, redstone output, player spawning range. When setting the despawn distance to anything lower it will cause semi weird behaivour as the creaking will willingly move outside its despawn distance and etc. So i think we should either scale that stuff, Math.min it or add extra api for it. though leaving it half broken like this feels bad

ok for that then im wait for some more feedback about what do...

  • Add a min like Math.min(Math.abs(DISTANCE_CREAKING_TOO_FAR - 2), PLAYER_DETECTION_RANGE) where DISTANCE_CREAKING_TOO_FAR its the custom field
  • Add tags for the others limits and make the user handle that if its going to modify any for not restrict that behaviours
rustic folioBOT
rustic folioBOT
#

Hi @Owen1212055,

Thanks for the follow-up and the insight into the tellNeutralMobsThatIDied range limitation — that makes a lot of sense and helps clarify the root of the issue.

Just to understand your perspective a bit better: since this patch is aimed at replicating the intended vanilla behavior (as per the gamerule forgiveDeadPlayers and the related Mojang bug report), could you clarify why this should still be behind a configuration option? Wouldn’t correcting this behavior bring Paper closer to vanilla, rather than further from it?

Really appreciate your guidance on this!

Best regards,
Guilherme Corvelo

rustic folioBOT
rustic folioBOT
rustic folioBOT
#

The end goal of this pull request is to address the need to put Inventory on a view builder during the build process. The goal is to completely replace HumanEntity#openInvenotry(Inventory). and deprecate Bukkit#createInventory(InventoryType, ...); methods.

When deciding what approach to take to do this I decided it'd be best to avoid
A. Intrusive insertion of Inventories into builders. (This is because Inventories are supported on only some menus and not others)
B. Adding more inheritance (Adding more inheritance while allowing for a more streamlined builder process also makes implementation and future maintenance a pain).

In this iteration I took the approach to instead add an InventorySupport class that allows for the api consumer to cast their builder and then add the inventory from there.

final var builder = MenuType.GENERIC_9X2.builder();
if (builder instanceof InventorySupport<?> cast) {
    cast.inventory(this.container)
            .build(event.ge...
rustic folioBOT
#

This PR replaces the following deprecated Maven resolver dependencies:

compileOnly("org.apache.maven.resolver:maven-resolver-connector-basic:1.9.18")
compileOnly("org.apache.maven.resolver:maven-resolver-transport-http:1.9.18")

with:

compileOnly("org.apache.maven.resolver:maven-resolver-supplier-mvn3:2.0.8")

Rationale:
The new maven-resolver-supplier-mvn3 module encapsulates the default resolver setup for Maven environments and provides a cleaner and more modern way to integrate Maven resolution logic.

Code changes:

  • Dependencies updated
  • Internal resolver setup adjusted to use the MavenResolverSupplier from the new dependency
  • Add the commons-lang3 dependency because this where transitive from the removed

This simplifies dependency management and reduces direct reliance on individual connector/transport components.

Let me know if additional adjustments are needed.

rustic folioBOT
#

I am a bit iffy on having the model be defined here.
Given those are very very version specific, I think I'd prefer them on the registry entries.

In general, I am unsure how useful exposing the assetId and model of a variant truely is to the general server API. I don't really have a usecase in mind for it, if you have one please share :)
Otherwise, I think we'd be best of just not exposing these in the stable API.

rustic folioBOT
rustic folioBOT
rustic folioBOT
rustic folioBOT
#

This resolves an issue where raid data containing the legacy HeroesOfTheVillage field fails to convert properly to the modern heroes_of_the_village field name during world loading.

What's happening
When loading raid data from older worlds/saves, the data converter misses the field rename from:
HeroesOfTheVillage to heroes_of_the_village

This results in errors like:

No key heroes_of_the_village in MapLike[{HeroesOfTheVillage:[[I;-1184423578,...]]]
Verified fixed conversion using test world saves with legacy raid data
Confirmed error no longer appears in server logs during world loading

this PR fix is also connected to the issue 12515
rustic folioBOT
rustic folioBOT
rustic folioBOT
rustic folioBOT
#

Spark Profile

https://spark.lucko.me/tOqv5BuZpF

Description of issue

I've been running vanilla minecraft on OpenBSD 7.7-current. In a new folder, I created a papermc server. There is a significant performance loss on papermc compared to the vanilla jar.

/usr/local/jdk-21/bin/java -Xms10240M -Xmx10240M -jar _server.jar_

Plugin and Datapack List

Server Plugins (0):

There are 3 data pack(s) enabled: [vanilla (built-in)], [file/bukkit (world)], [paper (built-in)]
There are 3 data pack(s) enabled: [vanilla (built-in)], [file/bukkit (world)], [paper (built-in)]

Server config files

These are all default settings

settings:
  allow-end: true
  warn-on-overload: true
  permissions-file: permissions.yml
  update-folder: update
  plugin-profiling: false
  connection-throttle: 4000
  query-plugins: true
  deprecated-verbose: default
  shutdown-message: Server closed
  minimum-api: none
  use-map-color-cache: true
spawn-limits:
  monsters: 70
  animals: ...
rustic folioBOT
rustic folioBOT
#

Expected behavior

Entities require 2 ticks to be teleported by Nether portals (vanilla behavior).

Observed/Actual behavior

Teleportation occurs after stepping only 1 tick.

Steps/models to reproduce

Use /tick freeze, place a mob in the portal, then use /tick step 1 to advance until teleportation.

Plugin and Datapack List

Server Plugins (0):

There are 3 data pack(s) enabled: [vanilla (built-in)], [file/bukkit (world)], [paper (built-in)]
There are 3 data pack(s) enabled: [vanilla (built-in)], [file/bukkit (world)], [paper (built-in)]

Paper version

This server is running Paper version 1.21.4-227-ver/1.21.4@7675321 (2025-04-28T19:07:04Z) (Implementing API version 1.21.4-R0.1-SNAPSHOT)
You are running the latest version

Other

No response

rustic folioBOT
rustic folioBOT
rustic folioBOT
rustic folioBOT
rustic folioBOT
#

Expected behavior

$ docker run --rm -p 25565:25565 -e EULA=TRUE -e MOTD= itzg/minecraft-server
... <snipped> ...
[22:25:48] [Netty Epoll Server IO #6/ERROR]: Error sending packet clientbound/minecraft:disconnect                                                                                                                                    
io.netty.handler.codec.EncoderException: Sending unknown packet 'clientbound/minecraft:disconnect'                                                                                                                                    
        at zd.a(SourceFile:50) ~[server-1.21.5.jar:?]                                                                                                                                                                                 
        at zd.encode(SourceFile:14) ~[server-1.21.5.jar:?]                                                                                                                            ...
#

Generally lgtm on the idea of this. During PR Party, the concern that came up was a very niche change like the screen message requiring a rename to the death message. Would you be fine with moving screen death component to an "override" kinda system?

null would indicate falling back to the deathMessage() Anything else would override.

You would then lose the ability to remove the screen message... Also it being different model from deathChatMessage might confuse devs. I think. Also also I left the original deathMessage() to allow changing both screen&chat values...

If you insist on this, I can change it, but I think this model would be more consistent...

rustic folioBOT
#

Fair points, tho I will say that you do not loose the ability to hide the death message.
Component.empty() would work perfectly fine there to "hide it". The server has to send the packet and has to provide a component, it is just "empty". null would be the only value for the death message component that would trigger a fallback to the chat/deathMessage.

Whether or not the override system is confusing is I guess a good discussion to be had.
I'd just really like to avoid a rename/deprecation change to #deathMessage for a feature that is as niche as the screen death message being different from the one in chat, so the override layout was the thing we came up with.
I'll grumble about it for a bit longer, maybe I can come up with a solution outside of override but yea, such a system certainly would not prevent setting the screen message to empty()

#

Ah, the discussion was marked as resolved, I did not see it :sweat_smile: mb
I guess the magic boolean has always been there, so exposing it is a general good change.
I'll chat with owen on the naming of this, I think I'd prefer this being named very closely after the gamerule and/or include the fact that this is a gamerule in the method name but, that is pending further chats with other team members.

#

Component.empty() would work perfectly fine there to "hide it". The server has to send the packet and has to provide a component, it is just "empty". null would be the only value for the death message component that would trigger a fallback to the chat/deathMessage.

Fair point...

I'd just really like to avoid a rename/deprecation change to #deathMessage for a feature that is as niche as the screen death

AFAIR I only deprecated the getter, setter is still there nondeprecated as a utility method to rename both. I could leave the getter undeprecated as well, but then it might be confusing...

I would also argue it is not as niche. I think it is quite useful to allow displaying different values to the player dying and other players and currently there is no api for that (I do it with packets currently)...

#

AFAIR I only deprecated the getter, setter is still there nondeprecated as a utility method to rename both. I could leave the getter undeprecated as well, but then it might be confusing...

Yea, the setter isn't deprecated, tho I am unsure how consistent that is with a full separation of chat and screen death message when it is just named "deathMessage".

I would also argue it is not as niche. I think it is quite useful to allow displaying different values to the player dying and other players and currently there is no api for that (I do it with packets currently)...

It certainly is quite useful, I just have never heard a feature request for it on github or the discord (outside of your just now), which is why I am considering this niche. It certainly isn't the main behaviour of the event to split these two.
Having a single source of "true" death message is pretty useful when plugins attempt to interop. Promoting the single-player packet only screen death message to the...

#

It certainly is quite useful, I just have never heard a feature request for it on github or the discord (outside of your just now), which is why I am considering this niche. It certainly isn't the main behaviour of the event to split these two.

I blame it to the fact users either didn't need that or did not know that was possible :D

Having a single source of "true" death message is pretty useful when plugins attempt to interop. Promoting the single-player packet only screen death message to the same level as the "death message" or now "chat death message" means choosing the "correct" one is now pretty much up to the plugins.

Ok that is a strong point, let's go with the override model... I will update the PR later today...

rustic folioBOT
#

Is your feature request related to a problem?

I want to reliably get the entity involved in killing a player upon their death. In cases where an entity is directly responsible for the player's death, this can easily be done with PlayerDeathEvent#getDamageSource#getCausingEntity. However, this returns null in cases where the entity is indirectly responsible, such as when a player is "doomed to fall" by an entity. Calling Player#getKiller is not a solution for this, because that only returns a Player.

Proof that Minecraft tracks the killing entity in these indirect cases:

Image

Describe the solution you'd like.

Some kind of PlayerDeathEvent#getKiller method that returns an Entity representing the entity that is directly, or indirectly, responsible for the player's death, as tracked by Minecraft.

Describe alternatives you've considered.

Already described in the "Is you...

rustic folioBOT
#

Expected behavior

When the method is called, the entity fires an arrow with a loaded crossbow.

Observed/Actual behavior

Nothing happens

Steps/models to reproduce

I created a mobgoal, what makes the entity perform ranged attack

@Override
    public void tick() {
        LivingEntity target = entity.getTarget();
        if (target != null) {
            boolean hasSight = entity.hasLineOfSight(target);
            boolean var2 = seeTime > 0;
            if (hasSight != var2) {
                seeTime = 0;
            }

            if (hasSight) {
                ++seeTime;
            } else {
                --seeTime;
            }

            double distanceSqr = entity.getLocation().distanceSquared(target.getLocation());
            boolean canAttack = (distanceSqr > attackRadiusSqr || seeTime > 5) && attackDelay == 0;

            entity.lookAt(target,30f,30f);

            switch (crossbowState) {
                case UNCHARGED -> {
                   ...
rustic folioBOT
rustic folioBOT
#

Is your feature request related to a problem?

Currently, plugin developers cannot retrieve a player's body yaw (i.e., the direction the player's body is facing) in a version-stable and API-safe way. This makes it difficult to build features that rely on accurate body orientation, such as animation systems, custom AI, or advanced detection logic.

Accessing body yaw currently requires NMS and reflection, which breaks with each update and makes plugins fragile.

Describe the solution you'd like.

Add a method like float Player#getBodyYaw() to the Paper API.

This would expose the player's current body orientation in degrees, independent of their head/camera rotation (which is already available via getLocation().getYaw()).

This field already exists internally in NMS (EntityPlayer.bodyYaw), so exposing it via the API would be straightforward and greatly beneficial.

Describe alternatives you've considered.

  • Accessing NMS via `((CraftPlayer) player).getHandle().body...
#

This is caused by moonrise, specifically this part here:
https://github.com/PaperMC/Paper/blob/c98cd65802fcecfd3db613819e6053e2b8cbdf4f/paper-server/patches/features/0015-Moonrise-optimisation-patches.patch#L26802-L26815

When the teleportDelay is over 400, a ClientboundEntityPositionSyncPacket is used instead of a ClientboundMoveEntityPacket, which seems to be causing the jitter. Probably has something to do with how the client interprets velocity for the different packets?

rustic folioBOT
#

Expected behavior

Using a nether portal should link to the closest one (within 128 blocks) in the overworld.

Observed/Actual behavior

Nether portal doesn't link with the closest one (within 128 blocks) in the overworld instead a new one gets created, however if a player stands close to the destination portal in the overworld, no new portal are created on you're sent to the destination portal.

Steps/models to reproduce

Build a portal in the nether at coordinates (but it shouldn't matter) X: 100 Y: 100 Z: 0
Build a portal in the overworld at coordinates X: 132 Y: 100 Z: 0

100 / 8 = ~12.5
We add about 120 blocks to be roughly on the edge of the search radius, so X: 12 + 120

Observe how you do not get sent to that portal and instead a new one gets created

Repeat the entire process, but this time have a player stand in the overworld next to the destination portal

Observe how you get sent to the destination portal and no new portal are created

Plugin and Data...

rustic folioBOT
#

Expected behavior

Items smoothly flowing around:

https://github.com/user-attachments/assets/a9fe4c23-087e-4bd9-bb0f-d9dadbbc063b

Observed/Actual behavior

Erratic motion of items in water streams:

https://github.com/user-attachments/assets/0793a296-21d3-4d6e-a63f-f79946be97fd

If I'm close enough they move normally.

Steps/models to reproduce

Boot up a new Paper server on Minecraft 1.21.4, build a simple circular water stream and move more than ~16 blocks away.

Plugin and Datapack List

plugins
[21:15:59 INFO]: ℹ Server Plugins (0):
datapack list
[21:16:24 INFO]: There are 3 data pack(s) enabled: [vanilla (built-in)], [file/bukkit (world)], [paper (built-in)]
[21:16:24 INFO]: There are no more data packs available

Paper version

version
[21:17:34 INFO]: Checking version, please wait...
[21:17:35 INFO]: This server is running Paper version 1.21.4-227-ver/1.21.4@7675321 (2025-04-28T19:07:04Z) (Implementing API version 1.21.4-R0.1-SNAPSHOT)
You are runn...

rustic folioBOT
#
[PaperMC/Paper] branch deleted: feat/internal-command-registration
rustic folioBOT
#

After some more thought, this can literally be implemented via

@EventHandler
public void on(final PlayerDropItemEvent event) {
    if (event.getPlayer().isDead()) event.setCancelled(true);
}

Passing the "was keep inventory" around is also simple on a plugin perspective with the death event being called prior to the dropping.

In the name of not polluting our configuration with things plugins could be implementing, I'll be closing the PR.
Thank you so much for it anyway, as per usual, really well crafted and documented <3

rustic folioBOT
#
[PaperMC/Paper] New branch created: fix/async-level-data
rustic folioBOT
rustic folioBOT
#

This PR is addresses #12314

The goal of this pull request is to enhance the current Player#[hide:show]Entity and Player#[hide:show]Player. It is somewhat frequently requests that these methods should have some ability to list hidden players. To address this I slightly tweaked the Player#listPlayer Player#unlistPlayer api to not check for can seeing and instead allow for listing unseen players.

rustic folioBOT
#

Is your feature request related to a problem?

With paper's expanding registry support, many things you can add to the registry aren't really worth it without resource packs such as banner patterns, painting variants, and now mob variants. Using resource packs with plugins currently requires hosting the packs externally which can get really messy when it comes to making public plugins.

Describe the solution you'd like.

I could see how this may be out of scope for Paper, but I would like to see a system that allows for plugin developers to require resource packs through an option in their paper-plugin.yml. These could then either be bundled into the plugin's resources or placed into something like a "resourcepacks" directory in the server's main directory. Then Paper would verify the resource packs and essentially host a web server with these resource packs readily accessible to be sent to players. This way bundling resource packs with plugins is much more streamlined and...

rustic folioBOT
rustic folioBOT
rustic folioBOT
#

Welcome to paper :wave:
Thank you for the PR!

The linked issue and this PR are a bit of a head-scratcher for me given how stupidly hot this event could be, quite possibly the hottest event in the server in some scenarios given it is called n^2 times for non stacking item clusters.
There are mitigating factors, e.g. stationary items only checking for merges every 40 ticks instead of every 2 and obviously the merge radios being relatively small, e.g. only .5, which at least would make it rare for this event to become incredibly spammy.

As you pointed out however, the event also fails in a couple areas which might prove pretty counter-intuitive, e.g. max size or unstackable.
I am unsure if the better alternative to such an event wouldn't be the respective plugins that want to force such behaviour to implement their own merging checks on a tick-based iteration through item entities they know to require such checks. It would a) allow such plugins full control over me...

rustic folioBOT
#

As far as verification goes it would basically be checking for a valid pack.mcmeta and the right file structure, but yeah, that makes sense. Hopefully one day Mojang will give us a better "drag and drop" solution for resource packs like there is for data packs, but being able to send multiple packs from the server was a great step in the right direction.

rustic folioBOT
#

Expected behavior

LevelledMobs plugin should load just fine, as it did before I upgraded from version #69 to #73. The plugin didn’t receive any updates, and nothing changed except for the replacement of the Paper .jar file.

Observed/Actual behavior

LevelledMobs crashes, with an error in the console.

Steps/models to reproduce

  1. Update to Paper 1.21.5 #73 (the latest version as of the time writing this).
  2. Restart the server with LevelledMobs plugin installed
  3. LevelledMobs won't launch.

Plugin and Datapack List

LevelledMobs, ViaVersion, ViaBackwards, SeeMore.

Paper version

This server is running Paper version 1.21.5-73-main@ab0253f (2025-05-07T00:19:05Z) (Implementing API version 1.21.5-R0.1-SNAPSHOT)

Other

[20:56:05 ERROR]: [LevelledMobs] Error initializing plugin 'LevelledMobs-4.3.1 b112.jar' in folder 'plugins/.paper-remapped' (Is it up to date?)
java.lang.NullPointerException: Cannot invoke "java.lang.reflect.Constructor.newInstance(Objec...
#

Here is the full console log, in case it's useful:

container@pterodactyl~ java -Xms3072M -Xmx6144M -jar server.jar
Starting org.bukkit.craftbukkit.Main
[20:55:59 INFO]: [bootstrap] Running Java 21 (OpenJDK 64-Bit Server VM 21.0.7+6-LTS; Eclipse Adoptium Temurin-21.0.7+6) on Linux 6.1.0-13-amd64 (amd64)
[20:55:59 INFO]: [bootstrap] Loading Paper 1.21.5-73-main@ab0253f (2025-05-07T00:19:05Z) for Minecraft 1.21.5
[20:55:59 INFO]: [PluginInitializerManager] Initializing plugins...
[20:55:59 INFO]: [PluginInitializerManager] Initialized 4 plugins
[20:55:59 INFO]: [PluginInitializerManager] Bukkit plugins (4):
 - LevelledMobs (4.3.1 b112), SeeMore (1.0.2), ViaBackwards (5.3.2), ViaVersion (5.3.2)
[20:56:02 INFO]: Environment: Environment[sessionHost=https://sessionserver.mojang.com, servicesHost=https://api.minecraftservices.com, name=PROD]
[20:56:02 INFO]: Found non-pack entry './world/datapacks/.DS_Store', ignoring
[20:56:03 INFO]: Loaded 1373 recipes
[20:56:03 INFO]: Loaded 1484 ad...
#
[PaperMC/Paper] branch deleted: fix/async-level-data
rustic folioBOT
#

After further reviewing this logic there are significant things that need to be redone with the flattening logic. We will be revisiting this in hopes of better resolving issues like these. In this current implementation, (not inheritably your changes) there are circular redirects/forks that occur that cause improving this logic to fail.

This requires more significant refactors that we will be reserving for the dev team.

Thank you so much for your PR, and sorry for the wait. ❤️

rustic folioBOT
rustic folioBOT
rustic folioBOT
rustic folioBOT
rustic folioBOT
rustic folioBOT
rustic folioBOT
rustic folioBOT
#

Currently works.

BlocksAttacks.DamageReduction damageReduction = BlocksAttacks.DamageReduction.damageReduction().type(RegistrySet.keySet(RegistryKey.DAMAGE_TYPE, TypedKey.create(RegistryKey.DAMAGE_TYPE, DamageType.ARROW.key()), TypedKey.create(RegistryKey.DAMAGE_TYPE, DamageType.MOB_ATTACK.key()), TypedKey.create(RegistryKey.DAMAGE_TYPE, DamageType.EXPLOSION.key()))).horizontalBlockingAngle(1).base(0).factor(0.5f).build();

BlocksAttacks blocksAttacks = BlocksAttacks.blocksAttacks()
                    .disableCooldownScale(0)
                    .blockSound(Sound.BLOCK_ANVIL_DESTROY.key())
                    .itemDamage(BlocksAttacks.ItemDamageFunction.itemDamageFunction().build())
                    .addDamageReduction(damageReduction)
                    .build();

ItemStack itemStack = ItemType.DIAMOND_SWORD.createItemStack();
itemStack.setData(DataComponentTypes.BLOCKS_ATTACKS, blocksAttacks);

just need make sure dont forget any and the docs.

rustic folioBOT
#

Expected behavior

Using a distance=0 selector should successfully select entities summoned in the same tick, which are exactly on top of the entity executing, at the position of the command.

Observed/Actual behavior

Using the selector distance=0 does not select the expected entity.

Steps/models to reproduce

Use these commands to test
/tick freeze
/loot spawn ~ ~ ~ loot minecraft:blocks/chiseled_stone_bricks
/say @e[distance=0]
See if the item name is spit out as well as the player.

This command will work always, but is not the most precise possible in datapack dev tools, and can lead to some possible problems if this is the only solution.
/say @e[distance=0..0.001]

Plugin and Datapack List

No plugins installed.

Paper version

This server is running Paper version 1.21.4-229-ver/1.21.4@e2ca477 (2025-05-09T15:52:06Z) (Implementing API version 1.21.4-R0.1-SNAPSHOT)

I believe it's in 1.24.4 and other versions, but don't have time to check.

Oth...

rustic folioBOT
#
[PaperMC/Paper] branch deleted: jd/getCustomModelData-deprecation
rustic folioBOT
#

As cat said on discord, mitigating this is fun due to how the option works, it slightly changes the position of the item so that it's the exact same when sent to the client, causing the distance=0 to no longer be true. Luckily it's only for item entities at least.

Possible mitigations that I see would be to change the selector to still count distance as 0 for items if it's within the imprecision, or to make the position change apply later in the tick or a tick later, but both of these thoughts definitely aren't great.

The smallest possible distance that does work 100% of the time is 1/4096 (/say @e[distance=0..0.000244140625]), but that's obviously not as good as =0 is.

rustic folioBOT
rustic folioBOT
#

Is your feature request related to a problem?

Yes. Currently, when creating custom Brigadier commands in Paper using StringArgumentType.word() or StringArgumentType.string(), it is not possible to enter vanilla-style operation symbols (e.g., +=, *=, %=, etc.) without the argument turning red and being rejected as invalid by the client. This prevents the user from completing the command and adding arguments after it.

The only workaround is to use StringArgumentType.greedyString(), but that restricts me from adding further arguments, which limits command flexibility and usability.

Describe the solution you'd like.

I would like Paper to add a native ArgumentType that allows for the inclusion of vanilla-style operation symbols (+=, -=, *=, /=, %=, etc.) in a way that works seamlessly with the client’s command validation—just like /scoreboard players operation in vanilla Minecraft.

Ideally, this argument type would:

  • Provide proper suggestions for ...
#

Yes, here is a typical command in vanilla Minecraft.
It takes different operations and shows them as suggestions and syntax highlighted, then after it, it then prompts for next argument:
/scoreboard players operation @s Health += 10

<img width="812" alt="Image" src="https://github.com/user-attachments/assets/9876df69-5287-4c3c-8da3-762bd85d801d" />

rustic folioBOT
rustic folioBOT
rustic folioBOT
rustic folioBOT
rustic folioBOT
rustic folioBOT
#

Expected behavior

Hover events do not appear to support translatable components.

// text.foo = "foo"
Component.translatable("text.foo")
  .hoverEvent(HoverEvent.hoverEvent(HoverEvent.Action.SHOW_TEXT,
    Component.translatable("text.foo")))

Paper 1.21.5

Observed/Actual behavior

The code produces "foo" when sent to a player, but "text.foo" when hovered.

Steps/models to reproduce

Use the code above.

Plugin and Datapack List

? Server Plugins (4):
Bukkit Plugins:

  • LuckPerms, NBTAPI, prism, WorldEdit

There are 3 data pack(s) enabled: [vanilla (built-in)], [file/bukkit (world)], [paper (built-in)]

Paper version

1.21.5-76-main@04ffca0 (2025-05-09T15:38:33Z) (Implementing API version 1.21.5-R0.1-SNAPSHOT)

Other

No response

rustic folioBOT
rustic folioBOT
#

Expected behavior

I am using the newest version of paper

I have a Item Display above my chest which gets refreshed every second with the items in the chest. after restarting the server in 1.21.5 the item display is frozen with the last item and not refreshing anymore. in 1.21.1 it works perfectly

Observed/Actual behavior

As I mentioned earlier, The Item Display is frozen, i did a System Output and in console it shows the correct current item, in minecraft, it doesnt refresh anymore.

Steps/models to reproduce

The Piece of code: https://pastebin.com/y25Fzvjb
The Server logs: https://pastebin.com/y25Fzvjb

Plugin and Datapack List

No PLugins, no DataPacks

Paper version

1.21.5-69

Other

No response

rustic folioBOT
#

Finally got around to benchmarking this myself.

50 player characters with 400 pigs, so maximum 20_000 checks a tick.
Running the server for 2400 ticks, or 2 minutes, the required CPU time of TemptGoal#canUse is reduced from 2507ms (1.04ms per tick) to 160ms (or 0.06ms per tick).

Obviously this kind of scenario is incredibly fabricated, normal servers are not going to be running into such extreme situations if their player base is remotely distributed. This however could be in the realm of responsibility if case of larger farms using animals with tempt goals etc.
Given the only regression compared to vanilla this patch introduces is the skipped recomputation mid-tick, and tick order is generally not something reliably exploited/depended upon, I'd argue this is fine to merge.

We should still monitor this patch once merged. In case the behaviour change does infact prove problematic, the behaviour could easily be toggled via a configuration option. With how easy this is...

rustic folioBOT
rustic folioBOT
rustic folioBOT
rustic folioBOT
rustic folioBOT
rustic folioBOT
#

True, I guess; I guess it would maybe make sense to try to point to people about those recommendations somewhere, the entire reason we patched this was because it was a huge problem for servers, snowballs are more accidently so due to low sim distances rather than something people on the server do; 1.21.4 has 55k users, .5 has 27k users, I don't think that we're in the phase of experimental of just being able to gloss over stuff as easily as "we're still in experimental" now

#

I thought this was merged because the linked issue for it was considered a confirmed but not fixed vanilla issue.
Otherwise, this should have had a config option from the very beginning if this wasn't a plain vanilla bugfix.

We could very well include this in the stable 1.21.5 ping and note that, to re-create this, people ought to set the arrows TTLs.

#

a bunch of things probably should have had config options when we added them, we have also generally been considering these builds "probably stable but we can't really go back to experimental mid run for some library and so we're keeping it as quasi experimental" for some time, I don't think that the "but we're still experimental" flag really has much of a bearing on anybody non-religous over that stuff

rustic folioBOT
#

most entity limiting stuff I see generally caters onto living entities, not targeting random entities which people might be upset if they lost; most of the servers I saw impacted by the snowball issue were generally servers using dangerously low simulation distance values, not your average normie servers which were getting hit with the arrow one intentionally

rustic folioBOT
#

most entity limiting stuff I see generally caters onto living entities, not targeting random entities which people might be upset if they lost; most of the servers I saw impacted by the snowball issue were generally servers using dangerously low simulation distance values, not your average normie servers which were getting hit with the arrow one intentionally

This was patched more due to it being a support burden, rather than it being some super duper unmitigatable by servers issue

Are you referring to snowballs entering unloaded chunks? Not the same snowball issue I was meaning, look at this video: https://www.youtube.com/watch?v=aItr0pRsBa8 plus snowballs into unloaded chunks can already be mitigated with configuration chunk save limits

rustic folioBOT
rustic folioBOT
rustic folioBOT
rustic folioBOT
rustic folioBOT
rustic folioBOT
#

Expected behavior

According to the option's description ("prevent ender pearls from being saved to the player and loading chunks, meaning they will behave like they did in 1.21.1 and before"), when legacy-ender-pearl-behavior is true:
An Ender Pearl thrown by a player who dies before the pearl impacts should despawn or be invalidated.
No teleportation should occur for the player after they respawn.
No teleportation should occur if the player changes dimension before the pearl impacts. The pearl should effectively become invalid for the player once they are no longer in the dimension it was thrown in or upon their death.

Observed/Actual behavior

Even with legacy-ender-pearl-behavior set to true, players are still occasionally teleported by an Ender Pearl in the following edge-case scenarios:
Death Race Condition: If a player throws an Ender Pearl (especially at short range) and dies almost simultaneously with the pearl's impact (e.g., from fall damage, /kill, or other imm...

rustic folioBOT
#

What you describe is what happens in Vanilla 1.21.1 (parts of that in 1.21.5 as well). While the chunk is still loaded and the ender pearl hits something, the thrower is teleported if online, it doesn't matter if you switch dimensions. If you want help with preventing this via events, you can use our paper-dev help channel

rustic folioBOT
#

This api is a sort of a one way override for ensuring a player stays unlisted. e.g. isListed also just return whether the player has such an override set for the passed player or not. So this will cause some inconsistent behaivour between listing and unlisting (so it made sense to disallow this api for hidden players, as normally players are always listed). I would be in favor of adding a new sort of tristate override system that supports both overriding listing and unlisting

rustic folioBOT
#

This api is a sort of a one way override for ensuring a player stays unlisted. e.g. isListed also just return whether the player has such an override set for the passed player or not. So this will cause some inconsistent behaivour between listing and unlisting (so it made sense to disallow this api for hidden players, as normally players are always listed). I would be in favor of adding a new sort of tristate override system that supports both overriding listing and unlisting

I think the current behavior is also somewhat confusing I was debating opening an issue for this. Somewhat unintuitively, the #isListed method also returns true for players that are hidden. This isn't specified in the java docs and somewhat circumvents the behavior I'd intuitively assume #isListed performs.

I also like the idea of the tristate system. Have you thought about how that might take shape? I feel like doing too much overloading might clutter this API.

rustic folioBOT
rustic folioBOT
#

It could be as simple as

that wouldn't provide a way to list them once they are already hidden without listing

I also like the idea of the tristate system. Have you thought about how that might take shape? I feel like doing too much overloading might clutter this API.

I would have just deprecated the old methods and added new ones such as:

setter: listingOverride(Player, Tristate)
getter: listingOverride(Player)

while making sure the deprecated methods keep their current behaivour

rustic folioBOT
rustic folioBOT
rustic folioBOT
rustic folioBOT
rustic folioBOT
rustic folioBOT
rustic folioBOT
rustic folioBOT
#

One of the biggest problems on large survival servers is a long tile entity tick loop, especially hoppers. By introducing a limit on the time tile entites are allowed to take, this can be alleviated.

A config option is added to configure the amount of milliseconds that a tile entitiy ticking may take in a single tick, setting it to 0 (which is also the default value) disables the feature.

#

One of the biggest problems on large survival servers is a long tile entity tick loop, especially hoppers. By introducing a limit on the time tile entites are allowed to take, this can be alleviated.

A config option is added to configure the amount of milliseconds that a tile entitiy ticking may take in a single tick, setting it to 0 (which is also the default value) disables the feature.

rustic folioBOT
rustic folioBOT
rustic folioBOT
#

I think this not cover the whole fix added in https://hub.spigotmc.org/stash/projects/SPIGOT/repos/craftbukkit/commits/3b4fd5b321f4440a2b3a67f3945739b45e6e687f

The changes to WorldServer appeared unrelated (eg. why was lightning touched?), and this patch alone was enough to resolve the crash in my local testing. But I'm happy to bring across the Spigot change in full if that's the preferred route.

rustic folioBOT
rustic folioBOT
#

Welcome :)

not sure about the name, but i dont wanna suggest a thing like getSpawnItem, also for non NMS classes you dont need add the // Paper comments

Yea, I was thinking something on the line of getPickItemResult or getPickItem but I'm not sure really what would work for the name could just stick to getPickResult but it seems like a confusing name to me I'm open to suggestions though!

rustic folioBOT
rustic folioBOT
rustic folioBOT
rustic folioBOT
#

This PR adds two new methods to UnsafeValues to improve the workflow of working with Advancements:

  • loadAdvancement(NamespacedKey key, String advancement, boolean persist)
  • loadAdvancements(Map<Key, String> advancements, boolean persist)

The first method just adds a new overload to the existing loadAdvancement method, which allows for disabling the printing into the Bukkit datapack. From my testing, this doesn't actually persist the Advancement anyways, so I am not even entirely certain what the point of storing it in the Bukkit datapack is, but that's probably a bug and it was intended to work that way.

The second method allows for bulk-registering advancements.

<details>
<summary>Example of registering two enchantments using the new loadAdvancements method</summary>

final boolean persist = false;
Bukkit.getUnsafe().loadAdvancements(Map.of(
        new NamespacedKey("cool_plugin", "cool/root"), """
            {
                "display": {
...
rustic folioBOT
rustic folioBOT
#

Is your feature request related to a problem?

Hard to know when the right time to remove a deprecated feature is

Describe the solution you'd like.

You can just search Github for a specific method usage across all repositories, if the repo is popular you can PR the new method, meaning you can remove the old one with peace of mind that it isn't being widely used, stuff like bukkit PlayerRecipeBookClickEvent is only being used by a couple plugins

Describe alternatives you've considered.

idk, this solution is genius though

Other

No response

#

I disagree. It's not a solution but a workaround. Why every professional project I work on in the past 10 years uses frameworks that includes slf4j ? Logging features of libraries like slf4J and log4j are useful for reducing log noises without loosing the ability to diagnose production issues. This is necessary to build monitoring and alerting in a devops organization.

By the way, I found that: https://github.com/Djaytan/bukkit-slf4j. Not tested yet.

sir this is a minecraft server, not an enterprise SASS as a service fintech SingletonAbstractBeanInstanceFactory

rustic folioBOT
#

Removal of deprecated methods isn't decided based on the popularity of them. Instead it depends on the viability of maintaining the methods, functionality (some things simply got removed from the game) and how Paper can provide compatibility and replacements for them.

Your example is deprecated simply because its a duplicate event. It might get removed if compatibility can be provided via asm-utils at some point, e.g. listeners to the old event can be redirected to the new one on a bytecode level.
And while the Bukkit API has always provided long-term backwards compatibility, sometimes the game changes in such a fundamental way that methods will have to be removed, no matter how popular they are.

Additionally, pure GitHub repo stats are pretty meaningless.

  1. GitHub does not index all public repositories reliably.
  2. There are plenty of plugins without publicly published source code, or with source code published on another platform.
  3. Pure plugin count is a pretty meaningless...
rustic folioBOT
#

Removal of deprecated methods isn't decided based on the popularity of them. Instead it depends on the viability of maintaining the methods, functionality (some things simply got removed from the game) and how Paper can provide compatibility and replacements for them.

Your example is deprecated simply because its a duplicate event. It might get removed if compatibility can be provided via asm-utils at some point, e.g. listeners to the old event can be redirected to the new one on a bytecode level. And while the Bukkit API has always provided long-term backwards compatibility, sometimes the game changes in such a fundamental way that methods will have to be removed, no matter how popular they are.

Additionally, pure GitHub repo stats are pretty meaningless.

  1. GitHub does not index all public repositories reliably.
  2. There are plenty of plugins without publicly published source code, or with source code published on another platform.
  3. Pure plugin count is a pr...
rustic folioBOT
#

A very very large amount of plugins are never uploaded. So it isn't really a fair comparison. Furthermore, as Malfrador already said, Paper doesn't "just" remove methods. Those decisions are based on other factors he listed.

Do you have any specific issue with why you do not want to have deprecated methods in-code? Because I don't think there is any real issue with having them there as long as they do not add maintenance time.

rustic folioBOT
#

Expected behavior

Regardless of whether it is a book or not, the lectern should drop the itemStack contained in its nbt.

Observed/Actual behavior

The lectern only drops the itemStack in its NBT if its a book

Steps/models to reproduce

store any non-book itemStack in the nbt. eg. using. "/setblock ~ ~ ~ lectern{Book:{id:"minecraft:dirt",count:1}}"
Break the lectern.

Plugin and Datapack List

None

Paper version

This server is running Paper version 1.21.4-147-main@3bd69f2 (2025-02-10T22:59:40Z) (Implementing API version 1.21.4-R0.1-SNAPSHOT)\nYou are 83 version(s) behind\nDownload the new version at: https://papermc.io/downloads/paper

Other

No response

rustic folioBOT
rustic folioBOT
rustic folioBOT
#

Is your feature request related to a problem?

Supporting lastDamageSource is from my perspective a better implementation to lastDamageCause and provides the same and more information to the users. Especially in cases where a custom damage type might be defined.

Describe the solution you'd like.

I would like a method added onto LivingEntity preferably like #getLastDamageSource matching it along with getLastDamage and getLastDamageCause

Describe alternatives you've considered.

I haven't considered any alternatives to this implementation

Other

While I'm aware that getLastDamageCause returns EntityDamageEvent I find this behavior of it in poor taste, I would rather use a method provided by minecraft than one that I assume is custom made by the server.

rustic folioBOT
#

Expected behavior

Player#getCombatTracker should return a non-stale instance of CombatTracker.

Observed/Actual behavior

Player#getCombatTracker returns a stale combat tracker after the player dies.

Steps/models to reproduce

Kill a player twice, and observe the state of their combat tracker after each death. After the first death, the combat tracker will no longer update.

Plugin and Datapack List

Just a test plugin, which prints the current state of the combat tracker.

Paper version

This server is running Paper version 1.21.5-80-main@841d634 (2025-05-17T14:18:02Z) (Implementing API version 1.21.5-R0.1-SNAPSHOT)
You are running the latest version
Previous version: 1.21.5-69-c98cd65 (MC: 1.21.5)

Other

This is due a player's API combat tracker not being recreated on death.

The API tracker is created here, in CraftLivingEntity:
https://github.com/PaperMC/Paper/blob/841d63423076b815500380a896f45fbb9c1cb19d/paper-server/src/main/java/org/bukkit/c...

rustic folioBOT
rustic folioBOT
#

I disagree. It's not a solution but a workaround. Why every professional project I work on in the past 10 years uses frameworks that includes slf4j ? Logging features of libraries like slf4J and log4j are useful for reducing log noises without loosing the ability to diagnose production issues. This is necessary to build monitoring and alerting in a devops organization.
By the way, I found that: https://github.com/Djaytan/bukkit-slf4j. Not tested yet.

sir this is a minecraft server, not an enterprise SASS as a service fintech SingletonAbstractBeanInstanceFactory

Please don't caricature my position in order to criticise it.
Adding a clean logging system does not mean setting up a gas factory.

rustic folioBOT
#

I'm not really sure this is worth the effort and potential breakages it would entail. This seems like overkill for a Minecraft server.

Exposing details such as the log level to plugins would just lead to misuse with plugins setting wildly random, potentially very annoying levels, because "my plugin is cooler than yours". We already have plenty of plugins spamming the log with ASCII art on startup because they think it's cool. Don't have to make that worse by giving people more tools for that.

This fine granularity might be something developers in an professional setting might appreciate, but in this community with plenty of plugins not even the logger in the first place - is that really something worth implementing?

More detailed login for bug reports is a very valid use case, however most plugins simply use a "debug" Boolean in their config for that. Which is also much easier to change for the end-user you are requesting the bug report from than some full-blown logging config...

rustic folioBOT
#

Pull Request Overview

Adds support for the previously missing damage_reductions and item_damage fields in the BlocksAttacks data component, closing issue #12537.

  • Introduces PaperDamageReduction and PaperItemDamageFunction records with builders
  • Updates PaperBlocksAttacks (API + server) to include new getters and builder methods
  • Adds service loader bridge and package info for the new subpackage

Reviewed Changes

Copilot reviewed 10 out of 10 changed files in this pull request and generated 3 comments.

<details>
<summary>Show a summary per file</summary>

File Description
.../services/.../BlocksAttacksBridge Registers the implementation in the service loader
package-info.java Adds documentation and null annotations for the new package
PaperItemDamageFunction.java Implements ItemDamageFunction wrapper and its builder
PaperDamageReduction.java Implements DamageReduction wrapper and its builder ...
rustic folioBOT
rustic folioBOT
#

This seems like it would cause the event to get called every following tick when cancelled and prevent items past the despawn time from doing their normal tick logic due to the return.

As an alternative, we already have the item despawn time option in the spigot config and the alt item despawn rate option in the paper world config that you could use, they are better for items in this case

#

Yeah, in general this behavior is independent from the default item despawn behavior, which is what that event covers... so I am not sure if putting the event there is the best.

This logic is configurable for each server and sets a hard despawn for each entity, which I am not sure should be configured by plugins. Your plugin can listen to this removal by the EntityRemoveEvent and check for DESPAWN reason.

rustic folioBOT
#

Yea, also in favour of not using this (very much vanilla despawn behaviour) event for this purpose.
Paper's "despawn time" setting (while maybe inappropriately named) is not at all related to vanilla despawning (items have that alternative despawning behaviour to configure the vanilla values there).
It can very much be interpreted in the same vein of a plugin .remove()-ing the entity after a certain set of ticks.

I'll throw this at one more pair of eyes here tho :+1:

#
  • [ ] Rename world config's entity.spawning.despawn-time. The config should not imply that the removal follows all server despawn logic
  • [ ] Rework brigadier client tree building. Redirects make briagdier commands a graph instead of a tree. DFT is not a suitable algorithm for such data structures.
rustic folioBOT
rustic folioBOT
#

A very very large amount of plugins are never uploaded. So it isn't really a fair comparison. Furthermore, as Malfrador already said, Paper doesn't "just" remove methods. Those decisions are based on other factors he listed.

Do you have any specific issue with why you do not want to have deprecated methods in-code? Because I don't think there is any real issue with having them there as long as they do not add maintenance time.

most servers just download plugins from the internet, or will at most hire a dev to code something very specific and small, the reason i propose such a tool is because i think it will be useful on weighing the trade-off of supporting a tricky feature vs dropping support

rustic folioBOT
#

Pull Request Overview

This PR replaces the old Bukkit-based /version command with a new Brigadier-backed implementation, updates registration to use a namespace parameter, and deprecates the legacy API command.

  • Introduce PaperVersionCommand using Brigadier for both server and plugin version lookups
  • Change PaperCommands.registerInternalCommand to accept a namespace and register the new command
  • Deprecate the old VersionCommand and adjust VersionFetcher interface to a parameterless method

Reviewed Changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated 3 comments.

<details>
<summary>Show a summary per file</summary>

File Description
paper-server/src/main/java/io/papermc/paper/command/PaperVersionCommand.java New Brigadier-based /version command with plugin suggestions and async fetch
paper-server/src/main/java/io/papermc/paper/command/PaperCommands.java Updated registration API to ...
#

I just realized there actually is a real use case for having a method to check whether the server is configured for a proxy
I have a plugin which provides a lobby command only if the server is configured for a proxy
At the moment I use the deprecated config methods and having a method for that as well would solve that in a more fashionable way
What do you guys think? What about a generic "isProxyEnabled" method, not tied to bungee or velocity?

#

Yea I think recreating the instance is a fine alternative.
The current behaviour is gonna run into issues once we (finally) stop reusing the ServerPlayer instance and would need to be re-migrated.

Alternatively, the nms CombatTracker could hold its own API view (similar to Entity's getBukkitEntity) and we return that.
A single record creation there should really not be a big deal tho, no state is copied in the creation, all methods are stateless.

#

Yea I think recreating the instance is a fine alternative.
The current behaviour is gonna run into issues once we (finally) stop reusing the ServerPlayer instance and would need to be re-migrated.

Alternatively, the nms CombatTracker could hold its own API view (similar to Entity's getBukkitEntity) and we return that.
A single record creation there should really not be a big deal tho, no state is copied in the creation, all methods are stateless.

Then i can add the wrapper in the nms class like the bukkit entity and use that.

#

Expected behavior

Calling event.getDrops().clear() clears out the drops and making items not spawning in the world after death. Like how it is stated in the docs of the setKeepInventory() function.

Observed/Actual behavior

Utilizing event.getDrops().clear() does effectively nothing to prevent items spawning

Steps/models to reproduce

  • register handler for PlayerDeathEvent
  • do event.drops.clear()

Plugin and Datapack List

/

Paper version

1.21.4-230-ver/1.21.4@af71568

Other

No response

rustic folioBOT
rustic folioBOT
#

Checking using the block filter doesn't really work. As an example:

Location location = ...;
World world = location.getWorld();

// Hits collidable blocks & lava fluid blocks
world.rayTrace(builder -> builder
    .blockCollisionMode(BlockCollisionMode.COLLIDER)
    .fluidCollisionMode(FluidCollisionMode.LAVA)
    .targets(RayTraceTarget.BLOCK)
);

// Hits non-waterlogged collidable blocks & lava fluid blocks
world.rayTrace(builder -> builder
    .blockCollisionMode(BlockCollisionMode.COLLIDER)
    .blockFilter(block -> {
        FluidData data = world.getFluidData(block.getX(), block.getY(), block.getZ());
        Fluid fluid = data.getFluidType();

        return fluid == Fluid.EMPTY || fluid == Fluid.LAVA || fluid == Fluid.FLOWING_LAVA;
    })
    .targets(RayTraceTarget.BLOCK)
);

The block filter can't really be used to be distinguish hitting the block part of a waterlogged block, or the fluid part.

rustic folioBOT
#

Expected behavior

It should load

Observed/Actual behavior

https://cpaste.de/raw/kigoxubige

Steps/models to reproduce

  1. Put this player data file your server playerdata folder (it is just one of the player datas from our server causing the exception, it was loading fine in 1.21.4): https://webinterface.cubeside.de/temp/81bb948b-9723-47f9-b8db-f2a816e6d50b.dat
  2. Use the code in https://cpaste.de/raw/kigoxubige to load the player data
  3. Exception

Plugin and Datapack List

just a test plugin

Paper version

This server is running Paper version 1.21.5-87-main@fa360aa (2025-05-18T22:35:50Z) (Implementing API version 1.21.5-R0.1-SNAPSHOT)
You are running the latest version

Other

No response

rustic folioBOT
#

Expected behavior

The map should load

Observed/Actual behavior

Exception: https://cpaste.de/raw/daraxareya

Steps/models to reproduce

  1. Add this map to your server (the exception is happening with many maps on our server but not all): https://webinterface.cubeside.de/temp/map_5423.dat
  2. Use the code mentioned here to load the map: https://cpaste.de/raw/daraxareya
  3. Join the server
  4. Exception: https://cpaste.de/raw/daraxareya

Plugin and Datapack List

just a test plugin

Paper version

This server is running Paper version 1.21.5-87-main@fa360aa (2025-05-18T22:35:50Z) (Implementing API version 1.21.5-R0.1-SNAPSHOT)
You are running the latest version

Other

No response

#

Stack trace

[21:13:26 ERROR]: ------------------------------
[21:13:26 ERROR]: Server thread dump (Look for plugins here before reporting to Paper!):
[21:13:26 ERROR]: ------------------------------
[21:13:26 ERROR]: Current Thread: Server thread
[21:13:26 ERROR]:       PID: 64 | Suspended: false | Native: false | State: RUNNABLE
[21:13:26 ERROR]:       Stack:
[21:13:26 ERROR]:               java.base@21.0.7/java.util.Collections$UnmodifiableCollection.size(Collections.java:1065)
[21:13:26 ERROR]:               io.papermc.paper.adventure.PaperAdventure.lambda$static$0(PaperAdventure.java:110)
[21:13:26 ERROR]:               io.papermc.paper.adventure.PaperAdventure$$Lambda/0x000001cad2069290.accept(Unknown Source)
[21:13:26 ERROR]:               net.kyori.adventure.text.flattener.ComponentFlattenerImpl$BuilderImpl.lambda$complexMapper$2(ComponentFlattenerImpl.java:154)
[21:13:26 ERROR]:               net.kyori.adventure.text.flattener.ComponentFlattenerImpl$BuilderImpl$...
rustic folioBOT
#
[PaperMC/Paper] New branch created: fix/player-name-datafixer
rustic folioBOT
#

After investigating, there are a large amount of issues with Vanilla datafixers with old maps:

  • They incorrectly wrap the entire data in data (MapIdFix was incorrectly updated at one point)
  • They don't datafix dimension until 25w18a, so that is incorrect (25w05a caused this breaking change)
  • They don't define the map schema correctly in many places, assuming the data is present, or not.
  • We should be using optional codecs in our createUUIDBackedDimensionKeyCodec
rustic folioBOT
rustic folioBOT
#

Welcome to paper 👋 Thank you for the PR!

The linked issue and this PR are a bit of a head-scratcher for me given how stupidly hot this event could be, quite possibly the hottest event in the server in some scenarios given it is called n^2 times for non stacking item clusters. There are mitigating factors, e.g. stationary items only checking for merges every 40 ticks instead of every 2 and obviously the merge radios being relatively small, e.g. only .5, which at least would make it rare for this event to become incredibly spammy.

As you pointed out however, the event also fails in a couple areas which might prove pretty counter-intuitive, e.g. max size or unstackable. I am unsure if the better alternative to such an event wouldn't be the respective plugins that want to force such behaviour to implement their own merging checks on a tick-based iteration through item entities they know to require such checks. It would a) allow such plugins full control over m...

rustic folioBOT
#

Expected behavior

if I jump of the edge of a block the PlayerJumpEvent should fire, because I jumped.

Observed/Actual behavior

PlayerJumpEvent does not fire if jumping of block edge.

Steps/models to reproduce

Cancel a the PlayerJumpEvent and jump of block edge. -> does not fire -> able to jump

Plugin and Datapack List

My Plugin (only cancels the event)

Paper version

[14:34:39 INFO]: Checking version, please wait...
[14:34:39 INFO]: This server is running Paper version 1.21.5-87-main@fa360aa (2025-05-18T22:35:50Z) (Implementing API version 1.21.5-R0.1-SNAPSHOT)
You are running the latest version
Previous version: 1.21.4-230-af71568 (MC: 1.21.4)

Other

No response

rustic folioBOT
#

I'm not sure if the note about endermen taking damage if the event is cancelled was ever really true, in the original commit (b4ece16) there's nothing really indicating it.
I played around a bit with adding a damage call upon a cancelled event and got some varied results, while they do do damage, arrows just bounce off and tridents go straight through, this is because of both of them are hardcoded to not run any of their damage follow-up code if the hit entity is an enderman.

it did do damage in old versions, at least 1.12.2

1.12.2 sounds a littlle old... maybe the vanilla behaviour change with the time.. currently the NMS code not show any for make damage for projectiles and in vanilla how the logic is "escape" then never run the damage... the only way currently its just cancel the event and make the damage to the entity.

Maybe the docs for the event need a few more details about the ...

rustic folioBOT
rustic folioBOT
rustic folioBOT
rustic folioBOT
#
[PaperMC/Paper] New branch created: build/pw2b17
rustic folioBOT
#
[PaperMC/Paper] branch deleted: build/pw2b17
rustic folioBOT
#

Sorry for the long inactivity on my side.

After further investigation, I believe the issue is related to PaperMC’s authlib. I frequently see JSON errors in the console when trying to load player skulls. For example, when using SkinRestorer (without any other plugins) and running /skin update, I get this error quite often:

[10:15:20 WARN]: Couldn't look up profile properties for f8fbbfbd-fd9e-478b-ae03-a76243f948af
com.mojang.authlib.exceptions.MinecraftClientException: Failed to read from https://sessionserver.mojang.com/session/minecraft/profile/f8fbbfbdfd9e478bae03a76243f948af?unsigned=false due to Read timed out
...
Caused by: java.net.SocketTimeoutException: Read timed out

Right now, on my test server, I don’t see this error anymore when giving myself heads, but the skulls still don’t load properly. As I mentioned before, the issue is inconsistent: it happens on some servers (like my local setups and my friends’ servers), but on some other public servers it works fi...

rustic folioBOT
rustic folioBOT
#

After some more thought, this can literally be implemented via

@EventHandler
public void on(final PlayerDropItemEvent event) {
    if (event.getPlayer().isDead()) event.setCancelled(true);
}

Passing the "was keep inventory" around is also simple on a plugin perspective with the death event being called prior to the dropping.

In the name of not polluting our configuration with things plugins could be implementing, I'll be closing the PR. Thank you so much for it anyway, as per usual, really well crafted and documented <3

I tested this listener and it does indeed work (kind of), which is very unexpected, since the placeItemBackInInventory() method isn't being called when player.drop() is called, but it seems that bukkit has functionality to rollback the item drop when PlayerDropItemEvent is cancelled.

That being said, it only works when the death is keep-inventory, if it is not, then the item gets returned to the inventory after...

#

Is your feature request related to a problem?

Currently, PaperMC doesn't support the game test framework. This would allow plugins to have unit-tests to make sure certain behaviors work.

I'll make a quick example, imagine you're working on a plugin that gives mobs levels when they spawn in, so they can be procedurally more challenge. You could then create a game test that spawns a zombie (or some other mob), gives it a level, lets the plugin give it equipment, then check it's equipment.

Describe the solution you'd like.

I think PaperMC should provide API support for the GameTest framework in Minecraft. I don't think it has to mirror the internals exactly, but some sense of compatibility would be nice.

During bootstrapping, you should be able to define:

  • Test environments
  • Test instances
  • Code function tests

Test environments & test instances should probably be exposed through PaperMC's registry system & event lifecycle systems. Code function tests could be registere...

rustic folioBOT
#

somehow removing the following patches fixes minecarts...

diff --git a/paper-server/patches/features/0015-Moonrise-optimisation-patches.patch b/paper-server/patches/features/0015-Moonrise-optimisation-patches.patch
index 49514101c..398157e0b 100644
--- a/paper-server/patches/features/0015-Moonrise-optimisation-patches.patch
+++ b/paper-server/patches/features/0015-Moonrise-optimisation-patches.patch
@@ -26801,22 +26801,6 @@ index c50a1a01d167696134bd65b2d28db323d81d6ebd..5d63bf024cbcbd2f627c64fee77553c9
          }
      }
  }
-diff --git a/net/minecraft/server/level/ServerEntity.java b/net/minecraft/server/level/ServerEntity.java
-index 69fbcd734c269bbc9858b0ad0b3b268ddb81fcc6..a1ae77b70f69852d9e4332bf1cb3409c33b21de0 100644
---- a/net/minecraft/server/level/ServerEntity.java
-+++ b/net/minecraft/server/level/ServerEntity.java
-@@ -104,6 +104,11 @@ public class ServerEntity {
-     }
- 
-     public void sendChanges() {
-+        // Paper start - optimise collisions
-+   ...
rustic folioBOT