diff --git a/paper-api/src/main/java/io/papermc/paper/event/entity/EntityChangeWorldEvent.java b/paper-api/src/main/java/io/papermc/paper/event/entity/EntityChangeWorldEvent.java
new file mode 100644
index 000000000000..7e73cc0f1dff
--- /dev/null
+++ b/paper-api/src/main/java/io/papermc/paper/event/entity/EntityChangeWorldEvent.java
@@ -0,0 +1,45 @@
+package io.papermc.paper.event.entity;
+
+import org.bukkit.World;
+import org.bukkit.entity.Entity;
+import org.bukkit.event.HandlerList;
+import org.bukkit.event.entity.EntityEvent;
+import org.jetbrains.annotations.ApiStatus;
+import org.jspecify.annotations.NullMarked;
+
+/**
+ * Called when an entity switches to another world.
+ *
+ * Not called for players, use {@link org.bukkit.event.player.PlayerChangedWorldEvent} to handle player world switches.
+ */
+@NullMarked
+public final class EntityChangeWorldEvent extends EntityEvent {
+
+ private static final HandlerList HANDLER_LIST = new HandlerList();
+
+ private final World from;
+
+ @ApiStatus.Internal
+ public EntityChangeWorldEvent(final Entity entity, final World from) {
+ super(entity);
+ this.from = from;
+ }
+
+ /**
+ * Gets the world that the entity switched from.
+ *
+ * @return the previous world of the entity
+ */
+ public World getFrom() {
+ return from;
+ }
+
+ @Override
+ public HandlerList getHandlers() {
+ return HANDLER_LIST;
+ }
+
+ public static HandlerList getHandlerList() {
+ return HANDLER_LIST;
+ }
+}
diff --git a/paper-server/patches/features/0003-Moonrise-optimisation-patches.patch b/paper-server/patches/features/0003-Moonrise-optimisation-patches.patch
index a94fd82ee50c..f33feba7c4d7 100644
--- a/paper-server/patches/features/0003-Moonrise-optimisation-patches.patch
+++ b/paper-server/patches/features/0003-Moonrise-optimisation-patches.patch
@@ -32059,7 +32059,7 @@ index e3644ac93ffc2cfdc5e788456e9d54a9975272f3..6111ecdfaac7c003859040d49d91cc74
+ // Paper end - block counting
}
diff --git a/net/minecraft/world/entity/Entity.java b/net/minecraft/world/entity/Entity.java
-index 5fb9ac4b0fdd245207c15677795566c81b629a20..5c7b5a4e78457b691bae727844d63212949e7cf6 100644
+index 3b843980bfa3268aa2debd34fc91fba86020c66f..88139fabe0ccab03d156f0d10806b52b22fa41d4 100644
--- a/net/minecraft/world/entity/Entity.java
+++ b/net/minecraft/world/entity/Entity.java
@@ -166,7 +166,7 @@ public abstract class Entity
@@ -32532,7 +32532,7 @@ index 5fb9ac4b0fdd245207c15677795566c81b629a20..5c7b5a4e78457b691bae727844d63212
}
public InteractionResult interact(final Player player, final InteractionHand hand, final Vec3 location) {
-@@ -4579,15 +4821,17 @@ public abstract class Entity
+@@ -4580,15 +4822,17 @@ public abstract class Entity
}
public Iterable getIndirectPassengers() {
@@ -32558,7 +32558,7 @@ index 5fb9ac4b0fdd245207c15677795566c81b629a20..5c7b5a4e78457b691bae727844d63212
}
public int countPlayerPassengers() {
-@@ -4898,6 +5142,15 @@ public abstract class Entity
+@@ -4899,6 +5143,15 @@ public abstract class Entity
}
public final void setPosRaw(double x, double y, double z, boolean forceBoundingBoxUpdate) {
@@ -32574,7 +32574,7 @@ index 5fb9ac4b0fdd245207c15677795566c81b629a20..5c7b5a4e78457b691bae727844d63212
if (!checkPosition(this, x, y, z)) {
return;
}
-@@ -5060,6 +5313,12 @@ public abstract class Entity
+@@ -5061,6 +5314,12 @@ public abstract class Entity
@Override
public final void setRemoved(final Entity.RemovalReason reason, org.bukkit.event.entity.EntityRemoveEvent.@Nullable Cause cause) { // CraftBukkit - add Bukkit remove cause
@@ -32587,7 +32587,7 @@ index 5fb9ac4b0fdd245207c15677795566c81b629a20..5c7b5a4e78457b691bae727844d63212
org.bukkit.craftbukkit.event.CraftEventFactory.callEntityRemoveEvent(this, cause); // CraftBukkit
final boolean alreadyRemoved = this.removalReason != null; // Paper - Folia schedulers
if (this.removalReason == null) {
-@@ -5071,7 +5330,7 @@ public abstract class Entity
+@@ -5072,7 +5331,7 @@ public abstract class Entity
this.stopRiding();
}
@@ -32596,7 +32596,7 @@ index 5fb9ac4b0fdd245207c15677795566c81b629a20..5c7b5a4e78457b691bae727844d63212
this.levelCallback.onRemove(reason);
this.onRemoval(reason);
// Paper start - Folia schedulers
-@@ -5109,7 +5368,7 @@ public abstract class Entity
+@@ -5110,7 +5369,7 @@ public abstract class Entity
public boolean shouldBeSaved() {
return (this.removalReason == null || this.removalReason.shouldSave())
&& !this.isPassenger()
diff --git a/paper-server/patches/features/0016-Optimise-EntityScheduler-ticking.patch b/paper-server/patches/features/0016-Optimise-EntityScheduler-ticking.patch
index 985f33c4ae06..cf0f93ac7d03 100644
--- a/paper-server/patches/features/0016-Optimise-EntityScheduler-ticking.patch
+++ b/paper-server/patches/features/0016-Optimise-EntityScheduler-ticking.patch
@@ -66,10 +66,10 @@ index 482b428cab996c19664b57c341c55db5a66a6387..bd5efcf1dee77c204bf29ef4693ac541
io.papermc.paper.adventure.providers.ClickCallbackProviderImpl.ADVENTURE_CLICK_MANAGER.handleQueue(this.tickCount); // Paper
io.papermc.paper.adventure.providers.ClickCallbackProviderImpl.DIALOG_CLICK_MANAGER.handleQueue(this.tickCount); // Paper
diff --git a/net/minecraft/world/entity/Entity.java b/net/minecraft/world/entity/Entity.java
-index b5503b25ef58c7b19592c2e90649c774b155a17b..ffbb54a8576877f2b477615d1e2f84457fdf31e1 100644
+index f91e14cceeb435e273d61befd078714388e25664..ebbc0113d3aeb23bf9ccef7b48b7bbab64625282 100644
--- a/net/minecraft/world/entity/Entity.java
+++ b/net/minecraft/world/entity/Entity.java
-@@ -5385,6 +5385,11 @@ public abstract class Entity
+@@ -5386,6 +5386,11 @@ public abstract class Entity
this.getBukkitEntity().taskScheduler.retire();
}
// Paper end - Folia schedulers
diff --git a/paper-server/patches/sources/net/minecraft/world/entity/Entity.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/Entity.java.patch
index e1b8ab770c21..3cc6b6c6a731 100644
--- a/paper-server/patches/sources/net/minecraft/world/entity/Entity.java.patch
+++ b/paper-server/patches/sources/net/minecraft/world/entity/Entity.java.patch
@@ -1589,6 +1589,14 @@
for (Entity newPassenger : newPassengers) {
newPassenger.startRiding(newEntity, true, false);
+@@ -3217,6 +_,7 @@
+ transition.postTeleportTransition().onTransition(newEntity);
+ this.teleportSpectators(transition, oldLevel);
+ profiler.pop();
++ new io.papermc.paper.event.entity.EntityChangeWorldEvent(newEntity.getBukkitEntity(), oldLevel.getWorld()).callEvent(); // Paper - Add EntityChangeWorldEvent
+ return newEntity;
+ }
+
@@ -3232,6 +_,13 @@
private TeleportTransition calculatePassengerTransition(final TeleportTransition transition, final Entity passenger) {
float passengerYRot = transition.yRot() + (transition.relatives().contains(Relative.Y_ROT) ? 0.0F : passenger.getYRot() - this.getYRot());