Since 19w08b, the Ender Dragon's vertical velocity when flying to a target node has been incorrect, causing erratic behavior and difficulties flying towards its target, flying back and forth around it. This is most obvious on its perching phase, but also during its hover phase, when it is seen flying back and forth repetitively around its nodes.
This issue is responsible of MC-271336, MC-271337, and in some ways to MC-197201 as the dragon would often fail to reach the player when charging it after a perch. Contrary to what those reports suggest, it is unrelated to the dragon phase mechanic or to any fix given in 19w08b, and must have been introduced in an internal rewrite.
An earlier report, MC-201937 described the same issue but was wrongfully ruled as invalid.
Expected behavior:
The dragon is able to fly up and dive down at the proper vertical velocity and reach its target with the shortest path possible, without needing to fly back and forth.
Steps to Reproduce:
There are several ways to reproduce it:
First way:
1. Go to the End, break all crystals and wait for the dragon to perch on the end podium
-> Notice how it roams back and forth while slowly descending to the podium
Second way:
1. Go to the End, break all crystals
2. Wait for it to perch, build a pillar with a significant height with respect to the end podium, several dozens of blocks away from the dragon, sufficiently far and close to it to charge you at the end of the perch
3. Stand on the pillar and Switch to survival mode
-> Notice how the dragon often fails to charge at the player and glides below the player
Third way (if you have sufficient knowledge of the Ender Dragon's AI):
1. Go to the End
2. Stand by a dragon AI pathfinding node
3. Wait until the dragon pathfinds to it
-> Notice how the dragon circles back and forth and around the target node
Code Analysis:
Before 19w08b, there is a portion of code in the method directing the dragon's movement towards its target (called "aiStep" in mojmaps) which adjusted the vertical velocity of the ender dragon by a certain amount:
(Decompiled from Release 1.12, MCP mappings)
Vec3d vec3d = iphase.getTargetLocation();
if (vec3d != null)
{
double d6 = vec3d.xCoord - this.posX;
double d7 = vec3d.yCoord - this.posY;
double d8 = vec3d.zCoord - this.posZ;
double d3 = d6 * d6 + d7 * d7 + d8 * d8;
float f5 = iphase.getMaxRiseOrFall();
d7 = MathHelper.clamp(d7 / (double)MathHelper.sqrt(d6 * d6 + d8 * d8), (double)(-f5), (double)f5);
this.motionY += d7 * 0.10000000149011612D;
....However, in versions after 19w08b, the same portion of code shows a tiny mistake:
(Decompiled from Release 1.20.6, Mojmaps, in EnderDragon::aiStep)
Vec3 vec32 = dragonPhaseInstance.getFlyTargetLocation();
if (vec32 != null) {
double d = vec32.x - this.getX();
double e = vec32.y - this.getY();
double j = vec32.z - this.getZ();
double k = d * d + e * e + j * j;
float l = dragonPhaseInstance.getFlySpeed();
double m = Math.sqrt(d * d + j * j);
if (m > 0.0) {
e = Mth.clamp(e / m, (double)(-l), (double)l);
}
this.setDeltaMovement(this.getDeltaMovement().add(0.0, e * 0.01, 0.0));
....As shown here, the last line which modifies its vertical velocity, shows a mistake on the scaling factor (0.01 instead of 0.1).
The fix would be to change that scaling factor back to 0.1, which would fix all aforementioned issues related to the dragon behavior.
Environment
Windows 11, Java 17, Java 21
Linked issues
relates to 2
Attachments
Comments 20
Can confirm in 1.21.3 and 24w44a, it's worth noting that MC-158205, fixed in yesterday's snapshot, appeared in the same version as this bug.
Note that the ramifications of this bug are quite large. Fixing this typo would virtually invalidate all strategies of speedrunning and one cycling.
One cycling was possible before the bug was introduced, it may actually be faster to do even though it's more difficult, since you wouldn't have to wait for the dragon all the time, and the dragon would descend to the portal more often thanks to the fixed AI.
Well, believe it or not, I use fabric-mixin, just change a single number, then I fix MC197201, MC271336, MC271337, MC272431 successfully. I test this in 26.1.2 and it works perfectly.
All the four bugs are all about Enderdragon’s incorrect y velocity, in net.minecraft.world.entity.boss.enderdragon EnderDragon.class. Previous comment mentioned that in the picture 屏幕截图 2025-12-31 164529.png I uploaded at 20251231, about line 217, public void aiStep(){}, this line is not correct:
this.setDeltaMovement(this.getDeltaMovement().add((double)0.0F, ydd * 0.01, (double)0.0F)),
ydd * 0.01 should be changed into ydd * 0.1.
I use fabric-mixin method to achieve the change needed above.
@Mixin({EnderDragon.class})
public class EnderDragonMixin {
public EnderDragonMixin() {
}
@Redirect(
method = {"aiStep"},
at = @At(
value = "INVOKE",
target = "Lnet/minecraft/world/phys/Vec3;add(DDD)Lnet/minecraft/world/phys/Vec3;",
ordinal = 0
)
)
private Vec3 modifyYddAddition(Vec3 instance, double x, double y, double z) {
return instance.add(x, y * (double)10.0F, z);
}
}Result: Now that MC197201, MC271336, MC271337 solved, so MC272431 also done.
Now Enderdragon perches normally as that in Java 1.9-1.13 and Bedrock. Fixd MC271336 and MC271337.
Now Enderdragon can dive-fireball to player as that in Java 1.9-1.13 and Bedrock. Fixd MC197201.
For MOJANG, it’s much easier to fix these 4 bugs because they just need to change ydd * 0.01 into ydd * 0.1.
I use mixin method and ask for AI Deepseek to help me to adjust code, and I solve MC197201, MC271336, MC271337, MC272431 for just a few hours. I really don’t understand why these bugs don’t get fixed from 1.14 to 26.2!
I fix MC197201, MC271336, MC272431 by changing a single number. Which means in net.minecraft.world.entity.boss.enderdragon Enderdragon.class, Mojang only needs to change this.setDeltaMovement(this.getDeltaMovement().add((double)0.0F, ydd * 0.01, (double)0.0F)) to this.setDeltaMovement(this.getDeltaMovement().add((double)0.0F, ydd * 0.1, (double)0.0F)).
My fix code is on https://github.com/EnderdragonGateway/important-bug-fix .
Before the fix: Dive fireball fails (MC197201, 272431), Perch too slow (MC271336, 272431).
After fix to what it should be: Dive Fireball successes, Perch normally. Like what in Bedrock Edition and Java 1.9-1.13. Also this fix don’t break other dragon behaviours like node flying and dragon phase, et.
You may say speedruning has 0 and 1 cycle. However, in more than 75% cases, y speed is so slow that it make dragon perching 3 times longer, which will waste so much time on waiting.
Like mining fatigue in MC279819, this is also caused by adding an extra 0 by mistake. But I really don’t know why it’s never fixed since 1.14 and do not synchronous to Bedrock if Mojang wants to design this. It’s really that hard to remove a single number in the code? The programmer who write this code in 1.14 is absolutely irresponsible at work!
This relates to 3 bugs(197201、271336、271337) for the same reason: y speed is too slow to fly to target spot in time, but X/Z speed is correct. Because this.setDeltaMovement(this.getDeltaMovement().add((double)0.0F, ydd * 0.1, (double)0.0F)) was written as this.setDeltaMovement(this.getDeltaMovement().add((double)0.0F, ydd * 0.01, (double)0.0F)) by mistake in 19w08b. And it’s not introduced by fixing any bugs in the snapshot, but just a manual typing mistake by a irresponsible staff of Mojang.
MC197201: Target is player, but Jean’s y speed is too slow to reach player, which leads to the failure of diving fireball. The boss can’t even touch me after 1.14. And that’s so boring because Mojang can’t even make boss fighting work well in the main thread.
MC271336: Target is bedrock fountain, but Jean’s y speed is too slow to diving down, which leads to the strange perching back and forward.
MC271337: Target is knot, but Jean’s y speed is too slow to get there in time, which makes Jean flying around these knots.
Again: Like mining fatigue in MC279819, this is also caused by adding an extra 0 by mistake. But I really don’t know why it’s never fixed since 1.14, and it’s never synchronous to Bedrock if Mojang really wants to design this. It’s really that hard to remove a single number in the code? The programmer who write this code in 1.14 is absolutely irresponsible at work!
can confirm for 1.20.6