1.21.7
The 1.21.5 / 1.21.6 / 1.21.7 Update
It’s been a hot minute since the last post, but here we are!
As always, backups are absolutely mandatory.
After upgrading your world to 1.21.7, you cannot downgrade back to a lower version!
We can also give you a pinky promise that it won’t take this long to exit the experimental phase again, and we have already addressed this inflexibility in build channels — more on that below and on our Discord.
We would like to thank everyone that worked on this update:
- Gerrygames for his work on Velocity
- @electronicboy
- @jmp
- kennytv
- Lulu13022002
- @lynxplay
- @Machine Maker
- @Noah
- @Owen1212055
- @MiniDigger
- SpaceWalkerRS
- @Spottedleaf
If you’d like to support PaperMC as a whole, you can find more information at papermc.io/sponsors.
Release Channel Changes
Among other changes — and the new V3 of our Downloads API — release channels have changed to:
alpha: Equivalent to the priorexperimentallabelbeta: New middle-point for builds that aren’t entirely unstable but partially unfinished (e.g., missing config options or, as with the long 1.21.5 phase, missing datafixer changes)stable: Equivalent to the priordefaultlabel — always make sure you stay up-to-date with new builds here, as important fixes and changes continue being pushedrecommended: Unused in Paper, but currently used for Velocity releases. If this ever changes, we will announce it beforehand.
force-upgrade Startup Param
Time and time again, issues in old world upgrade code are found, with fairly important issues having been fixed by Mojang or Paper in recent versions.
If you use the --forceUpgrade startup flag, you lose out on fixes from future versions, since it forcefully loads and upgrades all worlds and entities.
Only if you are updating from a version before 1.13 should you use force-upgrade, as it can save some performance during expensive conversions.
In that case, the safer option is to force-upgrade on Paper 1.21.7, but you should otherwise never force upgrade without a specific reason.
Reloading with /reload
For many years, the Bukkit reload mechanic has been unofficially deprecated, with big warnings whenever someone triggers it via /reload or related API methods.
We are officially deprecating it, to be removed at a later time.
The /reload command will now point to /minecraft:reload, a reload mechanic that is and will stay supported, as it’s a Vanilla mechanic.
Users should stop and start the server when making changes that require a restart.
Developers should use hot reloading or full restarts instead. For guidance on hotswap, see the pinned messages in our #paper-dev Discord channel.
For Developers
Configuration Phase API & Deprecation of PlayerLoginEvent
The use of PlayerLoginEvent is now deprecated.
This change has been made to allow us to start developing API for the Configuration Phase in Minecraft.
This phase most notably allows dialogs to be sent to the player before they join the game, or resource packs to be sent earlier.
This is an early warning: while PlayerLoginEvent will remain available for now, breaking changes may be introduced in the future.
Plugins relying on this event should begin migrating as soon as possible.
What You Should Use Instead
Please migrate to the following events based on your needs:
-
PlayerConnectionValidateLoginEvent
Use this when controlling whether a player should be able to join the game — i.e., logic that previously prevented login viaPlayerLoginEvent.
This event fires twice: once when logging in, and once when exiting the configuration phase.
You do not have access to aPlayerentity here, only aPlayerProfile. -
PlayerServerFullCheckEvent
Replaces the commonPlayerLoginEventuse case that allowed players to join even if the server was full.
Other Configuration Phase Related Events
The configuration phase occurs between logging into a server and fully joining a world.
During this time, server data — including tags and custom registry elements — is sent to the client.
You can send custom data or apply a resource pack before they exit the loading screen.
You can also throw a player back into the configuration phase using:
PlayerGameConnection#reenterConfigurationPlayerConfigurationConnection#completeReconfiguration
New events include:
PlayerConnectionInitialConfigureEvent(when joining initially)AsyncPlayerConnectionConfigureEventPlayerConnectionReconfigureEvent(when re-entering configuration)
Dialog API
Dialog API will be merged into 1.21.7 soon — we’ll post a dev announcement once it’s in!
You can see its current status here:
You will also be able to open dialogs via a new click event type using ClickEvent.openDialog.
For custom click actions, you may use PlayerCustomClickEvent, but the preferred option is to directly pass a callback in DialogAction.customClick, which will be run when the player clicks the specified element.
ItemStack Config Serialization
ItemStacks now use the SNBT format when written to configuration files.
This allows ItemStacks to run upgrades through Minecraft’s data fixers for more reliable migrations.
Direct serialization of ItemMeta (storing raw ItemMeta in a config) is now considered unsupported and may be removed in the future.
If you want to serialize items to other formats, such as JSON or raw bytes, the (de)serializeStack methods on UnsafeValues may be of interest.
Cow and Splash Potion Type Changes
Cow inheritance has been adjusted to fit Vanilla:
MushroomCowno longer extendsCow, but the newAbstractCowCownow extendsAbstractCow
Additionally, the potion entity type has been split into splash and lingering potion entities.
You must now use those specific entity types and can no longer swap between them without creating a new entity.
Other API Additions and Changes
A small selection of recent API additions that may be interesting:
- Registry events for modifying or adding custom cat, chicken, cow, frog, pig, and wolf variants, as well as damage types and paintings
Player#openVirtualSignto open unplaced signs (changes viaUncheckedSignChangeEvent)Entity#getPickItemStackto get the spawn egg/item for an entity when using the pick actionHumanEntity#setCooldown(Key, int ticks)and getter for grouped cooldowns (not per-item)Server#sendRichMessage(String)andsendPlainMessagefor broadcasting and logging text- New events including:
PlayerMapFilledEventPlayerPickBlockEventPlayerPickEntityEventVaultChangeStateEventClientTickEndEventEntityEquipmentChangedEventEntityAttemptSmashAttackEventPlayerClientLoadedWorldEventEntityEffectTickEvent