diff --git a/fabric/src/main/java/ca/spottedleaf/moonrise/fabric/FabricHooks.java b/fabric/src/main/java/ca/spottedleaf/moonrise/fabric/FabricHooks.java
index d73c78d5..39245640 100644
--- a/fabric/src/main/java/ca/spottedleaf/moonrise/fabric/FabricHooks.java
+++ b/fabric/src/main/java/ca/spottedleaf/moonrise/fabric/FabricHooks.java
@@ -19,6 +19,7 @@
 import net.minecraft.world.level.chunk.ChunkAccess;
 import net.minecraft.world.level.chunk.LevelChunk;
 import net.minecraft.world.level.chunk.ProtoChunk;
+import net.minecraft.world.level.chunk.status.ChunkStatusTasks;
 import net.minecraft.world.level.chunk.storage.SerializableChunkData;
 import net.minecraft.world.level.entity.EntityTypeTest;
 import net.minecraft.world.phys.AABB;
@@ -186,4 +187,24 @@ public boolean hasMainChunkLoadHook() {
     public void mainChunkLoad(final ChunkAccess chunk, final SerializableChunkData chunkData) {
 
     }
+
+    @Override
+    public List<Entity> modifySavedEntities(final ServerLevel world, final int chunkX, final int chunkZ, final List<Entity> entities) {
+        return entities;
+    }
+
+    @Override
+    public void unloadEntity(final Entity entity) {
+        entity.setRemoved(Entity.RemovalReason.UNLOADED_TO_CHUNK);
+    }
+
+    @Override
+    public void postLoadProtoChunk(final ServerLevel world, final ProtoChunk chunk) {
+        ChunkStatusTasks.postLoadProtoChunk(world, chunk.getEntities());
+    }
+
+    @Override
+    public int modifyEntityTrackingRange(final Entity entity, final int currentRange) {
+        return currentRange;
+    }
 }
diff --git a/neoforge/src/main/java/ca/spottedleaf/moonrise/neoforge/NeoForgeHooks.java b/neoforge/src/main/java/ca/spottedleaf/moonrise/neoforge/NeoForgeHooks.java
index 324442d2..c53be2eb 100644
--- a/neoforge/src/main/java/ca/spottedleaf/moonrise/neoforge/NeoForgeHooks.java
+++ b/neoforge/src/main/java/ca/spottedleaf/moonrise/neoforge/NeoForgeHooks.java
@@ -21,6 +21,7 @@
 import net.minecraft.world.level.chunk.ImposterProtoChunk;
 import net.minecraft.world.level.chunk.LevelChunk;
 import net.minecraft.world.level.chunk.ProtoChunk;
+import net.minecraft.world.level.chunk.status.ChunkStatusTasks;
 import net.minecraft.world.level.chunk.storage.SerializableChunkData;
 import net.minecraft.world.level.entity.EntityTypeTest;
 import net.minecraft.world.phys.AABB;
@@ -218,4 +219,24 @@ public boolean hasMainChunkLoadHook() {
     public void mainChunkLoad(final ChunkAccess chunk, final SerializableChunkData chunkData) {
         NeoForge.EVENT_BUS.post(new ChunkDataEvent.Load(chunk, chunkData));
     }
+
+    @Override
+    public List<Entity> modifySavedEntities(final ServerLevel world, final int chunkX, final int chunkZ, final List<Entity> entities) {
+        return entities;
+    }
+
+    @Override
+    public void unloadEntity(final Entity entity) {
+        entity.setRemoved(Entity.RemovalReason.UNLOADED_TO_CHUNK);
+    }
+
+    @Override
+    public void postLoadProtoChunk(final ServerLevel world, final ProtoChunk chunk) {
+        ChunkStatusTasks.postLoadProtoChunk(world, chunk.getEntities());
+    }
+
+    @Override
+    public int modifyEntityTrackingRange(final Entity entity, final int currentRange) {
+        return currentRange;
+    }
 }
diff --git a/src/main/java/ca/spottedleaf/moonrise/common/PlatformHooks.java b/src/main/java/ca/spottedleaf/moonrise/common/PlatformHooks.java
index 25b898da..f70a4f28 100644
--- a/src/main/java/ca/spottedleaf/moonrise/common/PlatformHooks.java
+++ b/src/main/java/ca/spottedleaf/moonrise/common/PlatformHooks.java
@@ -95,6 +95,14 @@ public CompoundTag convertNBT(final DataFixTypes type, final DataFixer dataFixer
 
     public void mainChunkLoad(final ChunkAccess chunk, final SerializableChunkData chunkData);
 
+    public List<Entity> modifySavedEntities(final ServerLevel world, final int chunkX, final int chunkZ, final List<Entity> entities);
+
+    public void unloadEntity(final Entity entity);
+
+    public void postLoadProtoChunk(final ServerLevel world, final ProtoChunk chunk);
+
+    public int modifyEntityTrackingRange(final Entity entity, final int currentRange);
+
     public static final class Holder {
         private Holder() {
         }
diff --git a/src/main/java/ca/spottedleaf/moonrise/common/util/ConfigHolder.java b/src/main/java/ca/spottedleaf/moonrise/common/util/ConfigHolder.java
index a4965292..d2f97ef8 100644
--- a/src/main/java/ca/spottedleaf/moonrise/common/util/ConfigHolder.java
+++ b/src/main/java/ca/spottedleaf/moonrise/common/util/ConfigHolder.java
@@ -1,5 +1,6 @@
 package ca.spottedleaf.moonrise.common.util;
 
+import ca.spottedleaf.moonrise.common.PlatformHooks;
 import ca.spottedleaf.moonrise.common.config.adapter.TypeAdapterRegistry;
 import ca.spottedleaf.moonrise.common.config.config.YamlConfig;
 import ca.spottedleaf.moonrise.common.config.moonrise.MoonriseConfig;
@@ -13,7 +14,7 @@ public final class ConfigHolder {
 
     private static final Logger LOGGER = LoggerFactory.getLogger(ConfigHolder.class);
 
-    private static final File CONFIG_FILE = new File(System.getProperty("Moonrise.ConfigFile", "config/moonrise.yml"));
+    private static final File CONFIG_FILE = new File(System.getProperty(PlatformHooks.get().getBrand() + ".ConfigFile", "config/moonrise.yml"));
     private static final TypeAdapterRegistry CONFIG_ADAPTERS = new TypeAdapterRegistry();
     private static final YamlConfig<MoonriseConfig> CONFIG;
     static {
@@ -25,7 +26,7 @@ public final class ConfigHolder {
             throw new RuntimeException(ex);
         }
     }
-    private static final String CONFIG_HEADER = """
+    private static final String CONFIG_HEADER = String.format("""
             This is the configuration file for Moonrise.
             
             Each configuration option is prefixed with a comment to explain what it does. Additional changes to this file
@@ -33,10 +34,10 @@ public final class ConfigHolder {
             
             Below are the Moonrise startup flags. Note that startup flags must be placed in the JVM arguments, not
             program arguments.
-            -DMoonrise.ConfigFile=<file> - Override the config file location. Might be useful for multiple game versions.
-            -DMoonrise.WorkerThreadCount=<number> - Override the auto configured worker thread counts (worker-threads).
-            -DMoonrise.MaxViewDistance=<number> - Overrides the maximum view distance, should only use for debugging purposes.
-            """;
+            -D%1$s.ConfigFile=<file> - Override the config file location. Might be useful for multiple game versions.
+            -D%1$s.WorkerThreadCount=<number> - Override the auto configured worker thread counts (worker-threads).
+            -D%1$s.MaxViewDistance=<number> - Overrides the maximum view distance, should only use for debugging purposes.
+            """, PlatformHooks.get().getBrand());
 
     static {
         reloadConfig();
diff --git a/src/main/java/ca/spottedleaf/moonrise/common/util/MoonriseCommon.java b/src/main/java/ca/spottedleaf/moonrise/common/util/MoonriseCommon.java
index 3285f265..c125c70a 100644
--- a/src/main/java/ca/spottedleaf/moonrise/common/util/MoonriseCommon.java
+++ b/src/main/java/ca/spottedleaf/moonrise/common/util/MoonriseCommon.java
@@ -19,7 +19,7 @@ public final class MoonriseCommon {
                 @Override
                 public void accept(Thread thread) {
                     thread.setDaemon(true);
-                    thread.setName("Moonrise Common Worker #" + this.idGenerator.getAndIncrement());
+                    thread.setName(PlatformHooks.get().getBrand() + " Common Worker #" + this.idGenerator.getAndIncrement());
                     thread.setUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
                         @Override
                         public void uncaughtException(final Thread thread, final Throwable throwable) {
@@ -44,7 +44,7 @@ public static void adjustWorkerThreads(final int configWorkerThreads, final int
         } else {
             defaultWorkerThreads = defaultWorkerThreads / 2;
         }
-        defaultWorkerThreads = Integer.getInteger("Moonrise.WorkerThreadCount", Integer.valueOf(defaultWorkerThreads));
+        defaultWorkerThreads = Integer.getInteger(PlatformHooks.get().getBrand() + ".WorkerThreadCount", Integer.valueOf(defaultWorkerThreads));
 
         int workerThreads = configWorkerThreads;
 
diff --git a/src/main/java/ca/spottedleaf/moonrise/common/util/MoonriseConstants.java b/src/main/java/ca/spottedleaf/moonrise/common/util/MoonriseConstants.java
index ffffad18..559c959a 100644
--- a/src/main/java/ca/spottedleaf/moonrise/common/util/MoonriseConstants.java
+++ b/src/main/java/ca/spottedleaf/moonrise/common/util/MoonriseConstants.java
@@ -1,8 +1,10 @@
 package ca.spottedleaf.moonrise.common.util;
 
+import ca.spottedleaf.moonrise.common.PlatformHooks;
+
 public final class MoonriseConstants {
 
-    public static final int MAX_VIEW_DISTANCE = Integer.getInteger("Moonrise.MaxViewDistance", 32);
+    public static final int MAX_VIEW_DISTANCE = Integer.getInteger(PlatformHooks.get().getBrand() + ".MaxViewDistance", 32);
 
     private MoonriseConstants() {}
 
diff --git a/src/main/java/ca/spottedleaf/moonrise/mixin/blockstate_propertyaccess/BooleanPropertyMixin.java b/src/main/java/ca/spottedleaf/moonrise/mixin/blockstate_propertyaccess/BooleanPropertyMixin.java
index 797edbcb..cf61f642 100644
--- a/src/main/java/ca/spottedleaf/moonrise/mixin/blockstate_propertyaccess/BooleanPropertyMixin.java
+++ b/src/main/java/ca/spottedleaf/moonrise/mixin/blockstate_propertyaccess/BooleanPropertyMixin.java
@@ -6,6 +6,7 @@
 import net.minecraft.world.level.block.state.properties.BooleanProperty;
 import net.minecraft.world.level.block.state.properties.Property;
 import org.spongepowered.asm.mixin.Mixin;
+import org.spongepowered.asm.mixin.Unique;
 import org.spongepowered.asm.mixin.injection.At;
 import org.spongepowered.asm.mixin.injection.Constant;
 import org.spongepowered.asm.mixin.injection.Inject;
@@ -17,6 +18,9 @@ protected BooleanPropertyMixin(String string, Class<Boolean> class_) {
         super(string, class_);
     }
 
+    @Unique
+    private static final Boolean[] BY_ID = new Boolean[]{ Boolean.FALSE, Boolean.TRUE };
+
     @Override
     public final int moonrise$getIdFor(final Boolean value) {
         return value.booleanValue() ? 1 : 0;
@@ -33,6 +37,6 @@ protected BooleanPropertyMixin(String string, Class<Boolean> class_) {
         )
     )
     private void init(final CallbackInfo ci) {
-        this.moonrise$setById(new Boolean[]{ Boolean.FALSE, Boolean.TRUE });
+        this.moonrise$setById(BY_ID);
     }
 }
diff --git a/src/main/java/ca/spottedleaf/moonrise/mixin/chunk_system/ChunkHolderMixin.java b/src/main/java/ca/spottedleaf/moonrise/mixin/chunk_system/ChunkHolderMixin.java
index 0ba8d53d..a6906d42 100644
--- a/src/main/java/ca/spottedleaf/moonrise/mixin/chunk_system/ChunkHolderMixin.java
+++ b/src/main/java/ca/spottedleaf/moonrise/mixin/chunk_system/ChunkHolderMixin.java
@@ -66,9 +66,6 @@ public ChunkHolderMixin(ChunkPos chunkPos) {
     @Unique
     private final ReferenceList<ServerPlayer> playersSentChunkTo = new ReferenceList<>(EMPTY_PLAYER_ARRAY);
 
-    @Unique
-    private boolean isMarkedDirtyForPlayers;
-
     @Unique
     private ChunkMap getChunkMap() {
         return (ChunkMap)this.playerProvider;
@@ -123,16 +120,6 @@ private ChunkMap getChunkMap() {
         return ret;
     }
 
-    @Override
-    public final boolean moonrise$isMarkedDirtyForPlayers() {
-        return this.isMarkedDirtyForPlayers;
-    }
-
-    @Override
-    public final void moonrise$markDirtyForPlayers(final boolean value) {
-        this.isMarkedDirtyForPlayers = value;
-    }
-
     @Unique
     private static final ServerPlayer[] EMPTY_PLAYER_ARRAY = new ServerPlayer[0];
 
diff --git a/src/main/java/ca/spottedleaf/moonrise/mixin/entity_tracker/TrackedEntityMixin.java b/src/main/java/ca/spottedleaf/moonrise/mixin/entity_tracker/TrackedEntityMixin.java
index 247b6127..738c0a7b 100644
--- a/src/main/java/ca/spottedleaf/moonrise/mixin/entity_tracker/TrackedEntityMixin.java
+++ b/src/main/java/ca/spottedleaf/moonrise/mixin/entity_tracker/TrackedEntityMixin.java
@@ -1,5 +1,6 @@
 package ca.spottedleaf.moonrise.mixin.entity_tracker;
 
+import ca.spottedleaf.moonrise.common.PlatformHooks;
 import ca.spottedleaf.moonrise.common.list.ReferenceList;
 import ca.spottedleaf.moonrise.common.misc.NearbyPlayers;
 import ca.spottedleaf.moonrise.common.util.TickThread;
@@ -144,8 +145,8 @@ private <E> Set<E> useBetterIdentitySet() {
      */
     @Overwrite
     public int getEffectiveRange() {
-        int range = this.range;
         final Entity entity = this.entity;
+        int range = PlatformHooks.get().modifyEntityTrackingRange(entity, this.range);
 
         if (entity.getPassengers() == ImmutableList.<Entity>of()) {
             return this.scaledRange(range);
@@ -154,8 +155,9 @@ public int getEffectiveRange() {
         // note: we change to List
         final List<Entity> passengers = (List<Entity>)entity.getIndirectPassengers();
         for (int i = 0, len = passengers.size(); i < len; ++i) {
+            final Entity passenger = passengers.get(i);
             // note: max should be branchless
-            range = Math.max(range, passengers.get(i).getType().clientTrackingRange() << 4);
+            range = Math.max(range, PlatformHooks.get().modifyEntityTrackingRange(passenger, passenger.getType().clientTrackingRange() << 4));
         }
 
         return this.scaledRange(range);
diff --git a/src/main/java/ca/spottedleaf/moonrise/mixin/fluid/MappedRegistryMixin.java b/src/main/java/ca/spottedleaf/moonrise/mixin/fluid/MappedRegistryMixin.java
index a616ebea..ca8c7c3c 100644
--- a/src/main/java/ca/spottedleaf/moonrise/mixin/fluid/MappedRegistryMixin.java
+++ b/src/main/java/ca/spottedleaf/moonrise/mixin/fluid/MappedRegistryMixin.java
@@ -29,9 +29,9 @@ private void injectFluidRegister(
         final RegistrationInfo registrationInfo,
         final CallbackInfoReturnable<Holder.Reference<T>> cir
     ) {
-        if (resourceKey.registryKey() == (Object) Registries.FLUID) {
-            for (final FluidState possibleState : ((Fluid) object).getStateDefinition().getPossibleStates()) {
-                ((FluidFluidState) (Object) possibleState).moonrise$initCaches();
+        if (resourceKey.registryKey() == (Object)Registries.FLUID) {
+            for (final FluidState possibleState : ((Fluid)object).getStateDefinition().getPossibleStates()) {
+                ((FluidFluidState)(Object)possibleState).moonrise$initCaches();
             }
         }
     }
diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/chunk/ChunkSystemChunkHolder.java b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/chunk/ChunkSystemChunkHolder.java
index ba9111f7..7d049d75 100644
--- a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/chunk/ChunkSystemChunkHolder.java
+++ b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/chunk/ChunkSystemChunkHolder.java
@@ -23,8 +23,4 @@ public interface ChunkSystemChunkHolder {
 
     public LevelChunk moonrise$getFullChunk();
 
-    public boolean moonrise$isMarkedDirtyForPlayers();
-
-    public void moonrise$markDirtyForPlayers(final boolean value);
-
 }
diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/entity/ChunkEntitySlices.java b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/entity/ChunkEntitySlices.java
index 445da569..40dc7569 100644
--- a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/entity/ChunkEntitySlices.java
+++ b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/entity/ChunkEntitySlices.java
@@ -1,5 +1,6 @@
 package ca.spottedleaf.moonrise.patches.chunk_system.level.entity;
 
+import ca.spottedleaf.moonrise.common.PlatformHooks;
 import ca.spottedleaf.moonrise.common.list.EntityList;
 import ca.spottedleaf.moonrise.patches.chunk_system.level.chunk.ChunkData;
 import ca.spottedleaf.moonrise.patches.chunk_system.entity.ChunkSystemEntity;
@@ -103,7 +104,7 @@ public static CompoundTag saveEntityChunk0(final List<Entity> entities, final Ch
         }
 
         final ListTag entitiesTag = new ListTag();
-        for (final Entity entity : entities) {
+        for (final Entity entity : PlatformHooks.get().modifySavedEntities(world, chunkPos.x, chunkPos.z, entities)) {
             CompoundTag compoundTag = new CompoundTag();
             if (entity.save(compoundTag)) {
                 entitiesTag.add(compoundTag);
@@ -150,12 +151,12 @@ public boolean unload() {
                 continue;
             }
             if (entity.shouldBeSaved()) {
-                entity.setRemoved(Entity.RemovalReason.UNLOADED_TO_CHUNK);
+                PlatformHooks.get().unloadEntity(entity);
                 if (entity.isVehicle()) {
                     // we cannot assume that these entities are contained within this chunk, because entities can
                     // desync - so we need to remove them all
                     for (final Entity passenger : entity.getIndirectPassengers()) {
-                        passenger.setRemoved(Entity.RemovalReason.UNLOADED_TO_CHUNK);
+                        PlatformHooks.get().unloadEntity(passenger);
                     }
                 }
             }
diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/entity/EntityLookup.java b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/entity/EntityLookup.java
index e65da01d..93335de8 100644
--- a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/entity/EntityLookup.java
+++ b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/level/entity/EntityLookup.java
@@ -1057,7 +1057,7 @@ public void onMove() {
         @Override
         public void onRemove(final Entity.RemovalReason reason) {
             final Entity entity = this.entity;
-            EntityLookup.this.checkThread(entity, "Cannot remove entity off-main"); // Paper - rewrite chunk system
+            EntityLookup.this.checkThread(entity, "Cannot remove entity off-main");
             final Visibility tickingState = EntityLookup.getEntityStatus(entity);
 
             EntityLookup.this.removeEntity(entity);
diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/player/RegionizedPlayerChunkLoader.java b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/player/RegionizedPlayerChunkLoader.java
index cd2c674a..b2fa9883 100644
--- a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/player/RegionizedPlayerChunkLoader.java
+++ b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/player/RegionizedPlayerChunkLoader.java
@@ -427,11 +427,11 @@ private void sendUnloadChunk(final int chunkX, final int chunkZ) {
             if (!this.sentChunks.remove(CoordinateUtils.getChunkKey(chunkX, chunkZ))) {
                 return;
             }
-            PlatformHooks.get().onChunkUnWatch(this.world, new ChunkPos(chunkX, chunkZ), this.player);
             this.sendUnloadChunkRaw(chunkX, chunkZ);
         }
 
         private void sendUnloadChunkRaw(final int chunkX, final int chunkZ) {
+            PlatformHooks.get().onChunkUnWatch(this.world, new ChunkPos(chunkX, chunkZ), this.player);
             // Note: Check PlayerChunkSender#dropChunk for other logic
             // Note: drop isAlive() check so that chunks properly unload client-side when the player dies
             ((ChunkSystemChunkHolder)((ChunkSystemServerLevel)this.world).moonrise$getChunkTaskScheduler().chunkHolderManager
@@ -1077,5 +1077,9 @@ void remove() {
 
             // now all tickets should be removed, which is all of our external state
         }
+
+        public LongOpenHashSet getSentChunksRaw() {
+            return this.sentChunks;
+        }
     }
 }
diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/task/ChunkFullTask.java b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/task/ChunkFullTask.java
index 98382575..6ab353b0 100644
--- a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/task/ChunkFullTask.java
+++ b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/task/ChunkFullTask.java
@@ -65,7 +65,7 @@ public void run() {
                 final ServerLevel world = this.world;
                 final ProtoChunk protoChunk = (ProtoChunk)this.fromChunk;
                 chunk = new LevelChunk(this.world, protoChunk, (final LevelChunk unused) -> {
-                    ChunkStatusTasks.postLoadProtoChunk(world, protoChunk.getEntities());
+                    PlatformHooks.get().postLoadProtoChunk(world, protoChunk);
                 });
                 this.chunkHolder.replaceProtoChunk(new ImposterProtoChunk(chunk, false));
             }