Skip to content

Fix initiateRespawn(Collection<EnderCrystal>) not respecting empty crystal lists - #14254

Open
CozREV wants to merge 4 commits into
PaperMC:mainfrom
CozREV:fix/14183-dragonbattle
Open

CozREV wants to merge 4 commits into
PaperMC:mainfrom
CozREV:fix/14183-dragonbattle

Conversation

@CozREV

@CozREV CozREV commented Sep 14, 2026

Copy link
Copy Markdown

DragonBattle#initiateRespawn(Collection<EnderCrystal>) would start
the respawn sequence (setting phase to START) even when the filtered
crystal list ended up empty, since EnderDragonFight#respawnDragon
doesn't validate its input. The next tick would then immediately
abort the sequence back to NONE, since EnderDragonFight#tick requires
non-empty respawnCrystals to proceed.

This adds a check for an empty filtered crystal list before calling
respawnDragon, returning false instead of silently starting and then
aborting the sequence.

Only addresses the initiateRespawn(Collection) case described in
the issue — the no-arg initiateRespawn() and resetCrystals() cases
are still open.

Verified this compiles cleanly (./gradlew compileJava) and the dev
server boots correctly with the change. Have not verified in a live
client yet.

Related to #14183

Prevent Ender Dragon respawn attempts from running when no valid crystals remain in the current world. This avoids invalid respawn logic after the dragon has been killed and keeps initiateRespawn consistent with the battle state.
@CozREV
CozREV requested a review from a team as a code owner September 14, 2026 13:34
@github-project-automation github-project-automation Bot moved this to Awaiting review in Paper PR Queue Sep 14, 2026
@Doc94

Doc94 commented Sep 14, 2026

Copy link
Copy Markdown
Member

The issue with this change is the javadoc of the method still mention null/empty like a valid input for make the respawn cannot be canceled (destroy the crystals).

Maybe the fix can be add a temp field in the NMS EnderDragonFight like ignoreEmptyCrystalsToRespawn set that true when API try to pass an empty crystals, make the tick not abort respawn if the field is true and in the END step of respawn set that again to false.

…he call

Per DragonBattle#initiateRespawn's javadoc, a null or empty crystal
list is meant to make the respawn sequence uncancellable, not invalid.
The previous fix incorrectly rejected empty lists at the API layer,
contradicting documented behavior (per Doc94's review).

This instead adds ignoreEmptyCrystalsToRespawn on EnderDragonFight,
set when initiateRespawn is called with empty/null crystals, so
EnderDragonFight#tick no longer aborts an intentionally-uncancellable
respawn just because there are no crystals to check. The flag resets
once the respawn sequence reaches END.
Adds a flag on EnderDragonFight that, when set, prevents tick() from
aborting a respawn sequence just because respawnCrystals is empty.
This preserves the documented behavior of initiateRespawn(Collection)
with a null/empty list: an intentionally uncancellable respawn.
@CozREV

CozREV commented Sep 15, 2026

Copy link
Copy Markdown
Author

@Doc94 Thanks for pointing it out, and you're right about the javadoc. Empty or null crystals is documented as intentionally making the respawn uncancellable, not something to reject. Reverted the earlier fix and added the ignoreEmptyCrystalsToRespawn flag on EnderDragonFight like you suggested: set to true when initiateRespawn gets empty/null crystals, tick() skips the abort in that case, resets to false once respawn hits END.
Compiles cleanly. Haven't tested it live in a client, happy to if that's needed before review.

@Doc94

Doc94 commented Sep 15, 2026

Copy link
Copy Markdown
Member

Thanks @CozREV if you can check the CONTRIBUTION file and move this change from feature to simple patchs can review this later.

Per Doc94's feedback, this belongs as a simple per-file patch modification rather than a standalone feature patch.
@CozREV

CozREV commented Sep 15, 2026

Copy link
Copy Markdown
Author

@Doc94, moved it to a simple per-file patch on EnderDragonFight.java instead of a standalone feature patch

@Doc94 Doc94 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The // Paper comments maybe can include a detail like
// Paper - Support for disable cancel dragon respawn if not crystals are found

Now i see the implementation maybe the field can has a better name, related to the "abortRespawnSequence" if any wanna suggest another name if not its fine...

this.abortRespawnSequence();
return;
}
-

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

unnecesary diff

public boolean initiateRespawn(Collection<EnderCrystal> crystals) { // todo doesn't seems to work without crystals
public boolean initiateRespawn(Collection<EnderCrystal> crystals) {
if (this.hasBeenPreviouslyKilled() && this.getRespawnPhase() == RespawnPhase.NONE) {
// Copy from EnderDragonFight#tryRespawn for generate exit portal if not exists

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please keep this, is a reference if the Mojang change any.

@github-project-automation github-project-automation Bot moved this from Awaiting review to Changes required in Paper PR Queue Sep 15, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Changes required

Development

Successfully merging this pull request may close these issues.

2 participants