--- a/net/minecraft/world/level/chunk/status/ChunkStatusTasks.java
+++ b/net/minecraft/world/level/chunk/status/ChunkStatusTasks.java
@@ -35,7 +_,7 @@
         WorldGenContext worldGenContext, ChunkStep step, StaticCache2D<GenerationChunkHolder> cache, ChunkAccess chunk
     ) {
         ServerLevel serverLevel = worldGenContext.level();
-        if (serverLevel.getServer().getWorldData().worldGenOptions().generateStructures()) {
+        if (serverLevel.serverLevelData.worldGenOptions().generateStructures()) { // CraftBukkit
             worldGenContext.generator()
                 .createStructures(
                     serverLevel.registryAccess(),
@@ -182,7 +_,7 @@
             if (protoChunk instanceof ImposterProtoChunk imposterProtoChunk) {
                 wrapped = imposterProtoChunk.getWrapped();
             } else {
-                wrapped = new LevelChunk(serverLevel, protoChunk, chunk1 -> postLoadProtoChunk(serverLevel, protoChunk.getEntities()));
+                wrapped = new LevelChunk(serverLevel, protoChunk, chunk1 -> postLoadProtoChunk(serverLevel, protoChunk.getEntities(), protoChunk.getPos())); // Paper - rewrite chunk system
                 generationChunkHolder.replaceProtoChunk(new ImposterProtoChunk(wrapped, false));
             }
 
@@ -196,9 +_,60 @@
         }, worldGenContext.mainThreadExecutor());
     }
 
-    private static void postLoadProtoChunk(ServerLevel level, List<CompoundTag> entityTags) {
+    public static void postLoadProtoChunk(ServerLevel level, List<CompoundTag> entityTags, ChunkPos pos) { // Paper - public // Paper - rewrite chunk system - add ChunkPos param
         if (!entityTags.isEmpty()) {
-            level.addWorldGenChunkEntities(EntityType.loadEntitiesRecursive(entityTags, level, EntitySpawnReason.LOAD));
-        }
-    }
+            // CraftBukkit start - these are spawned serialized (DefinedStructure) and we don't call an add event below at the moment due to ordering complexities
+            level.addWorldGenChunkEntities(EntityType.loadEntitiesRecursive(entityTags, level, EntitySpawnReason.LOAD).filter((entity) -> {
+                boolean needsRemoval = false;
+                net.minecraft.server.dedicated.DedicatedServer server = level.getCraftServer().getServer();
+                if (!level.getChunkSource().spawnFriendlies && (entity instanceof net.minecraft.world.entity.animal.Animal || entity instanceof net.minecraft.world.entity.animal.WaterAnimal)) {
+                    entity.discard(null); // CraftBukkit - add Bukkit remove cause
+                    needsRemoval = true;
+                }
+                checkDupeUUID(level, entity); // Paper - duplicate uuid resolving
+                return !needsRemoval;
+            }), pos); // Paper - rewrite chunk system
+            // CraftBukkit end
+        }
+    }
+
+    // Paper start - duplicate uuid resolving
+    // rets true if to prevent the entity from being added
+    public static boolean checkDupeUUID(ServerLevel level, net.minecraft.world.entity.Entity entity) {
+        io.papermc.paper.configuration.WorldConfiguration.Entities.Spawning.DuplicateUUID.DuplicateUUIDMode mode = level.paperConfig().entities.spawning.duplicateUuid.mode;
+        if (mode != io.papermc.paper.configuration.WorldConfiguration.Entities.Spawning.DuplicateUUID.DuplicateUUIDMode.WARN
+            && mode != io.papermc.paper.configuration.WorldConfiguration.Entities.Spawning.DuplicateUUID.DuplicateUUIDMode.DELETE
+            && mode != io.papermc.paper.configuration.WorldConfiguration.Entities.Spawning.DuplicateUUID.DuplicateUUIDMode.SAFE_REGEN) {
+            return false;
+        }
+        net.minecraft.world.entity.Entity other = level.getEntity(entity.getUUID());
+
+        if (other == null || other == entity) {
+            return false;
+        }
+
+        if (mode == io.papermc.paper.configuration.WorldConfiguration.Entities.Spawning.DuplicateUUID.DuplicateUUIDMode.SAFE_REGEN && other != null && !other.isRemoved()
+            && java.util.Objects.equals(other.getEncodeId(), entity.getEncodeId())
+            && entity.getBukkitEntity().getLocation().distance(other.getBukkitEntity().getLocation()) < level.paperConfig().entities.spawning.duplicateUuid.safeRegenDeleteRange
+        ) {
+            entity.discard(null);
+            return true;
+        }
+        if (!other.isRemoved()) {
+            switch (mode) {
+                case SAFE_REGEN: {
+                    entity.setUUID(java.util.UUID.randomUUID());
+                    break;
+                }
+                case DELETE: {
+                    entity.discard(org.bukkit.event.entity.EntityRemoveEvent.Cause.DISCARD);
+                    return true;
+                }
+                default:
+                    break;
+            }
+        }
+        return false;
+    }
+    // Paper end - duplicate uuid resolving
 }
