Well, those are plugins.
Make sure you are trying this without any plugins or client mods.
#paper
1 messages ยท Page 20 of 1
Resolves #11395
Introduced a RotationResolver to handle rotation arguments and added related methods to ArgumentTypes, and argument provider classes. This enables resolving and processing rotation data using CommandSourceStack.
The Vector2f in RotationArgument was just a temp solution because I wasn't sure on whether to add a rotation object that clearly combines a yaw and pitch
Well, those are plugins. Make sure you are trying this without any plugins or client mods.
I don't have any plugins except viaversion and viabackwards, without them I simply can't log in to the server. And I don't have any modifications.
I know for a fact that a client mod causes this since I had the same problem a few weeks ago
it got resolved after updating my mods
I can't tell you which mod exactly caused it, but I assume it was either Meteor or ViaFabricPlus.
f261baa Add skipTripwireHookPlacementValidation - Owen1212055
[PaperMC/Paper] New branch created: feat/tripwire-dupe-option
This allows for the configuration of tripwire hook duping.
Tested with https://www.youtube.com/watch?v=sRYuZn4r9RY
With this option disabled, both tripwires are broken.
With this option enabled, only one tripwire "breaks", but 2 items are dropped... (so it dupes)
unsupported-settings:
skip-tripwire-hook-placement-validation: true
[PaperMC/Paper] New comment on issue: #12083 Server GUI partially freezing when using 'help' command
Oddly enough I have not been able to reproduce this today, even though it had 100% reproduction rate yesterday. It may have been something that was resolved by rebooting.
I tried to replicate the same environment as yesterday, eg. running from battery (GUI used weaker GPU then).
java -version output:
openjdk version "21.0.3" 2024-04-16 LTS
OpenJDK Runtime Environment Temurin-21.0.3+9 (build 21.0.3+9-LTS)
OpenJDK 64-Bit Server VM Temurin-21.0.3+9 (build 21.0.3+9-LTS, mixed mode, sharing)
Windows 11 24H2 (build 26100.3037)
iGPU_0: AMD Radeon(TM) Graphics provided by AMD Ryzen 5 4600H
iGPU_1: NVIDIA GeForce GTX 1650 (Laptop one)
Move EntityUtil to paper-server's main source path, which prevents the IDE error about the package name having an inconsistent file directory.
Before
After
Shouldn't this be kept in the feature patch, but just fix the location?
No, the only parts of moonrise in the feature patch are basically the hooks into mojang code, etc; the majority of it lives outside of there already
Move the change into the patch
nevermind keep it as is
Is your feature request related to a problem?
Hello ๐๐ป currently there is no way to know if a teleport failed due to a player having passengers. Which means if any plugin uses player.teleport() the teleport fails. This is a huge problem as it prevents compatibility between plugins.
Describe the solution you'd like.
I would like to see a PlayerTeleportFailedEvent added to paper. This means that when a teleport fails we could handle the passengers correctly and then re-teleport the player to enable the functionality again.
Describe alternatives you've considered.
I have tried the PlayerCommandPreprocessEvent to listen in on commands that teleport the player although this is limited as it means every single command needs to be manually added and there is no way to detect plugins that use it in other cases.
Other
I did find that there was a pull request for this exact feature #10173 and even though it had a lot of engagement it was never added ๐
This is basically a duplicate of; https://github.com/PaperMC/Paper/issues/10168
The concern is that a failed event doesn't allow people to correct the event outside of re-teleporting, which breaks the whole causation aspect; so, a failed event is pretty meh as an overall solution here
This is basically a duplicate of; #10168
The concern is that a failed event doesn't allow people to correct the event outside of re-teleporting, which breaks the whole causation aspect; so, a failed event is pretty meh as an overall solution here
I am a little bit unsure of what you mean in the second part. I am not sure there is any other way currently than detecting the fail, removing the passengers and then re-teleporting.
The goal would be to allow plugins to intercept before that and determine to set flags or correct the issue beforehand
The goal would be to allow plugins to intercept before that and determine to set flags or correct the issue beforehand
Oh I see sorry, basically the same outcome just a different way of doing it. I could have a go at a PR. I was thinking maybe detecting if the player has a passenger or is in a vehicle and then firing an event before the teleport so it can be handled before the player is teleported. Would that be a better approach? ๐
There was some discussion about this here on discord:
#paper-contrib message
Generally it seems like the consensus was to simply align with vanilla here, by allowing teleports with passengers by default. Its weird that Paper/Craftbukkit deviate from vanilla here.
Then such an event would no longer be needed, and a plugin actually wanting to do the opposite and prevent teleports with passengers could cancel the already existing teleport event.
Two small comments but otherwise all looks good to me
This new import is not used in the file
If opening noises should be prevented (as is done with chest using useFakeBlockEntity), then perhaps that could be done here too with the shulker.
- methods for activate/deactivate the creaking
- methods for home of creaking
Ported from my PR in Spigot ref: Bukkit Commit
CraftBukkit Commit
"aka where can be a heart" is grammatically... funky. Perhaps "where its {heart} could be found"
Also, phrasing feels off here too.
Javadocs have some phrasing issues, and some extra periods (they don't belong with @param or @return statements).
Also, curious about the home world requirement.
Needs a @throws for the different world part, if that's actually how it must go.
When make the PR in spigot just avoid test if try set a home in another world cause issues with behaviour... maybe can test if really cause issues...
Draft because need test if call the correct things...
maybe can specify the behaviour better here...
Yeah The whole shulker thing is a bit more nuanced due to the need for it to be distinctly different than a chest with GENERIC_9x3. In the interest of trying to keep this PR focused on adding default titles, this will need to be addressed in a PR where I rewrite the opening logic that Bukkit does. Long story short getNotchInventoryType isn't actually smart enough to identify the difference between a shulker box and GENERIC_9x3 as they'd be created with this API. The way around this is to define and force the use of the BlockEntity for now* The chest is okay to avoid this because it is a GENERIC_9x3.
So, I tested it on a clean client with no mods. I checked on the server version of Paper 1.21.4 and on my own 1.20.4 Optifine and the problem is the same
Did you test it on a client client, or did you test it on 1.20.4 optifine? Big difference between those two, and the latter would also indiciate you're still not testing this without plugins.
Add nullable + note that a creaking might not have a home pos in the return tag
This seems like it would fail inside the toBukkit method if getHomePos returns null
should be following and attacking here in the jd, instead of follow and attack.
Expected behavior
getAttachedBlock() method should return the block the arrow is attached to
Observed/Actual behavior
the getAttachedBlock() method always returns air if the arrow is attached to a solid block
Steps/models to reproduce
- shoot an arrow into a solid wall
- run arrow.getAttachedBlock() after it hits the wall
- wrong block
but if you shoot a non-solid block it is fine
Plugin and Datapack List
Server Plugins (5):
Bukkit Plugins: packetevents, Skript, skript-reflect, ViaBackwards, ViaVersion
There are 3 data pack(s) enabled: [vanilla (built-in)], [file/bukkit (world)], [paper (built-in)]
There are no more data packs available
Paper version
This server is running Paper version 1.21.4-144-main@edacfdf (2025-02-09T10:56:49Z) (Implementing API version 1.21.4-R0.1-SNAPSHOT)
You are running the latest version
Other
No response
The deactivate javadoc does still read a bit weird, but can't think of much else
I think a new rotation wrapper class would be good for this, but will want see what others think first.
Marks this entity as deactivated and clears the attack target?
Not sure I like my own wording,
/**
* Deactivates the entity, clearing its current attack target and
* marking it as inactive.
*/
Here is ChatGPT
cafef9c [ci skip] Move EntityUtil to correct directory ... - Dreeam-qwq
Would using @apiNote make sense for this?
Probably more @implNote? ๐คท
@implNote is more of a note for API implementors rather than API users, that's what @apiNote is for, (besides we don't handle @implNote tag)
Kinda unrelated to this PR but, Is there still a reason to only read this if the entity is a living entity?
In the despawn time check inside Entity#tick, totalEntityAge should also be used instead if we don't want unloading to affect their configured despawn time.
Should be just ItemTypeChoice
Since the impl is in the same package it could be possible to make this sealed.
Entity despawn now uses the totalEntityAge
apiNote sounds reasonable
Other methods in the class are already using Note so would it be smart to update those docs in a separate PR as well or just leave them be?
I don't think we wanna do general cleanup prs yet, so just leave them be for now.
Alright, so apiNote it is?
[PaperMC/Paper] New comment on issue: #12083 Server GUI partially freezing when using 'help' command
mmmh, strange. I suggest we blame windows (or well, its desktop manager) and move on. if this comes up again, try restarting explorer.exe and see if that fixes it, but I doubt we can do aynthing from papers side here, so ill close this
Kinda unrelated to this PR but, is there still a reason to only read this if the entity is a living entity?
Spigot api resets tickCount for non-living entities, so leaving it here just for api behavior is same as spigot.
The only way this seems to be fixable is by checking for entities in the players line of sight as there doesn't seem to be a reliable way to distinguish an actual UseItemPacket from one that is falsely sent by the client in this case
cannot reproduce this with the information you provided on the latest build. Might have been fixed on accident while mojang was making changes to bundles.
It might be worth documenting here that this event is also called upon entities being added to worlds, since it isn't immediately obvious to users of the event that the game counts that as "changed".
The naming and approach of this PR seems good to me
I have this problem too... https://imgur.com/a/lJnDuEx
Added some examples of situations that can call the event.
The case of foxes harvesting a sweet berry bush is currently missing, can be added in the FoxEatBerriesGoal#pickSweetBerries method
It could be noted here and in the player event that this list is mutable.
some grammar in the jd needs to be fixed
Not sure why we need to min this? i think we should also increase the spawn range when we increase the max Distance.
yeah not sure how handle this... the idea its just avoid if i set the too far distance to 2, the block not turns into a "spawn creaking, its far, break, try again, its far, try again" any suggest?
Expected behavior
Redstone dust should work at any height
Observed/Actual behavior
Redstone dust does not function at Y 319 when the redstone-implementation is set to ALTERNATE_CURRENT.
Steps/models to reproduce
Steps to reproduce:
-
Set the redstone-implementation to ALTERNATE_CURRENT in paper-world-defaults.yml
-
Place redstone dust at Y 319 (max build height)
-
Power the redstone
Plugin and Datapack List
No plugins, no datapacks
Paper version
ver
[23:39:39 INFO]: This server is running Paper version 1.21.4-144-main@edacfdf (2025-02-09T10:56:49Z) (Implementing API version 1.21.4-R0.1-SNAPSHOT)
You are running the latest version
Other
No response
IJ try to make me use this like 4 times.. and forget that last xd fixed...
I'd guess the question here is, can this be reproduced in the AC mod?
Well that isnโt going to be a problem is we scale the spawn range according to the maxDistance. So i think the best thing to do is either add extra api for the spawn range (though i think thats a bit excessive) or change the spawn range by the same factor as maxDistance was changed. but the current behaivour for this is sort of weird
Yes, this can be reproduced in the AC mod.
I would file the issue there, we generally aim to keep our AC implementation as a 1:1 with theirs
yeah still a little lost in this... unless just restrict the distance for not being low than the range... but dont like that... then not sure how best can modify here.
I was thinking about something along the lines of this:
+ EntityType.CREAKING, EntitySpawnReason.SPAWNER, level, blockPos, 5, creakingHeart.getDistanceCreakingTooFar() / creakingHeart.DISTANCE_CREAKING_TOO_FAR * SPAWN_RANGE_XZ, creakingHeart.getDistanceCreakingTooFar() / creakingHeart.DISTANCE_CREAKING_TOO_FARcreakingHeart.DISTANCE_CREAKING_TOO_FAR *SPAWN_RANGE_Y, SpawnUtil.Strategy.ON_TOP_OF_COLLIDER_NO_LEAVES, true // Paper - handle too far distance for avoid spawn out of limits
fa5824e Add skipTripwireHookPlacementValidation (#12091) - Owen1212055
[PaperMC/Paper] branch deleted: feat/tripwire-dupe-option
3bd69f2 [ci skip] Enhance javadoc for World#setAutoSave... - NonSwag
I'd also be in favour of a rotation type, mostly because we can add some utils on there to e.g. convert to a direction vector.
x and y are also just terrible names so, another good reason for a quick interface + package private record impl.
Use the constants in Tag
You should also handle unplaced block state properly
I am a bit confused regarding the usage of this method.
Simulating the spawning behaviour of an entity type is something that might be useful API, but I don't think I'd want it to live in random block state types like this.
Developers can very well just spawn a creeking and set it via the setter.
The spawnProtector method really doesn't do more than spawning it + game events.
A bit rough here if we wanna write.
We should keep the int but we'd ideal also want a way for the developer to fall back to vanillas value even if it changes across versions.
The current implementation would lock every creaking heart at the current vanilla value.
I'd be in favour of potentially adding extra API to increase the spawn radius down the line, for now I am unsure if we need this? The most important usecase I see for this is reducing the range.
I am fine with the min here to avoid the look of spawning one outside the rage and have it die immediately.
Scaling it is a nice idea, but I think I'd prefer extra API.
Use Tag.TAG_ANY_NUMERIC instead of 99.
Anything against sticking to the vanilla naming here? E.g. getProtector?
Other peoples input here before actually changing this tho.
I do not like this method name.
Especially when we also might add API for the creaking spawn distance.
getProtectorSurvivalRange
setProtectorSurvivalRange
getProtectorSpawnRange
setProtectorSpawnRange
might work, more peoples input tho pls.
oh.. then what is better?
- the last change for the scaling (broken need fix that)
- the min thing and in another PR implement a proper api for that
* Activates this creaking to target and follow a player.
* Deactivates the creaking, clearing its current attack target and
* Returns if this creaking is currently active and hunting.
*
* @see #activate(Player)
Ah, I personally am not much of a fan of scaling it, I think I'd just add the API for it.
Preconditions to verify that spawn <= survival range and survival range >= spawn range etc.
Scaling seems nice for auto vanilla-like feeling to the API but I think API just offers more specific control and doesn't "magically" change values.
ok that logic currently just return 0 if try to set the distance in 2...
hmmm yeah.. i fell useful just call the same NMS logic but maybe can just remove that and let users use the normal ways.
the lasts ones not like just becauuse that value its not for spawn.. its for limit the max distance where a creaking can "live"
maybe the first can work.. but not sure..
The last ones were for the new API regarding the replacement for scaling, sorry xD
But yea, more people time chime in.
Maybe just a
if (this.distanceCreakingTooFar != DISTANCE_CREAKING_TOO_FAR) tag.putInt(PAPER_CREAKING_MAX_DISTANCE_TAG, this.distanceCreakingTooFar); // Paper - Custom max distance for Creaking ?
okay i base in the beacon class (then that class need use tha Tag class too) but fixed here.
The case of foxes harvesting a sweet berry bush is currently missing, can be added in the FoxEatBerriesGoal#pickSweetBerries method
ready i try to handle the whole logic where the "first" item its used for the mount of the fox and the rest for drop.
I have this problem too... https://imgur.com/a/lJnDuEx
delete the chunk with mca selector
Closes #11677
As a fix for custom maps not being able to affect the dirtyDecorations field here, CB seems to have simply ignored this field entirely for all maps.
This fix restores vanilla behavior while still allowing custom maps to be updated, reducing the amount of map data packets that get sent for vanilla maps.
... we can add some utils on there to e.g. convert to a direction vector.
My math skills are too... non-existent... to do something like that
as far as I know a vector consists out of 3 components_?_
Just ignore for now, we don't need to add utils yet.
Was just an argument for using a proper type instead of reusing joml's Vector2F
The only way this seems to be fixable is by checking for entities in the players line of sight as there doesn't seem to be a reliable way to distinguish an actual UseItemPacket from one that is falsely sent by the client in this case
I am fine with this solution, I mean line of sight checks are already used in player interact event for arm swing packets IIRC
Hello! I encountered the exact same issue on my 1.21.3 Paper server. After some observations, I upgraded to 1.21.4 (most recent build), though it didn't fix the issue either.
After some trials & errors with my plugins, I discovered it was caused by HeadsPluginAPI. I'm not sure how it causes it, but on my side it was what caused those errors.
I'm guessing it is due to some incompatibility between some plugins and Paper๐
AbstractArrows don't just have one block they are attached to. i definitely think we should expose all the blocks to the api. whether or not the existing method should be deprecated is up for debate though the current jd for it is misleading as it makes the user think there might only be one block keeping the arrow from falling
The only real concern I see would be getAttachedBlock not returning the block plugins are expecting in relation to the hit event. I would ponder deprecating the old method just for the "you should probably consider them all, or default to the first if that fits your needs"
leftover unused import here
There should be some way to obtain an instance of this if we want it to be useful outside of commands, RotationImpl can be moved into the math package in api and a static method can be added in this class, the same is currently done in Position for example.
Future api, but may be nice to have a method to get all the blocks in a provided bounding box in a world.
Added has methods for the methods that used to return a set and changed them to return a collection instead
Expected behavior
The header documentation on https://jd.papermc.io/paper/1.21.4/io/papermc/paper/tag/PreFlattenTagRegistrar.html gives example code for creating a new tag but does not include the definition of the tag itself, just how to give it a value. The original PR included this bit of code which is missing:
public static final TagKey<ItemType> AXE_PICKAXE = TagKey.create(RegistryKey.ITEM, Key.key("test", "axe_pickaxe"));
Observed/Actual behavior
Non-functional example due to missing variable definition.
Steps/models to reproduce
Look at the documentation, try to use the example to make your own tag.
Plugin and Datapack List
N/A
Paper version
N/A
Other
No response
Primarily fixes two typos I noticed while browsing the javadoc.
If such basic PRs are not wanted, just close it.
This resolve #12100 adding the missing declaration used in the example..
The only real concern I see would be getAttachedBlock not returning the block plugins are expecting in relation to the hit event.
The Block that was hit in the hitevent is already Stored in a Variable (i think). could return that in the old method if it is still there
I would suggest something like editMeta does
A consumer in which you can edit the state of the world without modifying it directly and after you are done the changes are persisted
By doing so it could be possible to say whether block or light updates should happen and then resend the chunk
Discussion Category: Ideas
13c80a5 [ci skip] Fix PlayerShearBlockEvent javadoc typ... - aerulion
db2aa18 [ci skip] Fix incomplete example in javadocs fo... - Doc94
Missing unmodifiable annotation.
cf7c6c7 [ci skip] Fix incomplete example in javadocs fo... - Doc94
Complete nitpick, but if you wanna one-line this, just use Iterables.getFirst(getAttachedBlocks(), null).
Impl methods are still returning Set here.
I think getConnectedPlayers is fine to be a Set, the order there is completely irrelevant.
* Gets the home location for this creaking (where its {@link org.bukkit.block.CreakingHeart} could be found).
I also made Location implement Rotation
I am a fan of the add/removal methods on Location, not so much of the inheritance.
Location isn't a rotation, it has a rotation.
I also generally do not see a benefit in making Location implement it beyond the above issue I take with it.
Can you elaborate when it'd be useful to pass a Location to something that takes Rotation?
hmm... you are right
might have not been thought through very well
as long as there are no APIs that utilize rotation, there is no real point in making location implement rotation
I will revert that commit
Closes https://github.com/PaperMC/Paper/issues/8988
And fix some more issues:
- ARROW_PARTICLES should support Arrow and not the deprecated class
- EntityEvent#START_ATTACKING should support the Creaking
Whats the reasoning beyond marking other "renames" as forRemoval but this one isn't?
Why do the other eqipments get a see to their equipment slot but these two don't?
Please do not use wildcard imports.
They are generally considered not too stable and iirc even banned in like the google code style.
IJ sometimes does that, but you can iirc just incr the value of imports to like 99999.
Same here, forRemoval?
Closes https://github.com/PaperMC/Paper/issues/11673
And fix another NPE when trying to get the default value of an experimental gamerule.
Expected behavior
OfflinePlayer#getPlayer should return a valid Player instance at the moment it is called.
Observed/Actual behavior
OfflinePlayer#getPlayer created when the player was online and has since logged out and logged back in will return an outdated Player instance.
Steps/models to reproduce
Bukkit.getOfflinePlayerwhen the player is online.- Player logs out and logs back in.
OfflinePlayer#getPlayerand try something likePlayer#openInventory.
Plugin and Datapack List
None.
Paper version
1.21.4-147-main@3bd69f2
Other
I'll start off by saying that I am not sure if this is intentional or not, so if it is then apologies.
Because Bukkit.getOfflinePlayer returns the Player instance itself when the player is online and Player#getPlayer returns this it can be an unexpected behavior. This makes it so if you are expecting an OfflinePlayer but want to do something extra if they are online, like sending a message, but the...
Is your feature request related to a problem?
I don't know of any reason why you can't pass your Scoreboard implementation to player#setScoreboard
In fact, this artificial restriction creates big problems for developers
For example: I want to โmergeโ two Scoreboards (previous and new) using the previous one as a reference.
This is done when I want to leave the logic of another plugin and merge it with my own. People bypass this by making terrible implementations with ReflectionAPI, etc.
Example:
final class MergeScoreboard implements Scoreboard {
private final Scoreboard left;
private final Scoreboard right;
MergeScoreboard(final Scoreboard left, final Scoreboard right) {
this.left = left;
this.right = right;
}
@Override
public Team registerNewTeam(final String name) {
final Team l = this.left.registerNewTeam(name);
final Team r = this.right.registerNewTeam(name);
return new MergeTeam(l, r);
}
}
...
udp: I'll try to make this change in CraftBukkit first.
In fact, this artificial restriction creates big problems for developers
This is definitely not an artificial restriction, paper needs to get a nms scoreboard which would be passed in the game code, scoreboards aren't pure api concepts. Creating a custom nms implementation that delegates to your implementation is way too hard to maintain
udp: I'll try to make this change in CraftBukkit first.
Also, do not that CraftBukkit died in 2014. You will find only failure in that change attempt. We no longer update based on any upstream but Minecraft itself, so changes you wish to see in Paper would need to be proposed in Paper.
Generally I like the cleanup, passing the cause like this is a lot nicer.
The thing I am a bit confused on is the withers/setters in DamageSource now.
Some are withers, e.g. perform a copy, others actually mutate the instance.
It seems semi arbitrary, presumably this is fine like this as the setters are only called on instances copied prior, however that feels pretty much like we are asking for an explosion down the line given the inconsistent behaviour here.
The two setters, critial and customBlockState, are I think not in a hot enough code path where the one extra copy of a damage source (which involves 0 deep copying anyway) would be a problem.
Are there other reasons I missed as to why you decided to make them setters?
072a831 Add proper attached blocks API to AbstractArrow... - notTamion
1be2e5f Fix vanilla map decorations sending when not di... - Warriorrrr
Should be using Armadillo#SCARE_CHECK_INTERVAL
46f4fda Add support for rotation argument handling (#12... - NonSwag
This should probably be another interface + package private record impl combo.
We also should be defensively copying the stacks on access to prevent plugins from changing these accidentally.
Just move the "unmodifiable" wrapping into the getter instead.
It is cheap enough to do there and just ensures we don't accidentally move it later.
Should also note in the docs that the lists contained are also unmodifiable.
checkArgument instead.
its that? this thing its really hard to find because in a few tests the behaviour running is ArmadilloBallUp
Applied requested changes
In 1.14 spigot removed the implementation of this api, but this information is still not present in the javadocs. This also deprecates for removal the api, as with newer versions it's harder and harder to imagine this api coming back.
maybe change the message in the implementation too (and cleanup that comment code)? currently its like "if can fix..."
It was re-implemented for a while in 1.18.1 in this commit, don't remember in what version it was removed again though
Pretty recently iirc? We can deprecate for removal, the comment seems overkill.
It was re-implemented for a while in 1.18.1 in this commit, don't remember in what version it was removed again though
Yeah, seems like around 1.21/1.21.1, as 1.20.6 still had the api implemented
Is your feature request related to a problem?
Currently, it is not possible to use world presets outside the ones defined in the WorldType enum
It would be extremely helpful for creating worlds with custom generators and world height (or other values defined by a world preset)
For example: right now, it is not possible to modify the world height without affecting all other worlds or some very hacky java code
Describe the solution you'd like.
Expose the world presets by replacing the WorldType enum with an interface reflecting the registry content similar to how the Biome enum was replaced
Describe alternatives you've considered.
Other
No response
For example: right now, it is not possible to modify the world height without affecting all other worlds or some very hacky java code
You can easily override Minecraft stuff using datapacks. For height you just put this file https://github.com/InventivetalentDev/minecraft-assets/blob/58d92c8cee4c7ac22d02988fb2bc3e4648af9ef2/data/minecraft/dimension_type/overworld.json#L9 with modified height, which will override the height for the world
You can easily override Minecraft stuff using datapacks. For height you just put this file https://github.com/InventivetalentDev/minecraft-assets/blob/58d92c8cee4c7ac22d02988fb2bc3e4648af9ef2/data/minecraft/dimension_type/overworld.json#L9 with modified height, which will override the height for the world
This is exactly what I don't want to modify as this also affects all other normal worlds on the server which isn't optimal
Oh, so you want an addition to registry modification api to be able to register custom dimension types which could be used in world creation?
udp: I'll try to make this change in CraftBukkit first.
Also, do not that CraftBukkit died in 2014. You will find only failure in that change attempt. We no longer update based on any upstream but Minecraft itself, so changes you wish to see in Paper would need to be proposed in Paper.
Eh, I guess you're right, but my last CraftBukkit commit was merged into Paper, I thought you were updating. About the artificial limitation, perhaps I shouldn't have been so unsubstantiated, the problem turned out to be quite serious
kinda, I'm fine with it being read only for now but what I want is to be able to use all world presets which are present in the registry (i can add them myself with a datapack)
I'm specifically talking about world presets not dimension types as they are already present in the bukkit api in the form of the WorldType enum so it wouldn't require additional api just some small changes
I have some diff locally that does this, Iโll see about maybe opening a draft PR with it.
I'm specifically talking about world presets not dimension types
They're just small tweaks to the world generator, they don't control mentioned stuff like world height, that's on dimension types
I have some diff locally that does this, Iโll see about maybe opening a draft PR with it.
Nice if not I can also do it myself I just never worked with patches or the paper source code so I my code will likely be of lower quality
They're just small tweaks to the world generator, they don't control mentioned stuff like world height, that's on dimension types
yes but the server gets the dimension type from the world preset
so being able to control the world preset means being able to control the levelstem and controlling the dimension type and generator settings
I did some digging and you seem to actually mean Spigot's zombie corpse of CraftBukkit they inexplicably keep around. We no longer follow that.
fixes #11678
one side effect is that if the player continues to hold down his right mouse button it will continue to try and use the bow which might result in further cancellations etc. though i think that is better than having the player be confused about why their arrow just suddenly disappeared
make this a default method than we can yoink the entire method implementation
Marked ItemStack parameter as @Nullable to explicitly indicate it can be null. This improves clarity, avoids nullability problems, and aligns with the method's documented behavior for handling null values.
Was semi wanted because I wanted to move people to ItemStack.empty(), nullable stacks are something that'll slowly be yanked, but yea. Fair enough, I should do that in a proper follow up PR down the line.
6cfa2f7 [ci skip] Add missing nullability annotation to... - NonSwag
Haven't tested but just a thought to make sure. considering in the vanilla logic we would popresource i times that would produce multiple items on the ground that are not immediately bundled together right? though since we just creating one itemstack with i amount here those would all immediately be bundled together when they get spawned. not sure but just going to leave it here so we don't overlook it
i would maybe add that for foxes the first item will be used for its mouth
no need to clone the list here since we aren't modifying it later.
entityHarvestBlockEvent.callEvent();
can also remove this call as we call it later anyway
yeah or just normally in the comment. both is fine with me
It appears paper has now added HopperInventorySearchEvent, however InventoryMoveItemEvent is still "broken". Now that I thought about it some more I think, it would be way more efficient if "protection" plugins just used HopperInventorySearchEvent, set target inventory to null and set cooldown, instead of doing processing in IMIE where stacks are already being processed.
And if plugins move from IMIE to HopperInventorySearchEvent, IMIE functionality could be restored so that IMIE is fired for every slot and that could be extended even further so that item taken from source inventory is actually item passed over by getItem from IMIE.
I've only added support for changing item amount (for even better implementation IMIE and its extended Paper's IMIE should check if not only getItem but also setItem was called and adjust items accordingly), just the change that restores full IMIE functionally and allows plugins to change amount of moved item would look like this:
 or set your own.
I think we'd benefit from potential passing the "result" as well? Also this is very much like, PlayerAttemptSmashAttackEvent (what a name). But just attack event might make it sound like this is the actual attack instead of just an event to control the check.
PlayerAttemptSmashAttackEvent does describe the event better. What do you mean with "passing the "result" as well"?
Well, it would be nice for plugins to know if the player can actually perform such an attack via the event.
So, instead of computing the value after and using the Result type, we could instead just fire the event pre-cancelled in case players do not meet the requirements.
Oh I see, yeah that makes sense. I would still run the event always when the player attempts a smash attack and add a boolean field canSmashAttack, that tells if the player is allowed to perform a smash attack before any modifications, because the event can still be used to to something if there has been a successful smash attack.
maybe i bad read this but the logic is the same than vanilla, the event is called with only one item and is used for pop, if you add more items then pop for every element.. the only thing is if you make a thing like "add potato", "add potato" and that are different items added in the list... but still respect the original thing.
Expected behavior
I tried to reproduce the tripwire hook duplication glitch as in the attached video. In vanilla, the bug still works, but with the latest version of PaperMC that I've attached to this request, it no longer does.
I've enabled the option in the configuration and reloaded the server:
skip-tripwire-hook-placement-validation: true
Observed/Actual behavior
Despite this, the duplication doesn't work. For everyone on the server, in version 1.21.4-150-main@46f4fda 1.21.4-R0.1-SNAPSHOT, the bug doesn't work either.
Can you confirm whether a fix has been applied to this version, or whether there's some other action to be taken?
Thank you in advance for your feedback.
Steps/models to reproduce
https://www.youtube.com/watch?v=syjbP8r8qx8
Plugin and Datapack List
0 Plugins
Paper version
1.21.4-150-main@46f4fda 1.21.4-R0.1-SNAPSHOT
Other
No response
This is known.
Pick another farm that does not rely on the same-tick door update to break the thing for a temporary "fix".
It is caused by another fix to the block physics API. Obviously not ideal, but fixing that bug is even more difficult and, if a dupe is the only thing broken by it, just not at the top of the priority list.
Someone may care to investigate but, this option is in unsupported for a reason.
Yea kinda. You'd basically mark the event as "cancelled" by setting event.setCancelled(!canSmashAttack(player)) before calling it.
That way, plugins can "override" vanillas behaviour by setting cancelled back tofalse.
I think CraftPlayer returning a player from craft server would be an okay "fix", maintaining a new implementation definitely doesn't seem worth it.
But yeah plugins should be using uuids instead. I found this issue on a plugin because of a completely different problem where attempting to open an inventory on an outdated player instance overrides the inventory holder if they had another inventory opened at the time and now could take items from said inventory.
9b9de82 Update Alternate Current patch to v1.9.1 (#12115) - SpaceWalkerRS
I don't think we can do that? That way Player#getPlayer would return the "updated" player too, which seems wrong.
The entire idea of keeping the OfflinePlayer of an online player around is just so wrong, I don't think we'd wanna encourage it by fixing things for that exact usecase.
I think this might just be on plugins to fix sadly.
Thank you for the report anyway, sorry if the resolution isn't what you were hoping for!
Adds a guard in to catch null list entries, will need info about what paper comments are needed
Can just be Preconditions.checkArgument(lore.get(i) != null, ".....")
Hi, thanks for the changes. Right now tho, every attack is a smash attack because it is just passing the vanilla canSmash value to the event.
Just remove that boolean from the event again, as I said above, you'd just event.setCancelled(vanillaSmashFlagHere) before calling.
My idea was that the information about the vanilla behviour persists, even when other plugins "uncancel" the event.
The event is set to cancelled depending on canSmashAttack in the event constructor.
Fair point, that sounds smart!
Can you still (just for my sanity) move the cancelled setter to the callside instead of the constructor.
That is how all the other "pre-canclled" cases look, avoids surprises down the road.
The goal of this Pull Request is to add a basic level of support for Point of Interest in the API. This more used within entity AI, however, there can be exposed a useful detect Point of interests in the world. I want to flesh this out if possible, however I also want testing to be done on the current API to make sure it works as intended.
record maybe?
Sound easier. Also nullmarked.
Radius should probably be non-negative and enforced via precondition.
Use InternalAPIBridge, that is generally the place we throw stuff like this now.
This is standard to null mark implementations, so I know going forward?
Stack trace
Caused by: java.util.NoSuchElementException: No value present
at java.base/java.util.Optional.orElseThrow(Optional.java:377) ~[?:?]
at io.papermc.paper.util.ItemComponentSanitizer.dummyEnchantments(ItemComponentSanitizer.java:59) ~[paper-1.21.4.jar:1.21.4-151-9b9de82]
at io.papermc.paper.util.ItemComponentSanitizer.lambda$static$0(ItemComponentSanitizer.java:30) ~[paper-1.21.4.jar:1.21.4-151-9b9de82]
at net.minecraft.Util.make(Util.java:596) ~[paper-1.21.4.jar:1.21.4-151-9b9de82]
at io.papermc.paper.util.ItemComponentSanitizer.<clinit>(ItemComponentSanitizer.java:28) ~[paper-1.21.4.jar:1.21.4-151-9b9de82]
Plugin and Datapack List
Disabled the vanilla datapack & removed all enchantments from mine
Actions to reproduce (if known)
- Disable the vanilla datapack
- Add a new datapack that contains the things vanilla requires (tags, some worldgen etc), but crucially no enchantments...
Can we get away with just creating our own (non-registered) enchantment instead? I'd imagine the client doesn't need to know the enchantment 'exists'?
The client needs to know about it, otherwise it eats dirt last I knew
The solution is to disable this obfuscator if such a state is introduced.
Because you can't have any enchantments anyways.
Lets you create custom dimension types and levelstems. This hooks into the vanilla way of creating new dimensions by modifing the levelstem registry.
This can easily be used to just break worlds as you can modify existing worlds, like change the overworld to use the nether-like chunk generator and the overworld will just switch.
Resolves https://github.com/PaperMC/Paper/issues/12110
I like the pattern I added here for copyGeneratorFrom since I don't want to add all needed API to create instances of chunk generators, so this just allows you to copy it from elsewhere. We can use this in future registry API when we don't want to go all the way.
It's also the case for DatapackRegistrar, it doesn't compile currently (cause BoostrapContext is not valid)
4041678 [ci-skip] Mention missing World#regenerateChunk... - masmc05
The javadocs in the PersistentDataViewHolder interface which this method is from already seems good to me, it states that it's only capable of viewing tags, not modifying them.
We should open a docs PR to include the changes on the PDC page (thanks Lulu)
Thank you for your work on this PR, though we've instead decided to go with #11954 as that PR would fix the whole underlying problem behind the issue being fixed here.
This PR just add the missing annotation for nullable in bukkitEntity.
It's also the case for DatapackRegistrar, it doesn't compile currently (cause BoostrapContext is not valid)
dont compile? this?
This PR handle a TODO for add a description in the /plugins command with the hangar mention and also a URL to current docs for plugins.
This PR based in https://github.com/PaperMC/Paper/pull/12103#issuecomment-2661093797 just mention how this example assume you add the directory need... if you just copy and run this throw a NPE for the Objects.requireNonNull
The todo on line 39 can be removed
I have this problem too... https://imgur.com/a/lJnDuEx
delete the chunk with mca selector
Even when I removed it, after a few days more appeared... It's like a spinning wheel, you delete one corrupted one, another one appears
The space removed? Or that show the ide when edit
I don't see why this diff is a problem. He is just removing the space. It's not in a patch anymore so I think it's fine?
it's extra diff, but, shouldn't really be an issue here; it would be more of a concern if this was touching some area we're expecting 20 PRs for
Expected behavior
Cancelling the events causes the arrow(s) to not be consumed
Observed/Actual behavior
The arrows are consumed anyways
Steps/models to reproduce
Cancel EntityShootBowEvents or ProjectileLaunchEvents and fire a bow or crossbow and observe your arrow stack count/the crossbow unloading without firing an arrow.
Plugin and Datapack List
only testing plugin
Paper version
1.21.4#152
Other
This happens because the arrow is already removed from the inventory/crossbow before the events are even called
Seems to have been fixed at some point.
fixes #12123
draft pr for now. need to come back to this
Makes it more clear that chunks loaded with this method will have a higher priority over other chunk loads, adds javadocs to a default method that didn't have them before
With the current changes the /plugins command looks like.
Persona... dont like this but its like the same than move to MiniMessage and apply a tag finally...
just chunk x coordinate should be enough.
chunk x and loc x is already confusing enough, I don't think we can explain that in a single line nicely without making it even more confusing.
Is your feature request related to a problem?
I am developing a fishing plugin and would like to implement fishing in lava.
However, the TagKey<Fluid> referenced by the NMS FishingHook class is hardcoded. To allow fishing in lava, I would have to completely reimplement the vanilla water fishing mechanics from scratch. This would require significant effort and could negatively impact server performance.
Describe the solution you'd like.
- Add a TagKey<Fluid> field to the
FishingHookclass and set its default value toFluidTags.WATER. - Modify references to
FluidTags.WATERwithin theFishingHookclass to use the newly added field instead. - Add two methods to the Bukkit
FishHookclass:TagKey<Fluid> getBobbingFluids()void setBobbingFluids(TagKey<Fluid> fluids)
- Implement these methods in CraftFishHook. (Would parsing with PaperRegistries.toNms be the appropriate implementation?)
I considered adding this as a World Configuration option, but sinc...
Expected behavior
disable-tripwire-updates should cancel all tripwire block state updates completely
Observed/Actual behavior
The option correctly cancels updates related to other tripwire blocks placed nearby and entities stepping on it.
It does NOT cancel updates from tripwire hook blocks, which change the attached state property of the tripwire โ that's a bug.
Steps/models to reproduce
- Set up a paper server
- Change the
block-updates.disable-tripwire-updatesoption inpaper-global.ymltotrue - Start the server and join the world
- Place two solid blocks 3 blocks apart
- Place tripwire hooks on the sides of the placed blocks facing each other
- Place a string inbetween them
- The string will have the
attachedstate property changed totrueโ bug
Plugin and Datapack List
[15:28:45 INFO]: Server Plugins (0):
[15:28:56 INFO]: There are 3 data pack(s) enabled: [vanilla (built-in)], [file/bukkit (world)], [paper (built-in)]
[...
If they aren't constants anymore, just make them into private static methods that take the int and return the component. E.g.
private static Component paperHeader(int count) { return text(....) }
I originally copied it from another method but that pseudocode example actually seems to be wrong for negative coordinates, should I fix that in this PR or a new one?
Follow up PR sounds good :+1:
I forgot that we also need the FluidRegistry modification API. However, since this is off-topic for this issue, we should create a separate issue.
not sounds bad, how about that part in NMS where check for Block based in BlockState and not for Fluid for particles? this also need to be adapted based in the fluild or is a side case?
Fixes #12127
Currently the disable-tripwire-updates has a bug, it does NOT cancel updates from tripwire hook blocks, which change the attached state property of the tripwire.
This PR fixes this by blocking the calculateState method inside TripWireHookBlock from running.
This is justified as the methods only functionality is:
- Checking nearby blocks to find a correct tripwire line
- Setting
attachedappropriately - Also managing redstone signals and firing events related to them (which already never happens when
disable-tripwire-updatesis on as the tripwires never getpowered)
TLDR it only does block updates and nothing else, half of which are already not being ran with disable-tripwire-updates, hence I think the best solution is to just cancel the entire method.
Fixes #12127
Currently the disable-tripwire-updates has a bug, it does NOT cancel updates from tripwire hook blocks, which change the attached state property of the tripwire.
This PR fixes this by blocking the calculateState method inside TripWireHookBlock from running.
This is justified as the methods only functionality is:
- Checking nearby blocks to find a correct tripwire line
- Setting
attachedappropriately - Also managing redstone signals and firing events related to them (which already never happens when
disable-tripwire-updatesis on as the tripwires never getpowered)
TLDR it only does block updates and nothing else, half of which are already not being ran with disable-tripwire-updates, hence I think the best solution is to just cancel the entire method.
That's not really what i meant, i have updated the pr
That's not really what i meant, i have updated the pr
Ahhh... How i font notice that if i copy-paste the example... Or what i do now i think ._.
a6e82d9 [ci skip] Clarify getChunkAtAsyncUrgently javad... - Warriorrrr
Is your feature request related to a problem?
n/a
Describe the solution you'd like.
typedKey like utils for creating tag keys.
Describe alternatives you've considered.
none
Other
No response
cb25c0c [ci skip] Fix annotation fields used in NMS get... - Doc94
0070126 [ci skip] improvement example in javadoc for Da... - Doc94
After some more review, I did end up changing this back to result xD
Sorry for the extra work, thank you for the PR!
I switched this, but I still think maybe if we go record should we use record notation for methods in PoiSearchResult API e.g. location() instead of getLocation() and poiType() instead of getPoiType()? I like the record pattern more for such objects, but this really isn't the "standard" with the other result APIs
608f004 add method on ItemStack to edit pdc (#12022) - Machine-Maker
Is there any way in specific we should handle this case
I got this comment on spigot a few months ago. Do we either
- specify the discrepancy in the API documentation
- each PoiType internal would run through something like CraftMenus but for PaperPoiTypes etc that will map to some Predicate that can make up for the non straightforward discrepancies. This isn't super straightforward and kind of annoying, but it does "fix" some things internals is a bit uneven about.
Just tested this, and will I get the expected result for Villager workstation (specifically farmer).
I do not get the result for beehives.
For beehives it gets only found for occupancy ANY, and returns null for the other two ones. Regardless if it is empty, 1 / 2 Bees or full.
The javadocs for the getChunkAtAsync family of methods provide an example of how to get the chunk coord from a world coord, but this example returns the wrong coord for negative coordinates.
a3781ff Separate tick count to ensure vanilla parity (#... - HaHaWTH
2a4a115 Add EntityEquipmentChangedEvent (#12011) - TonytheMacaroni
Sorry for the late reply, maybe someone will still look here, so I thought that it could be worth mentioning what motivated me to create this PR, or rather what was I basing it on.
It's hard for me to disagree with the above answers, and I won't discuss, but there's a little inconsistency in official stance on this topic. In the documentation of scheduler, a similar method of converting units to the one I proposed in this PR is shown. There is a small mention in upper section that if the server runs 10 ticks per second, the conversion rate to human time will be different, but if it is such a problem as you say, in my opinion it should be more emphasized, especially since below, there is an entire section with a bolded header dedicated to the topic of 'ignorant' (referring to the above discussion, this is not intended to offend anyone who created this part of the documentation) unit conversion.
Anyway, I understand why my PR was re...
I forgot that we also need the FluidRegistry modification API. However, since this is off-topic for this issue, we should create a separate issue.
Why do you need registry modification for fluids? I don't think that will happen for a while. Shouldn't the getter/setter for the tag be enough?
60394c5 Fix PlayerReadyArrowEvent cancellation desync (... - notTamion
b27e11c Fix bad world to chunk coordinate example in ja... - Warriorrrr
We need to figure out how to handle the home removal as the block entity right now isn't notified of such removal and is left in an invalid state where its protector does not believe it is its protector.
idk what the best approach for that is and my brain is kinda fried rn
88cdd22 Fixup luck and random implementation in CB loot... - FlorianMichael
We need to figure out how to handle the home removal as the block entity right now isn't notified of such removal and is left in an invalid state where its protector does not believe it is its protector.
idk what the best approach for that is and my brain is kinda fried rn
Hmm i can try think if not just remove that for now...
Removing it seems best, in contrib I proposed having methods to (un)link creakings on the heart block entity itself that would make sure all the state is correct.
Yea that sounds semi smart, I'll think about it again tomorrow.
Rebase notification D:
This still need more improvements?
Uh, good question. I'll try to get to it again soon but I'll throw it at other peeps too.
posting here to also take owen with me to the grave if this has a bug our testing did not find.
84609dc Don't auto-create any brig redirects (#11954) - Machine-Maker
8eb8e44 Allow For Default Titles in InventoryView Build... - Y2Kwastaken
Is your feature request related to a problem?
Currently, only the initial interaction with a brush item throws an event. Dragging the brush between blocks while holding allows players to continue brushing suspicious blocks without plugin oversight.
Describe the solution you'd like.
BrushableBlockEntity should throw EntityChangeBlockEvents before making changes to the block. This may require some reshuffling of the logic to preserve loot table state. Events should be thrown both for the dusted property change as well as the final brushingCompleted change.
Describe alternatives you've considered.
https://github.com/PaperMC/Paper/pull/9898#pullrequestreview-1726114004
Other
No response
This PR calls EntityChangeBlockEvent for brushable blocks so brushing can be detected as specified #12132.
From thinking might need to change when lootTable is generated for BrushableBlockEntity. While my brief testing of event took place I didn't see anything catastrophic while not moving it though. So I'm curious about that.
not sounds bad, how about that part in NMS where check for Block based in BlockState and not for Fluid for particles? this also need to be adapted based in the fluild or is a side case?
Wow, you're right! I totally didn't notice that.
Why is it even handled based on BlockState in the first place?
It looks like switching it to FluidState shouldn't cause any issues!
While we're at it, it would be nice to have a way to change the particles being sent.
But I guess that would be better handled by extending PlayerFishEvent, so it might be outside the scope of this topic.
I forgot that we also need the FluidRegistry modification API. However, since this is off-topic for this issue, we should create a separate issue.
Why do you need registry modification for fluids? I don't think that will happen for a while. Shouldn't the getter/setter for the tag be enough?
That's true, too. Sorry ๐
Yeah, go ahead and open a PR. In your tests, make sure the desync between client/server on the tag in FishingHook doesn't cause odd issues, or if it does, keep them in mind to note them in the PR. I see the tag being used in code ran on the client side, and obviously we can't change that.
Thanks! I'll get started on it right away!
Everything looks mostly good, some small style stuff, but we can fix that.
The new PredicateChoice requires an example stack, but this might not really make sense for use in the PotionMix
I think what we can do is just create a dummy example stack there. The only place the old predicate choice was used was in potion mixes where the example stack didn't matter. So just creating a random itemstack isn't going to break anything unless people start using the now-deprecated method for actual recipes. Which is their problem.
Is your feature request related to a problem?
In many cases, users of plugins encounter errors when starting them. Unfortunately, it is not clear to users what actions they need to take to solve the problem. In some cases, the problem is also that users generally do not understand the error.
Describe the solution you'd like.
Describe alternatives you've considered.
Using Doc's function, you could throw a specific exception and extra fields at the OnEnable, which then contains more detailed information on why the plugin is disabled or what you have to do to get the plugin functional again.
Other
This would give developers a way to give users UX-friendly help and make it uniform
- We generally don't want to shove 20 dozen pieces of hover text inside of the plugins message, the output is limited and hover stuff can burn through that pretty fast
- I'm not really sure what this solves, which isn't already solvable if people handled this in the logs. It's the port of call for understanding why something went sideways
5b9786c Readd dead redirect recovery - lynxplay
[PaperMC/Paper] New branch created: bugfix/brigadier-dead-redirects-commands-yaml
While the paper command system no longer uses redirects for namespaced
registration, vanilla still does. This means that removal of vanilla
redirecting target nodes still causes issues, e.g. the removal of the
vanilla 'msg' node in favour of a command alias one.
Redirecting nodes like tell, minecraft:msg and minecraft:tell are broken
by this and need to by flattened before sending them to the client.
The event calls are too late right now.
Right now, the block would drop its content even if people cancelled the change event.
It would also unpack its loottable, which, that modifies the block.
We need to move the unpacking down, dropContent calls it so, I think we can just move it right before the block set when a completion state changed (needs testing).
But yea, cancelling these events should maintain the block in the same state (not drop items/unpack loot tables).
Welcome to paper :tada:
Thank you for the PR!
I am a bit unsure on cancelling the entire method here.
We are only preventing updates to tripwires, not to the hooks.
Additionally, if something else ever happens in this method in the future, this change would make it very difficult for us to spot that during a version update.
Does moving this check down to the actual update of the tripwire also solve the issue correctly? (I'd imagine so)
Expected behavior
The getVelocity() method should return the player velocity.
Observed/Actual behavior
The getVelocity() method always returns zero as the player velocity.
Steps/models to reproduce
Calling getVelocity() on player while moving
Plugin and Datapack List
Single plugin calling getVelocity()
Paper version
This server is running Paper version 1.21.4-164-main@8eb8e44 (2025-02-16T22:13:26Z) (Implementing API version 1.21.4-R0.1-SNAPSHOT)
You are running the latest version
Previous version: 1.21.4-151-9b9de82 (MC: 1.21.4)
Other
No response
Players don't move using a velocity, outside of 'impulse' (i.e. knockback), the client just sends delta movements to the server
Players don't move using a velocity, outside of 'impulse' (i.e. knockback), the client just sends delta movements to the server
So what is the actual way to know whether player is moving or not?
The apis like getForwardsMovement() are broken but not marked for removal?
getForwardsMovement needs to be fixed, that was the thing I was hoping you'd create an issue for xD
getForwardsMovement needs to be fixed, that was the thing I was hoping you'd create an issue for xD
So velocity wont be fixed but there will be alternative api to use instead, I gotcha, I will make another issue then
The only way to check player movement, outside of the few edge cases, is to use the PlayerMoveEvent, all we get is deltas, there is generally no continual movement on players, given that they're not entirely predictable, so, velocity is working 100% as intended for Players.
getForwardsMovement used xxa and zza values, which were set in 1.21.1.
They are no longer updated in 1.21.2+ as the input packet now updates a separate field.
The API for that needs to use that new state.
Expected behavior
The method should return the player's movement direction from -1 to 1
Observed/Actual behavior
The method always returns 0 even when player is moving
Steps/models to reproduce
Check getForwardsMovement value while a player is moving
Plugin and Datapack List
Single plugin checking getForwardsMovement
Paper version
This server is running Paper version 1.21.4-164-main@8eb8e44 (2025-02-16T22:13:26Z) (Implementing API version 1.21.4-R0.1-SNAPSHOT)
You are running the latest version
Previous version: 1.21.4-151-9b9de82 (MC: 1.21.4)
Other
No response
The only way to check player movement, outside of the few edge cases, is to use the PlayerMoveEvent, all we get is deltas, there is generally no continual movement on players, given that they're not entirely predictable, so, velocity is working 100% as intended for Players.
I see, that makes sense now, thank you for explaining this
The javadocs of these methods state that this value is only updated for players while they are riding another entity, but while testing it this seems to no longer be the case.
Depending on your use case, you could use the Player#getCurrentInput method to detect whether a player is holding forwards/backwards as an alternative.
Yea I think we are best off to just forward CraftPlayer impl of these two to the input and then -1/1 them.
It would also unpack its loottable, which, that modifies the block.
Ran into this now the loot should only be unpacked after the first permitted brush Cancelling the event should not persist the state.
We need to move the unpacking down, dropContent calls
I moved these down as well and it seems to be working as intended to me.
I did some more playing around with the event and wasn't able to change the state after cancelling as intended using the vanilla brushing behavior. The patch needs a bit of cleaning up, but I'll leave it as is for now to see if this is what we will go with before I do that.
Approved outside of the if branch styling.
Mhmmm, I did not even think about the brushCount, good catch.
This makes this entire block a lot more difficult, but yea, I think this is the way to go forward (shuffling).
The client should be perfectly fine and we still unpack the loottable on the first brush (the first brush count moves from 0 to 1 in completion stage)
Event is still not fully cancelling the "last" and final brush tho, the game event is still called and the brushCount is not reset either.
Only calls BlockFadeEvents for blocks fading no longer players interacting, resolves #11566
[PaperMC/Paper] New branch created: feature/adventure-4.19
I wonder if its maybe better to add a parameter to the method that signals if the event should be called?
Thinking about future uses of that turnToDirt method not being noticed and so the event call not being done there.
Could possible trigger the event for a null entity passed? Or i can add a new param for event calling
Yeah, I'm good with that. no entity = world caused which is what we are going for.
Part of the process to promote lifecycle/paper plugins (or whatever we end up calling them).
Simplified Conditionals:
Combined multiple conditional blocks and removed unnecessary checks for a more concise flow. For example, the check for $isreject is simplified and placed directly inside the logic that handles applying the patch.
Refactored Reset Logic:
Consolidated the multiple $gitcmd reset --hard and $gitcmd clean -f calls into a single block. This prevents redundancy and makes the script more efficient.
Improved Variable Names:
No major changes to variable names, but the variable names are used consistently and meaningfully (e.g., summaryfail, summarygood, missingfiles).
Error Handling:
The script checks and logs errors related to missing files and patch application failures in a more streamlined manner, improving the clarity of the error output.
Patch Application:
The check for successfully applying the patch ($gitcmd am -3 "$file") is now more direct, skipping unnecessary steps if the patch application succeeds.
Handling Rejected Patches:
The bl...
In pretty much all the cases where a plugin blows up, you can easily find a solution by just asking google or contacting the dev
also, most less knowledged users don't even read stacktraces nor well written error messages let alone hover messages
ended up going with a field here, other option was an extra parameter in the brushingComplete, method, and I'm not sure if I like that diff as much, felt it was easier to insert as a field here.
Thanks for the review @lynxplay
I moved the check down to the part of code that updates the block, and ensured it only runs for tripwire and not tripwire hooks.
It still does function correctly like that and the tripwire doesn't get updated (all fields are false).
Though the hook now sets attached to true if it found a valid tripwire line when placed and doesn't update afterwards unless the other hook is broken. This might seem a little inconsistent, tell me if I should cancel updating specifically the attached property for the hook too (by removing the first condition inside the if statement). Just mentioning it, I don't know if it's a concern or not. Other than that all is good. ๐
Thanks for the quick response!
I think that is fine, the tripwire hooks are not part of the cancelled update, even if the resulting state looks fine.
Complete nitpick on my end, but can you just move the if statement directly infront of the setBlock line.
E.g.
if (!config.disableUpdatesTripWire) level.setBlock(blockPos1,....) // Paper - rest of comment
That way, in future updates, the patch fails to apply if the setBlock line there changes and we can correct it.
Beyond that, LGTM
Done that @lynxplay
Thank you again for the feedback & swift responses โค๏ธ
Are you sure you are doing this right?
The main world will keep ticking for a while after you leave it, it will do that in vanilla too (specifically 15 seconds).
If your portal is too far off the fishing hook in terms of x and y coordinates, it'll be destroyed. But that happens, at least from my testing, in vanilla as well.
Expected behavior
No spam in the logs ๐
Observed/Actual behavior
Since build 163 of paper 1.21.4 I've been spammed with logs that look like the following:
[Mon 21:48:37 ERROR ca.spottedleaf.dataconverter.minecraft.converters.custom.V3818_Commands] Failed to convert command '/say im a big fat idiot with no life lol'
java.lang.IllegalStateException: Cannot handle non-root redirects
at ca.spottedleaf.dataconverter.util.CommandArgumentUpgrader.copyCommand(CommandArgumentUpgrader.java:460)
at ca.spottedleaf.dataconverter.util.CommandArgumentUpgrader.copyCommand(CommandArgumentUpgrader.java:500)
at ca.spottedleaf.dataconverter.util.CommandArgumentUpgrader.<init>(CommandArgumentUpgrader.java:108)
at ca.spottedleaf.dataconverter.util.CommandArgumentUpgrader.<init>(CommandArgumentUpgrader.java:87)
at ca.spottedleaf.dataconverter.util.CommandArgumentUpgrader.upgrader_1_20_4_to_1_20_5(CommandArgumentUpgrader.java:75)
at ca.spottedleaf.dataconverter.mine...
Maybe getUpwardsMovement could be overriden too for consistency even if the javadocs say otherwise.
Can you also format the javadocs to make proper list (or at least newlines inbetween) currently the list is flattened.
ef2d8dd Default minecraft alias to redirect - lynxplay
[PaperMC/Paper] New branch created: bugfix/data-converted-redirect-fun
While the running server will still be using the recently introduced
copy-mechanic for vanilla command namespacing, the data converter logic
relies on the fact that namespaced aliases were redirects as well.
To not break the converted, the commands type now takes a modern flag
only set by the running server.
Resolves: #12145
Don't think we need to go further than sidewards/forward.
The new way of this is going to be the player input that is exposed.
We can obsolete them on Player in a follow up PR if we want but yea.
[PaperMC/Paper] branch deleted: bugfix/brigadier-dead-redirects-commands-yaml
[PaperMC/Paper] branch deleted: bugfix/data-converted-redirect-fun
b386a8f Add simpler JavaPlugin command registration (#1... - Machine-Maker
f070081 Remove Experimental from TypedKey (#12134) - Machine-Maker
769de10f62 might be a separate solution, not gonna push over yet because I am too tired.
Will review tomorrow.
09f1f88 Fix getForwards/SidewaysMovement for players (#... - Warriorrrr
@Machine-Maker
Lava fishing works, and FishHookState transitions correctly. However, the fishing hook does not float on top of lava.
While testing various things, I realized that, just as you mentioned, there is indeed a strange desync issue with the client. It took some time to figure out, but thanks to your heads-up, I was able to notice it. I really appreciate it!
For now, I'll open the PR and include a video showing the strange behavior as proof.
Implements #12126
This PR allows modifying the TagKey referenced by FishHook for bobbing.
If the associated TagKey includes lava or flowing_lava, fish will now be able to bite in those fluids as well.
โ Important Notes
This works correctly on the server-side, but there are some strange client-side desync issues to be aware of.
If the TagKey includes lava or flowing_lava without including water or flowing_water, the client perceives the behavior differently:
- The fishing hook does not appear to bob on lava.
- The fishing hook appears to bob on water, even if it shouldn't.
To make this issue clearer, Iโve attached a video demonstrating the behavior.
https://github.com/user-attachments/assets/befab695-133e-46a3-862b-5a68bf354217
I'm not very familiar with packet handling, so I donโt know of a good solution for thisโsorry about that.
Other Notes
Iโve read the CONTRIBUTING.md, but...
Maybe, will sending the ClientboundSetEntityMotionPacket solve the desync issue?
I'll give it a try for now.
Expected behavior
PlayerDeathEvent should only be called once
Observed/Actual behavior
PlayerDeathEvent is called twice
Steps/models to reproduce
Listen to an EntityDamageEvent and PlayerDeathEvent.
if the entity in the damage event is a player, cancel the event and call entity.setHealth(0);
Take fall damage or something so that you die, and the player death event will be called twice
Plugin and Datapack List
Irrelevant, confirmed by @lynxplay
Paper version
This server is running Paper version 1.21.4-164-main@8eb8e44 (2025-02-16T22:13:26Z) (Implementing API version 1.21.4-R0.1-SNAPSHOT)
You are 8 version(s) behind
Download the new version at: https://papermc.io/downloads/paper
Previous version: 1.21.1-119-7cd4f2c (MC: 1.21.1)
Other
No response
TL;DR, setHealth(0) will call die which will setClientLoaded(false)
The original damage of the process will call actuallyHurt with the cancelled event but, a non client loaded player is completely invuln, leading to that method returning true. That last bit of behaviour is new since the addition of the client loaded world packet and is the root cause of this issue.
Solutions are a bit out there. One attempt would be revisiting simply moving the event cancellation check outside of the invuln check. Seems incorrect to return true from that method if the event was cancelled but the player is invuln. That might however also lead to other issues not currently on my radar so, testing be advised.
Maybe, will sending the ClientboundSetEntityMotionPacket solve the desync issue?
I'll give it a try for now.
Yea, was having a ponder too, the player is considered invulnerable and so skips that entire logic and jumps to the hard return true; I'd probably defer this to Machine as he's familiar with this logic
Well we have been very active on that method returning false for the cancelled event, but yea. MM's opinion on this is gonna be valuable.
Closes #12118
Fixes an exception during item obfuscation initialization when all enchantments have been removed from the server
If you could get the entity data for the villager still it would help track down this issue
Let us know when you've been able to reproduce this, closing this as can't reproduce for now.
Closing this issue for now until more details are given, what's been provided so far is not enough to reproduce the issue with.
You can use https://docs.papermc.io/paper/reference/global-configuration#spark_enable_immediately if you want spark to be available immediately
The server has a movement check that prevents players from moving at high speeds, singleplayer does not have this. After doing /gamerule disablePlayerMovementCheck true I was able to reproduce your expected behaviour by getting launched thousands of blocks into the air.
Could you confirm whether this gamerule fixes your issue?
Closes #8770
Superseeds #8665
Adds ItemStack#getCreativeCategories and ItemType#getCreativeCategories to replace the old creative category api methods and updates the enum (javadocs copied from MM's PR). I tried to get the tests to pass, but that seems to not be possible without more changes.
Is there any way to get an instance of FeatureFlagSet that works both at runtime & during testing, or would I have to add something similar to what CraftRegistry does with its static registry field
Precondition here to make sure fluids isn't null
Welcome to Paper!
Just from quickly looking at the video: Do the items instantly get burned when you fish?
We definitely have to figure out an efficient way to have the client keep up with the hooks position as otherwise setBobbingFluids isn't really doing what it says it does.
Expected behavior
so the content of plugin.yml is
name: genocideauth
version: '1'
main: shaylyn.gg.genocideauth.discordauth
api-version: '1.21.4'
authors: [Shaylyn]
description: DiscordAuth For GenoCide
website: https://discord.gg/SVGgaxpAj7
commands:
discordauth:
description: ๋์ค์ฝ๋ ์ธ์ฆ ํ๋ฌ๊ทธ์ธ ๋ช
๋ น์ด
usage: /discordauth help
permission: discordauth.admin
permissions:
discordauth.admin:
description: ๋์ค์ฝ๋ ์ธ์ฆ ๊ด๋ฆฌ์ ๊ถํ
default: op
this and the version is 1.21.4(https://papermc.io/downloads/all)
please fix for me
Observed/Actual behavior
[22:04:34 ERROR]: [ModernPluginLoadingStrategy] Could not load plugin 'DiscordAuth-1.jar' in folder 'plugins.paper-remapped'
org.bukkit.plugin.InvalidPluginException: Cannot find main class `shaylyn.gg.genocideauth.discordauth'
at org.bukkit.plugin.java.PluginClassLoader.<init>(PluginClassLoader.java:80) ~[paper-api-1.21.4-R0.1-SNAPSHOT.jar:?]
at io.papermc.paper.plugin.provider.type.spigot.SpigotPluginProvi...
The github issue tracker is not for plugin support. Join our discord for support at https://discord.gg/papermc
Replaces the call to sendParticles() with sendParticlesSource() in SpawnParticlesEffect in order to attribute the effect to the player
Perhaps it would be nice to modify sendParticlesSource in the future so that it accepts any entity instead of only players (the method itself was added by CB), since entities can be hidden too.
Expected behavior
Full disable/no access to End world.
Observed/Actual behavior
When I disabled it on bukkit.yml and deleted the world_the_end folder, it still generates of which it shouldn't.
Steps/models to reproduce
Just disable the end in bukkit.yml
Plugin and Datapack List
[09:03:51 INFO]: Bukkit Plugins (35):
[09:03:51 INFO]: - AdvancedEnchantments, AuctionHouse, AuraSkills, BetterRTP, BetterStructures, Chunky, Citizens, CMILib, DailyRewardsPlus, DecentHolograms
[09:03:51 INFO]: DeluxeMenus, Denizen, EconomyBridge, EliteMobs, Essentials, EssentialsChat, EssentialsSpawn, ExcellentCrates, FastAsyncWorldEdit, ItemsAdder
[09:03:51 INFO]: Jobs, LoneLibs, LuckPerms, Multiverse-Core, nightcore, PlaceholderAPI, ProtocolLib, ShopGUIPlus, SkinsRestorer, TerraformGenerator
[09:03:51 INFO]: Vault, ViaBackwards, ViaVersion, VoidGen, WorldGuard
Paper version
I am using Purpur version latest (Current Purpur Version: 1.21.4-2398-196c176 (MC: 1.21.4)*) but I th...
I cannot reproduce this, I deleted world_the_end and set allow-end to false and no new world_the_end was created. This is not a paper issue, and please don't report issues to us that happen while running other software.
Could be done by the merger, lgtm.
I feel like something like this is very tricky to get right without Vanilla here, especially due to the rather large desync introduced by Vanilla. Probably better to just wait for them to add a fluid tag at one point into this area of code, since the desync is unavoidable without some nasty hacks. Because of course, the client expects water.
I think that documenting the fact that some POITypes are used more as "markers" for the block rather than storing occupancy would be useful.
Could maybe even add a method onto the poi type class if it has 0 max tickets so people can check themselves.
I'm a little torn, because of the fact that we arent sharing any inheritance I really think we should make the EntityHarvestBlockEvent "more proper".
- clone itemstacks, add getters/setters
- make the list immutable, add a setter/getter
Issue is then people wanting to use the other event may get a bit confused.
At some point along the hardfork process, this patch got messed up and started passing both the "from" and "to" blocks to be the same when using a honeycomb to wax a copper block.
This patch restores previous behaviour.
5e2a3bc Call EntityChangeBlockEvent with correct block ... - rymiel
I'm a little torn, because of the fact that we arent sharing any inheritance I really think we should make the EntityHarvestBlockEvent "more proper".
- clone itemstacks, add getters/setters
- make the list immutable, add a setter/getter
Issue is then people wanting to use the other event may get a bit confused.
yeah i prefer keep the two events like the same.. if not then modify the two with this new "behaviours" but set itemstack? i mean all are in the list or i bad read something?
Cleans up the connection throttle code and replaces a hardcoded check excluding the ipv4 loopback address
Expected behavior
it shouldn't spam itself
Observed/Actual behavior
it spamming itself continuously until you take a step back from the damager block (like magma, cactus, campfire etc.)
Steps/models to reproduce
in EntityDamageEvent, just make the damage lower than 1 by using event.setDamage (like 0.9). then, just jump on a damager block (like magma, cactus, campfire etc.). and don't forget to make an output next to it, so you can see it's spamming itself.
Example Code:
public void test(EntityDamageEvent event) {
Bukkit.getServer().broadcast(Component.text("hit."))
event.setDamage(0.9) // - bug starts when you set this lower than 1
}
Plugin and Datapack List
nothing, just a clean server with my test plugin.
Paper version
This server is running Paper version 1.21.4-174-main@5e2a3bc (2025-02-20T09:56:44Z) (Implementing API version 1.21.4-R0.1-SNAPSHOT)
Other
I've tried it in multiple versions but problem still exists. (in 1.21.1, 1.21.3, 1.2...
Expected behavior
I use this code to check for Respawn Anchor Damage and it should work:
Observed/Actual behavior
In the console I get the error that the Block is null:
Steps/models to reproduce
- Use the code mentioned above and register the Event
- Damage/Kill yourself with a Respawn Anchor
Plugin and Datapack List
Only my testing Plugin that only contains the code from above
Paper version
This server is running Paper version 1.21.4-174-main@5e2a3bc (2025-02-20T09:56:44Z) (Implementing API version 1.21.4-R0.1-SNAPSHOT)
Other
The API Version is 1.21, so everything is up-to-date
Full Error:
`[19:20:29 ERROR]: Could not pass event EntityDamageByBlockEvent to DebugPlugin v1.0.0
java.lang.NullPointerException: Cannot invoke "org.bukkit.block.Block.getType()" because "damager" is null
at debug-plugin-1.0.0.jar/de.skyking_px.debugPlugin.DebugPlugin.onEntityDamageByBlock(DebugPlugin.java:29) ~[debug-plugin-1.0.0.jar:?]
at co.aikar.timings.TimedEventExecutor.execute(TimedEventExecutor.java:80) ~[paper-api-1.21.4-R0.1-SNAPSHOT.jar:?]
at org.bukkit.plugin.RegisteredListener.callEvent(RegisteredListener.java:70) ~[paper-api-1.21.4-R0.1-SNAPSHOT.jar:?]
at io.papermc.paper.plugin.manager.PaperEventManager.callEvent(PaperEventManager.java:54) ~[paper-1.21.4.jar:1.21.4-174-5e2a3bc]
at io.papermc.paper.plugin.manager.PaperPluginManagerImpl.callEvent(PaperPluginManagerImpl.java:131) ~[paper-1.21.4.jar:1.21.4-174-5e2a3bc]
at org.bukkit.plugin.SimplePluginManager.callEvent(SimplePluginManager.java:628) ~[paper-api-1.21.4-R0.1-S...
Always passes the respective block to a damage source when passing a
block state. While we could technically use the damageSourcePosition
here by, we'd have to translate it back to a block position by
subtracting .5 from all its components.
Such behaviour however relies on the caller logic's mutation of the
damageSourcePosition and will break once this position is not the centre
of the block.
Passing in the block at the specific callsite is a lot more future
proof.
Resolves: #12157
Thank you for the report, https://github.com/PaperMC/Paper/pull/12158 is going to have a runnable paper jar attached in a couple of minutes if you need a hot fix for this.
I'll merge it once I poke someone else for a review.
Expected behavior
Tripwire should stay after door opens
https://youtu.be/gTsdEnRWYb8?si=OfCVbWiIFRsQvMox
Observed/Actual behavior
Tripwire breaks after setting it on iron door and iron door open but doesn't dupe.
Steps/models to reproduce
Make paper server
Turn skip-tripwire-hook-placement-validation to true
build: https://youtu.be/gTsdEnRWYb8?si=OfCVbWiIFRsQvMox
Plugin and Datapack List
I tried with and without plugins. Both didn't work.
Backuper, CoreProtect, dynmap, Essentials, EssentialsChat, EssentialsSpawn, floodgate, Geyser-Spigot, GSit, LuckPerms, LWC, Multiverse-Core, NoteBlockAPI, PL-Hide, PlugManX, Sit, SkinsRestorer, TAB, Vault, voicechat, voicechat-discord, WeatherVote, WorldEdit, WorldGuard
Paper version
This server is running Paper version 1.21.4-175-main@ab984a0 (2025-02-20T19:29:15Z) (Implementing API version 1.21.4-R0.1-SNAPSHOT)
You are running the latest version
Previous version: 1.21.4-144-edacfdf (MC: 1.21.4)
Other
Tripwire ...
Closed due to being a duplicate.
7b4d44f Revert "Always pass event block to damage sourc... - lynxplay
@SkyKingPX seems I did not correctly test this, this is expected behaviour. You should defaul to the getDamagerBlockState if getDamage() is null. Fix was reverted.
e5a8ee8 Hide soul speed particles for vanished players ... - bonan
I agree with Owen here.
This seems a bit too hacky imo given the client does desync quite heavily.
Exposing an API like this that in the end barely works feels rough, especially when its a feature mojang does not remotely support.
Been a few more days, but I think I am on warriors side here.
Removal should probably be on the heart only.
Having to chunk load in the heart sounds rough.
We have for now decided against since annotation in the project.
Adding some is just gonna make our lifes even more miserable when/if we solve them semi automatically.
computeMostSignificantFall
The intend ruined your diff here.
can you just call the createCombatEntry overload here.
Makes life easier if that ctor ever changes.
Pre-allocate with size.
Not a fan of the param naming here.
loadAndValidate?
Been a few more days, but I think I am on warriors side here. Removal should probably be on the heart only. Having to chunk load in the heart sounds rough.
okay removed the method
PS: I forget this branch was modified then i hope not mess in the rebase xd
Welcome to Paper! Just from quickly looking at the video: Do the items instantly get burned when you fish? We definitely have to figure out an efficient way to have the client keep up with the hooks position as otherwise setBobbingFluids isn't really doing what it says it does.
The fishing hook moves back and forth between the lava and the air, so sometimes the caught items burn, and sometimes they donโt. This is expected behavior.
I feel like something like this is very tricky to get right without Vanilla here, especially due to the rather large desync introduced by Vanilla. Probably better to just wait for them to add a fluid tag at one point into this area of code, since the desync is unavoidable without some nasty hacks. Because of course, the client expects water.
I've been trying various approaches over the past few days, but as you said, the only available methods are dirty hacks.
The simplest approach was to send a MotionPacket only when the tag is set to something other than FluidTags.WATER, but it seems that the client ignores the motion packet for the fishing hook, so that didn't work ๐ฅฒ
When I added lava to fluid/water.json, the fishing mechanics worked correctly.
Iโd like to confirm something: My understanding is that the server sends the water tag and its associated values to the client, and the client reads this tag to determine whether the fishing hook can bob on a fluid. Is this correct?
Implementing this with a hack could cause compatibility issues in the future if Vanilla updates its mechanics. So, Iโve decided to temporarily withdraw this PR and wait for Vanilla to make changes.
If there are no objections, could you kindly close this PR?
In the meantime, Iโll add details about the issue preventing this featureโs implementation to #12126.
I agree with Owen here. This seems a bit too hacky imo given the client does desync quite heavily. Exposing an API like this that in the end barely works feels rough, especially when its a feature mojang does not remotely support.
I agree
After some additional review I think this is related to the quasi-connectivity redstone logic, where an item affected by redstone is updated when there is any block state change next to it. Weird but probably a relic from a hacky work-around to support doors with switches over them originally.
Implementation is currently impossible due to desync issues between the client and server until Vanilla supports modifying the fluid registry.
- The client determines whether a fishing hook can float by referencing the water tag.
- The server does not send any packets to the client between shooting the fishing hook and a fish biting.
- The client ignores velocity packets sent for the fishing hook.
If Vanilla ever adds support for modifying the fluid registry, feel free to ping me in this issueโI'd be happy to work on the PR again! :)
should generally be ready for review now. one thing to note is that crossbows now remove items one by one from their charged projectiles, that way plugins can choose to fire only certain projectiles and have the other ones remain charged
Thoughts on expanding the scope of this event?
I like the idea of being able to provide/replace a projectile in any scenario, like the linked EntityGetProjectileForWeaponEvent from the patch above, and have a similar EntityLoadsProjectileEvent in my fork (and its feature patch), though I also feed the default projectile into the event.
Expected behavior
An entity within activation range should be ticking as normal.
Observed/Actual behavior
Following setup:
- fresh new server/world
- server.properties unchanged (therefore view/sim distance = 10)
- all configs unchanged except activation/tracking ranges in spigot.yml all set to 500
Entities not so far away are not moving.
(The pigs in the video are about 32 blocks away, well within the 500 block activation range)
https://github.com/user-attachments/assets/1f96ce3f-58b2-4921-a350-1fcd048e2ca7
When I move closer, they activate:
https://github.com/user-attachments/assets/faf5a2b5-6b93-4cb2-9921-9d91a8990763
Added bonus:
If I set the pigs ablaze... they run for their lives:
https://github.com/user-attachments/assets/0842b6c8-958e-4232-9ab2-fd2d6106b52a
Steps/models to reproduce
See above for setup.
Just log in, and look at how mobs are not moving.
Plugin and Datapack List
No datapacks, only plugin Im using is Skript, just for debugging (ie: ...
update:
Ok, so this might be a vanilla thing?!?!
When did MC add this?
I guess its not a bug anymore, but maybe a setting to modify this could be added?!?!
Like other events of this nature, the client will still shrink the item by 1 when the event is cancelled and become desynced.
- Adds overloads to
World#rayTraceandWorld#rayTraceBlocks, as well as the methodPositionedRayTraceConfigurationBuilder#blockCollisionMode, that take aBlockCollisionModeinstead of the booleanignorePassableBlocksto determine block collisions. - Add
FluidCollisionMode.WATER. - Remove outdated javadocs on
World#rayTrace,World#rayTraceBlocks,PositionedRayTraceConfigurationBuilder#fluidCollisionMode, andPositionedRayTraceConfigurationBuilder#ignorePassableBlocksthat mention caveats with portal blocks and fluids that no longer exist. Portal blocks are always considered 'passable', and the value ofignorePassableBlockshas no effect on fluid collisions.
The entire point of the builder was that we do not overload this further.
It is already pain xD
The overloads are necessary for the builder to function?
No, CraftWorld executes the builder.
It can/should use non public methods for that.
Overload the methods needed one last time in CraftWorld.
Any additions after that will just use the method you are about to add and add params.
Alright, removed the method from World.
Thanks, this solves the problem nicely.
Expected behavior
Taking Cramming(Squishing) Damage
Observed/Actual behavior
Not Taking Cramming(Squishing) Damage
Steps/models to reproduce
Paper
https://github.com/user-attachments/assets/f49fde13-5f3c-4a2c-abb5-ec3bcba5d96f
Vanilla
https://github.com/user-attachments/assets/e1f208da-d9b9-4352-b263-f6d98e1ce6e0
Plugin and Datapack List
- No Plugins
- Bulit-in Datapacks(vanilla, file/bukkit, paper)
Paper version
This server is running Paper version 1.21.4-177-main@e5a8ee8 (2025-02-21T11:12:22Z) (Implementing API version 1.21.4-R0.1-SNAPSHOT)
You are running the latest version
Other
No response
Is your feature request related to a problem?
Currently there is no event when an Eyeblossom opens/closes, to this cannot be logged or stopped by plugins. Same for Creaking hearts that activate/deactivate.
Describe the solution you'd like.
For the opening/closing Eyeblossom spigot is using the BlockFormEvent, maybe that could be called in paper too or maybe some other event. For the heart maybe the same event.
I am not completely happy with the BlockFormEvent, but it is used for block transforming itself like concrete powder->concrete too so it could be fine. And i think it is better than using the BlockGrowEvent, because it is not realy about growing.
Or maybe some completely new event, but I don't know how it should be named.
Describe alternatives you've considered.
/
Other
No response
Currently, PlayerFishEvent is not triggered when a FishHook changes its state. This means that if you want to track state transitions, you have to monitor them using a scheduler, which is inefficient. To address this, I have implemented FishHookStateChangeEvent.
- This event is useful when you want to send messages, titles, or sounds to players based on fishing hook state transitions.
- Canceling the transition to
HookState.BOBBINGpreventsMinecraft#FishingHook#catchingFishfrom executing. - Be cautious when handling this event, as canceling it will not prevent the state transition from being re-evaluated in the next tick. If the conditions are still met, the event will be instantiated and called repeatedly. (This behavior is documented in the Javadoc.)
For consistency, this event is mostly copied from PufferFishStateChangeEvent. However, I feel that "State Transition" might be a more appropriate term than "State Change."
Closes #12038
This PR makes it so that setDelay changes the task's state in the same way as the constructor does, so that the state can properly become STATE_ON_TIMER
Stack trace
Plugin and Datapack List
- FancyHolograms, qXP-Boosts
Bukkit Plugins (77): - AdvancedBan, AutoPickup, AutoReplant, AxAuctions, AxiomPaper, Backuper, BannedWordsEffective, BetterGUI, BetterMessages, BetterRTP
BottledExp, CatchBall, Chunky, Citizens, CleanroomGenerator, Clumps, CMILib, CommunityQuests, CrazyEnchantments, CustomAnvil
DelphiVote, DiscordSRV, dynmap, Dynmap-Towny, EasyArmorStands, Elevator, Emojis, Essentials, EssentialsChat, EssentialsProtect
EssentialsSpawn, ExecutableBlocks, ExecutableEvents, ExecutableItems, EzChestShopReborn, FastAsyncWorldEdit, GrimAC, GSit, Infiniteannouncements, InteractiveChat
InvisibleItemFrames, Jobs, LuckPerms, Maintenance, mcMMO, MilkyPixelart, MiniMOTD, MobFarmManager, MobSizeRandomizer, Multiverse-Core
MyCommand, MyFurniture, ODailyQuests, packetevents, PlaceholderAPI, PlayerPoints, PlayerWarps, ProtocolLib, Quests, RealScoreboard
*ResourcePack, SCore, SilkSpawners_v2, SimplePronouns, StaffC...
Avoid changing the indentation of these lines to help with diff.
So you would have a paper comment on the if statement, then the bracket
So
if (...) { // Paper - blah
...
...
..
} // Paper - blah
This way you are not changing the code inside of the if, and it wraps the diff cleanly.
Is your feature request related to a problem?
Not really a problem per se, just some of the methods for using TypedKey/TagKey seem awfully verbose.
Comparing a Block to a TypedKey
(I dont think anyone would do this, just wanted to show it off)
(block referencing a Bukkit Block)
TypedKey<BlockType> blockTypedKey = TypedKey.create(RegistryKey.BLOCK, block.getType().key());
if (blockTypedKey.equals(BlockTypeKeys.STONE)) {
}
Checking if a Block matches a TagKey
(as far as I know this is the shortest way?!?!?)
(block referencing a Bukkit Block)
TypedKey<BlockType> blockTypedKey = TypedKey.create(RegistryKey.BLOCK, block.getType().key());
Tag<BlockType> tag = RegistryAccess.registryAccess().getRegistry(RegistryKey.BLOCK).getTag(myTagKey);
if (tag.contains(blockTypedKey)) {
}
Describe the solution you'd like.
I would like to see some additions similar to NMS Methods.
Ex: NMS ItemStack:
(I believe BlockStateBehaviour has these as well)
<img width="32...
Closes https://github.com/PaperMC/Paper/issues/12082
And fix more issues:
- RECORD_PLAY should take a jukebox song
- DRAGON_BREATH/EXTINGUISH should take a boolean
This is just a bandaid, later a better api should be done to properly enforce data types
Instead of hardcoding the class name, fetch it dynamically and show more useful info to distinguish the instances
The current logic try to compare a MobEffect with a Holder<MobEffect> which always fail.
Generally this logic would need to be more involved with the recent tag/effect addition. I think it's better done via a plugin depending of the type of server.
Yeah, a lot of what you describe is something that is planned. But no issue open, so this works. Basically the idea is that every type that has a Regisrty will have several โisโ methods. Kinda replacing Keyed. is(Key), is(TypedKey), isTaggedBy(TagKey). So ItemType/BlockType and all the others will have that.
I'm glad to hear all that.
I'm excited to see the direction that all of this is going.
Transferring a player will require both sender and receiver to have transfers enabled in paper-global.yml and server.properties respectively.
This increases security as server staff with elevated permissions can send players to self-hosted servers to ip-grab them without having console access in the "sender" server.
This also breaks attack vectors where server staff is tricked into transferring players directly via command or clicking a sign.
Transferring a player will require both sender and receiver to have transfers enabled in paper-global.yml and server.properties respectively.
This increases security as server staff with elevated permissions can send players to self-hosted servers to ip-grab them without having console access in the "sender" server.
This also breaks attack vectors where server staff is tricked into transferring players directly via command or clicking a sign.
I am not a large fan of this change.
Paper already assigns permission nodes to all vanilla commands.
Servers concerned with this should just be removing the permission for the transfer command minecraft.command.transfer from everyone.
Has the same effect without the need for a new server option.
I thought of something similar while reviewing the code so I made the implementation on the send packet function to also prevent plugins from doing this using packets.
So... it is not limited to just the /transfer command.
I am confused, why would a plugin transfer players if the server owner is not interested in transfers?
To follow up on this, the transfer command is not something normal players have access to.
A server would have to effectively grant operator permissions to someone for them to be able to use it or explicitly the transfer permissions. That is already incredibly dangerous, transferring seems like the least of your worries if someone has such level of permissions.
The angle of a plugin transferring has two parts.
Either the plugin maliciously does it, at which point, you have malware.
Or the plugin exposes a transfer mechanism and somehow a staff member not meant to have that permission gained that? Which is pretty much the same point as above.
I just really don't see an angle where a server might have accidental transfers enabled without it being aggressively missconfigured, which I doubt those servers will use a config option to fix that.
I'll throw it at some other members for their input, but from my point of view, I don't think I want to pull this change.
Sometimes people upload malicious plugins to official platforms like it happened in modrinth a couple of months ago.
Other times server owners get custom plugins from other people like "friends" or worse, players.
Tbh, that last one is mostly their fault ๐
But still is something that sometimes happens, specially for non experienced server owners, and the ones at risk ends up being the players
No problems, you can close it.
Thx for the compliment!
Yea malware certainly exist :sweat_smile: Issue with that is usually "ah fuck, malware might as well just change the parsed config value before sending this". Fighting malware outside of "do not install it in the first place" is sadly usually a lost cause.
I'll throw the PR at someone else before I close it just to make sure the team agrees with me on this. But yea, thank you already for the PR no matter the outcome!
Sometimes people upload malicious plugins to official platforms like it happened in modrinth a couple of months ago.
Tbh I can't see a reason why would someone transfer people instead of silently grab the exact same information on your server and send it back to the bad dev. People will quickly start to notice those transfers and complain, exposing the plugin, all this for no extra information that a transferred server could extract.
Sometimes people upload malicious plugins to official platforms like it happened in modrinth a couple of months ago.
Tbh I can't see a reason why would someone transfer people instead of silently grab the exact same information on your server and send it back to the bad dev. People will quickly start to notice those transfers and complain, exposing the plugin, all this for no extra information that a transferred server could extract.
True, if they managed to get the plugin on the server they can already have access to player information there.
The original idea was based on the /transfer command where the attacker doesn't necessarily have access to the console and then I thought of the plugins making the same.
But yh, limiting access to the command via permission plus the fact that plugins already have console access and can make worse stuff than just transferring players makes this config a bit pointless.
Btw, I think it would be a good idea to mention stuff ...
Btw, this is the first PR I make to Paper, so I'm not yet aware of your workflow if usually you close the PRs or I should be closing it.
I vote no on this:
-
Regarding the command, as already stated, commands have permissions and should be negated. No one but the server owner should be op, therefor no one but the server owner should have permission for that command.
-
Regarding malicious plugins.... no matter what, a malicious plugin would still be able to change the config option and force transfer a player. The config option wont stop anyone.
This implementation is far too trivial to bypass by anybody remotely familiar with the networking library in use, and wouldn't take much rocket science to see how to bypass the method here. The only way you'd be able to do this is to handle this in the pipeline itself, but, this generally just offers a fake security assurance which nobody can promise when you're running arbitrary code on your server.
Is your feature request related to a problem?
At present, it's not possible to detect when an armadillo changes its state and cancel it. This is problematic for vanish plugins, as they can't cancel the state change caused by a vanished player.
Describe the solution you'd like.
I suggest introducing a new cancellable ArmadilloStateChangeEvent, similar to the WardenAngerChangeEvent.
#12026 seems to be a good basis for this feature request, as it adds API features for armadillos (such as an enum for the armadillo state).
Describe alternatives you've considered.
N/A
Other
No response
What's up with this diff? Why use the Value directly instead of BIT_MASK?
Did you forget to rename this one too? same in the javadocs here and below
Small typo on climable
There's no need to remove the final modifier for those?
I mean it's fine, but why would you change the listing from rgb to bgr?
Expected behavior
On teleporting with minecraft command /tp chunk should load one time
Observed/Actual behavior
Chunk gets loaded multiple times
` public SomeEventListener(Plugin plugin) {
Bukkit.getScheduler().runTaskTimer(plugin, () -> {
map.keySet().stream()
.filter(key -> map.get(key) > 1)
.forEach(key -> {
Bukkit.getConsoleSender().sendMessage("Chunks that loaded: " + key + " times: " + map.get(key));
});
map.clear();
}, 20L, 20L);
}
@EventHandler
public void onChunkLoad(ChunkLoadEvent e) {
map.put(e.getChunk().toString(), map.getOrDefault(e.getChunk().toString(), 0) + 1);
}`
Steps/models to reproduce
Teleport to unloaded chunks
Plugin and Datapack List
 method allows to take Pointered from MiniMessage context (net.kyori.adventure.text.minimessage.Context) using Context#target method.
Usage example:
static TagResolver DISPLAY_NAME_TAG_RESOLVER = TagResolver.resolver("display_name", new BiFunction<ArgumentQueue, Context, Tag>() { // without the use of lambda for clarity
@Override
public Tag apply(final ArgumentQueue argumentQueue, final Context context) {
Audience target = context.targetAsType(Audience.class); // Or CommandSender, Player, etc.
return Tag.inserting(target.get(Identity.DISPLAY_NAME).orElseThrow());
}
});
...
player.sendRichMessage("You display name is: <display_name>", DISPLAY_NAME_TAG_RESOLVER);
The simplest testing:
 method allows to take Pointered from MiniMessage context (net.kyori.adventure.text.minimessage.Context) using Context#target method.
Usage example:
static TagResolver DISPLAY_NAME_TAG_RESOLVER = TagResolver.resolver("display_name", new BiFunction<ArgumentQueue, Context, Tag>() { // without the use of lambda for clarity
@Override
public Tag apply(final ArgumentQueue argumentQueue, final Context context) {
Audience target = context.targetAsType(Audience.class); // Or CommandSender, Player, etc.
return Tag.inserting(target.get(Identity.DISPLAY_NAME).orElseThrow());
}
});
...
player.sendRichMessage("You display name is: <display_name>", DISPLAY_NAME_TAG_RESOLVER);
The simplest testing:
.
The fact that 99% of entities now only expose their uuid is fine to me, I don't think toString() is a reliable
debugging source in the first place.
Noting that, I am confused why you chose to keep CraftHumanEntity's name in the toString impl?
It sticks out a bit given other entities lost their debug information (like horse variants or itemframe rotations).
because this is the javadoc for the fromBRG method?
I am semi inclined to agree here.
I guess the intention is that "comparing a value to a mask makes no sense".
The more correct precondition I guess would be (alpha & BITMASK) == alpha).
If this is a cleanup PR, this should be id++ + ":" +
Looks like its crashing during Garbage Collection of some chunk data. Given that you have 79 plugins that all could be doing something here, there really isn't a lot we can do with this crash log.
Are you able to reproduce this without plugins?
Is your feature request related to a problem?
Among the numerous kinds of doors that Minecraft has accumulated over the years, many of them have unique sounds when opening or closing them. Currently there is no way to get these sounds via the API. If you wish to emulate opening or closing a door through code, the sounds aren't played automatically, but you also have no way of knowing which sound to play in a robust and future-proof way.
Describe the solution you'd like.
A way to access the sounds given a Door or TrapDoor kind of object representing the specific kind of door.
Describe alternatives you've considered.
Hard-coding everything and crying when Mojang adds yet another wood type in the next update.
Other
Vanilla has a BlockSetType for this, which is stored in the field of a DoorBlock. I'd love for an equivalent to be exposed. I tried implementing this myself but failed because the Material system is so incompatible with vanilla's system. I'm hoping...
Expected behavior
If using CustomArgumentType<T, N> and also overriding the parse(reader, source) function, it should default to it instead of using the less advanced parse(reader) function.
This should make it possible to access the source and adapt the parsed content to it.
Observed/Actual behavior
Override the parse(reader, source) function does effectively nothing. There is no way to parse based on source/context, and it always only uses the parse(reader) function instead.
In code comments (and Paper Docs) there is no word about this behavior, or how to deal with it, of the CustomArgumentType, so it looks like it is just not working as intended / thought.
Steps/models to reproduce
- Implement CustomArgumentType<*, *>
- Override parse(reader, source)
- Try to use it
Plugin and Datapack List
/
Paper version
This server is running Paper version 1.21.4-177-main@e5a8ee8 (2025-02-21T11:12:22Z) (Implementing API version 1.21.4-R0.1-SNAPSHOT)
You are runni...
Water friction is just a type of friction, like air and ground friction.
This more closely matches my expectation of "this shouldn't slow down naturally over time without external forces".
I wasn't sure what to do about ADVANCEMENT, BOSS_BARS and MEMORY_MODULE_TYPE registries.
Any ideas, or is my implementation good enough?
This could probably just be a default method.
Like, by default we use Iterables.size and then override this for delegate, map based and internal reg.
It is 100% fine for the deprecated registries to be a bit slower like this.
Slowly migrate custom to proper tags by deprecating the redundant tag, the other tags should probably be generated using the data generator later
wouldn't it be better to just make NotARegistry use Iterables.size by default since the issue only affects them?
If we are going to expose water we should add lava to the nms enum and add it here aswell
Feels kinda weird to expose this one, as i think it would feel pretty random to someone using the API. And its only really there for internal Falldamage calculations
Is your feature request related to a problem?
Fullbright is unfair to vanilla players.Didn't use the solution without using mods.
Describe the solution you'd like.
set client Light
Describe alternatives you've considered.
use https://dev.bukkit.org/projects/anti-fullbright/
use mod
Other
No response
No that is not possible.
The plugin you linked doesn't prevent full bright, it simply punishes users that attempt to mine blocks while at a light level where they should not see much.
This is outside the scope of paper.
Additionally pins configurate-core as a transitive dependency of
configurate-yml, as the yaml snapshot depends on a snapshot itself.
Closes #12178
Adds a config to toggle the behavior of bees getting a cooldown for future release attempts when an attempt fails (such as the hive being blocked). Disabling this brings behavior back to how it is in vanilla, at the cost of reduced performance.
Expected behavior
My RCON client expects a valid response to an empty command to detect the end of fragmentation.
Observed/Actual behavior
The server throws an ArrayIndexOutOfBoundsException:
[16:48:50 INFO]: Thread RCON Client /127.0.0.1 started
[16:48:54 WARN]: Unexpected exception while parsing console command ""
java.lang.ArrayIndexOutOfBoundsException: Index 0 out of bounds for length 0
at org.bukkit.craftbukkit.CraftServer.dispatchCommand(CraftServer.java:1031) ~[paper-1.21.4.jar:1.21.4-178-636ae0c]
at org.bukkit.craftbukkit.CraftServer.dispatchCommand(CraftServer.java:1021) ~[paper-1.21.4.jar:1.21.4-178-636ae0c]
at org.bukkit.craftbukkit.CraftServer.dispatchServerCommand(CraftServer.java:1002) ~[paper-1.21.4.jar:1.21.4-178-636ae0c]
at net.minecraft.server.dedicated.DedicatedServer.lambda$runCommand$4(DedicatedServer.java:743) ~[paper-1.21.4.jar:1.21.4-178-636ae0c]
at net.minecraft.util.thread.BlockableEventLoop.lambda$submitAsync$0(BlockableEventLoop.java...
In the future, the bukkit & spigot config will eventually be merged into the paper one. Since this API hasn't been great from the start (there's 0 guarantee that any given config option actually exists), that makes this a good time to deprecate these methods.
I feel this only avoid the problem the fact that dispatchCommand throw such exception is already an issue. It should probably say something like "Unknown or incomplete command, see below for error" and return false.
We should actually just rip out the bukkit command system, it's still lingering in a couple callsites
1d9b399 Add config option for failed beehive release co... - Warriorrrr
5f2ee83 Fix first execution of async delayed/repeating ... - Warriorrrr
b00875f Add a method on Registry to get the size (#12182) - GliczDev
Good enough for a quick fix, more can be done separately
7f3d359 Use MiniMessage#deserialize(String, Pointered) ... - novitpw
f63dbea Fix cancelled HangingPlaceEvent inventory desyn... - Warriorrrr
since should be the version that it became unusable with
any updates on this?
I have been swallowed by university work. I don't have a timeline for this but I'll rebase the patch once I have time. (if okx-code reads this).
I think im just remove that methods xd
When finish the blackout
If a plugin changes the damage in EntityDamageEvent, it can cause the INVULNERABILITY_REDUCTION damage modifier to be set to 0 and render invulnerability damage reduction, added in https://github.com/PaperMC/Paper/pull/11599, ineffective
This happens because a float (the lastHurt value in a Player) is being compared to a double (stored in the modifiers of EntityDamageEvent), and a float can be greater than a double, even if they are the same value:
jshell> 3.2D < 3.2F
$2 ==> true
Due to lossy floating point precision, 3.2F is implicitly casting to 3.200000047683716, which indeed would be greater than 3.2.
float lastHurt is the result of casting the double from EntityDamageEvent#getFinalDamage, which causes this imprecision. The fix is to cast the doubles from EntityDamageEvent to floats when comparing them here. This ensures that if they are the same value, then one will not be less than the other, because they have both been cast from the same dou...
Since it's been broken for so long, I wonder if its not just better to create a whole new type, and make it an interface and registry-able type since its a registry in vanilla.
yeah, you should be able to replicate it yourself with the predicate anyways right?
Kinda - for some reason, this mode uses a full block shape instead of the actual collision shape of the block.
Hmm, I'm hesitant to add API similar to vanilla's BlockSetType at this time. That type seems ripe for becoming datadriven at any point during which it's structure could change.
I wonder if there's a way we could expose just the sounds themselves somewhere instead of needing to add a whole type like BlockSetType.
Maybe can just use handle.getScoreboardName so we don't have to leave the toString implementation in CraftPlayer either.
Expected behavior
Good question - no server timeout, of course. To be more specific, it would be fine for the cartographer villager to have treasure maps that don't work in his inventory. So there would be no treasure chest. The issue seems to be around the server code trying to generate whatever is required for a treasure map in a void world but not being able to, probably ending up in an infinite loop, I'm guessing.
Observed/Actual behavior
Forced server shutdown after ranking up a cartographer through trading (which triggers treasure maps to attempt to be generated).
Log:
[21:37:59 ERROR]: --- DO NOT REPORT THIS TO PAPER - THIS IS NOT A BUG OR A CRASH - 1.21.4-183-f63dbea (MC: 1.21.4) ---
[21:37:59 ERROR]: The server has not responded for 10 seconds! Creating thread dump
[21:37:59 ERROR]: ------------------------------
[21:37:59 ERROR]: Server thread dump (Look for plugins here before reporting to Paper!):
[21:37:59 ERROR]: ------------------------------
[21:37:...
It makes the enums we have in the API seem rather random, same thing for the WATER, LAVA Review i left. If this uses a collision mode (full block shape) we donโt otherwise have in the api then we should instead expose that one without the fall damage filtering part, that seems a lot more useful.
If the event is cancelled then the return here and in the block below is also skipped, could that have any unwanted effect?
Ah, I completely overlooked that. The client's interpolation would cause strange desync issues, making it appear as if the hook is still attached from the clientโs perspective.
While canceling this event could be useful, it might lead to event spamming or further desync issues. I'm okay with making it non-cancellable, but what do you think?
+ // Cast the passed in double down to a float as double -> float -> double is lossy.
+ // If last damage is a (float) 3.2D (since the events use doubles), we cannot compare
9421f22 Make CustomArgumentType use parse(reader,source... - Machine-Maker
How hard its make more "dynamic" the getHandle for avoid declare that for every class? or is not related to the point of this PR?
Unrelated to this PR and effectively impossible unless we want to create CraftEntity<E extends nms.Entity> which seems like a lot
I will see what i can do for that poor armadillo. iirc the setter is also immediately reverted so there's no other way around
hey, it turns out it was actually an issue with the docker of the server, sorry for that
Generally am also on the side to expose a much as we need, as little as we can.
Overexposing internals for the sake of exposing them just makes your life harder when things change.
It is possible to get the InventoryType, but not MenuType.
Since there is a new (better) way to create views for players using MenuType, it would be nice to also be able to get it back from InventoryView after creating.
In order to ensure the API functions properly, some adjustments are needed. Iโve tested it, and currently, the API throws an error for any menu that doesnโt have a MenuType. This is an issue in scenarios like the playerโs inventory or with animals, where a MenuType is not applicable. In these cases, it results in an UnsupportedOperationException. If youโre aiming for this to be merged, Iโd recommend modifying the behavior to return null instead of throwing the exception. Otherwise, everything else seems fine. I'm not in love with the CraftContainer impl, but I think its pretty much unavoidable at this point sadly.
Given the changes required to make this API work effectively, this should be marked as Nullable.
fixes #11981
i think we should prevent this from happening as to me it seems the only reason this wasn't put where all the other water splash potion logic is is that the onHitBlock method was just convenient for mojang
In these cases, it results in an UnsupportedOperationException.
@Y2Kwastaken does it also throw inCraftContainerimplementation? It seems thatCraftContainer.getNotchInventoryTypenever returns null, so there should be no issues, but I want to verify it.
In these cases, it results in an UnsupportedOperationException.
@Y2Kwastaken does it also throw in
CraftContainerimplementation? It seems thatCraftContainer.getNotchInventoryTypenever returns null, so there should be no issues, but I want to verify it.
The naive conversion for Inventory's is fine and won't throw that exception to see why its thrown see AbstractContainerMenu#getType
The treasure map option lives in the world configuration no?
You should be able to just disable them for your void world.
I don't think we can really have a nicer option than just disabling them for the specific void worlds that do not generate structures. We could investigate if we can skip this kind of structure search in case the worlds chunk generator states defines 0 possible structures, but the world might already have structures to find so, I don't think that is a proper solution here either.
You are probably best off just using the config option for the specific world.
rather than just stating null if not applicable might be smart to list the cases where null is returned here as far as I'm aware this is the case only player and animal menus, but it might be worth poking around a bit more to make sure that I'm 100% right about this. Might just be nice to have a little paragraph not in the return statement being more involved on why this method might return null
In the custom chunk generator there is an Override that I set to true for the void worlds:
@Override
public boolean shouldGenerateStructures() {
return false;
}
Could you key off this and not have the villager code try? The issue is that as the plugin author, I can't edit this file or disable it unless there's an API - I assume there isn't one is there? (I could access the file directly and edit it, but that's a bit of a security no-no). Right now I have to inform users to edit this file to turn off treasure maps otherwise their server will crash, which isn't a great user experience and TBH I'm already getting blamed for this error. The text says it's not a Paper Error etc, etc.
I'm not sure about calling the super method here. It means the super method is called twice in a normal launch so two TargetHitEvent for example.
This will throw a NPE from the api since result is nullable
It also feels weird to only cancel interaction with fire but still handle redstone thing and everything called by Block#onProjectileHit. So maybe the responsibily should be moved to the ProjectileHitEvent.
but it's still a good idea to have an env for secret file path
Discussion Category: Ideas
Any other steps to replicate? tried with a beehive and a chest with data in it and works fine
getLifecycleManager().registerEventHandler(LifecycleEvents.COMMANDS, e -> {
e.registrar().register(Commands.literal("place").then(
Commands.argument("block_state", ArgumentTypes.blockState())
.executes(commandContext -> {
final BlockState state = commandContext.getArgument("block_state", BlockState.class);
final CommandSender sender = commandContext.getSource().getSender();
if (!(sender instanceof final Player player)) return 0;
final BlockState copy = state.copy(player.getLocation());
copy.update(true);
return 1;
})
).build()
);
});
with
/place chest{Items:[{Slot:0b,id:"minecraft:cake",count:1}]}
This is a client limitation that Mojang resolved as a "Won't Fix" https://bugs.mojang.com/browse/MC/issues/MC-277546, display entities must exist on the client with their full state before any interpolation can take place, it needs the previous state to interpolate to the new state, and interpolation starts on the next client tick.
This is simply not something the server can fix. The only viable solution for plugins is to wait some time (one server tick might not be enough, as this whole mechanism relies on client ticks), or for Paper to add API for the client end tick packet (which a modified client might also choose to not send), but that event would be very hot so it'd come with a "handle with care" label.
It seems this config always only applied to air even in the original PR that was mentioned (and in the javadocs of Frictional), if something like that is done it should be the same for all entities if possible and the javadocs changed
This will throw a NPE for empty stacks
The method on Material should be deprecated too
Minecarts don't care about frictionState if they're not on a rail, so they're already treated differently than other entities.
I wouldn't bother with this change if they didn't make minecarts work on rails underwater.
Currently:
- minecarts on rails in air respect
frictionState, - minecarts on rails in water don't respect
frictionState. - minecarts not on rails don't respect
frictionState.
I think minecarts should respect frictionState on rails regardless of water so map makers can set them off at a specific speed without worrying about them being treated differently in an underwater section of the railway.
It's a unique situation to minecarts. I don't think other entities not ignoring water needs to be considered unless this change evolves into adding a water friction flag.
Yep and it's useful
Discussion Category: Ideas
This computation is flawed anyway since it doesn't take in account the recent damage modifier added by Spigot (freezing) accounted in Vanilla. So the armor generally take less damage in some environment.
For example with a datapack that clear the #bypasses_armor damage type tag and add the player to the #freeze_hurts_extra_types entity type tag.
Expected behavior
beacons will not break
Observed/Actual behavior
beacons break, they do not drop item
Steps/models to reproduce
- place a beacon
- cancell PlayerInteractEvent using plugin:
@EventHandler public void PlayerInteractEvent(PlayerInteractEvent event) { event.setCancelled(true); } - go in survival mode and try to break beacon
Plugin and Datapack List
testplugin (what I used for cancelling block event)
Paper version
1.21.4-185-main@0a6e743 (2025-02-26T13:10:43Z) (Implementing API version 1.21.4-R0.1-SNAPSHOT)
Other
No response
I cannot reproduce this, the beacon does not break for me.
Added a new CreativeModeTab API class and corresponding registry, deprecated the old creative category api in favour of this new one.
Applies id to blockstate tag when not provided, fixes #11700
Is your feature request related to a problem?
Mojang added a new packet in 1.21.3, ServerboundClientTickEndPacket, to let the server know when a client-sided tick ends. Some features, namely display entity interpolation, are wholly dependent on the client's tick loop, not the server's. Currently, it is impossible for a client to tell if it is safe to perform transformations on a display entity and having the guarantee that it will be interpolated expectedly.
Describe the solution you'd like.
A ClientTickEndEvent that is called when the server receives the aforementioned ServerboundClientTickEndPacket.
Describe alternatives you've considered.
Delaying applying transformations to a display entity for an arbitrary amount of time (one server tick might not be enough to guarantee the client will interpolate the changes) (yuck), or using internals to listen to the packet being received (yucker).
Other
I recognise the event would be very hot, with potential...
My thoughts while testing was that it being cancellable isn't great due to the mentioned spam and desync issue, it's likely the reason there isn't a setter in the api for the current state
Thank you for testing!
You're absolutely right. Since most of the desired functionality can already be achieved through PlayerFishEvent, I'll remove the cancelable implementation ๐
After re-testing, I confirmed that everything works perfectly. If nothing has been overlooked, then this should be complete๐
https://github.com/user-attachments/assets/3c847469-9a7e-42a0-a7be-15f39db6b8fb
Expected behavior
Projectile is expected to hit the entity, however, occasionally goes ignores the entity.
Observed/Actual behavior
The projectile completely ignores entities.
Steps/models to reproduce
I can consistently reproduce with an arrow or fishing rod in survival mode. It was impossible for me to reproduce this while in creative mode.
Latest version of Paper with a plugin to spawn the bot (no event listeners).
https://youtu.be/_Uk5kCJ3Z0o
https://youtu.be/B-FhIEWiy1Q
https://youtu.be/OPEVF-fKsdc
Plugin and Datapack List
Only 1 private plugin.
Paper version
This server is running Paper version 1.21.4-185-main@0a6e743 (2025-02-26T13:10:43Z) (Implementing API version 1.21.4-R0.1-SNAPSHOT)\nYou are running the latest version\nPrevious version: 1.21.4-177-e5a8ee8 (MC: 1.21.4)
Other
I attempted to fix this by using a task to manually check if bounding box between projectile and entities overlap, and this also failed.
I also cannot reproduce this on another computer. I test it some more later when I am back home.
Expected behavior
For example: If I set the worldborder to 2.5k radius and do /tp 500000 0 500000 I would be teleported to 2500 0 2500 instead of 500000 0 500000. Previous versions was like this until the latest one.
Observed/Actual behavior
When I set the worldborder to 2.5k radius and tped to 500000 0 500000, I was actually tped to that coordinate instead of 2500 0 2500.
Steps/models to reproduce
Just install the latest version of paper. Do /worldborder center 0 0, then /worldborder set 5000 and /tp 1000000 0 100000(or anything higher/outside the worldborder limit).
Plugin and Datapack List
[23:56:41 INFO]: โน Server Plugins (0):
[23:57:00 INFO]: There are 3 data pack(s) enabled: [vanilla (built-in)], [file/bukkit (world)], [paper (built-in)]
[23:57:00 INFO]: There are no more data packs available
Paper version
[23:57:21 INFO]: This server is running Paper version 1.21.4-185-main@0a6e743 (2025-02-26T13:10:43Z) (Implementing API version 1.21.4-R0.1-SNA...
Specifically used jspecify for arrays since paper is moving torwards it and either javax or jetbrains handle arrays differently.
Sooo...
I tested some more, turns out that this affects every block at coordinates 0 0 0, in my case there was a beacon. Dont know why I did not think of placing a different block there.
Should I close this issue or change title and description to be right?
After additional testing I've found that the predicate matching works unpredictably when used with shapeless recipes. I've converted the PR to a draft while I figure out the issue.
General approval, haven't tested it:tm:
I think I would prefer having getters for the two individually and to properly distinguish with who is pushing who, since there is an underlying order to it (?)
And lots of brackets missing, the whole thing could also go into some helper method in Level
[PaperMC/Paper] Pull request review comment: #11905 Fix BlockDestroyEvent not called for some blocks
Param names need fixing, same for others
[PaperMC/Paper] Pull request review comment: #11905 Fix BlockDestroyEvent not called for some blocks
LevelEvent.PARTICLES_DESTROY_BLOCK, same for others
Handle more case that would toggle the powered property once a block is placed:
- skull, copper bulb, bell, target block, note block
- wind charge on button/lever
- lighting strike on lightning rod only called the event for the transition 0 -> 15 and not 15 -> 0
The links should be in the deprecation message, not on the method as see links.
This way, they won't be directly visible when emitting the deprecation message.
SpawnCategory is an enum on both nms and bukkit. Entity type is a registry value, which feels really wrong to cache
* Attempt to roll out if the armadillo is not {@link State#IDLE}
* Attempt to roll up if the armadillo is {@link State#IDLE}
1d5e5a5 Document replacement for Skull owner profile me... - Warriorrrr
Tbh can't be sure what it is to make a better explanation, the only 5 vanilla usages are
- {"sound":"minecraft:ambient.basalt_deltas.additions","tick_chance":0.0111}
- {"sound":"minecraft:ambient.crimson_forest.additions","tick_chance":0.0111}
- {"sound":"minecraft:ambient.nether_wastes.additions","tick_chance":0.0111}
- {"sound":"minecraft:ambient.soul_sand_valley.additions","tick_chance":0.0111}
- {"sound":"minecraft:ambient.warped_forest.additions","tick_chance":0.0111}
They really seems like an addition to other sounds, and wiki doesn't have any more info than what's in this javadoc
Expected behavior
When loading a structure block over a filled container, the container should be overwritten so that the items inside the container are removed
Observed/Actual behavior
Items in containers overwritten by structure blocks drop on the ground, as though the inventory was broken, when it should have instead been overwritten
Steps/models to reproduce
Load a structure block over a container that contains items, like a chest or a dispenser. When the structure block loads, all of the items in that container will fall on the ground
Plugin and Datapack List
CoreProtect, LuckPerms, Gsit, Armor Stand editor, Dynmap, one custom datapack
Paper version
This server is running Paper version 1.21.4-150-main@46f4fda (2025-02-12T22:37:19Z) (Implementing API version 1.21.4-R0.1-SNAPSHOT)
Other
This issue does on occur in Vanilla or in Spigot
Applied requested changes
My colleague and I were looking to reproduce this bug and further our investigation of it. However, we cannot seem to reproduce the bug. I would like to request some guidance in the step of creating the plug-in. More specifically whether the class EntityKnockbackByEntityEvent needs an explicit declaration of the getHandlers() or getHandlerList() methods, taking into account the fact that the event classes that extend Event do not inherit these methods from said class, according to Paperโs website. While EntityKnockbackEvent possesses the referred methods, EntityKnockbackByEntityEvent lacks declarations for them. Is this supposed to happen? Documentation on Paperโs guide clearly states that entities lacking the getHandlerList() method cannot be listened to.
Reference:
https://docs.papermc.io/paper/dev/event-listeners
It walks up the class hierarchy to look for the handler list to use
On Fri, 28 Feb 2025 at 22:26, Afonso Mendonรงa Jacinto <
@.***> wrote:
My colleague and I were looking forward to reproducing this bug and
further our investigation of it. However, we cannot seem to reproduce the
bug. I would like to request some guidance in the step of creating the
plug-in. More specifically whether the class EntityKnockbackByEntityEvent
needs an explicit declaration of the getHandlers() or getHandlerList()
methods, taking into account the fact that the event classes that extend
Event do not inherit these methods from said class, according to Paperโs
website. While EntityKnockbackEvent possesses the referred methods,
EntityKnockbackByEntityEvent lacks declarations for them. Is this supposed
to happen? Documentation on Paperโs guide clearly states that entities
lacking the getHandlerList() method cannot be listened to.Reference:
https://docs.pape...
It walks up the class hierarchy to look for the handler list to use
On Fri, 28 Feb 2025 at 22:26, Afonso Mendonรงa Jacinto <
@.***> wrote:
My colleague and I were looking forward to reproducing this bug and
further our investigation of it. However, we cannot seem to reproduce the
bug. I would like to request some guidance in the step of creating the
plug-in. More specifically whether the class EntityKnockbackByEntityEvent
needs an explicit declaration of the getHandlers() or getHandlerList()
methods, taking into account the fact that the event classes that extend
Event do not inherit these methods from said class, according to Paperโs
website. While EntityKnockbackEvent possesses the referred methods,
EntityKnockbackByEntityEvent lacks declarations for them. Is this supposed
to happen? Documentation on Paperโs guide clearly states that entities
lacking the getHandlerList() metho...
Is your feature request related to a problem?
ItemStack#enchantWithLevels should allow using any level > 1 to enchant with (any level lower would effectively do nothing). The vanilla logic already allows this, there's just a level cap at 30 for some reason. Vanilla loot tables already use level 39, as seen in the end city treasure table.
Describe the solution you'd like.
ItemStack#enchantWithLevels and the ItemFactory equivalents should accept levels up to max int, as there is really no vanilla restriction to the method. The minimum value of 1 still makes sense, as calling it with 0 or lower would do nothing.
Describe alternatives you've considered.
Only alternatives currently for the desired functionality are calling game internals.
Other
No response
Thank you for your feedback, @electronicboy. I ended up replicating the bug with no issues whatsoever. I apologize for the initial confusion. Upon confirmation that the bug persists in version 1.21.4, my colleague and I will proceed to investigate matters further.
Resolves #12208 by removing the level range check on ItemFactory#enchantWithLevels. The old ItemFactory#enchantItem did not have a level range, and the vanilla method does not have a level range either. There isn't really any reason to have this. If desired, it could be capped with a lower bound of 1, but it doesn't seem necessary.
This is just because the attack does actually knockback the entity twice. Dealing damage does knockback (see nms.LivingEntity#hurtServer). Separately, mobs & players can deal additional knockback via the minecraft:attack_knockback attribute - this extra knockback is also dealt when players are sprinting, since sprinting increases attack knockback for players by 1.
These are two separate sources of knockback, so the event will be called twice.
Expected behavior
Calling Entity::new with a null Level within a custom implementation of Entity will create an Entity instance without requiring a costly Level object, useable for constructing packets which take an Entity as a parameter without huge overhead. The constructor will succeed even with a null Level.
Observed/Actual behavior
As of 2f58805, calling Entity::new in the described scenario throws a NullPointerException due to no null check being present for the Level in the recently merged custom despawn time system.
Steps/models to reproduce
Create a custom implementation of Entity, which passes a null Level to the super constructor. Create a new instance of the custom entity.
Plugin and Datapack List
None
Paper version
This server is running Paper version 1.21.4-187-main@1d5e5a5 (2025-02-28T19:53:30Z) (Implementing API version 1.21.4-R0.1-SNAPSHOT)
You are running the latest version
Previous version: 1.21-130-b1b5d4c (MC: 1.21)
Other
htt...
Although I would also be in favor of a null check here
I don't really see the point in having an entity without a world
If you are using the entity just to send packets you could just send the packets without the entity object itself
If you are using the entity just to send packets you could just send the packets without the entity object itself
I would prefer to not use an Entity object but some packet constructors (e.g. ClientboundSetPassengersPacket...) do not have a public constructor that does not take a nullable Entity as a parameter. Note all of the functionality used to manipulate the data serialized in this packet does not require a Level reference to use (e.g. Entity.passengers access is widened).
Good point
Maybe opening a pr about that would be worth it
What OP seems to be suggesting is that rather than the event being called twice, the expected behaviour would be that the event is called only once, only with increased force, compared to non-sprinting knockback events. A knockback event being called twice loses part of its' meaning and takes value away from the "knockback" attribute.
WHich is great, but, the server causes a knockback twice, there isn't any real ways of mitigating that without breaking behavior or trying to 'collect' it later, which is generally overly invasive and breaky at the same time
What prevents you from simply assigning the default world to the entity?
I am not particularly a friend of introducing code changes just for NMS usage given people using NMS are expected to deal with breaking changes like this.
Is the following theoretical scenario impossible?
When calling the EntityKnockbackByEntityEvent, since it inherits from EntityKnockbackEvent, it has the getCause() method, so it is possible to check what causes the Event. If it returns either SWEEP_ATTACK or ENTITY_ATTACK, and since EntityKnockbackEvent implements cancellable, could we cancel this knockback event? Since we already have the damage knockback. Only issue I can see, for now, is the amount of knockback. @electronicboy said that it was incremented when a player sprints, so I assume it will be associated with the event we pretend to cancel, and not with the damage knockback, so I fear the amount of knockback might become too little.
Is your feature request related to a problem?
There is currently a bug in vanilla, where the compass (and clocks, have not tested) goes crazy. They spin around like they have taken something.... this only happens in dimensions outside the "vanilla overworld".
Describe the solution you'd like.
Getting the bug fixed.
Describe alternatives you've considered.
There is a workaround, using resourcepack:
Other
I hope I posted this in the correct category.. since it's a vanilla bug - and not a paper bug.
I am pretty certain this is completely impossible for paper to fix.
The client hardcodes the dimension where the compass works to minecraft:overworld.
There is nothing we can do outside of lying to the client that a separate overworld is minecraft:overworld, which comes with a whole array of unfun given we'd desync the client from the server.
This should be reported to mojang.
The other thing or im missing something is the natural field for the dimension (who control bed works, compass and another things) https://minecraft.wiki/w/Dimension_type
I dont check but this was not based in the enchantment table? Based in the range of 1-30 also this PR now allow you pass 0 or negative levels (not sure how that works)
it's a hardcoded check on the dimension name
It was based on the enchantment table, but arbitrarily so, there is no such lower bound or upper bound on the actual method being called. 0 or negative levels gracefully do nothing.
It's also useful to note the internal method ItemFactory#enchantWithLevels relies on (EnchantmentHelper#enchantItem) is also used for the minecraft:enchant_with_levels item modifier, which doesn't have a level restriction. I.e. it using a range of [20, 39] levels for the minecraft:chests/end_city_treasure loot table, as mentioned in the PR's body.
I think that it's worth noting that you can only use levels 1-30 in a normal enchanting table, and that at higher levels (>= 100) you will not be able to get any enchants in vanilla.
What prevents you from simply assigning the default world to the entity?
This is the plan.
I am not particularly a friend of introducing code changes just for NMS usage given people using NMS are expected to deal with breaking changes like this.
It's worth noting that null world constructor has had a null check in Spigot since at least 1.8, and is only broken explicitly by Paper now in 1.24.4. Vanilla 1.24.4 does not even use the Level at all in the Entity constructor. In this case, the breaking change was not introduced by Mojang, it is a Paper-only issue. If this change was introduced by Mojang I would not expect Paper to fix it.
NMS is not API and we reserve ourselves the ability to modify internals in whatever way we see fit at any point in time, including mid version, such as this change.
"Fixing" this (even tho it is not a bug as stated before) would be simple, I am just not particularly supportive of changes to NMS like this because I do not want to set a precedent in the community that NMS was remotely stable and that issues like yours are something people can expect to be addressed by us.
I'll throw it at some more people in the team, given that some of our other diff in Entity does null-check the level and given the "fix" is so simple, but yea.
Stack trace
java.lang.RuntimeException: Failed to encode Minecraft Component: translation{key='chat.square_brackets', args=[empty[style={italic}, siblings=[io.papermc.paper.adventure.AdventureComponent@d7c3825c]]]}[style={color=aqua,hoverEvent=TypedHoverEvent[action=<action show_item>, value=net.minecraft.network.chat.HoverEvent$ItemStackInfo@9f802d36]}]; Value must be within range [1;99]: 169
at io.papermc.paper.adventure.WrapperAwareSerializer.lambda$deserialize$0(WrapperAwareSerializer.java:28) ~[paper-1.21.4.jar:1.21.4-DEV-1d5e5a5]
at com.mojang.serialization.DataResult$Error.getOrThrow(DataResult.java:287) ~[datafixerupper-8.0.16.jar:?]
at io.papermc.paper.adventure.WrapperAwareSerializer.deserialize(WrapperAwareSerializer.java:28) ~[paper-1.21.4.jar:1.21.4-DEV-1d5e5a5]
at io.papermc.paper.adventure.WrapperAwareSerializer.deserialize(WrapperAwareSerializer.java:13) ~[paper-1.21.4.jar:1.21.4-DEV-1d5e5a5]
at io.papermc.paper.adventure.PaperAdventure.asAdventure(Pape...
Instead of blowing up later (minecraft limits item stack amount between 1 and 99 inclusive)
Fixes #12213
I assume there used to be an upper bound of 64 but when 1.20.5 came out it was removed because someone wasn't sure what the new max item amount limit was
Preconditions.checkArgument(amount <= 99, "amount must be no greater than 99");
Maybe can be good add the range annotation to the amount. Also docs missing mention the limit
The ItemStack ctors/factory method did never enforce this amount, not prior to 1.20.4 either.
We actively decided not to include such a check as it was/is semi common to create an oversized ItemStack and send it off to Inventory#addItem, which correctly handles these items by splitting them.
For this case, we'd be able to throw a precondition in the ItemStack#asHoverEvent method given hover events always fail with oversized items anyway. The factory methods are to be left untouched.
A big issue is that many plugins end up doing stuff like using an oversized stack amount in order to let the server deal with splitting it out, we couldn't change such behaviour without breaking a whole host of plugins
ItemStack::asHoverEvent or better ItemFactory::asHoverEvent with a copy of the throw mention in the ItemStack method?
if not problem i can make the PR fot that :)
When the PlayerInteractEvent gets canceled, the destroyPos field won't be updated, meaning the block won't get broken because the position doesn't match in the check at ServerPlayerGamemode line 261. However, the default value for destroyPos is BlockPos.ZERO.
This leads to the condition returning to true if the player has not mined any blocks before, even if the interactevent was denied. The issue also happens if someone is allowed to break a block the first time, but is denied the second time, since the destroyPos will stay the same
This commit fixes #12196 by making the destroyPos nullable instead of using BlockPos.ZERO as a null value.
I'm not super familiar with how the breaking system works, so I'm not sure if this has an unintended side effect somewhere down the chain (did check all reads of destroyPos ofc). I did a fair bit of testing though and couldn't get it to break...
This is absolutely not the right fix and you seem to be confused about the block id with the block entity id (its block entity type key)
Okay i found a way to replicate this.
ItemStack itemStack = new ItemStack(Material.STICK, 200);
player.sendMessage(Component.text("Item1").appendSpace().append(itemStack.displayName()));
this code not use the ItemStack ItemStack::asHoverEvent or ItemFactory::asHoverEvent, the code provided fails because the displayName used in the ItemFactory use the NMS method for displayname who add the hoverevent internally for show the item and use the NMS methods nothing with the paper/bukkit side.
i think this make a little more hard fix and avoid mess (because cannot add a precondition for getDisplayName just for create an item over the limit if is used for split in inventory like lynx say)... unless wanna omit the hoverevent from NMS if the item has more size elements like.
public Component getDisplayName() {
MutableComponent mutableComponent = Component.empty().append...
Eh, I think we are fine with just documentation on the ItemStack#displayName.
I'd be interested in more input on whether documentation or a throw exception in adventure asHoverEvent is better.
Alright, talked this over with a few more team members. We are gonna be okay with a PR to allow a fallback for null level on the TIL logic.
Obviously for anyone reading this, this is a case-by-case decision and was made here specifically because
- it is a super small PR
- other paper diff in Entity respects a null level.
Feel free to open such a PR ๐