diff --git a/patches/unapplied/server/Do-not-run-raytrace-logic-for-AIR.patch b/patches/server/Do-not-run-raytrace-logic-for-AIR.patch
similarity index 100%
rename from patches/unapplied/server/Do-not-run-raytrace-logic-for-AIR.patch
rename to patches/server/Do-not-run-raytrace-logic-for-AIR.patch
diff --git a/patches/unapplied/server/Don-t-lookup-fluid-state-when-raytracing.patch b/patches/server/Don-t-lookup-fluid-state-when-raytracing.patch
similarity index 100%
rename from patches/unapplied/server/Don-t-lookup-fluid-state-when-raytracing.patch
rename to patches/server/Don-t-lookup-fluid-state-when-raytracing.patch
diff --git a/patches/unapplied/server/Don-t-read-neighbour-chunk-data-off-disk-when-conver.patch b/patches/server/Don-t-read-neighbour-chunk-data-off-disk-when-conver.patch
similarity index 88%
rename from patches/unapplied/server/Don-t-read-neighbour-chunk-data-off-disk-when-conver.patch
rename to patches/server/Don-t-read-neighbour-chunk-data-off-disk-when-conver.patch
index f01e20cd03..21a3c1061d 100644
--- a/patches/unapplied/server/Don-t-read-neighbour-chunk-data-off-disk-when-conver.patch
+++ b/patches/server/Don-t-read-neighbour-chunk-data-off-disk-when-conver.patch
@@ -18,4 +18,4 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +        if (true) return true; // Paper - this isn't even needed anymore, light is purged updating to 1.14+, why are we holding up the conversion process reading chunk data off disk - return true, we need to set light populated to true so the converter recognizes the chunk as being "full"
          ChunkPos pos = new ChunkPos(x, z);
          if (cps != null) {
-             //com.google.common.base.Preconditions.checkState(org.bukkit.Bukkit.isPrimaryThread(), "primary thread"); // Paper - this function is now MT-Safe
+             com.google.common.base.Preconditions.checkState(org.bukkit.Bukkit.isPrimaryThread(), "primary thread");
diff --git a/patches/unapplied/server/Make-sure-inlined-getChunkAt-has-inlined-logic-for-l.patch b/patches/server/Make-sure-inlined-getChunkAt-has-inlined-logic-for-l.patch
similarity index 100%
rename from patches/unapplied/server/Make-sure-inlined-getChunkAt-has-inlined-logic-for-l.patch
rename to patches/server/Make-sure-inlined-getChunkAt-has-inlined-logic-for-l.patch
diff --git a/patches/unapplied/server/Oprimise-map-impl-for-tracked-players.patch b/patches/server/Oprimise-map-impl-for-tracked-players.patch
similarity index 100%
rename from patches/unapplied/server/Oprimise-map-impl-for-tracked-players.patch
rename to patches/server/Oprimise-map-impl-for-tracked-players.patch
diff --git a/patches/unapplied/server/Optimise-BlockSoil-nearby-water-lookup.patch b/patches/server/Optimise-BlockSoil-nearby-water-lookup.patch
similarity index 100%
rename from patches/unapplied/server/Optimise-BlockSoil-nearby-water-lookup.patch
rename to patches/server/Optimise-BlockSoil-nearby-water-lookup.patch
diff --git a/patches/unapplied/server/Optimise-random-block-ticking.patch b/patches/server/Optimise-random-block-ticking.patch
similarity index 80%
rename from patches/unapplied/server/Optimise-random-block-ticking.patch
rename to patches/server/Optimise-random-block-ticking.patch
index cd6f831a3c..69b3ebec97 100644
--- a/patches/unapplied/server/Optimise-random-block-ticking.patch
+++ b/patches/server/Optimise-random-block-ticking.patch
@@ -108,94 +108,53 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
          ProfilerFiller gameprofilerfiller = this.getProfiler();
  
          gameprofilerfiller.push("thunder");
--        BlockPos blockposition;
 +        final BlockPos.MutableBlockPos blockposition = this.chunkTickMutablePosition; // Paper - use mutable to reduce allocation rate, final to force compile fail on change
- 
++
          if (!this.paperConfig().environment.disableThunder && flag && this.isThundering() && this.spigotConfig.thunderChance > 0 && this.random.nextInt(this.spigotConfig.thunderChance) == 0) { // Spigot // Paper - disable thunder
--            blockposition = this.findLightningTargetAround(this.getBlockRandomPos(j, 0, k, 15));
+-            BlockPos blockposition = this.findLightningTargetAround(this.getBlockRandomPos(j, 0, k, 15));
 +            blockposition.set(this.findLightningTargetAround(this.getBlockRandomPos(j, 0, k, 15))); // Paper
+ 
              if (this.isRainingAt(blockposition)) {
                  DifficultyInstance difficultydamagescaler = this.getCurrentDifficultyAt(blockposition);
-                 boolean flag1 = this.getGameRules().getBoolean(GameRules.RULE_DOMOBSPAWNING) && this.random.nextDouble() < (double) difficultydamagescaler.getEffectiveDifficulty() * this.paperConfig().entities.spawning.skeletonHorseThunderSpawnChance.or(0.01D) && !this.getBlockState(blockposition.below()).is(Blocks.LIGHTNING_ROD); // Paper
 @@ -0,0 +0,0 @@ public class ServerLevel extends Level implements WorldGenLevel {
-         int i1;
- 
-         if (!this.paperConfig().environment.disableIceAndSnow && this.random.nextInt(16) == 0) { // Paper - Disable ice and snow
--            blockposition = this.getHeightmapPos(Heightmap.Types.MOTION_BLOCKING, this.getBlockRandomPos(j, 0, k, 15));
--            BlockPos blockposition1 = blockposition.below();
-+            // Paper start - optimise chunk ticking
-+            this.getRandomBlockPosition(j, 0, k, 15, blockposition);
-+            int normalY = chunk.getHeight(Heightmap.Types.MOTION_BLOCKING, blockposition.getX() & 15, blockposition.getZ() & 15) + 1;
-+            int downY = normalY - 1;
-+            blockposition.setY(normalY);
-+            // Paper end
-             Biome biomebase = (Biome) this.getBiome(blockposition).value();
- 
--            if (biomebase.shouldFreeze(this, blockposition1)) {
--                org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockFormEvent(this, blockposition1, Blocks.ICE.defaultBlockState(), null); // CraftBukkit
-+            // Paper start - optimise chunk ticking
-+            blockposition.setY(downY);
-+            if (biomebase.shouldFreeze(this, blockposition)) {
-+                org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockFormEvent(this, blockposition, Blocks.ICE.defaultBlockState(), null); // CraftBukkit
-+                // Paper end
-             }
- 
-             if (flag) {
-                 l = this.getGameRules().getInt(GameRules.RULE_SNOW_ACCUMULATION_HEIGHT);
-+
-+                blockposition.setY(normalY); // Paper
-                 if (l > 0 && biomebase.shouldSnow(this, blockposition)) {
-                     BlockState iblockdata = this.getBlockState(blockposition);
- 
-@@ -0,0 +0,0 @@ public class ServerLevel extends Level implements WorldGenLevel {
-                         org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockFormEvent(this, blockposition, Blocks.SNOW.defaultBlockState(), null); // CraftBukkit
-                     }
-                 }
-+                blockposition.setY(downY); // Paper
- 
--                Biome.Precipitation biomebase_precipitation = biomebase.getPrecipitationAt(blockposition1);
-+                Biome.Precipitation biomebase_precipitation = biomebase.getPrecipitationAt(blockposition); // Paper
- 
-                 if (biomebase_precipitation != Biome.Precipitation.NONE) {
--                    BlockState iblockdata2 = this.getBlockState(blockposition1);
-+                    BlockState iblockdata2 = this.getBlockState(blockposition); // Paper
- 
--                    iblockdata2.getBlock().handlePrecipitation(iblockdata2, this, blockposition1, biomebase_precipitation);
-+                    iblockdata2.getBlock().handlePrecipitation(iblockdata2, this, blockposition, biomebase_precipitation); // Paper
-                 }
+         if (!this.paperConfig().environment.disableIceAndSnow) { // Paper
+         for (int l = 0; l < randomTickSpeed; ++l) {
+             if (this.random.nextInt(48) == 0) {
+-                this.tickIceAndSnow(flag, this.getBlockRandomPos(j, 0, k, 15));
++                this.getRandomBlockPosition(j, 0, k, 15, blockposition);
++                this.tickIceAndSnow(flag, blockposition);
              }
          }
+         } // Paper
  
--        gameprofilerfiller.popPush("tickBlocks");
 +        // Paper start - optimise random block ticking
-+        gameprofilerfiller.popPush("randomTick");
+         gameprofilerfiller.popPush("tickBlocks");
          timings.chunkTicksBlocks.startTiming(); // Paper
          if (randomTickSpeed > 0) {
 -            LevelChunkSection[] achunksection = chunk.getSections();
 -
--            for (int j1 = 0; j1 < achunksection.length; ++j1) {
--                LevelChunkSection chunksection = achunksection[j1];
+-            for (int i1 = 0; i1 < achunksection.length; ++i1) {
+-                LevelChunkSection chunksection = achunksection[i1];
 -
 -                if (chunksection.isRandomlyTicking()) {
--                    l = chunk.getSectionYFromSectionIndex(j1);
--                    int k1 = SectionPos.sectionToBlockCoord(l);
+-                    int j1 = chunk.getSectionYFromSectionIndex(i1);
+-                    int k1 = SectionPos.sectionToBlockCoord(j1);
 -
--                    for (i1 = 0; i1 < randomTickSpeed; ++i1) {
--                        BlockPos blockposition2 = this.getBlockRandomPos(j, k1, k, 15);
+-                    for (int l1 = 0; l1 < randomTickSpeed; ++l1) {
+-                        BlockPos blockposition1 = this.getBlockRandomPos(j, k1, k, 15);
 -
 -                        gameprofilerfiller.push("randomTick");
--                        BlockState iblockdata3 = chunksection.getBlockState(blockposition2.getX() - j, blockposition2.getY() - k1, blockposition2.getZ() - k);
-+            LevelChunkSection[] sections = chunk.getSections();
-+            int minSection = io.papermc.paper.util.WorldUtil.getMinSection(this);
-+            for (int sectionIndex = 0; sectionIndex < sections.length; ++sectionIndex) {
-+                LevelChunkSection section = sections[sectionIndex];
-+                if (section == null || section.tickingList.size() == 0) {
-+                    continue;
-+                }
- 
--                        if (iblockdata3.isRandomlyTicking()) {
--                            iblockdata3.randomTick(this, blockposition2, this.random);
+-                        BlockState iblockdata = chunksection.getBlockState(blockposition1.getX() - j, blockposition1.getY() - k1, blockposition1.getZ() - k);
+-
+-                        if (iblockdata.isRandomlyTicking()) {
+-                            iblockdata.randomTick(this, blockposition1, this.random);
 -                        }
++            LevelChunkSection[] sections = chunk.getSections();
++            final int minSection = io.papermc.paper.util.WorldUtil.getMinSection(this);
++            for (int sectionIndex = 0; sectionIndex < sections.length; sectionIndex++) {
++                LevelChunkSection section = sections[sectionIndex];
++                if (section == null || section.tickingList.size() == 0) continue;
++
 +                int yPos = (sectionIndex + minSection) << 4;
 +                for (int a = 0; a < randomTickSpeed; ++a) {
 +                    int tickingBlocks = section.tickingList.size();
@@ -204,7 +163,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +                        continue;
 +                    }
  
--                        FluidState fluid = iblockdata3.getFluidState();
+-                        FluidState fluid = iblockdata.getFluidState();
 +                    long raw = section.tickingList.getRaw(index);
 +                    int location = com.destroystokyo.paper.util.maplist.IBlockDataList.getLocationFromRaw(raw);
 +                    int randomX = location & 15;
@@ -212,7 +171,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +                    int randomZ = (location >>> 4) & 15;
  
 -                        if (fluid.isRandomlyTicking()) {
--                            fluid.randomTick(this, blockposition2, this.random);
+-                            fluid.randomTick(this, blockposition1, this.random);
 -                        }
 +                    BlockPos blockposition2 = blockposition.set(j + randomX, randomY, k + randomZ);
 +                    BlockState iblockdata = com.destroystokyo.paper.util.maplist.IBlockDataList.getBlockDataFromRaw(raw);
@@ -225,11 +184,53 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
                  }
              }
          }
--
 +        // Paper end - optimise random block ticking
+ 
          timings.chunkTicksBlocks.stopTiming(); // Paper
          gameprofilerfiller.pop();
      }
+ 
+-    private void tickIceAndSnow(boolean raining, BlockPos pos) {
+-        BlockPos blockposition1 = this.getHeightmapPos(Heightmap.Types.MOTION_BLOCKING, pos);
+-        BlockPos blockposition2 = blockposition1.below();
++    private void tickIceAndSnow(boolean raining, BlockPos.MutableBlockPos blockposition1, final LevelChunk chunk) { // Paper - optimise chunk ticking
++        // Paper start - optimise chunk ticking
++        int normalY = chunk.getHeight(Heightmap.Types.MOTION_BLOCKING, blockposition1.getX() & 15, blockposition1.getZ() & 15) + 1;
++        int downY = normalY - 1;
++        blockposition1.setY(normalY);
+         Biome biomebase = (Biome) this.getBiome(blockposition1).value();
+ 
+-        if (biomebase.shouldFreeze(this, blockposition2)) {
+-            org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockFormEvent(this, blockposition2, Blocks.ICE.defaultBlockState(), null); // CraftBukkit
++        if (biomebase.shouldFreeze(this, blockposition1)) {
++            org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockFormEvent(this, blockposition1, Blocks.ICE.defaultBlockState(), null); // CraftBukkit
+         }
++        // Paper end - optimise chunk ticking
+ 
+         if (raining) {
+             int i = this.getGameRules().getInt(GameRules.RULE_SNOW_ACCUMULATION_HEIGHT);
+ 
++            blockposition1.setY(normalY); // Paper - optimise chunk ticking
+             if (i > 0 && biomebase.shouldSnow(this, blockposition1)) {
+                 BlockState iblockdata = this.getBlockState(blockposition1);
+ 
+@@ -0,0 +0,0 @@ public class ServerLevel extends Level implements WorldGenLevel {
+                 }
+             }
+ 
+-            Biome.Precipitation biomebase_precipitation = biomebase.getPrecipitationAt(blockposition2);
++            blockposition1.setY(downY); // Paper - optimise chunk ticking
++            Biome.Precipitation biomebase_precipitation = biomebase.getPrecipitationAt(blockposition1); // Paper - optimise chunk ticking
+ 
+             if (biomebase_precipitation != Biome.Precipitation.NONE) {
+-                BlockState iblockdata2 = this.getBlockState(blockposition2);
++                BlockState iblockdata2 = this.getBlockState(blockposition1); // Paper - optimise chunk ticking
+ 
+-                iblockdata2.getBlock().handlePrecipitation(iblockdata2, this, blockposition2, biomebase_precipitation);
++                iblockdata2.getBlock().handlePrecipitation(iblockdata2, this, blockposition1, biomebase_precipitation); // Paper - optimise chunk ticking
+             }
+         }
+ 
 diff --git a/src/main/java/net/minecraft/util/BitStorage.java b/src/main/java/net/minecraft/util/BitStorage.java
 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
 --- a/src/main/java/net/minecraft/util/BitStorage.java
@@ -421,9 +422,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 -
              }
 -        }
- 
--        a a0 = new a();
 -
+-        a a0 = new a();
+ 
 -        this.states.count(a0);
 -        this.nonEmptyBlockCount = (short) a0.nonEmptyBlockCount;
 -        this.tickingBlockCount = (short) a0.tickingBlockCount;
diff --git a/patches/unapplied/server/Send-full-pos-packets-for-hard-colliding-entities.patch b/patches/server/Send-full-pos-packets-for-hard-colliding-entities.patch
similarity index 100%
rename from patches/unapplied/server/Send-full-pos-packets-for-hard-colliding-entities.patch
rename to patches/server/Send-full-pos-packets-for-hard-colliding-entities.patch
diff --git a/patches/unapplied/server/Time-scoreboard-search.patch b/patches/server/Time-scoreboard-search.patch
similarity index 91%
rename from patches/unapplied/server/Time-scoreboard-search.patch
rename to patches/server/Time-scoreboard-search.patch
index de75179ecd..cb551a956b 100644
--- a/patches/unapplied/server/Time-scoreboard-search.patch
+++ b/patches/server/Time-scoreboard-search.patch
@@ -11,12 +11,13 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 --- a/src/main/java/co/aikar/timings/MinecraftTimings.java
 +++ b/src/main/java/co/aikar/timings/MinecraftTimings.java
 @@ -0,0 +0,0 @@ public final class MinecraftTimings {
+ 
      public static final Timing antiXrayUpdateTimer = Timings.ofSafe("anti-xray - update");
      public static final Timing antiXrayObfuscateTimer = Timings.ofSafe("anti-xray - obfuscate");
-     public static final Timing distanceManagerTick = Timings.ofSafe("Distance Manager Tick"); // Paper - add timings for distance manager
 +    public static final Timing scoreboardScoreSearch = Timings.ofSafe("Scoreboard score search"); // Paper - add timings for scoreboard search
++
  
-     public static final Timing midTickChunkTasks = Timings.ofSafe("Mid Tick Chunk Tasks");
+     private static final Map<Class<?>, String> taskNameCache = new MapMaker().weakKeys().makeMap();
  
 diff --git a/src/main/java/org/bukkit/craftbukkit/scoreboard/CraftScoreboardManager.java b/src/main/java/org/bukkit/craftbukkit/scoreboard/CraftScoreboardManager.java
 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
diff --git a/patches/unapplied/server/Add-packet-limiter-config.patch b/patches/unapplied/skipped/Add-packet-limiter-config.patch
similarity index 100%
rename from patches/unapplied/server/Add-packet-limiter-config.patch
rename to patches/unapplied/skipped/Add-packet-limiter-config.patch
diff --git a/patches/unapplied/server/Consolidate-flush-calls-for-entity-tracker-packets.patch b/patches/unapplied/skipped/Consolidate-flush-calls-for-entity-tracker-packets.patch
similarity index 100%
rename from patches/unapplied/server/Consolidate-flush-calls-for-entity-tracker-packets.patch
rename to patches/unapplied/skipped/Consolidate-flush-calls-for-entity-tracker-packets.patch