diff --git a/game/client/src/main/java/net/betterthanadventure/utils/BiomeFinder.java b/game/client/src/main/java/net/betterthanadventure/utils/BiomeFinder.java
index bba31dcd5..e43f9ee96 100644
--- a/game/client/src/main/java/net/betterthanadventure/utils/BiomeFinder.java
+++ b/game/client/src/main/java/net/betterthanadventure/utils/BiomeFinder.java
@@ -2,6 +2,8 @@ package net.betterthanadventure.utils;
 
 import com.mojang.logging.LogUtils;
 import net.minecraft.client.Minecraft;
+import net.minecraft.client.world.WorldClient;
+import net.minecraft.client.world.WorldEmpty;
 import net.minecraft.client.world.chunk.provider.ChunkProviderDynamic;
 import net.minecraft.core.Global;
 import net.minecraft.core.MinecraftAccessor;
@@ -15,19 +17,18 @@ import net.minecraft.core.world.biome.Biome;
 import net.minecraft.core.world.biome.provider.BiomeProvider;
 import net.minecraft.core.world.biome.provider.BiomeProviderOverworld;
 import net.minecraft.core.world.chunk.Chunk;
-import net.minecraft.core.world.chunk.IChunkLoader;
-import net.minecraft.core.world.chunk.provider.IChunkProvider;
+import net.minecraft.core.world.chunk.ChunkLoader;
+import net.minecraft.core.world.chunk.provider.ChunkProvider;
 import net.minecraft.core.world.pos.ChunkPos;
 import net.minecraft.core.world.pos.ChunkTilePos;
 import net.minecraft.core.world.pos.TilePos;
 import net.minecraft.core.world.save.LevelStorage;
 import net.minecraft.core.world.save.SaveFormatBase;
-import net.minecraft.core.world.save.LevelStorageDummy;
 import net.minecraft.core.world.save.mcregion.SaveFormat19134;
-import net.minecraft.core.world.saveddata.SavedDataStorage;
 import net.minecraft.core.world.type.WorldType;
 import net.minecraft.core.world.type.WorldTypes;
 import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
 import org.slf4j.Logger;
 
 import javax.swing.*;
@@ -494,12 +495,12 @@ public class BiomeFinder implements MinecraftAccessor {
 		BiomeProvider biomeProvider;
 		World world;
 		if (worldFolder == null){
-			biomeProvider = worldType.createBiomeProvider(new World(new SavedDataStorage(new LevelStorageDummy()), "", seed, dimension, worldType));
+			biomeProvider = worldType.createBiomeProvider(WorldEmpty.INSTANCE);
 			world = null;
 		} else {
 			SaveFormatBase saveFormat = new SaveFormat19134(worldFolder.getParentFile());
-			LevelStorage saveHandler = saveFormat.getLevelStorage(worldFolder.getName(), false);
-			world = new World(saveHandler, saveHandler.getLevelData().getWorldName(), saveHandler.getLevelData().getRandomSeed(), Dimension.OVERWORLD, null);
+			LevelStorage levelStorage = saveFormat.getLevelStorage(worldFolder.getName(), false);
+			world = new World(levelStorage, levelStorage.getLevelData().getWorldName(), levelStorage.getLevelData().getRandomSeed(), Dimension.OVERWORLD);
 			biomeProvider = worldType.createBiomeProvider(world);
 		}
 		allBiomes.clear();
@@ -650,11 +651,6 @@ public class BiomeFinder implements MinecraftAccessor {
 		return null;
 	}
 
-	@Override
-	public IChunkProvider createChunkProvider(World world, IChunkLoader chunkLoader) {
-		return new ChunkProviderDynamic(world, chunkLoader, world.getWorldType().createChunkGenerator(world));
-	}
-
 	@Override
 	public int getAutosaveTimer() {
 		return 0;
@@ -670,4 +666,19 @@ public class BiomeFinder implements MinecraftAccessor {
 		return null;
 	}
 
+	private static final class World extends net.minecraft.core.world.World {
+		public World(final @NotNull LevelStorage levelStorage, final @Nullable String name, final long seed, final @NotNull Dimension dimension) {
+			super(levelStorage, name, seed, dimension, null);
+		}
+
+		@Override
+		public void setLightningFlicker(final int flicker) {
+			// Do nothing
+		}
+
+		@Override
+		protected @NotNull ChunkProvider createChunkProvider(@NotNull final LevelStorage levelStorage) {
+			return new ChunkProviderDynamic(this, levelStorage.getChunkLoader(this.dimension), this.getWorldType().createChunkGenerator(this));
+		}
+	}
 }
diff --git a/game/client/src/main/java/net/betterthanadventure/utils/DataDumper.java b/game/client/src/main/java/net/betterthanadventure/utils/DataDumper.java
index a5002e1af..da9d8804a 100644
--- a/game/client/src/main/java/net/betterthanadventure/utils/DataDumper.java
+++ b/game/client/src/main/java/net/betterthanadventure/utils/DataDumper.java
@@ -21,8 +21,8 @@ import net.minecraft.core.item.tool.ItemToolPickaxe;
 import net.minecraft.core.lang.I18n;
 import net.minecraft.core.world.World;
 import net.minecraft.core.world.biome.Biome;
-import net.minecraft.core.world.chunk.IChunkLoader;
-import net.minecraft.core.world.chunk.provider.IChunkProvider;
+import net.minecraft.core.world.chunk.ChunkLoader;
+import net.minecraft.core.world.chunk.provider.ChunkProvider;
 import net.minecraft.core.world.weather.Weather;
 import org.slf4j.Logger;
 
@@ -212,11 +212,6 @@ public class DataDumper implements MinecraftAccessor {
         return minecraftDir;
     }
 
-    @Override
-    public IChunkProvider createChunkProvider(World world, IChunkLoader chunkLoader) {
-        return null;
-    }
-
     @Override
     public int getAutosaveTimer() {
         return 0;
diff --git a/game/client/src/main/java/net/minecraft/client/Minecraft.java b/game/client/src/main/java/net/minecraft/client/Minecraft.java
index 5be459f2d..0496247ab 100644
--- a/game/client/src/main/java/net/minecraft/client/Minecraft.java
+++ b/game/client/src/main/java/net/minecraft/client/Minecraft.java
@@ -176,8 +176,8 @@ import net.minecraft.core.world.World;
 import net.minecraft.core.world.biome.provider.BiomeProviderOverworld;
 import net.minecraft.core.world.chunk.Chunk;
 import net.minecraft.core.world.chunk.ChunkCoordinates;
-import net.minecraft.core.world.chunk.IChunkLoader;
-import net.minecraft.core.world.chunk.provider.IChunkProvider;
+import net.minecraft.core.world.chunk.ChunkLoader;
+import net.minecraft.core.world.chunk.provider.ChunkProvider;
 import net.minecraft.core.world.pos.TilePos;
 import net.minecraft.core.world.save.DimensionData;
 import net.minecraft.core.world.save.ISaveConverter;
@@ -773,19 +773,6 @@ public class Minecraft
         return VERSION;
     }
 
-    @Override
-    public IChunkProvider createChunkProvider(World world, IChunkLoader chunkLoader) {
-        return switch (GameSettings.CHUNK_PROVIDER.value) {
-            case DYNAMIC ->
-                new ChunkProviderDynamic(world, chunkLoader, world.getWorldType().createChunkGenerator(world));
-
-            case THREADED ->
-                new ChunkProviderThreadedClient(world, chunkLoader, world.getWorldType().createChunkGenerator(world));
-
-            default -> new ChunkProviderStatic(world, chunkLoader, world.getWorldType().createChunkGenerator(world));
-        };
-    }
-
     public static File getAppDir(String s) {
         String homeDirPath = System.getProperty("user.home", ".");
         File appDir;
@@ -1398,7 +1385,7 @@ public class Minecraft
         Debug.change("misc");
         this.worldRenderer.getMouseOver(1.0F);
         if (this.thePlayer != null) {
-            IChunkProvider chunkProvider = this.currentWorld.getChunkProvider();
+            ChunkProvider chunkProvider = this.currentWorld.getChunkProvider();
             int playerChunkX = MathHelper.floor_float((int) this.thePlayer.x) >> 4;
             int playerChunkZ = MathHelper.floor_float((int) this.thePlayer.z) >> 4;
             chunkProvider.setCurrentChunkOver(playerChunkX, playerChunkZ);
@@ -1634,8 +1621,8 @@ public class Minecraft
                 TileEntityRenderDispatcher.instance.tick();
 
                 Debug.change("entity");
-                if (this.currentWorld.lightningFlicker > 0) {
-                    this.currentWorld.lightningFlicker--;
+                if (this.currentWorld.getLightningFlicker() > 0) {
+                    this.currentWorld.setLightningFlicker(this.currentWorld.getLightningFlicker() - 1);
                 }
                 try {
                     this.currentWorld.updateEntities();
@@ -2053,6 +2040,7 @@ public class Minecraft
         }
 
         final @NotNull WorldClient world = new WorldClient(
+            this,
             levelStorage,
             worldConfiguration.getFinalWorldName(),
             worldConfiguration.getFinalNumericSeed(),
@@ -2083,7 +2071,7 @@ public class Minecraft
         int worldSaveVersion = 0;
 
         try {
-            LevelData info = new LevelData(new File(this.mcDataDir, "saves/" + worldDirName));
+            LevelData info = LevelData.fromWorldDir(new File(this.mcDataDir, "saves/" + worldDirName));
             worldSaveVersion = info.getSaveVersion();
         } catch (IOException e) {
             worldSaveVersion = this.saveFormat.getSaveVersion();
@@ -2102,7 +2090,7 @@ public class Minecraft
                 dimension = Dimension.OVERWORLD;
             }
 
-            WorldClient world = new WorldClient(saveHandler, null, 0L, dimension, null);
+            WorldClient world = new WorldClient(this, saveHandler, null, 0L, dimension, null);
             this.statsCounter.add(StatList.loadWorldStat, 1);
             this.statsCounter.add(StatList.startGameStat, 1);
             changeWorld(world, i18n.translateKey("gui.loading.label.loading"));
@@ -2179,7 +2167,7 @@ public class Minecraft
         this.sndManager.stopMusic();
         if (this.currentWorld != null) {
             this.currentWorld.saveWorldIndirectly(this.loadingScreen);
-            IChunkLoader loader = this.currentWorld.getLevelStorage().getChunkLoader(this.currentWorld.dimension);
+            ChunkLoader loader = this.currentWorld.getLevelStorage().getChunkLoader(this.currentWorld.dimension);
             if (loader != null) {
                 while (loader.isSaving()) {
                     try {
@@ -2220,7 +2208,7 @@ public class Minecraft
             if (this.particleEngine != null) {
                 this.particleEngine.setWorld(world);
             }
-            IChunkProvider ichunkprovider = world.getChunkProvider();
+            ChunkProvider ichunkprovider = world.getChunkProvider();
             int i = MathHelper.floor_float((int) this.thePlayer.x) >> 4;
             int j = MathHelper.floor_float((int) this.thePlayer.z) >> 4;
             ichunkprovider.setCurrentChunkOver(i, j);
@@ -2297,7 +2285,7 @@ public class Minecraft
         int i = 0;
         int j = (c * 2) / 16 + 1;
         j *= j;
-        IChunkProvider ichunkprovider = this.currentWorld.getChunkProvider();
+        ChunkProvider ichunkprovider = this.currentWorld.getChunkProvider();
         TilePos spawnPoint = this.currentWorld.getSpawnPoint();
         if (this.thePlayer != null) {
             spawnPoint.x = (int) this.thePlayer.x;
@@ -2370,7 +2358,7 @@ public class Minecraft
             bedSpawnCoordinates = this.currentWorld.getSpawnPoint();
             canRespawnAtBed = false;
         }
-        IChunkProvider ichunkprovider = this.currentWorld.getChunkProvider();
+        ChunkProvider ichunkprovider = this.currentWorld.getChunkProvider();
         ichunkprovider.setCurrentChunkOver(bedSpawnCoordinates.x >> 4, bedSpawnCoordinates.z >> 4);
         this.currentWorld.getRespawnLocation();
         this.currentWorld.updateEntityList();
diff --git a/game/client/src/main/java/net/minecraft/client/entity/player/PlayerLocalMultiplayer.java b/game/client/src/main/java/net/minecraft/client/entity/player/PlayerLocalMultiplayer.java
index 9d7e0ed5e..9118aa0d5 100644
--- a/game/client/src/main/java/net/minecraft/client/entity/player/PlayerLocalMultiplayer.java
+++ b/game/client/src/main/java/net/minecraft/client/entity/player/PlayerLocalMultiplayer.java
@@ -209,7 +209,7 @@ public class PlayerLocalMultiplayer extends PlayerLocal implements Player.Player
 	public void respawnPlayer()
     {
         sendInventoryChanged();
-        sendQueue.addToSendQueue(new PacketRespawn((byte)dimension, (byte) Registries.WORLD_TYPES.getNumericIdOfItem(world.worldType)));
+        sendQueue.addToSendQueue(new PacketRespawn((byte)dimension, (byte) Registries.WORLD_TYPES.getNumericIdOfItem(world.getWorldType())));
     }
 
     @Override
diff --git a/game/client/src/main/java/net/minecraft/client/gui/guidebook/mobs/GuidebookPageMob.java b/game/client/src/main/java/net/minecraft/client/gui/guidebook/mobs/GuidebookPageMob.java
index 03c87103b..1a59d37df 100644
--- a/game/client/src/main/java/net/minecraft/client/gui/guidebook/mobs/GuidebookPageMob.java
+++ b/game/client/src/main/java/net/minecraft/client/gui/guidebook/mobs/GuidebookPageMob.java
@@ -15,6 +15,7 @@ import net.minecraft.client.render.renderer.Shaders;
 import net.minecraft.client.render.renderer.State;
 import net.minecraft.client.render.texture.stitcher.TextureRegistry;
 import net.minecraft.client.world.WorldClient;
+import net.minecraft.client.world.WorldEmpty;
 import net.minecraft.core.achievement.stat.StatList;
 import net.minecraft.core.data.registry.recipe.RecipeSymbol;
 import net.minecraft.core.entity.Entity;
@@ -50,7 +51,7 @@ public class GuidebookPageMob
         this.mobInfo = mobInfo;
         Mob example = null;
         try {
-            example = EntityDispatcher.getInstance().createEntityInWorld(mobClass, WorldClient.EMPTY_WORLD);
+            example = EntityDispatcher.getInstance().createEntityInWorld(mobClass, WorldEmpty.INSTANCE);
         } catch (Exception e) {
             LOGGER.error("Failed to create example instance of mob '{}'!", mobClass.getSimpleName(), e);
         }
diff --git a/game/client/src/main/java/net/minecraft/client/gui/hud/HudIngame.java b/game/client/src/main/java/net/minecraft/client/gui/hud/HudIngame.java
index c887c7b46..dffb4cdec 100644
--- a/game/client/src/main/java/net/minecraft/client/gui/hud/HudIngame.java
+++ b/game/client/src/main/java/net/minecraft/client/gui/hud/HudIngame.java
@@ -317,7 +317,7 @@ public class HudIngame extends Gui {
 
                     drawDebugScreenLine("Temperature: " + temperature + " Humidity: " + humidity);
 
-                    WindProvider windProvider = this.mc.currentWorld.worldType.getWindManager();
+                    WindProvider windProvider = this.mc.currentWorld.getWorldType().getWindManager();
                     if (windProvider != null) {
                         float direction = (float) floor100(windProvider.getWindDirection(this.mc.currentWorld, 0.0f, 500.0f, 0.0f));
                         float intensity = (float) floor100(windProvider.getWindIntensity(this.mc.currentWorld, 0.0f, 500.0f, 0.0f));
diff --git a/game/client/src/main/java/net/minecraft/client/gui/hud/component/HudComponentInfoOverlay.java b/game/client/src/main/java/net/minecraft/client/gui/hud/component/HudComponentInfoOverlay.java
index 1ba7ed0f5..6732801a6 100644
--- a/game/client/src/main/java/net/minecraft/client/gui/hud/component/HudComponentInfoOverlay.java
+++ b/game/client/src/main/java/net/minecraft/client/gui/hud/component/HudComponentInfoOverlay.java
@@ -141,7 +141,7 @@ public class HudComponentInfoOverlay
             }
             if (GameSettings.OVERLAY_SHOW_WEATHER.value) {
                 Weather weather = mc.currentWorld.getCurrentWeather();
-                if (weather != null && weather != mc.currentWorld.worldType.getDefaultWeather()) {
+                if (weather != null && weather != mc.currentWorld.getWorldType().getDefaultWeather()) {
                     drawString(I18n.getInstance().translateKey(weather.getNameLanguageKey()), x, y + tsp + lineHeight * line++, GameSettings.OVERLAY_MODE.value == 2 ? 0xFFFF80FF : 0xFFFFFFFF, rightAligned);
                 }
             }
diff --git a/game/client/src/main/java/net/minecraft/client/gui/options/data/OptionsPages.java b/game/client/src/main/java/net/minecraft/client/gui/options/data/OptionsPages.java
index 11b27bd85..21f188e8b 100644
--- a/game/client/src/main/java/net/minecraft/client/gui/options/data/OptionsPages.java
+++ b/game/client/src/main/java/net/minecraft/client/gui/options/data/OptionsPages.java
@@ -32,6 +32,7 @@ import net.minecraft.client.sound.SoundEngine;
 import net.minecraft.client.util.helper.FileOpener;
 import net.minecraft.client.util.helper.JavaProcess;
 import net.minecraft.client.world.WorldClient;
+import net.minecraft.client.world.WorldEmpty;
 import net.minecraft.core.Global;
 import net.minecraft.core.achievement.stat.Stat;
 import net.minecraft.core.achievement.stat.StatList;
@@ -368,7 +369,7 @@ public abstract class OptionsPages {
             .withComponent(new OptionsCategory("gui.options.page.debug.category.utility")
                 .withComponent(new ShortcutComponent("gui.options.page.debug.button.open.model_viewer", () -> {
                                    mc.playerController = new PlayerControllerSP(mc);
-                                   mc.changeWorld(WorldClient.EMPTY_WORLD, "Loading Model Viewer");
+                                   mc.changeWorld(WorldEmpty.INSTANCE, "Loading Model Viewer");
                                    mc.displayScreen(new ScreenModelViewer());
                                }) {
                                    @Override
diff --git a/game/client/src/main/java/net/minecraft/client/net/command/ClientCommandSource.java b/game/client/src/main/java/net/minecraft/client/net/command/ClientCommandSource.java
index 2546a7b1b..2ed5d4e34 100644
--- a/game/client/src/main/java/net/minecraft/client/net/command/ClientCommandSource.java
+++ b/game/client/src/main/java/net/minecraft/client/net/command/ClientCommandSource.java
@@ -121,7 +121,7 @@ public class ClientCommandSource implements CommandSource {
 
     @Override
     public World getWorld(int dimension) {
-        return this.mc.currentWorld.dimension.id == dimension ? this.mc.currentWorld : new World(this.mc.currentWorld, Dimension.getDimensionList().get(dimension));
+        return this.mc.currentWorld.dimension.id == dimension ? this.mc.currentWorld : new WorldClient(this.mc.currentWorld, Dimension.getDimensionList().get(dimension));
     }
 
     public void movePlayerToDimension(Player player, int dimension) {
diff --git a/game/client/src/main/java/net/minecraft/client/net/handler/PacketHandlerClient.java b/game/client/src/main/java/net/minecraft/client/net/handler/PacketHandlerClient.java
index bc37df58f..8e708c319 100644
--- a/game/client/src/main/java/net/minecraft/client/net/handler/PacketHandlerClient.java
+++ b/game/client/src/main/java/net/minecraft/client/net/handler/PacketHandlerClient.java
@@ -69,8 +69,6 @@ import net.minecraft.core.world.data.SynchedEntityData;
 import net.minecraft.core.world.pos.ChunkPos;
 import net.minecraft.core.world.pos.TilePos;
 import net.minecraft.core.world.save.LevelData;
-import net.minecraft.core.world.save.LevelStorageDummy;
-import net.minecraft.core.world.saveddata.SavedDataStorage;
 import net.minecraft.core.world.weather.Weather;
 import net.minecraft.core.world.weather.Weathers;
 import org.jetbrains.annotations.NotNull;
@@ -93,7 +91,6 @@ public class PacketHandlerClient extends PacketHandler {
     private final Minecraft mc;
     private WorldClientMP worldClientMP;
     private boolean started; // Name from b1.2 leak
-    public SavedDataStorage savedDataStorage;
     public List<PlayerProfile> players;
     public HashMap<String, String> playerList = new HashMap<>();
     Random rand;
@@ -102,7 +99,6 @@ public class PacketHandlerClient extends PacketHandler {
         throws IOException {
         this.disconnected = false;
         this.started = false;
-        this.savedDataStorage = new SavedDataStorage(new LevelStorageDummy());
         this.rand = new Random();
         this.mc = minecraft;
         Socket socket = new Socket(InetAddress.getByName(host), port);
@@ -149,7 +145,7 @@ public class PacketHandlerClient extends PacketHandler {
     public void handleLogin(@NotNull PacketLogin packetLogin) {
         this.mc.playerController = new PlayerControllerMP(this.mc, this);
         this.mc.statsCounter.add(StatList.joinMultiplayerStat, 1);
-        this.worldClientMP = new WorldClientMP(this, packetLogin.worldSeed, packetLogin.dimensionId, packetLogin.worldTypeId);
+        this.worldClientMP = new WorldClientMP(this, mc, packetLogin.worldSeed, packetLogin.dimensionId, packetLogin.worldTypeId);
         this.worldClientMP.isClientSide = true;
         this.mc.changeWorld(this.worldClientMP);
         this.mc.thePlayer.dimension = packetLogin.dimensionId;
@@ -686,7 +682,7 @@ public class PacketHandlerClient extends PacketHandler {
     @Override
     public void handleSetSpawnPosition(@NotNull PacketSetSpawnPosition packetSetSpawnPosition) {
         this.mc.thePlayer.setPlayerSpawnPoint(new TilePos(packetSetSpawnPosition.x, packetSetSpawnPosition.y, packetSetSpawnPosition.z));
-        this.mc.currentWorld.getLevelData().setSpawn(packetSetSpawnPosition.x, packetSetSpawnPosition.y, packetSetSpawnPosition.z);
+        this.mc.currentWorld.getLevelData().getSpawnPos().set(packetSetSpawnPosition.x, packetSetSpawnPosition.y, packetSetSpawnPosition.z);
     }
 
     @Override
@@ -749,7 +745,7 @@ public class PacketHandlerClient extends PacketHandler {
     public void handleRespawn(@NotNull PacketRespawn packetRespawn) {
         if (packetRespawn.respawnDimensionId != this.mc.thePlayer.dimension) {
             this.started = false;
-            this.worldClientMP = new WorldClientMP(this, this.worldClientMP.getLevelData().getRandomSeed(), packetRespawn.respawnDimensionId, packetRespawn.respawnWorldTypeId);
+            this.worldClientMP = new WorldClientMP(this, mc, this.worldClientMP.getLevelData().getRandomSeed(), packetRespawn.respawnDimensionId, packetRespawn.respawnWorldTypeId);
             this.worldClientMP.isClientSide = true;
             this.mc.changeWorld(this.worldClientMP);
             this.mc.thePlayer.dimension = packetRespawn.respawnDimensionId;
diff --git a/game/client/src/main/java/net/minecraft/client/render/LightmapHelper.java b/game/client/src/main/java/net/minecraft/client/render/LightmapHelper.java
index c1b375e69..ced5da4e6 100644
--- a/game/client/src/main/java/net/minecraft/client/render/LightmapHelper.java
+++ b/game/client/src/main/java/net/minecraft/client/render/LightmapHelper.java
@@ -12,6 +12,7 @@ import net.minecraft.client.option.GameSettings;
 import net.minecraft.client.option.enums.LightmapStyle;
 import net.minecraft.client.util.helper.Textures;
 import net.minecraft.client.util.helper.Buffer;
+import net.minecraft.client.world.WorldClient;
 import net.minecraft.core.util.helper.Color;
 import net.minecraft.core.util.helper.MathHelper;
 import net.minecraft.core.world.World;
@@ -43,7 +44,7 @@ public class LightmapHelper {
 	}
 	
 	public void setup() {
-		World world = this.mc.currentWorld;
+		WorldClient world = this.mc.currentWorld;
 		if(GameSettings.CUSTOM_LIGHTMAP.value && world != null) {
 			int dimension = world.dimension.id;
 			
@@ -67,7 +68,7 @@ public class LightmapHelper {
 	}
 
 	public void tick() {
-		World world = this.mc.currentWorld;
+		WorldClient world = this.mc.currentWorld;
 		if(world == null) {
 			return;
 		}
@@ -84,7 +85,7 @@ public class LightmapHelper {
 	}
 
 	public void update(float partialTicks) {
-		World world = this.mc.currentWorld;
+		WorldClient world = this.mc.currentWorld;
 
 		if(world == null) {
 			return;
@@ -143,11 +144,11 @@ public class LightmapHelper {
 				}
 				float modifiedSkylight = Math.max(0, skyLightLevel - skyDarken);
 				float light = Math.max(blockLightLevel, modifiedSkylight);
-				brightness = MathHelper.getInterpolate(world.worldType.getBrightnessRamp(), light);
+				brightness = MathHelper.getInterpolate(world.getWorldType().getBrightnessRamp(), light);
 			}else {
 				int modifiedSkylight = Math.max(0, skyLightLevel - world.skyDarken);
 				int light = Math.max(blockLightLevel, modifiedSkylight);
-				brightness = world.worldType.getBrightnessRamp()[light];
+				brightness = world.getWorldType().getBrightnessRamp()[light];
 			}
 			
 			brightness = applyGamma(brightness, GameSettings.BRIGHTNESS.value - 0.5f);
@@ -298,7 +299,7 @@ public class LightmapHelper {
 	}
 
 	public float getBrightnessRemoveMinLight(@NotNull World world, int i) {
-		float brightness = world.worldType.getBrightnessRamp()[i];
+		float brightness = world.getWorldType().getBrightnessRamp()[i];
 		float min = 0.05f;
 
 		return (brightness - min) / (1.0f - min);
diff --git a/game/client/src/main/java/net/minecraft/client/render/RenderGlobal.java b/game/client/src/main/java/net/minecraft/client/render/RenderGlobal.java
index 07e442446..36e126c8b 100644
--- a/game/client/src/main/java/net/minecraft/client/render/RenderGlobal.java
+++ b/game/client/src/main/java/net/minecraft/client/render/RenderGlobal.java
@@ -657,8 +657,8 @@ public class RenderGlobal
     }
 
     public void tick() {
-        float windDirection = this.world.worldType.getWindManager().getWindDirection(this.world, 0.0f, 500f, 0.0f);
-        float windIntensity = this.world.worldType.getWindManager().getWindIntensity(this.world, 0.0f, 500f, 0.0f);
+        float windDirection = this.world.getWorldType().getWindManager().getWindDirection(this.world, 0.0f, 500f, 0.0f);
+        float windIntensity = this.world.getWorldType().getWindManager().getWindIntensity(this.world, 0.0f, 500f, 0.0f);
 
         float dx = -(float) (Math.cos(windDirection * Math.PI * 2) * windIntensity);
         float dz = -(float) (Math.sin(windDirection * Math.PI * 2) * windIntensity);
diff --git a/game/client/src/main/java/net/minecraft/client/render/WorldRenderer.java b/game/client/src/main/java/net/minecraft/client/render/WorldRenderer.java
index 6aaf4e042..96bf0b895 100644
--- a/game/client/src/main/java/net/minecraft/client/render/WorldRenderer.java
+++ b/game/client/src/main/java/net/minecraft/client/render/WorldRenderer.java
@@ -53,7 +53,7 @@ import net.minecraft.core.util.helper.Time;
 import net.minecraft.core.util.phys.HitResult;
 import net.minecraft.core.world.World;
 import net.minecraft.core.world.biome.Biome;
-import net.minecraft.core.world.chunk.provider.IChunkProvider;
+import net.minecraft.core.world.chunk.provider.ChunkProvider;
 import net.minecraft.core.world.weather.Weather;
 import org.lwjgl.opengl.GL41;
 import org.slf4j.Logger;
@@ -595,10 +595,10 @@ public class WorldRenderer {
             Mob activeEntity = camera.mob;
             double viewEntityX = activeEntity.xo + (activeEntity.x - activeEntity.xo) * (double) partialTicks;
             double viewEntityZ = activeEntity.zo + (activeEntity.z - activeEntity.zo) * (double) partialTicks;
-            IChunkProvider iChunkProvider = this.mc.currentWorld.getChunkProvider();
+            ChunkProvider chunkProvider = this.mc.currentWorld.getChunkProvider();
             int chunkX = MathHelper.floor_float((int) viewEntityX) >> 4;
             int chunkZ = MathHelper.floor_float((int) viewEntityZ) >> 4;
-            iChunkProvider.setCurrentChunkOver(chunkX, chunkZ);
+            chunkProvider.setCurrentChunkOver(chunkX, chunkZ);
         }
 
         this.fogManager.updateFogColor(partialTicks);
diff --git a/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelFire.java b/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelFire.java
index 20231603c..a04cb277b 100644
--- a/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelFire.java
+++ b/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelFire.java
@@ -3,6 +3,7 @@ package net.minecraft.client.render.block.model;
 import net.minecraft.client.render.tessellator.TessellatorGeneral;
 import net.minecraft.client.render.texture.stitcher.IconCoordinate;
 import net.minecraft.client.world.WorldClient;
+import net.minecraft.client.world.WorldEmpty;
 import net.minecraft.core.block.Block;
 import net.minecraft.core.block.BlockLogic;
 import net.minecraft.core.block.BlockLogicFire;
@@ -44,7 +45,7 @@ public class BlockModelFire<T extends BlockLogic> extends BlockModelStandard<T>
         int y = tilePos.y();
         int z = tilePos.z();
 
-        if (this.overrideRender || worldSource.isBlockNormalCube(tilePos.down(queryPos)) || BlockLogicFire.canBurn(worldSource, tilePos.down(queryPos)) || worldSource == WorldClient.EMPTY_WORLD) {
+        if (this.overrideRender || worldSource.isBlockNormalCube(tilePos.down(queryPos)) || BlockLogicFire.canBurn(worldSource, tilePos.down(queryPos)) || worldSource == WorldEmpty.INSTANCE) {
             double d8 = (double) x + 0.5D + 0.2D;
             double d9 = ((double) x + 0.5D) - 0.2D;
             double d12 = (double) z + 0.5D + 0.2D;
diff --git a/game/client/src/main/java/net/minecraft/client/render/colorizer/Colorizer.java b/game/client/src/main/java/net/minecraft/client/render/colorizer/Colorizer.java
index 0ec6906a1..06e2ed886 100644
--- a/game/client/src/main/java/net/minecraft/client/render/colorizer/Colorizer.java
+++ b/game/client/src/main/java/net/minecraft/client/render/colorizer/Colorizer.java
@@ -35,7 +35,7 @@ public class Colorizer {
         String path = null;
 
         // First, check for worldtype overrides
-        WorldType worldType = minecraft.currentWorld.worldType;
+        WorldType worldType = minecraft.currentWorld.getWorldType();
         if (worldType == WorldTypes.OVERWORLD_HELL) {
             path = "/assets/minecraft/textures/colormap/" + this.name + "/hell.png";
             this.texturePack = Colorizers.findTexturePackWithFile(minecraft, path);
diff --git a/game/client/src/main/java/net/minecraft/client/render/entity/MobRendererFireflyCluster.java b/game/client/src/main/java/net/minecraft/client/render/entity/MobRendererFireflyCluster.java
index 6c56a558b..2fcb86f46 100644
--- a/game/client/src/main/java/net/minecraft/client/render/entity/MobRendererFireflyCluster.java
+++ b/game/client/src/main/java/net/minecraft/client/render/entity/MobRendererFireflyCluster.java
@@ -6,6 +6,7 @@ import net.minecraft.client.render.renderer.State;
 import net.minecraft.client.render.texture.stitcher.TextureRegistry;
 import net.minecraft.client.render.tessellator.TessellatorGeneral;
 import net.minecraft.client.world.WorldClient;
+import net.minecraft.client.world.WorldEmpty;
 import net.minecraft.core.entity.animal.MobFireflyCluster;
 import net.minecraft.client.render.particle.ParticleFirefly;
 import org.jetbrains.annotations.NotNull;
@@ -21,7 +22,7 @@ public class MobRendererFireflyCluster extends EntityRenderer<MobFireflyCluster>
 
     public MobRendererFireflyCluster() {
         for (int i = 0; i < 20; i++) {
-            final ParticleFirefly fx = new ParticleFirefly(WorldClient.EMPTY_WORLD, this.rand.nextFloat() - 0.5f, this.rand.nextFloat() - 0.5f, 0, 0, 0, 0, 0);
+            final ParticleFirefly fx = new ParticleFirefly(WorldEmpty.INSTANCE, this.rand.nextFloat() - 0.5f, this.rand.nextFloat() - 0.5f, 0, 0, 0, 0, 0);
             fx.noPhysics = true;
             fx.setAge(this.rand.nextInt(20));
             this.fireflies.add(fx);
@@ -67,7 +68,7 @@ public class MobRendererFireflyCluster extends EntityRenderer<MobFireflyCluster>
         if (this.fireflies.size() < 20) {
             for (int i = this.fireflies.size(); i < 20; i++) {
                 if (this.rand.nextInt(4) == 0) continue;
-                final ParticleFirefly fx = new ParticleFirefly(WorldClient.EMPTY_WORLD, this.rand.nextFloat() - 0.5f, this.rand.nextFloat() - 0.5f, 0, 0, 0, 0, entity.getColor().getId());
+                final ParticleFirefly fx = new ParticleFirefly(WorldEmpty.INSTANCE, this.rand.nextFloat() - 0.5f, this.rand.nextFloat() - 0.5f, 0, 0, 0, 0, entity.getColor().getId());
                 fx.noPhysics = true;
                 fx.setAge(this.rand.nextInt(20));
                 this.fireflies.add(fx);
diff --git a/game/client/src/main/java/net/minecraft/client/render/particle/ParticleLeaf.java b/game/client/src/main/java/net/minecraft/client/render/particle/ParticleLeaf.java
index 174fa6963..7a768d0f6 100644
--- a/game/client/src/main/java/net/minecraft/client/render/particle/ParticleLeaf.java
+++ b/game/client/src/main/java/net/minecraft/client/render/particle/ParticleLeaf.java
@@ -40,8 +40,8 @@ public class ParticleLeaf extends Particle {
     @Override
     public void tick() {
         this.cachedLightmapCoord = calcLightIndex(1f);
-        float windDirection = this.world.worldType.getWindManager().getWindDirection(this.world, (float) this.x, (float) this.y, (float) this.z);
-        float windIntensity = this.world.worldType.getWindManager().getWindIntensity(this.world, (float) this.x, (float) this.y, (float) this.z) * 0.01f;
+        float windDirection = this.world.getWorldType().getWindManager().getWindDirection(this.world, (float) this.x, (float) this.y, (float) this.z);
+        float windIntensity = this.world.getWorldType().getWindManager().getWindIntensity(this.world, (float) this.x, (float) this.y, (float) this.z) * 0.01f;
 
         float dx = (float) (Math.cos(windDirection * Math.PI * 2) * windIntensity);
         float dz = (float) (Math.sin(windDirection * Math.PI * 2) * windIntensity);
diff --git a/game/client/src/main/java/net/minecraft/client/render/tileentity/TileEntityRendererMobSpawner.java b/game/client/src/main/java/net/minecraft/client/render/tileentity/TileEntityRendererMobSpawner.java
index 5b20c4cc1..a76932b2f 100644
--- a/game/client/src/main/java/net/minecraft/client/render/tileentity/TileEntityRendererMobSpawner.java
+++ b/game/client/src/main/java/net/minecraft/client/render/tileentity/TileEntityRendererMobSpawner.java
@@ -8,6 +8,7 @@ import net.minecraft.client.render.entity.EntityRenderer;
 import net.minecraft.client.render.renderer.GLRenderer;
 import net.minecraft.client.render.tessellator.TessellatorGeneral;
 import net.minecraft.client.world.WorldClient;
+import net.minecraft.client.world.WorldEmpty;
 import net.minecraft.core.block.entity.TileEntityMobSpawner;
 import net.minecraft.core.entity.Entity;
 import net.minecraft.core.entity.EntityDispatcher;
@@ -33,7 +34,7 @@ public class TileEntityRendererMobSpawner extends TileEntityRenderer<TileEntityM
         GLRenderer.modelM4f().translate((float) x + 0.5F, (float) y, (float) z + 0.5F);
         Entity entity = this.entityHashMap.get(mobSpawner.getMobId());
         if (entity == null) {
-            entity = EntityDispatcher.getInstance().createEntityInWorld(mobSpawner.getMobId(), WorldClient.EMPTY_WORLD);
+            entity = EntityDispatcher.getInstance().createEntityInWorld(mobSpawner.getMobId(), WorldEmpty.INSTANCE);
             this.entityHashMap.put(mobSpawner.getMobId(), entity);
         }
         if (entity != null) {
diff --git a/game/client/src/main/java/net/minecraft/client/world/WorldClient.java b/game/client/src/main/java/net/minecraft/client/world/WorldClient.java
index bc7b6482a..add22177d 100644
--- a/game/client/src/main/java/net/minecraft/client/world/WorldClient.java
+++ b/game/client/src/main/java/net/minecraft/client/world/WorldClient.java
@@ -1,18 +1,26 @@
 package net.minecraft.client.world;
 
+import net.minecraft.client.Minecraft;
 import net.minecraft.client.option.GameSettings;
 import net.minecraft.client.render.camera.ICamera;
 import net.minecraft.client.render.colorizer.Colorizers;
 import net.minecraft.client.render.worldtype.WorldTypeFXDispatcher;
+import net.minecraft.client.world.chunk.provider.ChunkProviderDynamic;
+import net.minecraft.client.world.chunk.provider.ChunkProviderStatic;
+import net.minecraft.client.world.chunk.provider.ChunkProviderThreadedClient;
 import net.minecraft.client.world.chunk.provider.ChunkProviderViewer;
+import net.minecraft.core.Global;
 import net.minecraft.core.entity.player.Player;
 import net.minecraft.core.util.helper.MathHelper;
 import net.minecraft.core.world.Dimension;
 import net.minecraft.core.world.World;
 import net.minecraft.core.world.biome.Biome;
+import net.minecraft.core.world.chunk.ChunkLoader;
+import net.minecraft.core.world.chunk.provider.ChunkProvider;
 import net.minecraft.core.world.pos.TilePos;
 import net.minecraft.core.world.save.LevelData;
 import net.minecraft.core.world.save.LevelStorage;
+import net.minecraft.core.world.save.LevelStorageDummy;
 import net.minecraft.core.world.saveddata.SavedDataStorage;
 import net.minecraft.core.world.season.SeasonManager;
 import net.minecraft.core.world.season.Seasons;
@@ -27,9 +35,11 @@ import org.joml.Vector3f;
 import org.joml.Vector3fc;
 
 public class WorldClient extends World {
-    public static final WorldClient EMPTY_WORLD = new WorldClient();
+    private final @NotNull Minecraft mc;
+    private int lightningFlicker;
 
     public WorldClient(
+        final @NotNull Minecraft mc,
         final @NotNull LevelStorage levelStorage,
         final @Nullable String name,
         final long seed,
@@ -37,35 +47,40 @@ public class WorldClient extends World {
         final @Nullable Biome startingBiome
     ) {
         super(levelStorage, name, seed, dimension, startingBiome);
+
+        this.mc = mc;
     }
 
     public WorldClient(
-        final @NotNull World world,
+        final @NotNull WorldClient parent,
         final @NotNull Dimension dimension
     ) {
-        super(world, dimension);
+        super(parent, dimension);
+
+        this.mc = parent.mc;
     }
 
-    public WorldClient(
-        final @NotNull SavedDataStorage savedDataStorage,
-        final @NotNull String name,
-        final long seed,
-        final @NotNull Dimension dimension,
-        final @NotNull WorldType worldType
-    ) {
-        super(savedDataStorage, name, seed, dimension, worldType);
+    @Override
+    public void setLightningFlicker(final int lightningFlicker) {
+        this.lightningFlicker = lightningFlicker;
     }
 
-    public WorldClient() {
-        this.dimension = Dimension.OVERWORLD;
-        this.worldType = WorldTypes.DEBUG;
-        this.chunkProvider = new ChunkProviderViewer(this);
-        this.seasonManager = SeasonManager.fromConfig(this, this.worldType.getSeasonConfig());
-        updateSkyBrightness();
+    public int getLightningFlicker() {
+        return this.lightningFlicker;
+    }
+
+    @Override
+    protected @NotNull ChunkProvider createChunkProvider(final @NotNull LevelStorage levelStorage) {
+        final ChunkLoader chunkLoader = levelStorage.getChunkLoader(this.dimension);
+        return switch (GameSettings.CHUNK_PROVIDER.value) {
+            case DYNAMIC ->
+                new ChunkProviderDynamic(this, chunkLoader, this.getWorldType().createChunkGenerator(this));
 
-        this.weatherManager = new WeatherManager(this);
+            case THREADED ->
+                new ChunkProviderThreadedClient(this, chunkLoader, this.getWorldType().createChunkGenerator(this));
 
-        this.biomeProvider = this.worldType.createBiomeProvider(this);
+            default -> new ChunkProviderStatic(this, chunkLoader, this.getWorldType().createChunkGenerator(this));
+        };
     }
 
     @Override
@@ -106,7 +121,7 @@ public class WorldClient extends World {
         double y = camera.getY(partialTick);
         double z = camera.getZ(partialTick);
         float celestialAngle = getCelestialAngle(partialTick);
-        return WorldTypeFXDispatcher.getInstance().getDispatch(this.worldType).getFogColor(this, x, y, z, celestialAngle, partialTick);
+        return WorldTypeFXDispatcher.getInstance().getDispatch(this.getWorldType()).getFogColor(this, x, y, z, celestialAngle, partialTick);
     }
 
     public @NotNull Vector3fc getSkyColor(@NotNull ICamera camera, float partialTick) {
diff --git a/game/client/src/main/java/net/minecraft/client/world/WorldClientMP.java b/game/client/src/main/java/net/minecraft/client/world/WorldClientMP.java
index 1cd0a5b1c..b3a826e02 100644
--- a/game/client/src/main/java/net/minecraft/client/world/WorldClientMP.java
+++ b/game/client/src/main/java/net/minecraft/client/world/WorldClientMP.java
@@ -2,6 +2,7 @@ package net.minecraft.client.world;
 
 import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
 import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
+import net.minecraft.client.Minecraft;
 import net.minecraft.client.net.handler.PacketHandlerClient;
 import net.minecraft.client.world.chunk.provider.ChunkProviderClient;
 import net.minecraft.core.block.Block;
@@ -12,11 +13,12 @@ import net.minecraft.core.net.packet.PacketDisconnect;
 import net.minecraft.core.world.Dimension;
 import net.minecraft.core.world.chunk.Chunk;
 import net.minecraft.core.world.chunk.ChunkCoordinates;
-import net.minecraft.core.world.chunk.provider.IChunkProvider;
-import net.minecraft.core.world.save.LevelStorageDummy;
+import net.minecraft.core.world.chunk.provider.ChunkProvider;
 import net.minecraft.core.world.pos.ChunkPos;
 import net.minecraft.core.world.pos.TilePos;
 import net.minecraft.core.world.pos.TilePosc;
+import net.minecraft.core.world.save.LevelStorage;
+import net.minecraft.core.world.save.LevelStorageDummy;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 
@@ -34,16 +36,19 @@ public class WorldClientMP extends WorldClient {
 
     public WorldClientMP(
         final @NotNull PacketHandlerClient packetHandler,
+        final @NotNull Minecraft mc,
         final long seed,
         final int dimensionId,
         final int worldTypeId
     ) {
         super(
-            packetHandler.savedDataStorage,
+            mc,
+            new LevelStorageDummy(),
             "MpServer",
             seed,
             Dimension.getDimensionList().get(dimensionId),
-            Registries.WORLD_TYPES.getItemByNumericId(worldTypeId)
+//            Registries.WORLD_TYPES.getItemByNumericId(worldTypeId)
+            null
         );
 
         this.positionTypesList = new LinkedList<>();
@@ -101,7 +106,7 @@ public class WorldClientMP extends WorldClient {
     }
 
     @Override
-    protected IChunkProvider createChunkProvider() {
+    protected @NotNull ChunkProvider createChunkProvider(final @NotNull LevelStorage levelStorage) {
         this.chunkCache = new ChunkProviderClient(this);
         return this.chunkCache;
     }
diff --git a/game/client/src/main/java/net/minecraft/client/world/WorldEmpty.java b/game/client/src/main/java/net/minecraft/client/world/WorldEmpty.java
new file mode 100644
index 000000000..501578fda
--- /dev/null
+++ b/game/client/src/main/java/net/minecraft/client/world/WorldEmpty.java
@@ -0,0 +1,22 @@
+package net.minecraft.client.world;
+
+import net.minecraft.client.Minecraft;
+import net.minecraft.client.world.chunk.provider.ChunkProviderViewer;
+import net.minecraft.core.world.Dimension;
+import net.minecraft.core.world.chunk.provider.ChunkProvider;
+import net.minecraft.core.world.save.LevelStorage;
+import net.minecraft.core.world.save.LevelStorageDummy;
+import org.jetbrains.annotations.NotNull;
+
+public class WorldEmpty extends WorldClient {
+    public static final @NotNull WorldEmpty INSTANCE = new WorldEmpty(Minecraft.getMinecraft());
+
+    private WorldEmpty(final @NotNull Minecraft mc) {
+        super(mc, new LevelStorageDummy(), "Empty World", 0, Dimension.OVERWORLD, null);
+    }
+
+    @Override
+    protected @NotNull ChunkProvider createChunkProvider(final @NotNull LevelStorage levelStorage) {
+        return new ChunkProviderViewer(this);
+    }
+}
diff --git a/game/client/src/main/java/net/minecraft/client/world/chunk/provider/ChunkProviderClient.java b/game/client/src/main/java/net/minecraft/client/world/chunk/provider/ChunkProviderClient.java
index cb86c1179..f18cc4cca 100644
--- a/game/client/src/main/java/net/minecraft/client/world/chunk/provider/ChunkProviderClient.java
+++ b/game/client/src/main/java/net/minecraft/client/world/chunk/provider/ChunkProviderClient.java
@@ -5,14 +5,15 @@ import net.minecraft.core.world.ProgressListener;
 import net.minecraft.core.world.World;
 import net.minecraft.core.world.chunk.Chunk;
 import net.minecraft.core.world.chunk.EmptyChunk;
-import net.minecraft.core.world.chunk.provider.IChunkProvider;
+import net.minecraft.core.world.chunk.provider.ChunkProvider;
 import net.minecraft.core.world.pos.ChunkPos;
+import net.minecraft.core.world.pos.ChunkPosc;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 
 import java.util.*;
 
-public class ChunkProviderClient implements IChunkProvider {
+public class ChunkProviderClient implements ChunkProvider {
     protected static final @NotNull ChunkPos MIN_POS = new ChunkPos(Integer.MIN_VALUE, Integer.MIN_VALUE);
 
     private final @NotNull Chunk blankChunk;
@@ -30,7 +31,7 @@ public class ChunkProviderClient implements IChunkProvider {
     }
 
     @Override
-    public boolean isChunkLoaded(@NotNull ChunkPos chunkPos) {
+    public boolean isChunkLoaded(@NotNull ChunkPosc chunkPos) {
         if (chunkPos.equals(this.lastQueriedChunkPos)) return true;
         if (this.chunkMapping.containsKey(chunkPos)) {
             this.lastQueriedChunkPos = new ChunkPos(chunkPos);
@@ -41,7 +42,7 @@ public class ChunkProviderClient implements IChunkProvider {
     }
 
     @Override
-    public void regenerateChunk(@NotNull ChunkPos chunkPos) {
+    public void regenerateChunk(@NotNull ChunkPosc chunkPos) {
     }
 
     public void dropChunk(@NotNull ChunkPos chunkPos) {
@@ -53,7 +54,7 @@ public class ChunkProviderClient implements IChunkProvider {
     }
 
     @Override
-    public @NotNull Chunk prepareChunk(@NotNull ChunkPos chunkPos, boolean priority) {
+    public @NotNull Chunk prepareChunk(@NotNull ChunkPosc chunkPos, boolean priority) {
         if (this.chunkMapping.containsKey(chunkPos)) return this.chunkMapping.get(chunkPos);
         Chunk chunk = new Chunk(this.world, new ChunkPos(chunkPos));
         this.chunkMapping.put(chunk.pos, chunk);
@@ -62,11 +63,11 @@ public class ChunkProviderClient implements IChunkProvider {
     }
 
     @Override
-    public @NotNull Chunk provideChunk(@NotNull ChunkPos chunkPos, boolean priority) {
+    public @NotNull Chunk provideChunk(@NotNull ChunkPosc chunkPos, boolean priority) {
         if (chunkPos.equals(this.lastQueriedChunkPos)) return this.lastQueriedChunk;
         Chunk chunk = this.chunkMapping.get(chunkPos);
         if (chunk != null) {
-            this.lastQueriedChunkPos = chunkPos;
+            this.lastQueriedChunkPos.set(chunkPos);
             this.lastQueriedChunk = chunk;
             return chunk;
         }
@@ -93,7 +94,7 @@ public class ChunkProviderClient implements IChunkProvider {
     }
 
     @Override
-    public void populate(@NotNull ChunkPos chunkPos) {
+    public void populate(@NotNull ChunkPosc chunkPos) {
     }
 
     @Override
@@ -102,7 +103,7 @@ public class ChunkProviderClient implements IChunkProvider {
     }
 
     @Override
-    public void setCurrentChunkOver(@NotNull ChunkPos chunkPos) {
+    public void setCurrentChunkOver(@NotNull ChunkPosc chunkPos) {
         // Do nothing
     }
 }
diff --git a/game/client/src/main/java/net/minecraft/client/world/chunk/provider/ChunkProviderDynamic.java b/game/client/src/main/java/net/minecraft/client/world/chunk/provider/ChunkProviderDynamic.java
index fb07bd306..4b651703c 100644
--- a/game/client/src/main/java/net/minecraft/client/world/chunk/provider/ChunkProviderDynamic.java
+++ b/game/client/src/main/java/net/minecraft/client/world/chunk/provider/ChunkProviderDynamic.java
@@ -4,9 +4,10 @@ import com.mojang.logging.LogUtils;
 import net.minecraft.core.world.ProgressListener;
 import net.minecraft.core.world.World;
 import net.minecraft.core.world.chunk.*;
-import net.minecraft.core.world.chunk.provider.IChunkProvider;
+import net.minecraft.core.world.chunk.provider.ChunkProvider;
 import net.minecraft.core.world.generate.chunk.ChunkGenerator;
 import net.minecraft.core.world.pos.ChunkPos;
+import net.minecraft.core.world.pos.ChunkPosc;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 import org.slf4j.Logger;
@@ -14,13 +15,13 @@ import org.slf4j.Logger;
 import java.io.IOException;
 import java.util.*;
 
-public class ChunkProviderDynamic implements IChunkProvider {
+public class ChunkProviderDynamic implements ChunkProvider {
     public static final int CHUNK_RADIUS = 32;
     private static final Logger LOGGER = LogUtils.getLogger();
     private final Set<ChunkPos> droppedChunksSet;
     private final Chunk emptyChunk;
     public @Nullable ChunkGenerator chunkGenerator;
-    private final @Nullable IChunkLoader chunkLoader;
+    private final @Nullable ChunkLoader chunkLoader;
     private final @NotNull Map<@NotNull ChunkPos, @NotNull Chunk> chunkMap;
     private final @NotNull Map<@NotNull ChunkPos, @NotNull Chunk> forceLoadedChunkMap;
     private final @NotNull List<Chunk> forceLoadedChunkList;
@@ -33,7 +34,7 @@ public class ChunkProviderDynamic implements IChunkProvider {
     private int lastQueriedChunkZPos;
     private Chunk lastQueriedChunk;
 
-    public ChunkProviderDynamic(@NotNull World world, @Nullable IChunkLoader chunkLoader, @Nullable ChunkGenerator chunkGenerator) {
+    public ChunkProviderDynamic(@NotNull World world, @Nullable ChunkLoader chunkLoader, @Nullable ChunkGenerator chunkGenerator) {
         this.droppedChunksSet = new HashSet<>();
         this.chunkMap = new HashMap<>();
         this.forceLoadedChunkList = new ArrayList<>();
@@ -45,40 +46,40 @@ public class ChunkProviderDynamic implements IChunkProvider {
     }
 
     @Override
-    public boolean isChunkLoaded(@NotNull ChunkPos chunkPos) {
+    public boolean isChunkLoaded(@NotNull ChunkPosc chunkPos) {
 
         if (canChunkBeUnloaded(chunkPos)) {
-            if (this.chunkMap.containsKey(chunkPos)) this.droppedChunksSet.add(chunkPos);
+            if (this.chunkMap.containsKey(chunkPos)) this.droppedChunksSet.add(new ChunkPos(chunkPos));
             return false;
         }
         Chunk chunk = this.chunkMap.get(chunkPos);
         return chunk == this.emptyChunk || (chunk != null && chunk.isAtLocation(chunkPos));
     }
 
-    public boolean canChunkBeUnloaded(@NotNull ChunkPos chunkPos) {
+    public boolean canChunkBeUnloaded(@NotNull ChunkPosc chunkPos) {
 
         if (this.forceLoadedChunkMap.containsKey(chunkPos)) return false;
         int renderDistance = CHUNK_RADIUS - 1;
-        return !(chunkPos.x >= this.currentChunkX - renderDistance && chunkPos.z >= this.currentChunkZ - renderDistance && chunkPos.x <= this.currentChunkX + renderDistance && chunkPos.z <= this.currentChunkZ + renderDistance);
+        return !(chunkPos.x() >= this.currentChunkX - renderDistance && chunkPos.z() >= this.currentChunkZ - renderDistance && chunkPos.x() <= this.currentChunkX + renderDistance && chunkPos.z() <= this.currentChunkZ + renderDistance);
     }
 
     @Override
-    public @NotNull Chunk provideChunk(@NotNull ChunkPos chunkPos, boolean priority) {
-        if (chunkPos.x == this.lastQueriedChunkXPos && chunkPos.z == this.lastQueriedChunkZPos && this.lastQueriedChunk != null) {
+    public @NotNull Chunk provideChunk(@NotNull ChunkPosc chunkPos, boolean priority) {
+        if (chunkPos.x() == this.lastQueriedChunkXPos && chunkPos.z() == this.lastQueriedChunkZPos && this.lastQueriedChunk != null) {
             return this.lastQueriedChunk;
         }
         if (!this.world.findingSpawnPoint && canChunkBeUnloaded(chunkPos)) return this.emptyChunk;
 
-        if (!isChunkLoaded(chunkPos.x, chunkPos.z)) {
+        if (!isChunkLoaded(chunkPos.x(), chunkPos.z())) {
             if (this.chunkMap.get(chunkPos) != null) {
                 Chunk chunk = this.chunkMap.get(chunkPos);
                 saveChunk(chunk);
                 chunk.onUnload();
             }
-            Chunk chunk = loadChunk(chunkPos.x, chunkPos.z);
+            Chunk chunk = loadChunk(chunkPos.x(), chunkPos.z());
             if (chunk == null) {
                 if (this.chunkGenerator != null) {
-                    chunk = this.chunkGenerator.generate(chunkPos.x, chunkPos.z);
+                    chunk = this.chunkGenerator.generate(chunkPos.x(), chunkPos.z());
                     chunk.fixMissingBlocks();
                 } else {
                     chunk = this.emptyChunk;
@@ -87,60 +88,96 @@ public class ChunkProviderDynamic implements IChunkProvider {
             this.chunkMap.put(new ChunkPos(chunkPos), chunk);
             chunk.checkForLightGaps();
             chunk.onLoad();
-            if (!chunk.isTerrainPopulated && isChunkLoaded(chunkPos.x + 1, chunkPos.z + 1) && isChunkLoaded(chunkPos.x, chunkPos.z + 1) && isChunkLoaded(chunkPos.x + 1, chunkPos.z)) {
-                populate(this, chunkPos.x, chunkPos.z);
+            final @NotNull ChunkPos queryPos = new ChunkPos(chunkPos);
+            if (
+                !chunk.isTerrainPopulated &&
+                isChunkLoaded(chunkPos.add(1, 1, queryPos)) &&
+                isChunkLoaded(chunkPos.add(0, 1, queryPos)) &&
+                isChunkLoaded(chunkPos.add(1, 0, queryPos))
+            ) {
+                populate(chunkPos);
             }
-            if (isChunkLoaded(chunkPos.x - 1, chunkPos.z) && !provideChunk(chunkPos.x - 1, chunkPos.z).isTerrainPopulated && isChunkLoaded(chunkPos.x - 1, chunkPos.z + 1) && isChunkLoaded(chunkPos.x, chunkPos.z + 1) && isChunkLoaded(chunkPos.x - 1, chunkPos.z)) {
-                populate(this, chunkPos.x - 1, chunkPos.z);
+            if (
+                isChunkLoaded(chunkPos.add(-1, 0, queryPos)) && !provideChunk(chunkPos.add(-1, 0, queryPos), true).isTerrainPopulated &&
+                isChunkLoaded(chunkPos.add(-1, 1, queryPos)) &&
+                isChunkLoaded(chunkPos.add(0, 1, queryPos))
+            ) {
+                populate(chunkPos.add(-1, 0, queryPos));
             }
-            if (isChunkLoaded(chunkPos.x, chunkPos.z - 1) && !provideChunk(chunkPos.x, chunkPos.z - 1).isTerrainPopulated && isChunkLoaded(chunkPos.x + 1, chunkPos.z - 1) && isChunkLoaded(chunkPos.x, chunkPos.z - 1) && isChunkLoaded(chunkPos.x + 1, chunkPos.z)) {
-                populate(this, chunkPos.x, chunkPos.z - 1);
+            if (
+                isChunkLoaded(chunkPos.add(0, -1, queryPos)) && !provideChunk(chunkPos.add(0, -1, queryPos), true).isTerrainPopulated &&
+                isChunkLoaded(chunkPos.add(1, -1, queryPos)) &&
+                isChunkLoaded(chunkPos.add(1, 0, queryPos))
+            ) {
+                populate(chunkPos.add(0, -1, queryPos));
             }
-            if (isChunkLoaded(chunkPos.x - 1, chunkPos.z - 1) && !provideChunk(chunkPos.x - 1, chunkPos.z - 1).isTerrainPopulated && isChunkLoaded(chunkPos.x - 1, chunkPos.z - 1) && isChunkLoaded(chunkPos.x, chunkPos.z - 1) && isChunkLoaded(chunkPos.x - 1, chunkPos.z)) {
-                populate(this, chunkPos.x - 1, chunkPos.z - 1);
+            if (
+                isChunkLoaded(chunkPos.add(-1, -1, queryPos)) && !provideChunk(chunkPos.add(-1, -1, queryPos), true).isTerrainPopulated &&
+                isChunkLoaded(chunkPos.add(0, -1, queryPos)) &&
+                isChunkLoaded(chunkPos.add(-1, 0, queryPos))
+            ) {
+                populate(chunkPos.add(-1, -1, queryPos));
             }
             if (this.world.getCurrentWeather() != null) {
                 this.world.getCurrentWeather().doChunkLoadEffect(this.world, chunk);
             }
         }
-        this.lastQueriedChunkXPos = chunkPos.x;
-        this.lastQueriedChunkZPos = chunkPos.z;
+        this.lastQueriedChunkXPos = chunkPos.x();
+        this.lastQueriedChunkZPos = chunkPos.z();
         this.lastQueriedChunk = this.chunkMap.get(chunkPos);
         return this.chunkMap.get(chunkPos);
     }
 
     @Override
-    public @NotNull Chunk prepareChunk(@NotNull ChunkPos chunkPos, boolean priority) {
+    public @NotNull Chunk prepareChunk(@NotNull ChunkPosc chunkPos, boolean priority) {
         return provideChunk(chunkPos, true);
     }
 
     @Override
-    public void regenerateChunk(@NotNull ChunkPos chunkPos) {
+    public void regenerateChunk(@NotNull ChunkPosc chunkPos) {
 
         this.droppedChunksSet.remove(chunkPos);
         this.chunkMap.remove(chunkPos);
         Chunk chunk;
         if (this.chunkGenerator != null) {
-            chunk = this.chunkGenerator.generate(chunkPos.x, chunkPos.z);
+            chunk = this.chunkGenerator.generate(chunkPos.x(), chunkPos.z());
             chunk.fixMissingBlocks();
         } else return;
         this.chunkMap.put(new ChunkPos(chunkPos), chunk);
-        if (!chunk.isTerrainPopulated && isChunkLoaded(chunkPos.x + 1, chunkPos.z + 1) && isChunkLoaded(chunkPos.x, chunkPos.z + 1) && isChunkLoaded(chunkPos.x + 1, chunkPos.z)) {
-            populate(new ChunkPos(chunkPos.x, chunkPos.z));
+        final @NotNull ChunkPos queryPos = new ChunkPos(chunkPos);
+        if (
+            !chunk.isTerrainPopulated &&
+                isChunkLoaded(chunkPos.add(1, 1, queryPos)) &&
+                isChunkLoaded(chunkPos.add(0, 1, queryPos)) &&
+                isChunkLoaded(chunkPos.add(1, 0, queryPos))
+        ) {
+            populate(chunkPos);
         }
-        if (isChunkLoaded(chunkPos.x - 1, chunkPos.z) && !provideChunk(chunkPos.x - 1, chunkPos.z).isTerrainPopulated && isChunkLoaded(chunkPos.x - 1, chunkPos.z + 1) && isChunkLoaded(chunkPos.x, chunkPos.z + 1) && isChunkLoaded(chunkPos.x - 1, chunkPos.z)) {
-            populate(new ChunkPos(chunkPos.x - 1, chunkPos.z));
+        if (
+            isChunkLoaded(chunkPos.add(-1, 0, queryPos)) && !provideChunk(chunkPos.add(-1, 0, queryPos), true).isTerrainPopulated &&
+                isChunkLoaded(chunkPos.add(-1, 1, queryPos)) &&
+                isChunkLoaded(chunkPos.add(0, 1, queryPos))
+        ) {
+            populate(chunkPos.add(-1, 0, queryPos));
         }
-        if (isChunkLoaded(chunkPos.x, chunkPos.z - 1) && !provideChunk(chunkPos.x, chunkPos.z - 1).isTerrainPopulated && isChunkLoaded(chunkPos.x + 1, chunkPos.z - 1) && isChunkLoaded(chunkPos.x, chunkPos.z - 1) && isChunkLoaded(chunkPos.x + 1, chunkPos.z)) {
-            populate(new ChunkPos(chunkPos.x, chunkPos.z - 1));
+        if (
+            isChunkLoaded(chunkPos.add(0, -1, queryPos)) && !provideChunk(chunkPos.add(0, -1, queryPos), true).isTerrainPopulated &&
+                isChunkLoaded(chunkPos.add(1, -1, queryPos)) &&
+                isChunkLoaded(chunkPos.add(1, 0, queryPos))
+        ) {
+            populate(chunkPos.add(0, -1, queryPos));
         }
-        if (isChunkLoaded(chunkPos.x - 1, chunkPos.z - 1) && !provideChunk(chunkPos.x - 1, chunkPos.z - 1).isTerrainPopulated && isChunkLoaded(chunkPos.x - 1, chunkPos.z - 1) && isChunkLoaded(chunkPos.x, chunkPos.z - 1) && isChunkLoaded(chunkPos.x - 1, chunkPos.z)) {
-            populate(new ChunkPos(chunkPos.x - 1, chunkPos.z - 1));
+        if (
+            isChunkLoaded(chunkPos.add(-1, -1, queryPos)) && !provideChunk(chunkPos.add(-1, -1, queryPos), true).isTerrainPopulated &&
+                isChunkLoaded(chunkPos.add(0, -1, queryPos)) &&
+                isChunkLoaded(chunkPos.add(-1, 0, queryPos))
+        ) {
+            populate(chunkPos.add(-1, -1, queryPos));
         }
     }
 
     @Override
-    public void populate(@NotNull ChunkPos chunkPos) {
+    public void populate(@NotNull ChunkPosc chunkPos) {
         Chunk chunk = provideChunk(chunkPos, true);
         if (!chunk.isTerrainPopulated) {
             chunk.isTerrainPopulated = true;
@@ -245,7 +282,7 @@ public class ChunkProviderDynamic implements IChunkProvider {
         return true;
     }
 
-    public @Nullable IChunkLoader getChunkLoader() {
+    public @Nullable ChunkLoader getChunkLoader() {
         return this.chunkLoader;
     }
 
@@ -272,8 +309,8 @@ public class ChunkProviderDynamic implements IChunkProvider {
     }
 
     @Override
-    public void setCurrentChunkOver(@NotNull ChunkPos chunkPos) {
-        this.currentChunkX = chunkPos.x;
-        this.currentChunkZ = chunkPos.z;
+    public void setCurrentChunkOver(@NotNull ChunkPosc chunkPos) {
+        this.currentChunkX = chunkPos.x();
+        this.currentChunkZ = chunkPos.z();
     }
 }
\ No newline at end of file
diff --git a/game/client/src/main/java/net/minecraft/client/world/chunk/provider/ChunkProviderStatic.java b/game/client/src/main/java/net/minecraft/client/world/chunk/provider/ChunkProviderStatic.java
index f19a55cdd..b6a248ca2 100644
--- a/game/client/src/main/java/net/minecraft/client/world/chunk/provider/ChunkProviderStatic.java
+++ b/game/client/src/main/java/net/minecraft/client/world/chunk/provider/ChunkProviderStatic.java
@@ -6,10 +6,11 @@ import net.minecraft.core.world.ProgressListener;
 import net.minecraft.core.world.World;
 import net.minecraft.core.world.chunk.Chunk;
 import net.minecraft.core.world.chunk.EmptyChunk;
-import net.minecraft.core.world.chunk.IChunkLoader;
-import net.minecraft.core.world.chunk.provider.IChunkProvider;
+import net.minecraft.core.world.chunk.ChunkLoader;
+import net.minecraft.core.world.chunk.provider.ChunkProvider;
 import net.minecraft.core.world.generate.chunk.ChunkGenerator;
 import net.minecraft.core.world.pos.ChunkPos;
+import net.minecraft.core.world.pos.ChunkPosc;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 import org.slf4j.Logger;
@@ -18,14 +19,14 @@ import java.io.IOException;
 import java.util.Arrays;
 
 public class ChunkProviderStatic
-    implements IChunkProvider {
+    implements ChunkProvider {
     public static final int CHUNK_RADIUS = 32; // Radius should *always* be a power of 2!
     public static final int CHUNK_MASK = CHUNK_RADIUS * 2 - 1;
 
     private static final Logger LOGGER = LogUtils.getLogger();
     private final Chunk blankChunk;
     public ChunkGenerator chunkGenerator;
-    private final IChunkLoader chunkLoader;
+    private final ChunkLoader chunkLoader;
     private final Chunk[] chunks;
     private final World worldObj;
     int lastQueriedChunkXPos;
@@ -35,7 +36,7 @@ public class ChunkProviderStatic
     private int curChunkY;
 
 
-    public ChunkProviderStatic(World world, IChunkLoader ichunkloader, ChunkGenerator chunkGenerator) {
+    public ChunkProviderStatic(World world, ChunkLoader ichunkloader, ChunkGenerator chunkGenerator) {
         this.chunks = new Chunk[CHUNK_RADIUS * 2 * CHUNK_RADIUS * 2];
         this.lastQueriedChunkXPos = Integer.MIN_VALUE;
         this.lastQueriedChunkZPos = Integer.MIN_VALUE;
@@ -47,75 +48,93 @@ public class ChunkProviderStatic
     }
 
     @Override
-    public void setCurrentChunkOver(@NotNull ChunkPos chunkPos) {
-        this.curChunkX = chunkPos.x;
-        this.curChunkY = chunkPos.z;
+    public void setCurrentChunkOver(@NotNull ChunkPosc chunkPos) {
+        this.curChunkX = chunkPos.x();
+        this.curChunkY = chunkPos.z();
     }
 
-    public boolean canChunkExist(@NotNull ChunkPos chunkPos) {
+    public boolean canChunkExist(@NotNull ChunkPosc chunkPos) {
         byte byte0 = CHUNK_RADIUS - 1;
-        return chunkPos.x >= this.curChunkX - byte0 && chunkPos.z >= this.curChunkY - byte0 && chunkPos.x <= this.curChunkX + byte0 && chunkPos.z <= this.curChunkY + byte0;
+        return chunkPos.x() >= this.curChunkX - byte0 && chunkPos.z() >= this.curChunkY - byte0 && chunkPos.x() <= this.curChunkX + byte0 && chunkPos.z() <= this.curChunkY + byte0;
     }
 
     @Override
-    public void regenerateChunk(@NotNull ChunkPos chunkPos) {
-        int k = chunkPos.x & CHUNK_MASK;
-        int l = chunkPos.z & CHUNK_MASK;
+    public void regenerateChunk(@NotNull ChunkPosc chunkPos) {
+        int k = chunkPos.x() & CHUNK_MASK;
+        int l = chunkPos.z() & CHUNK_MASK;
         int i1 = k + l * CHUNK_RADIUS * 2;
         Chunk newChunk;
         if (this.chunkGenerator != null) {
-            newChunk = this.chunkGenerator.generate(chunkPos.x, chunkPos.z);
+            newChunk = this.chunkGenerator.generate(chunkPos.x(), chunkPos.z());
             newChunk.fixMissingBlocks();
         } else {
             return;
         }
         this.chunks[i1] = newChunk;
-        if (!this.chunks[i1].isTerrainPopulated && isChunkLoaded(chunkPos.x + 1, chunkPos.z + 1) && isChunkLoaded(chunkPos.x, chunkPos.z + 1) && isChunkLoaded(chunkPos.x + 1, chunkPos.z)) {
-            populate(this, chunkPos.x, chunkPos.z);
+        final @NotNull ChunkPos queryPos = new ChunkPos(chunkPos);
+        if (
+            !newChunk.isTerrainPopulated &&
+                isChunkLoaded(chunkPos.add(1, 1, queryPos)) &&
+                isChunkLoaded(chunkPos.add(0, 1, queryPos)) &&
+                isChunkLoaded(chunkPos.add(1, 0, queryPos))
+        ) {
+            populate(chunkPos);
         }
-        if (isChunkLoaded(chunkPos.x - 1, chunkPos.z) && !provideChunk(chunkPos.x - 1, chunkPos.z).isTerrainPopulated && isChunkLoaded(chunkPos.x - 1, chunkPos.z + 1) && isChunkLoaded(chunkPos.x, chunkPos.z + 1) && isChunkLoaded(chunkPos.x - 1, chunkPos.z)) {
-            populate(this, chunkPos.x - 1, chunkPos.z);
+        if (
+            isChunkLoaded(chunkPos.add(-1, 0, queryPos)) && !provideChunk(chunkPos.add(-1, 0, queryPos), true).isTerrainPopulated &&
+                isChunkLoaded(chunkPos.add(-1, 1, queryPos)) &&
+                isChunkLoaded(chunkPos.add(0, 1, queryPos))
+        ) {
+            populate(chunkPos.add(-1, 0, queryPos));
         }
-        if (isChunkLoaded(chunkPos.x, chunkPos.z - 1) && !provideChunk(chunkPos.x, chunkPos.z - 1).isTerrainPopulated && isChunkLoaded(chunkPos.x + 1, chunkPos.z - 1) && isChunkLoaded(chunkPos.x, chunkPos.z - 1) && isChunkLoaded(chunkPos.x + 1, chunkPos.z)) {
-            populate(this, chunkPos.x, chunkPos.z - 1);
+        if (
+            isChunkLoaded(chunkPos.add(0, -1, queryPos)) && !provideChunk(chunkPos.add(0, -1, queryPos), true).isTerrainPopulated &&
+                isChunkLoaded(chunkPos.add(1, -1, queryPos)) &&
+                isChunkLoaded(chunkPos.add(1, 0, queryPos))
+        ) {
+            populate(chunkPos.add(0, -1, queryPos));
         }
-        if (isChunkLoaded(chunkPos.x - 1, chunkPos.z - 1) && !provideChunk(chunkPos.x - 1, chunkPos.z - 1).isTerrainPopulated && isChunkLoaded(chunkPos.x - 1, chunkPos.z - 1) && isChunkLoaded(chunkPos.x, chunkPos.z - 1) && isChunkLoaded(chunkPos.x - 1, chunkPos.z)) {
-            populate(this, chunkPos.x - 1, chunkPos.z - 1);
+        if (
+            isChunkLoaded(chunkPos.add(-1, -1, queryPos)) && !provideChunk(chunkPos.add(-1, -1, queryPos), true).isTerrainPopulated &&
+                isChunkLoaded(chunkPos.add(0, -1, queryPos)) &&
+                isChunkLoaded(chunkPos.add(-1, 0, queryPos))
+        ) {
+            populate(chunkPos.add(-1, -1, queryPos));
         }
     }
 
     @Override
-    public boolean isChunkLoaded(@NotNull ChunkPos chunkPos) {
+    public boolean isChunkLoaded(@NotNull ChunkPosc chunkPos) {
         if (!canChunkExist(chunkPos)) {
             return false;
         }
-        if (chunkPos.x == this.lastQueriedChunkXPos && chunkPos.z == this.lastQueriedChunkZPos && this.lastQueriedChunk != null) {
+        if (chunkPos.x() == this.lastQueriedChunkXPos && chunkPos.z() == this.lastQueriedChunkZPos && this.lastQueriedChunk != null) {
             return true;
         } else {
-            int k = chunkPos.x & CHUNK_MASK;
-            int l = chunkPos.z & CHUNK_MASK;
+            int k = chunkPos.x() & CHUNK_MASK;
+            int l = chunkPos.z() & CHUNK_MASK;
             int chunkIndex = k + l * CHUNK_RADIUS * 2;
-            return this.chunks[chunkIndex] == this.blankChunk || (this.chunks[chunkIndex] != null && this.chunks[chunkIndex].isAtLocation(chunkPos.x, chunkPos.z));
+            return this.chunks[chunkIndex] == this.blankChunk || (this.chunks[chunkIndex] != null && this.chunks[chunkIndex].isAtLocation(chunkPos));
         }
     }
 
     @Override
-    public @NotNull Chunk prepareChunk(@NotNull ChunkPos chunkPos, boolean priority) {
-        return provideChunk(chunkPos.x, chunkPos.z);
+    public @NotNull Chunk prepareChunk(@NotNull ChunkPosc chunkPos, boolean priority) {
+        return provideChunk(chunkPos, priority);
     }
 
     @Override
-    public @NotNull Chunk provideChunk(@NotNull ChunkPos chunkPos, boolean priority) {
-        if (chunkPos.x == this.lastQueriedChunkXPos && chunkPos.z == this.lastQueriedChunkZPos && this.lastQueriedChunk != null) {
+    public @NotNull Chunk provideChunk(@NotNull ChunkPosc chunkPos, boolean priority) {
+        if (chunkPos.x() == this.lastQueriedChunkXPos && chunkPos.z() == this.lastQueriedChunkZPos && this.lastQueriedChunk != null) {
             return this.lastQueriedChunk;
         }
         if (!this.worldObj.findingSpawnPoint && !canChunkExist(chunkPos)) {
             return this.blankChunk;
         }
-        int k = chunkPos.x & CHUNK_MASK;
-        int l = chunkPos.z & CHUNK_MASK;
+        int k = chunkPos.x() & CHUNK_MASK;
+        int l = chunkPos.z() & CHUNK_MASK;
         int i1 = k + l * CHUNK_RADIUS * 2;
-        if (!isChunkLoaded(chunkPos.x, chunkPos.z)) {
+        if (!isChunkLoaded(chunkPos)) {
             if (this.chunks[i1] != null) {
                 saveChunk(this.chunks[i1]);
                 this.chunks[i1].onUnload();
@@ -123,7 +142,7 @@ public class ChunkProviderStatic
             Chunk chunk = loadChunk(chunkPos);
             if (chunk == null) {
                 if (this.chunkGenerator != null) {
-                    chunk = this.chunkGenerator.generate(chunkPos.x, chunkPos.z);
+                    chunk = this.chunkGenerator.generate(chunkPos.x(), chunkPos.z());
                     chunk.fixMissingBlocks();
                 } else {
                     chunk = this.blankChunk;
@@ -134,40 +153,58 @@ public class ChunkProviderStatic
                 this.chunks[i1].checkForLightGaps();
                 this.chunks[i1].onLoad();
             }
-            if (!this.chunks[i1].isTerrainPopulated && isChunkLoaded(chunkPos.x + 1, chunkPos.z + 1) && isChunkLoaded(chunkPos.x, chunkPos.z + 1) && isChunkLoaded(chunkPos.x + 1, chunkPos.z)) {
-                populate(this, chunkPos.x, chunkPos.z);
+            final @NotNull ChunkPos queryPos = new ChunkPos(chunkPos);
+            if (
+                !chunk.isTerrainPopulated &&
+                    isChunkLoaded(chunkPos.add(1, 1, queryPos)) &&
+                    isChunkLoaded(chunkPos.add(0, 1, queryPos)) &&
+                    isChunkLoaded(chunkPos.add(1, 0, queryPos))
+            ) {
+                populate(chunkPos);
             }
-            if (isChunkLoaded(chunkPos.x - 1, chunkPos.z) && !provideChunk(chunkPos.x - 1, chunkPos.z).isTerrainPopulated && isChunkLoaded(chunkPos.x - 1, chunkPos.z + 1) && isChunkLoaded(chunkPos.x, chunkPos.z + 1) && isChunkLoaded(chunkPos.x - 1, chunkPos.z)) {
-                populate(this, chunkPos.x - 1, chunkPos.z);
+            if (
+                isChunkLoaded(chunkPos.add(-1, 0, queryPos)) && !provideChunk(chunkPos.add(-1, 0, queryPos), true).isTerrainPopulated &&
+                    isChunkLoaded(chunkPos.add(-1, 1, queryPos)) &&
+                    isChunkLoaded(chunkPos.add(0, 1, queryPos))
+            ) {
+                populate(chunkPos.add(-1, 0, queryPos));
             }
-            if (isChunkLoaded(chunkPos.x, chunkPos.z - 1) && !provideChunk(chunkPos.x, chunkPos.z - 1).isTerrainPopulated && isChunkLoaded(chunkPos.x + 1, chunkPos.z - 1) && isChunkLoaded(chunkPos.x, chunkPos.z - 1) && isChunkLoaded(chunkPos.x + 1, chunkPos.z)) {
-                populate(this, chunkPos.x, chunkPos.z - 1);
+            if (
+                isChunkLoaded(chunkPos.add(0, -1, queryPos)) && !provideChunk(chunkPos.add(0, -1, queryPos), true).isTerrainPopulated &&
+                    isChunkLoaded(chunkPos.add(1, -1, queryPos)) &&
+                    isChunkLoaded(chunkPos.add(1, 0, queryPos))
+            ) {
+                populate(chunkPos.add(0, -1, queryPos));
             }
-            if (isChunkLoaded(chunkPos.x - 1, chunkPos.z - 1) && !provideChunk(chunkPos.x - 1, chunkPos.z - 1).isTerrainPopulated && isChunkLoaded(chunkPos.x - 1, chunkPos.z - 1) && isChunkLoaded(chunkPos.x, chunkPos.z - 1) && isChunkLoaded(chunkPos.x - 1, chunkPos.z)) {
-                populate(this, chunkPos.x - 1, chunkPos.z - 1);
+            if (
+                isChunkLoaded(chunkPos.add(-1, -1, queryPos)) && !provideChunk(chunkPos.add(-1, -1, queryPos), true).isTerrainPopulated &&
+                    isChunkLoaded(chunkPos.add(0, -1, queryPos)) &&
+                    isChunkLoaded(chunkPos.add(-1, 0, queryPos))
+            ) {
+                populate(chunkPos.add(-1, -1, queryPos));
             }
             if (this.worldObj.getCurrentWeather() != null) {
                 this.worldObj.getCurrentWeather().doChunkLoadEffect(this.worldObj, chunk);
             }
         }
-        this.lastQueriedChunkXPos = chunkPos.x;
-        this.lastQueriedChunkZPos = chunkPos.z;
+        this.lastQueriedChunkXPos = chunkPos.x();
+        this.lastQueriedChunkZPos = chunkPos.z();
         this.lastQueriedChunk = this.chunks[i1];
         return this.chunks[i1];
     }
 
-    private Chunk loadChunk(@NotNull ChunkPos chunkPos) {
+    private Chunk loadChunk(@NotNull ChunkPosc chunkPos) {
         if (this.chunkLoader == null) {
             return this.blankChunk;
         }
         try {
-            Chunk chunk = this.chunkLoader.loadChunk(this.worldObj, chunkPos.x, chunkPos.z);
+            Chunk chunk = this.chunkLoader.loadChunk(this.worldObj, chunkPos.x(), chunkPos.z());
             if (chunk != null) {
                 chunk.lastSaveTime = this.worldObj.getWorldTime();
             }
             return chunk;
         } catch (Exception exception) {
-            LOGGER.error("Error loading chunk at X:{}, Z:{}", chunkPos.x, chunkPos.z, exception);
+            LOGGER.error("Error loading chunk at X:{}, Z:{}", chunkPos.x(), chunkPos.z(), exception);
         }
         return this.blankChunk;
     }
@@ -185,7 +222,7 @@ public class ChunkProviderStatic
     }
 
     @Override
-    public void populate(@NotNull ChunkPos chunkPos) {
+    public void populate(@NotNull ChunkPosc chunkPos) {
         Chunk chunk = provideChunk(chunkPos, true);
         if (!chunk.isTerrainPopulated) {
             chunk.isTerrainPopulated = true;
@@ -254,7 +291,7 @@ public class ChunkProviderStatic
         return "ChunkCache: " + this.chunks.length;
     }
 
-    public IChunkLoader getChunkLoader() {
+    public ChunkLoader getChunkLoader() {
         return this.chunkLoader;
     }
 }
diff --git a/game/client/src/main/java/net/minecraft/client/world/chunk/provider/ChunkProviderThreadedClient.java b/game/client/src/main/java/net/minecraft/client/world/chunk/provider/ChunkProviderThreadedClient.java
index a3466059c..ecc925aff 100644
--- a/game/client/src/main/java/net/minecraft/client/world/chunk/provider/ChunkProviderThreadedClient.java
+++ b/game/client/src/main/java/net/minecraft/client/world/chunk/provider/ChunkProviderThreadedClient.java
@@ -3,24 +3,25 @@ package net.minecraft.client.world.chunk.provider;
 import net.minecraft.client.Minecraft;
 import net.minecraft.core.entity.player.Player;
 import net.minecraft.core.world.World;
-import net.minecraft.core.world.chunk.IChunkLoader;
+import net.minecraft.core.world.chunk.ChunkLoader;
 import net.minecraft.core.world.chunk.provider.ChunkProviderThreaded;
 import net.minecraft.core.world.generate.chunk.ChunkGenerator;
 import net.minecraft.core.world.pos.ChunkPos;
+import net.minecraft.core.world.pos.ChunkPosc;
 import org.jetbrains.annotations.NotNull;
 
 public class ChunkProviderThreadedClient extends ChunkProviderThreaded {
-    public ChunkProviderThreadedClient(@NotNull World world, @NotNull IChunkLoader chunkLoader, @NotNull ChunkGenerator chunkGenerator) {
+    public ChunkProviderThreadedClient(@NotNull World world, @NotNull ChunkLoader chunkLoader, @NotNull ChunkGenerator chunkGenerator) {
         super(world, chunkLoader, chunkGenerator);
     }
 
     @Override
-    protected boolean isChunkValid(@NotNull ChunkPos chunkPos) {
+    protected boolean isChunkValid(@NotNull ChunkPosc chunkPos) {
         Minecraft mc = Minecraft.getMinecraft();
         int rd = this.world.renderDistance() + 1;
         if (this.chunkOver != null) {
-            int dx = this.chunkOver.x - chunkPos.x;
-            int dz = this.chunkOver.z - chunkPos.z;
+            int dx = this.chunkOver.x - chunkPos.x();
+            int dz = this.chunkOver.z - chunkPos.z();
             if (dx <= 2 && dx >= -2 && dz <= 2 && dz >= -2) {
                 return true;
             }
@@ -30,8 +31,8 @@ public class ChunkProviderThreadedClient extends ChunkProviderThreaded {
         if (player != null) {
             int pCX = ((int) player.x >> 4);
             int pCZ = ((int) player.z >> 4);
-            int dx = pCX - chunkPos.x;
-            int dz = pCZ - chunkPos.z;
+            int dx = pCX - chunkPos.x();
+            int dz = pCZ - chunkPos.z();
             return dx <= rd && dx >= -rd && dz <= rd && dz >= -rd;
         }
         return false;
diff --git a/game/client/src/main/java/net/minecraft/client/world/chunk/provider/ChunkProviderViewer.java b/game/client/src/main/java/net/minecraft/client/world/chunk/provider/ChunkProviderViewer.java
index 287109632..6e9f8d6f6 100644
--- a/game/client/src/main/java/net/minecraft/client/world/chunk/provider/ChunkProviderViewer.java
+++ b/game/client/src/main/java/net/minecraft/client/world/chunk/provider/ChunkProviderViewer.java
@@ -5,12 +5,12 @@ import net.minecraft.core.world.World;
 import net.minecraft.core.world.chunk.Chunk;
 import net.minecraft.core.world.chunk.DisplayChunk;
 import net.minecraft.core.world.chunk.EmptyChunk;
-import net.minecraft.core.world.chunk.provider.IChunkProvider;
-import net.minecraft.core.world.pos.ChunkPos;
+import net.minecraft.core.world.chunk.provider.ChunkProvider;
+import net.minecraft.core.world.pos.ChunkPosc;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 
-public class ChunkProviderViewer implements IChunkProvider {
+public class ChunkProviderViewer implements ChunkProvider {
     public final @NotNull Chunk blankChunk;
     public final @NotNull Chunk displayChunk;
 
@@ -20,33 +20,33 @@ public class ChunkProviderViewer implements IChunkProvider {
     }
 
     @Override
-    public boolean isChunkLoaded(@NotNull ChunkPos chunkPos) {
+    public boolean isChunkLoaded(@NotNull ChunkPosc chunkPos) {
         return true;
     }
 
     @Override
-    public @NotNull Chunk provideChunk(@NotNull ChunkPos chunkPos, boolean priority) {
-        if (chunkPos.x == 0 && chunkPos.z == 0) {
+    public @NotNull Chunk provideChunk(@NotNull ChunkPosc chunkPos, boolean priority) {
+        if (chunkPos.x() == 0 && chunkPos.z() == 0) {
             return this.displayChunk;
         }
         return this.blankChunk;
     }
 
     @Override
-    public @NotNull Chunk prepareChunk(@NotNull ChunkPos chunkPos, boolean priority) {
-        if (chunkPos.x == 0 && chunkPos.z == 0) {
+    public @NotNull Chunk prepareChunk(@NotNull ChunkPosc chunkPos, boolean priority) {
+        if (chunkPos.x() == 0 && chunkPos.z() == 0) {
             return this.displayChunk;
         }
         return this.blankChunk;
     }
 
     @Override
-    public void regenerateChunk(@NotNull ChunkPos chunkPos) {
+    public void regenerateChunk(@NotNull ChunkPosc chunkPos) {
 
     }
 
     @Override
-    public void populate(@NotNull ChunkPos chunkPos) {
+    public void populate(@NotNull ChunkPosc chunkPos) {
 
     }
 
@@ -76,7 +76,7 @@ public class ChunkProviderViewer implements IChunkProvider {
     }
 
     @Override
-    public void setCurrentChunkOver(@NotNull ChunkPos chunkPos) {
+    public void setCurrentChunkOver(@NotNull ChunkPosc chunkPos) {
 
     }
 }
diff --git a/game/client/src/main/java/net/minecraft/client/world/save/LevelStorageClientSP.java b/game/client/src/main/java/net/minecraft/client/world/save/LevelStorageClientSP.java
index 2d4ff4e49..cc7207891 100644
--- a/game/client/src/main/java/net/minecraft/client/world/save/LevelStorageClientSP.java
+++ b/game/client/src/main/java/net/minecraft/client/world/save/LevelStorageClientSP.java
@@ -3,12 +3,13 @@ package net.minecraft.client.world.save;
 import com.mojang.nbt.tags.CompoundTag;
 import net.minecraft.core.entity.player.Player;
 import net.minecraft.core.world.chunk.ChunkLoaderRegionAsync;
-import net.minecraft.core.world.chunk.IChunkLoader;
+import net.minecraft.core.world.chunk.ChunkLoader;
 import net.minecraft.core.world.Dimension;
 import net.minecraft.core.world.save.ISaveFormat;
 import net.minecraft.core.world.save.LevelData;
 import net.minecraft.core.world.save.LevelStorageBase;
 import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
 
 import java.io.File;
 import java.util.List;
@@ -36,7 +37,7 @@ public class LevelStorageClientSP
     }
 
     @Override
-    public IChunkLoader getChunkLoader(Dimension dimension)
+    public @Nullable ChunkLoader getChunkLoader(@NotNull Dimension dimension)
     {
         File dimDir = saveFormat.getDimensionRootDir(worldDirName, dimension);
         dimDir.mkdirs();
diff --git a/game/core/src/main/java/net/minecraft/core/MinecraftAccessor.java b/game/core/src/main/java/net/minecraft/core/MinecraftAccessor.java
index 3cda4836e..b7235272a 100644
--- a/game/core/src/main/java/net/minecraft/core/MinecraftAccessor.java
+++ b/game/core/src/main/java/net/minecraft/core/MinecraftAccessor.java
@@ -3,8 +3,8 @@ package net.minecraft.core;
 import net.minecraft.core.entity.SkinVariantList;
 import net.minecraft.core.sound.SoundTypes;
 import net.minecraft.core.world.World;
-import net.minecraft.core.world.chunk.IChunkLoader;
-import net.minecraft.core.world.chunk.provider.IChunkProvider;
+import net.minecraft.core.world.chunk.ChunkLoader;
+import net.minecraft.core.world.chunk.provider.ChunkProvider;
 
 import java.io.File;
 import java.util.Collection;
@@ -13,8 +13,6 @@ public interface MinecraftAccessor
 {
     File getMinecraftDir();
 
-    IChunkProvider createChunkProvider(World world, IChunkLoader chunkLoader);
-
     int getAutosaveTimer();
 
     SkinVariantList getSkinVariantList();
diff --git a/game/core/src/main/java/net/minecraft/core/block/BlockLogicBed.java b/game/core/src/main/java/net/minecraft/core/block/BlockLogicBed.java
index 8e88945a9..bd75af502 100644
--- a/game/core/src/main/java/net/minecraft/core/block/BlockLogicBed.java
+++ b/game/core/src/main/java/net/minecraft/core/block/BlockLogicBed.java
@@ -56,7 +56,7 @@ public class BlockLogicBed
         }
 
         // Explode in invalid dimensions
-        if (!world.worldType.mayRespawn()) {
+        if (!world.getWorldType().mayRespawn()) {
             world.setBlockTypeNotify(tilePos, Blocks.AIR);
             if (world.getBlockType(footPos) == this.block) {
                 world.setBlockTypeNotify(footPos, Blocks.AIR);
diff --git a/game/core/src/main/java/net/minecraft/core/block/entity/TileEntitySeat.java b/game/core/src/main/java/net/minecraft/core/block/entity/TileEntitySeat.java
index c89a1f0d9..96c2e51bc 100644
--- a/game/core/src/main/java/net/minecraft/core/block/entity/TileEntitySeat.java
+++ b/game/core/src/main/java/net/minecraft/core/block/entity/TileEntitySeat.java
@@ -8,6 +8,7 @@ import net.minecraft.core.world.IVehicle;
 import net.minecraft.core.world.World;
 import com.mojang.nbt.tags.CompoundTag;
 import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
 
 public class TileEntitySeat
     extends TileEntity
@@ -105,7 +106,7 @@ public class TileEntitySeat
     }
 
     @Override
-    public void setPassenger(Entity entity) {
+    public void setPassenger(@Nullable Entity entity) {
         this.passenger = entity;
     }
 
diff --git a/game/core/src/main/java/net/minecraft/core/block/entity/TileEntityTrommel.java b/game/core/src/main/java/net/minecraft/core/block/entity/TileEntityTrommel.java
index afa3343fe..af2b60b1d 100644
--- a/game/core/src/main/java/net/minecraft/core/block/entity/TileEntityTrommel.java
+++ b/game/core/src/main/java/net/minecraft/core/block/entity/TileEntityTrommel.java
@@ -24,8 +24,10 @@ import net.minecraft.core.item.ItemStack;
 import net.minecraft.core.player.inventory.container.Container;
 import net.minecraft.core.util.helper.Direction;
 import net.minecraft.core.util.helper.MathHelper;
+import net.minecraft.core.world.Dimension;
 import net.minecraft.core.world.World;
 import net.minecraft.core.world.pos.TilePos;
+import net.minecraft.core.world.save.LevelStorageDummy;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 import org.slf4j.Logger;
@@ -509,44 +511,46 @@ public class TileEntityTrommel extends TileEntity
         }
     }
 
-    public static void main(String[] args) {
-        Blocks.init();
-        Items.init();
-
-        new Registries();
-
-        // Load vanilla recipes
-        DataLoader.loadRecipesFromFile("/recipes/blast_furnace.json");
-        DataLoader.loadRecipesFromFile("/recipes/furnace.json");
-        DataLoader.loadRecipesFromFile("/recipes/trommel.json");
-        DataLoader.loadRecipesFromFile("/recipes/workbench.json");
-
-//        DataLoader.loadDataPacks(this);
-
-        TileEntityTrommel trommel = new TileEntityTrommel();
-        trommel.worldObj = new World();
-
-        trommel.simulateTrommelDrops(10000, Blocks.MUD.getDefaultStack());
-        trommel.simulateTrommelDrops(10000, Blocks.DIRT.getDefaultStack());
-        trommel.simulateTrommelDrops(10000, Blocks.GRAVEL.getDefaultStack());
-        trommel.simulateTrommelDrops(10000, Blocks.SAND.getDefaultStack());
-        trommel.simulateTrommelDrops(10000, Blocks.SOULSAND.getDefaultStack());
-        trommel.simulateTrommelDrops(10000, Blocks.BLOCK_CLAY.getDefaultStack());
-        trommel.simulateTrommelDrops(10000, Blocks.DIRT_SCORCHED_RICH.getDefaultStack());
-    }
-
-    public static void simulate() {
-        TileEntityTrommel trommel = new TileEntityTrommel();
-        trommel.worldObj = new World();
-
-        trommel.simulateTrommelDrops(10000, Blocks.MUD.getDefaultStack());
-        trommel.simulateTrommelDrops(10000, Blocks.DIRT.getDefaultStack());
-        trommel.simulateTrommelDrops(10000, Blocks.GRAVEL.getDefaultStack());
-        trommel.simulateTrommelDrops(10000, Blocks.SAND.getDefaultStack());
-        trommel.simulateTrommelDrops(10000, Blocks.SOULSAND.getDefaultStack());
-        trommel.simulateTrommelDrops(10000, Blocks.BLOCK_CLAY.getDefaultStack());
-        trommel.simulateTrommelDrops(10000, Blocks.DIRT_SCORCHED_RICH.getDefaultStack());
-    }
+    // Move this to client
+//    public static void main(String[] args) {
+//        Blocks.init();
+//        Items.init();
+//
+//        new Registries();
+//
+//        // Load vanilla recipes
+//        DataLoader.loadRecipesFromFile("/recipes/blast_furnace.json");
+//        DataLoader.loadRecipesFromFile("/recipes/furnace.json");
+//        DataLoader.loadRecipesFromFile("/recipes/trommel.json");
+//        DataLoader.loadRecipesFromFile("/recipes/workbench.json");
+//
+////        DataLoader.loadDataPacks(this);
+//
+//        TileEntityTrommel trommel = new TileEntityTrommel();
+//        trommel.worldObj = new World(new LevelStorageDummy(), "TrommelWorld", 0, Dimension.OVERWORLD, null);
+//
+//        trommel.simulateTrommelDrops(10000, Blocks.MUD.getDefaultStack());
+//        trommel.simulateTrommelDrops(10000, Blocks.DIRT.getDefaultStack());
+//        trommel.simulateTrommelDrops(10000, Blocks.GRAVEL.getDefaultStack());
+//        trommel.simulateTrommelDrops(10000, Blocks.SAND.getDefaultStack());
+//        trommel.simulateTrommelDrops(10000, Blocks.SOULSAND.getDefaultStack());
+//        trommel.simulateTrommelDrops(10000, Blocks.BLOCK_CLAY.getDefaultStack());
+//        trommel.simulateTrommelDrops(10000, Blocks.DIRT_SCORCHED_RICH.getDefaultStack());
+//    }
+//
+//    @SuppressWarnings("unused")
+//    public static void simulate() {
+//        TileEntityTrommel trommel = new TileEntityTrommel();
+//        trommel.worldObj = new World(new LevelStorageDummy(), "TrommelWorld", 0, Dimension.OVERWORLD, null);
+//
+//        trommel.simulateTrommelDrops(10000, Blocks.MUD.getDefaultStack());
+//        trommel.simulateTrommelDrops(10000, Blocks.DIRT.getDefaultStack());
+//        trommel.simulateTrommelDrops(10000, Blocks.GRAVEL.getDefaultStack());
+//        trommel.simulateTrommelDrops(10000, Blocks.SAND.getDefaultStack());
+//        trommel.simulateTrommelDrops(10000, Blocks.SOULSAND.getDefaultStack());
+//        trommel.simulateTrommelDrops(10000, Blocks.BLOCK_CLAY.getDefaultStack());
+//        trommel.simulateTrommelDrops(10000, Blocks.DIRT_SCORCHED_RICH.getDefaultStack());
+//    }
 
     @Override
     public void heldTick(World world, Entity holder) {
diff --git a/game/core/src/main/java/net/minecraft/core/data/gamerule/GameRuleCollection.java b/game/core/src/main/java/net/minecraft/core/data/gamerule/GameRuleCollection.java
index defc46d2a..2f545381b 100644
--- a/game/core/src/main/java/net/minecraft/core/data/gamerule/GameRuleCollection.java
+++ b/game/core/src/main/java/net/minecraft/core/data/gamerule/GameRuleCollection.java
@@ -60,7 +60,7 @@ public final class GameRuleCollection
         return out;
     }
 
-    public static GameRuleCollection readFromNBT(CompoundTag tag)
+    public static @NotNull GameRuleCollection readFromNBT(CompoundTag tag)
     {
         GameRuleCollection collection = new GameRuleCollection();
 
diff --git a/game/core/src/main/java/net/minecraft/core/entity/player/Player.java b/game/core/src/main/java/net/minecraft/core/entity/player/Player.java
index c72f07452..758e8f824 100644
--- a/game/core/src/main/java/net/minecraft/core/entity/player/Player.java
+++ b/game/core/src/main/java/net/minecraft/core/entity/player/Player.java
@@ -54,7 +54,7 @@ import net.minecraft.core.world.ICarriable;
 import net.minecraft.core.world.SpawnerMobs;
 import net.minecraft.core.world.World;
 import net.minecraft.core.world.chunk.ChunkCoordinates;
-import net.minecraft.core.world.chunk.provider.IChunkProvider;
+import net.minecraft.core.world.chunk.provider.ChunkProvider;
 import net.minecraft.core.world.pos.TilePos;
 import net.minecraft.core.world.pos.TilePosc;
 import net.minecraft.core.world.weather.Weathers;
@@ -1104,7 +1104,7 @@ public abstract class Player
             if (isPlayerSleeping() || !isAlive()) {
                 return EnumSleepStatus.OTHER_PROBLEM;
             }
-            if (!this.world.worldType.mayRespawn()) {
+            if (!this.world.getWorldType().mayRespawn()) {
                 return EnumSleepStatus.NOT_POSSIBLE_HERE;
             }
             if (java.lang.Math.abs(this.x - (double) x) > 3D || java.lang.Math.abs(this.y - (double) y) > 3D || java.lang.Math.abs(this.z - (double) z) > 3D) {
@@ -1219,7 +1219,7 @@ public abstract class Player
     }
 
     public static @Nullable TilePos getValidBedSpawnCoordinates(@NotNull final World world, @NotNull final TilePos coords) {
-        final IChunkProvider chunkProvider = world.getChunkProvider();
+        final ChunkProvider chunkProvider = world.getChunkProvider();
         chunkProvider.setCurrentChunkOver(coords.x >> 4, coords.z >> 4);
         chunkProvider.prepareChunk(coords.x - 3 >> 4, coords.z - 3 >> 4);
         chunkProvider.prepareChunk(coords.x + 3 >> 4, coords.z - 3 >> 4);
diff --git a/game/core/src/main/java/net/minecraft/core/item/ItemMap.java b/game/core/src/main/java/net/minecraft/core/item/ItemMap.java
index 11b149740..dde2ff1d0 100644
--- a/game/core/src/main/java/net/minecraft/core/item/ItemMap.java
+++ b/game/core/src/main/java/net/minecraft/core/item/ItemMap.java
@@ -60,8 +60,8 @@ public class ItemMap extends Item implements IComplexItem
 				}
 			}
             mapData = new ItemMapSavedData(s);
-			mapData.x = world.getLevelData().getSpawnX();
-			mapData.z = world.getLevelData().getSpawnZ();
+			mapData.x = world.getLevelData().getSpawnPos().x();
+			mapData.z = world.getLevelData().getSpawnPos().z();
 			mapData.scale = scale;
 			mapData.dimension = (byte)world.dimension.id;
 			mapData.setDirty();
@@ -104,8 +104,8 @@ public class ItemMap extends Item implements IComplexItem
 				}
 			}
             mapData = new ItemMapSavedData(s);
-            mapData.x = world.getLevelData().getSpawnX();
-            mapData.z = world.getLevelData().getSpawnZ();
+            mapData.x = world.getLevelData().getSpawnPos().x();
+            mapData.z = world.getLevelData().getSpawnPos().z();
             mapData.scale = scale;
             mapData.dimension = (byte)world.dimension.id;
             mapData.setDirty();
@@ -157,7 +157,7 @@ public class ItemMap extends Item implements IComplexItem
 		final int entityOnMapZ = MathHelper.floor(entity.z - (double) mapCenterZ) / blocksPerPixel + mapHeight / 2;
 
 		int discoverRadius = 128 / blocksPerPixel;
-		if(world.worldType.hasCeiling()) {
+		if(world.getWorldType().hasCeiling()) {
 			discoverRadius /= 2;
 		}
 		
@@ -203,7 +203,7 @@ public class ItemMap extends Item implements IComplexItem
 				int waterDepth = 0;
 				double pixelHeight = 0.0D;
 				
-				if(world.worldType.hasCeiling()) {
+				if(world.getWorldType().hasCeiling()) {
 					//Determine Color (Nether)
 					int rand = blockX + blockZ * 0x389bf;
 					rand = rand * rand * 0x1dd6751 + rand * 11;
diff --git a/game/core/src/main/java/net/minecraft/core/world/Dimension.java b/game/core/src/main/java/net/minecraft/core/world/Dimension.java
index 3ec417331..f4693a627 100644
--- a/game/core/src/main/java/net/minecraft/core/world/Dimension.java
+++ b/game/core/src/main/java/net/minecraft/core/world/Dimension.java
@@ -37,7 +37,7 @@ public class Dimension
 		{
 			return world.getDimensionData();
 		}
-		DimensionData dimensionData = world.getLevelStorage().getDimensionData(this.id);
+		DimensionData dimensionData = world.getLevelStorage().getDimensionData(this);
 		if (dimensionData == null) dimensionData = new DimensionData(this.defaultWorldType);
 		
 		return dimensionData;
diff --git a/game/core/src/main/java/net/minecraft/core/world/IVehicle.java b/game/core/src/main/java/net/minecraft/core/world/IVehicle.java
index a909cf7f5..4aba9a3b2 100644
--- a/game/core/src/main/java/net/minecraft/core/world/IVehicle.java
+++ b/game/core/src/main/java/net/minecraft/core/world/IVehicle.java
@@ -1,6 +1,7 @@
 package net.minecraft.core.world;
 
 import net.minecraft.core.entity.Entity;
+import org.jetbrains.annotations.Nullable;
 
 public interface IVehicle {
     boolean isRemoved();
@@ -9,7 +10,7 @@ public interface IVehicle {
 
     void positionRider();
 
-    void setPassenger(Entity entity);
+    void setPassenger(@Nullable Entity entity);
 
     Entity getPassenger();
 
diff --git a/game/core/src/main/java/net/minecraft/core/world/World.java b/game/core/src/main/java/net/minecraft/core/world/World.java
index b347c3cf2..13fda2270 100644
--- a/game/core/src/main/java/net/minecraft/core/world/World.java
+++ b/game/core/src/main/java/net/minecraft/core/world/World.java
@@ -41,23 +41,18 @@ import net.minecraft.core.world.chunk.ChunkCache;
 import net.minecraft.core.world.chunk.ChunkCoordinate;
 import net.minecraft.core.world.chunk.ChunkCoordinates;
 import net.minecraft.core.world.chunk.ChunkSection;
-import net.minecraft.core.world.chunk.IChunkLoader;
-import net.minecraft.core.world.chunk.provider.IChunkProvider;
+import net.minecraft.core.world.chunk.ChunkLoader;
+import net.minecraft.core.world.chunk.provider.ChunkProvider;
 import net.minecraft.core.world.config.spawning.SpawnerConfig;
 import net.minecraft.core.world.lighting.LightingEngine;
 import net.minecraft.core.world.lighting.LightingEngineLegacy;
 import net.minecraft.core.world.pathfinder.Path;
 import net.minecraft.core.world.pathfinder.PathFinder;
-import net.minecraft.core.world.pos.ChunkPos;
-import net.minecraft.core.world.pos.ChunkTilePos;
-import net.minecraft.core.world.pos.TilePos;
-import net.minecraft.core.world.pos.TilePosc;
+import net.minecraft.core.world.pos.*;
 import net.minecraft.core.world.save.*;
 import net.minecraft.core.world.saveddata.SavedData;
-import net.minecraft.core.world.saveddata.SavedDataStorage;
 import net.minecraft.core.world.season.SeasonManager;
 import net.minecraft.core.world.type.WorldType;
-import net.minecraft.core.world.type.WorldTypeGroups;
 import net.minecraft.core.world.weather.IPrecipitation;
 import net.minecraft.core.world.weather.Weather;
 import net.minecraft.core.world.weather.WeatherManager;
@@ -84,8 +79,8 @@ import static net.minecraft.core.Global.DAY_LENGTH_TICKS;
 import static net.minecraft.core.Global.accessor;
 import static net.minecraft.core.Global.isServer;
 
-public class World implements MutableWorldSource {
-    private static final Logger LOGGER = LogUtils.getLogger();
+public abstract class World implements MutableWorldSource {
+    private static final @NotNull Logger LOGGER = LogUtils.getLogger();
     public static boolean AUTOSAVE = true;
 
     public static final int HEIGHT_BLOCKS = 256;
@@ -108,7 +103,7 @@ public class World implements MutableWorldSource {
     public final @NotNull List<@NotNull Entity> weatherEffects = new ObjectArrayList<>();
     public final @NotNull List<@NotNull AABBdc> collidingBoundingBoxes = new ObjectArrayList<>();
     public final @NotNull List<@NotNull LevelListener> listeners = new ObjectArrayList<>();
-    private final @NotNull Set<@NotNull ChunkCoordinate> positionsToUpdate = new ObjectOpenHashSet<>();
+    private final @NotNull Set<@NotNull ChunkPosc> positionsToUpdate = new ObjectOpenHashSet<>();
     private final @NotNull List<@NotNull Entity> entityBuffer = new ObjectArrayList<>();
     private final @NotNull Set<@NotNull NextTickListEntry> immediatelyUpdatedPositions = new ObjectOpenHashSet<>();
 
@@ -120,19 +115,17 @@ public class World implements MutableWorldSource {
     public int startingRainbowTicks = 0;
     public boolean dayCanHaveRainbow = true;
     public boolean noNeighborUpdate = false;
-    private long lockTimestamp = System.currentTimeMillis();
+
     public final @NotNull Random rand = new Random();
     public final boolean isNewWorld;
-    public Dimension dimension;
-    public WorldType worldType;
-    public IChunkProvider chunkProvider;
+    public final @NotNull Dimension dimension;
+    public final @NotNull ChunkProvider chunkProvider;
     private final @NotNull LevelStorage levelStorage;
     private final @NotNull LevelData levelData;
     private final @NotNull DimensionData dimensionData;
     public boolean findingSpawnPoint;
     protected boolean enoughPlayersSleeping;
-    public final @NotNull SavedDataStorage savedDataStorage;
-    protected final LightingEngine lightingEngine = new LightingEngineLegacy(this);
+    protected final @NotNull LightingEngine lightingEngine = new LightingEngineLegacy(this);
     private boolean updatingTileEntities;
 
     private int caveSoundCounter = this.rand.nextInt(12000);
@@ -141,35 +134,37 @@ public class World implements MutableWorldSource {
     private long runtime = 0;
     public int dayCountLastTick;
 
-    public BiomeProvider biomeProvider;
-    public SeasonManager seasonManager;
+    public final @NotNull BiomeProvider biomeProvider;
+    public final @NotNull SeasonManager seasonManager;
     public WeatherManager weatherManager;
 
     private final @NotNull CommandManager commandManager = new CommandManager(isServer);
     private final @NotNull WireHandler wireHandler = new WireHandler(this);
 
-    //Usually called when a world is loaded or generated (Singleplayer & Server)
-    public World(
-        final @NotNull LevelStorage levelStorage,
-        final @Nullable String name,
+    private World(
         final long seed,
+        final @Nullable String name,
         final @NotNull Dimension dimension,
+        final @NotNull LevelStorage levelStorage,
+        final @Nullable LevelData levelData,
+        final @Nullable DimensionData dimensionData,
         final @Nullable Biome startingBiome
     ) {
+        if (name == null && levelData == null) {
+            throw new IllegalArgumentException("name and levelData cannot both be null!");
+        }
+
         this.levelStorage = levelStorage;
-        this.savedDataStorage = new SavedDataStorage(levelStorage);
 
-        final @Nullable LevelData levelData = levelStorage.getLevelData();
+        // Set up level data
         this.isNewWorld = levelData == null;
-        this.levelData = Objects.requireNonNullElseGet(levelData, () -> new LevelData(seed, name));
+        this.levelData = Objects.requireNonNullElseGet(levelData, () -> new LevelData(seed, Objects.requireNonNull(name)));
 
-        // Provided dimension
+        // Set up dimension data
         this.dimension = dimension;
-        this.dimensionData = Objects.requireNonNullElseGet(levelStorage.getDimensionData(this.dimension.id), () -> new DimensionData(this.dimension.defaultWorldType));
-
-        // World type from dimension data
-        this.worldType = this.dimensionData.getWorldType();
+        this.dimensionData = Objects.requireNonNullElseGet(dimensionData, () -> new DimensionData(this.dimension.defaultWorldType));
 
+        // Set up weather manager
         this.weatherManager = new WeatherManager(this,
             this.dimensionData.getCurrentWeather(),
             this.dimensionData.getNextWeather(),
@@ -177,97 +172,64 @@ public class World implements MutableWorldSource {
             this.dimensionData.getWeatherPower()
         );
 
-        this.chunkProvider = createChunkProvider();
+        // Set up chunk provider
+        this.chunkProvider = this.createChunkProvider(levelStorage);
 
-        this.seasonManager = SeasonManager.fromConfig(this, this.worldType.getSeasonConfig());
+        // Set up season manager
+        this.seasonManager = SeasonManager.fromConfig(this, this.getWorldType().getSeasonConfig());
 
-        this.biomeProvider = this.worldType.createBiomeProvider(this);
-
-        if (this.isNewWorld) {
-            this.worldType.onWorldCreation(this);
-            getInitialSpawnLocation(startingBiome);
-        }
-        updateSkyBrightness();
+        // Set up biome provider
+        this.biomeProvider = this.getWorldType().createBiomeProvider(this);
 
+        // Set up command manager
         this.commandManager.init();
-    }
-
-    //Usually called when going through portals
-    public World(final @NotNull World parent, final @NotNull Dimension dimension) {
-        this.lockTimestamp = parent.lockTimestamp;
-        this.levelStorage = parent.levelStorage;
-        this.dimension = dimension;
 
-        this.levelData = new LevelData(parent.levelData);
-        this.dimensionData = Objects.requireNonNullElseGet(parent.levelStorage.getDimensionData(this.dimension.id), () -> new DimensionData(this.dimension.defaultWorldType));
-
-        this.weatherManager = new WeatherManager(this,
-            this.dimensionData.getCurrentWeather(),
-            this.dimensionData.getNextWeather(),
-            this.dimensionData.getWeatherDuration(),
-            this.dimensionData.getWeatherPower()
-        );
-
-        this.isNewWorld = false;
-
-        // Set up info from dimension data
-        this.worldType = this.dimensionData.getWorldType();
-
-        this.savedDataStorage = new SavedDataStorage(this.levelStorage);
-        this.chunkProvider = createChunkProvider();
-        this.seasonManager = SeasonManager.fromConfig(this, this.worldType.getSeasonConfig());
-
-        this.biomeProvider = this.worldType.createBiomeProvider(this);
-
-        updateSkyBrightness();
-
-        this.commandManager.init();
+        // Do world initialization
+        if (this.isNewWorld && !this.isClientSide) {
+            this.getWorldType().onWorldCreation(this);
+            this.getInitialSpawnLocation(startingBiome);
+        }
+        this.updateSkyBrightness();
     }
 
-    //Usually called when joining a server
+    // Usually called when a world is loaded or generated (Singleplayer & Server)
     public World(
-        final @NotNull SavedDataStorage savedDataStorage,
-        final @NotNull String name,
+        final @NotNull LevelStorage levelStorage,
+        final @Nullable String name,
         final long seed,
         final @NotNull Dimension dimension,
-        final @NotNull WorldType worldType
+        final @Nullable Biome startingBiome
     ) {
-        this.levelStorage = savedDataStorage.getLevelStorage();
-        this.savedDataStorage = savedDataStorage;
-
-        this.levelData = new LevelData(seed, name);
-        this.isNewWorld = false;
-
-        // Provided dimension
-        this.dimension = dimension;
-        this.dimensionData = new DimensionData(worldType);
-
-        // Provided world type
-        this.worldType = worldType;
-
-        this.weatherManager = new WeatherManager(this);
-
-        this.chunkProvider = createChunkProvider();
-
-        this.seasonManager = SeasonManager.fromConfig(this, this.worldType.getSeasonConfig());
-
-        this.biomeProvider = this.worldType.createBiomeProvider(this);
-
-        this.updateSkyBrightness();
-
-        this.commandManager.init();
+        this(
+            seed,
+            name,
+            dimension,
+            levelStorage,
+            levelStorage.getLevelData(),
+            levelStorage.getDimensionData(dimension),
+            startingBiome
+        );
     }
 
-    public World() {
-        this.levelStorage = new LevelStorageDummy();
-        this.savedDataStorage = new SavedDataStorage(this.levelStorage);
-
-        this.isNewWorld = false;
-        this.levelData = new LevelData(0, "Dummy World");
-        this.dimensionData = new DimensionData(WorldTypeGroups.DEFAULT.get(Dimension.OVERWORLD));
+    // Usually called when going through portals
+    public World(
+        final @NotNull World parent,
+        final @NotNull Dimension dimension
+    ) {
+        this(
+            parent.getLevelData().getRandomSeed(),
+            parent.getLevelData().getWorldName(),
+            dimension,
+            parent.levelStorage,
+            new LevelData(parent.levelData),
+            parent.levelStorage.getDimensionData(dimension),
+            null
+        );
     }
 
-    public <T> T getGameRuleValue(GameRule<T> gameRule) {
+    public abstract void setLightningFlicker(final int flicker);
+
+    public <T> T getGameRuleValue(final GameRule<T> gameRule) {
         return this.levelData.getGameRules().getValue(gameRule);
     }
 
@@ -292,47 +254,47 @@ public class World implements MutableWorldSource {
         return this.wireHandler;
     }
 
-    protected IChunkProvider createChunkProvider() {
-        IChunkLoader chunkLoader = this.levelStorage.getChunkLoader(this.dimension);
+    protected abstract @NotNull ChunkProvider createChunkProvider(@NotNull LevelStorage levelStorage); /* {
+        final ChunkLoader chunkLoader = this.levelStorage.getChunkLoader(this.dimension);
         return accessor.createChunkProvider(this, chunkLoader);
-    }
+    }*/
 
-    protected void getInitialSpawnLocation(@Nullable Biome startingBiome) {
+    protected void getInitialSpawnLocation(@Nullable final Biome startingBiome) {
         this.findingSpawnPoint = true;
-        getWorldType().getInitialSpawnLocation(this, startingBiome);
+        this.getWorldType().getInitialSpawnLocation(this, startingBiome);
         this.findingSpawnPoint = false;
     }
 
     public void getRespawnLocation() {
-        getWorldType().getRespawnLocation(this);
+        this.getWorldType().getRespawnLocation(this);
     }
 
-    public int getTopBlock(int x, int z) {
-        int y = this.levelData.getSpawnY() - 1;
-        while (!isAirBlock(x, y + 1, z)) {
+    public int getTopBlock(final int x, final int z) {
+        int y = this.levelData.getSpawnPos().y() - 1;
+        while (!this.isAirBlock(x, y + 1, z)) {
             y++;
         }
-        return getBlockId(x, y, z);
+        return this.getBlockId(x, y, z);
     }
 
-    public void spawnPlayerWithLoadedChunks(Player player, boolean respawning) {
+    public void spawnPlayerWithLoadedChunks(final Player player, final boolean respawning) {
         try {
             if (!respawning) {
-                PlayerIO playerIO = this.levelStorage.getPlayerFileData();
+                final PlayerIO playerIO = this.levelStorage.getPlayerFileData();
                 if (playerIO != null) {
                     playerIO.load(player);
                 }
             }
-            int chunkX = MathHelper.floor_float((int) player.x) / Chunk.CHUNK_SIZE_X;
-            int chunkZ = MathHelper.floor_float((int) player.z) / Chunk.CHUNK_SIZE_Z;
+            final int chunkX = MathHelper.floor_float((int) player.x) / Chunk.CHUNK_SIZE_X;
+            final int chunkZ = MathHelper.floor_float((int) player.z) / Chunk.CHUNK_SIZE_Z;
             this.chunkProvider.setCurrentChunkOver(chunkX, chunkZ);
-            entityJoinedWorld(player);
-        } catch (Exception e) {
+            this.entityJoinedWorld(player);
+        } catch (final Exception e) {
             LOGGER.error("Failed to spawn player with loaded chunks!", e);
         }
     }
 
-    public void saveWorld(boolean saveImmediately, ProgressListener progressUpdate, boolean saveLevelData) {
+    public void saveWorld(final boolean saveImmediately, final ProgressListener progressUpdate, final boolean saveLevelData) {
         if (!this.chunkProvider.canSave()) {
             return;
         }
@@ -342,7 +304,7 @@ public class World implements MutableWorldSource {
                 progressUpdate.progressStart("Saving level data");
             }
 
-            saveWorldData();
+            this.saveWorldData();
         }
 
         if (progressUpdate != null) {
@@ -356,18 +318,17 @@ public class World implements MutableWorldSource {
     }
 
     private void saveWorldData() {
-        checkSessionLock();
+        this.checkSessionLock();
         this.levelStorage.saveLevelDataAndPlayerData(this.levelData, this.players);
         this.levelStorage.saveDimensionData(this.dimension.id, this.dimensionData);
-        this.savedDataStorage.save();
     }
 
-    public boolean pauseScreenSave(int i) {
+    public boolean pauseScreenSave(final int i) {
         if (!this.chunkProvider.canSave()) {
             return true;
         }
         if (i == 0) {
-            saveWorldData();
+            this.saveWorldData();
         }
         return this.chunkProvider.saveChunks(false, null);
     }
@@ -401,7 +362,7 @@ public class World implements MutableWorldSource {
             }
 
             if (temperature == Double.NEGATIVE_INFINITY) {
-                temperature = getBiomeProvider().getTemperature(tilePos.x(), tilePos.z());
+                temperature = this.getBiomeProvider().getTemperature(tilePos.x(), tilePos.z());
                 if (chunk != null) {
                     chunk.setBlockTemperature(tilePos.x() & (Chunk.CHUNK_SIZE_X - 1), tilePos.z() & (Chunk.CHUNK_SIZE_Z - 1), temperature);
                 }
@@ -534,6 +495,7 @@ public class World implements MutableWorldSource {
     public boolean areBlocksLoaded(final @NotNull AABBdc aabb) {
         return this.areBlocksLoaded(new TilePos(aabb.minX(), aabb.minY(), aabb.minZ()), new TilePos(aabb.maxX(), aabb.maxY(), aabb.maxZ()));
     }
+
     public boolean areBlocksLoaded(final @NotNull TilePosc tilePos, final int range) {
         return this.areBlocksLoaded(tilePos.sub(range, range, range, new TilePos()), tilePos.add(range, range, range, new TilePos()));
     }
@@ -572,7 +534,7 @@ public class World implements MutableWorldSource {
         return this.areBlocksLoaded(new TilePos(minX, minY, minZ), new TilePos(maxX, maxY, maxZ));
     }
 
-    public boolean isChunkLoaded(final @NotNull ChunkPos chunkPos) {
+    public boolean isChunkLoaded(final @NotNull ChunkPosc chunkPos) {
         return this.chunkProvider.isChunkLoaded(chunkPos);
     }
 
@@ -590,11 +552,11 @@ public class World implements MutableWorldSource {
         return this.getChunk(new TilePos(x, 0, z));
     }
 
-    public @NotNull Chunk getChunk(final @NotNull ChunkPos chunkPos) {
+    public @NotNull Chunk getChunk(final @NotNull ChunkPosc chunkPos) {
         return this.chunkProvider.provideChunk(chunkPos, true);
     }
 
-    public @NotNull Chunk getChunk(final @NotNull ChunkPos chunkPos, boolean priority) {
+    public @NotNull Chunk getChunk(final @NotNull ChunkPosc chunkPos, final boolean priority) {
         return this.chunkProvider.provideChunk(chunkPos, priority);
     }
 
@@ -769,7 +731,7 @@ public class World implements MutableWorldSource {
     }
 
     public void notifyBlocksOfNeighborChange(final @NotNull TilePosc tilePos, final @NotNull Block<?> block) {
-        TilePos queryPos = new TilePos();
+        final TilePos queryPos = new TilePos();
         this.notifyBlockOfNeighborChange(tilePos.add(Direction.WEST, queryPos), block);
         this.notifyBlockOfNeighborChange(tilePos.add(Direction.EAST, queryPos), block);
         this.notifyBlockOfNeighborChange(tilePos.add(Direction.DOWN, queryPos), block);
@@ -829,7 +791,7 @@ public class World implements MutableWorldSource {
 
         if (first) {
             if (this.getBlockLitInteriorSurface(tilePos)) {
-                TilePos queryPos = new TilePos();
+                final TilePos queryPos = new TilePos();
                 final int lightUp = this.getBlockLightValue_do(tilePos.add(Direction.UP, queryPos), false);
                 final int lightEast = this.getBlockLightValue_do(tilePos.add(Direction.EAST, queryPos), false);
                 final int lightWest = this.getBlockLightValue_do(tilePos.add(Direction.WEST, queryPos), false);
@@ -887,7 +849,7 @@ public class World implements MutableWorldSource {
     }
 
     @Override
-    public byte getSavedLightIndex(@NotNull TilePosc tilePos) {
+    public byte getSavedLightIndex(@NotNull final TilePosc tilePos) {
         if (!tilePos.inBounds(this)) {
             return LightLayer.DEFAULT_LIGHT_INDEX;
         } else if (!this.isBlockLoaded(tilePos)) {
@@ -899,7 +861,7 @@ public class World implements MutableWorldSource {
 
     @Override
     public boolean isRetro() {
-        return this.worldType.isRetro();
+        return this.getWorldType().isRetro();
     }
 
     @Override
@@ -915,22 +877,22 @@ public class World implements MutableWorldSource {
     @Override
     public float getBrightness(final @NotNull TilePosc tilePos, final int lightEmission) {
         final int lightValue = this.getBlockLightValue(tilePos);
-        return this.worldType.getBrightnessRamp()[Math.max(lightValue, lightEmission)];
+        return this.getWorldType().getBrightnessRamp()[Math.max(lightValue, lightEmission)];
     }
 
     @Override
     public byte getLightIndex(final @NotNull TilePosc tilePos, final int lightEmission) {
-        byte lightIndex = getSavedLightIndex(tilePos);
+        byte lightIndex = this.getSavedLightIndex(tilePos);
         lightIndex = LightIndexHelper.max(lightIndex, (byte) lightEmission);
 
         if (this.getBlockLitInteriorSurface(tilePos)) {
-            TilePos queryPos = new TilePos();
-            lightIndex = LightIndexHelper.max(lightIndex, getSavedLightIndex(tilePos.up(queryPos)));
-            lightIndex = LightIndexHelper.max(lightIndex, getSavedLightIndex(tilePos.down(queryPos)));
-            lightIndex = LightIndexHelper.max(lightIndex, getSavedLightIndex(tilePos.east(queryPos)));
-            lightIndex = LightIndexHelper.max(lightIndex, getSavedLightIndex(tilePos.west(queryPos)));
-            lightIndex = LightIndexHelper.max(lightIndex, getSavedLightIndex(tilePos.south(queryPos)));
-            lightIndex = LightIndexHelper.max(lightIndex, getSavedLightIndex(tilePos.north(queryPos)));
+            final TilePos queryPos = new TilePos();
+            lightIndex = LightIndexHelper.max(lightIndex, this.getSavedLightIndex(tilePos.up(queryPos)));
+            lightIndex = LightIndexHelper.max(lightIndex, this.getSavedLightIndex(tilePos.down(queryPos)));
+            lightIndex = LightIndexHelper.max(lightIndex, this.getSavedLightIndex(tilePos.east(queryPos)));
+            lightIndex = LightIndexHelper.max(lightIndex, this.getSavedLightIndex(tilePos.west(queryPos)));
+            lightIndex = LightIndexHelper.max(lightIndex, this.getSavedLightIndex(tilePos.south(queryPos)));
+            lightIndex = LightIndexHelper.max(lightIndex, this.getSavedLightIndex(tilePos.north(queryPos)));
         }
 
         return lightIndex;
@@ -938,35 +900,35 @@ public class World implements MutableWorldSource {
 
     @Override
     public float getLightBrightness(final @NotNull TilePosc tilePos) {
-        return this.worldType.getBrightnessRamp()[this.getBlockLightValue(tilePos)];
+        return this.getWorldType().getBrightnessRamp()[this.getBlockLightValue(tilePos)];
     }
 
     public boolean isDaytime() {
         return this.skyDarken < 4;
     }
 
-    public @Nullable HitResult checkBlockCollisionBetweenPoints(@NotNull Vector3dc start, @NotNull Vector3dc end) {
-        return checkBlockCollisionBetweenPoints(start, end, false, false, false);
+    public @Nullable HitResult checkBlockCollisionBetweenPoints(@NotNull final Vector3dc start, @NotNull final Vector3dc end) {
+        return this.checkBlockCollisionBetweenPoints(start, end, false, false, false);
     }
 
 
-    public @Nullable HitResult checkBlockCollisionBetweenPoints(@NotNull Vector3dc start, @NotNull Vector3dc end, boolean shouldCollideWithFluids) {
-        return checkBlockCollisionBetweenPoints(start, end, shouldCollideWithFluids, false, false);
+    public @Nullable HitResult checkBlockCollisionBetweenPoints(@NotNull final Vector3dc start, @NotNull final Vector3dc end, final boolean shouldCollideWithFluids) {
+        return this.checkBlockCollisionBetweenPoints(start, end, shouldCollideWithFluids, false, false);
     }
 
-    public @Nullable HitResult checkBlockCollisionBetweenPoints(@NotNull Vector3dc start, @NotNull Vector3dc end, boolean shouldCollideWithFluids, boolean ignoreNonColliderBlocks, boolean useSelectorBoxes) {
+    public @Nullable HitResult checkBlockCollisionBetweenPoints(@NotNull final Vector3dc start, @NotNull final Vector3dc end, final boolean shouldCollideWithFluids, final boolean ignoreNonColliderBlocks, final boolean useSelectorBoxes) {
         if (!start.isFinite()) {
             return null;
         }
         if (!end.isFinite()) {
             return null;
         }
-        Vector3d start2 = new Vector3d(start);
-        Vector3d end2 = new Vector3d(end);
-        TilePos blockEnd = new TilePos(end2);
-        TilePos blockStart = new TilePos(start2);
-        final @NotNull Block<?> block = getBlockType(blockStart);
-        int meta = getBlockData(blockStart);
+        final Vector3d start2 = new Vector3d(start);
+        final Vector3d end2 = new Vector3d(end);
+        final TilePos blockEnd = new TilePos(end2);
+        final TilePos blockStart = new TilePos(start2);
+        final @NotNull Block<?> block = this.getBlockType(blockStart);
+        final int meta = this.getBlockData(blockStart);
         final @Nullable AABBdc aabb;
         if (useSelectorBoxes) {
             aabb = block.getSelectionAABB(this, blockStart);
@@ -974,7 +936,7 @@ public class World implements MutableWorldSource {
             aabb = block.getCollisionAABB(this, blockStart);
         }
         if ((!ignoreNonColliderBlocks || aabb != null) && block.canCollideCheck(meta, shouldCollideWithFluids)) {
-            HitResult hitResult = block.collisionRayTrace(this, blockStart, start2, end2, useSelectorBoxes);
+            final HitResult hitResult = block.collisionRayTrace(this, blockStart, start2, end2, useSelectorBoxes);
             if (hitResult != null) {
                 return hitResult;
             }
@@ -1016,9 +978,9 @@ public class World implements MutableWorldSource {
             double d3 = 999D;
             double d4 = 999D;
             double d5 = 999D;
-            double d6 = end2.x - start2.x;
-            double d7 = end2.y - start2.y;
-            double d8 = end2.z - start2.z;
+            final double d6 = end2.x - start2.x;
+            final double d7 = end2.y - start2.y;
+            final double d8 = end2.z - start2.z;
             if (flag2) {
                 d3 = (d - start2.x) / d6;
             }
@@ -1057,7 +1019,7 @@ public class World implements MutableWorldSource {
                 start2.y += d7 * d5;
                 start2.z = d2;
             }
-            Vector3d startCopy = new Vector3d(start2);
+            final Vector3d startCopy = new Vector3d(start2);
             blockStart.x = (int) (startCopy.x = MathHelper.floor(start2.x()));
             if (byte0 == 5) {
                 blockStart.x--;
@@ -1073,16 +1035,16 @@ public class World implements MutableWorldSource {
                 blockStart.z--;
                 startCopy.z++;
             }
-            final @NotNull Block<?> block1 = getBlockType(blockStart);
+            final @NotNull Block<?> block1 = this.getBlockType(blockStart);
             final @Nullable AABBdc aabb1;
             if (useSelectorBoxes) {
                 aabb1 = block1.getSelectionAABB(this, blockStart);
             } else {
                 aabb1 = block1.getCollisionAABB(this, blockStart);
             }
-            int metadata1 = getBlockData(blockStart);
+            final int metadata1 = this.getBlockData(blockStart);
             if ((!ignoreNonColliderBlocks || aabb1 != null) && block1.canCollideCheck(metadata1, shouldCollideWithFluids)) {
-                HitResult hitResult = block1.collisionRayTrace(this, blockStart, start2, end2, useSelectorBoxes);
+                final HitResult hitResult = block1.collisionRayTrace(this, blockStart, start2, end2, useSelectorBoxes);
                 if (hitResult != null) {
                     return hitResult;
                 }
@@ -1092,32 +1054,32 @@ public class World implements MutableWorldSource {
         return null;
     }
 
-    public void playSoundAtEntity(@Nullable Entity player, @NotNull Entity entity, String soundPath, float volume, float pitch) {
-        for (LevelListener listener : this.listeners) {
+    public void playSoundAtEntity(@Nullable final Entity player, @NotNull final Entity entity, final String soundPath, final float volume, final float pitch) {
+        for (final LevelListener listener : this.listeners) {
             listener.playSound(player, soundPath, SoundCategory.ENTITY_SOUNDS, entity.x, entity.y - (double) entity.heightOffset, entity.z, volume, pitch);
         }
 
     }
 
-    public void playSoundEffect(@Nullable Entity player, SoundCategory category, double x, double y, double z, String soundPath,
-                                float volume, float pitch) {
-        for (LevelListener listener : this.listeners) {
+    public void playSoundEffect(@Nullable final Entity player, final SoundCategory category, final double x, final double y, final double z, final String soundPath,
+                                final float volume, final float pitch) {
+        for (final LevelListener listener : this.listeners) {
             listener.playSound(player, soundPath, category, x, y, z, volume, pitch);
         }
     }
 
-    public void playBlockSoundEffect(@Nullable Entity player, double x, double y, double z, final @NotNull Block<?> block, EnumBlockSoundEffectType soundType) {
-        BlockSound sound = block.getSound();
+    public void playBlockSoundEffect(@Nullable final Entity player, final double x, final double y, final double z, final @NotNull Block<?> block, final EnumBlockSoundEffectType soundType) {
+        final BlockSound sound = block.getSound();
         if (sound == null) return;
 
-        String name;
+        final String name;
         if (soundType == EnumBlockSoundEffectType.MINE) {
             name = sound.getBreakSoundName();
         } else {
             name = sound.getStepSoundName();
         }
 
-        playSoundEffect(player, SoundCategory.WORLD_SOUNDS, x, y, z, name, soundType.modifyVolume(sound.getVolume()), soundType.modifyPitch(sound.getPitch()));
+        this.playSoundEffect(player, SoundCategory.WORLD_SOUNDS, x, y, z, name, soundType.modifyVolume(sound.getVolume()), soundType.modifyPitch(sound.getPitch()));
     }
 
     public void playRecord(final @Nullable String soundPath, final @Nullable String author, final @NotNull TilePos tilePos) {
@@ -1163,40 +1125,40 @@ public class World implements MutableWorldSource {
         this.rainbowTicks = this.startingRainbowTicks = rainbowTicks;
     }
 
-    public boolean entityJoinedWorld(Entity entity) {
-        int i = MathHelper.floor(entity.x / Chunk.CHUNK_SIZE_X);
-        int j = MathHelper.floor(entity.z / Chunk.CHUNK_SIZE_Z);
-        boolean flag = entity instanceof Player;
-        if (flag || isChunkLoaded(i, j)) {
-            if (entity instanceof Player entityplayer) {
+    public boolean entityJoinedWorld(final Entity entity) {
+        final int i = MathHelper.floor(entity.x / Chunk.CHUNK_SIZE_X);
+        final int j = MathHelper.floor(entity.z / Chunk.CHUNK_SIZE_Z);
+        final boolean flag = entity instanceof Player;
+        if (flag || this.isChunkLoaded(i, j)) {
+            if (entity instanceof final Player entityplayer) {
                 this.players.add(entityplayer);
-                updateEnoughPlayersSleepingFlag(null);
+                this.updateEnoughPlayersSleepingFlag(null);
             }
 
-            getChunkFromChunkCoords(i, j).addEntity(entity);
+            this.getChunkFromChunkCoords(i, j).addEntity(entity);
             this.entities.add(entity);
-            obtainEntitySkin(entity);
+            this.obtainEntitySkin(entity);
             return true;
         } else {
             return false;
         }
     }
 
-    protected void obtainEntitySkin(Entity entity) {
+    protected void obtainEntitySkin(final Entity entity) {
         for (int i = 0; i < this.listeners.size(); i++) {
             this.listeners.get(i).entityAdded(entity);
         }
 
     }
 
-    protected void releaseEntitySkin(Entity entity) {
+    protected void releaseEntitySkin(final Entity entity) {
         for (int i = 0; i < this.listeners.size(); i++) {
             this.listeners.get(i).entityRemoved(entity);
         }
 
     }
 
-    public void setEntityDead(Entity entity) {
+    public void setEntityDead(final Entity entity) {
         if (entity.passenger != null) {
             entity.passenger.startRiding(null);
         }
@@ -1206,49 +1168,49 @@ public class World implements MutableWorldSource {
         entity.remove();
         if (entity instanceof Player) {
             this.players.remove((Player) entity);
-            updateEnoughPlayersSleepingFlag(null);
+            this.updateEnoughPlayersSleepingFlag(null);
         }
     }
 
-    public void removePlayer(Entity entity) {
+    public void removePlayer(final Entity entity) {
         entity.remove();
         if (entity instanceof Player) {
             this.players.remove((Player) entity);
-            updateEnoughPlayersSleepingFlag(null);
+            this.updateEnoughPlayersSleepingFlag(null);
         }
-        int i = entity.chunkCoordX;
-        int j = entity.chunkCoordZ;
-        if (entity.addedToChunk && isChunkLoaded(i, j)) {
-            getChunkFromChunkCoords(i, j).removeEntity(entity);
+        final int i = entity.chunkCoordX;
+        final int j = entity.chunkCoordZ;
+        if (entity.addedToChunk && this.isChunkLoaded(i, j)) {
+            this.getChunkFromChunkCoords(i, j).removeEntity(entity);
         }
         this.entities.remove(entity);
-        releaseEntitySkin(entity);
+        this.releaseEntitySkin(entity);
     }
 
-    public void addListener(@NotNull LevelListener levelListener) {
+    public void addListener(@NotNull final LevelListener levelListener) {
         this.listeners.add(levelListener);
     }
 
-    public void removeListener(@NotNull LevelListener levelListener) {
+    public void removeListener(@NotNull final LevelListener levelListener) {
         this.listeners.remove(levelListener);
     }
 
-    public @NotNull List<@NotNull AABBdc> getCubes(@NotNull Entity entity, @NotNull AABBdc aabb) {
-        TilePos d = new TilePos(entity);
+    public @NotNull List<@NotNull AABBdc> getCubes(@NotNull final Entity entity, @NotNull final AABBdc aabb) {
+        final TilePos d = new TilePos(entity);
         this.collidingBoundingBoxes.clear();
 
-        int minX = MathHelper.floor(aabb.minX());
-        int maxX = MathHelper.floor(aabb.maxX() + 1.0D);
-        int minY = MathHelper.floor(aabb.minY());
-        int maxY = MathHelper.floor(aabb.maxY() + 1.0D);
-        int minZ = MathHelper.floor(aabb.minZ());
-        int maxZ = MathHelper.floor(aabb.maxZ() + 1.0D);
-
-        ChunkPos p = new ChunkPos(0, 0);
-        int cMinX = minX >> 4;
-        int cMaxX = maxX >> 4;
-        int cMinZ = minZ >> 4;
-        int cMaxZ = maxZ >> 4;
+        final int minX = MathHelper.floor(aabb.minX());
+        final int maxX = MathHelper.floor(aabb.maxX() + 1.0D);
+        final int minY = MathHelper.floor(aabb.minY());
+        final int maxY = MathHelper.floor(aabb.maxY() + 1.0D);
+        final int minZ = MathHelper.floor(aabb.minZ());
+        final int maxZ = MathHelper.floor(aabb.maxZ() + 1.0D);
+
+        final ChunkPos p = new ChunkPos(0, 0);
+        final int cMinX = minX >> 4;
+        final int cMaxX = maxX >> 4;
+        final int cMinZ = minZ >> 4;
+        final int cMaxZ = maxZ >> 4;
         for (p.x = cMinX; p.x <= cMaxX; p.x++) {
             for (p.z = cMinZ; p.z <= cMaxZ; p.z++) {
                 if (!this.chunkProvider.isChunkLoaded(p)) {
@@ -1260,8 +1222,8 @@ public class World implements MutableWorldSource {
         for (d.x = minX - 1; d.x <= maxX; d.x++) {
             for (d.z = minZ - 1; d.z <= maxZ; d.z++) {
                 for (d.y = minY - 1; d.y <= maxY; d.y++) {
-                    Block<?> block = getBlockType(d);
-                    int metadata = getBlockData(d);
+                    final Block<?> block = this.getBlockType(d);
+                    final int metadata = this.getBlockData(d);
                     if (block.collidesWithEntity(entity, this, d) && entity.collidesWithBlock(block, metadata)) {
                         block.getCollisionAABBs(this, d, aabb, this.collidingBoundingBoxes);
                     }
@@ -1269,10 +1231,10 @@ public class World implements MutableWorldSource {
             }
         }
 
-        double radius = 0.25D;
-        List<Entity> entities = getEntitiesWithinAABBExcludingEntity(entity, MathHelper.aabbGrow(aabb, radius, radius, radius, new AABBd()));
-        for (Entity e : entities) {
-            AABBdc entityBB = e.getCollisionAABB();
+        final double radius = 0.25D;
+        final List<Entity> entities = this.getEntitiesWithinAABBExcludingEntity(entity, MathHelper.aabbGrow(aabb, radius, radius, radius, new AABBd()));
+        for (final Entity e : entities) {
+            final AABBdc entityBB = e.getCollisionAABB();
             if (entityBB != null && entityBB.intersectsAABB((AABBd) aabb)) {
                 this.collidingBoundingBoxes.add(entityBB);
             }
@@ -1281,22 +1243,22 @@ public class World implements MutableWorldSource {
         return this.collidingBoundingBoxes;
     }
 
-    public @NotNull List<@NotNull AABBdc> getCollidingSolidBlockBoundingBoxes(@Nullable Entity entity, @NotNull AABBdc aabb) {
+    public @NotNull List<@NotNull AABBdc> getCollidingSolidBlockBoundingBoxes(@Nullable final Entity entity, @NotNull final AABBdc aabb) {
         this.collidingBoundingBoxes.clear();
-        int minX = MathHelper.floor(aabb.minX());
-        int maxX = MathHelper.floor(aabb.maxX() + 1.0D);
-        int minY = MathHelper.floor(aabb.minY());
-        int maxY = MathHelper.floor(aabb.maxY() + 1.0D);
-        int minZ = MathHelper.floor(aabb.minZ());
-        int maxZ = MathHelper.floor(aabb.maxZ() + 1.0D);
-        TilePos tilePos = new TilePos(0, 0, 0);
+        final int minX = MathHelper.floor(aabb.minX());
+        final int maxX = MathHelper.floor(aabb.maxX() + 1.0D);
+        final int minY = MathHelper.floor(aabb.minY());
+        final int maxY = MathHelper.floor(aabb.maxY() + 1.0D);
+        final int minZ = MathHelper.floor(aabb.minZ());
+        final int maxZ = MathHelper.floor(aabb.maxZ() + 1.0D);
+        final TilePos tilePos = new TilePos(0, 0, 0);
         for (tilePos.x = minX - 1; tilePos.x <= maxX; tilePos.x++) {
             for (tilePos.z = minZ - 1; tilePos.z <= maxZ; tilePos.z++) {
-                if (!isBlockLoaded(tilePos.x, 64, tilePos.z)) {
+                if (!this.isBlockLoaded(tilePos.x, 64, tilePos.z)) {
                     continue;
                 }
                 for (tilePos.y = minY - 1; tilePos.y <= maxY; tilePos.y++) {
-                    Block<?> block = getBlockType(tilePos);
+                    final Block<?> block = this.getBlockType(tilePos);
                     if (block != null && block.isSolidRender()) {
                         // ignore mesh blocks if entity is instance of an item
                         if (!(entity instanceof EntityItem && (block.id() == Blocks.MESH.id() || block.id() == Blocks.SPIKES.id() || block.id() == Blocks.MOBSPAWNER.id())))
@@ -1308,10 +1270,10 @@ public class World implements MutableWorldSource {
 
         }
 
-        double d = 0.25D;
-        List<Entity> list = getEntitiesWithinAABBExcludingEntity(entity, MathHelper.aabbGrow(aabb, d, d, d, new AABBd()));
+        final double d = 0.25D;
+        final List<Entity> list = this.getEntitiesWithinAABBExcludingEntity(entity, MathHelper.aabbGrow(aabb, d, d, d, new AABBd()));
         for (int j2 = 0; j2 < list.size(); j2++) {
-            AABBdc collisionBB = list.get(j2).getCollisionAABB();
+            final AABBdc collisionBB = list.get(j2).getCollisionAABB();
             if (collisionBB != null && collisionBB.intersectsAABB((AABBd) aabb)) {
                 this.collidingBoundingBoxes.add(collisionBB);
             }
@@ -1320,20 +1282,20 @@ public class World implements MutableWorldSource {
         return this.collidingBoundingBoxes;
     }
 
-    public float getAmbientBrightness(float partialTicks) {
-        float angle = getCelestialAngle(partialTicks);
+    public float getAmbientBrightness(final float partialTicks) {
+        final float angle = this.getCelestialAngle(partialTicks);
         float bright = 1.0F - (MathHelper.cos(angle * MathHelper.PI * 2.0F) * 2.0F + 0.2F);
         bright = 1.0f - MathHelper.clamp(bright, 0.0f, 1.0f);
 
-        Weather weather = this.weatherManager.getCurrentWeather();
+        final Weather weather = this.weatherManager.getCurrentWeather();
         if (weather != null) {
             // TODO Unhardcode somehow
             if (weather == Weathers.OVERWORLD_RAIN) {
-                float power = this.weatherManager.getWeatherIntensity() * this.weatherManager.getWeatherPower();
+                final float power = this.weatherManager.getWeatherIntensity() * this.weatherManager.getWeatherPower();
                 bright = (float) (bright * (1.0 - (power * 5.0f) / 16.0));
             }
             if (weather == Weathers.OVERWORLD_STORM) {
-                float power = this.weatherManager.getWeatherIntensity() * this.weatherManager.getWeatherPower();
+                final float power = this.weatherManager.getWeatherIntensity() * this.weatherManager.getWeatherPower();
                 bright = (float) (bright * (1.0 - (power * 5.0f) / 16.0));
                 bright = (float) (bright * (1.0 - (power * 5.0f) / 16.0));
             }
@@ -1343,21 +1305,21 @@ public class World implements MutableWorldSource {
     }
 
     public float getCelestialAngle(float partialTick) {
-        if (!getGameRuleValue(GameRules.DO_DAY_CYCLE)) {
+        if (!this.getGameRuleValue(GameRules.DO_DAY_CYCLE)) {
             partialTick = 1.0f;
         }
-        return this.worldType.getCelestialAngle(this, this.levelData.getWorldTime(), partialTick);
+        return this.getWorldType().getCelestialAngle(this, this.levelData.getWorldTime(), partialTick);
     }
 
 
     public int findTopSolidBlock(int x, int z) {
-        Chunk chunk = getChunkFromBlockCoords(x, z);
-        int y = getHeightBlocks() - 1;
+        final Chunk chunk = this.getChunkFromBlockCoords(x, z);
+        int y = this.getHeightBlocks() - 1;
         x &= (Chunk.CHUNK_SIZE_X - 1);
         z &= (Chunk.CHUNK_SIZE_Z - 1);
         while (y > 0) {
-            int id = chunk.getBlockID(x, y, z);
-            Material material = id != 0 ? Blocks.blocksList[id].getMaterial() : Materials.AIR;
+            final int id = chunk.getBlockID(x, y, z);
+            final Material material = id != 0 ? Blocks.blocksList[id].getMaterial() : Materials.AIR;
             if (!material.blocksMotion() && !material.isLiquid()) {
                 y--;
             } else {
@@ -1368,13 +1330,13 @@ public class World implements MutableWorldSource {
     }
 
     public int findTopSolidNonLiquidBlock(int x, int z) {
-        Chunk chunk = getChunkFromBlockCoords(x, z);
-        int y = getHeightBlocks() - 1;
+        final Chunk chunk = this.getChunkFromBlockCoords(x, z);
+        int y = this.getHeightBlocks() - 1;
         x &= (Chunk.CHUNK_SIZE_X - 1);
         z &= (Chunk.CHUNK_SIZE_Z - 1);
         while (y > 0) {
-            Block<?> block = Blocks.getBlock(chunk.getBlockID(x, y, z));
-            Material material = block != null ? block.getMaterial() : Materials.AIR;
+            final Block<?> block = Blocks.getBlock(chunk.getBlockID(x, y, z));
+            final Material material = block != null ? block.getMaterial() : Materials.AIR;
             if (!material.blocksMotion()) {
                 y--;
             } else {
@@ -1384,8 +1346,8 @@ public class World implements MutableWorldSource {
         return -1;
     }
 
-    public float getStarBrightness(float partialTick) {
-        float f1 = getCelestialAngle(partialTick);
+    public float getStarBrightness(final float partialTick) {
+        final float f1 = this.getCelestialAngle(partialTick);
         float f2 = 1.0F - (MathHelper.cos(f1 * MathHelper.PI * 2.0F) * 2.0F + 0.75F);
         if (f2 < 0.0F) {
             f2 = 0.0F;
@@ -1402,11 +1364,11 @@ public class World implements MutableWorldSource {
     }
 
     public void scheduleBlockUpdate(final @NotNull TilePosc tilePos, final @NotNull Block<?> block, final long delay) {
-        NextTickListEntry entry = new NextTickListEntry(tilePos, block);
+        final NextTickListEntry entry = new NextTickListEntry(tilePos, block);
         final byte radius = 8;
 
         if (this.scheduledUpdatesAreImmediate && !this.immediatelyUpdatedPositions.contains(entry)) {
-            if (areBlocksLoaded(entry.tilePos.x - radius, entry.tilePos.y - radius, entry.tilePos.z - radius, entry.tilePos.x() + radius, entry.tilePos.y() + radius, entry.tilePos.z() + radius)) {
+            if (this.areBlocksLoaded(entry.tilePos.x - radius, entry.tilePos.y - radius, entry.tilePos.z - radius, entry.tilePos.x() + radius, entry.tilePos.y() + radius, entry.tilePos.z() + radius)) {
                 final @NotNull Block<?> worldBlock = this.getBlockType(entry.tilePos);
                 if (worldBlock == entry.block) {
                     this.immediatelyUpdatedPositions.add(entry);
@@ -1415,8 +1377,8 @@ public class World implements MutableWorldSource {
             }
             return;
         }
-        if (areBlocksLoaded(tilePos, radius)) {
-            entry.setDelay(delay + runtime);
+        if (this.areBlocksLoaded(tilePos, radius)) {
+            entry.setDelay(delay + this.runtime);
             if (!this.tickNextTickSet.contains(entry)) {
                 this.tickNextTickSet.add(entry);
                 this.tickNextTickList.add(entry);
@@ -1426,7 +1388,7 @@ public class World implements MutableWorldSource {
 
     public void updateEntities() {
         for (int i = 0; i < this.weatherEffects.size(); i++) {
-            Entity entity = this.weatherEffects.get(i);
+            final Entity entity = this.weatherEffects.get(i);
             entity.tick();
             if (entity.removed) {
                 this.weatherEffects.remove(i--);
@@ -1435,21 +1397,21 @@ public class World implements MutableWorldSource {
 
         this.entities.removeAll(this.entitiesToRemove);
         for (int j = 0; j < this.entitiesToRemove.size(); j++) {
-            Entity entity1 = this.entitiesToRemove.get(j);
-            int i1 = entity1.chunkCoordX;
-            int k1 = entity1.chunkCoordZ;
-            if (entity1.addedToChunk && isChunkLoaded(i1, k1)) {
-                getChunkFromChunkCoords(i1, k1).removeEntity(entity1);
+            final Entity entity1 = this.entitiesToRemove.get(j);
+            final int i1 = entity1.chunkCoordX;
+            final int k1 = entity1.chunkCoordZ;
+            if (entity1.addedToChunk && this.isChunkLoaded(i1, k1)) {
+                this.getChunkFromChunkCoords(i1, k1).removeEntity(entity1);
             }
         }
 
         for (int k = 0; k < this.entitiesToRemove.size(); k++) {
-            releaseEntitySkin(this.entitiesToRemove.get(k));
+            this.releaseEntitySkin(this.entitiesToRemove.get(k));
         }
 
         this.entitiesToRemove.clear();
         for (int l = 0; l < this.entities.size(); l++) {
-            Entity entity2 = this.entities.get(l);
+            final Entity entity2 = this.entities.get(l);
             if (entity2.vehicle != null) {
                 if (!entity2.vehicle.isRemoved() && entity2.vehicle.getPassenger() == entity2) {
                     continue;
@@ -1458,29 +1420,29 @@ public class World implements MutableWorldSource {
                 entity2.vehicle = null;
             }
             if (!entity2.removed) {
-                updateEntity(entity2);
+                this.updateEntity(entity2);
             }
             if (!entity2.removed) {
                 continue;
             }
-            int j1 = entity2.chunkCoordX;
-            int l1 = entity2.chunkCoordZ;
-            if (entity2.addedToChunk && isChunkLoaded(j1, l1)) {
-                getChunkFromChunkCoords(j1, l1).removeEntity(entity2);
+            final int j1 = entity2.chunkCoordX;
+            final int l1 = entity2.chunkCoordZ;
+            if (entity2.addedToChunk && this.isChunkLoaded(j1, l1)) {
+                this.getChunkFromChunkCoords(j1, l1).removeEntity(entity2);
             }
             this.entities.remove(l--);
-            releaseEntitySkin(entity2);
+            this.releaseEntitySkin(entity2);
         }
 
         this.updatingTileEntities = true;
         for (int i = this.tileEntityList.size() - 1; i >= 0; i--) {
-            TileEntity tileEntity = this.tileEntityList.get(i);
-            if (!tileEntity.isInvalid() && isBlockLoaded(tileEntity.x, tileEntity.y, tileEntity.z)) {
+            final TileEntity tileEntity = this.tileEntityList.get(i);
+            if (!tileEntity.isInvalid() && this.isBlockLoaded(tileEntity.x, tileEntity.y, tileEntity.z)) {
                 tileEntity.tick();
             }
             if (tileEntity.isInvalid()) {
                 this.tileEntityList.remove(i);
-                Chunk chunk = getChunkFromChunkCoords(Math.floorDiv(tileEntity.x, Chunk.CHUNK_SIZE_X), Math.floorDiv(tileEntity.z, Chunk.CHUNK_SIZE_Z));
+                final Chunk chunk = this.getChunkFromChunkCoords(Math.floorDiv(tileEntity.x, Chunk.CHUNK_SIZE_X), Math.floorDiv(tileEntity.z, Chunk.CHUNK_SIZE_Z));
                 if (chunk != null) {
                     chunk.removeTileEntity(tileEntity);
                 }
@@ -1489,21 +1451,21 @@ public class World implements MutableWorldSource {
         this.updatingTileEntities = false;
     }
 
-    public void addAllBlockEntities(Collection<TileEntity> blockEntities) {
+    public void addAllBlockEntities(final Collection<TileEntity> blockEntities) {
         this.tileEntityList.addAll(blockEntities);
     }
 
-    public void updateEntity(Entity entity) {
-        updateEntityWithOptionalForce(entity, true);
+    public void updateEntity(final Entity entity) {
+        this.updateEntityWithOptionalForce(entity, true);
     }
 
-    public void updateEntityWithOptionalForce(Entity entity, boolean flag) {
-        int i = MathHelper.floor(entity.x);
-        int j = MathHelper.floor(entity.z);
-        byte byte0 = 32;
-        if (flag && !areBlocksLoaded(i - byte0, 0, j - byte0, i + byte0, getHeightBlocks() - 1, j + byte0)) {
+    public void updateEntityWithOptionalForce(final Entity entity, final boolean flag) {
+        final int i = MathHelper.floor(entity.x);
+        final int j = MathHelper.floor(entity.z);
+        final byte byte0 = 32;
+        if (flag && !this.areBlocksLoaded(i - byte0, 0, j - byte0, i + byte0, this.getHeightBlocks() - 1, j + byte0)) {
             //try to despawn if entity wanders into nonexistant chunk
-            if (entity instanceof Mob mob) {
+            if (entity instanceof final Mob mob) {
                 mob.tryToDespawn();
             }
             return;
@@ -1535,16 +1497,16 @@ public class World implements MutableWorldSource {
         if (Double.isNaN(entity.yRot) || Double.isInfinite(entity.yRot)) {
             entity.yRot = entity.yRotO;
         }
-        int k = MathHelper.floor(entity.x / Chunk.CHUNK_SIZE_X);
-        int l = MathHelper.floor(entity.y / 16D);
-        int i1 = MathHelper.floor(entity.z / Chunk.CHUNK_SIZE_Z);
+        final int k = MathHelper.floor(entity.x / Chunk.CHUNK_SIZE_X);
+        final int l = MathHelper.floor(entity.y / 16D);
+        final int i1 = MathHelper.floor(entity.z / Chunk.CHUNK_SIZE_Z);
         if (!entity.addedToChunk || entity.chunkCoordX != k || entity.chunkCoordY != l || entity.chunkCoordZ != i1) {
-            if (entity.addedToChunk && isChunkLoaded(entity.chunkCoordX, entity.chunkCoordZ)) {
-                getChunkFromChunkCoords(entity.chunkCoordX, entity.chunkCoordZ).removeEntityAtIndex(entity, entity.chunkCoordY);
+            if (entity.addedToChunk && this.isChunkLoaded(entity.chunkCoordX, entity.chunkCoordZ)) {
+                this.getChunkFromChunkCoords(entity.chunkCoordX, entity.chunkCoordZ).removeEntityAtIndex(entity, entity.chunkCoordY);
             }
-            if (isChunkLoaded(k, i1)) {
+            if (this.isChunkLoaded(k, i1)) {
                 entity.addedToChunk = true;
-                getChunkFromChunkCoords(k, i1).addEntity(entity);
+                this.getChunkFromChunkCoords(k, i1).addEntity(entity);
             } else {
                 entity.addedToChunk = false;
             }
@@ -1554,15 +1516,15 @@ public class World implements MutableWorldSource {
                 entity.passenger.vehicle = null;
                 entity.passenger = null;
             } else {
-                updateEntity(entity.passenger);
+                this.updateEntity(entity.passenger);
             }
         }
     }
 
-    public boolean checkIfAABBIsClear(@NotNull AABBdc aabb) {
-        List<Entity> list = getEntitiesWithinAABBExcludingEntity(null, aabb);
+    public boolean checkIfAABBIsClear(@NotNull final AABBdc aabb) {
+        final List<Entity> list = this.getEntitiesWithinAABBExcludingEntity(null, aabb);
         for (int i = 0; i < list.size(); i++) {
-            Entity entity = list.get(i);
+            final Entity entity = list.get(i);
             if (entity instanceof MobFireflyCluster) continue;
             if (!entity.removed && entity.blocksBuilding) {
                 return false;
@@ -1572,18 +1534,18 @@ public class World implements MutableWorldSource {
         return true;
     }
 
-    public boolean getIsAnySolidGround(@NotNull AABBdc aabb) {
-        int minX = MathHelper.floor(aabb.minX());
-        int maxX = MathHelper.floor(aabb.maxX());
-        int minY = MathHelper.floor(aabb.minY());
-        int maxY = MathHelper.floor(aabb.maxY());
-        int minZ = MathHelper.floor(aabb.minZ());
-        int maxZ = MathHelper.floor(aabb.maxZ());
+    public boolean getIsAnySolidGround(@NotNull final AABBdc aabb) {
+        final int minX = MathHelper.floor(aabb.minX());
+        final int maxX = MathHelper.floor(aabb.maxX());
+        final int minY = MathHelper.floor(aabb.minY());
+        final int maxY = MathHelper.floor(aabb.maxY());
+        final int minZ = MathHelper.floor(aabb.minZ());
+        final int maxZ = MathHelper.floor(aabb.maxZ());
 
         for (int x = minX; x <= maxX; x++) {
             for (int y = minY; y <= maxY; y++) {
                 for (int z = minZ; z <= maxZ; z++) {
-                    Block<?> block = Blocks.blocksList[getBlockId(x, y, z)];
+                    final Block<?> block = Blocks.blocksList[this.getBlockId(x, y, z)];
                     if (block != null) {
                         return true;
                     }
@@ -1591,10 +1553,10 @@ public class World implements MutableWorldSource {
             }
         }
 
-        List<Entity> entities = getEntitiesWithinAABBExcludingEntity(null, aabb);
+        final List<Entity> entities = this.getEntitiesWithinAABBExcludingEntity(null, aabb);
 
-        for (Entity entity : entities) {
-            AABBdc collisionAABB = entity.getCollisionAABB();
+        for (final Entity entity : entities) {
+            final AABBdc collisionAABB = entity.getCollisionAABB();
             if (collisionAABB != null && collisionAABB.intersectsAABB((AABBd) aabb)) {
                 this.collidingBoundingBoxes.add(collisionAABB);
             }
@@ -1604,20 +1566,20 @@ public class World implements MutableWorldSource {
     }
 
 
-    public boolean getIsAnyLiquid(@NotNull AABBdc aabb) {
-        int minX = MathHelper.floor(aabb.minX());
-        int maxX = MathHelper.floor(aabb.maxX());
-        int minY = MathHelper.floor(aabb.minY());
-        int maxY = MathHelper.floor(aabb.maxY());
-        int minZ = MathHelper.floor(aabb.minZ());
-        int maxZ = MathHelper.floor(aabb.maxZ());
+    public boolean getIsAnyLiquid(@NotNull final AABBdc aabb) {
+        final int minX = MathHelper.floor(aabb.minX());
+        final int maxX = MathHelper.floor(aabb.maxX());
+        final int minY = MathHelper.floor(aabb.minY());
+        final int maxY = MathHelper.floor(aabb.maxY());
+        final int minZ = MathHelper.floor(aabb.minZ());
+        final int maxZ = MathHelper.floor(aabb.maxZ());
 
-        TilePos tilePos = new TilePos(0, 0, 0);
+        final TilePos tilePos = new TilePos(0, 0, 0);
         for (tilePos.x = minX; tilePos.x <= maxX; tilePos.x++) {
             for (tilePos.y = minY; tilePos.y <= maxY; tilePos.y++) {
                 for (tilePos.z = minZ; tilePos.z <= maxZ; tilePos.z++) {
-                    if (isBlockLoaded(tilePos)) {
-                        Block<?> block = getBlockType(tilePos);
+                    if (this.isBlockLoaded(tilePos)) {
+                        final Block<?> block = this.getBlockType(tilePos);
                         if (block != null && block.getMaterial().isLiquid()) {
                             return true;
                         }
@@ -1629,28 +1591,28 @@ public class World implements MutableWorldSource {
         return false;
     }
 
-    public boolean isBoundingBoxBurning(@NotNull AABBdc aabb) {
-        return isMaterialInBB(aabb, Materials.FIRE, Materials.LAVA);
+    public boolean isBoundingBoxBurning(@NotNull final AABBdc aabb) {
+        return this.isMaterialInBB(aabb, Materials.FIRE, Materials.LAVA);
     }
 
-    public boolean handleMaterialAcceleration(@NotNull AABBdc aabb, @NotNull Material material, @NotNull Entity entity, boolean addVelocity) {
-        int minX = MathHelper.floor(aabb.minX());
-        int maxX = MathHelper.floor(aabb.maxX() + 1.0D);
-        int minY = MathHelper.floor(aabb.minY());
-        int maxY = MathHelper.floor(aabb.maxY() + 1.0D);
-        int minZ = MathHelper.floor(aabb.minZ());
-        int maxZ = MathHelper.floor(aabb.maxZ() + 1.0D);
-        if (!areBlocksLoaded(minX, minY, minZ, maxX, maxY, maxZ)) {
+    public boolean handleMaterialAcceleration(@NotNull final AABBdc aabb, @NotNull final Material material, @NotNull final Entity entity, final boolean addVelocity) {
+        final int minX = MathHelper.floor(aabb.minX());
+        final int maxX = MathHelper.floor(aabb.maxX() + 1.0D);
+        final int minY = MathHelper.floor(aabb.minY());
+        final int maxY = MathHelper.floor(aabb.maxY() + 1.0D);
+        final int minZ = MathHelper.floor(aabb.minZ());
+        final int maxZ = MathHelper.floor(aabb.maxZ() + 1.0D);
+        if (!this.areBlocksLoaded(minX, minY, minZ, maxX, maxY, maxZ)) {
             return false;
         }
         boolean flag = false;
-        TilePos tilePos = new TilePos(0, 0, 0);
-        Vector3d velDir = new Vector3d();
+        final TilePos tilePos = new TilePos(0, 0, 0);
+        final Vector3d velDir = new Vector3d();
         for (tilePos.x = minX; tilePos.x < maxX; tilePos.x++) {
             for (tilePos.y = minY; tilePos.y < maxY; tilePos.y++) {
                 for (tilePos.z = minZ; tilePos.z < maxZ; tilePos.z++) {
-                    final @NotNull Block<?> block = getBlockType(tilePos);
-                    if (!isMaterialInBB(aabb, material)) {
+                    final @NotNull Block<?> block = this.getBlockType(tilePos);
+                    if (!this.isMaterialInBB(aabb, material)) {
                         continue;
                     }
                     flag = true;
@@ -1663,7 +1625,7 @@ public class World implements MutableWorldSource {
 
         if (velDir.length() > 0.0D && addVelocity) {
             velDir.normalize();
-            double d = 0.014D;
+            final double d = 0.014D;
             entity.xd += velDir.x * d;
             entity.yd += velDir.y * d;
             entity.zd += velDir.z * d;
@@ -1671,21 +1633,21 @@ public class World implements MutableWorldSource {
         return flag;
     }
 
-    public boolean isMaterialInBB(@NotNull AABBdc aabb, @NotNull Material @NotNull ... materials) {
-        int minX_i = MathHelper.floor(aabb.minX());
-        int maxX_i = MathHelper.floor(aabb.maxX() + 1.0D);
-        int minY_i = MathHelper.floor(aabb.minY());
-        int maxY_i = MathHelper.floor(aabb.maxY() + 1.0D);
-        int minZ_i = MathHelper.floor(aabb.minZ());
-        int maxZ_i = MathHelper.floor(aabb.maxZ() + 1.0D);
-        TilePos tilePos = new TilePos(0, 0, 0);
+    public boolean isMaterialInBB(@NotNull final AABBdc aabb, @NotNull final Material @NotNull ... materials) {
+        final int minX_i = MathHelper.floor(aabb.minX());
+        final int maxX_i = MathHelper.floor(aabb.maxX() + 1.0D);
+        final int minY_i = MathHelper.floor(aabb.minY());
+        final int maxY_i = MathHelper.floor(aabb.maxY() + 1.0D);
+        final int minZ_i = MathHelper.floor(aabb.minZ());
+        final int maxZ_i = MathHelper.floor(aabb.maxZ() + 1.0D);
+        final TilePos tilePos = new TilePos(0, 0, 0);
         for (tilePos.x = minX_i; tilePos.x < maxX_i; tilePos.x++) {
             for (tilePos.y = minY_i; tilePos.y < maxY_i; tilePos.y++) {
                 for (tilePos.z = minZ_i; tilePos.z < maxZ_i; tilePos.z++) {
-                    Block<?> block = getBlockType(tilePos);
+                    final Block<?> block = this.getBlockType(tilePos);
                     if (block != null) {
                         boolean isMaterial = false;
-                        for (Material m : materials) {
+                        for (final Material m : materials) {
                             if (block.getMaterial() == m) {
                                 isMaterial = true;
                                 break;
@@ -1705,18 +1667,18 @@ public class World implements MutableWorldSource {
         return false;
     }
 
-    public boolean isMaterialInBB(@NotNull AABBdc aabb, @NotNull Material material) {
-        int minX_i = MathHelper.floor(aabb.minX());
-        int maxX_i = MathHelper.floor(aabb.maxX() + 1.0D);
-        int minY_i = MathHelper.floor(aabb.minY());
-        int maxY_i = MathHelper.floor(aabb.maxY() + 1.0D);
-        int minZ_i = MathHelper.floor(aabb.minZ());
-        int maxZ_i = MathHelper.floor(aabb.maxZ() + 1.0D);
-        TilePos tilePos = new TilePos(0, 0, 0);
+    public boolean isMaterialInBB(@NotNull final AABBdc aabb, @NotNull final Material material) {
+        final int minX_i = MathHelper.floor(aabb.minX());
+        final int maxX_i = MathHelper.floor(aabb.maxX() + 1.0D);
+        final int minY_i = MathHelper.floor(aabb.minY());
+        final int maxY_i = MathHelper.floor(aabb.maxY() + 1.0D);
+        final int minZ_i = MathHelper.floor(aabb.minZ());
+        final int maxZ_i = MathHelper.floor(aabb.maxZ() + 1.0D);
+        final TilePos tilePos = new TilePos(0, 0, 0);
         for (tilePos.x = minX_i; tilePos.x < maxX_i; tilePos.x++) {
             for (tilePos.y = minY_i; tilePos.y < maxY_i; tilePos.y++) {
                 for (tilePos.z = minZ_i; tilePos.z < maxZ_i; tilePos.z++) {
-                    Block<?> block = getBlockType(tilePos);
+                    final Block<?> block = this.getBlockType(tilePos);
                     if (block != null) {
                         if (block.getMaterial() != material) continue;
 
@@ -1731,22 +1693,22 @@ public class World implements MutableWorldSource {
         return false;
     }
 
-    public boolean isAABBInMaterial(@NotNull AABBdc aabb, @NotNull Material material) {
-        int minX = MathHelper.floor(aabb.minX());
-        int maxX = MathHelper.floor(aabb.maxX() + 1.0D);
-        int minY = MathHelper.floor(aabb.minY());
-        int maxY = MathHelper.floor(aabb.maxY() + 1.0D);
-        int minZ = MathHelper.floor(aabb.minZ());
-        int maxZ = MathHelper.floor(aabb.maxZ() + 1.0D);
-        TilePos tilePos = new TilePos(0, 0, 0);
+    public boolean isAABBInMaterial(@NotNull final AABBdc aabb, @NotNull final Material material) {
+        final int minX = MathHelper.floor(aabb.minX());
+        final int maxX = MathHelper.floor(aabb.maxX() + 1.0D);
+        final int minY = MathHelper.floor(aabb.minY());
+        final int maxY = MathHelper.floor(aabb.maxY() + 1.0D);
+        final int minZ = MathHelper.floor(aabb.minZ());
+        final int maxZ = MathHelper.floor(aabb.maxZ() + 1.0D);
+        final TilePos tilePos = new TilePos(0, 0, 0);
         for (tilePos.x = minX; tilePos.x < maxX; tilePos.x++) {
             for (tilePos.y = minY; tilePos.y < maxY; tilePos.y++) {
                 for (tilePos.z = minZ; tilePos.z < maxZ; tilePos.z++) {
-                    final @NotNull Block<?> block = getBlockType(tilePos);
+                    final @NotNull Block<?> block = this.getBlockType(tilePos);
                     if (block.getMaterial() != material) {
                         continue;
                     }
-                    int j2 = getBlockData(tilePos);
+                    final int j2 = this.getBlockData(tilePos);
                     double d = tilePos.y + 1;
                     if (j2 < 8) {
                         d = (double) (tilePos.y + 1) - (double) j2 / 8D;
@@ -1763,12 +1725,12 @@ public class World implements MutableWorldSource {
         return false;
     }
 
-    public Explosion createExplosion(Entity entity, double x, double y, double z, float explosionSize) {
-        return createExplosion(entity, x, y, z, explosionSize, false, false);
+    public Explosion createExplosion(final Entity entity, final double x, final double y, final double z, final float explosionSize) {
+        return this.createExplosion(entity, x, y, z, explosionSize, false, false);
     }
 
-    public Explosion createExplosion(Entity entity, double x, double y, double z, float explosionSize, boolean flaming, boolean isCannonBall) {
-        Explosion explosion;
+    public Explosion createExplosion(final Entity entity, final double x, final double y, final double z, final float explosionSize, final boolean flaming, final boolean isCannonBall) {
+        final Explosion explosion;
         if (!isCannonBall)
             explosion = new Explosion(this, entity, x, y, z, explosionSize);
         else
@@ -1779,20 +1741,20 @@ public class World implements MutableWorldSource {
         return explosion;
     }
 
-    public float getSeenPercent(@NotNull Vector3dc eyePos, @NotNull AABBdc aabb) {
-        double d = 1.0D / ((aabb.maxX() - aabb.minX()) * 2D + 1.0D);
-        double d1 = 1.0D / ((aabb.maxY() - aabb.minY()) * 2D + 1.0D);
-        double d2 = 1.0D / ((aabb.maxZ() - aabb.minZ()) * 2D + 1.0D);
+    public float getSeenPercent(@NotNull final Vector3dc eyePos, @NotNull final AABBdc aabb) {
+        final double d = 1.0D / ((aabb.maxX() - aabb.minX()) * 2D + 1.0D);
+        final double d1 = 1.0D / ((aabb.maxY() - aabb.minY()) * 2D + 1.0D);
+        final double d2 = 1.0D / ((aabb.maxZ() - aabb.minZ()) * 2D + 1.0D);
         int i = 0;
         int j = 0;
-        Vector3d entCheckPos = new Vector3d();
+        final Vector3d entCheckPos = new Vector3d();
         for (float f = 0.0F; f <= 1.0F; f = (float) ((double) f + d)) {
             for (float f1 = 0.0F; f1 <= 1.0F; f1 = (float) ((double) f1 + d1)) {
                 for (float f2 = 0.0F; f2 <= 1.0F; f2 = (float) ((double) f2 + d2)) {
-                    double x = aabb.minX() + (aabb.maxX() - aabb.minX()) * (double) f;
-                    double y = aabb.minY() + (aabb.maxY() - aabb.minY()) * (double) f1;
-                    double z = aabb.minZ() + (aabb.maxZ() - aabb.minZ()) * (double) f2;
-                    if (checkBlockCollisionBetweenPoints(eyePos, entCheckPos.set(x, y, z)) == null) {
+                    final double x = aabb.minX() + (aabb.maxX() - aabb.minX()) * (double) f;
+                    final double y = aabb.minY() + (aabb.maxY() - aabb.minY()) * (double) f1;
+                    final double z = aabb.minZ() + (aabb.maxZ() - aabb.minZ()) * (double) f2;
+                    if (this.checkBlockCollisionBetweenPoints(eyePos, entCheckPos.set(x, y, z)) == null) {
                         i++;
                     }
                     j++;
@@ -1820,9 +1782,9 @@ public class World implements MutableWorldSource {
         this.onBlockHit(player, new TilePos(x, y, z), side);
     }
 
-    public @Nullable Entity getEntityByID(int id) {
+    public @Nullable Entity getEntityByID(final int id) {
         for (int i = 0; i < this.entities.size(); i++) {
-            Entity entity = this.entities.get(i);
+            final Entity entity = this.entities.get(i);
             if (entity.id == id) {
                 return entity;
             }
@@ -1913,8 +1875,8 @@ public class World implements MutableWorldSource {
     public void onUnload() {
         // Unloads all entities
         try {
-            updateEntities();
-        } catch (Throwable t) {
+            this.updateEntities();
+        } catch (final Throwable t) {
             LOGGER.error("Unhandled exception while unloading all entities!", t);
             throw t;
         } finally {
@@ -1927,8 +1889,8 @@ public class World implements MutableWorldSource {
         this.chunkProvider.close();
     }
 
-    public void saveWorldIndirectly(ProgressListener iprogressupdate) {
-        saveWorld(true, iprogressupdate, true);
+    public void saveWorldIndirectly(final ProgressListener iprogressupdate) {
+        this.saveWorld(true, iprogressupdate, true);
     }
 
     public boolean updatingLighting() {
@@ -1961,29 +1923,29 @@ public class World implements MutableWorldSource {
     }
 
     public void updateSkyBrightness() {
-        int i = this.worldType.getSkyDarken(this, getWorldTime(), 1.0F);
+        final int i = this.getWorldType().getSkyDarken(this, this.getWorldTime(), 1.0F);
         if (i != this.skyDarken) {
             this.skyDarken = i;
         }
     }
 
-    public void allChanged(boolean lightChanged, boolean seasonChanged) {
+    public void allChanged(final boolean lightChanged, final boolean seasonChanged) {
         for (int i = 0; i < this.listeners.size(); i++) {
             this.listeners.get(i).allChanged(lightChanged, seasonChanged);
         }
     }
 
     protected void updateSleepingPlayers() {
-        if (areEnoughPlayersFullyAsleep()) {
+        if (this.areEnoughPlayersFullyAsleep()) {
             boolean wasInterrupted = false;
-            if (getSpawnerConfig().canHostileSpawn(this) && getPlayersRequiredToSkipNight() <= 1) {
+            if (this.getSpawnerConfig().canHostileSpawn(this) && this.getPlayersRequiredToSkipNight() <= 1) {
                 wasInterrupted = SpawnerMobs.performSleepSpawning(this, this.players);
             }
             if (!wasInterrupted) {
-                long timePlusOneDay = this.levelData.getWorldTime() + Global.DAY_LENGTH_TICKS;
-                this.levelData.setWorldTime(timePlusOneDay - timePlusOneDay % Global.DAY_LENGTH_TICKS + this.worldType.getSunriseTick(this) + DAY_LENGTH_TICKS / 24);
+                final long timePlusOneDay = this.levelData.getWorldTime() + Global.DAY_LENGTH_TICKS;
+                this.levelData.setWorldTime(timePlusOneDay - timePlusOneDay % Global.DAY_LENGTH_TICKS + this.getWorldType().getSunriseTick(this) + DAY_LENGTH_TICKS / 24);
 
-                wakeUpAllPlayers();
+                this.wakeUpAllPlayers();
             }
         }
     }
@@ -1994,34 +1956,34 @@ public class World implements MutableWorldSource {
         Debug.change("weather");
         this.weatherManager.tick();
         Debug.change("misc");
-        updateSleepingPlayers();
+        this.updateSleepingPlayers();
         Debug.change("spawning");
         // TODO mob spawning seems to be the cause of many lag spikes, specifically the checks for is a mob is allowed to spawn at a certain xyz position seem to be the worst offenders
-        SpawnerMobs.performSpawning(this, getSpawnerConfig());
+        SpawnerMobs.performSpawning(this, this.getSpawnerConfig());
         Debug.change("chunk");
         this.chunkProvider.tick();
 
         Debug.change("autosave");
-        int autosaveTimeInSeconds = Global.accessor.getAutosaveTimer();
-        int autosaveTimeInTicks = (autosaveTimeInSeconds * 20);
+        final int autosaveTimeInSeconds = Global.accessor.getAutosaveTimer();
+        final int autosaveTimeInTicks = (autosaveTimeInSeconds * 20);
 
         AUTOSAVE = autosaveTimeInTicks != 0;
         if (AUTOSAVE && this.runtime % (long) autosaveTimeInTicks == 0L) {
-            saveWorld(false, null, true);
+            this.saveWorld(false, null, true);
         }
 
         Debug.change("misc");
-        if (getGameRuleValue(GameRules.DO_DAY_CYCLE)) {
+        if (this.getGameRuleValue(GameRules.DO_DAY_CYCLE)) {
             this.levelData.setWorldTime(this.levelData.getWorldTime() + 1L);
         }
 
         this.runtime++;
 
-        tickPendingTicks(false);
+        this.tickPendingTicks(false);
         Debug.change("blocks&cavesSounds");
-        updateBlocksAndPlayCaveSounds();
+        this.updateBlocksAndPlayCaveSounds();
         Debug.change("season&light");
-        updateSeasonAndLight();
+        this.updateSeasonAndLight();
         if (this.rainbowTicks > 0) {
             this.rainbowTicks--;
         }
@@ -2032,7 +1994,7 @@ public class World implements MutableWorldSource {
         boolean seasonChanged = false;
         boolean lightChanged = false;
 
-        int currentDayCount = ((int) (this.levelData.getWorldTime() / Global.DAY_LENGTH_TICKS));
+        final int currentDayCount = ((int) (this.levelData.getWorldTime() / Global.DAY_LENGTH_TICKS));
         if (currentDayCount != this.dayCountLastTick) {
             this.dayCountLastTick = currentDayCount;
             if (!this.isClientSide) {
@@ -2043,27 +2005,27 @@ public class World implements MutableWorldSource {
             seasonChanged = true;
         }
 
-        int currentSkyDarken = this.worldType.getSkyDarken(this, getWorldTime(), 1.0f);
+        final int currentSkyDarken = this.getWorldType().getSkyDarken(this, this.getWorldTime(), 1.0f);
         if (currentSkyDarken != this.skyDarken) {
             this.skyDarken = currentSkyDarken;
             lightChanged = true;
         }
 
         if (seasonChanged || lightChanged) {
-            allChanged(lightChanged, seasonChanged);
+            this.allChanged(lightChanged, seasonChanged);
         }
     }
 
     protected void updateBlocksAndPlayCaveSounds() {
         this.positionsToUpdate.clear();
         for (int i = 0; i < this.players.size(); i++) {
-            Player entityplayer = this.players.get(i);
-            int playerChunkX = MathHelper.floor(entityplayer.x / Chunk.CHUNK_SIZE_X);
-            int playerChunkZ = MathHelper.floor(entityplayer.z / Chunk.CHUNK_SIZE_Z);
-            byte radius = 9;
+            final Player entityplayer = this.players.get(i);
+            final int playerChunkX = MathHelper.floor(entityplayer.x / Chunk.CHUNK_SIZE_X);
+            final int playerChunkZ = MathHelper.floor(entityplayer.z / Chunk.CHUNK_SIZE_Z);
+            final byte radius = 9;
             for (int x = -radius; x <= radius; x++) {
                 for (int z = -radius; z <= radius; z++) {
-                    this.positionsToUpdate.add(new ChunkCoordinate(x + playerChunkX, z + playerChunkZ));
+                    this.positionsToUpdate.add(new ChunkPos(x + playerChunkX, z + playerChunkZ));
                 }
             }
         }
@@ -2071,49 +2033,49 @@ public class World implements MutableWorldSource {
         if (this.caveSoundCounter > 0) {
             this.caveSoundCounter--;
         }
-        final int randomTicks = getGameRuleValue(GameRules.RANDOM_TICK_SPEED);
-        for (ChunkCoordinate coordinate : this.positionsToUpdate) {
-            int chunkBlockX = coordinate.x * Chunk.CHUNK_SIZE_X;
-            int chunkBlockZ = coordinate.z * Chunk.CHUNK_SIZE_Z;
-            if (!isChunkLoaded(coordinate.x, coordinate.z)) {
+        final int randomTicks = this.getGameRuleValue(GameRules.RANDOM_TICK_SPEED);
+        for (final ChunkPosc chunkPos : this.positionsToUpdate) {
+            final int chunkBlockX = chunkPos.x() * Chunk.CHUNK_SIZE_X;
+            final int chunkBlockZ = chunkPos.z() * Chunk.CHUNK_SIZE_Z;
+            if (!this.isChunkLoaded(chunkPos)) {
                 continue;
             }
-            Chunk chunk = getChunkFromChunkCoords(coordinate.x, coordinate.z);
+            final Chunk chunk = this.getChunk(chunkPos);
             this.updateLCG = this.updateLCG * 3 + 0x3c6ef35f;
             int randVal = this.updateLCG >> 2;
             int blockX = randVal & (Chunk.CHUNK_SIZE_X - 1);
             int blockZ = (randVal / (Chunk.CHUNK_SIZE_Z * Chunk.CHUNK_SIZE_X)) & (Chunk.CHUNK_SIZE_Z - 1);
 
             if (this.caveSoundCounter == 0) {
-                int blockY = (randVal / (HEIGHT_BLOCKS * Chunk.CHUNK_SIZE_Z * Chunk.CHUNK_SIZE_X)) & (HEIGHT_BLOCKS - 1);
-                int id = chunk.getBlockID(blockX, blockY, blockZ);
+                final int blockY = (randVal / (HEIGHT_BLOCKS * Chunk.CHUNK_SIZE_Z * Chunk.CHUNK_SIZE_X)) & (HEIGHT_BLOCKS - 1);
+                final int id = chunk.getBlockID(blockX, blockY, blockZ);
                 blockX += chunkBlockX;
                 blockZ += chunkBlockZ;
-                if (id == 0 && getFullBlockLightValue(blockX, blockY, blockZ) <= this.rand.nextInt(8) && getSavedLightValue(LightLayer.Sky, blockX, blockY, blockZ) <= 0) {
-                    Player closestPlayer = getClosestPlayer((double) blockX + 0.5D, (double) blockY + 0.5D, (double) blockZ + 0.5D, 8D);
+                if (id == 0 && this.getFullBlockLightValue(blockX, blockY, blockZ) <= this.rand.nextInt(8) && this.getSavedLightValue(LightLayer.Sky, blockX, blockY, blockZ) <= 0) {
+                    final Player closestPlayer = this.getClosestPlayer((double) blockX + 0.5D, (double) blockY + 0.5D, (double) blockZ + 0.5D, 8D);
                     if (closestPlayer != null && closestPlayer.distanceToSqr((double) blockX + 0.5D, (double) blockY + 0.5D, (double) blockZ + 0.5D) > 4D) {
-                        playSoundEffect(null, SoundCategory.CAVE_SOUNDS, (double) blockX + 0.5D, (double) blockY + 0.5D, (double) blockZ + 0.5D, "ambient.cave.cave", 0.7F, 0.8F + this.rand.nextFloat() * 0.2F);
+                        this.playSoundEffect(null, SoundCategory.CAVE_SOUNDS, (double) blockX + 0.5D, (double) blockY + 0.5D, (double) blockZ + 0.5D, "ambient.cave.cave", 0.7F, 0.8F + this.rand.nextFloat() * 0.2F);
                         this.caveSoundCounter = this.rand.nextInt(12000) + 6000;
                     }
                 }
             }
 
-            if (getCurrentWeather() != null) {
+            if (this.getCurrentWeather() != null) {
                 this.updateLCG = this.updateLCG * 3 + 0x3c6ef35f;
                 randVal = this.updateLCG >> 2;
-                int weatherBlockX = randVal & (Chunk.CHUNK_SIZE_X - 1);
-                int weatherBlockZ = (randVal / (Chunk.CHUNK_SIZE_Z * Chunk.CHUNK_SIZE_X)) & (Chunk.CHUNK_SIZE_Z - 1);
-                getCurrentWeather().doEnvironmentUpdate(this, this.rand, chunkBlockX + weatherBlockX, chunkBlockZ + weatherBlockZ);
+                final int weatherBlockX = randVal & (Chunk.CHUNK_SIZE_X - 1);
+                final int weatherBlockZ = (randVal / (Chunk.CHUNK_SIZE_Z * Chunk.CHUNK_SIZE_X)) & (Chunk.CHUNK_SIZE_Z - 1);
+                this.getCurrentWeather().doEnvironmentUpdate(this, this.rand, chunkBlockX + weatherBlockX, chunkBlockZ + weatherBlockZ);
             }
 
             for (int s = 0; s < Chunk.CHUNK_SECTIONS; s++) {
                 for (int i = 0; i < randomTicks; i++) {
                     this.updateLCG = this.updateLCG * 3 + 0x3c6ef35f;
-                    int iRandVal = this.updateLCG >> 2;
-                    int iBlockX = iRandVal & (Chunk.CHUNK_SIZE_X - 1);
-                    int iBlockZ = (iRandVal / (Chunk.CHUNK_SIZE_Z * Chunk.CHUNK_SIZE_X)) & (Chunk.CHUNK_SIZE_Z - 1);
-                    int iBlockY = (iRandVal / (ChunkSection.SECTION_SIZE_Y * Chunk.CHUNK_SIZE_Z * Chunk.CHUNK_SIZE_X)) & (ChunkSection.SECTION_SIZE_Y - 1) + s * ChunkSection.SECTION_SIZE_Y;
-                    int id = chunk.getBlockID(iBlockX, iBlockY, iBlockZ);
+                    final int iRandVal = this.updateLCG >> 2;
+                    final int iBlockX = iRandVal & (Chunk.CHUNK_SIZE_X - 1);
+                    final int iBlockZ = (iRandVal / (Chunk.CHUNK_SIZE_Z * Chunk.CHUNK_SIZE_X)) & (Chunk.CHUNK_SIZE_Z - 1);
+                    final int iBlockY = (iRandVal / (ChunkSection.SECTION_SIZE_Y * Chunk.CHUNK_SIZE_Z * Chunk.CHUNK_SIZE_X)) & (ChunkSection.SECTION_SIZE_Y - 1) + s * ChunkSection.SECTION_SIZE_Y;
+                    final int id = chunk.getBlockID(iBlockX, iBlockY, iBlockZ);
                     if (Blocks.shouldTick[id]) {
                         Blocks.blocksList[id].updateTick(this, iBlockX + chunkBlockX, iBlockY, iBlockZ + chunkBlockZ, this.rand, true);
                     }
@@ -2134,7 +2096,7 @@ public class World implements MutableWorldSource {
 
         for (int i = 0; i < count; i++) {
             final @NotNull NextTickListEntry entry = this.tickNextTickList.first();
-            if (!all && entry.delay > runtime) {
+            if (!all && entry.delay > this.runtime) {
                 break;
             }
             this.tickNextTickList.remove(entry);
@@ -2156,7 +2118,7 @@ public class World implements MutableWorldSource {
         final int radius = 16;
         final @NotNull Random random = new Random();
 
-        TilePos randomPos = new TilePos();
+        final TilePos randomPos = new TilePos();
         for (int i = 0; i < ANIMATION_TICKS_PER_TICK; i++) {
             tilePos.add(
                 this.rand.nextInt(radius) - this.rand.nextInt(radius),
@@ -2176,16 +2138,16 @@ public class World implements MutableWorldSource {
         this.randomDisplayUpdates(new TilePos(x, y, z));
     }
 
-    public @NotNull List<@NotNull Entity> getEntitiesWithinAABBExcludingEntity(@Nullable Entity entity, @NotNull AABBdc aabb) {
+    public @NotNull List<@NotNull Entity> getEntitiesWithinAABBExcludingEntity(@Nullable final Entity entity, @NotNull final AABBdc aabb) {
         this.entityBuffer.clear();
-        int minX = MathHelper.floor((aabb.minX() - 2D) / Chunk.CHUNK_SIZE_X);
-        int maxX = MathHelper.floor((aabb.maxX() + 2D) / Chunk.CHUNK_SIZE_X);
-        int minZ = MathHelper.floor((aabb.minZ() - 2D) / Chunk.CHUNK_SIZE_Z);
-        int maxZ = MathHelper.floor((aabb.maxZ() + 2D) / Chunk.CHUNK_SIZE_Z);
+        final int minX = MathHelper.floor((aabb.minX() - 2D) / Chunk.CHUNK_SIZE_X);
+        final int maxX = MathHelper.floor((aabb.maxX() + 2D) / Chunk.CHUNK_SIZE_X);
+        final int minZ = MathHelper.floor((aabb.minZ() - 2D) / Chunk.CHUNK_SIZE_Z);
+        final int maxZ = MathHelper.floor((aabb.maxZ() + 2D) / Chunk.CHUNK_SIZE_Z);
         for (int x = minX; x <= maxX; x++) {
             for (int z = minZ; z <= maxZ; z++) {
-                if (isChunkLoaded(x, z)) {
-                    getChunkFromChunkCoords(x, z).getEntitiesWithin(entity, aabb, this.entityBuffer);
+                if (this.isChunkLoaded(x, z)) {
+                    this.getChunkFromChunkCoords(x, z).getEntitiesWithin(entity, aabb, this.entityBuffer);
                 }
             }
         }
@@ -2193,16 +2155,16 @@ public class World implements MutableWorldSource {
         return this.entityBuffer;
     }
 
-    public <T extends Entity> @NotNull List<@NotNull T> getEntitiesWithinAABB(@NotNull Class<T> ofClass, @NotNull AABBdc aabb) {
-        int minX = MathHelper.floor((aabb.minX() - 2D) / Chunk.CHUNK_SIZE_X);
-        int maxX = MathHelper.floor((aabb.maxX() + 2D) / Chunk.CHUNK_SIZE_X);
-        int minZ = MathHelper.floor((aabb.minZ() - 2D) / Chunk.CHUNK_SIZE_Z);
-        int maxZ = MathHelper.floor((aabb.maxZ() + 2D) / Chunk.CHUNK_SIZE_Z);
-        List<@NotNull T> entities = new ArrayList<>();
+    public <T extends Entity> @NotNull List<@NotNull T> getEntitiesWithinAABB(@NotNull final Class<T> ofClass, @NotNull final AABBdc aabb) {
+        final int minX = MathHelper.floor((aabb.minX() - 2D) / Chunk.CHUNK_SIZE_X);
+        final int maxX = MathHelper.floor((aabb.maxX() + 2D) / Chunk.CHUNK_SIZE_X);
+        final int minZ = MathHelper.floor((aabb.minZ() - 2D) / Chunk.CHUNK_SIZE_Z);
+        final int maxZ = MathHelper.floor((aabb.maxZ() + 2D) / Chunk.CHUNK_SIZE_Z);
+        final List<@NotNull T> entities = new ArrayList<>();
         for (int x = minX; x <= maxX; x++) {
             for (int z = minZ; z <= maxZ; z++) {
-                if (isChunkLoaded(x, z)) {
-                    getChunkFromChunkCoords(x, z).getEntitiesWithin(ofClass, aabb, entities);
+                if (this.isChunkLoaded(x, z)) {
+                    this.getChunkFromChunkCoords(x, z).getEntitiesWithin(ofClass, aabb, entities);
                 }
             }
 
@@ -2211,16 +2173,16 @@ public class World implements MutableWorldSource {
         return entities;
     }
 
-    public <T extends Entity> @NotNull List<@NotNull T> getEntitiesWithinRadius(@NotNull Class<T> ofClass, double x, double y, double z, double radius) {
-        int minX = MathHelper.floor(x - radius);
-        int minZ = MathHelper.floor(z - radius);
-        int maxX = MathHelper.ceil(x + radius);
-        int maxZ = MathHelper.ceil(z + radius);
-        List<@NotNull T> entities = new ArrayList<>();
+    public <T extends Entity> @NotNull List<@NotNull T> getEntitiesWithinRadius(@NotNull final Class<T> ofClass, final double x, final double y, final double z, final double radius) {
+        final int minX = MathHelper.floor(x - radius);
+        final int minZ = MathHelper.floor(z - radius);
+        final int maxX = MathHelper.ceil(x + radius);
+        final int maxZ = MathHelper.ceil(z + radius);
+        final List<@NotNull T> entities = new ArrayList<>();
         for (int bx = minX; bx <= maxX; bx++) {
             for (int bz = minZ; bz <= maxZ; bz++) {
-                if (isChunkLoaded(bx, bz)) {
-                    getChunkFromChunkCoords(bx, bz).getEntitiesWithinRadius(ofClass, x, y, z, radius, entities);
+                if (this.isChunkLoaded(bx, bz)) {
+                    this.getChunkFromChunkCoords(bx, bz).getEntitiesWithinRadius(ofClass, x, y, z, radius, entities);
                 }
             }
         }
@@ -2251,10 +2213,10 @@ public class World implements MutableWorldSource {
         this.updateTileEntityChunkAndSendToPlayer(new TilePos(x, y, z), tileEntity);
     }
 
-    public int countEntities(Class<?> clazz) {
+    public int countEntities(final Class<?> clazz) {
         int i = 0;
         for (int j = 0, entitiesSize = this.entities.size(); j < entitiesSize; j++) {
-            Entity entity = this.entities.get(j);
+            final Entity entity = this.entities.get(j);
             if (clazz.isAssignableFrom(entity.getClass())) {
                 i++;
             }
@@ -2263,16 +2225,16 @@ public class World implements MutableWorldSource {
         return i;
     }
 
-    public void addLoadedEntities(List<Entity> list) {
+    public void addLoadedEntities(final List<Entity> list) {
         this.entities.addAll(list);
         for (int i = 0, listSize = list.size(); i < listSize; i++) {
-            Entity entity = list.get(i);
-            obtainEntitySkin(entity);
+            final Entity entity = list.get(i);
+            this.obtainEntitySkin(entity);
         }
 
     }
 
-    public void unloadEntities(List<Entity> list) {
+    public void unloadEntities(final List<Entity> list) {
         this.entitiesToRemove.addAll(list);
     }
 
@@ -2312,18 +2274,18 @@ public class World implements MutableWorldSource {
         return this.canBlockIdBePlacedAt(id, new TilePos(x, y, z), ignoreCollision, side);
     }
 
-    public @Nullable Path getPathToEntity(Entity entity, Entity entityToTravelTo, float distance) {
-        int x1 = MathHelper.floor(entity.x);
-        int y2 = MathHelper.floor(entity.y);
-        int z1 = MathHelper.floor(entity.z);
-        int radius = (int) (distance + 16F);
-        int xMin = x1 - radius;
-        int yMin = y2 - radius;
-        int zMin = z1 - radius;
-        int xMax = x1 + radius;
-        int yMax = y2 + radius;
-        int zMax = z1 + radius;
-        ChunkCache chunkcache = new ChunkCache(this, xMin, yMin, zMin, xMax, yMax, zMax);
+    public @Nullable Path getPathToEntity(final Entity entity, final Entity entityToTravelTo, final float distance) {
+        final int x1 = MathHelper.floor(entity.x);
+        final int y2 = MathHelper.floor(entity.y);
+        final int z1 = MathHelper.floor(entity.z);
+        final int radius = (int) (distance + 16F);
+        final int xMin = x1 - radius;
+        final int yMin = y2 - radius;
+        final int zMin = z1 - radius;
+        final int xMax = x1 + radius;
+        final int yMax = y2 + radius;
+        final int zMax = z1 + radius;
+        final ChunkCache chunkcache = new ChunkCache(this, xMin, yMin, zMin, xMax, yMax, zMax);
         return (new PathFinder(chunkcache)).findPath(entity, entityToTravelTo, distance);
     }
 
@@ -2354,7 +2316,7 @@ public class World implements MutableWorldSource {
     }
 
     public boolean hasDirectSignal(final @NotNull TilePosc tilePos) {
-        TilePos queryPos = new TilePos();
+        final TilePos queryPos = new TilePos();
         for (final @NotNull Side side : Side.sides) {
             if (this.hasDirectSignal(tilePos.add(side.getDirection(), queryPos), side)) {
                 return true;
@@ -2416,29 +2378,29 @@ public class World implements MutableWorldSource {
         return this.hasNeighborSignal(new TilePos(x, y, z));
     }
 
-    public Player getClosestPlayerToEntity(Entity entity, double radius) {
-        return getClosestPlayer(entity.x, entity.y, entity.z, radius);
+    public Player getClosestPlayerToEntity(final Entity entity, final double radius) {
+        return this.getClosestPlayer(entity.x, entity.y, entity.z, radius);
     }
 
     /**
      * @param radius Radius around the point to search for a player, a radius less than 0 denotes searching for the closest player with 0 regard for radius
      */
-    public Player getClosestPlayer(double x, double y, double z, double radius) {
+    public Player getClosestPlayer(final double x, final double y, final double z, final double radius) {
         double closestDistance = Double.POSITIVE_INFINITY;
         Player entityplayer = null;
         if (radius < 0) {
 
-            for (Player entityPlayer1 : this.players) {
-                double currentDistance = entityPlayer1.distanceToSqr(x, y, z);
+            for (final Player entityPlayer1 : this.players) {
+                final double currentDistance = entityPlayer1.distanceToSqr(x, y, z);
                 if ((currentDistance < closestDistance)) {
                     closestDistance = currentDistance;
                     entityplayer = entityPlayer1;
                 }
             }
         } else {
-            double rSquared = radius * radius;
-            for (Player entityPlayer1 : this.players) {
-                double currentDistance = entityPlayer1.distanceToSqr(x, y, z);
+            final double rSquared = radius * radius;
+            for (final Player entityPlayer1 : this.players) {
+                final double currentDistance = entityPlayer1.distanceToSqr(x, y, z);
                 if (currentDistance < rSquared && (currentDistance < closestDistance)) {
                     closestDistance = currentDistance;
                     entityplayer = entityPlayer1;
@@ -2449,8 +2411,8 @@ public class World implements MutableWorldSource {
     }
 
 
-    public Player getPlayerEntityByName(String s) {
-        for (Player player : this.players) {
+    public Player getPlayerEntityByName(final String s) {
+        for (final Player player : this.players) {
             if (s.equals(player.username)) {
                 return player;
             }
@@ -2469,19 +2431,19 @@ public class World implements MutableWorldSource {
         return null;
     }
 
-    public void setChunkData(int x, int y, int z, int width, int height, int length, byte[] data) {
-        int minChunkX = Math.floorDiv(x, Chunk.CHUNK_SIZE_X);
-        int minChunkZ = Math.floorDiv(z, Chunk.CHUNK_SIZE_Z);
-        int maxChunkX = Math.floorDiv((x + width) - 1, Chunk.CHUNK_SIZE_X);
-        int maxChunkZ = Math.floorDiv((z + length) - 1, Chunk.CHUNK_SIZE_Z);
+    public void setChunkData(final int x, final int y, final int z, final int width, final int height, final int length, final byte[] data) {
+        final int minChunkX = Math.floorDiv(x, Chunk.CHUNK_SIZE_X);
+        final int minChunkZ = Math.floorDiv(z, Chunk.CHUNK_SIZE_Z);
+        final int maxChunkX = Math.floorDiv((x + width) - 1, Chunk.CHUNK_SIZE_X);
+        final int maxChunkZ = Math.floorDiv((z + length) - 1, Chunk.CHUNK_SIZE_Z);
         int startIndex = 0;
         int minY = y;
         int maxY = y + height;
         if (minY < 0) {
             minY = 0;
         }
-        if (maxY > getHeightBlocks()) {
-            maxY = getHeightBlocks();
+        if (maxY > this.getHeightBlocks()) {
+            maxY = this.getHeightBlocks();
         }
         for (int chunkX = minChunkX; chunkX <= maxChunkX; chunkX++) {
             int minX = x - chunkX * Chunk.CHUNK_SIZE_X;
@@ -2501,28 +2463,28 @@ public class World implements MutableWorldSource {
                 if (maxZ > Chunk.CHUNK_SIZE_Z) {
                     maxZ = Chunk.CHUNK_SIZE_Z;
                 }
-                startIndex = getChunkFromChunkCoords(chunkX, chunkZ).setChunkData(data, minX, minY, minZ, maxX, maxY, maxZ, startIndex);
-                markBlocksDirty(chunkX * Chunk.CHUNK_SIZE_X + minX, minY, chunkZ * Chunk.CHUNK_SIZE_Z + minZ, chunkX * Chunk.CHUNK_SIZE_X + maxX, maxY, chunkZ * Chunk.CHUNK_SIZE_Z + maxZ);
+                startIndex = this.getChunkFromChunkCoords(chunkX, chunkZ).setChunkData(data, minX, minY, minZ, maxX, maxY, maxZ, startIndex);
+                this.markBlocksDirty(chunkX * Chunk.CHUNK_SIZE_X + minX, minY, chunkZ * Chunk.CHUNK_SIZE_Z + minZ, chunkX * Chunk.CHUNK_SIZE_X + maxX, maxY, chunkZ * Chunk.CHUNK_SIZE_Z + maxZ);
             }
 
         }
 
     }
 
-    public byte[] getChunkData(int x, int y, int z, int xSize, int ySize, int zSize) {
-        byte[] data = new byte[xSize * ySize * zSize * 8];
-        int minChunkX = Math.floorDiv(x, Chunk.CHUNK_SIZE_X);
-        int minChunkZ = Math.floorDiv(z, Chunk.CHUNK_SIZE_Z);
-        int maxChunkX = Math.floorDiv((x + xSize) - 1, Chunk.CHUNK_SIZE_X);
-        int maxChunkZ = Math.floorDiv((z + zSize) - 1, Chunk.CHUNK_SIZE_Z);
+    public byte[] getChunkData(final int x, final int y, final int z, final int xSize, final int ySize, final int zSize) {
+        final byte[] data = new byte[xSize * ySize * zSize * 8];
+        final int minChunkX = Math.floorDiv(x, Chunk.CHUNK_SIZE_X);
+        final int minChunkZ = Math.floorDiv(z, Chunk.CHUNK_SIZE_Z);
+        final int maxChunkX = Math.floorDiv((x + xSize) - 1, Chunk.CHUNK_SIZE_X);
+        final int maxChunkZ = Math.floorDiv((z + zSize) - 1, Chunk.CHUNK_SIZE_Z);
         int startIndex = 0;
         int minY = y;
         int maxY = y + ySize;
         if (minY < 0) {
             minY = 0;
         }
-        if (maxY > getHeightBlocks()) {
-            maxY = getHeightBlocks();
+        if (maxY > this.getHeightBlocks()) {
+            maxY = this.getHeightBlocks();
         }
         for (int chunkX = minChunkX; chunkX <= maxChunkX; chunkX++) {
             int minX = x - chunkX * Chunk.CHUNK_SIZE_X;
@@ -2542,7 +2504,7 @@ public class World implements MutableWorldSource {
                 if (maxZ > Chunk.CHUNK_SIZE_Z) {
                     maxZ = Chunk.CHUNK_SIZE_Z;
                 }
-                startIndex = getChunkFromChunkCoords(chunkX, chunkZ).getChunkData(data, minX, minY, minZ, maxX, maxY, maxZ, startIndex);
+                startIndex = this.getChunkFromChunkCoords(chunkX, chunkZ).getChunkData(data, minX, minY, minZ, maxX, maxY, maxZ, startIndex);
             }
 
         }
@@ -2557,7 +2519,7 @@ public class World implements MutableWorldSource {
         this.levelStorage.checkSessionLock();
     }
 
-    public void setWorldTime(long l) {
+    public void setWorldTime(final long l) {
         this.levelData.setWorldTime(l);
     }
 
@@ -2583,29 +2545,29 @@ public class World implements MutableWorldSource {
         return this.levelData.getDifficulty();
     }
 
-    public void setDifficulty(Difficulty difficulty, boolean overrideLock) {
+    public void setDifficulty(final Difficulty difficulty, final boolean overrideLock) {
         this.levelData.setDifficulty(difficulty, overrideLock);
     }
 
-    public void setDifficulty(int difficulty, boolean overrideLock) {
+    public void setDifficulty(final int difficulty, final boolean overrideLock) {
         this.levelData.setDifficulty(difficulty, overrideLock);
     }
 
     public @NotNull TilePos getSpawnPoint() {
-        return new TilePos(this.levelData.getSpawnX(), this.levelData.getSpawnY(), this.levelData.getSpawnZ());
+        return new TilePos(this.levelData.getSpawnPos());
     }
 
-    public void setSpawnPoint(ChunkCoordinates chunkcoordinates) {
-        this.levelData.setSpawn(chunkcoordinates.x, chunkcoordinates.y, chunkcoordinates.z);
+    public void setSpawnPoint(final ChunkCoordinates chunkcoordinates) {
+        this.levelData.getSpawnPos().set(chunkcoordinates.x, chunkcoordinates.y, chunkcoordinates.z);
     }
 
-    public void joinEntityInSurroundings(Entity entity) {
-        int i = MathHelper.floor(entity.x / Chunk.CHUNK_SIZE_X);
-        int j = MathHelper.floor(entity.z / Chunk.CHUNK_SIZE_Z);
-        byte byte0 = 2;
+    public void joinEntityInSurroundings(final Entity entity) {
+        final int i = MathHelper.floor(entity.x / Chunk.CHUNK_SIZE_X);
+        final int j = MathHelper.floor(entity.z / Chunk.CHUNK_SIZE_Z);
+        final byte byte0 = 2;
         for (int k = i - byte0; k <= i + byte0; k++) {
             for (int l = j - byte0; l <= j + byte0; l++) {
-                getChunkFromChunkCoords(k, l);
+                this.getChunkFromChunkCoords(k, l);
             }
 
         }
@@ -2624,34 +2586,34 @@ public class World implements MutableWorldSource {
         return this.canMineBlock(player, new TilePos(x, y, z));
     }
 
-    public void sendTrackedEntityStatusUpdatePacket(Entity entityId, byte entityStatus) {
+    public void sendTrackedEntityStatusUpdatePacket(final Entity entityId, final byte entityStatus) {
     }
 
-    public void sendTrackedEntityStatusUpdatePacket(Entity entityId, byte entityStatus, float attackedAtYaw) {
+    public void sendTrackedEntityStatusUpdatePacket(final Entity entityId, final byte entityStatus, final float attackedAtYaw) {
     }
 
-    public void sendTrackedEntityDataPacket(Entity entity) {
+    public void sendTrackedEntityDataPacket(final Entity entity) {
 
     }
 
     public void updateEntityList() {
         this.entities.removeAll(this.entitiesToRemove);
         for (int i = 0; i < this.entitiesToRemove.size(); i++) {
-            Entity entity = this.entitiesToRemove.get(i);
-            int cX = entity.chunkCoordX;
-            int cZ = entity.chunkCoordZ;
-            if (entity.addedToChunk && isChunkLoaded(cX, cZ)) {
-                getChunkFromChunkCoords(cX, cZ).removeEntity(entity);
+            final Entity entity = this.entitiesToRemove.get(i);
+            final int cX = entity.chunkCoordX;
+            final int cZ = entity.chunkCoordZ;
+            if (entity.addedToChunk && this.isChunkLoaded(cX, cZ)) {
+                this.getChunkFromChunkCoords(cX, cZ).removeEntity(entity);
             }
         }
 
         for (int j = 0; j < this.entitiesToRemove.size(); j++) {
-            releaseEntitySkin(this.entitiesToRemove.get(j));
+            this.releaseEntitySkin(this.entitiesToRemove.get(j));
         }
 
         this.entitiesToRemove.clear();
         for (int i = 0; i < this.entities.size(); i++) {
-            Entity entity = this.entities.get(i);
+            final Entity entity = this.entities.get(i);
             if (entity.vehicle != null) {
                 if (!entity.vehicle.isRemoved() && entity.vehicle.getPassenger() == entity) {
                     continue;
@@ -2662,18 +2624,18 @@ public class World implements MutableWorldSource {
             if (!entity.removed) {
                 continue;
             }
-            int cX = entity.chunkCoordX;
-            int cZ = entity.chunkCoordZ;
-            if (entity.addedToChunk && isChunkLoaded(cX, cZ)) {
-                getChunkFromChunkCoords(cX, cZ).removeEntity(entity);
+            final int cX = entity.chunkCoordX;
+            final int cZ = entity.chunkCoordZ;
+            if (entity.addedToChunk && this.isChunkLoaded(cX, cZ)) {
+                this.getChunkFromChunkCoords(cX, cZ).removeEntity(entity);
             }
             this.entities.remove(i--);
-            releaseEntitySkin(entity);
+            this.releaseEntitySkin(entity);
         }
 
     }
 
-    public IChunkProvider getChunkProvider() {
+    public @NotNull ChunkProvider getChunkProvider() {
         return this.chunkProvider;
     }
 
@@ -2701,12 +2663,12 @@ public class World implements MutableWorldSource {
         return this.dimensionData;
     }
 
-    public void updateEnoughPlayersSleepingFlag(Player player) {
+    public void updateEnoughPlayersSleepingFlag(final Player player) {
         this.enoughPlayersSleeping = false;
         if (!this.players.isEmpty()) {
             int playersSleeping = 0;
-            int req = getPlayersRequiredToSkipNight();
-            for (Player p : this.players)
+            final int req = this.getPlayersRequiredToSkipNight();
+            for (final Player p : this.players)
                 if (p.isPlayerSleeping()) playersSleeping++;
             if (playersSleeping >= req) {
                 this.enoughPlayersSleeping = true;
@@ -2720,22 +2682,22 @@ public class World implements MutableWorldSource {
 
     protected void wakeUpAllPlayers() {
         this.enoughPlayersSleeping = false;
-        for (Player entityplayer : this.players) {
+        for (final Player entityplayer : this.players) {
             if (entityplayer.isPlayerSleeping()) {
                 entityplayer.wakeUpPlayer(false, false);
             }
         }
-        final @Nullable Weather currentWeather = getCurrentWeather();
+        final @Nullable Weather currentWeather = this.getCurrentWeather();
         if (currentWeather instanceof IPrecipitation && ((IPrecipitation) currentWeather).spawnRainParticles()) {
-            this.weatherManager.overrideWeather(this.worldType.getDefaultWeather());
+            this.weatherManager.overrideWeather(this.getWorldType().getDefaultWeather());
         }
     }
 
     public boolean areEnoughPlayersFullyAsleep() {
         if (this.enoughPlayersSleeping && !this.isClientSide) {
             int fullyAsleep = 0;
-            for (Player player : this.players) if (player.isPlayerFullyAsleep()) fullyAsleep++;
-            return fullyAsleep >= getPlayersRequiredToSkipNight() && fullyAsleep > 0;
+            for (final Player player : this.players) if (player.isPlayerFullyAsleep()) fullyAsleep++;
+            return fullyAsleep >= this.getPlayersRequiredToSkipNight() && fullyAsleep > 0;
         } else {
             return false;
         }
@@ -2766,16 +2728,16 @@ public class World implements MutableWorldSource {
         return this.isBlockBeingRainedOn(new TilePos(x, y, z));
     }
 
-    public void setSavedData(String id, SavedData savedData) {
-        this.savedDataStorage.set(id, savedData);
+    public void setSavedData(final String id, final SavedData savedData) {
+        this.getLevelStorage().getSavedDataStorage().set(id, savedData);
     }
 
-    public SavedData getSavedData(Class<? extends SavedData> saveDataClass, String id) {
-        return this.savedDataStorage.load(saveDataClass, id);
+    public SavedData getSavedData(final Class<? extends SavedData> saveDataClass, final String id) {
+        return this.getLevelStorage().getSavedDataStorage().load(saveDataClass, id);
     }
 
-    public int getUniqueDataId(String s) {
-        return this.savedDataStorage.getFreeMetadataFor(s);
+    public int getUniqueDataId(final String s) {
+        return this.getLevelStorage().getSavedDataStorage().getFreeMetadataFor(s);
     }
 
     public void playBlockEvent(final @NotNull TilePosc tilePos, final int id, final int data) {
@@ -2799,7 +2761,7 @@ public class World implements MutableWorldSource {
     }
 
     public @NotNull WorldType getWorldType() {
-        return this.worldType;
+        return this.dimensionData.getWorldType();
     }
 
     public @NotNull EntityItem dropItem(final @NotNull TilePosc tilePos, final @NotNull ItemStack itemStack) {
@@ -2819,8 +2781,8 @@ public class World implements MutableWorldSource {
         return this.dropItem(new TilePos(x, y, z), itemStack);
     }
 
-    public void sendGlobalMessage(String message) {
-        for (Player player : this.players) {
+    public void sendGlobalMessage(final String message) {
+        for (final Player player : this.players) {
             player.sendMessage(message);
         }
     }
diff --git a/game/core/src/main/java/net/minecraft/core/world/chunk/Chunk.java b/game/core/src/main/java/net/minecraft/core/world/chunk/Chunk.java
index 24d906cfd..df17a90bd 100644
--- a/game/core/src/main/java/net/minecraft/core/world/chunk/Chunk.java
+++ b/game/core/src/main/java/net/minecraft/core/world/chunk/Chunk.java
@@ -148,7 +148,7 @@ public class Chunk {
         recalcHeightmapOnly();
 
         // Generate skylight map
-        if (!this.world.worldType.hasCeiling()) {
+        if (!this.world.getWorldType().hasCeiling()) {
             for (int x = 0; x < CHUNK_SIZE_X; x++) {
                 for (int z = 0; z < CHUNK_SIZE_Z; z++) {
                     int skyLightValue = 15;
diff --git a/game/core/src/main/java/net/minecraft/core/world/chunk/ChunkCache.java b/game/core/src/main/java/net/minecraft/core/world/chunk/ChunkCache.java
index 8513989ec..3591baf06 100644
--- a/game/core/src/main/java/net/minecraft/core/world/chunk/ChunkCache.java
+++ b/game/core/src/main/java/net/minecraft/core/world/chunk/ChunkCache.java
@@ -135,7 +135,7 @@ public class ChunkCache
 
     @Override
     public float getLightBrightness(final @NotNull TilePosc tilePos) {
-        return this.world.worldType.getBrightnessRamp()[this.getBlockLightValue(tilePos)];
+        return this.world.getWorldType().getBrightnessRamp()[this.getBlockLightValue(tilePos)];
     }
 
     public int getBlockLightValue(final @NotNull TilePosc tilePos) {
diff --git a/game/core/src/main/java/net/minecraft/core/world/chunk/IChunkLoader.java b/game/core/src/main/java/net/minecraft/core/world/chunk/ChunkLoader.java
similarity index 96%
rename from game/core/src/main/java/net/minecraft/core/world/chunk/IChunkLoader.java
rename to game/core/src/main/java/net/minecraft/core/world/chunk/ChunkLoader.java
index ba2d08b41..96b6b1048 100644
--- a/game/core/src/main/java/net/minecraft/core/world/chunk/IChunkLoader.java
+++ b/game/core/src/main/java/net/minecraft/core/world/chunk/ChunkLoader.java
@@ -4,7 +4,7 @@ import net.minecraft.core.world.World;
 
 import java.io.IOException;
 
-public interface IChunkLoader
+public interface ChunkLoader
 {
     /**
      * Loads a chunk into memory.
diff --git a/game/core/src/main/java/net/minecraft/core/world/chunk/ChunkLoaderLegacy.java b/game/core/src/main/java/net/minecraft/core/world/chunk/ChunkLoaderLegacy.java
index 11196739e..8d9780774 100644
--- a/game/core/src/main/java/net/minecraft/core/world/chunk/ChunkLoaderLegacy.java
+++ b/game/core/src/main/java/net/minecraft/core/world/chunk/ChunkLoaderLegacy.java
@@ -34,7 +34,7 @@ import java.util.Arrays;
 import java.util.List;
 
 public class ChunkLoaderLegacy
-    implements IChunkLoader
+    implements ChunkLoader
 {
     private static final Logger LOGGER = LogUtils.getLogger();
     public ChunkLoaderLegacy(File worldDir, boolean createIfNecessary)
diff --git a/game/core/src/main/java/net/minecraft/core/world/chunk/ChunkLoaderRegion.java b/game/core/src/main/java/net/minecraft/core/world/chunk/ChunkLoaderRegion.java
index b79a94178..4d9a5f59f 100644
--- a/game/core/src/main/java/net/minecraft/core/world/chunk/ChunkLoaderRegion.java
+++ b/game/core/src/main/java/net/minecraft/core/world/chunk/ChunkLoaderRegion.java
@@ -13,7 +13,7 @@ import java.io.*;
 import java.util.zip.ZipException;
 
 public class ChunkLoaderRegion
-    implements IChunkLoader
+    implements ChunkLoader
 {
     private static final Logger LOGGER = LogUtils.getLogger();
     private final File worldDir;
diff --git a/game/core/src/main/java/net/minecraft/core/world/chunk/ChunkLoaderRegionAsync.java b/game/core/src/main/java/net/minecraft/core/world/chunk/ChunkLoaderRegionAsync.java
index a55c108ce..995322c38 100644
--- a/game/core/src/main/java/net/minecraft/core/world/chunk/ChunkLoaderRegionAsync.java
+++ b/game/core/src/main/java/net/minecraft/core/world/chunk/ChunkLoaderRegionAsync.java
@@ -13,7 +13,7 @@ import java.util.concurrent.locks.Lock;
 import java.util.concurrent.locks.ReentrantLock;
 
 public class ChunkLoaderRegionAsync
-    implements IChunkLoader
+    implements ChunkLoader
 {
     private static final Logger LOGGER = LogUtils.getLogger();
     private static final Queue<Chunk> chunksToSave = new LinkedList<>();
diff --git a/game/core/src/main/java/net/minecraft/core/world/chunk/provider/IChunkProvider.java b/game/core/src/main/java/net/minecraft/core/world/chunk/provider/ChunkProvider.java
similarity index 71%
rename from game/core/src/main/java/net/minecraft/core/world/chunk/provider/IChunkProvider.java
rename to game/core/src/main/java/net/minecraft/core/world/chunk/provider/ChunkProvider.java
index 5068c601c..7e370efbd 100644
--- a/game/core/src/main/java/net/minecraft/core/world/chunk/provider/IChunkProvider.java
+++ b/game/core/src/main/java/net/minecraft/core/world/chunk/provider/ChunkProvider.java
@@ -3,46 +3,47 @@ package net.minecraft.core.world.chunk.provider;
 import net.minecraft.core.world.ProgressListener;
 import net.minecraft.core.world.chunk.Chunk;
 import net.minecraft.core.world.pos.ChunkPos;
+import net.minecraft.core.world.pos.ChunkPosc;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 
-public interface IChunkProvider {
+public interface ChunkProvider {
 
     @Deprecated
     default boolean isChunkLoaded(int chunkX, int chunkZ) {
         return isChunkLoaded(new ChunkPos(chunkX, chunkZ));
     }
-    boolean isChunkLoaded(@NotNull ChunkPos chunkPos);
+    boolean isChunkLoaded(@NotNull ChunkPosc chunkPos);
 
     @Deprecated
     default @NotNull Chunk provideChunk(int chunkX, int chunkZ) {
         return provideChunk(new ChunkPos(chunkX, chunkZ), true);
     }
-    @NotNull Chunk provideChunk(@NotNull ChunkPos chunkPos, boolean priority);
+    @NotNull Chunk provideChunk(@NotNull ChunkPosc chunkPos, boolean priority);
 
     @Deprecated
     default @NotNull Chunk prepareChunk(int chunkX, int chunkZ) {
         return prepareChunk(new ChunkPos(chunkX, chunkZ), true);
     }
-    @NotNull Chunk prepareChunk(@NotNull ChunkPos chunkPos, boolean priority);
+    @NotNull Chunk prepareChunk(@NotNull ChunkPosc chunkPos, boolean priority);
 
     @Deprecated
     default void regenerateChunk(int chunkX, int chunkZ) {
         regenerateChunk(new ChunkPos(chunkX, chunkZ));
     }
-    void regenerateChunk(@NotNull ChunkPos chunkPos);
+    void regenerateChunk(@NotNull ChunkPosc chunkPos);
 
     @Deprecated
-    default void populate(IChunkProvider chunkProvider, int chunkX, int chunkZ) {
+    default void populate(ChunkProvider chunkProvider, int chunkX, int chunkZ) {
         populate(new ChunkPos(chunkX, chunkZ));
     }
-    void populate(@NotNull ChunkPos chunkPos);
+    void populate(@NotNull ChunkPosc chunkPos);
 
     @Deprecated
     default void setCurrentChunkOver(int chunkX, int chunkZ) {
         setCurrentChunkOver(new ChunkPos(chunkX, chunkZ));
     }
-    void setCurrentChunkOver(@NotNull ChunkPos chunkPos);
+    void setCurrentChunkOver(@NotNull ChunkPosc chunkPos);
 
     boolean saveChunks(boolean saveImmediately, @Nullable ProgressListener progressListener);
 
diff --git a/game/core/src/main/java/net/minecraft/core/world/chunk/provider/ChunkProviderThreaded.java b/game/core/src/main/java/net/minecraft/core/world/chunk/provider/ChunkProviderThreaded.java
index 00f8aaf2f..8ffa47a9e 100644
--- a/game/core/src/main/java/net/minecraft/core/world/chunk/provider/ChunkProviderThreaded.java
+++ b/game/core/src/main/java/net/minecraft/core/world/chunk/provider/ChunkProviderThreaded.java
@@ -7,9 +7,10 @@ import net.minecraft.core.entity.player.Player;
 import net.minecraft.core.world.ProgressListener;
 import net.minecraft.core.world.World;
 import net.minecraft.core.world.chunk.Chunk;
-import net.minecraft.core.world.chunk.IChunkLoader;
+import net.minecraft.core.world.chunk.ChunkLoader;
 import net.minecraft.core.world.generate.chunk.ChunkGenerator;
 import net.minecraft.core.world.pos.ChunkPos;
+import net.minecraft.core.world.pos.ChunkPosc;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 import org.slf4j.Logger;
@@ -23,13 +24,13 @@ import java.util.Map;
 import java.util.Set;
 import java.util.concurrent.atomic.AtomicBoolean;
 
-public class ChunkProviderThreaded implements IChunkProvider {
+public class ChunkProviderThreaded implements ChunkProvider {
     protected static final Logger LOGGER = LogUtils.getLogger();
     protected static final @NotNull ChunkPos MIN_POS = new ChunkPos(Integer.MIN_VALUE, Integer.MIN_VALUE);
 
     protected final @NotNull Chunk empty;
     protected final @NotNull World world;
-    protected final @NotNull IChunkLoader chunkLoader;
+    protected final @NotNull ChunkLoader chunkLoader;
     protected final @NotNull ChunkGenerator chunkGenerator;
     protected final @NotNull ChunkGenThread genThread;
 
@@ -44,7 +45,7 @@ public class ChunkProviderThreaded implements IChunkProvider {
 
     protected int tickCount = 0;
 
-    public ChunkProviderThreaded(@NotNull World world, @NotNull IChunkLoader chunkLoader, @NotNull ChunkGenerator chunkGenerator) {
+    public ChunkProviderThreaded(@NotNull World world, @NotNull ChunkLoader chunkLoader, @NotNull ChunkGenerator chunkGenerator) {
         this.world = world;
         this.chunkLoader = chunkLoader;
         this.chunkGenerator = chunkGenerator;
@@ -59,7 +60,7 @@ public class ChunkProviderThreaded implements IChunkProvider {
     }
 
     @Override
-    public boolean isChunkLoaded(@NotNull ChunkPos chunkPos) {
+    public boolean isChunkLoaded(@NotNull ChunkPosc chunkPos) {
         if (chunkPos.equals(this.lastQueriedChunkPos)) return true;
         boolean isLoaded;
         synchronized (this.loadedChunks) {
@@ -73,7 +74,7 @@ public class ChunkProviderThreaded implements IChunkProvider {
     }
 
     @Override
-    public @NotNull Chunk provideChunk(@NotNull ChunkPos chunkPos, boolean priority) {
+    public @NotNull Chunk provideChunk(@NotNull ChunkPosc chunkPos, boolean priority) {
         if (chunkPos.equals(this.lastQueriedChunkPos)) return this.lastQueriedChunk;
 
         Chunk chunk;
@@ -81,7 +82,7 @@ public class ChunkProviderThreaded implements IChunkProvider {
             chunk = this.loadedChunks.get(chunkPos);
         }
         if (chunk != null) {
-            this.lastQueriedChunkPos = chunkPos;
+            this.lastQueriedChunkPos = new ChunkPos(chunkPos);
             this.lastQueriedChunk = chunk;
             if (!chunk.isTerrainPopulated) {
                 handleDecoration(chunk);
@@ -101,17 +102,17 @@ public class ChunkProviderThreaded implements IChunkProvider {
     }
 
     @Override
-    public @NotNull Chunk prepareChunk(@NotNull ChunkPos chunkPos, boolean priority) {
+    public @NotNull Chunk prepareChunk(@NotNull ChunkPosc chunkPos, boolean priority) {
         return provideChunk(chunkPos, priority);
     }
 
     @Override
-    public void regenerateChunk(@NotNull ChunkPos chunkPos) {
+    public void regenerateChunk(@NotNull ChunkPosc chunkPos) {
         throw new UnsupportedOperationException();
     }
 
     @Override
-    public void populate(@NotNull ChunkPos chunkPos) {
+    public void populate(@NotNull ChunkPosc chunkPos) {
         Chunk chunk = provideChunk(chunkPos, true);
         decorate(chunk);
     }
@@ -129,8 +130,8 @@ public class ChunkProviderThreaded implements IChunkProvider {
     }
 
     @Override
-    public void setCurrentChunkOver(@NotNull ChunkPos chunkPos) {
-        this.chunkOver = chunkPos;
+    public void setCurrentChunkOver(@NotNull ChunkPosc chunkPos) {
+        this.chunkOver = new ChunkPos(chunkPos);
     }
 
     @Override
@@ -284,11 +285,11 @@ public class ChunkProviderThreaded implements IChunkProvider {
         return true;
     }
 
-    protected boolean isChunkValid(@NotNull ChunkPos chunkPos) {
+    protected boolean isChunkValid(@NotNull ChunkPosc chunkPos) {
         int rd = this.world.renderDistance() + 1;
         if (this.chunkOver != null) {
-            int dx = this.chunkOver.x - chunkPos.x;
-            int dz = this.chunkOver.z - chunkPos.z;
+            int dx = this.chunkOver.x - chunkPos.x();
+            int dz = this.chunkOver.z - chunkPos.z();
             if (dx <= 2 && dx >= -2 && dz <= 2 && dz >= -2) {
                 return true;
             }
@@ -300,8 +301,8 @@ public class ChunkProviderThreaded implements IChunkProvider {
                 Player player = players.get(i);
                 int pCX = ((int) player.x >> 4);
                 int pCZ = ((int) player.z >> 4);
-                int dx = pCX - chunkPos.x;
-                int dz = pCZ - chunkPos.z;
+                int dx = pCX - chunkPos.x();
+                int dz = pCZ - chunkPos.z();
                 if (dx <= rd && dx >= -rd && dz <= rd && dz >= -rd) {
                     return true;
                 }
@@ -310,16 +311,16 @@ public class ChunkProviderThreaded implements IChunkProvider {
         return false;
     }
 
-    private @NotNull Chunk loadChunk(@NotNull ChunkPos chunkPos) {
+    private @NotNull Chunk loadChunk(@NotNull ChunkPosc chunkPos) {
         try {
-            Chunk chunk = this.chunkLoader.loadChunk(this.world, chunkPos.x, chunkPos.z);
+            Chunk chunk = this.chunkLoader.loadChunk(this.world, chunkPos.x(), chunkPos.z());
             if (chunk == null) {
-                chunk = this.chunkGenerator.generate(chunkPos.x, chunkPos.z);
+                chunk = this.chunkGenerator.generate(chunkPos.x(), chunkPos.z());
                 chunk.fixMissingBlocks();
             }
             return chunk;
         } catch (Exception exception) {
-            LOGGER.error("Error loading chunk at X:{}, Z:{}", chunkPos.x, chunkPos.z, exception);
+            LOGGER.error("Error loading chunk at X:{}, Z:{}", chunkPos.x(), chunkPos.z(), exception);
         }
         return this.empty;
     }
@@ -404,13 +405,13 @@ public class ChunkProviderThreaded implements IChunkProvider {
             }
         }
 
-        public void queueChunk(@NotNull ChunkPos chunkPos) {
+        public void queueChunk(@NotNull ChunkPosc chunkPos) {
             synchronized (this.chunkProvider.preparedUndecoratedChunks) {
                 if (this.chunkProvider.preparedUndecoratedChunks.containsKey(chunkPos)) return;
             }
             synchronized (this.chunkQueueSet) {
                 if (!this.chunkQueueSet.contains(chunkPos)) {
-                    this.chunkQueueSet.add(chunkPos);
+                    this.chunkQueueSet.add(new ChunkPos(chunkPos));
                 } else {
                     return;
                 }
diff --git a/game/core/src/main/java/net/minecraft/core/world/config/spawning/SpawnerConfig.java b/game/core/src/main/java/net/minecraft/core/world/config/spawning/SpawnerConfig.java
index 15b9f388b..8678031b7 100644
--- a/game/core/src/main/java/net/minecraft/core/world/config/spawning/SpawnerConfig.java
+++ b/game/core/src/main/java/net/minecraft/core/world/config/spawning/SpawnerConfig.java
@@ -79,7 +79,7 @@ public class SpawnerConfig {
         }
     }
 
-    public static SpawnerConfig createFromTag(CompoundTag tag) {
+    public static @NotNull SpawnerConfig createFromTag(CompoundTag tag) {
         SpawnerConfig config = new SpawnerConfig();
         if (tag != null) {
             config.readFromTag(tag);
diff --git a/game/core/src/main/java/net/minecraft/core/world/generate/chunk/indev/LevelGenerator.java b/game/core/src/main/java/net/minecraft/core/world/generate/chunk/indev/LevelGenerator.java
index e28b80a18..4ed7fd55b 100644
--- a/game/core/src/main/java/net/minecraft/core/world/generate/chunk/indev/LevelGenerator.java
+++ b/game/core/src/main/java/net/minecraft/core/world/generate/chunk/indev/LevelGenerator.java
@@ -249,9 +249,9 @@ public final class LevelGenerator {
     }
 
     public static void generateHouse(@NotNull World world) {
-        int xSpawn = world.getLevelData().getSpawnX();
-        int ySpawn = world.getLevelData().getSpawnY();
-        int zSpawn = world.getLevelData().getSpawnZ();
+        int xSpawn = world.getLevelData().getSpawnPos().x();
+        int ySpawn = world.getLevelData().getSpawnPos().y();
+        int zSpawn = world.getLevelData().getSpawnPos().z();
 
         for (int x = xSpawn - 3; x <= xSpawn + 3; x++) {
             for (int y = ySpawn - 2; y <= ySpawn + 2; y++) {
diff --git a/game/core/src/main/java/net/minecraft/core/world/generate/chunk/perlin/TerrainGeneratorLerp.java b/game/core/src/main/java/net/minecraft/core/world/generate/chunk/perlin/TerrainGeneratorLerp.java
index 2452ce03e..e4ecc9a6a 100644
--- a/game/core/src/main/java/net/minecraft/core/world/generate/chunk/perlin/TerrainGeneratorLerp.java
+++ b/game/core/src/main/java/net/minecraft/core/world/generate/chunk/perlin/TerrainGeneratorLerp.java
@@ -116,7 +116,7 @@ public abstract class TerrainGeneratorLerp
                             for (int zInBlob = 0; zInBlob < zBlocksPerBlob; zInBlob++) {
                                 // Determine the coordinates for the block within the blob.
                                 int blockX = xInBlob + blobX * xBlocksPerBlob;
-                                int blockY = yInBlob + blobY * yBlocksPerBlob + this.world.worldType.getMinY();
+                                int blockY = yInBlob + blobY * yBlocksPerBlob + this.world.getWorldType().getMinY();
                                 int blockZ = zInBlob + blobZ * zBlocksPerBlob;
 
                                 int id = getBlockAt(chunk, blockX, blockY, blockZ, zLerpDensity);
diff --git a/game/core/src/main/java/net/minecraft/core/world/generate/chunk/perlin/overworld/ChunkDecoratorOverworld.java b/game/core/src/main/java/net/minecraft/core/world/generate/chunk/perlin/overworld/ChunkDecoratorOverworld.java
index ec2dbef7a..a0dbfe1c9 100644
--- a/game/core/src/main/java/net/minecraft/core/world/generate/chunk/perlin/overworld/ChunkDecoratorOverworld.java
+++ b/game/core/src/main/java/net/minecraft/core/world/generate/chunk/perlin/overworld/ChunkDecoratorOverworld.java
@@ -605,12 +605,12 @@ public class ChunkDecoratorOverworld
                 int dy = this.world.getHeightValue(dx, dz);
                 Biome localBiome = this.world.getBlockBiome(dx, dy, dz);
 
-                if ((localBiome.hasSurfaceSnow() || this.world.worldType == WorldTypes.OVERWORLD_WINTER) && dy > 0 && dy < this.world.getHeightBlocks()) {
+                if ((localBiome.hasSurfaceSnow() || this.world.getWorldType() == WorldTypes.OVERWORLD_WINTER) && dy > 0 && dy < this.world.getHeightBlocks()) {
                     if (this.world.isAirBlock(dx, dy, dz) && this.world.getBlockMaterial(dx, dy - 1, dz).blocksMotion()) {
                         this.world.setBlockWithNotify(dx, dy, dz, Blocks.LAYER_SNOW.id());
                     }
                 }
-                if ((localBiome.hasSurfaceIce() || this.world.worldType == WorldTypes.OVERWORLD_WINTER) && (this.world.getBlockId(dx, oceanY - 1, dz) == Blocks.FLUID_WATER_STILL.id() || this.world.getBlockId(dx, oceanY - 1, dz) == Blocks.FLUID_WATER_FLOWING.id())) {
+                if ((localBiome.hasSurfaceIce() || this.world.getWorldType() == WorldTypes.OVERWORLD_WINTER) && (this.world.getBlockId(dx, oceanY - 1, dz) == Blocks.FLUID_WATER_STILL.id() || this.world.getBlockId(dx, oceanY - 1, dz) == Blocks.FLUID_WATER_FLOWING.id())) {
                     this.world.setBlockWithNotify(dx, oceanY - 1, dz, Blocks.ICE.id());
                 }
 
diff --git a/game/core/src/main/java/net/minecraft/core/world/lighting/LightingEngineLegacy.java b/game/core/src/main/java/net/minecraft/core/world/lighting/LightingEngineLegacy.java
index 534e8f367..f6847acde 100644
--- a/game/core/src/main/java/net/minecraft/core/world/lighting/LightingEngineLegacy.java
+++ b/game/core/src/main/java/net/minecraft/core/world/lighting/LightingEngineLegacy.java
@@ -57,7 +57,7 @@ public class LightingEngineLegacy implements LightingEngine {
 
     @Override
     public void scheduleLightingUpdate(final LightLayer layer, final int minX, final int minY, final int minZ, final int maxX, final int maxY, final int maxZ) {
-        if(this.world.worldType.hasCeiling() && layer == LightLayer.Sky)
+        if(this.world.getWorldType().hasCeiling() && layer == LightLayer.Sky)
         {
             return;
         }
@@ -276,7 +276,7 @@ public class LightingEngineLegacy implements LightingEngine {
 
         private static void neighborLightPropagationChanged(final LightingEngine lightingEngine, final World world, final LightLayer lightLayer, final int x, final int y, final int z, int lightValue)
         {
-            if(world.worldType.hasCeiling() && lightLayer == LightLayer.Sky)
+            if(world.getWorldType().hasCeiling() && lightLayer == LightLayer.Sky)
             {
                 return;
             }
diff --git a/game/core/src/main/java/net/minecraft/core/world/pos/ChunkPos.java b/game/core/src/main/java/net/minecraft/core/world/pos/ChunkPos.java
index 8fbb56fd2..102c2c9f1 100644
--- a/game/core/src/main/java/net/minecraft/core/world/pos/ChunkPos.java
+++ b/game/core/src/main/java/net/minecraft/core/world/pos/ChunkPos.java
@@ -152,6 +152,12 @@ public final class ChunkPos implements Externalizable, Cloneable, ChunkPosc {
         return this;
     }
 
+    public @NotNull ChunkPos set(final @NotNull ChunkPosc chunkPos) {
+        this.x = chunkPos.x();
+        this.z = chunkPos.z();
+        return this;
+    }
+
     public @NotNull ChunkPos set(@NotNull TilePosc pos) {
         return set(Math.floorDiv(pos.x(), Chunk.CHUNK_SIZE_X), Math.floorDiv(pos.z(), Chunk.CHUNK_SIZE_Z));
     }
diff --git a/game/core/src/main/java/net/minecraft/core/world/save/DimensionData.java b/game/core/src/main/java/net/minecraft/core/world/save/DimensionData.java
index 76d24531b..ada53f8b5 100644
--- a/game/core/src/main/java/net/minecraft/core/world/save/DimensionData.java
+++ b/game/core/src/main/java/net/minecraft/core/world/save/DimensionData.java
@@ -1,5 +1,6 @@
 package net.minecraft.core.world.save;
 
+import com.mojang.logging.LogUtils;
 import com.mojang.nbt.tags.ByteTag;
 import com.mojang.nbt.tags.CompoundTag;
 import com.mojang.nbt.NbtIo;
@@ -7,148 +8,117 @@ import net.minecraft.core.data.legacy.LegacyWorldTypes;
 import net.minecraft.core.data.registry.Registries;
 import net.minecraft.core.world.Dimension;
 import net.minecraft.core.world.type.WorldType;
+import net.minecraft.core.world.type.WorldTypeGroups;
 import net.minecraft.core.world.type.WorldTypes;
 import net.minecraft.core.world.weather.Weather;
 import net.minecraft.core.world.weather.Weathers;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
+import org.slf4j.Logger;
 
 import java.io.File;
 import java.io.IOException;
 import java.nio.file.Files;
 import java.util.Objects;
 
-public class DimensionData
-{
-    private @NotNull String worldType;
-    private int weatherCurrentId = -1;
-    private int weatherNextId = -1;
-    private long weatherDuration;
-    private float weatherIntensity;
-    private float weatherPower;
+public class DimensionData {
+    private static final Logger LOGGER = LogUtils.getLogger();
 
-    public DimensionData(CompoundTag tag)
-    {
-        readFromNBTTag(tag);
-    }
+    public static @NotNull DimensionData fromCompoundTag(final @NotNull CompoundTag tag, final @NotNull Dimension dimension) {
+        @Nullable WorldType worldType = Registries.WORLD_TYPES.getItem(tag.getString("WorldType"));
+        if (worldType == null) {
+            worldType = WorldTypeGroups.DEFAULT.get(dimension);
+        }
 
-    public DimensionData(WorldType worldType)
-    {
-        this.worldType = Registries.WORLD_TYPES.getKey(worldType);
+        final @NotNull DimensionData dimensionData = new DimensionData(worldType);
+
+        final @NotNull CompoundTag weatherTag = tag.getCompound("Weather");
+        dimensionData.weatherCurrentId = weatherTag.getInteger("CurrentID");
+        dimensionData.weatherNextId = weatherTag.getInteger("NextID");
+        dimensionData.weatherDuration = weatherTag.getLong("Duration");
+        dimensionData.weatherIntensity = weatherTag.getFloat("Intensity");
+        dimensionData.weatherPower = weatherTag.getFloat("Power");
+
+        return dimensionData;
     }
 
-    public DimensionData(DimensionData dimensionData)
-    {
-        worldType = dimensionData.worldType;
-        weatherCurrentId = dimensionData.weatherCurrentId;
-        weatherNextId = dimensionData.weatherNextId;
-        weatherDuration = dimensionData.weatherDuration;
-        weatherIntensity = dimensionData.weatherIntensity;
-        weatherPower = dimensionData.weatherPower;
+    public static @NotNull CompoundTag toCompoundTag(final @NotNull DimensionData dimensionData, final @NotNull CompoundTag out) {
+        out.putString("WorldType", Objects.requireNonNull(Registries.WORLD_TYPES.getKey(dimensionData.worldType)));
+
+        final @NotNull CompoundTag weatherTag = new CompoundTag();
+        weatherTag.putInt("CurrentID", dimensionData.weatherCurrentId);
+        weatherTag.putInt("NextID", dimensionData.weatherNextId);
+        weatherTag.putLong("Duration", dimensionData.weatherDuration);
+        weatherTag.putFloat("Intensity", dimensionData.weatherIntensity);
+        weatherTag.putFloat("Power", dimensionData.weatherPower);
+
+        out.putCompound("Weather", weatherTag);
+
+        return out;
     }
 
-    public DimensionData(File worldDir, Dimension dimension)
-        throws IOException
-    {
-        CompoundTag nbtRootData = null;
-        File dimensionsDir = new File(worldDir, "dimensions");
-        File dimensionDir = new File(dimensionsDir, "" + dimension.id);
+    public static @NotNull DimensionData fromWorldDir(final @NotNull File worldDir, final @NotNull Dimension dimension) throws IOException {
+        @Nullable CompoundTag nbtRootData = null;
+        final @NotNull File dimensionsDir = new File(worldDir, "dimensions");
+        final @NotNull File dimensionDir = new File(dimensionsDir, "" + dimension.id);
 
-        if (!worldDir.exists() || !dimensionsDir.exists() || !dimensionDir.exists())
-        {
+        if (!worldDir.exists() || !dimensionsDir.exists() || !dimensionDir.exists()) {
             throw new IOException();
         }
-        File dimensionDat = new File(dimensionDir, "dimension.dat");
-        if (dimensionDat.exists())
-        {
-            CompoundTag nbtRoot = NbtIo.readCompressed((Files.newInputStream(dimensionDat.toPath())));
+        @NotNull File dimensionDat = new File(dimensionDir, "dimension.dat");
+        if (dimensionDat.exists()) {
+            final @NotNull CompoundTag nbtRoot = NbtIo.readCompressed((Files.newInputStream(dimensionDat.toPath())));
             nbtRootData = nbtRoot.getCompound("Data");
-        }
-        else
-        {
+        } else {
             dimensionDat = new File(dimensionDir, "dimension.dat_old");
-            if (dimensionDat.exists())
-            {
-                CompoundTag oldNbtRoot = NbtIo.readCompressed(Files.newInputStream(dimensionDat.toPath()));
+            if (dimensionDat.exists()) {
+                final @NotNull CompoundTag oldNbtRoot = NbtIo.readCompressed(Files.newInputStream(dimensionDat.toPath()));
                 nbtRootData = oldNbtRoot.getCompound("Data");
             }
         }
 
-        if (nbtRootData != null)
-        {
-            readFromNBTTag(nbtRootData);
-        }
-        else
-        {
+        if (nbtRootData != null) {
+            return DimensionData.fromCompoundTag(nbtRootData, dimension);
+        } else {
             throw new IOException();
         }
     }
 
-    public CompoundTag toNBTTag()
-    {
-        CompoundTag tag = new CompoundTag();
-        writeToNBTTag(tag);
-        return tag;
-    }
-
-    private void writeToNBTTag(CompoundTag dimTag)
-    {
-        dimTag.putString("WorldType", worldType);
-        CompoundTag weatherTag = new CompoundTag();
-        weatherTag.putInt("CurrentID", weatherCurrentId);
-        weatherTag.putInt("NextID", weatherNextId);
-        weatherTag.putLong("Duration", weatherDuration);
-        weatherTag.putFloat("Intensity", weatherIntensity);
-        weatherTag.putFloat("Power", weatherPower);
-        dimTag.putCompound("Weather", weatherTag);
-    }
-
-    private void readFromNBTTag(CompoundTag dimTag)
-    {
-        if (dimTag.getTag("WorldType") instanceof ByteTag)
-        {
-            // This is entirely to fix world types from worlds created during the prerelease period of 1.7.7.0, which used a byte ID the same as previous versions of BTA.
-            // This should be removed at some appropriate point in the future, such as 1.7.7.1.
-            WorldType legacyWorldType = LegacyWorldTypes.getWorldTypeById(dimTag.getByte("WorldType"));
-            if (legacyWorldType == null)
-            {
-                legacyWorldType = WorldTypes.OVERWORLD_EXTENDED;
-            }
+    private final @NotNull WorldType worldType;
+    private int weatherCurrentId = -1;
+    private int weatherNextId = -1;
+    private long weatherDuration;
+    private float weatherIntensity;
+    private float weatherPower;
 
-            worldType = Registries.WORLD_TYPES.getKey(legacyWorldType);
-        }
-        else
-        {
-            worldType = dimTag.getString("WorldType");
-        }
-        CompoundTag weatherTag = dimTag.getCompound("Weather");
-        weatherCurrentId = weatherTag.getInteger("CurrentID");
-        weatherNextId = weatherTag.getInteger("NextID");
-        weatherDuration = weatherTag.getLong("Duration");
-        weatherIntensity = weatherTag.getFloat("Intensity");
-        weatherPower = weatherTag.getFloat("Power");
+    public DimensionData(
+        final @NotNull WorldType worldType
+    ) {
+        this.worldType = worldType;
     }
 
-    public @NotNull WorldType getWorldType()
-    {
-        return Objects.requireNonNull(Registries.WORLD_TYPES.getItem(this.worldType));
+    public DimensionData(final @NotNull DimensionData dimensionData) {
+        this(dimensionData.worldType);
+
+        this.weatherCurrentId = dimensionData.weatherCurrentId;
+        this.weatherNextId = dimensionData.weatherNextId;
+        this.weatherDuration = dimensionData.weatherDuration;
+        this.weatherIntensity = dimensionData.weatherIntensity;
+        this.weatherPower = dimensionData.weatherPower;
     }
 
-    public void setWorldType(WorldType type)
-    {
-        this.worldType = Registries.WORLD_TYPES.getKey(type);
+    public @NotNull WorldType getWorldType() {
+        return this.worldType;
     }
 
-    public Weather getCurrentWeather()
-    {
-        if (weatherCurrentId < 0) {
+    public @Nullable Weather getCurrentWeather() {
+        if (this.weatherCurrentId < 0) {
             return null;
         }
-        return Weathers.getWeather(weatherCurrentId);
+        return Weathers.getWeather(this.weatherCurrentId);
     }
 
-    public void setCurrentWeather(@Nullable Weather weather)
-    {
+    public void setCurrentWeather(final @Nullable Weather weather) {
         if (weather == null) {
             this.weatherCurrentId = -1;
         } else {
@@ -156,51 +126,40 @@ public class DimensionData
         }
     }
 
-    public @Nullable Weather getNextWeather()
-    {
-        if (weatherNextId == -1) return null;
-        return Weathers.getWeather(weatherNextId);
+    public @Nullable Weather getNextWeather() {
+        if (this.weatherNextId == -1) return null;
+        return Weathers.getWeather(this.weatherNextId);
     }
 
-    public void setNextWeather(@Nullable Weather weather)
-    {
-        if (weather == null)
-        {
+    public void setNextWeather(final @Nullable Weather weather) {
+        if (weather == null) {
             this.weatherNextId = -1;
-        }
-        else
-        {
+        } else {
             this.weatherNextId = weather.getId();
         }
     }
 
-    public long getWeatherDuration()
-    {
-        return weatherDuration;
+    public long getWeatherDuration() {
+        return this.weatherDuration;
     }
 
-    public void setWeatherDuration(long duration)
-    {
+    public void setWeatherDuration(final long duration) {
         this.weatherDuration = duration;
     }
 
-    public float getWeatherIntensity()
-    {
-        return weatherIntensity;
+    public float getWeatherIntensity() {
+        return this.weatherIntensity;
     }
 
-    public void setWeatherIntensity(float intensity)
-    {
+    public void setWeatherIntensity(final float intensity) {
         this.weatherIntensity = intensity;
     }
 
-    public float getWeatherPower()
-    {
-        return weatherPower;
+    public float getWeatherPower() {
+        return this.weatherPower;
     }
 
-    public void setWeatherPower(float power)
-    {
+    public void setWeatherPower(final float power) {
         this.weatherPower = power;
     }
 }
diff --git a/game/core/src/main/java/net/minecraft/core/world/save/ISaveFormat.java b/game/core/src/main/java/net/minecraft/core/world/save/ISaveFormat.java
index 1ef4e0acc..2e34508b0 100644
--- a/game/core/src/main/java/net/minecraft/core/world/save/ISaveFormat.java
+++ b/game/core/src/main/java/net/minecraft/core/world/save/ISaveFormat.java
@@ -2,6 +2,7 @@ package net.minecraft.core.world.save;
 
 import com.mojang.nbt.tags.CompoundTag;
 import net.minecraft.core.world.Dimension;
+import org.jetbrains.annotations.NotNull;
 
 import java.io.File;
 import java.util.List;
@@ -59,18 +60,18 @@ public interface ISaveFormat
     /**
      * Fetches the dimension data for a given world.
      * @param worldDirName The name of the directory containing the world data.
-     * @param dimensionId The ID of the dimension to read.
+     * @param dimension The dimension to read.
      * @return The loaded dimension data for the requested dimension.
      */
-    DimensionData getDimensionData(String worldDirName, int dimensionId);
+    DimensionData getDimensionData(@NotNull String worldDirName, @NotNull Dimension dimension);
 
     /**
      * Fetches the dimension data for a given world as raw NBT.
      * @param worldDirName The name of the directory
-     * @param dimensionId The ID of the dimension to read.
+     * @param dimension The dimension to read.
      * @return The loaded dimension data for the requested dimension.
      */
-    CompoundTag getDimensionDataRaw(String worldDirName, int dimensionId);
+    CompoundTag getDimensionDataRaw(@NotNull String worldDirName, @NotNull Dimension dimension);
 
     /**
      * Deletes a given world.
diff --git a/game/core/src/main/java/net/minecraft/core/world/save/LevelData.java b/game/core/src/main/java/net/minecraft/core/world/save/LevelData.java
index 73b7bca1d..b33218d76 100644
--- a/game/core/src/main/java/net/minecraft/core/world/save/LevelData.java
+++ b/game/core/src/main/java/net/minecraft/core/world/save/LevelData.java
@@ -6,6 +6,7 @@ import net.minecraft.core.data.gamerule.GameRuleCollection;
 import com.mojang.nbt.tags.CompoundTag;
 import com.mojang.nbt.NbtIo;
 import net.minecraft.core.world.config.spawning.SpawnerConfig;
+import net.minecraft.core.world.pos.TilePos;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 import org.slf4j.Logger;
@@ -15,362 +16,279 @@ import java.io.IOException;
 import java.nio.file.Files;
 import java.util.UUID;
 
-public class LevelData
-{
-    private static final Logger LOGGER = LogUtils.getLogger();
-    private long randomSeed;
-    private int spawnX;
-    private int spawnY;
-    private int spawnZ;
-    private long worldTime;
-    private long lastTimePlayed;
-    private long sizeOnDisk;
-    @Deprecated
-    private CompoundTag playerTag;
-    @Deprecated
-    private int dimension;
-    @Deprecated
-    private int gamemode;
-    private @Nullable UUID lastPlayerUUID;
-    private @NotNull String levelName = "DEFAULT NAME";
-    private int saveVersion;
-    private boolean cheatsEnabled;
-    private @NotNull Difficulty difficulty = Difficulty.NORMAL;
-    private boolean difficultyLocked;
-    private GameRuleCollection gameRules;
-    private SpawnerConfig spawnerConfig;
-
+public class LevelData {
+    private static final @NotNull Logger LOGGER = LogUtils.getLogger();
 
-    public LevelData(CompoundTag tag)
-    {
-        readFromCompoundTag(tag);
-    }
+    public static @NotNull LevelData fromCompoundTag(final @NotNull CompoundTag tag) {
+        final long randomSeed = tag.getLong("RandomSeed");
+        final @NotNull String levelName = tag.getString("LevelName");
 
-    //do *not* add @NotNull to name here, breaks modding for some abstract reason
-    public LevelData(long seed, @NotNull String name)
-    {
-        randomSeed = seed;
-        levelName = name;
-        spawnerConfig = new SpawnerConfig();
-        gameRules = new GameRuleCollection();
-    }
-
-    public LevelData(long seed, @NotNull String name, GameRuleCollection gameRules)
-    {
-        randomSeed = seed;
-        levelName = name;
-        spawnerConfig = new SpawnerConfig();
-        this.gameRules = gameRules;
-    }
-
-    public LevelData(LevelData levelData)
-    {
-        randomSeed = levelData.randomSeed;
-        spawnX = levelData.spawnX;
-        spawnY = levelData.spawnY;
-        spawnZ = levelData.spawnZ;
-        worldTime = levelData.worldTime;
-        lastTimePlayed = levelData.lastTimePlayed;
-        sizeOnDisk = levelData.sizeOnDisk;
-        playerTag = levelData.playerTag;
-        dimension = levelData.dimension;
-        levelName = levelData.levelName;
-        saveVersion = levelData.saveVersion;
-        cheatsEnabled = levelData.cheatsEnabled;
-        gamemode = levelData.gamemode;
-        gameRules = levelData.gameRules;
-        spawnerConfig = levelData.getSpawnerConfig();
-        difficulty = levelData.difficulty;
-        difficultyLocked = levelData.difficultyLocked;
-        lastPlayerUUID = levelData.lastPlayerUUID;
-    }
-
-    public LevelData(File worldDir)
-            throws IOException
-    {
-        CompoundTag nbtRootData = null;
-
-        if(!worldDir.exists())
-        {
-            throw new IOException();
-        }
-        File worldLevelDat = new File(worldDir, "level.dat");
-        if(worldLevelDat.exists())
-        {
-            CompoundTag nbtRoot = NbtIo.readCompressed(Files.newInputStream(worldLevelDat.toPath()));
-            nbtRootData = nbtRoot.getCompound("Data");
-        }
-        else
-        {
-            worldLevelDat = new File(worldDir, "level.dat_old");
-            if(worldLevelDat.exists())
-            {
-                CompoundTag oldNbtRoot = NbtIo.readCompressed(Files.newInputStream(worldLevelDat.toPath()));
-                nbtRootData = oldNbtRoot.getCompound("Data");
-            }
-        }
-
-        if (nbtRootData != null)
-        {
-            readFromCompoundTag(nbtRootData);
-        }
-        else
-        {
-            throw new IOException();
-        }
-
-        if (gameRules == null)
-        {
+        final @NotNull GameRuleCollection gameRules;
+        if (tag.containsKey("GameRules")) {
+            final CompoundTag gameRulesTag = tag.getCompound("GameRules");
+            gameRules = GameRuleCollection.readFromNBT(gameRulesTag);
+        } else {
             gameRules = new GameRuleCollection();
         }
 
-        if (spawnerConfig == null) {
+        final @NotNull SpawnerConfig spawnerConfig;
+        if (tag.containsKey("SpawnConfig")) {
+            final CompoundTag spawnConfigTag = tag.getCompound("SpawnConfig");
+            spawnerConfig = SpawnerConfig.createFromTag(spawnConfigTag);
+        } else {
             spawnerConfig = new SpawnerConfig();
         }
-    }
-
-    public CompoundTag getNBTTagCompound()
-    {
-        CompoundTag tag = new CompoundTag();
-        updateTagCompound(tag);
-        return tag;
-    }
-
-    private void updateTagCompound(CompoundTag levelTag)
-    {
-        levelTag.putLong("RandomSeed", randomSeed);
-        levelTag.putInt("SpawnX", spawnX);
-        levelTag.putInt("SpawnY", spawnY);
-        levelTag.putInt("SpawnZ", spawnZ);
-        levelTag.putLong("Time", worldTime);
-        levelTag.putLong("SizeOnDisk", sizeOnDisk);
-        levelTag.putLong("LastPlayed", System.currentTimeMillis());
-        levelTag.putString("LevelName", levelName);
-        levelTag.putInt("version", saveVersion);
-        levelTag.putBoolean("CheatsEnabled", cheatsEnabled);
-        levelTag.putInt("Difficulty", difficulty.id());
-        levelTag.putBoolean("DifficultyLock", difficultyLocked);
-
-        CompoundTag gameRulesTag = new CompoundTag();
-        GameRuleCollection.writeToNBT(gameRulesTag, gameRules);
-        levelTag.put("GameRules", gameRulesTag);
-
-        if (lastPlayerUUID != null) {
-            levelTag.putString("LastPlayerUUID", lastPlayerUUID.toString());
-        }
 
-        if (spawnerConfig != null) {
-            CompoundTag spawnerConfigTag = new CompoundTag();
-            spawnerConfig.writeToTag(spawnerConfigTag);
-            levelTag.put("SpawnConfig", spawnerConfigTag);
+        final @NotNull LevelData data = new LevelData(
+            randomSeed,
+            levelName,
+            gameRules,
+            spawnerConfig
+        );
+
+        data.spawnPos.set(
+            tag.getInteger("SpawnX"),
+            tag.getInteger("SpawnY"),
+            tag.getInteger("SpawnZ")
+        );
+        data.worldTime = tag.getLong("Time");
+        data.lastTimePlayed = tag.getLong("LastPlayed");
+        data.sizeOnDisk = tag.getLong("SizeOnDisk");
+        data.saveVersion = tag.getInteger("version");
+        data.cheatsEnabled = tag.getBoolean("CheatsEnabled");
+        data.setDifficulty(tag.getIntegerOrDefault("Difficulty", Difficulty.NORMAL.id()), true);
+        data.difficultyLocked = tag.getBooleanOrDefault("DifficultyLock", false);
+
+        if (tag.containsKey("Player")) {
+            data.playerTag = tag.getCompound("Player");
         }
-    }
 
-    private void readFromCompoundTag(CompoundTag tag)
-    {
-        randomSeed = tag.getLong("RandomSeed");
-        spawnX = tag.getInteger("SpawnX");
-        spawnY = tag.getInteger("SpawnY");
-        spawnZ = tag.getInteger("SpawnZ");
-        worldTime = tag.getLong("Time");
-        lastTimePlayed = tag.getLong("LastPlayed");
-        sizeOnDisk = tag.getLong("SizeOnDisk");
-        levelName = tag.getString("LevelName");
-        saveVersion = tag.getInteger("version");
-        cheatsEnabled = tag.getBoolean("CheatsEnabled");
-        setDifficulty(tag.getIntegerOrDefault("Difficulty", Difficulty.NORMAL.id()), true);
-        difficultyLocked = tag.getBooleanOrDefault("DifficultyLock", false);
-        if (tag.containsKey("Player"))
-        {
-            playerTag = tag.getCompound("Player");
-            dimension = playerTag.getInteger("Dimension");
-            gamemode = playerTag.getInteger("Gamemode");
-        }
-        if (tag.containsKey("GameRules"))
-        {
-            CompoundTag gameRulesTag = tag.getCompound("GameRules");
-            gameRules = GameRuleCollection.readFromNBT(gameRulesTag);
-        }
-        else
-        {
-            gameRules = new GameRuleCollection();
-        }
         if (tag.containsKey("LastPlayerUUID")) {
-            lastPlayerUUID = UUID.fromString(tag.getString("LastPlayerUUID"));
+            data.lastPlayerUUID = UUID.fromString(tag.getString("LastPlayerUUID"));
         }
 
-        if (tag.containsKey("SpawnConfig")) {
-            CompoundTag spawnConfigTag = tag.getCompound("SpawnConfig");
-            spawnerConfig = SpawnerConfig.createFromTag(spawnConfigTag);
-        } else {
-            spawnerConfig = new SpawnerConfig();
+        return data;
+    }
+
+    public static @NotNull CompoundTag toCompoundTag(final @NotNull LevelData levelData, final @NotNull CompoundTag out) {
+        out.putLong("RandomSeed", levelData.randomSeed);
+        out.putInt("SpawnX", levelData.spawnPos.x);
+        out.putInt("SpawnY", levelData.spawnPos.y);
+        out.putInt("SpawnZ", levelData.spawnPos.z);
+        out.putLong("Time", levelData.worldTime);
+        out.putLong("SizeOnDisk", levelData.sizeOnDisk);
+        out.putLong("LastPlayed", System.currentTimeMillis());
+        out.putString("LevelName", levelData.levelName);
+        out.putInt("version", levelData.saveVersion);
+        out.putBoolean("CheatsEnabled", levelData.cheatsEnabled);
+        out.putInt("Difficulty", levelData.difficulty.id());
+        out.putBoolean("DifficultyLock", levelData.difficultyLocked);
+
+        final CompoundTag gameRulesTag = new CompoundTag();
+        GameRuleCollection.writeToNBT(gameRulesTag, levelData.gameRules);
+        out.put("GameRules", gameRulesTag);
+
+        if (levelData.lastPlayerUUID != null) {
+            out.putString("LastPlayerUUID", levelData.lastPlayerUUID.toString());
         }
-    }
 
-    public long getRandomSeed()
-    {
-        return randomSeed;
-    }
+        final CompoundTag spawnerConfigTag = new CompoundTag();
+        levelData.spawnerConfig.writeToTag(spawnerConfigTag);
+        out.put("SpawnConfig", spawnerConfigTag);
 
-    public int getSpawnX()
-    {
-        return spawnX;
+        return out;
     }
 
-    public int getSpawnY()
-    {
-        return spawnY;
-    }
+    public static @NotNull LevelData fromWorldDir(final @NotNull File worldDir) throws IOException {
+        @Nullable CompoundTag nbtRootData = null;
 
-    public int getSpawnZ()
-    {
-        return spawnZ;
-    }
+        if (!worldDir.exists()) {
+            throw new IOException();
+        }
+        @NotNull File worldLevelDat = new File(worldDir, "level.dat");
+        if (worldLevelDat.exists()) {
+            final @NotNull CompoundTag nbtRoot = NbtIo.readCompressed(Files.newInputStream(worldLevelDat.toPath()));
+            nbtRootData = nbtRoot.getCompound("Data");
+        } else {
+            worldLevelDat = new File(worldDir, "level.dat_old");
+            if (worldLevelDat.exists()) {
+                final @NotNull CompoundTag oldNbtRoot = NbtIo.readCompressed(Files.newInputStream(worldLevelDat.toPath()));
+                nbtRootData = oldNbtRoot.getCompound("Data");
+            }
+        }
 
-    public long getWorldTime()
-    {
-        return worldTime;
+        if (nbtRootData != null) {
+            return LevelData.fromCompoundTag(nbtRootData);
+        } else {
+            throw new IOException();
+        }
     }
 
-    public long getSizeOnDisk()
-    {
-        return sizeOnDisk;
-    }
+    private final long randomSeed;
+    private final @NotNull String levelName;
+    private final @NotNull TilePos spawnPos = new TilePos();
+    private final @NotNull GameRuleCollection gameRules;
+    private final @NotNull SpawnerConfig spawnerConfig;
 
-    @Deprecated
-    public CompoundTag getPlayerNBTTagCompound()
-    {
-        return playerTag;
-    }
+    private long worldTime;
+    private long lastTimePlayed;
+    private long sizeOnDisk;
+    private @Nullable UUID lastPlayerUUID;
+    private int saveVersion;
+    private boolean cheatsEnabled;
+    private @NotNull Difficulty difficulty = Difficulty.NORMAL;
+    private boolean difficultyLocked;
 
     @Deprecated
-    public int getDimension()
-    {
-        return dimension;
-    }
-
-    public @Nullable UUID getLastPlayerUUID() {
-        return lastPlayerUUID;
-    }
-
-    public void setSpawnX(int x)
-    {
-        spawnX = x;
+    private @Nullable CompoundTag playerTag;
+
+    private LevelData(
+        final long randomSeed,
+        final @NotNull String levelName,
+        final @NotNull GameRuleCollection gameRules,
+        final @NotNull SpawnerConfig spawnerConfig
+    ) {
+        this.randomSeed = randomSeed;
+        this.levelName = levelName;
+        this.gameRules = gameRules;
+        this.spawnerConfig = spawnerConfig;
+    }
+
+    public LevelData(
+        final long randomSeed,
+        final @NotNull String name
+    ) {
+        this(
+            randomSeed,
+            name,
+            new GameRuleCollection(),
+            new SpawnerConfig()
+        );
+    }
+
+    public LevelData(
+        final long randomSeed,
+        final @NotNull String name,
+        final @NotNull GameRuleCollection gameRules
+    ) {
+        this(
+            randomSeed,
+            name,
+            gameRules,
+            new SpawnerConfig()
+        );
+    }
+
+    public LevelData(final @NotNull LevelData levelData) {
+        this(levelData.randomSeed, levelData.levelName, levelData.gameRules, levelData.spawnerConfig);
+
+        this.spawnPos.set(levelData.spawnPos);
+        this.worldTime = levelData.worldTime;
+        this.lastTimePlayed = levelData.lastTimePlayed;
+        this.sizeOnDisk = levelData.sizeOnDisk;
+        this.playerTag = levelData.playerTag;
+        this.saveVersion = levelData.saveVersion;
+        this.cheatsEnabled = levelData.cheatsEnabled;
+        this.difficulty = levelData.difficulty;
+        this.difficultyLocked = levelData.difficultyLocked;
+        this.lastPlayerUUID = levelData.lastPlayerUUID;
     }
 
-    public void setSpawnY(int y)
-    {
-        spawnY = y;
+    @Deprecated
+    public @Nullable CompoundTag getPlayerTag() {
+        return this.playerTag;
     }
 
-    public void setSpawnZ(int z)
-    {
-        spawnZ = z;
+    public long getRandomSeed() {
+        return this.randomSeed;
     }
 
-    public void setWorldTime(long time)
-    {
-        worldTime = time;
+    public @NotNull TilePos getSpawnPos() {
+        return this.spawnPos;
     }
 
-    public void setSizeOnDisk(long size)
-    {
-        sizeOnDisk = size;
+    public long getWorldTime() {
+        return this.worldTime;
     }
 
-    @Deprecated
-    public void setPlayerNBTTagCompound(CompoundTag tag)
-    {
-        playerTag = tag;
+    public void setWorldTime(final long time) {
+        this.worldTime = time;
     }
 
-    public void setLastPlayerUUID(@Nullable UUID lastPlayerUUID) {
-        this.lastPlayerUUID = lastPlayerUUID;
+    public long getSizeOnDisk() {
+        return this.sizeOnDisk;
     }
 
-    public void setSpawn(int x, int y, int z)
-    {
-        spawnX = x;
-        spawnY = y;
-        spawnZ = z;
+    public void setSizeOnDisk(final long size) {
+        this.sizeOnDisk = size;
     }
 
-    public String getWorldName()
-    {
-        return levelName;
+    public @NotNull GameRuleCollection getGameRules() {
+        return this.gameRules;
     }
 
-    public void setWorldName(String s)
-    {
-        levelName = s;
+    public @NotNull SpawnerConfig getSpawnerConfig() {
+        return this.spawnerConfig;
     }
 
-    public int getSaveVersion()
-    {
-        return saveVersion;
+    public @Nullable UUID getLastPlayerUUID() {
+        return this.lastPlayerUUID;
     }
 
-    public void setSaveVersion(int i)
-    {
-        saveVersion = i;
+    public void setLastPlayerUUID(final @Nullable UUID lastPlayerUUID) {
+        this.lastPlayerUUID = lastPlayerUUID;
     }
 
-    public long getLastTimePlayed()
-    {
-        return lastTimePlayed;
+    public @NotNull String getWorldName() {
+        return this.levelName;
     }
 
-    @Deprecated
-    public int getGamemode()
-    {
-    	return gamemode;
+    public int getSaveVersion() {
+        return this.saveVersion;
     }
 
-    @Deprecated
-    public void setGamemode(int gamemode)
-    {
-    	this.gamemode = gamemode;
+    public void setSaveVersion(final int i) {
+        this.saveVersion = i;
     }
 
-    public GameRuleCollection getGameRules()
-    {
-        return gameRules;
+    public long getLastTimePlayed() {
+        return this.lastTimePlayed;
     }
 
-    public SpawnerConfig getSpawnerConfig() {
-        return spawnerConfig;
+    public boolean getCheatsEnabled() {
+        return this.cheatsEnabled;
     }
 
-    public boolean getCheatsEnabled()
-    {
-    	return cheatsEnabled;
+    public void setCheatsEnabled(final boolean enabled) {
+        this.cheatsEnabled = enabled;
     }
 
-    public void setCheatsEnabled(boolean enabled)
-    {
-    	this.cheatsEnabled = enabled;
-    }
+    public void setDifficulty(final @NotNull Difficulty difficulty, final boolean overrideLock) {
+        if (!overrideLock && this.difficultyLocked) {
+            return;
+        }
 
-    public void setDifficulty(Difficulty difficulty, boolean overrideLock) {
-        if (!overrideLock && difficultyLocked) return;
         this.difficulty = difficulty;
     }
 
-    public void setDifficulty(int difficulty, boolean overrideLock) {
-        if (!overrideLock && difficultyLocked) return;
+    public void setDifficulty(int difficulty, final boolean overrideLock) {
+        if (!overrideLock && this.difficultyLocked) {
+            return;
+        }
+
         if (difficulty < 0) {
-            LOGGER.warn("Attempted to set difficulty to '{}' which is less then 0!", difficulty);
+            LOGGER.warn("Attempted to set difficulty to '{}' which is less than 0!", difficulty);
             difficulty = 0;
         }
         if (difficulty >= Difficulty.values().length) {
-            LOGGER.error("Attempted to set difficulty to '{}' which is more then the '{}' difficulties!", difficulty, Difficulty.values().length);
+            LOGGER.error("Attempted to set difficulty to '{}' which is more than the '{}' difficulties!", difficulty, Difficulty.values().length);
             difficulty = Difficulty.values().length - 1;
         }
-        setDifficulty(Difficulty.values()[difficulty], overrideLock);
+        this.setDifficulty(Difficulty.values()[difficulty], overrideLock);
     }
 
-    public Difficulty getDifficulty() {
-        return difficulty;
+    public @NotNull Difficulty getDifficulty() {
+        return this.difficulty;
     }
 
     public void setDifficultyLocked() {
@@ -378,6 +296,6 @@ public class LevelData
     }
 
     public boolean getDifficultyLocked() {
-        return difficultyLocked;
+        return this.difficultyLocked;
     }
 }
diff --git a/game/core/src/main/java/net/minecraft/core/world/save/LevelStorage.java b/game/core/src/main/java/net/minecraft/core/world/save/LevelStorage.java
index a74037d40..3b03fcd78 100644
--- a/game/core/src/main/java/net/minecraft/core/world/save/LevelStorage.java
+++ b/game/core/src/main/java/net/minecraft/core/world/save/LevelStorage.java
@@ -2,8 +2,10 @@ package net.minecraft.core.world.save;
 
 import com.mojang.nbt.tags.CompoundTag;
 import net.minecraft.core.entity.player.Player;
-import net.minecraft.core.world.chunk.IChunkLoader;
+import net.minecraft.core.world.chunk.ChunkLoader;
 import net.minecraft.core.world.Dimension;
+import net.minecraft.core.world.saveddata.SavedData;
+import net.minecraft.core.world.saveddata.SavedDataStorage;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 
@@ -11,19 +13,18 @@ import java.io.File;
 import java.util.List;
 import java.util.UUID;
 
-public interface LevelStorage extends PlayerIO
-{
+public interface LevelStorage extends PlayerIO {
 	/**
 	 * Loads the level data for this save.
 	 * @return The loaded level data for this save.
 	 */
-	LevelData getLevelData();
+	@Nullable LevelData getLevelData();
 
 	/**
 	 * Loads the level data for this save in raw NBT format.
 	 * @return The loaded level data for this save.
 	 */
-	CompoundTag getLevelDataRaw();
+	@Nullable CompoundTag getLevelDataRaw();
 
 	/**
 	 * Ensures the save file lock from this session is still valid.
@@ -35,7 +36,7 @@ public interface LevelStorage extends PlayerIO
 	 * @param dimension The dimension to obtain the chunk loader for.
 	 * @return The instantiated chunk loader for the given dimension.
 	 */
-	IChunkLoader getChunkLoader(Dimension dimension);
+	@Nullable ChunkLoader getChunkLoader(@NotNull Dimension dimension);
 
 	/**
 	 * Saves the level data and data for any players.
@@ -43,53 +44,53 @@ public interface LevelStorage extends PlayerIO
 	 * @param levelData The level data to save.
 	 * @param playerList A list of players whose data should be saved.
 	 */
-	void saveLevelDataAndPlayerData(@NotNull LevelData levelData, @NotNull List<Player> playerList);
+	void saveLevelDataAndPlayerData(@NotNull LevelData levelData, @NotNull List<@NotNull Player> playerList);
 
 	/**
 	 * Saves the level data.
 	 * @param levelData The level data to save.
 	 */
-	void saveLevelData(LevelData levelData);
+	void saveLevelData(@NotNull LevelData levelData);
 
 	/**
 	 * Saves the level data using raw NBT.
 	 * @param levelDataTag The level data to save.
 	 */
-	void saveLevelDataRaw(CompoundTag levelDataTag);
+	void saveLevelDataRaw(@NotNull CompoundTag levelDataTag);
 
 	/**
 	 * Loads the dimension data for a given dimension.
-	 * @param dimensionId The ID of the dimension to read the data of.
+	 * @param dimension The dimension whose data should be read.
 	 * @return The dimension data.
 	 */
-	DimensionData getDimensionData(int dimensionId);
+	@Nullable DimensionData getDimensionData(@NotNull Dimension dimension);
 
 	/**
 	 * Loads the dimension data for a given dimension as raw NBT.
-	 * @param dimensionId The ID of the dimension to read the data of.
+	 * @param dimension The dimension whose data should be read.
 	 * @return The raw dimension data.
 	 */
-	CompoundTag getDimensionDataRaw(int dimensionId);
+	@Nullable CompoundTag getDimensionDataRaw(@NotNull Dimension dimension);
 
 	/**
 	 * Saves the dimension data for a given dimension.
 	 * @param dimensionId The ID of the dimension to save.
 	 * @param dimensionData The dimension data to save.
 	 */
-	void saveDimensionData(int dimensionId, DimensionData dimensionData);
+	void saveDimensionData(int dimensionId, @NotNull DimensionData dimensionData);
 
 	/**
 	 * Saves the dimension data for a given dimension as raw NBT.
 	 * @param dimensionId The ID of the dimension to save.
 	 * @param dimensionDataTag The dimension data to save.
 	 */
-	void saveDimensionDataRaw(int dimensionId, CompoundTag dimensionDataTag);
+	void saveDimensionDataRaw(int dimensionId, @NotNull CompoundTag dimensionDataTag);
 
 	@Nullable PlayerIO getPlayerFileData();
 
 	@Nullable CompoundTag getPlayerData(@Nullable String username, @NotNull UUID uuid);
 
-	File getDataFile(String fileName);
-
+	@Nullable File getDataFile(@NotNull String fileName);
 
+	@NotNull SavedDataStorage getSavedDataStorage();
 }
diff --git a/game/core/src/main/java/net/minecraft/core/world/save/LevelStorageBase.java b/game/core/src/main/java/net/minecraft/core/world/save/LevelStorageBase.java
index c0153e7ce..672b374c2 100644
--- a/game/core/src/main/java/net/minecraft/core/world/save/LevelStorageBase.java
+++ b/game/core/src/main/java/net/minecraft/core/world/save/LevelStorageBase.java
@@ -7,7 +7,8 @@ import com.mojang.nbt.NbtIo;
 import net.minecraft.core.entity.player.Player;
 import net.minecraft.core.world.Dimension;
 import net.minecraft.core.world.chunk.ChunkLoaderLegacy;
-import net.minecraft.core.world.chunk.IChunkLoader;
+import net.minecraft.core.world.chunk.ChunkLoader;
+import net.minecraft.core.world.saveddata.SavedDataStorage;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 import org.slf4j.Logger;
@@ -30,6 +31,7 @@ public abstract class LevelStorageBase implements LevelStorage
 	protected final File dataDirectory;
 	protected final long now = System.currentTimeMillis();
 	protected final ISaveFormat saveFormat;
+	private final @NotNull SavedDataStorage savedDataStorage;
 
 	public LevelStorageBase(ISaveFormat saveFormat, File savesDir, String worldDirName)
 	{
@@ -42,6 +44,8 @@ public abstract class LevelStorageBase implements LevelStorage
 		dataDirectory.mkdirs();
 		playersDirectory.mkdirs();
 		lockSession();
+
+		this.savedDataStorage = new SavedDataStorage(this);
 	}
 
 	private void lockSession()
@@ -84,7 +88,7 @@ public abstract class LevelStorageBase implements LevelStorage
 	}
 
 	@Override
-	public IChunkLoader getChunkLoader(Dimension dimension)
+	public @Nullable ChunkLoader getChunkLoader(@NotNull Dimension dimension)
 	{
 		File dimDir = saveFormat.getDimensionRootDir(worldDirName, dimension);
 		dimDir.mkdirs();
@@ -93,33 +97,33 @@ public abstract class LevelStorageBase implements LevelStorage
 	}
 
 	@Override
-	public LevelData getLevelData()
+	public @Nullable LevelData getLevelData()
 	{
 		return saveFormat.getLevelData(worldDirName);
 	}
 
 	@Override
-	public CompoundTag getLevelDataRaw()
+	public @Nullable CompoundTag getLevelDataRaw()
 	{
 		return saveFormat.getLevelDataRaw(worldDirName);
 	}
 
 	@Override
-	public DimensionData getDimensionData(int dimensionId)
+	public @Nullable DimensionData getDimensionData(@NotNull Dimension dimension)
 	{
-		return saveFormat.getDimensionData(worldDirName, dimensionId);
+		return saveFormat.getDimensionData(worldDirName, dimension);
 	}
 
 	@Override
-	public CompoundTag getDimensionDataRaw(int dimensionId)
+	public @Nullable CompoundTag getDimensionDataRaw(@NotNull Dimension dimension)
 	{
-		return saveFormat.getDimensionDataRaw(worldDirName, dimensionId);
+		return saveFormat.getDimensionDataRaw(worldDirName, dimension);
 	}
 
 	@Override
 	public void saveLevelDataAndPlayerData(@NotNull LevelData levelData, @NotNull List<Player> playerList)
 	{
-		CompoundTag dataTag = levelData.getNBTTagCompound();
+		CompoundTag dataTag = LevelData.toCompoundTag(levelData, new CompoundTag());
 		CompoundTag savedTag = new CompoundTag();
 		savedTag.put("Data", dataTag);
 		try
@@ -155,16 +159,18 @@ public abstract class LevelStorageBase implements LevelStorage
 				LOGGER.error("Failed to save player data for player '{}'!", player.username, e);
 			}
 		}
+
+		this.savedDataStorage.save();
 	}
 
 	@Override
-	public void saveLevelData(LevelData levelData)
+	public void saveLevelData(@NotNull LevelData levelData)
 	{
-		saveLevelDataRaw(levelData.getNBTTagCompound());
+		saveLevelDataRaw(LevelData.toCompoundTag(levelData, new CompoundTag()));
 	}
 
 	@Override
-	public void saveLevelDataRaw(CompoundTag levelDataTag)
+	public void saveLevelDataRaw(@NotNull CompoundTag levelDataTag)
 	{
 		CompoundTag rootTag = new CompoundTag();
 		rootTag.put("Data", levelDataTag);
@@ -198,13 +204,13 @@ public abstract class LevelStorageBase implements LevelStorage
 	}
 
 	@Override
-	public void saveDimensionData(int dimensionId, DimensionData dimensionData)
+	public void saveDimensionData(int dimensionId, @NotNull DimensionData dimensionData)
 	{
-		saveDimensionDataRaw(dimensionId, dimensionData.toNBTTag());
+		saveDimensionDataRaw(dimensionId, DimensionData.toCompoundTag(dimensionData, new CompoundTag()));
 	}
 
 	@Override
-	public void saveDimensionDataRaw(int dimensionId, CompoundTag dimensionDataTag)
+	public void saveDimensionDataRaw(int dimensionId, @NotNull CompoundTag dimensionDataTag)
 	{
 		CompoundTag rootTag = new CompoundTag();
 		rootTag.put("Data", dimensionDataTag);
@@ -241,7 +247,7 @@ public abstract class LevelStorageBase implements LevelStorage
 	}
 
 	@Override
-	public File getDataFile(String fileName)
+	public File getDataFile(@NotNull String fileName)
 	{
 		return new File(dataDirectory, fileName + ".dat");
 	}
@@ -278,9 +284,9 @@ public abstract class LevelStorageBase implements LevelStorage
 			player.load(tag);
 			return;
 		}
-		LevelData data;
-		if ((data = getLevelData()) != null){
-			tag = data.getPlayerNBTTagCompound();
+		LevelData data = getLevelData();
+		if (data != null){
+			tag = data.getPlayerTag();
 			if (tag != null) {
 				player.load(tag);
 			}
@@ -293,6 +299,11 @@ public abstract class LevelStorageBase implements LevelStorage
 		return this;
 	}
 
+	@Override
+	public @NotNull SavedDataStorage getSavedDataStorage() {
+		return this.savedDataStorage;
+	}
+
 	public @Nullable CompoundTag getPlayerData(@Nullable String username, @NotNull UUID uuid)
 	{
 		try
diff --git a/game/core/src/main/java/net/minecraft/core/world/save/LevelStorageCore.java b/game/core/src/main/java/net/minecraft/core/world/save/LevelStorageCore.java
index ea71bcfee..9380aa7ff 100644
--- a/game/core/src/main/java/net/minecraft/core/world/save/LevelStorageCore.java
+++ b/game/core/src/main/java/net/minecraft/core/world/save/LevelStorageCore.java
@@ -3,8 +3,9 @@ package net.minecraft.core.world.save;
 import net.minecraft.core.entity.player.Player;
 import net.minecraft.core.world.Dimension;
 import net.minecraft.core.world.chunk.ChunkLoaderRegionAsync;
-import net.minecraft.core.world.chunk.IChunkLoader;
+import net.minecraft.core.world.chunk.ChunkLoader;
 import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
 
 import java.io.File;
 import java.util.List;
@@ -19,7 +20,7 @@ public class LevelStorageCore
     }
     
     @Override
-    public IChunkLoader getChunkLoader(Dimension dimension)
+    public @Nullable ChunkLoader getChunkLoader(@NotNull Dimension dimension)
     {
         File dimDir = saveFormat.getDimensionRootDir(worldDirName, dimension);
         dimDir.mkdirs();
diff --git a/game/core/src/main/java/net/minecraft/core/world/save/LevelStorageDummy.java b/game/core/src/main/java/net/minecraft/core/world/save/LevelStorageDummy.java
index 0f667e959..5085c760a 100644
--- a/game/core/src/main/java/net/minecraft/core/world/save/LevelStorageDummy.java
+++ b/game/core/src/main/java/net/minecraft/core/world/save/LevelStorageDummy.java
@@ -2,12 +2,9 @@ package net.minecraft.core.world.save;
 
 import com.mojang.nbt.tags.CompoundTag;
 import net.minecraft.core.entity.player.Player;
-import net.minecraft.core.world.chunk.IChunkLoader;
+import net.minecraft.core.world.chunk.ChunkLoader;
 import net.minecraft.core.world.Dimension;
-import net.minecraft.core.world.save.DimensionData;
-import net.minecraft.core.world.save.LevelData;
-import net.minecraft.core.world.save.LevelStorage;
-import net.minecraft.core.world.save.PlayerIO;
+import net.minecraft.core.world.saveddata.SavedDataStorage;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 
@@ -17,31 +14,33 @@ import java.util.UUID;
 
 public class LevelStorageDummy implements LevelStorage
 {
+	private final @NotNull SavedDataStorage savedDataStorage;
+
 	public LevelStorageDummy()
 	{
-		
+		this.savedDataStorage = new SavedDataStorage(this);
 	}
 
 	@Override
-    public LevelData getLevelData()
+    public @Nullable LevelData getLevelData()
 	{
 		return null;
 	}
 
 	@Override
-	public CompoundTag getLevelDataRaw()
+	public @Nullable CompoundTag getLevelDataRaw()
 	{
 		return null;
 	}
 
 	@Override
-	public DimensionData getDimensionData(int dimensionId)
+	public @Nullable DimensionData getDimensionData(final @NotNull Dimension dimension)
 	{
 		return null;
 	}
 
 	@Override
-	public CompoundTag getDimensionDataRaw(int dimensionId)
+	public @Nullable CompoundTag getDimensionDataRaw(final @NotNull Dimension dimension)
 	{
 		return null;
 	}
@@ -53,7 +52,7 @@ public class LevelStorageDummy implements LevelStorage
 	}
 
 	@Override
-	public IChunkLoader getChunkLoader(Dimension dimension)
+	public @Nullable ChunkLoader getChunkLoader(@NotNull Dimension dimension)
 	{
 		return null;
 	}
@@ -65,31 +64,31 @@ public class LevelStorageDummy implements LevelStorage
 	}
 
 	@Override
-	public void saveLevelData(LevelData levelData)
+	public void saveLevelData(@NotNull LevelData levelData)
 	{
 		
 	}
 
 	@Override
-	public void saveLevelDataRaw(CompoundTag levelDataTag)
+	public void saveLevelDataRaw(@NotNull CompoundTag levelDataTag)
 	{
 
 	}
 
 	@Override
-	public void saveDimensionData(int dimensionId, DimensionData dimensionData)
+	public void saveDimensionData(int dimensionId, @NotNull DimensionData dimensionData)
 	{
 
 	}
 
 	@Override
-	public void saveDimensionDataRaw(int dimensionId, CompoundTag dimensionDataTag)
+	public void saveDimensionDataRaw(int dimensionId, @NotNull CompoundTag dimensionDataTag)
 	{
 
 	}
 
 	@Override
-	public File getDataFile(String fileName)
+	public File getDataFile(@NotNull String fileName)
 	{
 		return null;
 	}
@@ -114,4 +113,9 @@ public class LevelStorageDummy implements LevelStorage
 	public void load(@NotNull Player player) {
 
 	}
+
+	@Override
+	public @NotNull SavedDataStorage getSavedDataStorage() {
+		return this.savedDataStorage;
+	}
 }
diff --git a/game/core/src/main/java/net/minecraft/core/world/save/LevelStorageServer.java b/game/core/src/main/java/net/minecraft/core/world/save/LevelStorageServer.java
index c57d949e8..682bcd474 100644
--- a/game/core/src/main/java/net/minecraft/core/world/save/LevelStorageServer.java
+++ b/game/core/src/main/java/net/minecraft/core/world/save/LevelStorageServer.java
@@ -3,10 +3,11 @@ package net.minecraft.core.world.save;
 import com.mojang.logging.LogUtils;
 import net.minecraft.core.entity.player.Player;
 import com.mojang.nbt.tags.CompoundTag;
-import net.minecraft.core.world.chunk.IChunkLoader;
+import net.minecraft.core.world.chunk.ChunkLoader;
 import net.minecraft.core.world.Dimension;
 import net.minecraft.core.world.chunk.ChunkLoaderRegion;
 import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
 import org.slf4j.Logger;
 
 
@@ -26,7 +27,7 @@ public class LevelStorageServer
     }
     
     @Override
-    public IChunkLoader getChunkLoader(Dimension dimension)
+    public @Nullable ChunkLoader getChunkLoader(@NotNull Dimension dimension)
     {
         File dimDir = saveFormat.getDimensionRootDir(worldDirName, dimension);
         dimDir.mkdirs();
diff --git a/game/core/src/main/java/net/minecraft/core/world/save/SaveFormatBase.java b/game/core/src/main/java/net/minecraft/core/world/save/SaveFormatBase.java
index f6915c744..3f8a8fadc 100644
--- a/game/core/src/main/java/net/minecraft/core/world/save/SaveFormatBase.java
+++ b/game/core/src/main/java/net/minecraft/core/world/save/SaveFormatBase.java
@@ -38,7 +38,7 @@ public abstract class SaveFormatBase
     {
         CompoundTag tag = getLevelDataRaw(worldDirName);
         if (tag == null) return null;
-        return new LevelData(tag);
+        return LevelData.fromCompoundTag(tag);
     }
 
     @Override
@@ -81,15 +81,15 @@ public abstract class SaveFormatBase
     }
 
     @Override
-    public DimensionData getDimensionData(String worldDirName, int dimensionId)
+    public DimensionData getDimensionData(@NotNull String worldDirName, @NotNull Dimension dimension)
     {
-        CompoundTag tag = getDimensionDataRaw(worldDirName, dimensionId);
+        CompoundTag tag = getDimensionDataRaw(worldDirName, dimension);
         if (tag == null) return null;
-        return new DimensionData(tag);
+        return DimensionData.fromCompoundTag(tag, dimension);
     }
 
     @Override
-    public CompoundTag getDimensionDataRaw(String worldDirName, int dimensionId)
+    public CompoundTag getDimensionDataRaw(@NotNull String worldDirName, @NotNull Dimension dimension)
     {
         File worldDir = new File(savesDir, worldDirName);
         if(!worldDir.exists())
@@ -97,7 +97,7 @@ public abstract class SaveFormatBase
             return null;
         }
         File dimensionsDir = new File(worldDir, "dimensions");
-        File dimensionDir = new File(dimensionsDir, "" + dimensionId);
+        File dimensionDir = new File(dimensionsDir, "" + dimension.id);
         File dimensionDat = new File(dimensionDir, "dimension.dat");
         if (dimensionDat.exists())
         {
@@ -109,7 +109,7 @@ public abstract class SaveFormatBase
             }
             catch (Exception ex)
             {
-                LOGGER.error("Exception loading dimension dat '{}' for world '{}'!", dimensionId, worldDirName, ex);
+                LOGGER.error("Exception loading dimension dat '{}' for world '{}'!", dimension, worldDirName, ex);
             }
         }
         dimensionDat = new File(dimensionDir, "dimension.dat_old");
@@ -123,7 +123,7 @@ public abstract class SaveFormatBase
             }
             catch (Exception ex)
             {
-                LOGGER.error("Exception loading dimension dat old '{}' for world '{}'!", dimensionId, worldDirName, ex);
+                LOGGER.error("Exception loading dimension dat old '{}' for world '{}'!", dimension, worldDirName, ex);
             }
         }
 
@@ -167,7 +167,7 @@ public abstract class SaveFormatBase
                     }
                     for (Dimension dimension : Dimension.getDimensionList().values())
                     {
-                        dimensionData.put(dimension.id, getDimensionData(worldDirName, dimension.id));
+                        dimensionData.put(dimension.id, getDimensionData(worldDirName, dimension));
                     }
                 }
                 saveFileList.add(new SaveFile(worldDirName, worldName, levelData, dimensionData, lastTimePlayed, size, needsConversion));
diff --git a/game/core/src/main/java/net/minecraft/core/world/season/SeasonManager.java b/game/core/src/main/java/net/minecraft/core/world/season/SeasonManager.java
index 1dbf08351..df8473bbc 100644
--- a/game/core/src/main/java/net/minecraft/core/world/season/SeasonManager.java
+++ b/game/core/src/main/java/net/minecraft/core/world/season/SeasonManager.java
@@ -5,6 +5,8 @@ import net.minecraft.core.world.World;
 import net.minecraft.core.world.config.season.SeasonConfig;
 import net.minecraft.core.world.config.season.SeasonConfigCycle;
 import net.minecraft.core.world.config.season.SeasonConfigSingle;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
 
 import java.util.List;
 
@@ -13,7 +15,7 @@ import java.util.List;
  */
 public abstract class SeasonManager
 {
-    public static SeasonManager fromConfig(World world, SeasonConfig config)
+    public static @NotNull SeasonManager fromConfig(@NotNull World world, @NotNull SeasonConfig config)
     {
         if (config instanceof SeasonConfigSingle)
         {
@@ -23,10 +25,8 @@ public abstract class SeasonManager
         {
             return new SeasonManagerCycle(world, (SeasonConfigCycle) config);
         }
-        else
-        {
-            return null;
-        }
+
+        throw new IllegalArgumentException("Invalid season config!");
     }
 
     /**
diff --git a/game/core/src/main/java/net/minecraft/core/world/type/WorldType.java b/game/core/src/main/java/net/minecraft/core/world/type/WorldType.java
index 5dba29a81..d45ea3c07 100644
--- a/game/core/src/main/java/net/minecraft/core/world/type/WorldType.java
+++ b/game/core/src/main/java/net/minecraft/core/world/type/WorldType.java
@@ -85,7 +85,7 @@ public abstract class WorldType {
         return brightnessRamp;
     }
 
-    public SeasonConfig getSeasonConfig() {
+    public @NotNull SeasonConfig getSeasonConfig() {
         return seasonConfig;
     }
 
@@ -141,7 +141,7 @@ public abstract class WorldType {
         return (double)y / (double)range;
     }
 
-    public abstract BiomeProvider createBiomeProvider(World world);
+    public abstract @NotNull BiomeProvider createBiomeProvider(World world);
 
     public abstract @NotNull Biome @NotNull [] allBiomes();
 
@@ -180,7 +180,7 @@ public abstract class WorldType {
                 attemptsRemaining--;
             }
             if (found) {
-                world.getLevelData().setSpawn(spawnPos.x, spawnPos.y, spawnPos.z);
+                world.getLevelData().getSpawnPos().set(spawnPos);
                 return;
             }
         }
@@ -203,24 +203,23 @@ public abstract class WorldType {
             }
             attemptsRemaining--;
         }
-        world.getLevelData().setSpawn(spawnPos.x, spawnPos.y, spawnPos.z);
+        world.getLevelData().getSpawnPos().set(spawnPos);
     }
 
     public void getRespawnLocation(World world) {
         LevelData levelData = world.getLevelData();
-        if(levelData.getSpawnY() <= 0) {
-            levelData.setSpawnY(getOceanY());
+        if(levelData.getSpawnPos().y() <= 0) {
+            levelData.getSpawnPos().y = getOceanY();
         }
-        int x = levelData.getSpawnX();
-        int z = levelData.getSpawnZ();
+        int x = levelData.getSpawnPos().x();
+        final int y = levelData.getSpawnPos().y();
+        int z = levelData.getSpawnPos().z();
         while (world.getTopBlock(x, z) == 0) {
             x += world.rand.nextInt(8) - world.rand.nextInt(8);
             z += world.rand.nextInt(8) - world.rand.nextInt(8);
         }
 
-        levelData.setSpawnX(x);
-        levelData.setSpawnZ(z);
-
+        levelData.getSpawnPos().set(x, y, z);
     }
 
     protected int getDayLengthTicks(World world) {
diff --git a/game/core/src/main/java/net/minecraft/core/world/type/WorldTypeDebug.java b/game/core/src/main/java/net/minecraft/core/world/type/WorldTypeDebug.java
index f367fd9b8..d2abd3115 100644
--- a/game/core/src/main/java/net/minecraft/core/world/type/WorldTypeDebug.java
+++ b/game/core/src/main/java/net/minecraft/core/world/type/WorldTypeDebug.java
@@ -25,7 +25,7 @@ public class WorldTypeDebug
     }
 
     @Override
-    public BiomeProvider createBiomeProvider(World world) {
+    public @NotNull BiomeProvider createBiomeProvider(World world) {
         return new BiomeProviderSingleBiome(Biomes.OVERWORLD_PLAINS, 1.0, 1.0, 1.0);
     }
 
@@ -46,7 +46,7 @@ public class WorldTypeDebug
 
     @Override
     public void getInitialSpawnLocation(World world, @Nullable Biome startingBiome) {
-        world.getLevelData().setSpawn(0, 1, 0);
+        world.getLevelData().getSpawnPos().set(0, 1, 0);
     }
 
     @Override
diff --git a/game/core/src/main/java/net/minecraft/core/world/type/WorldTypeEmpty.java b/game/core/src/main/java/net/minecraft/core/world/type/WorldTypeEmpty.java
index 8c4fedf23..208d5afb3 100644
--- a/game/core/src/main/java/net/minecraft/core/world/type/WorldTypeEmpty.java
+++ b/game/core/src/main/java/net/minecraft/core/world/type/WorldTypeEmpty.java
@@ -30,7 +30,7 @@ public class WorldTypeEmpty
     }
 
     @Override
-    public BiomeProvider createBiomeProvider(World world) {
+    public @NotNull BiomeProvider createBiomeProvider(World world) {
         return new BiomeProviderSingleBiome(Biomes.OVERWORLD_PLAINS, 1.0, 1.0, 1.0);
     }
 
@@ -51,7 +51,7 @@ public class WorldTypeEmpty
 
     @Override
     public void getInitialSpawnLocation(World world, @Nullable Biome startingBiome) {
-        world.getLevelData().setSpawn(0, 1, 0);
+        world.getLevelData().getSpawnPos().set(0, 1, 0);
     }
 
     @Override
diff --git a/game/core/src/main/java/net/minecraft/core/world/type/drift/WorldTypeDrift.java b/game/core/src/main/java/net/minecraft/core/world/type/drift/WorldTypeDrift.java
index c1e850d2f..322629de5 100644
--- a/game/core/src/main/java/net/minecraft/core/world/type/drift/WorldTypeDrift.java
+++ b/game/core/src/main/java/net/minecraft/core/world/type/drift/WorldTypeDrift.java
@@ -53,7 +53,7 @@ public class WorldTypeDrift
     }
 
     @Override
-    public BiomeProvider createBiomeProvider(World world) {
+    public @NotNull BiomeProvider createBiomeProvider(World world) {
         return new BiomeProviderSingleBiome(Biomes.DRIFT_DRIFT, 0.5, 0.0, 0.0);
     }
 
diff --git a/game/core/src/main/java/net/minecraft/core/world/type/nether/WorldTypeNether.java b/game/core/src/main/java/net/minecraft/core/world/type/nether/WorldTypeNether.java
index c77053c8d..2090ca074 100644
--- a/game/core/src/main/java/net/minecraft/core/world/type/nether/WorldTypeNether.java
+++ b/game/core/src/main/java/net/minecraft/core/world/type/nether/WorldTypeNether.java
@@ -43,8 +43,7 @@ public class WorldTypeNether
     }
 
     @Override
-    public BiomeProvider createBiomeProvider(World world) {
-//        return new BiomeProviderSingleBiome(Biomes.NETHER_NETHER, 1.0, 0.0, 1.0);
+    public @NotNull BiomeProvider createBiomeProvider(World world) {
         return new BiomeProviderNether(world.getRandomSeed());
     }
 
diff --git a/game/core/src/main/java/net/minecraft/core/world/type/overworld/WorldTypeFlat.java b/game/core/src/main/java/net/minecraft/core/world/type/overworld/WorldTypeFlat.java
index 2e98e3b02..7fe2b1d83 100644
--- a/game/core/src/main/java/net/minecraft/core/world/type/overworld/WorldTypeFlat.java
+++ b/game/core/src/main/java/net/minecraft/core/world/type/overworld/WorldTypeFlat.java
@@ -17,7 +17,7 @@ public class WorldTypeFlat
     }
 
     @Override
-    public BiomeProvider createBiomeProvider(World world) {
+    public @NotNull BiomeProvider createBiomeProvider(World world) {
         return new BiomeProviderSingleBiome(Biomes.OVERWORLD_PLAINS, 0.5, 0.0, 0.0);
     }
 
diff --git a/game/core/src/main/java/net/minecraft/core/world/type/overworld/WorldTypeOverworld.java b/game/core/src/main/java/net/minecraft/core/world/type/overworld/WorldTypeOverworld.java
index d401efce2..a0291dc1d 100644
--- a/game/core/src/main/java/net/minecraft/core/world/type/overworld/WorldTypeOverworld.java
+++ b/game/core/src/main/java/net/minecraft/core/world/type/overworld/WorldTypeOverworld.java
@@ -54,7 +54,7 @@ public class WorldTypeOverworld
     }
 
     @Override
-    public BiomeProvider createBiomeProvider(World world) {
+    public @NotNull BiomeProvider createBiomeProvider(World world) {
         return new BiomeProviderOverworld(world.getRandomSeed(), this);
     }
 
diff --git a/game/core/src/main/java/net/minecraft/core/world/type/overworld/WorldTypeOverworldB173.java b/game/core/src/main/java/net/minecraft/core/world/type/overworld/WorldTypeOverworldB173.java
index 5365694fd..c15c2ebeb 100644
--- a/game/core/src/main/java/net/minecraft/core/world/type/overworld/WorldTypeOverworldB173.java
+++ b/game/core/src/main/java/net/minecraft/core/world/type/overworld/WorldTypeOverworldB173.java
@@ -15,7 +15,7 @@ public class WorldTypeOverworldB173
     }
 
     @Override
-    public BiomeProvider createBiomeProvider(World world) {
+    public @NotNull BiomeProvider createBiomeProvider(World world) {
         return new BiomeProviderB173(world.getRandomSeed());
     }
 
diff --git a/game/core/src/main/java/net/minecraft/core/world/type/overworld/WorldTypeOverworldClassic.java b/game/core/src/main/java/net/minecraft/core/world/type/overworld/WorldTypeOverworldClassic.java
index 6e59dace9..1c75f2e40 100644
--- a/game/core/src/main/java/net/minecraft/core/world/type/overworld/WorldTypeOverworldClassic.java
+++ b/game/core/src/main/java/net/minecraft/core/world/type/overworld/WorldTypeOverworldClassic.java
@@ -17,7 +17,7 @@ public class WorldTypeOverworldClassic
     }
 
     @Override
-    public BiomeProvider createBiomeProvider(World world) {
+    public @NotNull BiomeProvider createBiomeProvider(World world) {
         return new BiomeProviderSingleBiome(Biomes.OVERWORLD_RETRO, 1.0, 1.0, 1.0);
     }
 
diff --git a/game/core/src/main/java/net/minecraft/core/world/type/overworld/WorldTypeOverworldFloating.java b/game/core/src/main/java/net/minecraft/core/world/type/overworld/WorldTypeOverworldFloating.java
index b3b168cae..2acf4fb1f 100644
--- a/game/core/src/main/java/net/minecraft/core/world/type/overworld/WorldTypeOverworldFloating.java
+++ b/game/core/src/main/java/net/minecraft/core/world/type/overworld/WorldTypeOverworldFloating.java
@@ -7,6 +7,7 @@ import net.minecraft.core.world.biome.provider.BiomeProviderOverworld;
 import net.minecraft.core.world.generate.chunk.ChunkGenerator;
 import net.minecraft.core.world.generate.chunk.perlin.overworld.floating.ChunkGeneratorOverworldFloating;
 import net.minecraft.core.world.type.WorldType;
+import org.jetbrains.annotations.NotNull;
 
 public class WorldTypeOverworldFloating
         extends WorldTypeOverworld {
@@ -15,7 +16,7 @@ public class WorldTypeOverworldFloating
     }
 
     @Override
-    public BiomeProvider createBiomeProvider(World world) {
+    public @NotNull BiomeProvider createBiomeProvider(World world) {
         return new BiomeProviderOverworld(world.getRandomSeed(), this)
                 .withTemperatureScales(0.00625, 0.00625, 0.25, 0.01)
                 .withHumidityScales(0.0125, 0.0125, 0.3, 0.01)
diff --git a/game/core/src/main/java/net/minecraft/core/world/type/overworld/WorldTypeOverworldHell.java b/game/core/src/main/java/net/minecraft/core/world/type/overworld/WorldTypeOverworldHell.java
index faf55ee91..20f8898e5 100644
--- a/game/core/src/main/java/net/minecraft/core/world/type/overworld/WorldTypeOverworldHell.java
+++ b/game/core/src/main/java/net/minecraft/core/world/type/overworld/WorldTypeOverworldHell.java
@@ -23,7 +23,7 @@ public class WorldTypeOverworldHell
     }
 
     @Override
-    public BiomeProvider createBiomeProvider(World world) {
+    public @NotNull BiomeProvider createBiomeProvider(World world) {
         return new BiomeProviderSingleBiome(Biomes.OVERWORLD_HELL, 1.0, 1.0, 0.0);
     }
 
diff --git a/game/core/src/main/java/net/minecraft/core/world/type/overworld/WorldTypeOverworldIndev.java b/game/core/src/main/java/net/minecraft/core/world/type/overworld/WorldTypeOverworldIndev.java
index 12451aa1f..8337b9fc9 100644
--- a/game/core/src/main/java/net/minecraft/core/world/type/overworld/WorldTypeOverworldIndev.java
+++ b/game/core/src/main/java/net/minecraft/core/world/type/overworld/WorldTypeOverworldIndev.java
@@ -43,7 +43,7 @@ public class WorldTypeOverworldIndev
                 }
             }
         }
-        world.getLevelData().setSpawn(x, y, z);
+        world.getLevelData().getSpawnPos().set(x, y, z);
 
         LevelGenerator.generateHouse(world);
     }
@@ -53,7 +53,7 @@ public class WorldTypeOverworldIndev
     }
 
     @Override
-    public BiomeProvider createBiomeProvider(World world) {
+    public @NotNull BiomeProvider createBiomeProvider(World world) {
         return new BiomeProviderSingleBiome(Biomes.OVERWORLD_RETRO, 1.0, 1.0, 1.0);
     }
 
diff --git a/game/core/src/main/java/net/minecraft/core/world/type/overworld/WorldTypeOverworldRetro.java b/game/core/src/main/java/net/minecraft/core/world/type/overworld/WorldTypeOverworldRetro.java
index e91e9ba7b..af2d80f60 100644
--- a/game/core/src/main/java/net/minecraft/core/world/type/overworld/WorldTypeOverworldRetro.java
+++ b/game/core/src/main/java/net/minecraft/core/world/type/overworld/WorldTypeOverworldRetro.java
@@ -16,7 +16,7 @@ public class WorldTypeOverworldRetro
     }
 
     @Override
-    public BiomeProvider createBiomeProvider(World world) {
+    public @NotNull BiomeProvider createBiomeProvider(World world) {
         return new BiomeProviderSingleBiome(Biomes.OVERWORLD_RETRO, 1.0, 1.0, 1.0);
     }
 
diff --git a/game/core/src/main/java/net/minecraft/core/world/type/overworld/WorldTypeOverworldSkyblock.java b/game/core/src/main/java/net/minecraft/core/world/type/overworld/WorldTypeOverworldSkyblock.java
index f78a5c4d0..509afb222 100644
--- a/game/core/src/main/java/net/minecraft/core/world/type/overworld/WorldTypeOverworldSkyblock.java
+++ b/game/core/src/main/java/net/minecraft/core/world/type/overworld/WorldTypeOverworldSkyblock.java
@@ -17,7 +17,7 @@ public class WorldTypeOverworldSkyblock
     }
 
     @Override
-    public BiomeProvider createBiomeProvider(World world) {
+    public @NotNull BiomeProvider createBiomeProvider(World world) {
         return new BiomeProviderSingleBiome(Biomes.OVERWORLD_PLAINS, 1.0, 1.0, 1.0);
     }
 
@@ -38,7 +38,7 @@ public class WorldTypeOverworldSkyblock
 
     @Override
     public void getInitialSpawnLocation(World world, @Nullable Biome startingBiome) {
-        world.getLevelData().setSpawn(0, 66, 0);
+        world.getLevelData().getSpawnPos().set(0, 66, 0);
     }
 
     @Override
diff --git a/game/server/src/main/java/net/minecraft/server/MinecraftServer.java b/game/server/src/main/java/net/minecraft/server/MinecraftServer.java
index 81f0ab46d..a49350ddf 100644
--- a/game/server/src/main/java/net/minecraft/server/MinecraftServer.java
+++ b/game/server/src/main/java/net/minecraft/server/MinecraftServer.java
@@ -70,8 +70,8 @@ import net.minecraft.core.util.helper.RestHandler;
 import net.minecraft.core.world.Dimension;
 import net.minecraft.core.world.World;
 import net.minecraft.core.world.biome.provider.BiomeProviderOverworld;
-import net.minecraft.core.world.chunk.IChunkLoader;
-import net.minecraft.core.world.chunk.provider.IChunkProvider;
+import net.minecraft.core.world.chunk.ChunkLoader;
+import net.minecraft.core.world.chunk.provider.ChunkProvider;
 import net.minecraft.core.world.save.ISaveConverter;
 import net.minecraft.core.world.save.ISaveFormat;
 import net.minecraft.core.world.save.LevelData;
@@ -107,6 +107,7 @@ import net.minecraft.server.world.ConvertProgressUpdater;
 import net.minecraft.server.world.WorldManager;
 import net.minecraft.server.world.WorldServer;
 import net.minecraft.server.world.chunk.provider.ChunkProviderServer;
+import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 import org.slf4j.Logger;
 
@@ -471,7 +472,7 @@ public class MinecraftServer
 
         try
         {
-            LevelData info = new LevelData(new File(worldDirName));
+            LevelData info = LevelData.fromWorldDir(new File(worldDirName));
             worldSaveVersion = info.getSaveVersion();
         }
         catch (IOException e)
@@ -525,25 +526,24 @@ public class MinecraftServer
 
     }
 
-    private void initWorld(ISaveFormat saveFormat, String worldDirName, long l)
+    private void initWorld(ISaveFormat saveFormat, String worldDirName, long seed)
     {
         convertWorld(saveFormat, worldDirName);
         dimensionWorlds = new Int2ObjectArrayMap<>();
-        LevelStorageServer saveHandler = new LevelStorageServer(saveFormat, new File("."), worldDirName, true);
-        for (Int2ObjectMap.Entry<Dimension> entry : Dimension.getDimensionList().int2ObjectEntrySet())
+        LevelStorageServer levelStorage = new LevelStorageServer(saveFormat, new File("."), worldDirName, true);
+        for (final @NotNull Dimension dimension : Dimension.getDimensionList().values())
         {
-            int dimId = entry.getIntKey();
             WorldServer worldServer;
-            if (dimId == 0)
+            if (dimension.id == 0)
             {
-                worldServer = new WorldServer(this, saveHandler, worldDirName, dimId, l);
+                worldServer = new WorldServer(this, levelStorage, worldDirName, seed, dimension);
             }
             else
             {
-                worldServer = new WorldServer(this, dimensionWorlds.get(0), dimId);
+                worldServer = new WorldServer(dimensionWorlds.get(0), dimension);
             }
-            dimensionWorlds.put(dimId, worldServer);
-            worldServer.addListener(new WorldManager(this, dimensionWorlds.get(dimId)));
+            dimensionWorlds.put(dimension.id, worldServer);
+            worldServer.addListener(new WorldManager(this, dimensionWorlds.get(dimension.id)));
             worldServer.setDifficulty(difficulty, true);
             worldServer.sleepPercent = sleepPercentage;
             worldServer.getSpawnerConfig().setHostileSpawning(spawnHostiles);
@@ -587,7 +587,7 @@ public class MinecraftServer
                         outputPercentRemaining("Preparing spawn area", (k1 * 100) / j1);
                         l1 = l2;
                     }
-                    worldServer.chunkProviderServer.prepareChunk(chunkcoordinates.x + k >> 4, chunkcoordinates.z + i1 >> 4);
+                    worldServer.getChunkProvider().prepareChunk(chunkcoordinates.x + k >> 4, chunkcoordinates.z + i1 >> 4);
                     while (worldServer.updatingLighting() && serverRunning) ;
                 }
 
@@ -930,12 +930,6 @@ public class MinecraftServer
     }
 
 
-    @Override
-    public IChunkProvider createChunkProvider(World world, IChunkLoader chunkLoader)
-    {
-        return new ChunkProviderServer((WorldServer)world, chunkLoader, world.worldType.createChunkGenerator(world));
-    }
-
     @Override
     public void logInfo(String s) {
         LOGGER.info(s);
diff --git a/game/server/src/main/java/net/minecraft/server/entity/player/PlayerServer.java b/game/server/src/main/java/net/minecraft/server/entity/player/PlayerServer.java
index 7410b9e8e..b031a1053 100644
--- a/game/server/src/main/java/net/minecraft/server/entity/player/PlayerServer.java
+++ b/game/server/src/main/java/net/minecraft/server/entity/player/PlayerServer.java
@@ -63,7 +63,7 @@ public class PlayerServer extends Player implements ContainerListener {
         int i = chunkcoordinates.x;
         int j = chunkcoordinates.z;
         int k = chunkcoordinates.y;
-        if (!world.worldType.hasCeiling())
+        if (!world.getWorldType().hasCeiling())
         {
             i += random.nextInt(20) - 10;
             k = world.findTopSolidBlock(i, j);
diff --git a/game/server/src/main/java/net/minecraft/server/net/PlayerList.java b/game/server/src/main/java/net/minecraft/server/net/PlayerList.java
index 1c6416ea0..3aa4cc3d6 100644
--- a/game/server/src/main/java/net/minecraft/server/net/PlayerList.java
+++ b/game/server/src/main/java/net/minecraft/server/net/PlayerList.java
@@ -119,7 +119,7 @@ public class PlayerList
         }
         getPlayerManager(player.dimension).addPlayer(player);
         WorldServer world = server.getDimensionWorld(player.dimension);
-        world.chunkProviderServer.prepareChunk((int) player.x >> 4, (int) player.z >> 4);
+        world.getChunkProvider().prepareChunk((int) player.x >> 4, (int) player.z >> 4);
     }
 
     public int getMaxTrackingDistance()
@@ -142,7 +142,7 @@ public class PlayerList
         playerEntities.add(player);
         player.playerNetServerHandler.handleSendInitialPlayerList();
         WorldServer world = server.getDimensionWorld(player.dimension);
-        world.chunkProviderServer.prepareChunk((int) player.x >> 4, (int) player.z >> 4);
+        world.getChunkProvider().prepareChunk((int) player.x >> 4, (int) player.z >> 4);
 
         if (!world.getWorldType().hasCeiling())
         {
@@ -237,11 +237,11 @@ public class PlayerList
                 newPlayer.playerNetServerHandler.sendPacket(new PacketBedMessage(0));
             }
         }
-        worldserver.chunkProviderServer.prepareChunk((int) newPlayer.x >> 4, (int) newPlayer.z >> 4);
+        worldserver.getChunkProvider().prepareChunk((int) newPlayer.x >> 4, (int) newPlayer.z >> 4);
         while (!worldserver.getCubes(newPlayer, newPlayer.bb).isEmpty()) {
             newPlayer.setPos(newPlayer.x, newPlayer.y + 1.0D, newPlayer.z);
         }
-        newPlayer.playerNetServerHandler.sendPacket(new PacketRespawn((byte) newPlayer.dimension, (byte) Registries.WORLD_TYPES.getNumericIdOfItem(worldserver.worldType)));
+        newPlayer.playerNetServerHandler.sendPacket(new PacketRespawn((byte) newPlayer.dimension, (byte) Registries.WORLD_TYPES.getNumericIdOfItem(worldserver.getWorldType())));
         server.playerList.sendPacketToAllPlayers(new PacketPlayerGamemode(newPlayer.id, newPlayer.gamemode.getId()));
         newPlayer.playerNetServerHandler.teleportAndRotate(newPlayer.x, newPlayer.y, newPlayer.z, newPlayer.yRot, newPlayer.xRot);
         setTime(newPlayer, worldserver);
@@ -261,7 +261,7 @@ public class PlayerList
 
         playerServer.dimension = targetDim;
         WorldServer worldserver1 = server.getDimensionWorld(playerServer.dimension);
-        playerServer.playerNetServerHandler.sendPacket(new PacketRespawn((byte) playerServer.dimension, (byte) Registries.WORLD_TYPES.getNumericIdOfItem(worldserver1.worldType)));
+        playerServer.playerNetServerHandler.sendPacket(new PacketRespawn((byte) playerServer.dimension, (byte) Registries.WORLD_TYPES.getNumericIdOfItem(worldserver1.getWorldType())));
         worldserver.removePlayer(playerServer);
         playerServer.removed = false;
         double x = playerServer.x;
@@ -293,9 +293,9 @@ public class PlayerList
             playerServer.teleport(x, playerServer.y, z, playerServer.yRot, playerServer.xRot);
             worldserver1.updateEntityWithOptionalForce(playerServer, false);
             if (generatePortal){
-                worldserver1.chunkProviderServer.chunkLoadOverride = true;
+                worldserver1.getChunkProvider().chunkLoadOverride = true;
                 (new PortalHandler()).teleportEntity(worldserver1, playerServer, portalColor, lastDim, newDim);
-                worldserver1.chunkProviderServer.chunkLoadOverride = false;
+                worldserver1.getChunkProvider().chunkLoadOverride = false;
             }
         }
         syncPlayerDimension(playerServer);
diff --git a/game/server/src/main/java/net/minecraft/server/player/PlayerManager.java b/game/server/src/main/java/net/minecraft/server/player/PlayerManager.java
index 74fb5bb81..5db1056dd 100644
--- a/game/server/src/main/java/net/minecraft/server/player/PlayerManager.java
+++ b/game/server/src/main/java/net/minecraft/server/player/PlayerManager.java
@@ -211,7 +211,7 @@ public class PlayerManager
             this.chunkX = chunkX;
             this.chunkZ = chunkZ;
             currentChunk = new ChunkCoordinate(chunkX, chunkZ);
-            server.getDimensionWorld(dimension).chunkProviderServer.prepareChunk(chunkX, chunkZ);
+            server.getDimensionWorld(dimension).getChunkProvider().prepareChunk(chunkX, chunkZ);
         }
 
         public void addPlayer(PlayerServer player) {
@@ -236,7 +236,7 @@ public class PlayerManager
                 if (numBlocksToUpdate > 0) {
                     playerInstancesToUpdate.remove(this);
                 }
-                server.getDimensionWorld(dimension).chunkProviderServer.dropChunk(new ChunkPos(chunkX, chunkZ));
+                server.getDimensionWorld(dimension).getChunkProvider().dropChunk(new ChunkPos(chunkX, chunkZ));
             }
             player.loadedChunks.remove(currentChunk);
             if (player.field_420_ah.contains(currentChunk)) {
diff --git a/game/server/src/main/java/net/minecraft/server/world/WorldServer.java b/game/server/src/main/java/net/minecraft/server/world/WorldServer.java
index 7eb8556cb..a8b0efd4d 100644
--- a/game/server/src/main/java/net/minecraft/server/world/WorldServer.java
+++ b/game/server/src/main/java/net/minecraft/server/world/WorldServer.java
@@ -21,21 +21,21 @@ import net.minecraft.core.world.Explosion;
 import net.minecraft.core.world.ExplosionCannonball;
 import net.minecraft.core.world.SpawnerMobs;
 import net.minecraft.core.world.World;
-import net.minecraft.core.world.chunk.IChunkLoader;
-import net.minecraft.core.world.chunk.provider.IChunkProvider;
+import net.minecraft.core.world.biome.Biome;
+import net.minecraft.core.world.chunk.ChunkLoader;
+import net.minecraft.core.world.chunk.provider.ChunkProvider;
 import net.minecraft.core.world.pos.TilePosc;
 import net.minecraft.core.world.save.LevelStorage;
-import net.minecraft.core.world.type.WorldType;
+import net.minecraft.core.world.saveddata.SavedDataStorage;
 import net.minecraft.server.MinecraftServer;
 import net.minecraft.server.world.chunk.provider.ChunkProviderServer;
 import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
 
 import java.util.ArrayList;
 import java.util.List;
 
-public class WorldServer extends World
-{
-    public ChunkProviderServer chunkProviderServer;
+public class WorldServer extends World {
     public boolean dontSave;
     public MinecraftServer mcServer;
     private final Int2ObjectMap<Entity> entityIntHashMap;
@@ -43,37 +43,45 @@ public class WorldServer extends World
 
 
     public WorldServer(
-        MinecraftServer minecraftServer,
-        LevelStorage isavehandler,
-        String name,
-        int dimensionId,
-        long seed
+        final @NotNull MinecraftServer server,
+        final @NotNull LevelStorage levelStorage,
+        final @NotNull String name,
+        final long seed,
+        final @NotNull Dimension dimension
     ) {
-        super(isavehandler, name, seed, Dimension.getDimensionList().get(dimensionId), null);
+        super(levelStorage, name, seed, dimension, null);
 
         entityIntHashMap = new Int2ObjectOpenHashMap<>();
-        mcServer = minecraftServer;
+        mcServer = server;
         getLevelData().setLastPlayerUUID(null);
     }
 
     public WorldServer(
-        MinecraftServer minecraftServer,
-        WorldServer parent,
-        int dimensionId
+        final @NotNull WorldServer parent,
+        final @NotNull Dimension dimension
     ) {
-        super(parent, Dimension.getDimensionList().get(dimensionId));
+        super(parent, dimension);
 
         entityIntHashMap = new Int2ObjectOpenHashMap<>();
-        mcServer = minecraftServer;
+        this.mcServer = parent.mcServer;
         getLevelData().setLastPlayerUUID(null);
     }
 
     @Override
-    protected IChunkProvider createChunkProvider()
+    public void setLightningFlicker(final int flicker) {
+        // Do nothing
+    }
+
+    @Override
+    public @NotNull ChunkProviderServer getChunkProvider() {
+        return (ChunkProviderServer) super.getChunkProvider();
+    }
+
+    @Override
+    protected @NotNull ChunkProviderServer createChunkProvider(final @NotNull LevelStorage levelStorage)
     {
-        IChunkLoader ichunkloader = this.getLevelStorage().getChunkLoader(dimension);
-        this.chunkProviderServer = (ChunkProviderServer) Global.accessor.createChunkProvider(this, ichunkloader);
-        return chunkProviderServer;
+        final @Nullable ChunkLoader chunkLoader = levelStorage.getChunkLoader(dimension);
+        return new ChunkProviderServer(this, chunkLoader, this.getWorldType().createChunkGenerator(this));
     }
 
     public List<TileEntity> getBlockEntitiesWithinBounds(int minX, int minY, int minZ, int maxX, int maxY, int maxZ)
@@ -94,8 +102,8 @@ public class WorldServer extends World
     @Override
     public boolean canMineBlock(final @NotNull Player player, final @NotNull TilePosc tilePos) {
         if (this.mcServer.spawnProtectionRange <= 0 || this.mcServer.playerList.isOp(player.uuid)) return super.canMineBlock(player, tilePos);
-        final int dx = (int)MathHelper.abs(tilePos.x() - this.getLevelData().getSpawnX());
-        final int dz = (int)MathHelper.abs(tilePos.z() - this.getLevelData().getSpawnZ());
+        final int dx = (int)MathHelper.abs(tilePos.x() - this.getLevelData().getSpawnPos().x());
+        final int dz = (int)MathHelper.abs(tilePos.z() - this.getLevelData().getSpawnPos().z());
         return Math.max(dx, dz) > this.mcServer.spawnProtectionRange;
     }
 
@@ -141,7 +149,7 @@ public class WorldServer extends World
                 }
 
                 long timePlusOneDay = getLevelData().getWorldTime() + Global.DAY_LENGTH_TICKS;
-                getLevelData().setWorldTime(timePlusOneDay - timePlusOneDay % Global.DAY_LENGTH_TICKS + worldType.getSunriseTick(this) + Global.DAY_LENGTH_TICKS / 24);
+                getLevelData().setWorldTime(timePlusOneDay - timePlusOneDay % Global.DAY_LENGTH_TICKS + getWorldType().getSunriseTick(this) + Global.DAY_LENGTH_TICKS / 24);
                 wakeUpAllPlayers();
             }
         }
diff --git a/game/server/src/main/java/net/minecraft/server/world/chunk/provider/ChunkProviderServer.java b/game/server/src/main/java/net/minecraft/server/world/chunk/provider/ChunkProviderServer.java
index 48d08d675..5652e2676 100644
--- a/game/server/src/main/java/net/minecraft/server/world/chunk/provider/ChunkProviderServer.java
+++ b/game/server/src/main/java/net/minecraft/server/world/chunk/provider/ChunkProviderServer.java
@@ -2,8 +2,9 @@ package net.minecraft.server.world.chunk.provider;
 
 import com.mojang.logging.LogUtils;
 import net.minecraft.core.world.ProgressListener;
-import net.minecraft.core.world.chunk.provider.IChunkProvider;
+import net.minecraft.core.world.chunk.provider.ChunkProvider;
 import net.minecraft.core.world.pos.ChunkPos;
+import net.minecraft.core.world.pos.ChunkPosc;
 import net.minecraft.core.world.pos.TilePos;
 import net.minecraft.server.world.WorldServer;
 import net.minecraft.core.world.chunk.*;
@@ -16,18 +17,18 @@ import java.io.IOException;
 import java.util.*;
 
 public class ChunkProviderServer
-    implements IChunkProvider {
+    implements ChunkProvider {
     private static final Logger LOGGER = LogUtils.getLogger();
     private final Set<ChunkPos> droppedChunksSet;
     private final Chunk emptyChunk;
     public ChunkGenerator chunkGenerator;
-    private final IChunkLoader chunkLoader;
+    private final ChunkLoader chunkLoader;
     public boolean chunkLoadOverride;
     private final Map<ChunkPos, Chunk> chunkMap;
     private final List<Chunk> chunkList;
     private final WorldServer world;
 
-    public ChunkProviderServer(WorldServer world, IChunkLoader chunkLoader, ChunkGenerator chunkGenerator) {
+    public ChunkProviderServer(WorldServer world, ChunkLoader chunkLoader, ChunkGenerator chunkGenerator) {
         this.droppedChunksSet = new HashSet<>();
         this.chunkLoadOverride = false;
         this.chunkMap = new HashMap<>();
@@ -39,7 +40,7 @@ public class ChunkProviderServer
     }
 
     @Override
-    public boolean isChunkLoaded(@NotNull ChunkPos chunkPos) {
+    public boolean isChunkLoaded(@NotNull ChunkPosc chunkPos) {
         return this.chunkMap.containsKey(chunkPos);
     }
 
@@ -55,14 +56,14 @@ public class ChunkProviderServer
     }
 
     @Override
-    public @NotNull Chunk prepareChunk(@NotNull ChunkPos chunkPos, boolean priority) {
+    public @NotNull Chunk prepareChunk(@NotNull ChunkPosc chunkPos, boolean priority) {
         this.droppedChunksSet.remove(chunkPos);
         Chunk chunk = this.chunkMap.get(chunkPos);
         if (chunk == null) {
             chunk = loadChunkFromFile(chunkPos);
             if (chunk == null) {
                 if (this.chunkGenerator != null) {
-                    chunk = this.chunkGenerator.generate(chunkPos.x, chunkPos.z);
+                    chunk = this.chunkGenerator.generate(chunkPos.x(), chunkPos.z());
                     chunk.fixMissingBlocks();
                 } else {
                     chunk = this.emptyChunk;
@@ -72,17 +73,35 @@ public class ChunkProviderServer
             this.chunkList.add(chunk);
             chunk.checkForLightGaps();
             chunk.onLoad();
-            if (!chunk.isTerrainPopulated && isChunkLoaded(chunkPos.x + 1, chunkPos.z + 1) && isChunkLoaded(chunkPos.x, chunkPos.z + 1) && isChunkLoaded(chunkPos.x + 1, chunkPos.z)) {
-                populate(this, chunkPos.x, chunkPos.z);
+            final @NotNull ChunkPos queryPos = new ChunkPos(chunkPos);
+            if (
+                !chunk.isTerrainPopulated &&
+                    isChunkLoaded(chunkPos.add(1, 1, queryPos)) &&
+                    isChunkLoaded(chunkPos.add(0, 1, queryPos)) &&
+                    isChunkLoaded(chunkPos.add(1, 0, queryPos))
+            ) {
+                populate(chunkPos);
             }
-            if (isChunkLoaded(chunkPos.x - 1, chunkPos.z) && !provideChunk(chunkPos.x - 1, chunkPos.z).isTerrainPopulated && isChunkLoaded(chunkPos.x - 1, chunkPos.z + 1) && isChunkLoaded(chunkPos.x, chunkPos.z + 1) && isChunkLoaded(chunkPos.x - 1, chunkPos.z)) {
-                populate(this, chunkPos.x - 1, chunkPos.z);
+            if (
+                isChunkLoaded(chunkPos.add(-1, 0, queryPos)) && !provideChunk(chunkPos.add(-1, 0, queryPos), true).isTerrainPopulated &&
+                    isChunkLoaded(chunkPos.add(-1, 1, queryPos)) &&
+                    isChunkLoaded(chunkPos.add(0, 1, queryPos))
+            ) {
+                populate(chunkPos.add(-1, 0, queryPos));
             }
-            if (isChunkLoaded(chunkPos.x, chunkPos.z - 1) && !provideChunk(chunkPos.x, chunkPos.z - 1).isTerrainPopulated && isChunkLoaded(chunkPos.x + 1, chunkPos.z - 1) && isChunkLoaded(chunkPos.x, chunkPos.z - 1) && isChunkLoaded(chunkPos.x + 1, chunkPos.z)) {
-                populate(this, chunkPos.x, chunkPos.z - 1);
+            if (
+                isChunkLoaded(chunkPos.add(0, -1, queryPos)) && !provideChunk(chunkPos.add(0, -1, queryPos), true).isTerrainPopulated &&
+                    isChunkLoaded(chunkPos.add(1, -1, queryPos)) &&
+                    isChunkLoaded(chunkPos.add(1, 0, queryPos))
+            ) {
+                populate(chunkPos.add(0, -1, queryPos));
             }
-            if (isChunkLoaded(chunkPos.x - 1, chunkPos.z - 1) && !provideChunk(chunkPos.x - 1, chunkPos.z - 1).isTerrainPopulated && isChunkLoaded(chunkPos.x - 1, chunkPos.z - 1) && isChunkLoaded(chunkPos.x, chunkPos.z - 1) && isChunkLoaded(chunkPos.x - 1, chunkPos.z)) {
-                populate(this, chunkPos.x - 1, chunkPos.z - 1);
+            if (
+                isChunkLoaded(chunkPos.add(-1, -1, queryPos)) && !provideChunk(chunkPos.add(-1, -1, queryPos), true).isTerrainPopulated &&
+                    isChunkLoaded(chunkPos.add(0, -1, queryPos)) &&
+                    isChunkLoaded(chunkPos.add(-1, 0, queryPos))
+            ) {
+                populate(chunkPos.add(-1, -1, queryPos));
             }
             if (this.world.getCurrentWeather() != null) {
                 this.world.getCurrentWeather().doChunkLoadEffect(this.world, chunk);
@@ -92,34 +111,52 @@ public class ChunkProviderServer
     }
 
     @Override
-    public void regenerateChunk(@NotNull ChunkPos chunkPos) {
+    public void regenerateChunk(@NotNull ChunkPosc chunkPos) {
         this.droppedChunksSet.remove(chunkPos);
         this.chunkList.remove(this.chunkMap.get(chunkPos));
         this.chunkMap.remove(chunkPos);
         Chunk chunk;
         if (this.chunkGenerator != null) {
-            chunk = this.chunkGenerator.generate(chunkPos.x, chunkPos.z);
+            chunk = this.chunkGenerator.generate(chunkPos.x(), chunkPos.z());
             chunk.fixMissingBlocks();
         } else {
             return;
         }
         this.chunkMap.put(new ChunkPos(chunkPos), chunk);
-        if (!chunk.isTerrainPopulated && isChunkLoaded(chunkPos.x + 1, chunkPos.z + 1) && isChunkLoaded(chunkPos.x, chunkPos.z + 1) && isChunkLoaded(chunkPos.x + 1, chunkPos.z)) {
-            populate(new ChunkPos(chunkPos.x, chunkPos.z));
+        final @NotNull ChunkPos queryPos = new ChunkPos(chunkPos);
+        if (
+            !chunk.isTerrainPopulated &&
+                isChunkLoaded(chunkPos.add(1, 1, queryPos)) &&
+                isChunkLoaded(chunkPos.add(0, 1, queryPos)) &&
+                isChunkLoaded(chunkPos.add(1, 0, queryPos))
+        ) {
+            populate(chunkPos);
         }
-        if (isChunkLoaded(chunkPos.x - 1, chunkPos.z) && !provideChunk(chunkPos.x - 1, chunkPos.z).isTerrainPopulated && isChunkLoaded(chunkPos.x - 1, chunkPos.z + 1) && isChunkLoaded(chunkPos.x, chunkPos.z + 1) && isChunkLoaded(chunkPos.x - 1, chunkPos.z)) {
-            populate(new ChunkPos(chunkPos.x - 1, chunkPos.z));
+        if (
+            isChunkLoaded(chunkPos.add(-1, 0, queryPos)) && !provideChunk(chunkPos.add(-1, 0, queryPos), true).isTerrainPopulated &&
+                isChunkLoaded(chunkPos.add(-1, 1, queryPos)) &&
+                isChunkLoaded(chunkPos.add(0, 1, queryPos))
+        ) {
+            populate(chunkPos.add(-1, 0, queryPos));
         }
-        if (isChunkLoaded(chunkPos.x, chunkPos.z - 1) && !provideChunk(chunkPos.x, chunkPos.z - 1).isTerrainPopulated && isChunkLoaded(chunkPos.x + 1, chunkPos.z - 1) && isChunkLoaded(chunkPos.x, chunkPos.z - 1) && isChunkLoaded(chunkPos.x + 1, chunkPos.z)) {
-            populate(new ChunkPos(chunkPos.x, chunkPos.z - 1));
+        if (
+            isChunkLoaded(chunkPos.add(0, -1, queryPos)) && !provideChunk(chunkPos.add(0, -1, queryPos), true).isTerrainPopulated &&
+                isChunkLoaded(chunkPos.add(1, -1, queryPos)) &&
+                isChunkLoaded(chunkPos.add(1, 0, queryPos))
+        ) {
+            populate(chunkPos.add(0, -1, queryPos));
         }
-        if (isChunkLoaded(chunkPos.x - 1, chunkPos.z - 1) && !provideChunk(chunkPos.x - 1, chunkPos.z - 1).isTerrainPopulated && isChunkLoaded(chunkPos.x - 1, chunkPos.z - 1) && isChunkLoaded(chunkPos.x, chunkPos.z - 1) && isChunkLoaded(chunkPos.x - 1, chunkPos.z)) {
-            populate(new ChunkPos(chunkPos.x - 1, chunkPos.z - 1));
+        if (
+            isChunkLoaded(chunkPos.add(-1, -1, queryPos)) && !provideChunk(chunkPos.add(-1, -1, queryPos), true).isTerrainPopulated &&
+                isChunkLoaded(chunkPos.add(0, -1, queryPos)) &&
+                isChunkLoaded(chunkPos.add(-1, 0, queryPos))
+        ) {
+            populate(chunkPos.add(-1, -1, queryPos));
         }
     }
 
     @Override
-    public @NotNull Chunk provideChunk(@NotNull ChunkPos chunkPos, boolean priority) {
+    public @NotNull Chunk provideChunk(@NotNull ChunkPosc chunkPos, boolean priority) {
         Chunk chunk = this.chunkMap.get(chunkPos);
         if (chunk == null) {
             if (this.world.findingSpawnPoint || this.chunkLoadOverride) {
@@ -132,18 +169,18 @@ public class ChunkProviderServer
         }
     }
 
-    private Chunk loadChunkFromFile(@NotNull ChunkPos chunkPos) {
+    private @Nullable Chunk loadChunkFromFile(@NotNull ChunkPosc chunkPos) {
         if (this.chunkLoader == null) {
             return null;
         }
         try {
-            Chunk chunk = this.chunkLoader.loadChunk(this.world, chunkPos.x, chunkPos.z);
+            Chunk chunk = this.chunkLoader.loadChunk(this.world, chunkPos.x(), chunkPos.z());
             if (chunk != null) {
                 chunk.lastSaveTime = this.world.getWorldTime();
             }
             return chunk;
         } catch (Exception exception) {
-            LOGGER.error("Failed to load chunk at X:{}, Z:{} to disk!", chunkPos.x, chunkPos.z, exception);
+            LOGGER.error("Failed to load chunk at X:{}, Z:{} to disk!", chunkPos.x(), chunkPos.z(), exception);
         }
         return null;
     }
@@ -161,7 +198,7 @@ public class ChunkProviderServer
     }
 
     @Override
-    public void populate(@NotNull ChunkPos chunkPos) {
+    public void populate(@NotNull ChunkPosc chunkPos) {
         Chunk chunk = provideChunk(chunkPos, true);
         if (!chunk.isTerrainPopulated) {
             chunk.isTerrainPopulated = true;
@@ -228,7 +265,7 @@ public class ChunkProviderServer
     }
 
     @Override
-    public void setCurrentChunkOver(@NotNull ChunkPos chunkPos) {
+    public void setCurrentChunkOver(@NotNull ChunkPosc chunkPos) {
         // Do nothing
     }
 }
diff --git a/util/nbt/src/main/java/com/mojang/nbt/tags/CompoundTag.java b/util/nbt/src/main/java/com/mojang/nbt/tags/CompoundTag.java
index 11008e673..6eaae0cf6 100644
--- a/util/nbt/src/main/java/com/mojang/nbt/tags/CompoundTag.java
+++ b/util/nbt/src/main/java/com/mojang/nbt/tags/CompoundTag.java
@@ -4,6 +4,7 @@ import com.google.gson.JsonElement;
 import com.google.gson.JsonObject;
 import com.google.gson.JsonParseException;
 import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
 
 import java.io.*;
 import java.util.*;
@@ -248,12 +249,12 @@ public class CompoundTag extends Tag<@NotNull Map<String, Tag<?>>>
         put(key, new DoubleTag(value));
     }
 
-    public String getString(String key)
+    public @NotNull String getString(String key)
     {
         return getStringOrDefault(key, "");
     }
 
-    public String getStringOrDefault(String key, String defaultValue)
+    public @Nullable String getStringOrDefault(final @NotNull String key, final @Nullable String defaultValue)
     {
         Tag<?> tag = getTagOrDefault(key, null);
 
@@ -353,12 +354,12 @@ public class CompoundTag extends Tag<@NotNull Map<String, Tag<?>>>
         put(key, new LongArrayTag(array));
     }
 
-    public CompoundTag getCompound(String key)
+    public @NotNull CompoundTag getCompound(@NotNull String key)
     {
         return getCompoundOrDefault(key, new CompoundTag());
     }
 
-    public CompoundTag getCompoundOrDefault(String key, CompoundTag defaultCompound)
+    public @Nullable CompoundTag getCompoundOrDefault(@NotNull String key, @Nullable CompoundTag defaultCompound)
     {
         Tag<?> tag = getTagOrDefault(key, null);
 
diff --git a/util/seed-viewer/src/main/java/org/useless/seedviewer/bta/BTAChunkProvider.java b/util/seed-viewer/src/main/java/org/useless/seedviewer/bta/BTAChunkProvider.java
index 50f0fbfca..78fcbab91 100644
--- a/util/seed-viewer/src/main/java/org/useless/seedviewer/bta/BTAChunkProvider.java
+++ b/util/seed-viewer/src/main/java/org/useless/seedviewer/bta/BTAChunkProvider.java
@@ -6,6 +6,7 @@ import net.minecraft.core.block.Blocks;
 import net.minecraft.core.data.registry.Registries;
 import net.minecraft.core.item.Items;
 import net.minecraft.core.lang.I18n;
+import net.minecraft.core.world.Dimension;
 import net.minecraft.core.world.biome.Biomes;
 import net.minecraft.core.world.biome.provider.BiomeProvider;
 import net.minecraft.core.world.biome.provider.BiomeProviderOverworld;
@@ -45,7 +46,7 @@ public class BTAChunkProvider implements ChunkProvider {
 
     public BTAChunkProvider(File worldFolder, LevelData data) {
         this.biomeProvider = new BiomeProviderOverworld(data.getRandomSeed(), WorldTypes.OVERWORLD_EXTENDED);
-        this.chunkLoader = new ChunkLoader(worldFolder, 0);
+        this.chunkLoader = new ChunkLoader(worldFolder, Dimension.OVERWORLD);
     }
     @Override
     public ViewerChunk getChunk(ChunkPos location) {
diff --git a/util/seed-viewer/src/main/java/org/useless/seedviewer/bta/DummyMinecraft.java b/util/seed-viewer/src/main/java/org/useless/seedviewer/bta/DummyMinecraft.java
index a1eb4446b..1c3e89ab3 100644
--- a/util/seed-viewer/src/main/java/org/useless/seedviewer/bta/DummyMinecraft.java
+++ b/util/seed-viewer/src/main/java/org/useless/seedviewer/bta/DummyMinecraft.java
@@ -3,8 +3,8 @@ package org.useless.seedviewer.bta;
 import net.minecraft.core.MinecraftAccessor;
 import net.minecraft.core.entity.SkinVariantList;
 import net.minecraft.core.world.World;
-import net.minecraft.core.world.chunk.IChunkLoader;
-import net.minecraft.core.world.chunk.provider.IChunkProvider;
+import net.minecraft.core.world.chunk.ChunkLoader;
+import net.minecraft.core.world.chunk.provider.ChunkProvider;
 import org.useless.seedviewer.bta.chunk.provider.ChunkProviderSeedViewer;
 
 import java.io.File;
@@ -14,7 +14,7 @@ public class DummyMinecraft implements MinecraftAccessor {
         return getAppDir("minecraft-bta");
     }
 
-    public IChunkProvider createChunkProvider(World world, IChunkLoader chunkLoader) {
+    public ChunkProvider createChunkProvider(World world, ChunkLoader chunkLoader) {
         return new ChunkProviderSeedViewer(world, chunkLoader, world.getWorldType().createChunkGenerator(world));
     }
 
diff --git a/util/seed-viewer/src/main/java/org/useless/seedviewer/bta/DummyWorld.java b/util/seed-viewer/src/main/java/org/useless/seedviewer/bta/DummyWorld.java
new file mode 100644
index 000000000..62c0f422b
--- /dev/null
+++ b/util/seed-viewer/src/main/java/org/useless/seedviewer/bta/DummyWorld.java
@@ -0,0 +1,34 @@
+package org.useless.seedviewer.bta;
+
+import net.minecraft.core.world.Dimension;
+import net.minecraft.core.world.World;
+import net.minecraft.core.world.biome.Biome;
+import net.minecraft.core.world.chunk.provider.ChunkProvider;
+import net.minecraft.core.world.save.LevelStorage;
+import net.minecraft.core.world.save.LevelStorageDummy;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.useless.seedviewer.bta.worldloader.ChunkLoader;
+
+import java.lang.reflect.Field;
+import java.util.Objects;
+
+public class DummyWorld extends World {
+    public static @Nullable ChunkLoader CHUNK_LOADER = null;
+
+    public DummyWorld(
+        final @NotNull Dimension dimension
+    ) {
+        super(new LevelStorageDummy(), "Dummy World", 0, dimension, null);
+    }
+
+    @Override
+    public void setLightningFlicker(final int flicker) {
+        // Do nothing
+    }
+
+    @Override
+    protected @NotNull ChunkProvider createChunkProvider(final @NotNull LevelStorage levelStorage) {
+        return Objects.requireNonNull(CHUNK_LOADER);
+    }
+}
diff --git a/util/seed-viewer/src/main/java/org/useless/seedviewer/bta/chunk/provider/ChunkProviderSeedViewer.java b/util/seed-viewer/src/main/java/org/useless/seedviewer/bta/chunk/provider/ChunkProviderSeedViewer.java
index d94f0c391..027111c4b 100644
--- a/util/seed-viewer/src/main/java/org/useless/seedviewer/bta/chunk/provider/ChunkProviderSeedViewer.java
+++ b/util/seed-viewer/src/main/java/org/useless/seedviewer/bta/chunk/provider/ChunkProviderSeedViewer.java
@@ -5,10 +5,11 @@ import net.minecraft.core.world.ProgressListener;
 import net.minecraft.core.world.World;
 import net.minecraft.core.world.chunk.Chunk;
 import net.minecraft.core.world.chunk.EmptyChunk;
-import net.minecraft.core.world.chunk.IChunkLoader;
-import net.minecraft.core.world.chunk.provider.IChunkProvider;
+import net.minecraft.core.world.chunk.ChunkLoader;
+import net.minecraft.core.world.chunk.provider.ChunkProvider;
 import net.minecraft.core.world.generate.chunk.ChunkGenerator;
 import net.minecraft.core.world.pos.ChunkPos;
+import net.minecraft.core.world.pos.ChunkPosc;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 import org.slf4j.Logger;
@@ -16,14 +17,14 @@ import org.slf4j.Logger;
 import java.util.Arrays;
 
 public class ChunkProviderSeedViewer
-    implements IChunkProvider {
+    implements ChunkProvider {
     public static final int CHUNK_RADIUS = 64; // Radius should *always* be a power of 2!
     public static final int CHUNK_MASK = CHUNK_RADIUS * 2 - 1;
 
     private static final Logger LOGGER = LogUtils.getLogger();
     private final @NotNull Chunk blankChunk;
     public @Nullable ChunkGenerator chunkGenerator;
-    private final @Nullable IChunkLoader chunkLoader;
+    private final @Nullable ChunkLoader chunkLoader;
     private final Chunk[] chunks;
     private final @NotNull World world;
     private @NotNull ChunkPos lastQueriedChunkPos = new ChunkPos(Integer.MIN_VALUE, Integer.MIN_VALUE);
@@ -31,7 +32,7 @@ public class ChunkProviderSeedViewer
     private @NotNull ChunkPos curChunkPos = new ChunkPos(0, 0);
 
 
-    public ChunkProviderSeedViewer(@NotNull World world, @Nullable IChunkLoader ichunkloader, @Nullable ChunkGenerator chunkGenerator) {
+    public ChunkProviderSeedViewer(@NotNull World world, @Nullable ChunkLoader ichunkloader, @Nullable ChunkGenerator chunkGenerator) {
         this.chunks = new Chunk[CHUNK_RADIUS * 2 * CHUNK_RADIUS * 2];
         this.blankChunk = new EmptyChunk(world, new ChunkPos(0, 0));
         this.world = world;
@@ -41,23 +42,23 @@ public class ChunkProviderSeedViewer
     }
 
     @Override
-    public void setCurrentChunkOver(@NotNull ChunkPos chunkPos) {
+    public void setCurrentChunkOver(@NotNull ChunkPosc chunkPos) {
         this.curChunkPos = new ChunkPos(chunkPos);
     }
 
-    public boolean canChunkExist(@NotNull ChunkPos chunkPos) {
+    public boolean canChunkExist(@NotNull ChunkPosc chunkPos) {
         byte r = CHUNK_RADIUS - 1;
-        return chunkPos.x >= this.curChunkPos.x - r && chunkPos.z >= this.curChunkPos.z - r && chunkPos.x <= this.curChunkPos.x + r && chunkPos.z <= this.curChunkPos.z + r;
+        return chunkPos.x() >= this.curChunkPos.x - r && chunkPos.z() >= this.curChunkPos.z - r && chunkPos.x() <= this.curChunkPos.x + r && chunkPos.z() <= this.curChunkPos.z + r;
     }
 
     @Override
-    public void regenerateChunk(@NotNull ChunkPos chunkPos) {
-        int cx = chunkPos.x & CHUNK_MASK;
-        int cz = chunkPos.z & CHUNK_MASK;
+    public void regenerateChunk(@NotNull ChunkPosc chunkPos) {
+        int cx = chunkPos.x() & CHUNK_MASK;
+        int cz = chunkPos.z() & CHUNK_MASK;
         int index = cx + cz * CHUNK_RADIUS * 2;
         Chunk newChunk;
         if (this.chunkGenerator != null) {
-            newChunk = this.chunkGenerator.generate(chunkPos.x, chunkPos.z);
+            newChunk = this.chunkGenerator.generate(chunkPos.x(), chunkPos.z());
             newChunk.fixMissingBlocks();
         } else {
             return;
@@ -79,35 +80,35 @@ public class ChunkProviderSeedViewer
     }
 
     @Override
-    public boolean isChunkLoaded(@NotNull ChunkPos chunkPos) {
+    public boolean isChunkLoaded(@NotNull ChunkPosc chunkPos) {
         if (!canChunkExist(chunkPos)) {
             return false;
         }
         if (chunkPos.equals(this.lastQueriedChunkPos) && this.lastQueriedChunk != null) {
             return true;
         } else {
-            int k = chunkPos.x & CHUNK_MASK;
-            int l = chunkPos.z & CHUNK_MASK;
+            int k = chunkPos.x() & CHUNK_MASK;
+            int l = chunkPos.z() & CHUNK_MASK;
             int chunkIndex = k + l * CHUNK_RADIUS * 2;
             return this.chunks[chunkIndex] == this.blankChunk || (this.chunks[chunkIndex] != null && this.chunks[chunkIndex].isAtLocation(chunkPos));
         }
     }
 
     @Override
-    public @NotNull Chunk prepareChunk(@NotNull ChunkPos chunkPos, boolean priority) {
+    public @NotNull Chunk prepareChunk(@NotNull ChunkPosc chunkPos, boolean priority) {
         return provideChunk(chunkPos, true);
     }
 
     @Override
-    public @NotNull Chunk provideChunk(@NotNull ChunkPos chunkPos, boolean priority) {
+    public @NotNull Chunk provideChunk(@NotNull ChunkPosc chunkPos, boolean priority) {
         if (chunkPos.equals(this.lastQueriedChunkPos) && this.lastQueriedChunk != null) {
             return this.lastQueriedChunk;
         }
         if (!this.world.findingSpawnPoint && !canChunkExist(chunkPos)) {
             return this.blankChunk;
         }
-        int cx = chunkPos.x & CHUNK_MASK;
-        int cz = chunkPos.z & CHUNK_MASK;
+        int cx = chunkPos.x() & CHUNK_MASK;
+        int cz = chunkPos.z() & CHUNK_MASK;
         int index = cx + cz * CHUNK_RADIUS * 2;
         if (!isChunkLoaded(chunkPos)) {
             if (this.chunks[index] != null) {
@@ -116,7 +117,7 @@ public class ChunkProviderSeedViewer
             Chunk chunk = loadChunk(chunkPos);
             if (chunk == null) {
                 if (this.chunkGenerator != null) {
-                    chunk = this.chunkGenerator.generate(chunkPos.x, chunkPos.z);
+                    chunk = this.chunkGenerator.generate(chunkPos.x(), chunkPos.z());
                     chunk.fixMissingBlocks();
                 } else {
                     chunk = this.blankChunk;
@@ -142,29 +143,29 @@ public class ChunkProviderSeedViewer
                 this.world.getCurrentWeather().doChunkLoadEffect(this.world, chunk);
             }
         }
-        this.lastQueriedChunkPos = chunkPos;
+        this.lastQueriedChunkPos = new ChunkPos(chunkPos);
         this.lastQueriedChunk = this.chunks[index];
         return this.chunks[index];
     }
 
-    private Chunk loadChunk(@NotNull ChunkPos chunkPos) {
+    private Chunk loadChunk(@NotNull ChunkPosc chunkPos) {
         if (this.chunkLoader == null) {
             return this.blankChunk;
         }
         try {
-            Chunk chunk = this.chunkLoader.loadChunk(this.world, chunkPos.x, chunkPos.z);
+            Chunk chunk = this.chunkLoader.loadChunk(this.world, chunkPos.x(), chunkPos.z());
             if (chunk != null) {
                 chunk.lastSaveTime = this.world.getWorldTime();
             }
             return chunk;
         } catch (Exception exception) {
-            LOGGER.error("Error loading chunk at X:{}, Z:{}", chunkPos.x, chunkPos.x, exception);
+            LOGGER.error("Error loading chunk at X:{}, Z:{}", chunkPos.x(), chunkPos.x(), exception);
         }
         return this.blankChunk;
     }
 
     @Override
-    public void populate(@NotNull ChunkPos chunkPos) {
+    public void populate(@NotNull ChunkPosc chunkPos) {
 
     }
 
diff --git a/util/seed-viewer/src/main/java/org/useless/seedviewer/bta/worldloader/ChunkLoader.java b/util/seed-viewer/src/main/java/org/useless/seedviewer/bta/worldloader/ChunkLoader.java
index 7b257cfa7..c2b441e6a 100644
--- a/util/seed-viewer/src/main/java/org/useless/seedviewer/bta/worldloader/ChunkLoader.java
+++ b/util/seed-viewer/src/main/java/org/useless/seedviewer/bta/worldloader/ChunkLoader.java
@@ -5,37 +5,40 @@ import com.mojang.nbt.tags.CompoundTag;
 import com.mojang.nbt.NbtIo;
 import it.unimi.dsi.fastutil.ints.Int2ObjectArrayMap;
 import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
+import net.minecraft.core.world.Dimension;
 import net.minecraft.core.world.ProgressListener;
 import net.minecraft.core.world.World;
 import net.minecraft.core.world.chunk.Chunk;
 import net.minecraft.core.world.chunk.ChunkLoaderLegacy;
 import net.minecraft.core.world.chunk.EmptyChunk;
-import net.minecraft.core.world.chunk.provider.IChunkProvider;
+import net.minecraft.core.world.chunk.provider.ChunkProvider;
 import net.minecraft.core.world.chunk.reader.*;
 import net.minecraft.core.world.pos.ChunkPos;
+import net.minecraft.core.world.pos.ChunkPosc;
+import net.minecraft.core.world.save.LevelStorageDummy;
 import net.minecraft.core.world.save.mcregion.RegionFileCache;
-import net.minecraft.core.world.type.WorldTypes;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 import org.slf4j.Logger;
+import org.useless.seedviewer.bta.DummyWorld;
 
 import java.io.DataInputStream;
 import java.io.File;
 import java.io.IOException;
+import java.lang.reflect.Field;
 import java.util.Arrays;
 
-public class ChunkLoader implements IChunkProvider {
+public class ChunkLoader implements ChunkProvider {
     private static final Logger LOGGER = LogUtils.getLogger();
     private final @NotNull World dummyWorld;
     private final @NotNull Chunk empty;
 
 
     private final File dimensionDir;
-    public ChunkLoader(File worldFolder, int dimension) {
-        this.dimensionDir = new File(worldFolder, "dimensions/" + dimension);
-        this.dummyWorld = new World();
-        this.dummyWorld.worldType = WorldTypes.OVERWORLD_EXTENDED;
-        this.dummyWorld.chunkProvider = this;
+    public ChunkLoader(File worldFolder, Dimension dimension) {
+        this.dimensionDir = new File(worldFolder, "dimensions/" + dimension.id);
+        DummyWorld.CHUNK_LOADER = this;
+        this.dummyWorld = new DummyWorld(dimension);
         this.empty = new EmptyChunk(this.dummyWorld, 0, 0);
     }
 
@@ -58,8 +61,8 @@ public class ChunkLoader implements IChunkProvider {
         return tag.containsKey("Level");
     }
 
-    public Chunk loadChunk(ChunkPos location) throws IOException {
-        DataInputStream regionStream = RegionFileCache.getChunkInputStream(this.dimensionDir, location.x, location.z);
+    public @Nullable Chunk loadChunk(ChunkPosc location) throws IOException {
+        DataInputStream regionStream = RegionFileCache.getChunkInputStream(this.dimensionDir, location.x(), location.z());
         CompoundTag tag;
         if(regionStream != null)
         {
@@ -71,7 +74,7 @@ public class ChunkLoader implements IChunkProvider {
         }
         if(!tag.containsKey("Level"))
         {
-            LOGGER.error("Chunk file at {},{} is missing level data, skipping", location.x, location.z);
+            LOGGER.error("Chunk file at {},{} is missing level data, skipping", location.x(), location.z());
             return null;
         }
         return loadChunkFromCompound(tag.getCompound("Level"));
@@ -130,12 +133,12 @@ public class ChunkLoader implements IChunkProvider {
     }
 
     @Override
-    public boolean isChunkLoaded(@NotNull ChunkPos chunkPos) {
+    public boolean isChunkLoaded(@NotNull ChunkPosc chunkPos) {
         return false;
     }
 
     @Override
-    public @NotNull Chunk provideChunk(@NotNull ChunkPos chunkPos, boolean priority) {
+    public @NotNull Chunk provideChunk(@NotNull ChunkPosc chunkPos, boolean priority) {
         try {
             return loadChunk(chunkPos);
         } catch (IOException e) {
@@ -144,17 +147,17 @@ public class ChunkLoader implements IChunkProvider {
     }
 
     @Override
-    public @NotNull Chunk prepareChunk(@NotNull ChunkPos chunkPos, boolean priority) {
+    public @NotNull Chunk prepareChunk(@NotNull ChunkPosc chunkPos, boolean priority) {
         return provideChunk(chunkPos, true);
     }
 
     @Override
-    public void regenerateChunk(@NotNull ChunkPos chunkPos) {
+    public void regenerateChunk(@NotNull ChunkPosc chunkPos) {
 
     }
 
     @Override
-    public void populate(@NotNull ChunkPos chunkPos) {
+    public void populate(@NotNull ChunkPosc chunkPos) {
 
     }
 
@@ -184,7 +187,7 @@ public class ChunkLoader implements IChunkProvider {
     }
 
     @Override
-    public void setCurrentChunkOver(@NotNull ChunkPos chunkPos) {
+    public void setCurrentChunkOver(@NotNull ChunkPosc chunkPos) {
 
     }
 }
diff --git a/util/seed-viewer/src/main/java/org/useless/seedviewer/bta/worldloader/DimensionDataLoader.java b/util/seed-viewer/src/main/java/org/useless/seedviewer/bta/worldloader/DimensionDataLoader.java
index cc8069d74..e3d1e1cf7 100644
--- a/util/seed-viewer/src/main/java/org/useless/seedviewer/bta/worldloader/DimensionDataLoader.java
+++ b/util/seed-viewer/src/main/java/org/useless/seedviewer/bta/worldloader/DimensionDataLoader.java
@@ -3,6 +3,7 @@ package org.useless.seedviewer.bta.worldloader;
 import com.mojang.logging.LogUtils;
 import com.mojang.nbt.tags.CompoundTag;
 import com.mojang.nbt.NbtIo;
+import net.minecraft.core.world.Dimension;
 import net.minecraft.core.world.save.DimensionData;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
@@ -15,22 +16,22 @@ import java.util.Objects;
 public class DimensionDataLoader {
     private static final Logger LOGGER = LogUtils.getLogger();
     @Nullable
-    public static DimensionData getDimensionData(@NotNull File worldDir, int dimensionId) {
+    public static DimensionData getDimensionData(@NotNull File worldDir, @NotNull Dimension dimension) {
         Objects.requireNonNull(worldDir, "WorldDir must not be null!");
-        CompoundTag tag = getDimensionDataRaw(worldDir, dimensionId);
+        CompoundTag tag = getDimensionDataRaw(worldDir, dimension);
         if (tag == null) return null;
-        return new DimensionData(tag);
+        return DimensionData.fromCompoundTag(tag, dimension);
     }
 
     @Nullable
-    public static CompoundTag getDimensionDataRaw(@NotNull File worldDir, int dimensionId)
+    public static CompoundTag getDimensionDataRaw(@NotNull File worldDir, @NotNull Dimension dimension)
     {
         if(!worldDir.exists())
         {
             return null;
         }
         File dimensionsDir = new File(worldDir, "dimensions");
-        File dimensionDir = new File(dimensionsDir, "" + dimensionId);
+        File dimensionDir = new File(dimensionsDir, "" + dimension.id);
         File dimensionDat = new File(dimensionDir, "dimension.dat");
         if (dimensionDat.exists())
         {
@@ -41,7 +42,7 @@ public class DimensionDataLoader {
             }
             catch (Exception ex)
             {
-                LOGGER.error("Error parsing 'dimension.dat' in '{}' dimension {}", worldDir, dimensionId, ex);
+                LOGGER.error("Error parsing 'dimension.dat' in '{}' dimension {}", worldDir, dimension, ex);
             }
         }
         dimensionDat = new File(dimensionDir, "dimension.dat_old");
@@ -54,7 +55,7 @@ public class DimensionDataLoader {
             }
             catch (Exception ex)
             {
-                LOGGER.error("Error parsing 'dimension.dat_old' in '{}' dimension {}", worldDir, dimensionId, ex);
+                LOGGER.error("Error parsing 'dimension.dat_old' in '{}' dimension {}", worldDir, dimension, ex);
             }
         }
 
diff --git a/util/seed-viewer/src/main/java/org/useless/seedviewer/bta/worldloader/LevelDataLoader.java b/util/seed-viewer/src/main/java/org/useless/seedviewer/bta/worldloader/LevelDataLoader.java
index a80c5f5c5..3a7d15cff 100644
--- a/util/seed-viewer/src/main/java/org/useless/seedviewer/bta/worldloader/LevelDataLoader.java
+++ b/util/seed-viewer/src/main/java/org/useless/seedviewer/bta/worldloader/LevelDataLoader.java
@@ -21,7 +21,7 @@ public class LevelDataLoader {
         Objects.requireNonNull(worldDir, "WorldDir must not be null!");
         CompoundTag tag = getLevelDataRaw(worldDir);
         if (tag == null) return null;
-        return new LevelData(tag);
+        return LevelData.fromCompoundTag(tag);
     }
 
     @Nullable
