diff --git a/game/client/build.gradle.kts b/game/client/build.gradle.kts
index c3617418e..5e85d1edc 100644
--- a/game/client/build.gradle.kts
+++ b/game/client/build.gradle.kts
@@ -37,6 +37,7 @@ dependencies {
 
     // <core dependencies>
     implementation(libs.jetbrains.annotations)?.let { include(it) }
+    implementation(libs.fastutil)?.let { include(it) }
     implementation(libs.gson)?.let { include(it) }
     implementation(libs.brigadier)?.let { include(it) }
     implementation(libs.bundles.log4j)?.let { include(it) }
diff --git a/game/client/src/main/java/net/minecraft/client/GLAllocation.java b/game/client/src/main/java/net/minecraft/client/GLAllocation.java
index a7ba78a94..167988eb1 100644
--- a/game/client/src/main/java/net/minecraft/client/GLAllocation.java
+++ b/game/client/src/main/java/net/minecraft/client/GLAllocation.java
@@ -3,12 +3,15 @@ package net.minecraft.client;
 import java.nio.*;
 import java.util.ArrayList;
 import java.util.List;
+
+import it.unimi.dsi.fastutil.ints.IntArrayList;
+import it.unimi.dsi.fastutil.ints.IntList;
 import org.lwjgl.opengl.GL11;
 
 public class GLAllocation {
 
-	public static List<Integer> displayLists = new ArrayList<>();
-	public static List<Integer> textureNames = new ArrayList<>();
+	public static IntList displayLists = new IntArrayList();
+	public static IntList textureNames = new IntArrayList();
 
 	public GLAllocation() {}
 
@@ -22,7 +25,7 @@ public class GLAllocation {
 	public static synchronized void generateTextureNames(IntBuffer intbuffer) {
 		GL11.glGenTextures(intbuffer);
 		for (int i = intbuffer.position(); i < intbuffer.limit(); i++) {
-			textureNames.add(Integer.valueOf(intbuffer.get(i)));
+			textureNames.add(intbuffer.get(i));
 		}
 
 	}
@@ -36,8 +39,8 @@ public class GLAllocation {
 	public static synchronized void deleteTexture(int tex) {
 		GL11.glDeleteTextures(tex);
 		for (int i = 0; i < textureNames.size(); i++) {
-			if (textureNames.get(i) == tex) {
-				textureNames.remove(i);
+			if (textureNames.getInt(i) == tex) {
+				textureNames.removeInt(i);
 				return;
 			}
 		}
@@ -47,14 +50,14 @@ public class GLAllocation {
 	{
 		int displayListIndex = displayLists.indexOf(displayList);
 		if (displayListIndex < 0) return;
-		GL11.glDeleteLists(displayLists.get(displayListIndex), displayLists.get(displayListIndex + 1));
-		displayLists.remove(displayListIndex);
-		displayLists.remove(displayListIndex);
+		GL11.glDeleteLists(displayLists.getInt(displayListIndex), displayLists.getInt(displayListIndex + 1));
+		displayLists.removeInt(displayListIndex);
+		displayLists.removeInt(displayListIndex);
 	}
 
 	public static synchronized void deleteTexturesAndDisplayLists() {
 		for (int i = 0; i < displayLists.size(); i += 2) {
-			GL11.glDeleteLists(displayLists.get(i), displayLists.get(i + 1));
+			GL11.glDeleteLists(displayLists.getInt(i), displayLists.getInt(i + 1));
 		}
 
 		IntBuffer intbuffer = createDirectIntBuffer(textureNames.size());
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 b48af2805..42c494a26 100644
--- a/game/client/src/main/java/net/minecraft/client/Minecraft.java
+++ b/game/client/src/main/java/net/minecraft/client/Minecraft.java
@@ -14,6 +14,9 @@ import java.util.*;
 
 import com.mojang.logging.LogUtils;
 import com.mojang.nbt.tags.CompoundTag;
+import it.unimi.dsi.fastutil.objects.Object2IntMap;
+import it.unimi.dsi.fastutil.objects.Object2LongLinkedOpenHashMap;
+import it.unimi.dsi.fastutil.objects.Object2LongMap;
 import net.minecraft.client.console.LogMessageReceiver;
 import net.minecraft.client.console.shell.BindManager;
 import net.minecraft.client.entity.ClientSkinVariantList;
@@ -375,7 +378,7 @@ public class Minecraft
 			running = false;
 
 			LOGGER.error("An exception has occurred while trying to start the game!", throwable.exception);
-			
+
 			gameWindow.displayCrashReport(throwable, 1);
 			hasCrashed = true;
 			shutdownMinecraftApplet();
@@ -387,7 +390,7 @@ public class Minecraft
 			running = false;
 
             LOGGER.error("An exception has occurred while trying to start the game!", throwable.exception);
-			
+
 			gameWindow.displayCrashReport(throwable, 1);
 			hasCrashed = true;
 			shutdownMinecraftApplet();
@@ -398,7 +401,7 @@ public class Minecraft
 			running = false;
 
             LOGGER.error("An exception has occurred while trying to start the game!", throwable.exception);
-			
+
 			gameWindow.displayCrashReport(throwable, 2);
 			shutdownMinecraftApplet();
 			return;
@@ -487,7 +490,7 @@ public class Minecraft
         LOGGER.info("Java Version: {}", System.getProperty("java.version"));
 
 		printWrongJavaVersionInfo();
-		
+
 		gameWindow.init(this, overrideWidth != null ? overrideWidth : gameSettings.windowWidth.value, overrideHeight != null ? overrideHeight : gameSettings.windowHeight.value);
 
         final @Nullable String vendorString = GL11.glGetString(GL_VENDOR);
@@ -588,7 +591,7 @@ public class Minecraft
         loadScreen();	// Update loading screen so it doesn't say no response
         
         Colorizers.init(this);
-        
+
         textureManager.refreshTextures(new ArrayList<>());
 
         OptionsPages.init();
@@ -1087,7 +1090,7 @@ public class Minecraft
                     
                     Debug.change("render"); // 2
                     Debug.push("post"); // 3
-                    
+
                     renderer.beginRenderGame(timer.partialTicks);
                     glEnable(GL_ALPHA_TEST);
 
@@ -1563,9 +1566,9 @@ public class Minecraft
                         	step += MathHelper.clamp(scrollDelta, -1, 1);
                         	float newSpeed = step / steps;
                         	newSpeed = MathHelper.clamp(newSpeed, 0.0f, 5.0f);
-                        	
+
                         	gameSettings.flightSpeed.value = newSpeed;
-                        	
+
                         	thePlayer.setFlySpeed(newSpeed);
                         	hudIngame.heldItemTooltipElement.setOptionNameAndValueString(gameSettings.flightSpeed);
                         }
@@ -2349,7 +2352,7 @@ public class Minecraft
     {
     	mainMenuBackground.deleteTextures();
     	gameSettings.showCollisionBoxes.value = false;
-    	
+
         fullbright = false;
         statsCounter.fetchStats();
         statsCounter.saveStats();
@@ -2866,8 +2869,8 @@ public class Minecraft
     }
 
     private static class TimeKeeper {
-        private final @NotNull Map<@NotNull String, @NotNull Long> startTimes = new LinkedHashMap<>();
-        private final @NotNull Map<@NotNull String, @NotNull Long> endTimes = new LinkedHashMap<>();
+        private final @NotNull Object2LongMap<@NotNull String> startTimes = new Object2LongLinkedOpenHashMap<>();
+        private final @NotNull Object2LongMap<@NotNull String> endTimes = new Object2LongLinkedOpenHashMap<>();
 
         public void start(final @NotNull String key) {
             if (this.startTimes.containsKey(key)) LOGGER.error("Start key {} already assigned", key);
@@ -2887,9 +2890,8 @@ public class Minecraft
                     LOGGER.error("Perf key {} not ended!", s);
                     continue;
                 }
-                final Long start = this.startTimes.get(s);
-                final Long end = this.endTimes.get(s);
-                if (start == null || end == null) continue;
+                final long start = this.startTimes.getLong(s);
+                final long end = this.endTimes.getLong(s);
                 builder.append("\n\t").append(s).append(": ").append((end - start)/1000d).append("s");
             }
             return builder.toString();
diff --git a/game/client/src/main/java/net/minecraft/client/console/shell/BindManager.java b/game/client/src/main/java/net/minecraft/client/console/shell/BindManager.java
index aed2a30c3..7b83fa1e8 100644
--- a/game/client/src/main/java/net/minecraft/client/console/shell/BindManager.java
+++ b/game/client/src/main/java/net/minecraft/client/console/shell/BindManager.java
@@ -1,5 +1,8 @@
 package net.minecraft.client.console.shell;
 
+import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
+import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
+import it.unimi.dsi.fastutil.ints.IntCollection;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 
@@ -13,9 +16,9 @@ public final class BindManager {
         return INSTANCE;
     }
 
-    private @NotNull Map<@NotNull Integer, @NotNull Runnable> keyToRunnableMap = new HashMap<>();
+    private @NotNull Int2ObjectMap<@NotNull Runnable> keyToRunnableMap = new Int2ObjectOpenHashMap<>();
 
-    public @NotNull Collection<@NotNull Integer> getKeys() {
+    public @NotNull IntCollection getKeys() {
         return this.keyToRunnableMap.keySet();
     }
 
diff --git a/game/client/src/main/java/net/minecraft/client/entity/ClientSkinVariantList.java b/game/client/src/main/java/net/minecraft/client/entity/ClientSkinVariantList.java
index 086c36f1f..a3720b658 100644
--- a/game/client/src/main/java/net/minecraft/client/entity/ClientSkinVariantList.java
+++ b/game/client/src/main/java/net/minecraft/client/entity/ClientSkinVariantList.java
@@ -15,6 +15,8 @@ import com.google.gson.JsonObject;
 import com.google.gson.JsonParseException;
 import com.google.gson.JsonParser;
 import com.mojang.logging.LogUtils;
+import it.unimi.dsi.fastutil.objects.Object2IntMap;
+import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap;
 import net.minecraft.client.Minecraft;
 import net.minecraft.core.entity.SkinVariantList;
 import net.minecraft.core.util.helper.MathHelper;
@@ -162,10 +164,10 @@ public class ClientSkinVariantList extends SkinVariantList {
 			}
 
 
-			final Map<String, Integer> counts = new HashMap<>();
+			final Object2IntMap<String> counts = new Object2IntOpenHashMap<>();
 			for (final VariantEntry e : this.variantEntries) {
 				counts.putIfAbsent(e.textureKey, 0);
-				counts.put(e.textureKey, counts.get(e.textureKey) + 1);
+				counts.put(e.textureKey, counts.getInt(e.textureKey) + 1);
 			}
 		}
 
diff --git a/game/client/src/main/java/net/minecraft/client/gui/ScreenTextureViewer.java b/game/client/src/main/java/net/minecraft/client/gui/ScreenTextureViewer.java
index 58517d278..eb120d727 100644
--- a/game/client/src/main/java/net/minecraft/client/gui/ScreenTextureViewer.java
+++ b/game/client/src/main/java/net/minecraft/client/gui/ScreenTextureViewer.java
@@ -1,5 +1,6 @@
 package net.minecraft.client.gui;
 
+import it.unimi.dsi.fastutil.ints.IntList;
 import net.minecraft.client.GLAllocation;
 import net.minecraft.client.gui.modelviewer.elements.ListenerButtonElement;
 import net.minecraft.client.gui.modelviewer.elements.IListenerElement;
@@ -107,7 +108,7 @@ public class ScreenTextureViewer extends Screen {
     }
 
     protected void cycleTexture(int offset) {
-        List<Integer> textureList = GLAllocation.textureNames;
+        IntList textureList = GLAllocation.textureNames;
         texIndex += offset;
         if (texIndex < 0) {
             texIndex += textureList.size();
@@ -120,11 +121,11 @@ public class ScreenTextureViewer extends Screen {
 
         drawStringCenteredNoShadow(fontRenderer, I18n.getInstance().translateKey("gui.texture_viewer.label.title"), width/2, 5, 0xFFFFFF);
 
-        List<Integer> textureList = GLAllocation.textureNames;
+        IntList textureList = GLAllocation.textureNames;
         int id = texIndex % textureList.size();
-        GL11.glBindTexture(GL_TEXTURE_2D, textureList.get(id));
+        GL11.glBindTexture(GL_TEXTURE_2D, textureList.getInt(id));
 
-        Texture t = mc.textureManager.idToTextureMap.get(textureList.get(id));
+        Texture t = mc.textureManager.idToTextureMap.get(textureList.getInt(id));
 
 
         GL11.glEnable(GL_BLEND);
@@ -157,7 +158,7 @@ public class ScreenTextureViewer extends Screen {
             tessellator.draw();
         }
 
-        GL11.glBindTexture(GL_TEXTURE_2D, textureList.get(id));
+        GL11.glBindTexture(GL_TEXTURE_2D, textureList.getInt(id));
         tessellator.startDrawingQuads();
         if (flip) {
             tessellator.addVertexWithUV(x + 0,          y + imgHeight,  zLevel, 0, 0);
diff --git a/game/client/src/main/java/net/minecraft/client/gui/chat/GuiElementChatSuggestions.java b/game/client/src/main/java/net/minecraft/client/gui/chat/GuiElementChatSuggestions.java
index 89cc167c3..5c5b54947 100644
--- a/game/client/src/main/java/net/minecraft/client/gui/chat/GuiElementChatSuggestions.java
+++ b/game/client/src/main/java/net/minecraft/client/gui/chat/GuiElementChatSuggestions.java
@@ -40,6 +40,7 @@ import java.util.List;
 import java.util.Locale;
 import java.util.Map;
 import java.util.Optional;
+import java.util.OptionalInt;
 import java.util.concurrent.CompletableFuture;
 
 @SuppressWarnings({"OptionalGetWithoutIsPresent", "unused"})
@@ -161,7 +162,7 @@ public class GuiElementChatSuggestions extends Gui {
             String suggestionText = this.suggestions.get(i + this.scroll).getText();
             int suggestionHeight = 12 * (-i + Math.min(this.suggestions.size(), MAX_SUGGESTIONS) - 2) + 25;
             String colorCode;
-            if (i + this.scroll == this.commandIndex || (this.isHoveringOverSuggestions(mouseX, mouseY) && i + this.scroll == this.getIndexOfSuggestionBeingHoveredOver(mouseX, mouseY).get())) {
+            if (i + this.scroll == this.commandIndex || (this.isHoveringOverSuggestions(mouseX, mouseY) && i + this.scroll == this.getIndexOfSuggestionBeingHoveredOver(mouseX, mouseY).getAsInt())) {
                 colorCode = TextFormatting.YELLOW.toString();
             } else {
                 colorCode = TextFormatting.LIGHT_GRAY.toString();
@@ -172,8 +173,8 @@ public class GuiElementChatSuggestions extends Gui {
             fontRenderer.render(Tessellator.instance, colorCode + suggestionText, textX, minY + suggestionBoxHeight - suggestionHeight + 3).setShadow().setColor(0xE0E0E0).call();
         }
 
-        if (this.isHoveringOverSuggestions(mouseX, mouseY) && this.suggestions.get(this.getIndexOfSuggestionBeingHoveredOver(mouseX, mouseY).get()).getTooltip() != null) {
-            this.tooltip.render(this.suggestions.get(this.getIndexOfSuggestionBeingHoveredOver(mouseX, mouseY).get()).getTooltip().getString(), mouseX, mouseY, 0, 0);
+        if (this.isHoveringOverSuggestions(mouseX, mouseY) && this.suggestions.get(this.getIndexOfSuggestionBeingHoveredOver(mouseX, mouseY).getAsInt()).getTooltip() != null) {
+            this.tooltip.render(this.suggestions.get(this.getIndexOfSuggestionBeingHoveredOver(mouseX, mouseY).getAsInt()).getTooltip().getString(), mouseX, mouseY, 0, 0);
         }
     }
 
@@ -208,7 +209,7 @@ public class GuiElementChatSuggestions extends Gui {
 
         if (key == Keyboard.KEY_TAB) {
             if (this.commandIndex == -1 && this.isHoveringOverSuggestions(mouseX, mouseY)) {
-                this.cycleToSuggestion(this.getIndexOfSuggestionBeingHoveredOver(mouseX, mouseY).get());
+                this.cycleToSuggestion(this.getIndexOfSuggestionBeingHoveredOver(mouseX, mouseY).getAsInt());
             } else if (Keyboard.isKeyDown(Keyboard.KEY_LSHIFT)) {
                 this.cycleThroughSuggestions(-1);
             } else {
@@ -331,7 +332,7 @@ public class GuiElementChatSuggestions extends Gui {
 
     public void mouseClicked(int x, int y, int button) {
         if (isHoveringOverSuggestions(x, y) && button == 0) {
-            this.cycleToSuggestion(this.getIndexOfSuggestionBeingHoveredOver(x, y).get());
+            this.cycleToSuggestion(this.getIndexOfSuggestionBeingHoveredOver(x, y).getAsInt());
         }
     }
 
@@ -339,8 +340,8 @@ public class GuiElementChatSuggestions extends Gui {
         return this.getIndexOfSuggestionBeingHoveredOver(cursorX, cursorY).isPresent();
     }
 
-    public Optional<Integer> getIndexOfSuggestionBeingHoveredOver(int cursorX, int cursorY) {
-        if (this.suggestions.isEmpty() || this.hidden) return Optional.empty();
+    public OptionalInt getIndexOfSuggestionBeingHoveredOver(int cursorX, int cursorY) {
+        if (this.suggestions.isEmpty() || this.hidden) return OptionalInt.empty();
 
         int minX = this.xSupplier.get(this.textField, this, this.mc, SUGGESTIONS_FOLLOW_PARAMETERS);
 
@@ -363,10 +364,10 @@ public class GuiElementChatSuggestions extends Gui {
             int suggestionMaxY = suggestionMinY + 12;
 
             if (cursorX >= minX && cursorX < maxX && cursorY >= suggestionMinY && cursorY < suggestionMaxY) {
-                return Optional.of(i + this.scroll);
+                return OptionalInt.of(i + this.scroll);
             }
         }
-        return Optional.empty();
+        return OptionalInt.empty();
     }
 
     private void resetAllManagerVariables() {
@@ -522,7 +523,7 @@ public class GuiElementChatSuggestions extends Gui {
         if (this.shouldDrawSuggestionPreview()) {
             Suggestion suggestionToRender = null;
             if (this.isHoveringOverSuggestions(mouseX, mouseY)) {
-                suggestionToRender = this.getSuggestions().get(this.getIndexOfSuggestionBeingHoveredOver(mouseX, mouseY).get());
+                suggestionToRender = this.getSuggestions().get(this.getIndexOfSuggestionBeingHoveredOver(mouseX, mouseY).getAsInt());
             } else if (!this.getSuggestions().isEmpty()) {
                 suggestionToRender = this.getSuggestions().get(0);
             }
diff --git a/game/client/src/main/java/net/minecraft/client/gui/container/ScreenInventory.java b/game/client/src/main/java/net/minecraft/client/gui/container/ScreenInventory.java
index 135f6ff11..7a1aba857 100644
--- a/game/client/src/main/java/net/minecraft/client/gui/container/ScreenInventory.java
+++ b/game/client/src/main/java/net/minecraft/client/gui/container/ScreenInventory.java
@@ -5,6 +5,8 @@ import static org.lwjgl.opengl.GL11.*;
 import java.util.ArrayList;
 import java.util.List;
 
+import it.unimi.dsi.fastutil.ints.IntArrayList;
+import it.unimi.dsi.fastutil.ints.IntList;
 import net.minecraft.client.gui.ButtonElement;
 import net.minecraft.client.gui.GuiElement;
 import net.minecraft.client.gui.ListLayout;
@@ -37,7 +39,7 @@ public class ScreenInventory extends ScreenContainerAbstract
     protected int armourValuesFloat = 130;
     protected int armourButtonFloatX = 20;
 	protected ListLayout overlayButtonsLayout = new ListLayout(this).setAlign(0.5, 0.5).setVertical(false).setElementSize(11, 11).setOffset(-(xSize / 2), -(ySize / 2) - 10).setMargin(1);
-	private final List<Integer> uvs = new ArrayList<>();
+	private final IntList uvs = new IntArrayList();
 	
 	private DamageType hoveredDamageType;
 
@@ -171,7 +173,7 @@ public class ScreenInventory extends ScreenContainerAbstract
         
         for(int i=0; i < overlayButtonsLayout.elements.size(); i++) {
         	OverlayButtonElement<?> button = (OverlayButtonElement<?>) overlayButtonsLayout.elements.get(i);
-        	drawTexturedModalRect(button.xPosition + 1, button.yPosition + 1, 176, 9 + 9 * uvs.get(i), 9, 9);
+        	drawTexturedModalRect(button.xPosition + 1, button.yPosition + 1, 176, 9 + 9 * uvs.getInt(i), 9, 9);
         	boolean val = true;
         	if(button.option instanceof OptionBoolean) val = (Boolean) button.option.value;
         	if(!val) drawTexturedModalRect(button.xPosition + 1, button.yPosition + 1, 194, 0, 9, 9);
diff --git a/game/client/src/main/java/net/minecraft/client/gui/drawing/DrawableEditor.java b/game/client/src/main/java/net/minecraft/client/gui/drawing/DrawableEditor.java
index f6370c2c3..5273464f8 100644
--- a/game/client/src/main/java/net/minecraft/client/gui/drawing/DrawableEditor.java
+++ b/game/client/src/main/java/net/minecraft/client/gui/drawing/DrawableEditor.java
@@ -1,5 +1,6 @@
 package net.minecraft.client.gui.drawing;
 
+import it.unimi.dsi.fastutil.ints.IntIntPair;
 import net.minecraft.core.util.collection.Pair;
 
 import java.util.Stack;
@@ -230,21 +231,22 @@ public final class DrawableEditor<T>
 
     public void floodFill(int x, int y, T value)
     {
-        Stack<Pair<Integer, Integer>> floodFillStack = new Stack<>();
+        Stack<IntIntPair> floodFillStack = new Stack<>();
         T floodColor = surface.getPixelValue(x, y);
         if (floodColor == value) return;
 
-        floodFillStack.push(Pair.of(x, y));
+        floodFillStack.push(IntIntPair.of(x, y));
         while (!floodFillStack.isEmpty())
         {
-            Pair<Integer, Integer> item = floodFillStack.pop();
-            if (surface.getPixelValue(item.getLeft(), item.getRight()) == floodColor)
+
+            IntIntPair item = floodFillStack.pop();
+            if (surface.getPixelValue(item.leftInt(), item.rightInt()) == floodColor)
             {
-                drawPixel(item.getLeft(), item.getRight(), value);
-                if (item.getLeft() - 1 >= 0) floodFillStack.push(Pair.of(item.getLeft() - 1, item.getRight()));
-                if (item.getLeft() + 1 < surface.getWidth()) floodFillStack.push(Pair.of(item.getLeft() + 1, item.getRight()));
-                if (item.getRight() - 1 >= 0) floodFillStack.push(Pair.of(item.getLeft(), item.getRight() - 1));
-                if (item.getRight() + 1 < surface.getHeight()) floodFillStack.push(Pair.of(item.getLeft(), item.getRight() + 1));
+                drawPixel(item.leftInt(), item.rightInt(), value);
+                if (item.leftInt() - 1 >= 0) floodFillStack.push(IntIntPair.of(item.leftInt() - 1, item.rightInt()));
+                if (item.leftInt() + 1 < surface.getWidth()) floodFillStack.push(IntIntPair.of(item.leftInt() + 1, item.rightInt()));
+                if (item.rightInt() - 1 >= 0) floodFillStack.push(IntIntPair.of(item.leftInt(), item.rightInt() - 1));
+                if (item.rightInt() + 1 < surface.getHeight()) floodFillStack.push(IntIntPair.of(item.leftInt(), item.rightInt() + 1));
             }
         }
     }
diff --git a/game/client/src/main/java/net/minecraft/client/gui/guidebook/PageNavigationStack.java b/game/client/src/main/java/net/minecraft/client/gui/guidebook/PageNavigationStack.java
index 68aa577a0..580d764b6 100644
--- a/game/client/src/main/java/net/minecraft/client/gui/guidebook/PageNavigationStack.java
+++ b/game/client/src/main/java/net/minecraft/client/gui/guidebook/PageNavigationStack.java
@@ -1,6 +1,7 @@
 package net.minecraft.client.gui.guidebook;
 
 import com.mojang.logging.LogUtils;
+import it.unimi.dsi.fastutil.ints.IntStack;
 import org.slf4j.Logger;
 
 import java.util.Stack;
diff --git a/game/client/src/main/java/net/minecraft/client/gui/hud/HudIngameDoom.java b/game/client/src/main/java/net/minecraft/client/gui/hud/HudIngameDoom.java
index 309b28ca1..9e547dbc7 100644
--- a/game/client/src/main/java/net/minecraft/client/gui/hud/HudIngameDoom.java
+++ b/game/client/src/main/java/net/minecraft/client/gui/hud/HudIngameDoom.java
@@ -1,5 +1,7 @@
 package net.minecraft.client.gui.hud;
 
+import it.unimi.dsi.fastutil.ints.IntArrayList;
+import it.unimi.dsi.fastutil.ints.IntList;
 import net.minecraft.client.Minecraft;
 import net.minecraft.client.gui.ScreenPhotoMode;
 import net.minecraft.client.render.texture.stitcher.TextureRegistry;
@@ -159,7 +161,7 @@ public class HudIngameDoom
         GL11.glColor4f(1f, 1f, 1f, 1f);
         mc.textureManager.loadTexture("/assets/minecraft/textures/gui/hud/doom.png").bind();
 
-        List<Integer> parts = new ArrayList<>();
+        IntList parts = new IntArrayList();
 
         int prev = 0;
         int mult = 1;
@@ -172,8 +174,8 @@ public class HudIngameDoom
             mult *= 10;
         }
 
-        for (int digit : parts)
-        {
+        for (int j = 0; j < parts.size(); j++) {
+            int digit = parts.getInt(j);
             int width = NUMBER_WIDTHS[digit];
             int u = NUMBER_US[digit];
             int v = 209;
diff --git a/game/client/src/main/java/net/minecraft/client/gui/popup/PopupBuilder.java b/game/client/src/main/java/net/minecraft/client/gui/popup/PopupBuilder.java
index eb93e8ac1..2dd4b7466 100644
--- a/game/client/src/main/java/net/minecraft/client/gui/popup/PopupBuilder.java
+++ b/game/client/src/main/java/net/minecraft/client/gui/popup/PopupBuilder.java
@@ -1,5 +1,6 @@
 package net.minecraft.client.gui.popup;
 
+import it.unimi.dsi.fastutil.ints.IntIntPair;
 import net.minecraft.client.gui.Screen;
 import net.minecraft.core.lang.I18n;
 import net.minecraft.core.util.collection.Pair;
@@ -20,7 +21,7 @@ public class PopupBuilder
     private final List<PopupComponent> components = new ArrayList<>();
     private final Map<PopupComponent, String> componentKeyMap = new HashMap<>();
     private final List<PopupCloseListener> onCloseListeners = new ArrayList<>();
-    private Pair<Integer,Integer> backgroundColor = null;
+    private IntIntPair backgroundColor = null;
 
     public PopupBuilder(Screen parent, int width)
     {
@@ -172,7 +173,7 @@ public class PopupBuilder
     }
 
     public PopupBuilder withBackgroundColor(int color, int color2){
-        this.backgroundColor = Pair.of(color,color2);
+        this.backgroundColor = IntIntPair.of(color,color2);
         return this;
     }
 
diff --git a/game/client/src/main/java/net/minecraft/client/gui/popup/PopupScreen.java b/game/client/src/main/java/net/minecraft/client/gui/popup/PopupScreen.java
index dd77fcaec..29744e003 100644
--- a/game/client/src/main/java/net/minecraft/client/gui/popup/PopupScreen.java
+++ b/game/client/src/main/java/net/minecraft/client/gui/popup/PopupScreen.java
@@ -1,5 +1,6 @@
 package net.minecraft.client.gui.popup;
 
+import it.unimi.dsi.fastutil.ints.IntIntPair;
 import net.minecraft.client.gui.Screen;
 import net.minecraft.client.render.tessellator.Tessellator;
 import net.minecraft.core.util.collection.Pair;
@@ -27,7 +28,7 @@ public final class PopupScreen
     private final Map<PopupComponent, String> componentKeyMap;
     private final List<PopupCloseListener> onCloseListeners;
 
-    private final Pair<Integer,Integer> backgroundColor;
+    private final IntIntPair backgroundColor;
 
     private int statusCode = -1;
 
@@ -41,7 +42,7 @@ public final class PopupScreen
             List<PopupComponent> components,
             Map<PopupComponent, String> componentKeyMap,
             List<PopupCloseListener> onCloseListeners,
-            Pair<Integer,Integer> backgroundColor
+            IntIntPair backgroundColor
     )
     {
         this.parent = parent;
@@ -195,7 +196,7 @@ public final class PopupScreen
             int color = mc.gameSettings.guiBackgroundColor.value.getARGB();
             drawGradientRect(0, 0, width, height, color, color);
         } else {
-            drawGradientRect(0, 0, width, height, backgroundColor.getLeft(), backgroundColor.getRight());
+            drawGradientRect(0, 0, width, height, backgroundColor.leftInt(), backgroundColor.rightInt());
         }
 
 
diff --git a/game/client/src/main/java/net/minecraft/client/input/controller/ControllerTypeDatabase.java b/game/client/src/main/java/net/minecraft/client/input/controller/ControllerTypeDatabase.java
index bb94d9005..998afb471 100644
--- a/game/client/src/main/java/net/minecraft/client/input/controller/ControllerTypeDatabase.java
+++ b/game/client/src/main/java/net/minecraft/client/input/controller/ControllerTypeDatabase.java
@@ -1,13 +1,14 @@
 package net.minecraft.client.input.controller;
 
+import it.unimi.dsi.fastutil.ints.Int2ObjectArrayMap;
+import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
+
 import java.io.BufferedReader;
 import java.io.InputStream;
 import java.io.InputStreamReader;
-import java.util.HashMap;
-import java.util.Map;
 
 public abstract class ControllerTypeDatabase {
-    private static Map<Integer, ControllerType> controllers = null;
+    private static Int2ObjectMap<ControllerType> controllers = null;
 
     public static ControllerType getControllerType(int vid, int pid) {
         int combined = ((vid & 0xFFFF) << 16) | (pid & 0xFFFF);
@@ -18,7 +19,7 @@ public abstract class ControllerTypeDatabase {
     }
 
     private static void init() {
-        controllers = new HashMap<>();
+        controllers = new Int2ObjectArrayMap<>();
 
         // Read controllers.csv
         try (InputStream stream = ControllerTypeDatabase.class.getResourceAsStream("/controllers.csv")) {
diff --git a/game/client/src/main/java/net/minecraft/client/render/FlagRenderer.java b/game/client/src/main/java/net/minecraft/client/render/FlagRenderer.java
index 999c3cdc7..134b3053b 100644
--- a/game/client/src/main/java/net/minecraft/client/render/FlagRenderer.java
+++ b/game/client/src/main/java/net/minecraft/client/render/FlagRenderer.java
@@ -1,5 +1,8 @@
 package net.minecraft.client.render;
 
+import it.unimi.dsi.fastutil.ints.IntArrayList;
+import it.unimi.dsi.fastutil.ints.IntList;
+import it.unimi.dsi.fastutil.objects.ObjectList;
 import net.minecraft.client.GLAllocation;
 import net.minecraft.core.block.entity.TileEntityFlag;
 import net.minecraft.core.item.Items;
@@ -23,7 +26,7 @@ public class FlagRenderer {
 
     private final TextureManager textureManager;
 
-    private final List<Integer> freeTextures = new ArrayList<>();
+    private final IntList freeTextures = new IntArrayList();
     private final List<FlagTextureEntry> flagTextures = new ArrayList<>();
     private final Map<TileEntityFlag, FlagTextureEntry> cache = new Hashtable<>();
     
@@ -109,7 +112,7 @@ public class FlagRenderer {
             if (freeTextures.isEmpty()) {
                 tex = textureManager.createTexture(CANVAS_WIDTH, CANVAS_HEIGHT);
             } else {
-                tex = freeTextures.remove(0);
+                tex = freeTextures.removeInt(0);
             }
             returnEntry = new FlagTextureEntry(tex, flag.colorHash, flag.activeDyes, flag.flagColors);
             flagTextures.add(returnEntry);
@@ -168,8 +171,6 @@ public class FlagRenderer {
             this.colorHash = colorHash;
             this.activeDyes = activeDyes;
             this.colorData = colorData;
-
-
         }
     }
 }
diff --git a/game/client/src/main/java/net/minecraft/client/render/TextureManager.java b/game/client/src/main/java/net/minecraft/client/render/TextureManager.java
index f41b3dc38..738044ccb 100644
--- a/game/client/src/main/java/net/minecraft/client/render/TextureManager.java
+++ b/game/client/src/main/java/net/minecraft/client/render/TextureManager.java
@@ -14,6 +14,8 @@ import java.util.Map;
 import java.util.Objects;
 
 import com.mojang.logging.LogUtils;
+import it.unimi.dsi.fastutil.ints.Int2ObjectArrayMap;
+import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
 import net.minecraft.client.GLAllocation;
 import net.minecraft.client.Minecraft;
 import net.minecraft.client.gui.popup.PopupScreen;
@@ -64,7 +66,7 @@ public class TextureManager {
 
 	public final Minecraft mc;
 
-	public final Map<Integer, Texture> idToTextureMap = new HashMap<>();
+	public final Int2ObjectMap<Texture> idToTextureMap = new Int2ObjectArrayMap<>();
 	public final Map<String, Texture> textureMap = new HashMap<>();
 	public final List<TextureBuffered> bufferedTextures = new ArrayList<>();
 	public final Map<String, TextureDownloaded> downloadedTextures = new HashMap<>();
@@ -267,22 +269,19 @@ public class TextureManager {
 			glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
 			glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
 		}
-		
-		byte[] bytes = new byte[w * h * 4];
+
+		buffer.clear();
 		for (int l = 0; l < imageData.length; l++) {
 			int a = imageData[l] >> 24 & 0xff;
 			int r = imageData[l] >> 16 & 0xff;
 			int g = imageData[l] >> 8 & 0xff;
 			int b = imageData[l] & 0xff;
-			bytes[l * 4] 	 = (byte) r;
-			bytes[l * 4 + 1] = (byte) g;
-			bytes[l * 4 + 2] = (byte) b;
-			bytes[l * 4 + 3] = (byte) a;
+			buffer.put(l * 4, (byte) r);
+			buffer.put(l * 4 + 1, (byte) g);
+			buffer.put(l * 4 + 2, (byte) b);
+			buffer.put(l * 4 + 3, (byte) a);
 		}
-
-		buffer.clear();
-		buffer.put(bytes);
-		buffer.position(0).limit(bytes.length);
+		buffer.position(0).limit(w * h * 4);
 		
 		glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, w, h, GL_RGBA, GL_UNSIGNED_BYTE, buffer);
 	}
diff --git a/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelBrazier.java b/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelBrazier.java
index 48144a44c..aff52d9ca 100644
--- a/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelBrazier.java
+++ b/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelBrazier.java
@@ -17,7 +17,7 @@ public class BlockModelBrazier<T extends BlockLogicBrazier>
     extends BlockModelStandard<T> {
     protected IconCoordinate sideTexture = TextureRegistry.getTexture("minecraft:block/brazier/side");
     protected IconCoordinate baseTexture = TextureRegistry.getTexture("minecraft:block/brazier/base");
-    protected BlockModelStandard<?> fireModel = new BlockModelFire<>(Blocks.FIRE, true).withTextures("minecraft:block/fire");
+    protected BlockModelStandard<?> fireModel = new BlockModelFire<>(Blocks.FIRE, true).setAllTextures(BLOCK_TEXTURES, "minecraft:block/fire");
 
     public BlockModelBrazier(Block<T> block) {
         super(block);
diff --git a/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelWireRedstone.java b/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelWireRedstone.java
index 1664cf66c..4c87b01d4 100644
--- a/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelWireRedstone.java
+++ b/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelWireRedstone.java
@@ -19,7 +19,7 @@ public class BlockModelWireRedstone<T extends BlockLogic> extends BlockModelStan
     protected final IconCoordinate wireCross = TextureRegistry.getTexture("minecraft:block/wire_redstone_cross");
     public BlockModelWireRedstone(Block<T> block) {
         super(block);
-        withTextures("minecraft:block/wire_redstone_cross");
+        setAllTextures(BLOCK_TEXTURES, "minecraft:block/wire_redstone_cross");
     }
 
     @Override
diff --git a/game/client/src/main/java/net/minecraft/client/render/customatlas/Atlas.java b/game/client/src/main/java/net/minecraft/client/render/customatlas/Atlas.java
index 81e5bded3..353a19cb9 100644
--- a/game/client/src/main/java/net/minecraft/client/render/customatlas/Atlas.java
+++ b/game/client/src/main/java/net/minecraft/client/render/customatlas/Atlas.java
@@ -1,5 +1,7 @@
 package net.minecraft.client.render.customatlas;
 
+import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
+import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
 import org.jetbrains.annotations.NotNull;
 
 import java.io.BufferedReader;
@@ -46,7 +48,7 @@ public class Atlas {
 	public static Atlas read(final InputStream in) {
 		final Atlas atlas = new Atlas();
 		
-		final Map<Integer, AtlasTile> map = new HashMap<>();
+		final Int2ObjectMap<AtlasTile> map = new Int2ObjectOpenHashMap<>();
 		
 		BufferedReader br = null;
 		try {
diff --git a/game/client/src/main/java/net/minecraft/client/render/shader/Shader.java b/game/client/src/main/java/net/minecraft/client/render/shader/Shader.java
index 5def25de5..ef49ea328 100644
--- a/game/client/src/main/java/net/minecraft/client/render/shader/Shader.java
+++ b/game/client/src/main/java/net/minecraft/client/render/shader/Shader.java
@@ -6,6 +6,8 @@ import java.util.HashMap;
 import java.util.Map;
 
 import com.mojang.logging.LogUtils;
+import it.unimi.dsi.fastutil.objects.Object2IntArrayMap;
+import it.unimi.dsi.fastutil.objects.Object2IntMap;
 import net.minecraft.client.render.OpenGLHelper;
 import org.slf4j.Logger;
 
@@ -18,7 +20,7 @@ public class Shader {
 	
 	private boolean enabled = false;
 	
-	private final Map<String, Integer> uniformLocations = new HashMap<>();
+	private final Object2IntMap<String> uniformLocations = new Object2IntArrayMap<>();
 	
 	public Shader compile(ShaderProvider folder, String name) {
 		if(name == null) throw new NullPointerException();
@@ -90,8 +92,8 @@ public class Shader {
 	}
 	
 	public int getUniform(String uniform) {
-		Integer location = uniformLocations.get(uniform);
-		if(location == null) {
+		int location = uniformLocations.getOrDefault(uniform, -1);
+		if(location == -1) {
 			location = glGetUniformLocation(program, uniform);
 			uniformLocations.put(uniform, location);
 		}
diff --git a/game/client/src/main/java/net/minecraft/client/render/terrain/RegionBuffer.java b/game/client/src/main/java/net/minecraft/client/render/terrain/RegionBuffer.java
index 3da683cfd..af39ef45d 100644
--- a/game/client/src/main/java/net/minecraft/client/render/terrain/RegionBuffer.java
+++ b/game/client/src/main/java/net/minecraft/client/render/terrain/RegionBuffer.java
@@ -1,5 +1,8 @@
 package net.minecraft.client.render.terrain;
 
+import it.unimi.dsi.fastutil.ints.Int2ObjectArrayMap;
+import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
+
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.HashMap;
@@ -10,7 +13,7 @@ public class RegionBuffer {
 	
 	public final int regionSizeShift;
 	
-	private final Map<Integer, RenderRegion> regionMap = new HashMap<>();
+	private final Int2ObjectMap<RenderRegion> regionMap = new Int2ObjectArrayMap<>();
 	private final List<RenderRegion> regionList = new ArrayList<>();
 	private final List<RenderRegion> immutableRegionList = Collections.unmodifiableList(regionList);
 	
diff --git a/game/client/src/main/java/net/minecraft/client/render/tileentity/TileEntityRendererSign.java b/game/client/src/main/java/net/minecraft/client/render/tileentity/TileEntityRendererSign.java
index cdc633120..b43ec9b99 100644
--- a/game/client/src/main/java/net/minecraft/client/render/tileentity/TileEntityRendererSign.java
+++ b/game/client/src/main/java/net/minecraft/client/render/tileentity/TileEntityRendererSign.java
@@ -1,5 +1,7 @@
 package net.minecraft.client.render.tileentity;
 
+import it.unimi.dsi.fastutil.ints.IntArrayList;
+import it.unimi.dsi.fastutil.ints.IntList;
 import net.minecraft.client.GLAllocation;
 import net.minecraft.client.Minecraft;
 import net.minecraft.client.render.LightmapHelper;
@@ -40,8 +42,8 @@ public class TileEntityRendererSign extends TileEntityRenderer<TileEntitySign>
 
     public TileEntityRendererSign() {
         super();
-        for (int i = 0; i < signColorTextures.length; i++) {
-            signColorTextures[i] = "/assets/minecraft/textures/entity/sign/" + DyeColor.colorFromBlockMeta(i).colorID + ".png";
+        for (int i = 0; i < this.signColorTextures.length; i++) {
+            this.signColorTextures[i] = "/assets/minecraft/textures/entity/sign/" + DyeColor.colorFromBlockMeta(i).colorID + ".png";
         }
     }
 
@@ -91,9 +93,9 @@ public class TileEntityRendererSign extends TileEntityRenderer<TileEntitySign>
 
         GL11.glPushMatrix();
         GL11.glScalef(scale, scale, -scale);
-        int colorSign;
+        final int colorSign;
         if (Block.hasLogicClass(block, BlockLogicSignPainted.class)) {
-            DyeColor c = ((IPainted) block.getLogic()).fromMetadata(meta);
+            final DyeColor c = ((IPainted) block.getLogic()).fromMetadata(meta);
             bindTexture(this.signColorTextures[c.blockMeta]);
             colorSign = c.color.getARGB();
         } else {
@@ -164,7 +166,7 @@ public class TileEntityRendererSign extends TileEntityRenderer<TileEntitySign>
         }
         final int _x = 0;
         final int _y = - tileEntity.signText.length * 5;
-        if (tileEntity.isGlowing() && mc.gameSettings.fancyGraphics.value >= 1) {
+        if (tileEntity.isGlowing() && this.mc.gameSettings.fancyGraphics.value >= 1) {
             this.textMeshRenderer.render(sr, t, line1, line2, line3, line4, _x, _y, SF.setOutlined(SF.setColor(0, color)));
         } else {
             this.textMeshRenderer.render(sr,t, line1, line2, line3, line4, _x, _y, SF.setColor(0, color));
@@ -177,7 +179,7 @@ public class TileEntityRendererSign extends TileEntityRenderer<TileEntitySign>
         GL11.glDisable(GL12.GL_RESCALE_NORMAL);
     }
 
-    private static void drawTexturedModalRect(final double width, final double height, int color, final @NotNull IconCoordinate coordinate)
+    private static void drawTexturedModalRect(final double width, final double height, final int color, final @NotNull IconCoordinate coordinate)
     {
         coordinate.parentAtlas.bind();
         final Tessellator tessellator = Tessellator.instance;
@@ -207,7 +209,7 @@ public class TileEntityRendererSign extends TileEntityRenderer<TileEntitySign>
 
     public static class BufferedTextMeshRenderer {
         private static final long MAX_NON_RENDERED_TIME = 120 * 1000;
-        private final @NotNull List<@NotNull Integer> freeDisplayLists = new ArrayList<>();
+        private final @NotNull IntList freeDisplayLists = new IntArrayList();
         private final @NotNull List<@NotNull MeshEntry> bufferedMeshes = new ArrayList<>();
 
         private final @NotNull MeshEntry referenceEntry = new MeshEntry("", "", "", "", 0);
@@ -225,14 +227,14 @@ public class TileEntityRendererSign extends TileEntityRenderer<TileEntitySign>
         }
 
         public void flushCaches() {
-            for (MeshEntry entry : bufferedMeshes) {
+            for (final MeshEntry entry : this.bufferedMeshes) {
                 GLAllocation.deleteDisplayList(entry.list);
             }
-            bufferedMeshes.clear();
-            for (Integer list : freeDisplayLists) {
+            this.bufferedMeshes.clear();
+            for (final int list : this.freeDisplayLists) {
                 GLAllocation.deleteDisplayList(list);
             }
-            freeDisplayLists.clear();
+            this.freeDisplayLists.clear();
         }
 
         public void render(@NotNull final FontRenderer sr,
@@ -296,7 +298,7 @@ public class TileEntityRendererSign extends TileEntityRenderer<TileEntitySign>
             if (this.freeDisplayLists.isEmpty()) {
                 return GLAllocation.generateDisplayLists(1);
             } else {
-                return this.freeDisplayLists.remove(0);
+                return this.freeDisplayLists.removeInt(0);
             }
         }
 
diff --git a/game/client/src/main/java/net/minecraft/client/util/helper/ItemDragHandler.java b/game/client/src/main/java/net/minecraft/client/util/helper/ItemDragHandler.java
index 62b0c16da..063c8600f 100644
--- a/game/client/src/main/java/net/minecraft/client/util/helper/ItemDragHandler.java
+++ b/game/client/src/main/java/net/minecraft/client/util/helper/ItemDragHandler.java
@@ -7,6 +7,8 @@ import java.util.HashSet;
 import java.util.List;
 import java.util.Set;
 
+import it.unimi.dsi.fastutil.ints.IntArraySet;
+import it.unimi.dsi.fastutil.ints.IntSet;
 import org.lwjgl.input.Keyboard;
 
 import net.minecraft.client.Minecraft;
@@ -26,7 +28,7 @@ public class ItemDragHandler extends Gui {
 	private int renderOffsetX;
 	private int renderOffsetY;
 	
-	private Set<Integer> cancelRelease = new HashSet<>();
+	private IntSet cancelRelease = new IntArraySet();
 	
 	///////////////////////
 	
diff --git a/game/client/src/main/java/net/minecraft/client/util/helper/Textures.java b/game/client/src/main/java/net/minecraft/client/util/helper/Textures.java
index 0772c6fcf..7094b1476 100644
--- a/game/client/src/main/java/net/minecraft/client/util/helper/Textures.java
+++ b/game/client/src/main/java/net/minecraft/client/util/helper/Textures.java
@@ -17,6 +17,7 @@ import java.util.List;
 import javax.imageio.ImageIO;
 
 import com.mojang.logging.LogUtils;
+import it.unimi.dsi.fastutil.ints.IntList;
 import net.minecraft.client.render.texture.stitcher.AtlasStitcher;
 import net.minecraft.client.render.texture.stitcher.TextureRegistry;
 import net.minecraft.core.util.helper.Buffer;
@@ -121,10 +122,10 @@ public class Textures {
 		OpenGLHelper.checkError("pre texture dump");
 
 		LOGGER.info("Dump Textures...");
-		
-		List<Integer> textureList = GLAllocation.textureNames;
+
+		IntList textureList = GLAllocation.textureNames;
 		for(int i=0; i < textureList.size(); i++) {
-			Integer tex = textureList.get(i);
+			Integer tex = textureList.getInt(i);
 
             LOGGER.debug("Tex: {}", tex);
 			
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 cdba02ffa..c0f4a482f 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
@@ -1,12 +1,14 @@
 package net.minecraft.client.world;
 
+import it.unimi.dsi.fastutil.ints.Int2ObjectArrayMap;
+import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
+import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
 import net.minecraft.client.net.handler.PacketHandlerClient;
 import net.minecraft.client.world.chunk.provider.ChunkProviderClient;
 import net.minecraft.core.data.gamerule.GameRules;
 import net.minecraft.core.data.registry.Registries;
 import net.minecraft.core.entity.Entity;
 import net.minecraft.core.net.packet.PacketDisconnect;
-import net.minecraft.core.util.collection.IntHashMap;
 import net.minecraft.core.world.Dimension;
 import net.minecraft.core.world.chunk.ChunkCoordinates;
 import net.minecraft.core.world.chunk.provider.IChunkProvider;
@@ -20,7 +22,7 @@ public class WorldClientMP extends WorldClient {
     private final LinkedList<WorldBlockPositionType> positionTypesList;
     private final PacketHandlerClient sendQueue;
     private ChunkProviderClient chunkCache;
-    private final IntHashMap<Entity> entitiesById;
+    private final Int2ObjectMap<Entity> entitiesById;
     private final Set<Entity> forced;
     private final Set<Entity> reEntries;
 
@@ -28,7 +30,7 @@ public class WorldClientMP extends WorldClient {
     {
         super(new SaveHandlerClientMP(), "MpServer", Dimension.getDimensionList().get(dimensionId), Registries.WORLD_TYPES.getItemByNumericId(worldTypeId), seed);
         positionTypesList = new LinkedList<>();
-        entitiesById = new IntHashMap<>();
+        entitiesById = new Int2ObjectOpenHashMap<>();
         forced = new HashSet<>();
         reEntries = new HashSet<>();
         sendQueue = packetHandlerClient;
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 00dd4f354..da3815398 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
@@ -1,6 +1,10 @@
 package net.minecraft.client.world.chunk.provider;
 
 import com.mojang.logging.LogUtils;
+import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
+import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
+import it.unimi.dsi.fastutil.ints.IntArraySet;
+import it.unimi.dsi.fastutil.ints.IntSet;
 import net.minecraft.client.Minecraft;
 import net.minecraft.core.world.ProgressListener;
 import net.minecraft.core.world.World;
@@ -15,12 +19,12 @@ import java.util.*;
 public class ChunkProviderDynamic implements IChunkProvider
 {
     private static final Logger LOGGER = LogUtils.getLogger();
-    private final Set<Integer> droppedChunksSet;
+    private final IntSet droppedChunksSet;
     private final Chunk emptyChunk;
     public ChunkGenerator chunkGenerator;
     private final IChunkLoader chunkLoader;
-    private final Map<Integer, Chunk> chunkMap;
-    private final Map<Integer, Chunk> forceLoadedChunkMap;
+    private final Int2ObjectMap<Chunk> chunkMap;
+    private final Int2ObjectMap<Chunk> forceLoadedChunkMap;
     private final List<Chunk> forceLoadedChunkList;
     private final World world;
     private int currentChunkX;
@@ -33,10 +37,10 @@ public class ChunkProviderDynamic implements IChunkProvider
 
     public ChunkProviderDynamic(World world, IChunkLoader chunkLoader, ChunkGenerator chunkGenerator)
     {
-        droppedChunksSet = new HashSet<>();
-        chunkMap = new HashMap<>();
+        droppedChunksSet = new IntArraySet();
+        chunkMap = new Int2ObjectOpenHashMap<>();
         forceLoadedChunkList = new ArrayList<>();
-        forceLoadedChunkMap = new HashMap<>();
+        forceLoadedChunkMap = new Int2ObjectOpenHashMap<>();
         emptyChunk = new EmptyChunk(world, 0, 0);
         this.world = world;
         this.chunkLoader = chunkLoader;
@@ -253,7 +257,7 @@ public class ChunkProviderDynamic implements IChunkProvider
         }
         if(!droppedChunksSet.isEmpty()){
             int unloaded = 0;
-            HashSet<Integer> copy = new HashSet<>(droppedChunksSet);
+            IntSet copy = new IntArraySet(droppedChunksSet);
             for (int i : copy) {
                 if(unloaded >= maxUnloadPerTick) break;
                 if(forceLoadedChunkMap.containsKey(i)) continue;
diff --git a/game/client/src/main/java/org/useless/dragonfly/data/block/mojang/BlockModelMojangData.java b/game/client/src/main/java/org/useless/dragonfly/data/block/mojang/BlockModelMojangData.java
index affc2f3fa..4454f7bee 100644
--- a/game/client/src/main/java/org/useless/dragonfly/data/block/mojang/BlockModelMojangData.java
+++ b/game/client/src/main/java/org/useless/dragonfly/data/block/mojang/BlockModelMojangData.java
@@ -12,6 +12,8 @@ import com.google.gson.JsonSerializationContext;
 import com.google.gson.JsonSerializer;
 import com.google.gson.stream.JsonReader;
 import com.mojang.logging.LogUtils;
+import it.unimi.dsi.fastutil.objects.Object2IntArrayMap;
+import it.unimi.dsi.fastutil.objects.Object2IntMap;
 import net.minecraft.client.render.texturepack.TexturePackList;
 import net.minecraft.core.util.HardIllegalArgumentException;
 import net.minecraft.core.util.collection.NamespaceID;
@@ -93,7 +95,7 @@ public class BlockModelMojangData implements BlockModelData {
     /**
      * Each direction's color index, -1 represents no color
      */
-    public final @Nullable Map<@NotNull Direction, @NotNull Integer> particleIndices;
+    public final @Nullable Object2IntMap<@NotNull Direction> particleIndices;
 
     /**
      * Contains all the elements of the model.
@@ -109,7 +111,7 @@ public class BlockModelMojangData implements BlockModelData {
         @Nullable final Integer renderLayer,
         @Nullable final Map<@NotNull String, @NotNull DisplayPos> displayPositions,
         @Nullable final Map<@NotNull String, @NotNull String> textures,
-        @Nullable final Map<@NotNull Direction, @NotNull Integer> particleIndices,
+        @Nullable final Object2IntMap<@NotNull Direction> particleIndices,
         @Nullable final List<@NotNull Element> elements)
     {
         this.modelId = id.makePermanent();
@@ -120,7 +122,7 @@ public class BlockModelMojangData implements BlockModelData {
             if (parentData != null) {
                 this.displayPositions = new HashMap<>();
                 this.textures = new HashMap<>();
-                this.particleIndices = new HashMap<>();
+                this.particleIndices = new Object2IntArrayMap<>();
                 // Elements overrides parent's elements rather than merges them like other fields
                 this.elements = (parentData.elements != null && elements == null) ? new ArrayList<>(parentData.elements) : elements;
                 this.renderLayer = (parentData.renderLayer != null && renderLayer == null) ? parentData.renderLayer : renderLayer;
@@ -179,7 +181,7 @@ public class BlockModelMojangData implements BlockModelData {
         protected int renderLayer = DEFAULT_RENDER_LAYER;
         protected @Nullable Map<@NotNull String, @NotNull DisplayPos> displayPosMap = null;
         protected @Nullable Map<@NotNull String, @NotNull String> textures = null;
-        protected @Nullable Map<@NotNull Direction, @NotNull Integer> particleIndices = null;
+        protected @Nullable Object2IntMap<@NotNull Direction> particleIndices = null;
         protected @Nullable List<Element. @NotNull Builder> elements = null;
 
         public @NotNull Builder setParent(@Nullable final String parent) {
@@ -231,8 +233,8 @@ public class BlockModelMojangData implements BlockModelData {
             return this.textures;
         }
 
-        private @NotNull Map<@NotNull Direction, @NotNull Integer> prepareParticleIndicesMap() {
-            if (this.particleIndices == null) this.particleIndices = new HashMap<>();
+        private @NotNull Object2IntMap<@NotNull Direction> prepareParticleIndicesMap() {
+            if (this.particleIndices == null) this.particleIndices = new Object2IntArrayMap<>();
             return this.particleIndices;
         }
 
diff --git a/game/core/build.gradle.kts b/game/core/build.gradle.kts
index 926dc3843..6b45882d5 100644
--- a/game/core/build.gradle.kts
+++ b/game/core/build.gradle.kts
@@ -34,6 +34,7 @@ dependencies {
     // <core dependencies>
     implementation(libs.jetbrains.annotations)
     implementation(libs.gson)
+    implementation(libs.fastutil)
     implementation(libs.brigadier)
     implementation(libs.bundles.log4j)
     implementation(project(":util:nbt"))
diff --git a/game/core/src/main/java/net/minecraft/core/achievement/stat/StatList.java b/game/core/src/main/java/net/minecraft/core/achievement/stat/StatList.java
index ef3e4c5c3..fc6feae96 100644
--- a/game/core/src/main/java/net/minecraft/core/achievement/stat/StatList.java
+++ b/game/core/src/main/java/net/minecraft/core/achievement/stat/StatList.java
@@ -1,5 +1,9 @@
 package net.minecraft.core.achievement.stat;
 
+import it.unimi.dsi.fastutil.ints.Int2IntMap;
+import it.unimi.dsi.fastutil.ints.Int2IntOpenHashMap;
+import it.unimi.dsi.fastutil.ints.IntOpenHashSet;
+import it.unimi.dsi.fastutil.ints.IntSet;
 import net.minecraft.core.WeightedRandomBag;
 import net.minecraft.core.WeightedRandomLootObject;
 import net.minecraft.core.achievement.Achievements;
@@ -82,7 +86,7 @@ public abstract class StatList
 
     public static Map<NamespaceID, Stat> mobEncounterStats;
 
-    public static Map<Integer, Integer> replacementMap = new HashMap<>();
+    public static Int2IntMap replacementMap = new Int2IntOpenHashMap();
 
     public StatList()
     {
@@ -106,7 +110,7 @@ public abstract class StatList
         initReplaceMap();
         Achievements.init();
 
-        HashSet<Integer> craftable = new HashSet<>();
+        IntSet craftable = new IntOpenHashSet();
         for (RecipeEntryCrafting<?,?> r : Registries.RECIPES.getAllCraftingRecipes()){
             if (r.getOutput() instanceof ItemStack){
                 craftable.add(((ItemStack) r.getOutput()).itemID);
diff --git a/game/core/src/main/java/net/minecraft/core/achievement/stat/StatsCounter.java b/game/core/src/main/java/net/minecraft/core/achievement/stat/StatsCounter.java
index 4c56e4622..74af0d48f 100644
--- a/game/core/src/main/java/net/minecraft/core/achievement/stat/StatsCounter.java
+++ b/game/core/src/main/java/net/minecraft/core/achievement/stat/StatsCounter.java
@@ -14,24 +14,28 @@ import com.b100.json.element.JsonEntry;
 import com.b100.json.element.JsonObject;
 import com.b100.utils.FileUtils;
 import com.mojang.logging.LogUtils;
+import it.unimi.dsi.fastutil.objects.Object2IntMap;
+import it.unimi.dsi.fastutil.objects.Object2IntMaps;
+import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap;
 import net.minecraft.core.MD5String;
 import net.minecraft.core.achievement.Achievement;
 import net.minecraft.core.player.Session;
 import net.minecraft.core.util.HardIllegalArgumentException;
 import net.minecraft.core.util.collection.NamespaceID;
+import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Unmodifiable;
 import org.slf4j.Logger;
 
 public class StatsCounter {
 	private static final Logger LOGGER = LogUtils.getLogger();
-	private final Map<Stat, Integer> sessionStats; // Local copy of stats used by the client
-	private final Map<Stat, Integer> savedStats;
+	private final Object2IntMap<Stat> sessionStats; // Local copy of stats used by the client
+	private final Object2IntMap<Stat> savedStats;
 	private boolean modified;
 	private final StatsSyncher statsSyncher;
 
 	public StatsCounter(Session session, File mcDir) {
-		sessionStats = new HashMap<>();
-		savedStats = new HashMap<>();
+		sessionStats = new Object2IntOpenHashMap<>();
+		savedStats = new Object2IntOpenHashMap<>();
 		modified = false;
 		
 		File statsFolder = new File(mcDir, "stats");
@@ -48,46 +52,46 @@ public class StatsCounter {
 		modified = true;
 	}
 
-	private void addToMap(Map<Stat, Integer> map, Stat stat, int amount) {
+	private void addToMap(Object2IntMap<Stat> map, Stat stat, int amount) {
 		int currentValue = map.getOrDefault(stat, 0);
 		map.put(stat, currentValue + amount);
 	}
 
 	@Unmodifiable
-	public Map<Stat, Integer> getSavedStats() {
-		return Collections.unmodifiableMap(savedStats);
+	public Object2IntMap<Stat> getSavedStats() {
+		return Object2IntMaps.unmodifiable(savedStats);
 	}
 
-	public void addToBoth(Map<Stat, Integer> changes) {
+	public void addToBoth(Object2IntMap<Stat> changes) {
 		if(changes == null) {
 			return;
 		}
 		modified = true;
 		for (Stat stat : changes.keySet()) {
-			addToMap(savedStats, stat, changes.get(stat));
-			addToMap(sessionStats, stat, changes.get(stat));
+			addToMap(savedStats, stat, changes.getInt(stat));
+			addToMap(sessionStats, stat, changes.getInt(stat));
 		}
 
 	}
 
-	public void addToLocal(Map<Stat, Integer> changes) {
+	public void addToLocal(Object2IntMap<Stat> changes) {
 		if(changes == null) {
 			return;
 		}
 		for (Stat stat : changes.keySet()) {
 			int currentValue = savedStats.getOrDefault(stat, 0);
-			sessionStats.put(stat, currentValue + changes.get(stat));
+			sessionStats.put(stat, currentValue + changes.getInt(stat));
 		}
 
 	}
 
-	public void addToSaved(Map<Stat, Integer> map) {
+	public void addToSaved(Object2IntMap<Stat> map) {
 		if(map == null) {
 			return;
 		}
 		modified = true;
 		for (Stat stat : map.keySet()) {
-			addToMap(savedStats, stat, map.get(stat));
+			addToMap(savedStats, stat, map.getInt(stat));
 		}
 	}
 
@@ -143,8 +147,8 @@ public class StatsCounter {
 		}
 	}
 
-	public static Map<Stat, Integer> readStatsFromString(String jsonString) {
-		Map<Stat, Integer> map = new HashMap<>();
+	public static @NotNull Object2IntMap<Stat> readStatsFromString(String jsonString) {
+		Object2IntMap<Stat> map = new Object2IntOpenHashMap<>();
 		try {
 			JsonParser parser = new JsonParser();
 			JsonObject rootObject = parser.parseString(jsonString);
@@ -182,7 +186,7 @@ public class StatsCounter {
 		return map;
 	}
 
-	public static String getStatFileContentString(UUID uuid, String sessionID, Map<Stat, Integer> map) {
+	public static String getStatFileContentString(UUID uuid, String sessionID, Object2IntMap<Stat> map) {
 		StringBuilder displayString = new StringBuilder();
 		StringBuilder checkSumString = new StringBuilder();
 		boolean flag = true;
@@ -202,10 +206,10 @@ public class StatsCounter {
 			} else {
 				flag = false;
 			}
-			displayString.append("\r\n    {\"").append(statbase.statId).append("\":").append(map.get(statbase));
+			displayString.append("\r\n    {\"").append(statbase.statId).append("\":").append(map.getInt(statbase));
 
 			checkSumString.append(statbase.statId).append(","); // Used to use UUID rather than namespace
-			checkSumString.append(map.get(statbase)).append(",");
+			checkSumString.append(map.getInt(statbase)).append(",");
 		}
 
 		if (!flag) {
diff --git a/game/core/src/main/java/net/minecraft/core/achievement/stat/StatsSyncher.java b/game/core/src/main/java/net/minecraft/core/achievement/stat/StatsSyncher.java
index fee7b6d4c..bc3bc166d 100644
--- a/game/core/src/main/java/net/minecraft/core/achievement/stat/StatsSyncher.java
+++ b/game/core/src/main/java/net/minecraft/core/achievement/stat/StatsSyncher.java
@@ -2,17 +2,17 @@ package net.minecraft.core.achievement.stat;
 
 import com.b100.utils.StringUtils;
 import com.mojang.logging.LogUtils;
+import it.unimi.dsi.fastutil.objects.Object2IntMap;
 import net.minecraft.core.player.Session;
 import org.slf4j.Logger;
 
 import java.io.*;
-import java.util.Map;
 
 public class StatsSyncher {
     private static final Logger LOGGER = LogUtils.getLogger();
     private volatile boolean busy = false;
-    private volatile Map<Stat, Integer> queuedLocalStatsChanges;
-    private volatile Map<Stat, Integer> queuedSavedStatsChanges;
+    private volatile Object2IntMap<Stat> queuedLocalStatsChanges;
+    private volatile Object2IntMap<Stat> queuedSavedStatsChanges;
     private final StatsCounter statsCounter;
     private final File unsentStatsFile;
     private final File statsFile;
@@ -24,43 +24,43 @@ public class StatsSyncher {
     private int saveTimer;
     private int fetchChangesTimer; // I'm making a sorta longshot guess, but I think this is the remnant of an unused timer to retrieve stat changes from the server
 
-    public StatsSyncher(Session session, StatsCounter statsCounter, File statsDir) {
-        queuedLocalStatsChanges = null;
-        queuedSavedStatsChanges = null;
-        saveTimer = 0;
-        fetchChangesTimer = 0;
+    public StatsSyncher(final Session session, final StatsCounter statsCounter, final File statsDir) {
+        this.queuedLocalStatsChanges = null;
+        this.queuedSavedStatsChanges = null;
+        this.saveTimer = 0;
+        this.fetchChangesTimer = 0;
 
-        statsFile =           (new File(statsDir, "stats_" + session.uuid + ".dat"));
-        statsFileOld =        (new File(statsDir, "stats_" + session.uuid + ".old"));
-        statsFileTemp =       (new File(statsDir, "stats_" + session.uuid + ".tmp"));
-        unsentStatsFile =     (new File(statsDir, "stats_" + session.uuid + "_unsent.dat"));
-        unsentStatsFileOld =  (new File(statsDir, "stats_" + session.uuid + "_unsent.old"));
-        unsentStatsFileTemp = (new File(statsDir, "stats_" + session.uuid + "_unsent.tmp"));
+        this.statsFile =           (new File(statsDir, "stats_" + session.uuid + ".dat"));
+        this.statsFileOld =        (new File(statsDir, "stats_" + session.uuid + ".old"));
+        this.statsFileTemp =       (new File(statsDir, "stats_" + session.uuid + ".tmp"));
+        this.unsentStatsFile =     (new File(statsDir, "stats_" + session.uuid + "_unsent.dat"));
+        this.unsentStatsFileOld =  (new File(statsDir, "stats_" + session.uuid + "_unsent.old"));
+        this.unsentStatsFileTemp = (new File(statsDir, "stats_" + session.uuid + "_unsent.tmp"));
 
         // Remap pre-UUID stats to new UUID files
-        new File(statsDir, "stats_" + session.username.toLowerCase() + ".dat").renameTo(statsFile);
-        new File(statsDir, "stats_" + session.username.toLowerCase() + ".old").renameTo(statsFileOld);
-        new File(statsDir, "stats_" + session.username.toLowerCase() + ".tmp").renameTo(statsFileTemp);
-        new File(statsDir, "stats_" + session.username.toLowerCase() + "_unsent.dat").renameTo(unsentStatsFile);
-        new File(statsDir, "stats_" + session.username.toLowerCase() + "_unsent.old").renameTo(unsentStatsFileOld);
-        new File(statsDir, "stats_" + session.username.toLowerCase() + "_unsent.tmp").renameTo(unsentStatsFileTemp);
+        new File(statsDir, "stats_" + session.username.toLowerCase() + ".dat").renameTo(this.statsFile);
+        new File(statsDir, "stats_" + session.username.toLowerCase() + ".old").renameTo(this.statsFileOld);
+        new File(statsDir, "stats_" + session.username.toLowerCase() + ".tmp").renameTo(this.statsFileTemp);
+        new File(statsDir, "stats_" + session.username.toLowerCase() + "_unsent.dat").renameTo(this.unsentStatsFile);
+        new File(statsDir, "stats_" + session.username.toLowerCase() + "_unsent.old").renameTo(this.unsentStatsFileOld);
+        new File(statsDir, "stats_" + session.username.toLowerCase() + "_unsent.tmp").renameTo(this.unsentStatsFileTemp);
 
         this.statsCounter = statsCounter;
         this.session = session;
-        if (unsentStatsFile.exists()) {
-            statsCounter.addToBoth(readStatsFromFile(unsentStatsFile, unsentStatsFileTemp, unsentStatsFileOld));
+        if (this.unsentStatsFile.exists()) {
+            statsCounter.addToBoth(readStatsFromFile(this.unsentStatsFile, this.unsentStatsFileTemp, this.unsentStatsFileOld));
         }
         startRetrievalThread();
     }
 
-    private void renameFile(File parent, String child, File fileToRename) {
-        File destFile = new File(parent, child);
+    private void renameFile(final File parent, final String child, final File fileToRename) {
+        final File destFile = new File(parent, child);
         if (destFile.exists() && !destFile.isDirectory() && !fileToRename.exists()) {
             destFile.renameTo(fileToRename);
         }
     }
 
-    private Map<Stat, Integer> readStatsFromFile(File statsFile, File tempStatsFile, File oldStatsFile) {
+    private Object2IntMap<Stat> readStatsFromFile(final File statsFile, final File tempStatsFile, final File oldStatsFile) {
         if (statsFile.exists()) {
             return readStatsFromFile(statsFile);
         }
@@ -74,19 +74,19 @@ public class StatsSyncher {
         }
     }
 
-    private Map<Stat, Integer> readStatsFromFile(File statsFile) {
+    private Object2IntMap<Stat> readStatsFromFile(final File statsFile) {
         try {
             return StatsCounter.readStatsFromString(StringUtils.getFileContentAsString(statsFile));
-        } catch (Exception e) {
+        } catch (final Exception e) {
             LOGGER.warn("Failed to read stats from file '{}'!", statsFile.getPath(), e);
         }
         return null;
     }
 
-    private void saveStats(Map<Stat, Integer> map, File statsFile, File tempStatsFile, File oldStatsFile)
+    private void saveStats(final Object2IntMap<Stat> map, final File statsFile, final File tempStatsFile, final File oldStatsFile)
         throws IOException {
-        try (PrintWriter writer = new PrintWriter(new FileWriter(tempStatsFile, false))) {
-            writer.print(StatsCounter.getStatFileContentString(session.uuid, "local", map));
+        try (final PrintWriter writer = new PrintWriter(new FileWriter(tempStatsFile, false))) {
+            writer.print(StatsCounter.getStatFileContentString(this.session.uuid, "local", map));
         }
         if (oldStatsFile.exists()) {
             oldStatsFile.delete();
@@ -98,83 +98,83 @@ public class StatsSyncher {
     }
 
     public void startRetrievalThread() {
-        if (busy) {
+        if (this.busy) {
             throw new IllegalStateException("Can't get stats from server while StatsSyncher is busy!");
         } else {
-            saveTimer = 100;
-            busy = true;
+            this.saveTimer = 100;
+            this.busy = true;
             new Thread(() -> {
                 try {
-                    if (queuedLocalStatsChanges != null) {
-                        saveStats(queuedLocalStatsChanges, statsFile, statsFileTemp, statsFileOld);
-                    } else if (statsFile.exists()) {
-                        queuedLocalStatsChanges = readStatsFromFile(statsFile, statsFileTemp, statsFileOld);
+                    if (this.queuedLocalStatsChanges != null) {
+                        saveStats(this.queuedLocalStatsChanges, this.statsFile, this.statsFileTemp, this.statsFileOld);
+                    } else if (this.statsFile.exists()) {
+                        this.queuedLocalStatsChanges = readStatsFromFile(this.statsFile, this.statsFileTemp, this.statsFileOld);
                     }
-                } catch (Exception exception) {
+                } catch (final Exception exception) {
                     LOGGER.error("Unexpected exception in retrieval thread!", exception);
                 } finally {
-                    busy = false;
+                    this.busy = false;
                 }
             }).start();
         }
     }
 
-    public void startSavingThread(Map<Stat, Integer> mapToSave) {
-        if (busy) {
+    public void startSavingThread(final Object2IntMap<Stat> mapToSave) {
+        if (this.busy) {
             throw new IllegalStateException("Can't save stats while StatsSyncher is busy!");
         } else {
-            saveTimer = 100;
-            busy = true;
+            this.saveTimer = 100;
+            this.busy = true;
             new Thread(() -> {
                 try {
-                    saveStats(mapToSave, unsentStatsFile, unsentStatsFileTemp, unsentStatsFileOld);
-                } catch (Exception exception) {
+                    saveStats(mapToSave, this.unsentStatsFile, this.unsentStatsFileTemp, this.unsentStatsFileOld);
+                } catch (final Exception exception) {
                     LOGGER.error("Unexpected exception in saving thread!", exception);
                 } finally {
-                    busy = false;
+                    this.busy = false;
                 }
 
             }).start();
         }
     }
 
-    public void saveStatsToDisk(Map<Stat, Integer> map) {
-        for (int i = 30; busy && --i > 0; ) {
+    public void saveStatsToDisk(final Object2IntMap<Stat> map) {
+        for (int i = 30; this.busy && --i > 0; ) {
             try {
                 Thread.sleep(100L);
-            } catch (InterruptedException interrupt) {
+            } catch (final InterruptedException interrupt) {
                 LOGGER.warn("Interrupted!", interrupt);
             }
         }
 
-        busy = true;
+        this.busy = true;
         try {
-            saveStats(map, unsentStatsFile, unsentStatsFileTemp, unsentStatsFileOld);
-        } catch (Exception exception) {
+            saveStats(map, this.unsentStatsFile, this.unsentStatsFileTemp, this.unsentStatsFileOld);
+        } catch (final Exception exception) {
             LOGGER.error("Exception saving stats!", exception);
         } finally {
-            busy = false;
+            this.busy = false;
         }
     }
 
     public boolean pendingSave() {
-        return saveTimer <= 0 && !busy && queuedSavedStatsChanges == null;
+        return this.saveTimer <= 0 && !this.busy && this.queuedSavedStatsChanges == null;
     }
 
     public void tick() {
-        if (saveTimer > 0) {
-            saveTimer--;
+        if (this.saveTimer > 0) {
+            this.saveTimer--;
         }
-        if (fetchChangesTimer > 0) {
-            fetchChangesTimer--;
+        if (this.fetchChangesTimer > 0) {
+            this.fetchChangesTimer--;
         }
-        if (queuedSavedStatsChanges != null) {
-            statsCounter.addToSaved(queuedSavedStatsChanges);
-            queuedSavedStatsChanges = null;
+        if (this.queuedSavedStatsChanges != null) {
+            this.statsCounter.addToSaved(this.queuedSavedStatsChanges);
+            this.queuedSavedStatsChanges = null;
         }
-        if (queuedLocalStatsChanges != null) {
-            statsCounter.addToLocal(queuedLocalStatsChanges);
-            queuedLocalStatsChanges = null;
+        if (this.queuedLocalStatsChanges != null) {
+            this.statsCounter.addToLocal(this.queuedLocalStatsChanges);
+            this.queuedLocalStatsChanges = null;
         }
     }
 }
diff --git a/game/core/src/main/java/net/minecraft/core/block/BlockLogicMoss.java b/game/core/src/main/java/net/minecraft/core/block/BlockLogicMoss.java
index 9787d6a11..9e19c4a8f 100644
--- a/game/core/src/main/java/net/minecraft/core/block/BlockLogicMoss.java
+++ b/game/core/src/main/java/net/minecraft/core/block/BlockLogicMoss.java
@@ -1,5 +1,6 @@
 package net.minecraft.core.block;
 
+import it.unimi.dsi.fastutil.ints.Int2IntArrayMap;
 import net.minecraft.core.entity.player.Player;
 import net.minecraft.core.item.IBonemealable;
 import net.minecraft.core.item.ItemStack;
@@ -15,7 +16,7 @@ import java.util.Map.Entry;
 import java.util.Random;
 
 public class BlockLogicMoss extends BlockLogic implements IBonemealable {
-	public static WorldFeatureOre.OreMap variantMap = new WorldFeatureOre.OreMap();
+	public static Int2IntArrayMap variantMap = new Int2IntArrayMap();
 	public BlockLogicMoss(Block<?> block, Block<?> parentBlock) {
 		super(block, Material.moss);
 		block.setTicking(true);
diff --git a/game/core/src/main/java/net/minecraft/core/block/BlockLogicNote.java b/game/core/src/main/java/net/minecraft/core/block/BlockLogicNote.java
index 858749eee..7b023a62c 100644
--- a/game/core/src/main/java/net/minecraft/core/block/BlockLogicNote.java
+++ b/game/core/src/main/java/net/minecraft/core/block/BlockLogicNote.java
@@ -1,6 +1,8 @@
 package net.minecraft.core.block;
 
 import com.mojang.logging.LogUtils;
+import it.unimi.dsi.fastutil.ints.Int2ObjectArrayMap;
+import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
 import net.minecraft.core.block.entity.TileEntityActivator;
 import net.minecraft.core.entity.player.Player;
 import net.minecraft.core.sound.SoundCategory;
@@ -109,7 +111,7 @@ public class BlockLogicNote extends BlockLogic
     }
 
     public static class Instrument {
-        public static final Map<Integer, Instrument> instrumentMap = new HashMap<>();
+        public static final Int2ObjectMap<Instrument> instrumentMap = new Int2ObjectArrayMap<>();
         public final int index;
         public final String soundKey;
 
diff --git a/game/core/src/main/java/net/minecraft/core/block/BlockLogicOreCoal.java b/game/core/src/main/java/net/minecraft/core/block/BlockLogicOreCoal.java
index 7b638b37e..284823833 100644
--- a/game/core/src/main/java/net/minecraft/core/block/BlockLogicOreCoal.java
+++ b/game/core/src/main/java/net/minecraft/core/block/BlockLogicOreCoal.java
@@ -1,5 +1,6 @@
 package net.minecraft.core.block;
 
+import it.unimi.dsi.fastutil.ints.Int2IntArrayMap;
 import net.minecraft.core.block.entity.TileEntity;
 import net.minecraft.core.enums.EnumDropCause;
 import net.minecraft.core.item.Items;
@@ -13,7 +14,7 @@ import java.util.Map;
 
 public class BlockLogicOreCoal extends BlockLogic
 {
-    public static WorldFeatureOre.OreMap variantMap = new WorldFeatureOre.OreMap();
+    public static Int2IntArrayMap variantMap = new Int2IntArrayMap();
 
     public BlockLogicOreCoal(Block<?> block, Block<?> parentBlock, Material material){
         super(block, material);
diff --git a/game/core/src/main/java/net/minecraft/core/block/BlockLogicOreDiamond.java b/game/core/src/main/java/net/minecraft/core/block/BlockLogicOreDiamond.java
index e25b350f6..41c78b98b 100644
--- a/game/core/src/main/java/net/minecraft/core/block/BlockLogicOreDiamond.java
+++ b/game/core/src/main/java/net/minecraft/core/block/BlockLogicOreDiamond.java
@@ -1,5 +1,6 @@
 package net.minecraft.core.block;
 
+import it.unimi.dsi.fastutil.ints.Int2IntArrayMap;
 import net.minecraft.core.block.entity.TileEntity;
 import net.minecraft.core.enums.EnumDropCause;
 import net.minecraft.core.item.Items;
@@ -13,7 +14,7 @@ import java.util.Map;
 
 public class BlockLogicOreDiamond extends BlockLogic
 {
-    public static WorldFeatureOre.OreMap variantMap = new WorldFeatureOre.OreMap();
+    public static Int2IntArrayMap variantMap = new Int2IntArrayMap();
     public BlockLogicOreDiamond(Block<?> block, Block<?> parentBlock, Material material)
     {
         super(block, material);
diff --git a/game/core/src/main/java/net/minecraft/core/block/BlockLogicOreGold.java b/game/core/src/main/java/net/minecraft/core/block/BlockLogicOreGold.java
index 2bb4211df..1e768cbe6 100644
--- a/game/core/src/main/java/net/minecraft/core/block/BlockLogicOreGold.java
+++ b/game/core/src/main/java/net/minecraft/core/block/BlockLogicOreGold.java
@@ -1,5 +1,6 @@
 package net.minecraft.core.block;
 
+import it.unimi.dsi.fastutil.ints.Int2IntArrayMap;
 import net.minecraft.core.block.entity.TileEntity;
 import net.minecraft.core.enums.EnumDropCause;
 import net.minecraft.core.item.Items;
@@ -13,7 +14,7 @@ import java.util.Map;
 
 
 public class BlockLogicOreGold extends BlockLogic {
-    public static WorldFeatureOre.OreMap variantMap = new WorldFeatureOre.OreMap();
+    public static Int2IntArrayMap variantMap = new Int2IntArrayMap();
 
     public BlockLogicOreGold(Block<?> block, Block<?> parentBlock, Material material) {
         super(block, material);
diff --git a/game/core/src/main/java/net/minecraft/core/block/BlockLogicOreIron.java b/game/core/src/main/java/net/minecraft/core/block/BlockLogicOreIron.java
index 80a828668..af197ca1e 100644
--- a/game/core/src/main/java/net/minecraft/core/block/BlockLogicOreIron.java
+++ b/game/core/src/main/java/net/minecraft/core/block/BlockLogicOreIron.java
@@ -1,5 +1,6 @@
 package net.minecraft.core.block;
 
+import it.unimi.dsi.fastutil.ints.Int2IntArrayMap;
 import net.minecraft.core.block.entity.TileEntity;
 import net.minecraft.core.enums.EnumDropCause;
 import net.minecraft.core.item.Items;
@@ -13,7 +14,7 @@ import java.util.Map;
 
 public class BlockLogicOreIron extends BlockLogic
 {
-    public static WorldFeatureOre.OreMap variantMap = new WorldFeatureOre.OreMap();
+    public static Int2IntArrayMap variantMap = new Int2IntArrayMap();
     public BlockLogicOreIron(Block<?> block, Block<?> parentBlock, Material material) {
         super(block, material);
         variantMap.put(parentBlock.id(), block.id());
diff --git a/game/core/src/main/java/net/minecraft/core/block/BlockLogicOreLapis.java b/game/core/src/main/java/net/minecraft/core/block/BlockLogicOreLapis.java
index 228954fe8..e70f5f4d3 100644
--- a/game/core/src/main/java/net/minecraft/core/block/BlockLogicOreLapis.java
+++ b/game/core/src/main/java/net/minecraft/core/block/BlockLogicOreLapis.java
@@ -1,5 +1,6 @@
 package net.minecraft.core.block;
 
+import it.unimi.dsi.fastutil.ints.Int2IntArrayMap;
 import net.minecraft.core.block.entity.TileEntity;
 import net.minecraft.core.enums.EnumDropCause;
 import net.minecraft.core.item.Items;
@@ -14,7 +15,7 @@ import java.util.Map;
 
 public class BlockLogicOreLapis extends BlockLogic
 {
-    public static WorldFeatureOre.OreMap variantMap = new WorldFeatureOre.OreMap();
+    public static Int2IntArrayMap variantMap = new Int2IntArrayMap();
     public BlockLogicOreLapis(Block<?> block, Block<?> parentBlock, Material material)
     {
         super(block, material);
diff --git a/game/core/src/main/java/net/minecraft/core/block/BlockLogicOreRedstone.java b/game/core/src/main/java/net/minecraft/core/block/BlockLogicOreRedstone.java
index e5057d4bf..bee8f2431 100644
--- a/game/core/src/main/java/net/minecraft/core/block/BlockLogicOreRedstone.java
+++ b/game/core/src/main/java/net/minecraft/core/block/BlockLogicOreRedstone.java
@@ -1,5 +1,6 @@
 package net.minecraft.core.block;
 
+import it.unimi.dsi.fastutil.ints.Int2IntArrayMap;
 import net.minecraft.core.block.entity.TileEntity;
 import net.minecraft.core.block.entity.TileEntityActivator;
 import net.minecraft.core.entity.Entity;
@@ -18,7 +19,7 @@ import java.util.Random;
 
 public class BlockLogicOreRedstone extends BlockLogic
 {
-    public static WorldFeatureOre.OreMap variantMap = new WorldFeatureOre.OreMap();
+    public static Int2IntArrayMap variantMap = new Int2IntArrayMap();
     private final boolean illuminated;
     private final Block<?> normalBlock;
     private final Block<?> illuminatedBlock;
diff --git a/game/core/src/main/java/net/minecraft/core/block/Blocks.java b/game/core/src/main/java/net/minecraft/core/block/Blocks.java
index db6111b82..244fc868f 100644
--- a/game/core/src/main/java/net/minecraft/core/block/Blocks.java
+++ b/game/core/src/main/java/net/minecraft/core/block/Blocks.java
@@ -1,5 +1,7 @@
 package net.minecraft.core.block;
 
+import it.unimi.dsi.fastutil.objects.Object2IntMap;
+import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap;
 import net.minecraft.core.block.material.Material;
 import net.minecraft.core.block.material.MaterialColor;
 import net.minecraft.core.block.piston.BlockLogicPistonBase;
@@ -36,7 +38,7 @@ import java.util.Map;
 public final class Blocks {
     public static final @Nullable Block<?> @NotNull [] blocksList = new Block<?>[16384];
     public static final Map<NamespaceID, Block<?>> blockMap = new LinkedHashMap<>();
-    @Deprecated public static final Map<String, Integer> keyToIdMap = new HashMap<>();
+    @Deprecated public static final Object2IntMap<String> keyToIdMap = new Object2IntOpenHashMap<>();
     public static final boolean[] shouldTick = new boolean[blocksList.length];
     public static final boolean[] solid = new boolean[blocksList.length];
     public static final boolean[] isEntityTile = new boolean[blocksList.length];
@@ -1289,7 +1291,7 @@ public final class Blocks {
 
         if (Blocks.blocksList[container.id()] != null) throw new IllegalArgumentException("Id '" + id + "' of block '" + container.namespaceId() + "' is already being used by '" + Blocks.blocksList[container.id()].namespaceId() + "'!");
         Blocks.blocksList[container.id()] = container;
-        if (Blocks.keyToIdMap.containsKey(container.getKey())) throw new IllegalArgumentException("Key '" + container.getKey() + "' of block '" + container.namespaceId() + "' is already being used by '" + Blocks.getBlock(Blocks.keyToIdMap.get(container.getKey())).namespaceId() + "'!");
+        if (Blocks.keyToIdMap.containsKey(container.getKey())) throw new IllegalArgumentException("Key '" + container.getKey() + "' of block '" + container.namespaceId() + "' is already being used by '" + Blocks.getBlock(Blocks.keyToIdMap.getInt(container.getKey())).namespaceId() + "'!");
         Blocks.keyToIdMap.put(container.getKey(), container.id());
         if (Blocks.blockMap.containsKey(container.namespaceId())) throw new IllegalArgumentException("NamespaceId '" + container.namespaceId() + "' of block '" + container.getKey() + "' is already being used by '" + Blocks.blockMap.get(container.namespaceId()).namespaceId() + "'!");
         Blocks.blockMap.put(container.namespaceId(), container);
diff --git a/game/core/src/main/java/net/minecraft/core/block/entity/TileEntityBasket.java b/game/core/src/main/java/net/minecraft/core/block/entity/TileEntityBasket.java
index f0e75173d..207f7e274 100644
--- a/game/core/src/main/java/net/minecraft/core/block/entity/TileEntityBasket.java
+++ b/game/core/src/main/java/net/minecraft/core/block/entity/TileEntityBasket.java
@@ -2,6 +2,8 @@ package net.minecraft.core.block.entity;
 
 import java.util.*;
 
+import it.unimi.dsi.fastutil.objects.Object2IntArrayMap;
+import it.unimi.dsi.fastutil.objects.Object2IntMap;
 import net.minecraft.core.block.Blocks;
 import net.minecraft.core.entity.Entity;
 import net.minecraft.core.entity.EntityItem;
@@ -19,49 +21,49 @@ import org.jetbrains.annotations.NotNull;
 public class TileEntityBasket extends TileEntity
 {
     private int numUnitsInside = 0;
-    private final Map<BasketEntry, Integer> contents = new HashMap<>();
+    private final Object2IntMap<BasketEntry> contents = new Object2IntArrayMap<>();
 
 
     private void updateNumUnits()
     {
-        int prevNum = numUnitsInside;
-        numUnitsInside = 0;
+        final int prevNum = this.numUnitsInside;
+        this.numUnitsInside = 0;
 
-        for (Map.Entry<BasketEntry, Integer> entry : contents.entrySet())
+        for (final Object2IntMap.Entry<BasketEntry> entry : this.contents.object2IntEntrySet())
         {
-            BasketEntry be = entry.getKey();
-            int numItems = entry.getValue();
+            final BasketEntry be = entry.getKey();
+            final int numItems = entry.getIntValue();
 
-            int unitsPerItem = getItemSizeUnits(be.getItem());
-            numUnitsInside += (unitsPerItem * numItems);
+            final int unitsPerItem = getItemSizeUnits(be.getItem());
+            this.numUnitsInside += (unitsPerItem * numItems);
         }
-        if (prevNum != numUnitsInside && worldObj != null){
-            worldObj.notifyBlockChange(x, y, z, worldObj.getBlockId(x, y, z));
+        if (prevNum != this.numUnitsInside && this.worldObj != null){
+            this.worldObj.notifyBlockChange(this.x, this.y, this.z, this.worldObj.getBlockId(this.x, this.y, this.z));
         }
     }
 
-    private int getItemSizeUnits(Item item)
+    private int getItemSizeUnits(final Item item)
     {
         return 64 / item.getItemStackLimit(null);
     }
 
 
-    private void dropItemStack(Random rand, ItemStack itemstack)
+    private void dropItemStack(final Random rand, final ItemStack itemstack)
     {
         final float f = rand.nextFloat() * 0.8F + 0.1F;
         final float f1 = rand.nextFloat() * 0.8F + 0.1F;
         final float f2 = rand.nextFloat() * 0.8F + 0.1F;
 
-        World workingWorld;
-        if (worldObj != null) {
-            workingWorld = worldObj;
-        } else if (carriedBlock != null) {
-            workingWorld = carriedBlock.world;
+        final World workingWorld;
+        if (this.worldObj != null) {
+            workingWorld = this.worldObj;
+        } else if (this.carriedBlock != null) {
+            workingWorld = this.carriedBlock.world;
         } else {
             return;
         }
 
-        final EntityItem item = new EntityItem(workingWorld, x + f, y + f1, z + f2, itemstack);
+        final EntityItem item = new EntityItem(workingWorld, this.x + f, this.y + f1, this.z + f2, itemstack);
         final float f3 = 0.05F;
         item.xd = (float) rand.nextGaussian() * f3;
         item.yd = (float) rand.nextGaussian() * f3 + 0.25F;
@@ -71,7 +73,7 @@ public class TileEntityBasket extends TileEntity
 
     public int getNumUnitsInside()
     {
-        return numUnitsInside;
+        return this.numUnitsInside;
     }
 
     public int getMaxUnits()
@@ -80,39 +82,39 @@ public class TileEntityBasket extends TileEntity
     }
 
 	public void givePlayerAllItems(final World world, final Player player) {
-		List<BasketEntry> toRemove = new ArrayList<>();
+		final List<BasketEntry> toRemove = new ArrayList<>();
 
-		for(Map.Entry<BasketEntry, Integer> entry : contents.entrySet()) {
-			BasketEntry basketEntry = entry.getKey();
-			ItemStack basketEntryStack = new ItemStack(basketEntry.id, entry.getValue(), basketEntry.metadata, basketEntry.tag);
+		for(final Object2IntMap.Entry<BasketEntry> entry : this.contents.object2IntEntrySet()) {
+			final BasketEntry basketEntry = entry.getKey();
+			final ItemStack basketEntryStack = new ItemStack(basketEntry.id, entry.getIntValue(), basketEntry.metadata, basketEntry.tag);
 			// Beware! basketEntryStack may have a stack size higher than its limit!
 			
 			player.inventory.insertItem(basketEntryStack, true);
-			contents.put(basketEntry, basketEntryStack.stackSize);
+            this.contents.put(basketEntry, basketEntryStack.stackSize);
 			
 			if(basketEntryStack.stackSize <= 0) {
 				toRemove.add(basketEntry);
 			}
 		}
-		
-		for(BasketEntry entry : toRemove) {
-			contents.remove(entry);
+
+		for(final BasketEntry entry : toRemove) {
+            this.contents.removeInt(entry);
 		}
 
 		updateNumUnits();
-        world.notifyBlockChange(x, y, z, Blocks.BASKET.id());
+        world.notifyBlockChange(this.x, this.y, this.z, Blocks.BASKET.id());
 	}
 
     @Override
-    public void readAdditionalData(@NotNull CompoundTag compoundTag) {
+    public void readAdditionalData(@NotNull final CompoundTag compoundTag) {
         final ListTag itemsTag = compoundTag.getList("Items");
-        contents.clear();
+        this.contents.clear();
         for (int i = 0; i < itemsTag.tagCount(); i++)
         {
             final CompoundTag itemTag = (CompoundTag) itemsTag.tagAt(i);
-            BasketEntry entry = BasketEntry.read(itemTag);
+            final BasketEntry entry = BasketEntry.read(itemTag);
             final int count = itemTag.getShort("Count");
-            contents.put(entry, count);
+            this.contents.put(entry, count);
         }
         updateNumUnits();
     }
@@ -120,21 +122,23 @@ public class TileEntityBasket extends TileEntity
     @Override
     public void tick()
     {
-        if (worldObj != null && worldObj.isClientSide) return;
-        if (carriedBlock != null && carriedBlock.world.isClientSide) return;
-
-        double posX, posY, posZ;
-        World workingWorld;
-        if (worldObj != null) {
-            workingWorld = worldObj;
-            posX = x;
-            posY = y;
-            posZ = z;
-        } else if (carriedBlock != null) {
-            workingWorld = carriedBlock.world;
-            posX = carriedBlock.holder.x - 0.5;
-            posY = carriedBlock.holder.y - carriedBlock.holder.heightOffset;
-            posZ = carriedBlock.holder.z - 0.5;
+        if (this.worldObj != null && this.worldObj.isClientSide) return;
+        if (this.carriedBlock != null && this.carriedBlock.world.isClientSide) return;
+
+        final double posX;
+        final double posY;
+        final double posZ;
+        final World workingWorld;
+        if (this.worldObj != null) {
+            workingWorld = this.worldObj;
+            posX = this.x;
+            posY = this.y;
+            posZ = this.z;
+        } else if (this.carriedBlock != null) {
+            workingWorld = this.carriedBlock.world;
+            posX = this.carriedBlock.holder.x - 0.5;
+            posY = this.carriedBlock.holder.y - this.carriedBlock.holder.heightOffset;
+            posZ = this.carriedBlock.holder.z - 0.5;
         } else {
             return;
         }
@@ -163,35 +167,35 @@ public class TileEntityBasket extends TileEntity
 
         if (shouldUpdate)
         {
-            if (worldObj != null) {
-                worldObj.notifyBlockChange(x, y, z, Blocks.BASKET.id());
+            if (this.worldObj != null) {
+                this.worldObj.notifyBlockChange(this.x, this.y, this.z, Blocks.BASKET.id());
             }
             updateNumUnits();
         }
     }
 
-    private boolean importItemStack(ItemStack stack)
+    private boolean importItemStack(final ItemStack stack)
     {
-        BasketEntry entry = new BasketEntry(stack.itemID, stack.getMetadata(), stack.getData());
-        int sizeUnits = getItemSizeUnits(stack.getItem());
-        int freeUnits = getMaxUnits() - numUnitsInside;
-        int itemsToTake = Math.min(freeUnits / sizeUnits, stack.stackSize);
+        final BasketEntry entry = new BasketEntry(stack.itemID, stack.getMetadata(), stack.getData());
+        final int sizeUnits = getItemSizeUnits(stack.getItem());
+        final int freeUnits = getMaxUnits() - this.numUnitsInside;
+        final int itemsToTake = Math.min(freeUnits / sizeUnits, stack.stackSize);
         if (itemsToTake <= 0) return false;
         stack.stackSize -= itemsToTake;
-        int currentItemsInBE = contents.getOrDefault(entry, 0);
+        int currentItemsInBE = this.contents.getOrDefault(entry, 0);
         currentItemsInBE += itemsToTake;
-        contents.put(entry, currentItemsInBE);
+        this.contents.put(entry, currentItemsInBE);
         return true;
     }
 
     @Override
-    public void writeAdditionalData(@NotNull CompoundTag compoundTag)
+    public void writeAdditionalData(@NotNull final CompoundTag compoundTag)
     {
         final ListTag itemsTag = new ListTag();
-        for (Map.Entry<BasketEntry, Integer> entry : contents.entrySet())
+        for (final Object2IntMap.Entry<BasketEntry> entry : this.contents.object2IntEntrySet())
         {
             final CompoundTag itemTag = new CompoundTag();
-            itemTag.putShort("Count", (short)(int)entry.getValue());
+            itemTag.putShort("Count", (short) entry.getIntValue());
             BasketEntry.write(itemTag, entry.getKey());
             itemsTag.addTag(itemTag);
         }
@@ -205,38 +209,38 @@ public class TileEntityBasket extends TileEntity
     }
 
     @Override
-    public void dropContents(World world, int x, int y, int z) {
+    public void dropContents(final World world, final int x, final int y, final int z) {
         super.dropContents(world, x, y, z);
         final Random rand = new Random();
 
-        for (Map.Entry<BasketEntry, Integer> entry : contents.entrySet())
+        for (final Object2IntMap.Entry<BasketEntry> entry : this.contents.object2IntEntrySet())
         {
-            BasketEntry be = entry.getKey();
-            int numItems = entry.getValue();
+            final BasketEntry be = entry.getKey();
+            int numItems = entry.getIntValue();
 
             while (numItems > 0)
             {
-                int maxStackSize = be.getItem().getItemStackLimit(null);
+                final int maxStackSize = be.getItem().getItemStackLimit(null);
                 int stackSize = maxStackSize;
-                int remainingItems = numItems - maxStackSize;
+                final int remainingItems = numItems - maxStackSize;
                 if (remainingItems < 0) stackSize = numItems;
                 numItems -= stackSize;
                 dropItemStack(rand, new ItemStack(be.id, stackSize, be.metadata, be.tag));
             }
         }
 
-        contents.clear();
+        this.contents.clear();
 
         world.notifyBlockChange(x, y, z, Blocks.BASKET.id());
         updateNumUnits();
     }
 
     @Override
-    public void heldTick(World world, Entity holder) {
+    public void heldTick(final World world, final Entity holder) {
         tick();
     }
     @Override
-    public boolean canBeCarried(World world, Entity potentialHolder) {
+    public boolean canBeCarried(final World world, final Entity potentialHolder) {
         return true;
     }
 
@@ -246,23 +250,23 @@ public class TileEntityBasket extends TileEntity
         public final int metadata;
         public final CompoundTag tag;
 
-        public BasketEntry(int id, int metadata, CompoundTag tag)
+        public BasketEntry(final int id, final int metadata, final CompoundTag tag)
         {
             this.id = id;
             this.metadata = metadata;
             this.tag = tag;
         }
 
-        public static BasketEntry read(CompoundTag tag)
+        public static BasketEntry read(final CompoundTag tag)
         {
-            int id = tag.getShort("id");
-            int damage = tag.getShort("Damage");
-            CompoundTag data = tag.getCompound("Data");
+            final int id = tag.getShort("id");
+            final int damage = tag.getShort("Damage");
+            final CompoundTag data = tag.getCompound("Data");
 
             return new BasketEntry(id, damage, data);
         }
 
-        public static void write(CompoundTag tag, BasketEntry entry)
+        public static void write(final CompoundTag tag, final BasketEntry entry)
         {
             tag.putShort("id", (short) entry.id);
             tag.putShort("Damage", (short) entry.metadata);
@@ -271,29 +275,28 @@ public class TileEntityBasket extends TileEntity
 
         public Item getItem()
         {
-            return Item.itemsList[id];
+            return Item.itemsList[this.id];
         }
 
         @Override
-        public boolean equals(Object obj)
+        public boolean equals(final Object obj)
         {
             if (!(obj instanceof BasketEntry)) return false;
-            BasketEntry other = (BasketEntry) obj;
+            final BasketEntry other = (BasketEntry) obj;
             if (this.id != other.id || this.metadata != other.metadata) return false;
-            if (this.tag.getValues().size() > 2 || other.tag.getValues().size() > 2) return false;
-            return true;
+            return this.tag.getValues().size() <= 2 && other.tag.getValues().size() <= 2;
         }
 
         @Override
         public int hashCode()
         {
-            if (tag.getValues().size() <= 2)
+            if (this.tag.getValues().size() <= 2)
             {
-                return Objects.hash(id, metadata);
+                return Objects.hash(this.id, this.metadata);
             }
             else
             {
-                return Objects.hash(id, metadata, tag);
+                return Objects.hash(this.id, this.metadata, this.tag);
             }
         }
     }
diff --git a/game/core/src/main/java/net/minecraft/core/block/logic/RailDirection.java b/game/core/src/main/java/net/minecraft/core/block/logic/RailDirection.java
index 0467a8afa..4d47adc00 100644
--- a/game/core/src/main/java/net/minecraft/core/block/logic/RailDirection.java
+++ b/game/core/src/main/java/net/minecraft/core/block/logic/RailDirection.java
@@ -1,5 +1,7 @@
 package net.minecraft.core.block.logic;
 
+import it.unimi.dsi.fastutil.ints.Int2ObjectArrayMap;
+import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
 import org.jetbrains.annotations.NotNull;
 
 import java.util.HashMap;
@@ -40,7 +42,7 @@ public enum RailDirection {
         0, 0, -1,
         1, 0, 0);
 
-    private static final Map<Integer, RailDirection> directionMap = new HashMap<>();
+    private static final Int2ObjectMap<RailDirection> directionMap = new Int2ObjectArrayMap<>();
     public final int meta;
     private final boolean sloped;
     private final boolean straight;
diff --git a/game/core/src/main/java/net/minecraft/core/block/material/MaterialColor.java b/game/core/src/main/java/net/minecraft/core/block/material/MaterialColor.java
index c1957bf50..a31644738 100644
--- a/game/core/src/main/java/net/minecraft/core/block/material/MaterialColor.java
+++ b/game/core/src/main/java/net/minecraft/core/block/material/MaterialColor.java
@@ -1,6 +1,8 @@
 package net.minecraft.core.block.material;
 
 
+import it.unimi.dsi.fastutil.ints.Int2IntMap;
+import it.unimi.dsi.fastutil.ints.Int2IntOpenHashMap;
 import net.minecraft.core.block.Block;
 import net.minecraft.core.block.Blocks;
 
@@ -80,7 +82,7 @@ public class MaterialColor {
     public static final MaterialColor paintedRed = new MaterialColor(62, 0xed33434);
     public static final MaterialColor paintedBlack = new MaterialColor(63, 0x020202);
     // <<<<< Painted Colors pallet >>>>>
-    private static final Map<Integer, Integer> blockIdColorIndexMap = new HashMap<>();
+    private static final Int2IntMap blockIdColorIndexMap = new Int2IntOpenHashMap();
     private final int col;
     public final int id;
     private MaterialColor(int id, int col)
diff --git a/game/core/src/main/java/net/minecraft/core/block/tag/BlockTags.java b/game/core/src/main/java/net/minecraft/core/block/tag/BlockTags.java
index e038508dc..5b4bd4295 100644
--- a/game/core/src/main/java/net/minecraft/core/block/tag/BlockTags.java
+++ b/game/core/src/main/java/net/minecraft/core/block/tag/BlockTags.java
@@ -38,148 +38,148 @@ public abstract class BlockTags
     /**
      * block can be mined by {@link ItemToolPickaxe ItemToolPickaxe}.
      */
-    public static Tag<Block<?>> MINEABLE_BY_PICKAXE = Tag.of("mineable_by_pickaxe");
+    public static final Tag<Block<?>> MINEABLE_BY_PICKAXE = Tag.of("mineable_by_pickaxe");
     /**
      * block can be mined by {@link ItemToolAxe ItemToolAxe}.
      */
-    public static Tag<Block<?>> MINEABLE_BY_AXE = Tag.of("mineable_by_axe");
+    public static final Tag<Block<?>> MINEABLE_BY_AXE = Tag.of("mineable_by_axe");
     /**
      * block can be mined by {@link ItemToolShovel ItemToolShovel}.
      */
-    public static Tag<Block<?>> MINEABLE_BY_SHOVEL = Tag.of("mineable_by_shovel");
+    public static final Tag<Block<?>> MINEABLE_BY_SHOVEL = Tag.of("mineable_by_shovel");
     /**
      * block can be mined by {@link ItemToolHoe ItemToolHoe}.
      */
-    public static Tag<Block<?>> MINEABLE_BY_HOE = Tag.of("mineable_by_hoe");
+    public static final Tag<Block<?>> MINEABLE_BY_HOE = Tag.of("mineable_by_hoe");
     /**
      * block can be mined by {@link ItemToolSword ItemToolSword}.
      */
-    public static Tag<Block<?>> MINEABLE_BY_SWORD = Tag.of("mineable_by_sword");
+    public static final Tag<Block<?>> MINEABLE_BY_SWORD = Tag.of("mineable_by_sword");
     /**
      * block can be mined by {@link ItemToolShears ItemShears}.
      */
-    public static Tag<Block<?>> MINEABLE_BY_SHEARS = Tag.of("mineable_by_shears");
+    public static final Tag<Block<?>> MINEABLE_BY_SHEARS = Tag.of("mineable_by_shears");
     /**
      * derived block has the properties of water.
      */
-    public static Tag<Block<?>> IS_WATER = Tag.of("is_water");
+    public static final Tag<Block<?>> IS_WATER = Tag.of("is_water");
     /**
      * derived block has the properties of lava.
      */
-    public static Tag<Block<?>> IS_LAVA = Tag.of("is_lava");
+    public static final Tag<Block<?>> IS_LAVA = Tag.of("is_lava");
     /**
      * {@link BlockLogicFlower BlockFlower}-derived blocks can be placed on this block.
      */
-    public static Tag<Block<?>> GROWS_FLOWERS = Tag.of("grows_flowers");
+    public static final Tag<Block<?>> GROWS_FLOWERS = Tag.of("grows_flowers");
     /**
      * {@link BlockLogicSugarcane BlockSugarcane} can be placed on this block.
      */
-    public static Tag<Block<?>> GROWS_SUGAR_CANE = Tag.of("grows_sugar_cane");
+    public static final Tag<Block<?>> GROWS_SUGAR_CANE = Tag.of("grows_sugar_cane");
     /**
      * {@link BlockLogicCactus BlockCactus} can be placed on this block.
      */
-    public static Tag<Block<?>> GROWS_CACTI = Tag.of("grows_cacti");
+    public static final Tag<Block<?>> GROWS_CACTI = Tag.of("grows_cacti");
     /**
      * {@link net.minecraft.core.world.generate.feature.tree.WorldFeatureTree WorldFeatureTree} and its variations can be placed on this block.
      */
-    public static Tag<Block<?>> GROWS_TREES = Tag.of("grows_trees");
-    public static Tag<Block<?>> GROWS_SPINIFEX = Tag.of("grows_spinifex");
+    public static final Tag<Block<?>> GROWS_TREES = Tag.of("grows_trees");
+    public static final Tag<Block<?>> GROWS_SPINIFEX = Tag.of("grows_spinifex");
     /**
      * This block is destroyed when {@link BlockLogicFluid BlockFluid}-derived blocks try to move into its space.
      */
-    public static Tag<Block<?>> BROKEN_BY_FLUIDS = Tag.of("broken_by_fluids");
+    public static final Tag<Block<?>> BROKEN_BY_FLUIDS = Tag.of("broken_by_fluids");
     /**
      * The block can have other blocks placed "into" it, like how {@link BlockLogicTallGrass BlockTallGrass} behaves.
      */
-    public static Tag<Block<?>> PLACE_OVERWRITES = Tag.of("place_overwrites");
+    public static final Tag<Block<?>> PLACE_OVERWRITES = Tag.of("place_overwrites");
     /**
      * Passive mobs can spawn on this block.
      */
-    public static Tag<Block<?>> PASSIVE_MOBS_SPAWN = Tag.of("passive_mobs_spawn");
+    public static final Tag<Block<?>> PASSIVE_MOBS_SPAWN = Tag.of("passive_mobs_spawn");
     /**
      * {@link MobFireflyCluster MobFireflyCluster} can spawn on this block.
      */
-    public static Tag<Block<?>> FIREFLIES_CAN_SPAWN = Tag.of("fireflies_can_spawn");
+    public static final Tag<Block<?>> FIREFLIES_CAN_SPAWN = Tag.of("fireflies_can_spawn");
     /**
      * {@link BlockLogicFence BlockFence} visually connects to this block.
      */
-    public static Tag<Block<?>> FENCES_CONNECT = Tag.of("fences_connect");
+    public static final Tag<Block<?>> FENCES_CONNECT = Tag.of("fences_connect");
     /**
      * This block does <b>not</b> appear in the creative menu.
      */
-    public static Tag<Block<?>> NOT_IN_CREATIVE_MENU = Tag.of("not_in_creative_menu");
+    public static final Tag<Block<?>> NOT_IN_CREATIVE_MENU = Tag.of("not_in_creative_menu");
     /**
      * This block drops as if using a silk touch tool when broken by {@link ItemToolShears ItemShears}.
      */
-    public static Tag<Block<?>> SHEARS_DO_SILK_TOUCH = Tag.of("shears_do_silk_touch");
+    public static final Tag<Block<?>> SHEARS_DO_SILK_TOUCH = Tag.of("shears_do_silk_touch");
     /**
      * This block can be skated on using {@link net.minecraft.core.item.Items#ARMOR_BOOTS_ICESKATES ice skates}.
      */
-    public static Tag<Block<?>> SKATEABLE = Tag.of("skateable");
+    public static final Tag<Block<?>> SKATEABLE = Tag.of("skateable");
     /**
      * Detects grass surface blocks so that {@link CavesLargeFeature MapGenCaves} can replace any exposed dirt with grass once it has finished generating a surface cave.
      */
-    public static Tag<Block<?>> CAVE_GEN_REPLACES_SURFACE = Tag.of("cave_gen_replaces_surface");
+    public static final Tag<Block<?>> CAVE_GEN_REPLACES_SURFACE = Tag.of("cave_gen_replaces_surface");
     /**
      * Determines which blocks {@link CavesLargeFeature MapGenCaves} can cut through
      */
-    public static Tag<Block<?>> CAVES_CUT_THROUGH = Tag.of("caves_cut_through");
+    public static final Tag<Block<?>> CAVES_CUT_THROUGH = Tag.of("caves_cut_through");
     /**
      * Blocks such as {@link BlockLogicLanternFirefly BlockLanternFirefly} can hang off this block.
      */
-    public static Tag<Block<?>> CAN_HANG_OFF = Tag.of("can_hang_off");
+    public static final Tag<Block<?>> CAN_HANG_OFF = Tag.of("can_hang_off");
     /**
      * Blocks like snow layers play their own sound when walking in them, instead of the sound of the block below
      */
-    public static Tag<Block<?>> OVERRIDE_STEPSOUND = Tag.of("override_stepsound");
+    public static final Tag<Block<?>> OVERRIDE_STEPSOUND = Tag.of("override_stepsound");
     /**
      * {@link BlockLogicFenceChainlink BlockFenceChainlink} visually connects to this block.
      */
-    public static Tag<Block<?>> CHAINLINK_FENCES_CONNECT = Tag.of("chainlink_fences_connect");
+    public static final Tag<Block<?>> CHAINLINK_FENCES_CONNECT = Tag.of("chainlink_fences_connect");
     /**
      * Prevent mobs from spawning inside these blocks. Used for blocks with no collision like rails and redstone components
      */
-    public static Tag<Block<?>> PREVENT_MOB_SPAWNS = Tag.of("prevent_mob_spawns");
+    public static final Tag<Block<?>> PREVENT_MOB_SPAWNS = Tag.of("prevent_mob_spawns");
     /**
      * Block can be planted inside a {@link BlockLogicJar JarBlock}
      */
-    public static Tag<Block<?>> PLANTABLE_IN_JAR = Tag.of("plantable_in_jar");
+    public static final Tag<Block<?>> PLANTABLE_IN_JAR = Tag.of("plantable_in_jar");
     /**
      * Block allows fire to burn forever on it {@link BlockLogicFire BlockFire}
      */
-    public static Tag<Block<?>> INFINITE_BURN = Tag.of("infinite_burn");
+    public static final Tag<Block<?>> INFINITE_BURN = Tag.of("infinite_burn");
     /**
      * Block allows fire to burn forever on it {@link BlockFire BlockFire}
      */
-    public static Tag<Block<?>> INFINITE_BURN_COLD = Tag.of("infinite_burn_cold");
+    public static final Tag<Block<?>> INFINITE_BURN_COLD = Tag.of("infinite_burn_cold");
     /**
      * Block is broken on contact with an {@link EntityBoat EntityBoat}
      */
-    public static Tag<Block<?>> BOAT_BREAKS = Tag.of("boat_breaks");
+    public static final Tag<Block<?>> BOAT_BREAKS = Tag.of("boat_breaks");
     /**
      * Block extends the range of a motion sensor's sight.
      */
-    public static Tag<Block<?>> EXTENDS_MOTION_SENSOR_RANGE = Tag.of("extends_motion_sensor_range");
+    public static final Tag<Block<?>> EXTENDS_MOTION_SENSOR_RANGE = Tag.of("extends_motion_sensor_range");
     /**
      * When broken, items go into the player's inventory immediately instead of being dropped
      */
-    public static Tag<Block<?>> INSTANT_PICKUP = Tag.of("instant_pickup");
+    public static final Tag<Block<?>> INSTANT_PICKUP = Tag.of("instant_pickup");
     /**
      * Sheep will follow the player if they are holding this block.
      */
-    public static Tag<Block<?>> SHEEPS_FAVOURITE_BLOCK = Tag.of("sheeps_favourite_block");
+    public static final Tag<Block<?>> SHEEPS_FAVOURITE_BLOCK = Tag.of("sheeps_favourite_block");
     /**
      * Pigs will follow the player if they are holding this block.
      */
-    public static Tag<Block<?>> PIGS_FAVOURITE_BLOCK = Tag.of("pigs_favourite_block");
+    public static final Tag<Block<?>> PIGS_FAVOURITE_BLOCK = Tag.of("pigs_favourite_block");
     /**
      * Nether mobs can spawn on this block {@link MobZombiePig MobZombiePig}}.
      */
-    public static Tag<Block<?>> NETHER_MOBS_SPAWN = Tag.of("nether_mobs_spawn");
+    public static final Tag<Block<?>> NETHER_MOBS_SPAWN = Tag.of("nether_mobs_spawn");
     /**
      * Will drop block when piston extends into it
      */
-    public static Tag<Block<?>> PISTON_CRUSHING = Tag.of("piston_crushing");
+    public static final Tag<Block<?>> PISTON_CRUSHING = Tag.of("piston_crushing");
 
     public static List<Tag<Block<?>>> TAG_LIST;
 
diff --git a/game/core/src/main/java/net/minecraft/core/crafting/LookupFuelFurnace.java b/game/core/src/main/java/net/minecraft/core/crafting/LookupFuelFurnace.java
index b086c770c..1ca5ca011 100644
--- a/game/core/src/main/java/net/minecraft/core/crafting/LookupFuelFurnace.java
+++ b/game/core/src/main/java/net/minecraft/core/crafting/LookupFuelFurnace.java
@@ -1,5 +1,7 @@
 package net.minecraft.core.crafting;
 
+import it.unimi.dsi.fastutil.ints.Int2IntMap;
+import it.unimi.dsi.fastutil.ints.Int2IntOpenHashMap;
 import net.minecraft.core.item.Items;
 import net.minecraft.core.block.Blocks;
 
@@ -9,7 +11,7 @@ import java.util.Map;
 public class LookupFuelFurnace {
 
 	public static final LookupFuelFurnace instance = new LookupFuelFurnace();
-	protected final Map<Integer, Integer> fuelList = new HashMap<>();
+	protected final Int2IntMap fuelList = new Int2IntOpenHashMap();
 
 	protected LookupFuelFurnace() {
 		register();
@@ -89,10 +91,10 @@ public class LookupFuelFurnace {
 	}
 
 	public int getFuelYield(int id) {
-		return fuelList.get(id) == null ? 0 : fuelList.get(id);
+		return fuelList.getOrDefault(id, 0);
 	}
 
-	public Map<Integer, Integer> getFuelList() {
+	public Int2IntMap getFuelList() {
 		return fuelList;
 	}
 
diff --git a/game/core/src/main/java/net/minecraft/core/data/legacy/LegacyBiomes.java b/game/core/src/main/java/net/minecraft/core/data/legacy/LegacyBiomes.java
index 50d0fb1ad..b83ef34f1 100644
--- a/game/core/src/main/java/net/minecraft/core/data/legacy/LegacyBiomes.java
+++ b/game/core/src/main/java/net/minecraft/core/data/legacy/LegacyBiomes.java
@@ -1,5 +1,10 @@
 package net.minecraft.core.data.legacy;
 
+import it.unimi.dsi.fastutil.ints.Int2ObjectArrayMap;
+import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
+import it.unimi.dsi.fastutil.objects.Object2IntArrayMap;
+import it.unimi.dsi.fastutil.objects.Object2IntMap;
+import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap;
 import net.minecraft.core.world.biome.Biome;
 import net.minecraft.core.world.biome.Biomes;
 
@@ -8,8 +13,8 @@ import java.util.Map;
 
 public abstract class LegacyBiomes
 {
-    private static final Map<Integer, Biome> idToBiomeMap = new HashMap<>();
-    private static final Map<Biome, Integer> biomeToIdMap = new HashMap<>();
+    private static final Int2ObjectMap<Biome> idToBiomeMap = new Int2ObjectArrayMap<>();
+    private static final Object2IntMap<Biome> biomeToIdMap = new Object2IntArrayMap<>();
 
     private static void register(Biome biome, int id)
     {
@@ -24,7 +29,7 @@ public abstract class LegacyBiomes
 
     public static int getBiomeId(Biome biome)
     {
-        return biomeToIdMap.get(biome);
+        return biomeToIdMap.getInt(biome);
     }
 
     static
diff --git a/game/core/src/main/java/net/minecraft/core/data/legacy/LegacyWorldTypes.java b/game/core/src/main/java/net/minecraft/core/data/legacy/LegacyWorldTypes.java
index 53eb26ac7..c140cae3b 100644
--- a/game/core/src/main/java/net/minecraft/core/data/legacy/LegacyWorldTypes.java
+++ b/game/core/src/main/java/net/minecraft/core/data/legacy/LegacyWorldTypes.java
@@ -1,5 +1,9 @@
 package net.minecraft.core.data.legacy;
 
+import it.unimi.dsi.fastutil.ints.Int2ObjectArrayMap;
+import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
+import it.unimi.dsi.fastutil.objects.Object2IntArrayMap;
+import it.unimi.dsi.fastutil.objects.Object2IntMap;
 import net.minecraft.core.world.type.WorldType;
 import net.minecraft.core.world.type.WorldTypes;
 
@@ -8,8 +12,8 @@ import java.util.Map;
 
 public abstract class LegacyWorldTypes
 {
-    private static final Map<Integer, WorldType> idToWorldTypeMap = new HashMap<>();
-    private static final Map<WorldType, Integer> worldTypeToIdMap = new HashMap<>();
+    private static final Int2ObjectMap<WorldType> idToWorldTypeMap = new Int2ObjectArrayMap<>();
+    private static final Object2IntMap<WorldType> worldTypeToIdMap = new Object2IntArrayMap<>();
     private static final Map<String, WorldType> keyToWorldTypeMap = new HashMap<>();
     private static final Map<WorldType, String> worldTypeToKeyMap = new HashMap<>();
 
@@ -33,7 +37,7 @@ public abstract class LegacyWorldTypes
 
     public static int getWorldTypeId(WorldType worldType)
     {
-        return worldTypeToIdMap.get(worldType);
+        return worldTypeToIdMap.getInt(worldType);
     }
 
     public static String getWorldTypeKey(WorldType worldType)
diff --git a/game/core/src/main/java/net/minecraft/core/data/registry/Registry.java b/game/core/src/main/java/net/minecraft/core/data/registry/Registry.java
index 1d4331d20..0cea76c87 100644
--- a/game/core/src/main/java/net/minecraft/core/data/registry/Registry.java
+++ b/game/core/src/main/java/net/minecraft/core/data/registry/Registry.java
@@ -3,6 +3,8 @@ package net.minecraft.core.data.registry;
 import com.mojang.nbt.tags.CompoundTag;
 import com.mojang.nbt.tags.IntTag;
 import com.mojang.nbt.tags.Tag;
+import it.unimi.dsi.fastutil.ints.Int2ObjectArrayMap;
+import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
 
 import java.util.*;
 
@@ -163,16 +165,16 @@ public class Registry<T>
         }
     }
 
-    public static Map<Integer, String> readIdMapFromTag(CompoundTag tag)
+    public static Int2ObjectMap<String> readIdMapFromTag(CompoundTag tag)
     {
-        Map<Integer, String> map = new HashMap<>();
+        Int2ObjectMap<String> map = new Int2ObjectArrayMap<>();
 
         for (Map.Entry<String, Tag<?>> entry : tag.getValue().entrySet())
         {
             if (!(entry.getValue() instanceof IntTag)) continue;
 
             IntTag iTag = (IntTag) entry.getValue();
-            map.put(iTag.getValue(), entry.getKey());
+            map.put(iTag.getValue().intValue(), entry.getKey());
         }
 
         return map;
diff --git a/game/core/src/main/java/net/minecraft/core/data/registry/recipe/adapter/ItemStackJsonAdapter.java b/game/core/src/main/java/net/minecraft/core/data/registry/recipe/adapter/ItemStackJsonAdapter.java
index 08628163d..6d0b22d96 100644
--- a/game/core/src/main/java/net/minecraft/core/data/registry/recipe/adapter/ItemStackJsonAdapter.java
+++ b/game/core/src/main/java/net/minecraft/core/data/registry/recipe/adapter/ItemStackJsonAdapter.java
@@ -36,9 +36,9 @@ public class ItemStackJsonAdapter implements JsonDeserializer<ItemStack>, JsonSe
             String key = obj.get("key").getAsString();
             try {
                 if (key.startsWith("tile.")){
-                    item = Item.itemsList[Blocks.keyToIdMap.get(key)];
+                    item = Item.itemsList[Blocks.keyToIdMap.getInt(key)];
                 } else if (key.startsWith("item.")){
-                    item = Item.itemsList[Item.nameToIdMap.get(key)];
+                    item = Item.itemsList[Item.nameToIdMap.getInt(key)];
                 } else {
                     throw new IllegalArgumentException("Item keys must either start with 'tile' or 'item' provided key '" + key + "' does not!");
                 }
diff --git a/game/core/src/main/java/net/minecraft/core/data/registry/recipe/entry/RecipeEntryMapDuplication.java b/game/core/src/main/java/net/minecraft/core/data/registry/recipe/entry/RecipeEntryMapDuplication.java
index 579e940ce..1962f2bbe 100644
--- a/game/core/src/main/java/net/minecraft/core/data/registry/recipe/entry/RecipeEntryMapDuplication.java
+++ b/game/core/src/main/java/net/minecraft/core/data/registry/recipe/entry/RecipeEntryMapDuplication.java
@@ -26,9 +26,9 @@ public class RecipeEntryMapDuplication extends RecipeEntryCraftingDynamic{
             if (s != null)
             {
                 Item item = s.getItem();
-                if (item == Items.MAP) {
+                if (item == Items.MAP && ItemMap.hasInitialized(s)) {
                     map = s;
-                } else if (item == Items.PAPER) {
+                } else if (item == Items.MAP && !ItemMap.hasInitialized(s)) {
                     paperAmount++;
                 }
             }
@@ -63,12 +63,12 @@ public class RecipeEntryMapDuplication extends RecipeEntryCraftingDynamic{
                 if(stack == null) {
                     continue;
                 }
-                if(stack.itemID == Items.MAP.id) {
+                if(stack.itemID == Items.MAP.id && ItemMap.hasInitialized(stack)) {
                     if(mapStack != null) {
                         return false;
                     }
                     mapStack = stack;
-                } else if(stack.itemID == Items.PAPER.id){
+                } else if(stack.itemID == Items.MAP.id && !ItemMap.hasInitialized(stack)){
                     hasPaper = true;
                 }else {
                     return false;
diff --git a/game/core/src/main/java/net/minecraft/core/entity/EntityDispatcher.java b/game/core/src/main/java/net/minecraft/core/entity/EntityDispatcher.java
index 74a64f93d..48c24361f 100644
--- a/game/core/src/main/java/net/minecraft/core/entity/EntityDispatcher.java
+++ b/game/core/src/main/java/net/minecraft/core/entity/EntityDispatcher.java
@@ -1,6 +1,13 @@
 package net.minecraft.core.entity;
 
 import com.mojang.logging.LogUtils;
+import it.unimi.dsi.fastutil.ints.Int2ObjectArrayMap;
+import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
+import it.unimi.dsi.fastutil.ints.Int2ObjectMaps;
+import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
+import it.unimi.dsi.fastutil.objects.Object2IntArrayMap;
+import it.unimi.dsi.fastutil.objects.Object2IntMap;
+import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap;
 import net.minecraft.core.entity.animal.*;
 import net.minecraft.core.entity.monster.*;
 import net.minecraft.core.entity.player.Player;
@@ -27,9 +34,9 @@ public final class EntityDispatcher
     public static final Map<NamespaceID, Class<? extends Entity>> idToClassMap = new HashMap<>();
     public static final Map<String, Class<? extends Entity>> stringIdToClassMap = new HashMap<>();
 
-    private static final Map<Integer, Class<? extends Entity>> numericIdToClassMap = new HashMap<>();
-    private static final Map<Integer, String> numericIdToStringIdMap = new HashMap<>();
-    private static final Map<Class<? extends Entity>, Integer> classToNumericIdMap = new HashMap<>();
+    private static final Int2ObjectMap<Class<? extends Entity>> numericIdToClassMap = new Int2ObjectOpenHashMap<>();
+    private static final Int2ObjectMap<String> numericIdToStringIdMap = new Int2ObjectOpenHashMap<>();
+    private static final Object2IntMap<Class<? extends Entity>> classToNumericIdMap = new Object2IntOpenHashMap<>();
 
     private static final Map<Class<? extends Entity>, String> classToNameKeyMap = new HashMap<>();
 
@@ -82,28 +89,28 @@ public final class EntityDispatcher
         return classToNumericIdMap.getOrDefault(entityClass, -1);
     }
 
-    public static void setNumericIds(Map<Integer, String> mapping) {
+    public static void setNumericIds(final @NotNull Int2ObjectMap<String> mapping) {
         numericIdToClassMap.clear();
         numericIdToStringIdMap.clear();
         classToNumericIdMap.clear();
-        for (Map.Entry<Integer, String> entry : mapping.entrySet()) {
-            Class<? extends Entity> entityClass = classForId(entry.getValue());
+        for (final Int2ObjectMap.Entry<String> entry : mapping.int2ObjectEntrySet()) {
+            final Class<? extends Entity> entityClass = classForId(entry.getValue());
             if (entityClass == null) {
                 LOGGER.error("Could not find entityClass assigned to namespace id {}! Skipping!", entry.getValue());
                 continue;
             }
 
-            numericIdToClassMap.put(entry.getKey(), entityClass);
-            numericIdToStringIdMap.put(entry.getKey(), entry.getValue());
-            classToNumericIdMap.put(entityClass, entry.getKey());
+            numericIdToClassMap.put(entry.getIntKey(), entityClass);
+            numericIdToStringIdMap.put(entry.getIntKey(), entry.getValue());
+            classToNumericIdMap.put(entityClass, entry.getIntKey());
 
-            if (entry.getKey() >= mappingCount) {
-                mappingCount = entry.getKey() + 1;
+            if (entry.getIntKey() >= mappingCount) {
+                mappingCount = entry.getIntKey() + 1;
             }
         }
     }
 
-    public static Map<Integer, String> getEntityIds() {
+    public static Int2ObjectMap<String> getEntityIds() {
         return numericIdToStringIdMap;
     }
 
@@ -229,8 +236,8 @@ public final class EntityDispatcher
     public static class Legacy {
         public static final Map<String, Class<? extends Entity>> keyToClassMap = new HashMap<>();
         public static final Map<Class<? extends Entity>, String> classToKeyMap = new HashMap<>();
-        private static final Map<Integer, Class<? extends Entity>> idToClassMap = new HashMap<>();
-        private static final Map<Class<? extends Entity>, Integer> classToIdMap = new HashMap<>();
+        private static final Int2ObjectMap<Class<? extends Entity>> idToClassMap = new Int2ObjectArrayMap<>();
+        private static final Object2IntMap<Class<? extends Entity>> classToIdMap = new Object2IntArrayMap<>();
 
         private static int maxIdSize = 0;
 
diff --git a/game/core/src/main/java/net/minecraft/core/entity/animal/MobButterfly.java b/game/core/src/main/java/net/minecraft/core/entity/animal/MobButterfly.java
index 0676c72b1..26e40d478 100644
--- a/game/core/src/main/java/net/minecraft/core/entity/animal/MobButterfly.java
+++ b/game/core/src/main/java/net/minecraft/core/entity/animal/MobButterfly.java
@@ -1,6 +1,8 @@
 package net.minecraft.core.entity.animal;
 
 import com.mojang.nbt.tags.CompoundTag;
+import it.unimi.dsi.fastutil.ints.Int2ObjectArrayMap;
+import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
 import net.minecraft.core.Global;
 import net.minecraft.core.WeightedRandomBag;
 import net.minecraft.core.block.Block;
@@ -29,7 +31,7 @@ import java.util.Set;
 import java.util.function.Supplier;
 
 public class MobButterfly extends MobFlying implements AmbientCreature {
-    public static final Map<Integer, ButterflyEntry> colorEntries = new HashMap<>();
+    public static final Int2ObjectMap<ButterflyEntry> colorEntries = new Int2ObjectArrayMap<>();
 
     public static final int DATA_COLOR_ID = 16;
 
diff --git a/game/core/src/main/java/net/minecraft/core/entity/animal/MobFireflyCluster.java b/game/core/src/main/java/net/minecraft/core/entity/animal/MobFireflyCluster.java
index a2f44f0f9..145551dd7 100644
--- a/game/core/src/main/java/net/minecraft/core/entity/animal/MobFireflyCluster.java
+++ b/game/core/src/main/java/net/minecraft/core/entity/animal/MobFireflyCluster.java
@@ -1,6 +1,8 @@
 package net.minecraft.core.entity.animal;
 
 import com.mojang.nbt.tags.CompoundTag;
+import it.unimi.dsi.fastutil.ints.Int2ObjectArrayMap;
+import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
 import net.minecraft.core.block.Blocks;
 import net.minecraft.core.block.tag.BlockTags;
 import net.minecraft.core.entity.Entity;
@@ -432,7 +434,7 @@ public class MobFireflyCluster extends MobFlying
 	}
 
 	public static class FireflyColor {
-		public static Map<Integer, FireflyColor> fireFlyColors = new HashMap<>();
+		public static Int2ObjectMap<FireflyColor> fireFlyColors = new Int2ObjectArrayMap<>();
 		public static FireflyColor GREEN = register(new FireflyColor(0, "fireflyGreen", new Biome[] {
 				Biomes.OVERWORLD_RAINFOREST,
 				Biomes.OVERWORLD_SWAMPLAND,
diff --git a/game/core/src/main/java/net/minecraft/core/entity/monster/MobZombieArmored.java b/game/core/src/main/java/net/minecraft/core/entity/monster/MobZombieArmored.java
index 2a3423f1e..bcb1a9ca6 100644
--- a/game/core/src/main/java/net/minecraft/core/entity/monster/MobZombieArmored.java
+++ b/game/core/src/main/java/net/minecraft/core/entity/monster/MobZombieArmored.java
@@ -1,6 +1,8 @@
 package net.minecraft.core.entity.monster;
 
 import com.mojang.nbt.tags.CompoundTag;
+import it.unimi.dsi.fastutil.ints.IntArrayList;
+import it.unimi.dsi.fastutil.ints.IntList;
 import net.minecraft.core.entity.Entity;
 import net.minecraft.core.entity.EntityItem;
 import net.minecraft.core.entity.IItemHolding;
@@ -41,7 +43,7 @@ public class MobZombieArmored extends MobZombie implements IItemHolding
         super.spawnInit();
         Random rand = new Random();
         setHoldingSword(rand.nextInt(5)==0);
-        List<Integer> armorItems = new ArrayList<>();
+        IntList armorItems = new IntArrayList();
         armorItems.add(0);
         armorItems.add(1);
         armorItems.add(2);
@@ -50,8 +52,8 @@ public class MobZombieArmored extends MobZombie implements IItemHolding
         for (int i = 0; i < 4; i++)
         {
             int index = rand.nextInt(armorItems.size());
-            armorBreakOrder[i] = armorItems.get(index);
-            armorItems.remove(index);
+            armorBreakOrder[i] = armorItems.getInt(index);
+            armorItems.removeInt(index);
         }
         setArmorBreakOrder(armorBreakOrder);
         int[] armorBreakPoints = new int[4];
diff --git a/game/core/src/main/java/net/minecraft/core/item/Item.java b/game/core/src/main/java/net/minecraft/core/item/Item.java
index a2208d855..bc62d1e4a 100644
--- a/game/core/src/main/java/net/minecraft/core/item/Item.java
+++ b/game/core/src/main/java/net/minecraft/core/item/Item.java
@@ -1,6 +1,8 @@
 package net.minecraft.core.item;
 
 import com.mojang.nbt.tags.CompoundTag;
+import it.unimi.dsi.fastutil.objects.Object2IntMap;
+import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap;
 import net.minecraft.core.achievement.stat.Stat;
 import net.minecraft.core.achievement.stat.StatItem;
 import net.minecraft.core.achievement.stat.StatList;
@@ -34,7 +36,7 @@ import java.util.function.Supplier;
 public class Item implements ITaggable<Item>, IItemConvertible
 {
     protected static final Random itemRand = new Random();
-    public static final Map<String, Integer> nameToIdMap = new HashMap<>();
+    public static final Object2IntMap<String> nameToIdMap = new Object2IntOpenHashMap<>();
 
     public static final @Nullable Item @NotNull [] itemsList = new Item[32768];
     public static final Map<NamespaceID, Item> itemsMap = new LinkedHashMap<>();
@@ -53,19 +55,19 @@ public class Item implements ITaggable<Item>, IItemConvertible
 
     // Made this take an actual NamespaceID in the constructor to actually throw errors for modders when they update their mods, otherwise would be mistaken for the old lang key + item id constructor
 
-    public Item(NamespaceID namespaceId, int id)
+    public Item(final NamespaceID namespaceId, final int id)
     {
-        maxStackSize = 64;
-        maxDamage = 0;
-        hasSubtypes = false;
-        containerItem = null;
+        this.maxStackSize = 64;
+        this.maxDamage = 0;
+        this.hasSubtypes = false;
+        this.containerItem = null;
         this.id = id;
         this.namespaceID = namespaceId.makePermanent();
         if (itemsList[id] != null) {
             throw new IllegalArgumentException("Item slot '" + id + "' is already occupied by '" + itemsList[id] + "' when adding " + this);
         }
         if (itemsMap.containsKey(this.namespaceID)){
-            throw new IllegalArgumentException("Item id '" + namespaceID + "' is already used by '" + itemsMap.get(this.namespaceID) + "' when adding " + this);
+            throw new IllegalArgumentException("Item id '" + this.namespaceID + "' is already used by '" + itemsMap.get(this.namespaceID) + "' when adding " + this);
         }
 
         itemsList[this.id] = this;
@@ -74,39 +76,39 @@ public class Item implements ITaggable<Item>, IItemConvertible
         if (this.id > highestItemId)
             highestItemId = this.id;
     }
-    public Item(String translationKey, String namespaceId, int id)
+    public Item(final String translationKey, final String namespaceId, final int id)
     {
         this(makeNamespaceID(namespaceId), id);
         setKey(translationKey);
     }
 
-    private static NamespaceID makeNamespaceID(String string){ // This exists because java is idiotic
+    private static NamespaceID makeNamespaceID(final String string){ // This exists because java is idiotic
         try {
             return NamespaceID.getPermanent(string);
-        } catch (HardIllegalArgumentException e) {
+        } catch (final HardIllegalArgumentException e) {
             throw new IllegalArgumentException(e);
         }
     }
-    public Stat createStat(String statID, String nameKey){
+    public Stat createStat(final String statID, final String nameKey){
         if (getStat(statID) != null) return getStat(statID);
 
         Stat stat;
-        if (StatList.replacementMap.containsKey(id)){
-            Item replaceItem = Item.getItem(StatList.replacementMap.get(id));
+        if (StatList.replacementMap.containsKey(this.id)){
+            final Item replaceItem = Item.getItem(StatList.replacementMap.get(this.id));
             stat = replaceItem.getStat(statID);
             if (stat == null){
                 stat = replaceItem.createStat(statID, nameKey);
             }
         } else {
-            stat = new StatItem(NamespaceID.getPermanent(namespaceID.namespace(), namespaceID.value() + "_" + statID), nameKey, id).registerStat();
+            stat = new StatItem(NamespaceID.getPermanent(this.namespaceID.namespace(), this.namespaceID.value() + "_" + statID), nameKey, this.id).registerStat();
         }
 
         putStat(statID, stat);
         return stat;
     }
 
-    public void putStat(String statID, Stat stat){
-        stats.put(statID, stat);
+    public void putStat(final String statID, final Stat stat){
+        this.stats.put(statID, stat);
         statsInCategory.putIfAbsent(statID, new ArrayList<>());
         if (!statsInCategory.get(statID).contains(stat)){
             statsInCategory.get(statID).add(stat);
@@ -114,31 +116,31 @@ public class Item implements ITaggable<Item>, IItemConvertible
     }
 
     @Nullable
-    public Stat getStat(String statID){
-        return stats.get(statID);
+    public Stat getStat(final String statID){
+        return this.stats.get(statID);
     }
 
-    public Item setStatParent(@NotNull Supplier<@NotNull IItemConvertible> icon){
+    public Item setStatParent(@NotNull final Supplier<@NotNull IItemConvertible> icon){
         this.statParent = icon;
         return this;
     }
 
     @Nullable
     public Item getStatParent(){
-        if (statParent != null){
-            return statParent.get().asItem();
+        if (this.statParent != null){
+            return this.statParent.get().asItem();
         }
         return null;
     }
 
     @Nullable
-    public static List<Stat> getStats(String statID){
+    public static List<Stat> getStats(final String statID){
         return statsInCategory.get(statID);
     }
 
-    public Item withTags(Tag<Item>... tags)
+    public Item withTags(final Tag<Item>... tags)
     {
-        for (Tag<Item> tag : tags)
+        for (final Tag<Item> tag : tags)
         {
             tag.tag(this);
         }
@@ -146,46 +148,46 @@ public class Item implements ITaggable<Item>, IItemConvertible
         return this;
     }
 
-    public boolean hasTag(Tag<Item> tag)
+    public boolean hasTag(final Tag<Item> tag)
     {
         return tag.appliesTo(this);
     }
 
-    public Item setMaxStackSize(int maxStackSize)
+    public Item setMaxStackSize(final int maxStackSize)
     {
         this.maxStackSize = maxStackSize;
         return this;
     }
 
-    public boolean onUseItemOnBlock(@NotNull ItemStack itemstack, @Nullable Player player, @NotNull World world, int blockX, int blockY, int blockZ, @NotNull Side side, double xPlaced, double yPlaced)
+    public boolean onUseItemOnBlock(@NotNull final ItemStack itemstack, @Nullable final Player player, @NotNull final World world, final int blockX, final int blockY, final int blockZ, @NotNull final Side side, final double xPlaced, final double yPlaced)
     {
         return false;
     }
 
-    public void onUseByActivator(ItemStack itemStack, TileEntityActivator activatorBlock, World world, Random random, int blockX, int blockY, int blockZ, double offX, double offY, double offZ, Direction direction) {
+    public void onUseByActivator(final ItemStack itemStack, final TileEntityActivator activatorBlock, final World world, final Random random, final int blockX, final int blockY, final int blockZ, final double offX, final double offY, final double offZ, final Direction direction) {
     }
 
-    public float getStrVsBlock(ItemStack itemstack, Block<?> block)
+    public float getStrVsBlock(final ItemStack itemstack, final Block<?> block)
     {
         return 1.0F;
     }
 
-    public ItemStack onUseItem(ItemStack itemstack, World world, Player entityplayer)
+    public ItemStack onUseItem(final ItemStack itemstack, final World world, final Player entityplayer)
     {
         return itemstack;
     }
 
-    public int getItemStackLimit(@Nullable ItemStack itemStack)
+    public int getItemStackLimit(@Nullable final ItemStack itemStack)
     {
-        return maxStackSize;
+        return this.maxStackSize;
     }
     
     public boolean getHasSubtypes()
     {
-        return hasSubtypes;
+        return this.hasSubtypes;
     }
 
-    protected Item setHasSubtypes(boolean hasSubtypes)
+    protected Item setHasSubtypes(final boolean hasSubtypes)
     {
         this.hasSubtypes = hasSubtypes;
         return this;
@@ -196,23 +198,23 @@ public class Item implements ITaggable<Item>, IItemConvertible
         return getMaxDamageForStack(null);
     }
 
-    public int getMaxDamageForStack(@Nullable ItemStack itemStack)
+    public int getMaxDamageForStack(@Nullable final ItemStack itemStack)
     {
-        return maxDamage;
+        return this.maxDamage;
     }
 
-    protected Item setMaxDamage(int i)
+    protected Item setMaxDamage(final int i)
     {
-        maxDamage = i;
+        this.maxDamage = i;
         return this;
     }
 
     public boolean isDamagable()
     {
-        return maxDamage > 0 && !hasSubtypes;
+        return this.maxDamage > 0 && !this.hasSubtypes;
     }
 
-    public boolean hitEntity(ItemStack itemstack, Mob target, Mob attacker)
+    public boolean hitEntity(final ItemStack itemstack, final Mob target, final Mob attacker)
     {
         return false;
     }
@@ -220,52 +222,52 @@ public class Item implements ITaggable<Item>, IItemConvertible
     /**
      * Called before a block is destroyed with this item. If the return value is false, the block won't be destroyed
      */
-    public boolean beforeDestroyBlock(World world, ItemStack itemStack, int blockId, int x, int y, int z, Side side, Player player)
+    public boolean beforeDestroyBlock(final World world, final ItemStack itemStack, final int blockId, final int x, final int y, final int z, final Side side, final Player player)
     {
     	return true;
     }
 
-    public boolean onBlockDestroyed(World world, ItemStack itemstack, int removedBlockId, int x, int y, int z, Side side, Mob mob)
+    public boolean onBlockDestroyed(final World world, final ItemStack itemstack, final int removedBlockId, final int x, final int y, final int z, final Side side, final Mob mob)
     {
         return false;
     }
 
-    public int getDamageVsEntity(Entity entity, ItemStack itemStack)
+    public int getDamageVsEntity(final Entity entity, final ItemStack itemStack)
     {
         return 1;
     }
 
-    public boolean canHarvestBlock(Mob mob, ItemStack itemStack, Block<?> block)
+    public boolean canHarvestBlock(final Mob mob, final ItemStack itemStack, final Block<?> block)
     {
         return false;
     }
 
-    public boolean useItemOnEntity(ItemStack itemstack, Mob mob, Player player)
+    public boolean useItemOnEntity(final ItemStack itemstack, final Mob mob, final Player player)
     {
         return false;
     }
 
-    public Item setKey(String s)
+    public Item setKey(final String s)
     {
-        key = "item." + s;
-        nameToIdMap.put(key, this.id);
+        this.key = "item." + s;
+        nameToIdMap.put(this.key, this.id);
         return this;
     }
 
     public String getKey()
     {
-        return key;
+        return this.key;
     }
 
-    public String getLanguageKey(ItemStack itemstack)
+    public String getLanguageKey(final ItemStack itemstack)
     {
-        return key;
+        return this.key;
     }
-    public String getTranslatedName(ItemStack itemstack) {
+    public String getTranslatedName(final ItemStack itemstack) {
         return I18n.getInstance().translateKey(itemstack.getItemKey() + ".name");
     }
 
-    public String getTranslatedDescription(ItemStack itemstack) {
+    public String getTranslatedDescription(final ItemStack itemstack) {
         return I18n.getInstance().translateKey(itemstack.getItemKey() + ".desc");
     }
 
@@ -273,26 +275,26 @@ public class Item implements ITaggable<Item>, IItemConvertible
         return new CompoundTag();
     }
 
-    public Item setContainerItem(Item item)
+    public Item setContainerItem(final Item item)
     {
-        if(maxStackSize > 1)
+        if(this.maxStackSize > 1)
         {
             throw new IllegalArgumentException("Max stack size must be 1 for items with crafting results");
         } else
         {
-            containerItem = item;
+            this.containerItem = item;
             return this;
         }
     }
 
     public Item getContainerItem()
     {
-        return containerItem;
+        return this.containerItem;
     }
 
     public boolean hasContainerItem()
     {
-        return containerItem != null;
+        return this.containerItem != null;
     }
 
     public String getStatName()
@@ -300,11 +302,11 @@ public class Item implements ITaggable<Item>, IItemConvertible
         return I18n.getInstance().translateKey(getKey() + ".name");
     }
 
-    public void inventoryTick(ItemStack itemstack, World world, Entity entity, int slotId, boolean flag)
+    public void inventoryTick(final ItemStack itemstack, final World world, final Entity entity, final int slotId, final boolean flag)
     {
     }
 
-    public void onCraftedBy(ItemStack itemstack, World world, Player entityplayer)
+    public void onCraftedBy(final ItemStack itemstack, final World world, final Player entityplayer)
     {
     }
 
@@ -317,7 +319,7 @@ public class Item implements ITaggable<Item>, IItemConvertible
     	return false;
     }
 
-    public ItemStack onInventoryInteract(Player player, Slot slot, ItemStack stackInSlot, boolean isItemGrabbed) {
+    public ItemStack onInventoryInteract(final Player player, final Slot slot, final ItemStack stackInSlot, final boolean isItemGrabbed) {
     	return stackInSlot;
     }
 
@@ -326,7 +328,7 @@ public class Item implements ITaggable<Item>, IItemConvertible
     }
 
     @Override
-    public boolean isIn(Tag<Item> tag) {
+    public boolean isIn(final Tag<Item> tag) {
         return tag.appliesTo(this);
     }
 
@@ -340,14 +342,14 @@ public class Item implements ITaggable<Item>, IItemConvertible
         return new ItemStack(this);
     }
 
-    public static boolean hasTag(ItemStack itemStack, Tag<Item> tag) {
+    public static boolean hasTag(final ItemStack itemStack, final Tag<Item> tag) {
     	if(itemStack == null) {
     		return false;
     	}
     	return tag.appliesTo(itemsList[itemStack.itemID]);
     }
     @Nullable
-    public static Item getItem(int id) {
+    public static Item getItem(final int id) {
         return itemsList[Math.max(id, 0)];
     }
 }
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 1937dc62b..0a31d74d1 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
@@ -1,5 +1,9 @@
 package net.minecraft.core.item;
 
+import it.unimi.dsi.fastutil.ints.Int2IntMap;
+import it.unimi.dsi.fastutil.ints.Int2IntOpenHashMap;
+import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
+import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
 import net.minecraft.core.block.Blocks;
 import net.minecraft.core.block.entity.TileEntityFlag;
 import net.minecraft.core.block.material.Material;
@@ -23,7 +27,7 @@ import java.util.Map;
 
 public class ItemMap extends Item implements IComplexItem
 {
-	private static final Map<Integer, Map<Integer, Integer>> blockCounts = new HashMap<>();
+	private static final Int2ObjectMap<Int2IntMap> blockCounts = new Int2ObjectOpenHashMap<>();
     protected ItemMap(String name, String namespaceId, int id)
     {
         super(name, namespaceId, id);
@@ -201,10 +205,10 @@ public class ItemMap extends Item implements IComplexItem
 					int rand = blockX + blockZ * 0x389bf;
 					rand = rand * rand * 0x1dd6751 + rand * 11;
 					if((rand >> 20 & 1) == 0) {
-						blockCounts.putIfAbsent(Blocks.DIRT.id(), new HashMap<>());
+						if (!blockCounts.containsKey(Blocks.DIRT.id())) blockCounts.put(Blocks.DIRT.id(), new Int2IntOpenHashMap());
 						blockCounts.get(Blocks.DIRT.id()).put(-1, blockCounts.get(Blocks.DIRT.id()).getOrDefault(-1, 0) + 10);
 					} else {
-						blockCounts.putIfAbsent(Blocks.STONE.id(), new HashMap<>());
+						if (!blockCounts.containsKey(Blocks.STONE.id())) blockCounts.put(Blocks.STONE.id(), new Int2IntOpenHashMap());
 						blockCounts.get(Blocks.STONE.id()).put(-1, blockCounts.get(Blocks.STONE.id()).getOrDefault(-1, 0) + 10);
 					}
 					pixelHeight = 100D;
@@ -237,7 +241,7 @@ public class ItemMap extends Item implements IComplexItem
 							}
 							pixelHeight += (double) height / (double) (blocksPerPixel * blocksPerPixel);
                             int meta = chunk.getBlockMetadata(_x + blockInChunkX, height, _z + blockInChunkZ);
-							blockCounts.putIfAbsent(id, new HashMap<>());
+							if (!blockCounts.containsKey(id)) blockCounts.put(id, new Int2IntOpenHashMap());
 							blockCounts.get(id).put(-1, blockCounts.get(id).getOrDefault(-1, 0) + 1);
 							blockCounts.get(id).put(meta, blockCounts.get(id).getOrDefault(meta, 0) + 1);
 						}
@@ -249,9 +253,9 @@ public class ItemMap extends Item implements IComplexItem
 				
 				int max = 0;
 				int id = 0;
-				for (Map.Entry<Integer, Map<Integer, Integer>> e : blockCounts.entrySet()){
+				for (Int2ObjectMap.Entry<Int2IntMap> e : blockCounts.int2ObjectEntrySet()){
 					if (e.getValue().getOrDefault(-1, -1) > max){
-						id = e.getKey();
+						id = e.getIntKey();
 						max = e.getValue().get(-1);
 					}
 				}
diff --git a/game/core/src/main/java/net/minecraft/core/item/tool/ItemToolPickaxe.java b/game/core/src/main/java/net/minecraft/core/item/tool/ItemToolPickaxe.java
index 0b2bae886..2bdaf8aa8 100644
--- a/game/core/src/main/java/net/minecraft/core/item/tool/ItemToolPickaxe.java
+++ b/game/core/src/main/java/net/minecraft/core/item/tool/ItemToolPickaxe.java
@@ -1,8 +1,7 @@
 package net.minecraft.core.item.tool;
 
-import java.util.HashMap;
-import java.util.Map;
-
+import it.unimi.dsi.fastutil.objects.Object2IntMap;
+import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap;
 import net.minecraft.core.block.Block;
 import net.minecraft.core.block.Blocks;
 import net.minecraft.core.block.tag.BlockTags;
@@ -12,7 +11,7 @@ import net.minecraft.core.item.material.ToolMaterial;
 
 public class ItemToolPickaxe extends ItemTool {
 	
-	public static Map<Block<?>, Integer> miningLevels = new HashMap<>();
+	public static final Object2IntMap<Block<?>> miningLevels = new Object2IntOpenHashMap<>();
 	
 	static {
 		miningLevels.put(Blocks.OBSIDIAN, 3);
@@ -56,15 +55,15 @@ public class ItemToolPickaxe extends ItemTool {
 		miningLevels.put(Blocks.ORE_REDSTONE_GLOWING_LIMESTONE, 2);
 	}
 	
-	public ItemToolPickaxe(String name, String namespaceId, int id, ToolMaterial enumtoolmaterial) {
+	public ItemToolPickaxe(final String name, final String namespaceId, final int id, final ToolMaterial enumtoolmaterial) {
 		super(name, namespaceId, id, 2, enumtoolmaterial, BlockTags.MINEABLE_BY_PICKAXE);
 	}
 
 	@Override
-	public boolean canHarvestBlock(Mob mob, ItemStack itemStack, Block<?> block)
+	public boolean canHarvestBlock(final Mob mob, final ItemStack itemStack, final Block<?> block)
 	{
-		Integer miningLevel = miningLevels.get(block);
-		if(miningLevel != null) return material.getMiningLevel() >= miningLevel;
+		final int miningLevel = miningLevels.getOrDefault(block, -1);
+		if(miningLevel != -1) return this.material.getMiningLevel() >= miningLevel;
 		
 		return block.hasTag(BlockTags.MINEABLE_BY_PICKAXE);
 	}
diff --git a/game/core/src/main/java/net/minecraft/core/net/command/arguments/ArgumentTypeDimension.java b/game/core/src/main/java/net/minecraft/core/net/command/arguments/ArgumentTypeDimension.java
index fc27fffc8..7c4a80c57 100644
--- a/game/core/src/main/java/net/minecraft/core/net/command/arguments/ArgumentTypeDimension.java
+++ b/game/core/src/main/java/net/minecraft/core/net/command/arguments/ArgumentTypeDimension.java
@@ -6,6 +6,7 @@ import com.mojang.brigadier.context.CommandContext;
 import com.mojang.brigadier.exceptions.CommandSyntaxException;
 import com.mojang.brigadier.suggestion.Suggestions;
 import com.mojang.brigadier.suggestion.SuggestionsBuilder;
+import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
 import net.minecraft.core.lang.I18n;
 import net.minecraft.core.net.command.util.CommandHelper;
 import net.minecraft.core.world.Dimension;
@@ -27,8 +28,8 @@ public class ArgumentTypeDimension implements ArgumentType<Dimension> {
     public Dimension parse(StringReader reader) throws CommandSyntaxException {
         final String string = reader.readString();
 
-        for (Map.Entry<Integer, Dimension> dimension : Dimension.getDimensionList().entrySet()) {
-            if (CommandHelper.matchesKeyString(dimension.getValue().languageKey, string) || string.equals(String.valueOf(dimension.getKey()))) {
+        for (Int2ObjectMap.Entry<Dimension> dimension : Dimension.getDimensionList().int2ObjectEntrySet()) {
+            if (CommandHelper.matchesKeyString(dimension.getValue().languageKey, string) || string.equals(String.valueOf(dimension.getIntKey()))) {
                 return dimension.getValue();
             }
         }
diff --git a/game/core/src/main/java/net/minecraft/core/net/command/arguments/ArgumentTypeTime.java b/game/core/src/main/java/net/minecraft/core/net/command/arguments/ArgumentTypeTime.java
index a084a1512..4e4edea84 100644
--- a/game/core/src/main/java/net/minecraft/core/net/command/arguments/ArgumentTypeTime.java
+++ b/game/core/src/main/java/net/minecraft/core/net/command/arguments/ArgumentTypeTime.java
@@ -8,23 +8,23 @@ import com.mojang.brigadier.exceptions.Dynamic2CommandExceptionType;
 import com.mojang.brigadier.exceptions.SimpleCommandExceptionType;
 import com.mojang.brigadier.suggestion.Suggestions;
 import com.mojang.brigadier.suggestion.SuggestionsBuilder;
+import it.unimi.dsi.fastutil.objects.Object2IntArrayMap;
+import it.unimi.dsi.fastutil.objects.Object2IntMap;
 import net.minecraft.core.lang.I18n;
 import net.minecraft.core.net.command.util.CommandHelper;
 
 import java.util.Arrays;
 import java.util.Collection;
-import java.util.HashMap;
-import java.util.Map;
 import java.util.concurrent.CompletableFuture;
 
 public class ArgumentTypeTime implements ArgumentType<Integer> {
     private static final Collection<String> EXAMPLES = Arrays.asList("0d", "0s", "0t", "0");
     private static final SimpleCommandExceptionType ERROR_INVALID_UNIT = new SimpleCommandExceptionType(() -> I18n.getInstance().translateKey("command.argument_types.time.invalid_unit"));
     private static final Dynamic2CommandExceptionType ERROR_TICK_COUNT_TOO_LOW = new Dynamic2CommandExceptionType((object, object2) -> () -> I18n.getInstance().translateKeyAndFormat("command.argument_types.time.tick_count_too_low", object2, object));
-    private static final Map<String, Integer> UNITS = new HashMap<>();
+    private static final Object2IntMap<String> UNITS = new Object2IntArrayMap<>();
     final int minimum;
 
-    private ArgumentTypeTime(int i) {
+    private ArgumentTypeTime(final int i) {
         this.minimum = i;
     }
     
@@ -32,19 +32,19 @@ public class ArgumentTypeTime implements ArgumentType<Integer> {
         return new ArgumentTypeTime(Integer.MIN_VALUE);
     }
 
-    public static ArgumentTypeTime time(int i) {
+    public static ArgumentTypeTime time(final int i) {
         return new ArgumentTypeTime(i);
     }
 
     @Override
-    public Integer parse(StringReader stringReader) throws CommandSyntaxException {
-        float f = stringReader.readFloat();
-        String string = stringReader.readUnquotedString();
-        int i = UNITS.getOrDefault(string, 0);
+    public Integer parse(final StringReader stringReader) throws CommandSyntaxException {
+        final float f = stringReader.readFloat();
+        final String string = stringReader.readUnquotedString();
+        final int i = UNITS.getOrDefault(string, 0);
         if (i == 0) {
             throw ERROR_INVALID_UNIT.create();
         }
-        int j = Math.round(f * (float)i);
+        final int j = Math.round(f * (float)i);
         if (j < this.minimum) {
             throw ERROR_TICK_COUNT_TOO_LOW.create(j, this.minimum);
         }
@@ -52,11 +52,11 @@ public class ArgumentTypeTime implements ArgumentType<Integer> {
     }
 
     @Override
-    public <S> CompletableFuture<Suggestions> listSuggestions(CommandContext<S> commandContext, SuggestionsBuilder suggestionsBuilder) {
-        StringReader stringReader = new StringReader(suggestionsBuilder.getRemaining());
+    public <S> CompletableFuture<Suggestions> listSuggestions(final CommandContext<S> commandContext, final SuggestionsBuilder suggestionsBuilder) {
+        final StringReader stringReader = new StringReader(suggestionsBuilder.getRemaining());
         try {
             stringReader.readFloat();
-        } catch (CommandSyntaxException commandSyntaxException) {
+        } catch (final CommandSyntaxException commandSyntaxException) {
             return suggestionsBuilder.buildFuture();
         }
         return CommandHelper.suggest(UNITS.keySet(), suggestionsBuilder.createOffset(suggestionsBuilder.getStart() + stringReader.getCursor()));
diff --git a/game/core/src/main/java/net/minecraft/core/net/command/util/NbtHelper.java b/game/core/src/main/java/net/minecraft/core/net/command/util/NbtHelper.java
index 6fb79088c..60078ff34 100644
--- a/game/core/src/main/java/net/minecraft/core/net/command/util/NbtHelper.java
+++ b/game/core/src/main/java/net/minecraft/core/net/command/util/NbtHelper.java
@@ -15,6 +15,12 @@ import com.mojang.nbt.tags.ShortArrayTag;
 import com.mojang.nbt.tags.ShortTag;
 import com.mojang.nbt.tags.StringTag;
 import com.mojang.nbt.tags.Tag;
+import it.unimi.dsi.fastutil.bytes.ByteArrayList;
+import it.unimi.dsi.fastutil.bytes.ByteList;
+import it.unimi.dsi.fastutil.doubles.DoubleArrayList;
+import it.unimi.dsi.fastutil.doubles.DoubleList;
+import it.unimi.dsi.fastutil.shorts.ShortArrayList;
+import it.unimi.dsi.fastutil.shorts.ShortList;
 import net.minecraft.core.net.command.exceptions.CommandExceptions;
 
 import java.util.ArrayList;
@@ -86,7 +92,7 @@ public class NbtHelper {
             if (reader.peek() == ']') return new ByteArrayTag();
             else if (reader.peek() == ';') {
                 reader.skip();
-                List<Byte> bytes = new ArrayList<>();
+                ByteList bytes = new ByteArrayList();
                 while (reader.canRead() && reader.peek() != ']') {
                     reader.skipWhitespace();
                     String byteAsString = reader.readString();
@@ -100,7 +106,7 @@ public class NbtHelper {
                 reader.skipWhitespace();
                 if (reader.canRead() && reader.peek() == ']') {
                     reader.skip();
-                    return new ByteArrayTag(byteListToArray(bytes));
+                    return new ByteArrayTag(bytes.toByteArray());
                 }
                 throw CommandExceptions.expectedEndOfTag().create();
             }
@@ -114,7 +120,7 @@ public class NbtHelper {
             }
             else if (reader.peek() == ';') {
                 reader.skip();
-                List<Short> shorts = new ArrayList<>();
+                ShortList shorts = new ShortArrayList();
                 while (reader.canRead() && reader.peek() != ']') {
                     reader.skipWhitespace();
                     String shortAsString = reader.readString();
@@ -129,7 +135,7 @@ public class NbtHelper {
 
                 if (reader.canRead() && reader.peek() == ']') {
                     reader.skip();
-                    return new ShortArrayTag(shortListToArray(shorts));
+                    return new ShortArrayTag(shorts.toShortArray());
                 }
                 else throw CommandExceptions.expectedEndOfTag().create();
             }
@@ -143,7 +149,7 @@ public class NbtHelper {
             }
             else if (reader.peek() == ';') {
                 reader.skip();
-                List<Double> doubles = new ArrayList<>();
+                DoubleList doubles = new DoubleArrayList();
                 while (reader.canRead() && reader.peek() != ']') {
                     reader.skipWhitespace();
                     String doubleAsString = reader.readString();
@@ -162,7 +168,7 @@ public class NbtHelper {
                 reader.skipWhitespace();
                 if (reader.canRead() && reader.peek() == ']') {
                     reader.skip();
-                    return new DoubleArrayTag(doubles.stream().mapToDouble(Double::doubleValue).toArray());
+                    return new DoubleArrayTag(doubles.toDoubleArray());
                 }
                 else throw CommandExceptions.expectedEndOfTag().create();
             }
@@ -185,26 +191,6 @@ public class NbtHelper {
         throw CommandExceptions.incomplete().create();
     }
 
-    private static short[] shortListToArray(List<Short> shorts) {
-        short[] arr = new short[shorts.size()];
-
-        for (int i = 0; i < shorts.size(); i++) {
-            arr[i] = shorts.get(i);
-        }
-
-        return arr;
-    }
-
-    private static byte[] byteListToArray(List<Byte> bytes) {
-        byte[] arr = new byte[bytes.size()];
-
-        for (int i = 0; i < bytes.size(); i++) {
-            arr[i] = bytes.get(i);
-        }
-
-        return arr;
-    }
-
     private static Tag<?> type(String string) {
         try {
             if ("true".equalsIgnoreCase(string)) {
diff --git a/game/core/src/main/java/net/minecraft/core/net/entity/NetEntityHandler.java b/game/core/src/main/java/net/minecraft/core/net/entity/NetEntityHandler.java
index de6868f89..18413628b 100644
--- a/game/core/src/main/java/net/minecraft/core/net/entity/NetEntityHandler.java
+++ b/game/core/src/main/java/net/minecraft/core/net/entity/NetEntityHandler.java
@@ -1,5 +1,9 @@
 package net.minecraft.core.net.entity;
 
+import it.unimi.dsi.fastutil.ints.Int2ObjectArrayMap;
+import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
+import it.unimi.dsi.fastutil.objects.Object2IntArrayMap;
+import it.unimi.dsi.fastutil.objects.Object2IntMap;
 import net.minecraft.core.net.entity.entries.NetEntryAnimal;
 import net.minecraft.core.net.entity.entries.NetEntryArrow;
 import net.minecraft.core.net.entity.entries.NetEntryBoat;
@@ -32,8 +36,8 @@ public class NetEntityHandler {
     private static final List<INetworkEntry<?>> netEntries = new ArrayList<>();
     private static final List<IPacketEntry<?>> packetEntries = new ArrayList<>();
     private static final List<ITrackedEntry<?>> trackedEntries = new ArrayList<>();
-    private static final Map<Integer, IVehicleEntry<?>> typeToProviderMap = new HashMap<>();
-    private static final Map<IVehicleEntry<?>, Integer> providerToTypeMap = new HashMap<>();
+    private static final Int2ObjectMap<IVehicleEntry<?>> typeToProviderMap = new Int2ObjectArrayMap<>();
+    private static final Object2IntMap<IVehicleEntry<?>> providerToTypeMap = new Object2IntArrayMap<>();
     private static boolean isListDirty = false;
     public static <T> void registerNetworkEntry(INetworkEntry<T> networkEntity){
         addEntryRaw(networkEntity, -1);
@@ -52,7 +56,7 @@ public class NetEntityHandler {
             entryClassMap.remove(entityClass);
 
             if (type >= 0 && typeToProviderMap.containsKey(type)){
-                providerToTypeMap.remove(typeToProviderMap.remove(type));
+                providerToTypeMap.removeInt(typeToProviderMap.remove(type));
             }
         }
         entryClassMap.put(entityClass, entry);
@@ -83,7 +87,7 @@ public class NetEntityHandler {
             if (netEnt.getAppliedClass().isAssignableFrom(trackerEntry.getTrackedEntity().getClass())){
                 Packet packet;
                 if (netEnt instanceof IVehicleEntry){
-                    packet = ((IVehicleEntry)netEnt).getSpawnPacket(trackerEntry, trackerEntry.getTrackedEntity()).setType(providerToTypeMap.get(netEnt));
+                    packet = ((IVehicleEntry)netEnt).getSpawnPacket(trackerEntry, trackerEntry.getTrackedEntity()).setType(providerToTypeMap.getInt(netEnt));
                 } else {
                     packet = netEnt.getSpawnPacket(trackerEntry, trackerEntry.getTrackedEntity());
                 }
diff --git a/game/core/src/main/java/net/minecraft/core/net/packet/Packet.java b/game/core/src/main/java/net/minecraft/core/net/packet/Packet.java
index 88a4042c9..ebb157a66 100644
--- a/game/core/src/main/java/net/minecraft/core/net/packet/Packet.java
+++ b/game/core/src/main/java/net/minecraft/core/net/packet/Packet.java
@@ -3,6 +3,17 @@ package net.minecraft.core.net.packet;
 import com.mojang.logging.LogUtils;
 import com.mojang.nbt.tags.CompoundTag;
 import com.mojang.nbt.NbtIo;
+import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
+import it.unimi.dsi.fastutil.ints.Int2ObjectMaps;
+import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
+import it.unimi.dsi.fastutil.ints.IntArrayList;
+import it.unimi.dsi.fastutil.ints.IntArrays;
+import it.unimi.dsi.fastutil.ints.IntList;
+import it.unimi.dsi.fastutil.ints.IntOpenHashSet;
+import it.unimi.dsi.fastutil.ints.IntSet;
+import it.unimi.dsi.fastutil.objects.Object2IntMap;
+import it.unimi.dsi.fastutil.objects.Object2IntMaps;
+import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap;
 import net.minecraft.core.Global;
 import net.minecraft.core.net.handler.PacketHandler;
 import org.slf4j.Logger;
@@ -16,22 +27,17 @@ import java.io.EOFException;
 import java.io.IOException;
 import java.nio.charset.StandardCharsets;
 import java.util.Arrays;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
 import java.util.List;
-import java.util.Map;
-import java.util.Set;
 import java.util.UUID;
 
 public abstract class Packet
 {
     private static final Logger LOGGER = LogUtils.getLogger();
-    private static final List<Integer> INTERESTING_PACKETS = Arrays.asList(50, 51, 52);
-    private static final Map<Integer, Class<? extends Packet>> packetIdToClassMap = new HashMap<>();
-    private static final Map<Class<? extends Packet>, Integer> packetClassToIdMap = new HashMap<>();
-    private static final Set<Integer> clientBoundPacketIds = new HashSet<>();
-    private static final Set<Integer> serverBoundPacketIds = new HashSet<>();
+    private static final IntList INTERESTING_PACKETS = IntArrayList.of(50, 51, 52);
+    private static final Int2ObjectMap<Class<? extends Packet>> packetIdToClassMap = new Int2ObjectOpenHashMap<>();
+    private static final Object2IntMap<Class<? extends Packet>> packetClassToIdMap = new Object2IntOpenHashMap<>();
+    private static final IntSet clientBoundPacketIds = new IntOpenHashSet();
+    private static final IntSet serverBoundPacketIds = new IntOpenHashSet();
 
     public static final int MAX_USERNAME_SIZE = 16;
     public static final int MAX_NICKNAME_SIZE = 256;
@@ -82,7 +88,7 @@ public abstract class Packet
 
     public final int getId()
     {
-        return packetClassToIdMap.get(getClass());
+        return packetClassToIdMap.getInt(getClass());
     }
 
     public static Packet readPacket(DataInputStream dis, boolean isServer) throws IOException {
@@ -229,12 +235,12 @@ public abstract class Packet
         return new UUID(msb, lsb);
     }
 
-    public static Map<Class<? extends Packet>, Integer> getPacketClassToIdMap() {
-        return Collections.unmodifiableMap(packetClassToIdMap);
+    public static Object2IntMap<Class<? extends Packet>> getPacketClassToIdMap() {
+        return Object2IntMaps.unmodifiable(packetClassToIdMap);
     }
 
-    public static Map<Integer, Class<? extends Packet>> getPacketIdToClassMap() {
-        return Collections.unmodifiableMap(packetIdToClassMap);
+    public static Int2ObjectMap<Class<? extends Packet>> getPacketIdToClassMap() {
+        return Int2ObjectMaps.unmodifiable(packetIdToClassMap);
     }
 
     public abstract void read(DataInputStream dis)
diff --git a/game/core/src/main/java/net/minecraft/core/net/packet/PacketSyncIDs.java b/game/core/src/main/java/net/minecraft/core/net/packet/PacketSyncIDs.java
index 1504f896e..d37e8f14a 100644
--- a/game/core/src/main/java/net/minecraft/core/net/packet/PacketSyncIDs.java
+++ b/game/core/src/main/java/net/minecraft/core/net/packet/PacketSyncIDs.java
@@ -7,6 +7,8 @@ import java.util.HashMap;
 import java.util.Map;
 import java.util.Map.Entry;
 
+import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
+import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
 import net.minecraft.core.net.handler.PacketHandler;
 
 public class PacketSyncIDs extends Packet {
@@ -17,19 +19,19 @@ public class PacketSyncIDs extends Packet {
 	private int packetSize;
 
 	public int destinationId = -1;
-	public Map<Integer, String> mapping;
+	public Int2ObjectMap<String> mapping;
 
 	public PacketSyncIDs() {
 
 	}
 
-	public PacketSyncIDs(int destinationId, Map<Integer, String> mapping) {
+	public PacketSyncIDs(final int destinationId, final Int2ObjectMap<String> mapping) {
 		this.destinationId = destinationId;
 		this.mapping = mapping;
 	}
 
 	@Override
-	public void read(DataInputStream in) throws IOException {
+	public void read(final DataInputStream in) throws IOException {
 		int size = 0;
 		
 		size += readIds(in);
@@ -38,7 +40,7 @@ public class PacketSyncIDs extends Packet {
 	}
 
 	@Override
-	public void write(DataOutputStream out) throws IOException {
+	public void write(final DataOutputStream out) throws IOException {
 		int size = 0;
 		
 		size += writeIds(out);
@@ -46,33 +48,33 @@ public class PacketSyncIDs extends Packet {
 		this.packetSize = size;
 	}
 	
-	public int readIds(DataInputStream in) throws IOException {
-		this.mapping = new HashMap<>();
+	public int readIds(final DataInputStream in) throws IOException {
+		this.mapping = new Int2ObjectOpenHashMap<>();
 		
 		int bytesRead = 0;
 
 		this.destinationId = in.readByte() & 0xFF;
-		int count = in.readInt();
+		final int count = in.readInt();
 		bytesRead += 4;
 		
 		for(int i=0; i < count; i++) {
-			int id = in.readShort() & 0xFFFF;
-			String name = readStringUTF8(in, MAX_ID_STRING_SIZE);
-			mapping.put(id, name);
+			final int id = in.readShort() & 0xFFFF;
+			final String name = readStringUTF8(in, MAX_ID_STRING_SIZE);
+            this.mapping.put(id, name);
 		}
 		
 		return bytesRead;
 	}
 	
-	public int writeIds(DataOutputStream out) throws IOException {
+	public int writeIds(final DataOutputStream out) throws IOException {
 		int bytesWritten = 0;
 
-		out.writeByte(destinationId);
-		out.writeInt(mapping.size());
+		out.writeByte(this.destinationId);
+		out.writeInt(this.mapping.size());
 		bytesWritten += 4;
 		
-		for(Entry<Integer, String> entry : mapping.entrySet()) {
-			out.writeShort(entry.getKey());
+		for(final Int2ObjectMap.Entry<String> entry : this.mapping.int2ObjectEntrySet()) {
+			out.writeShort(entry.getIntKey());
 			writeStringUTF8(entry.getValue(), out);
 		}
 		
@@ -80,13 +82,13 @@ public class PacketSyncIDs extends Packet {
 	}
 
 	@Override
-	public void handlePacket(PacketHandler packetHandler) {
+	public void handlePacket(final PacketHandler packetHandler) {
 		packetHandler.handleIds(this);
 	}
 
 	@Override
 	public int getEstimatedSize() {
-		return packetSize + 1;
+		return this.packetSize + 1;
 	}
 
 }
diff --git a/game/core/src/main/java/net/minecraft/core/player/inventory/menu/MenuAbstract.java b/game/core/src/main/java/net/minecraft/core/player/inventory/menu/MenuAbstract.java
index 995214f2b..694159663 100644
--- a/game/core/src/main/java/net/minecraft/core/player/inventory/menu/MenuAbstract.java
+++ b/game/core/src/main/java/net/minecraft/core/player/inventory/menu/MenuAbstract.java
@@ -3,12 +3,13 @@ package net.minecraft.core.player.inventory.menu;
 import java.util.*;
 
 import com.mojang.logging.LogUtils;
+import it.unimi.dsi.fastutil.ints.IntArrayList;
+import it.unimi.dsi.fastutil.ints.IntList;
 import net.minecraft.core.InventoryAction;
 import net.minecraft.core.Global;
 import net.minecraft.core.crafting.ContainerListener;
 import net.minecraft.core.entity.player.Player;
 import net.minecraft.core.enums.HumanArmorShape;
-import net.minecraft.core.enums.IArmorShape;
 import net.minecraft.core.item.IArmorItem;
 import net.minecraft.core.item.Item;
 import net.minecraft.core.item.ItemStack;
@@ -113,7 +114,7 @@ public abstract class MenuAbstract
 	public Slot getSlot(int i)
 	{
 		try{
-			return (Slot) slots.get(i);
+			return slots.get(i);
 		}catch (Exception e) {
 			return null;
 		}
@@ -481,8 +482,8 @@ public abstract class MenuAbstract
 		if(action == InventoryAction.MOVE_SINGLE_ITEM || action == InventoryAction.MOVE_STACK) {
 			if(stackInSlot == null) return;
 
-			List<Integer> targetSlots = getTargetSlots(action, slot, target, player);
-			if(targetSlots == null || targetSlots.size() == 0) {
+			IntList targetSlots = getTargetSlots(action, slot, target, player);
+			if(targetSlots == null || targetSlots.isEmpty()) {
 				return;
 			}
 
@@ -508,8 +509,8 @@ public abstract class MenuAbstract
 		}
 
 		if(action == InventoryAction.MOVE_ALL || action == InventoryAction.MOVE_SIMILAR) {
-			List<Integer> moveSlots = getMoveSlots(action, slot, target, player);
-			List<Integer> targetSlots = getTargetSlots(action, slot, target, player);
+			IntList moveSlots = getMoveSlots(action, slot, target, player);
+			IntList targetSlots = getTargetSlots(action, slot, target, player);
 
 			if(moveSlots == null || targetSlots == null) return;
 
@@ -576,7 +577,7 @@ public abstract class MenuAbstract
 			return;
 		}
 
-		List<Integer> resultSlots = getTargetSlots(action, slot, target, player);
+		IntList resultSlots = getTargetSlots(action, slot, target, player);
 		if(resultSlots == null) {
 			return;
 		}
@@ -610,7 +611,7 @@ public abstract class MenuAbstract
 	 * Returns the amount of space available for the given item in the given slots.
 	 * Stops when max stack size is reached.
 	 */
-	public int getFreeSpace(ItemStack item, List<Integer> slots) {
+	public int getFreeSpace(ItemStack item, IntList slots) {
 		int space = 0;
 		int max = item.getMaxStackSize();
 
@@ -636,16 +637,16 @@ public abstract class MenuAbstract
 	}
 
 	/**
-	 * Slots to move items from when using MOVE_ALL or MOVE_SIMILAR.
-	 * If the return value is null, MOVE_ALL and MOVE_SIMILAR won't do anything!
-	 */
-	public abstract List<Integer> getMoveSlots(InventoryAction action, Slot slot, int target, Player player);
+     * Slots to move items from when using MOVE_ALL or MOVE_SIMILAR.
+     * If the return value is null, MOVE_ALL and MOVE_SIMILAR won't do anything!
+     */
+	public abstract IntList getMoveSlots(InventoryAction action, Slot slot, int target, Player player);
 
 	/**
 	 * Slots to move items to when using any MOVE action.
 	 * If the return value is null, all MOVE actions won't do anything!
 	 */
-	public abstract List<Integer> getTargetSlots(InventoryAction action, Slot slot, int target, Player player);
+	public abstract IntList getTargetSlots(InventoryAction action, Slot slot, int target, Player player);
 
 	/**
 	 * Pick up all items similar to the one the player is holding.
@@ -843,7 +844,7 @@ public abstract class MenuAbstract
 	 * Merge the given ItemStack into the given slots.
 	 * First merge with items that can stack with the one given, then into empty slots
 	 */
-	public final void mergeItems(ItemStack stack, List<Integer> targetSlots) {
+	public final void mergeItems(ItemStack stack, IntList targetSlots) {
 		if(stack == null || targetSlots == null) return;
 
 		for(int i = 0; i < targetSlots.size(); i++) {
@@ -886,8 +887,8 @@ public abstract class MenuAbstract
 	 * Crash in development mode so its obvious something is wrong.
 	 * When not in development just skip this slot
 	 */
-	public Slot getSlotFromList(List<Integer> slots, int i) {
-		int slotId = slots.get(i);
+	public Slot getSlotFromList(IntList slots, int i) {
+		int slotId = slots.getInt(i);
 		Slot slot = getSlot(slotId);
 		if(slot == null && Global.BUILD_CHANNEL.isUnstableBuild()) {
 			throw new NullPointerException("Slot "+slotId+" does not exist!");
@@ -896,7 +897,7 @@ public abstract class MenuAbstract
 	}
 
 	public final void mergeItems(ItemStack stack, int targetSlot) {
-		List<Integer> list = new ArrayList<>();
+		IntList list = new IntArrayList();
 		list.add(targetSlot);
 		mergeItems(stack, list);
 	}
@@ -905,11 +906,11 @@ public abstract class MenuAbstract
 		mergeItems(stack, getSlots(minSlot, (maxSlot - minSlot) + 1, lastSlotFirst));
 	}
 
-	public List<Integer> getSlots(int min, int count, boolean lastSlotsFirst) {
-		return getSlots(new ArrayList<>(), min, count, lastSlotsFirst);
+	public IntList getSlots(int min, int count, boolean lastSlotsFirst) {
+		return getSlots(new IntArrayList(), min, count, lastSlotsFirst);
 	}
 
-	public List<Integer> getSlots(List<Integer> targetSlots, int min, int count, boolean lastSlotsFirst) {
+	public IntList getSlots(IntList targetSlots, int min, int count, boolean lastSlotsFirst) {
 		for(int i = 0; i < count; i++) {
 			targetSlots.add(lastSlotsFirst ? min + count - 1 - i : min + i);
 		}
diff --git a/game/core/src/main/java/net/minecraft/core/player/inventory/menu/MenuActivator.java b/game/core/src/main/java/net/minecraft/core/player/inventory/menu/MenuActivator.java
index 9a786aa01..ca13ca28a 100644
--- a/game/core/src/main/java/net/minecraft/core/player/inventory/menu/MenuActivator.java
+++ b/game/core/src/main/java/net/minecraft/core/player/inventory/menu/MenuActivator.java
@@ -1,5 +1,6 @@
 package net.minecraft.core.player.inventory.menu;
 
+import it.unimi.dsi.fastutil.ints.IntList;
 import net.minecraft.core.InventoryAction;
 import net.minecraft.core.block.entity.TileEntityActivator;
 import net.minecraft.core.crafting.ContainerListener;
@@ -8,8 +9,6 @@ import net.minecraft.core.item.ItemStack;
 import net.minecraft.core.player.inventory.container.Container;
 import net.minecraft.core.player.inventory.slot.Slot;
 
-import java.util.List;
-
 public class MenuActivator extends MenuAbstract {
 	public static final int ID_SELECTOR = 0;
 	public static final int ID_LOCKED_SLOTS = 1;
@@ -86,7 +85,7 @@ public class MenuActivator extends MenuAbstract {
 	}
 
 	@Override
-	public List<Integer> getMoveSlots(InventoryAction action, Slot slot, int target, Player player) {
+	public IntList getMoveSlots(InventoryAction action, Slot slot, int target, Player player) {
 		if(slot.index >= activatorSlotsStart && slot.index < inventorySlotsStart) {
 			return getSlots(activatorSlotsStart, 9, false);
 		}
@@ -108,7 +107,7 @@ public class MenuActivator extends MenuAbstract {
 	}
 
 	@Override
-	public List<Integer> getTargetSlots(InventoryAction action, Slot slot, int target, Player player) {
+	public IntList getTargetSlots(InventoryAction action, Slot slot, int target, Player player) {
 		if(slot.index >= activatorSlotsStart && slot.index < inventorySlotsStart) {
 			return getSlots(inventorySlotsStart, 36, false);
 		}else {
diff --git a/game/core/src/main/java/net/minecraft/core/player/inventory/menu/MenuContainer.java b/game/core/src/main/java/net/minecraft/core/player/inventory/menu/MenuContainer.java
index eb231d31c..207c66d2b 100644
--- a/game/core/src/main/java/net/minecraft/core/player/inventory/menu/MenuContainer.java
+++ b/game/core/src/main/java/net/minecraft/core/player/inventory/menu/MenuContainer.java
@@ -1,7 +1,6 @@
 package net.minecraft.core.player.inventory.menu;
 
-import java.util.List;
-
+import it.unimi.dsi.fastutil.ints.IntList;
 import net.minecraft.core.InventoryAction;
 import net.minecraft.core.entity.player.Player;
 import net.minecraft.core.player.inventory.container.Container;
@@ -42,7 +41,7 @@ public class MenuContainer extends MenuAbstract {
 	}
 	
 	@Override
-	public List<Integer> getMoveSlots(InventoryAction action, Slot slot, int target, Player player) {
+	public IntList getMoveSlots(InventoryAction action, Slot slot, int target, Player player) {
 		int chestSize = numberOfRows * 9;
 		
 		if(slot.index >= 0 && slot.index < chestSize) {
@@ -70,7 +69,7 @@ public class MenuContainer extends MenuAbstract {
 	}
 
 	@Override
-	public List<Integer> getTargetSlots(InventoryAction action, Slot slot, int target, Player player) {
+	public IntList getTargetSlots(InventoryAction action, Slot slot, int target, Player player) {
 		int chestSize = numberOfRows * 9;
 		
 		if(slot.index < chestSize) {
diff --git a/game/core/src/main/java/net/minecraft/core/player/inventory/menu/MenuCrafting.java b/game/core/src/main/java/net/minecraft/core/player/inventory/menu/MenuCrafting.java
index 7ff5c8ea1..b1a7fd616 100644
--- a/game/core/src/main/java/net/minecraft/core/player/inventory/menu/MenuCrafting.java
+++ b/game/core/src/main/java/net/minecraft/core/player/inventory/menu/MenuCrafting.java
@@ -1,5 +1,6 @@
 package net.minecraft.core.player.inventory.menu;
 
+import it.unimi.dsi.fastutil.ints.IntList;
 import net.minecraft.core.InventoryAction;
 import net.minecraft.core.block.Blocks;
 import net.minecraft.core.data.registry.Registries;
@@ -13,8 +14,6 @@ import net.minecraft.core.player.inventory.slot.Slot;
 import net.minecraft.core.player.inventory.slot.SlotResult;
 import net.minecraft.core.world.World;
 
-import java.util.List;
-
 public class MenuCrafting extends MenuAbstract
 {
 	public ContainerCrafting craftSlots;
@@ -101,7 +100,7 @@ public class MenuCrafting extends MenuAbstract
      */
     
     @Override
-    public List<Integer> getMoveSlots(InventoryAction action, Slot slot, int target, Player player) {
+    public IntList getMoveSlots(InventoryAction action, Slot slot, int target, Player player) {
     	if(slot.index == 0) {
     		// Craft Result
     		return getSlots(0, 1, false);
@@ -129,7 +128,7 @@ public class MenuCrafting extends MenuAbstract
     }
     
     @Override
-    public List<Integer> getTargetSlots(InventoryAction action, Slot slot, int target, Player player) {
+    public IntList getTargetSlots(InventoryAction action, Slot slot, int target, Player player) {
     	if(slot.index >= 10 && slot.index <= 45) {
     		// Full ContainerInventory
     		if(target == 1) {
diff --git a/game/core/src/main/java/net/minecraft/core/player/inventory/menu/MenuFlag.java b/game/core/src/main/java/net/minecraft/core/player/inventory/menu/MenuFlag.java
index bdcd6609a..10f7129ae 100644
--- a/game/core/src/main/java/net/minecraft/core/player/inventory/menu/MenuFlag.java
+++ b/game/core/src/main/java/net/minecraft/core/player/inventory/menu/MenuFlag.java
@@ -1,7 +1,6 @@
 package net.minecraft.core.player.inventory.menu;
 
-import java.util.List;
-
+import it.unimi.dsi.fastutil.ints.IntList;
 import net.minecraft.core.InventoryAction;
 import net.minecraft.core.block.entity.TileEntityFlag;
 import net.minecraft.core.entity.player.Player;
@@ -39,7 +38,7 @@ public class MenuFlag extends MenuAbstract {
 	 *  30 -  38 Hotbar
 	 */
 	@Override
-	public List<Integer> getMoveSlots(InventoryAction action, Slot slot, int target, Player player) {
+	public IntList getMoveSlots(InventoryAction action, Slot slot, int target, Player player) {
 		if(slot.index >= 0 && slot.index <= 2) {
 			// Dye Slots
 			return getSlots(0, 3, false);
@@ -61,7 +60,7 @@ public class MenuFlag extends MenuAbstract {
 	}
 
 	@Override
-	public List<Integer> getTargetSlots(InventoryAction action, Slot slot, int target, Player player) {
+	public IntList getTargetSlots(InventoryAction action, Slot slot, int target, Player player) {
 		if(slot.index >= 0 && slot.index <= 2) {
 			// Dye Slots
 			return getSlots(3, 36, false); // Into ContainerInventory
diff --git a/game/core/src/main/java/net/minecraft/core/player/inventory/menu/MenuFurnace.java b/game/core/src/main/java/net/minecraft/core/player/inventory/menu/MenuFurnace.java
index c31ffea49..f6890db3a 100644
--- a/game/core/src/main/java/net/minecraft/core/player/inventory/menu/MenuFurnace.java
+++ b/game/core/src/main/java/net/minecraft/core/player/inventory/menu/MenuFurnace.java
@@ -1,7 +1,6 @@
 package net.minecraft.core.player.inventory.menu;
 
-import java.util.List;
-
+import it.unimi.dsi.fastutil.ints.IntList;
 import net.minecraft.core.InventoryAction;
 import net.minecraft.core.block.entity.TileEntityFurnace;
 import net.minecraft.core.crafting.ContainerListener;
@@ -92,15 +91,15 @@ public class MenuFurnace extends MenuAbstract {
 	}
 
 	/**
-	 *  0 Input
-	 *  1 Fuel
-	 *  2 Output
-	 *  3 - 29 Main ContainerInventory (27x)
-	 * 30 - 38 Hotbar (9x)
-	 */
+     * 0 Input
+     * 1 Fuel
+     * 2 Output
+     * 3 - 29 Main ContainerInventory (27x)
+     * 30 - 38 Hotbar (9x)
+     */
 
 	@Override
-	public List<Integer> getMoveSlots(InventoryAction action, Slot slot, int target, Player player) {
+	public IntList getMoveSlots(InventoryAction action, Slot slot, int target, Player player) {
 		if(slot.index >= 0 && slot.index <= 3) return getSlots(slot.index, 1, false);
 
 		if(action == InventoryAction.MOVE_ALL) {
@@ -121,7 +120,7 @@ public class MenuFurnace extends MenuAbstract {
 	}
 
 	@Override
-	public List<Integer> getTargetSlots(InventoryAction action, Slot slot, int target, Player player) {
+	public IntList getTargetSlots(InventoryAction action, Slot slot, int target, Player player) {
 		if(slot.index >= 3 && slot.index <= 39) {
 			// Full ContainerInventory
 			if(action != InventoryAction.MOVE_ALL) {
diff --git a/game/core/src/main/java/net/minecraft/core/player/inventory/menu/MenuGuidebook.java b/game/core/src/main/java/net/minecraft/core/player/inventory/menu/MenuGuidebook.java
index 4f22ccf54..09a337965 100644
--- a/game/core/src/main/java/net/minecraft/core/player/inventory/menu/MenuGuidebook.java
+++ b/game/core/src/main/java/net/minecraft/core/player/inventory/menu/MenuGuidebook.java
@@ -1,12 +1,11 @@
 package net.minecraft.core.player.inventory.menu;
 
+import it.unimi.dsi.fastutil.ints.IntList;
 import net.minecraft.core.InventoryAction;
 import net.minecraft.core.entity.player.Player;
 import net.minecraft.core.item.ItemStack;
 import net.minecraft.core.player.inventory.slot.Slot;
 
-import java.util.List;
-
 public class MenuGuidebook extends MenuAbstract
 {
 
@@ -22,12 +21,12 @@ public class MenuGuidebook extends MenuAbstract
 	}
 
 	@Override
-	public List<Integer> getMoveSlots(InventoryAction action, Slot slot, int target, Player player) {
+	public IntList getMoveSlots(InventoryAction action, Slot slot, int target, Player player) {
 		return null;
 	}
 	
 	@Override
-	public List<Integer> getTargetSlots(InventoryAction action, Slot slot, int target, Player player) {
+	public IntList getTargetSlots(InventoryAction action, Slot slot, int target, Player player) {
 		return null;
 	}
 	
diff --git a/game/core/src/main/java/net/minecraft/core/player/inventory/menu/MenuInventory.java b/game/core/src/main/java/net/minecraft/core/player/inventory/menu/MenuInventory.java
index a69475996..c85448158 100644
--- a/game/core/src/main/java/net/minecraft/core/player/inventory/menu/MenuInventory.java
+++ b/game/core/src/main/java/net/minecraft/core/player/inventory/menu/MenuInventory.java
@@ -1,10 +1,10 @@
 package net.minecraft.core.player.inventory.menu;
 
+import it.unimi.dsi.fastutil.ints.IntList;
 import net.minecraft.core.InventoryAction;
 import net.minecraft.core.data.registry.Registries;
 import net.minecraft.core.entity.player.Player;
 import net.minecraft.core.enums.HumanArmorShape;
-import net.minecraft.core.item.IArmorItem;
 import net.minecraft.core.item.ItemStack;
 import net.minecraft.core.player.inventory.container.Container;
 import net.minecraft.core.player.inventory.container.ContainerCrafting;
@@ -14,8 +14,6 @@ import net.minecraft.core.player.inventory.slot.Slot;
 import net.minecraft.core.player.inventory.slot.SlotArmor;
 import net.minecraft.core.player.inventory.slot.SlotResult;
 
-import java.util.List;
-
 public class MenuInventory extends MenuAbstract {
 
 	public ContainerCrafting craftSlots;
@@ -93,7 +91,7 @@ public class MenuInventory extends MenuAbstract {
 	 */
 
 	@Override
-	public List<Integer> getMoveSlots(InventoryAction action, Slot slot, int target, Player player) {
+	public IntList getMoveSlots(InventoryAction action, Slot slot, int target, Player player) {
 		if(slot.index == 0) {
 			// Craft Result
 			return getSlots(0, 1, false);
@@ -125,7 +123,7 @@ public class MenuInventory extends MenuAbstract {
 	}
 	
 	@Override
-	public List<Integer> getTargetSlots(InventoryAction action, Slot slot, int target, Player player) {
+	public IntList getTargetSlots(InventoryAction action, Slot slot, int target, Player player) {
 		if(slot.index >= 9 && slot.index <= 44) {
 			// Full ContainerInventory
 			if(target == 1) {
diff --git a/game/core/src/main/java/net/minecraft/core/player/inventory/menu/MenuTrap.java b/game/core/src/main/java/net/minecraft/core/player/inventory/menu/MenuTrap.java
index ecb705d86..5f35af980 100644
--- a/game/core/src/main/java/net/minecraft/core/player/inventory/menu/MenuTrap.java
+++ b/game/core/src/main/java/net/minecraft/core/player/inventory/menu/MenuTrap.java
@@ -1,7 +1,6 @@
 package net.minecraft.core.player.inventory.menu;
 
-import java.util.List;
-
+import it.unimi.dsi.fastutil.ints.IntList;
 import net.minecraft.core.InventoryAction;
 import net.minecraft.core.block.entity.TileEntityDispenser;
 import net.minecraft.core.entity.player.Player;
@@ -46,7 +45,7 @@ public class MenuTrap extends MenuAbstract {
 	}
 
 	@Override
-	public List<Integer> getMoveSlots(InventoryAction action, Slot slot, int target, Player player) {
+	public IntList getMoveSlots(InventoryAction action, Slot slot, int target, Player player) {
 		if(slot.index >= dispenserSlotsStart && slot.index < inventorySlotsStart) {
 			return getSlots(dispenserSlotsStart, 9, false);
 		}
@@ -68,7 +67,7 @@ public class MenuTrap extends MenuAbstract {
 	}
 
 	@Override
-	public List<Integer> getTargetSlots(InventoryAction action, Slot slot, int target, Player player) {
+	public IntList getTargetSlots(InventoryAction action, Slot slot, int target, Player player) {
 		if(slot.index >= dispenserSlotsStart && slot.index < inventorySlotsStart) {
 			return getSlots(inventorySlotsStart, 36, false);
 		}else {
diff --git a/game/core/src/main/java/net/minecraft/core/player/inventory/menu/MenuTrommel.java b/game/core/src/main/java/net/minecraft/core/player/inventory/menu/MenuTrommel.java
index 89fd3d854..cc224e04a 100644
--- a/game/core/src/main/java/net/minecraft/core/player/inventory/menu/MenuTrommel.java
+++ b/game/core/src/main/java/net/minecraft/core/player/inventory/menu/MenuTrommel.java
@@ -1,7 +1,6 @@
 package net.minecraft.core.player.inventory.menu;
 
-import java.util.List;
-
+import it.unimi.dsi.fastutil.ints.IntList;
 import net.minecraft.core.InventoryAction;
 import net.minecraft.core.block.entity.TileEntityTrommel;
 
@@ -86,7 +85,7 @@ public class MenuTrommel extends MenuAbstract {
 	 */
 
 	@Override
-	public List<Integer> getMoveSlots(InventoryAction action, Slot slot, int target, Player player) {
+	public IntList getMoveSlots(InventoryAction action, Slot slot, int target, Player player) {
 		if(slot.index >= 0 && slot.index <= 3) {
 			return getSlots(0, 4, false);
 		}
@@ -113,7 +112,7 @@ public class MenuTrommel extends MenuAbstract {
 	}
 
 	@Override
-	public List<Integer> getTargetSlots(InventoryAction action, Slot slot, int target, Player player) {
+	public IntList getTargetSlots(InventoryAction action, Slot slot, int target, Player player) {
 		if(slot.index >= 0 && slot.index <= 4) {
 			// Item and Fuel Slots
 			return getSlots(5, 36, false); // Into ContainerInventory
diff --git a/game/core/src/main/java/net/minecraft/core/sound/SoundTypes.java b/game/core/src/main/java/net/minecraft/core/sound/SoundTypes.java
index 86511985b..48af21e05 100644
--- a/game/core/src/main/java/net/minecraft/core/sound/SoundTypes.java
+++ b/game/core/src/main/java/net/minecraft/core/sound/SoundTypes.java
@@ -6,6 +6,10 @@ import com.google.gson.JsonObject;
 import com.google.gson.JsonParseException;
 import com.google.gson.JsonParser;
 import com.mojang.logging.LogUtils;
+import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
+import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
+import it.unimi.dsi.fastutil.objects.Object2IntMap;
+import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap;
 import net.minecraft.core.net.packet.PacketSyncIDs;
 import org.slf4j.Logger;
 
@@ -16,8 +20,8 @@ import java.util.Map.Entry;
 
 public class SoundTypes {
 	private static final Logger LOGGER = LogUtils.getLogger();
-	private static final Map<Integer, String> idToSoundNameMap = new HashMap<>();
-	private static final Map<String, Integer> soundNameToIdMap = new HashMap<>();
+	private static final Int2ObjectMap<String> idToSoundNameMap = new Int2ObjectOpenHashMap<>();
+	private static final Object2IntMap<String> soundNameToIdMap = new Object2IntOpenHashMap<>();
 	private static final String format = "/assets/%s/sounds/sounds.json";
 	private static int idCount = 0;
 	
@@ -71,11 +75,7 @@ public class SoundTypes {
 	 * Returns -1 if the given soundPath is not registered! 
 	 */
 	public static int getSoundId(final String soundPath) {
-		final Integer id = soundNameToIdMap.get(soundPath);
-		if(id == null) {
-			return -1;
-		}
-		return id;
+		return soundNameToIdMap.getOrDefault(soundPath, -1);
 	}
 	/**
 	 * Returns null if the given id does not exist!
@@ -85,12 +85,12 @@ public class SoundTypes {
 		return idToSoundNameMap.get(id);
 	}
 	
-	public static void setSoundIds(final Map<Integer, String> soundIds) {
+	public static void setSoundIds(final Int2ObjectMap<String> soundIds) {
 		idToSoundNameMap.clear();
 		soundNameToIdMap.clear();
 		
-		for(final Entry<Integer, String> entry : soundIds.entrySet()) {
-			final int id = entry.getKey();
+		for(final Int2ObjectMap.Entry<String> entry : soundIds.int2ObjectEntrySet()) {
+			final int id = entry.getIntKey();
 			final String name = entry.getValue();
 			
 			idToSoundNameMap.put(id, name);
@@ -98,7 +98,7 @@ public class SoundTypes {
 		}
 	}
 	
-	public static Map<Integer, String> getSoundIds() {
+	public static Int2ObjectMap<String> getSoundIds() {
 		// TODO Make soundNameToIdMap immutable
 		return idToSoundNameMap;
 	}
diff --git a/game/core/src/main/java/net/minecraft/core/util/collection/IntHashMap.java b/game/core/src/main/java/net/minecraft/core/util/collection/IntHashMap.java
deleted file mode 100644
index f5c71c6de..000000000
--- a/game/core/src/main/java/net/minecraft/core/util/collection/IntHashMap.java
+++ /dev/null
@@ -1,224 +0,0 @@
-// 
-// Decompiled by Procyon v0.6.0
-// 
-
-package net.minecraft.core.util.collection;
-
-public class IntHashMap<V>
-{
-    private static final int DEFAULT_INITIAL_CAPACITY = 16;
-    private static final int MAXIMUM_CAPACITY = 1073741824;
-    private static final float DEFAULT_LOAD_FACTOR = 0.75f;
-    private transient Entry<V>[] table;
-    private transient int size;
-    private int threshold;
-    private final float loadFactor;
-    private transient volatile int modCount;
-    
-    public IntHashMap() {
-        this.loadFactor = DEFAULT_LOAD_FACTOR;
-        this.threshold = 12;
-        this.table = new Entry[DEFAULT_INITIAL_CAPACITY];
-    }
-    
-    private static int hash(int n) {
-        n ^= (n >>> 20 ^ n >>> 12);
-        return n ^ n >>> 7 ^ n >>> 4;
-    }
-    
-    private static int indexFor(final int n, final int n2) {
-        return n & n2 - 1;
-    }
-    
-    public int size() {
-        return this.size;
-    }
-    
-    public boolean isEmpty() {
-        return this.size == 0;
-    }
-    
-    public V get(final int n) {
-        for (Entry<V> next = this.table[indexFor(hash(n), this.table.length)]; next != null; next = next.next) {
-            if (next.key == n) {
-                return next.value;
-            }
-        }
-        return null;
-    }
-    
-    public boolean containsKey(final int n) {
-        return this.getEntry(n) != null;
-    }
-    
-    final Entry<V> getEntry(final int n) {
-        for (Entry<V> next = this.table[indexFor(hash(n), this.table.length)]; next != null; next = next.next) {
-            if (next.key == n) {
-                return next;
-            }
-        }
-        return null;
-    }
-    
-    public void put(final int n, final V value) {
-        final int hash = hash(n);
-        final int index = indexFor(hash, this.table.length);
-        for (Entry<V> next = this.table[index]; next != null; next = next.next) {
-            if (next.key == n) {
-                next.value = value;
-            }
-        }
-        ++this.modCount;
-        this.addEntry(hash, n, value, index);
-    }
-    
-    private void resize(final int n) {
-        if (this.table.length == MAXIMUM_CAPACITY) {
-            this.threshold = Integer.MAX_VALUE;
-            return;
-        }
-        final Entry[] table = new Entry[n];
-        this.transfer(table);
-        this.table = table;
-        this.threshold = (int)(n * this.loadFactor);
-    }
-    
-    private void transfer(final Entry<V>[] array) {
-        final Entry<V>[] table = this.table;
-        final int length = array.length;
-        for (int i = 0; i < table.length; ++i) {
-            Entry<V> entry = table[i];
-            if (entry != null) {
-                table[i] = null;
-                do {
-                    final Entry<V> next = entry.next;
-                    final int index = indexFor(entry.hash, length);
-                    entry.next = array[index];
-                    array[index] = entry;
-                    entry = next;
-                } while (entry != null);
-            }
-        }
-    }
-    
-    public V remove(final int n) {
-        final Entry<V> removeEntryForKey = this.removeEntryForKey(n);
-        return (removeEntryForKey == null) ? null : removeEntryForKey.value;
-    }
-    
-    final Entry<V> removeEntryForKey(final int n) {
-        final int index = indexFor(hash(n), this.table.length);
-        Entry<V> entry2;
-        Entry<V> next;
-        for (Entry<V> entry = entry2 = this.table[index]; entry2 != null; entry2 = next) {
-            next = entry2.next;
-            if (entry2.key == n) {
-                ++this.modCount;
-                --this.size;
-                if (entry == entry2) {
-                    this.table[index] = next;
-                }
-                else {
-                    entry.next = next;
-                }
-                return entry2;
-            }
-            entry = entry2;
-        }
-        return entry2;
-    }
-    
-    public void clear() {
-        ++this.modCount;
-        final Entry<V>[] table = this.table;
-        for (int i = 0; i < table.length; ++i) {
-            table[i] = null;
-        }
-        this.size = 0;
-    }
-    
-    public boolean containsValue(final Object o) {
-        if (o == null) {
-            return this.containsNullValue();
-        }
-        final Entry<V>[] table = this.table;
-        for (int i = 0; i < table.length; ++i) {
-            for (Entry<V> next = table[i]; next != null; next = next.next) {
-                if (o.equals(next.value)) {
-                    return true;
-                }
-            }
-        }
-        return false;
-    }
-    
-    private boolean containsNullValue() {
-        final Entry<V>[] table = this.table;
-        for (int i = 0; i < table.length; ++i) {
-            for (Entry<V> next = table[i]; next != null; next = next.next) {
-                if (next.value == null) {
-                    return true;
-                }
-            }
-        }
-        return false;
-    }
-    
-    private void addEntry(final int n, final int n2, final V v, final int n3) {
-        this.table[n3] = new Entry<V>(n, n2, v, this.table[n3]);
-        if (this.size++ >= this.threshold) {
-            this.resize(2 * this.table.length);
-        }
-    }
-    
-    private static class Entry<V>
-    {
-        final int key;
-        V value;
-        Entry<V> next;
-        final int hash;
-        
-        Entry(final int hash, final int key, final V value, final Entry<V> next) {
-            this.value = value;
-            this.next = next;
-            this.key = key;
-            this.hash = hash;
-        }
-        
-        public final int getKey() {
-            return this.key;
-        }
-        
-        public final V getValue() {
-            return this.value;
-        }
-        
-        @Override
-        public final boolean equals(final Object o) {
-            if (!(o instanceof Entry)) {
-                return false;
-            }
-            final Entry entry = (Entry)o;
-            final Integer value = this.getKey();
-            final Integer value2 = entry.getKey();
-            if (value == value2 || (value != null && value.equals(value2))) {
-                final Object value3 = this.getValue();
-                final Object value4 = entry.getValue();
-                if (value3 == value4 || (value3 != null && value3.equals(value4))) {
-                    return true;
-                }
-            }
-            return false;
-        }
-        
-        @Override
-        public final int hashCode() {
-            return hash(this.key);
-        }
-        
-        @Override
-        public final String toString() {
-            return this.getKey() + "=" + this.getValue();
-        }
-    }
-}
diff --git a/game/core/src/main/java/net/minecraft/core/util/collection/LongHashMap.java b/game/core/src/main/java/net/minecraft/core/util/collection/LongHashMap.java
deleted file mode 100644
index 9a3672e12..000000000
--- a/game/core/src/main/java/net/minecraft/core/util/collection/LongHashMap.java
+++ /dev/null
@@ -1,228 +0,0 @@
-// 
-// Decompiled by Procyon v0.6.0
-// 
-
-package net.minecraft.core.util.collection;
-
-public class LongHashMap<V>
-{
-    private static final int DEFAULT_INITIAL_CAPACITY = 16;
-    private static final int MAXIMUM_CAPACITY = 1073741824;
-    private static final float DEFAULT_LOAD_FACTOR = 0.75f;
-    private transient Entry<V>[] table;
-    private transient int size;
-    private int threshold;
-    private final float loadFactor;
-    private transient volatile int modCount;
-    
-    public LongHashMap() {
-        this.loadFactor = DEFAULT_LOAD_FACTOR;
-        this.threshold = 12;
-        this.table = new Entry[DEFAULT_INITIAL_CAPACITY];
-    }
-    
-    private static int hash(final long n) {
-        return hash((int)(n ^ n >>> 32));
-    }
-    
-    private static int hash(int n) {
-        n ^= (n >>> 20 ^ n >>> 12);
-        return n ^ n >>> 7 ^ n >>> 4;
-    }
-    
-    private static int indexFor(final int n, final int n2) {
-        return n & n2 - 1;
-    }
-    
-    public int size() {
-        return this.size;
-    }
-    
-    public boolean isEmpty() {
-        return this.size == 0;
-    }
-    
-    public V get(final long n) {
-        for (Entry<V> next = this.table[indexFor(hash(n), this.table.length)]; next != null; next = next.next) {
-            if (next.key == n) {
-                return next.value;
-            }
-        }
-        return null;
-    }
-    
-    public boolean containsKey(final long n) {
-        return this.getEntry(n) != null;
-    }
-    
-    final Entry<V> getEntry(final long n) {
-        for (Entry<V> next = this.table[indexFor(hash(n), this.table.length)]; next != null; next = next.next) {
-            if (next.key == n) {
-                return next;
-            }
-        }
-        return null;
-    }
-    
-    public void put(final long n, final V value) {
-        final int hash = hash(n);
-        final int index = indexFor(hash, this.table.length);
-        for (Entry<V> next = this.table[index]; next != null; next = next.next) {
-            if (next.key == n) {
-                next.value = value;
-            }
-        }
-        ++this.modCount;
-        this.addEntry(hash, n, value, index);
-    }
-    
-    private void resize(final int n) {
-        if (this.table.length == MAXIMUM_CAPACITY) {
-            this.threshold = Integer.MAX_VALUE;
-            return;
-        }
-        final Entry[] table = new Entry[n];
-        this.transfer(table);
-        this.table = table;
-        this.threshold = (int)(n * this.loadFactor);
-    }
-    
-    private void transfer(final Entry<V>[] array) {
-        final Entry<V>[] table = this.table;
-        final int length = array.length;
-        for (int i = 0; i < table.length; ++i) {
-            Entry<V> entry = table[i];
-            if (entry != null) {
-                table[i] = null;
-                do {
-                    final Entry<V> next = entry.next;
-                    final int index = indexFor(entry.hash, length);
-                    entry.next = array[index];
-                    array[index] = entry;
-                    entry = next;
-                } while (entry != null);
-            }
-        }
-    }
-    
-    public V remove(final long n) {
-        final Entry<V> removeEntryForKey = this.removeEntryForKey(n);
-        return (removeEntryForKey == null) ? null : removeEntryForKey.value;
-    }
-    
-    final Entry<V> removeEntryForKey(final long n) {
-        final int index = indexFor(hash(n), this.table.length);
-        Entry<V> entry2;
-        Entry<V> next;
-        for (Entry<V> entry = entry2 = this.table[index]; entry2 != null; entry2 = next) {
-            next = entry2.next;
-            if (entry2.key == n) {
-                ++this.modCount;
-                --this.size;
-                if (entry == entry2) {
-                    this.table[index] = next;
-                }
-                else {
-                    entry.next = next;
-                }
-                return entry2;
-            }
-            entry = entry2;
-        }
-        return entry2;
-    }
-    
-    public void clear() {
-        ++this.modCount;
-        final Entry<V>[] table = this.table;
-        for (int i = 0; i < table.length; ++i) {
-            table[i] = null;
-        }
-        this.size = 0;
-    }
-    
-    public boolean containsValue(final Object o) {
-        if (o == null) {
-            return this.containsNullValue();
-        }
-        final Entry<V>[] table = this.table;
-        for (int i = 0; i < table.length; ++i) {
-            for (Entry<V> next = table[i]; next != null; next = next.next) {
-                if (o.equals(next.value)) {
-                    return true;
-                }
-            }
-        }
-        return false;
-    }
-    
-    private boolean containsNullValue() {
-        final Entry<V>[] table = this.table;
-        for (int i = 0; i < table.length; ++i) {
-            for (Entry<V> next = table[i]; next != null; next = next.next) {
-                if (next.value == null) {
-                    return true;
-                }
-            }
-        }
-        return false;
-    }
-    
-    private void addEntry(final int n, final long n2, final V v, final int n3) {
-        this.table[n3] = new Entry<V>(n, n2, v, this.table[n3]);
-        if (this.size++ >= this.threshold) {
-            this.resize(2 * this.table.length);
-        }
-    }
-    
-    private static class Entry<V>
-    {
-        final long key;
-        V value;
-        Entry<V> next;
-        final int hash;
-        
-        Entry(final int hash, final long key, final V value, final Entry<V> next) {
-            this.value = value;
-            this.next = next;
-            this.key = key;
-            this.hash = hash;
-        }
-        
-        public final long getKey() {
-            return this.key;
-        }
-        
-        public final V getValue() {
-            return this.value;
-        }
-        
-        @Override
-        public final boolean equals(final Object o) {
-            if (!(o instanceof Entry)) {
-                return false;
-            }
-            final Entry entry = (Entry)o;
-            final Long value = this.getKey();
-            final Long value2 = entry.getKey();
-            if (value == value2 || (value != null && value.equals(value2))) {
-                final Object value3 = this.getValue();
-                final Object value4 = entry.getValue();
-                if (value3 == value4 || (value3 != null && value3.equals(value4))) {
-                    return true;
-                }
-            }
-            return false;
-        }
-        
-        @Override
-        public final int hashCode() {
-            return hash(this.key);
-        }
-        
-        @Override
-        public final String toString() {
-            return this.getKey() + "=" + this.getValue();
-        }
-    }
-}
diff --git a/game/core/src/main/java/net/minecraft/core/util/phys/BoundingVolume.java b/game/core/src/main/java/net/minecraft/core/util/phys/BoundingVolume.java
index 9654978cd..6f653673f 100644
--- a/game/core/src/main/java/net/minecraft/core/util/phys/BoundingVolume.java
+++ b/game/core/src/main/java/net/minecraft/core/util/phys/BoundingVolume.java
@@ -1,5 +1,10 @@
 package net.minecraft.core.util.phys;
 
+import it.unimi.dsi.fastutil.floats.FloatArrayList;
+import it.unimi.dsi.fastutil.floats.FloatList;
+import it.unimi.dsi.fastutil.ints.IntArrayList;
+import it.unimi.dsi.fastutil.ints.IntList;
+
 import java.util.ArrayList;
 import java.util.EnumSet;
 import java.util.List;
@@ -179,7 +184,7 @@ public class BoundingVolume
 
     public void bake()
     {
-        List<Integer> lineCoords = new ArrayList<>();
+        IntList lineCoords = new IntArrayList();
         float scale = 1f / SIZE;
 
         for (int y = 0; y < SIZE; y++)
@@ -205,12 +210,12 @@ public class BoundingVolume
 
         System.out.println("Before line simplification: " + lineCoords.size() / 6 + " lines");
 
-        List<Integer> mergedLineCoords = mergeLines(lineCoords);
+        IntList mergedLineCoords = mergeLines(lineCoords);
 
         System.out.println("After line simplification: " + mergedLineCoords.size() / 6 + " lines");
 
-        List<Float> floatLineCoords = new ArrayList<>();
-        for (Integer i : mergedLineCoords)
+        FloatList floatLineCoords = new FloatArrayList();
+        for (int i : mergedLineCoords)
         {
             floatLineCoords.add(i * scale);
         }
@@ -218,27 +223,27 @@ public class BoundingVolume
         bakedLineCoords = floatLineCoords.toArray(new Float[0]);
     }
 
-    private List<Integer> mergeLines(List<Integer> lineCoords)
+    private IntList mergeLines(IntList lineCoords)
     {
-        List<Integer> mergedLineCoords = new ArrayList<>();
+        IntList mergedLineCoords = new IntArrayList();
 
         for (int i = 0; i < lineCoords.size(); i += 6)
         {
             boolean lineHandled = false;
             for (int j = 0; j < mergedLineCoords.size(); j += 6)
             {
-                int xMinA = mergedLineCoords.get(j + 0);
-                int yMinA = mergedLineCoords.get(j + 1);
-                int zMinA = mergedLineCoords.get(j + 2);
-                int xMaxA = mergedLineCoords.get(j + 3);
-                int yMaxA = mergedLineCoords.get(j + 4);
-                int zMaxA = mergedLineCoords.get(j + 5);
-                int xMinB = lineCoords.get(i + 0);
-                int yMinB = lineCoords.get(i + 1);
-                int zMinB = lineCoords.get(i + 2);
-                int xMaxB = lineCoords.get(i + 3);
-                int yMaxB = lineCoords.get(i + 4);
-                int zMaxB = lineCoords.get(i + 5);
+                int xMinA = mergedLineCoords.getInt(j + 0);
+                int yMinA = mergedLineCoords.getInt(j + 1);
+                int zMinA = mergedLineCoords.getInt(j + 2);
+                int xMaxA = mergedLineCoords.getInt(j + 3);
+                int yMaxA = mergedLineCoords.getInt(j + 4);
+                int zMaxA = mergedLineCoords.getInt(j + 5);
+                int xMinB = lineCoords.getInt(i + 0);
+                int yMinB = lineCoords.getInt(i + 1);
+                int zMinB = lineCoords.getInt(i + 2);
+                int xMaxB = lineCoords.getInt(i + 3);
+                int yMaxB = lineCoords.getInt(i + 4);
+                int zMaxB = lineCoords.getInt(i + 5);
 
                 if (xMinA == xMinB && yMinA == yMinB && zMinA == zMinB && xMaxA == xMaxB && yMaxA == yMaxB && zMaxA == zMaxB)
                 {
@@ -288,12 +293,12 @@ public class BoundingVolume
 
             if (!lineHandled)
             {
-                mergedLineCoords.add(lineCoords.get(i + 0));
-                mergedLineCoords.add(lineCoords.get(i + 1));
-                mergedLineCoords.add(lineCoords.get(i + 2));
-                mergedLineCoords.add(lineCoords.get(i + 3));
-                mergedLineCoords.add(lineCoords.get(i + 4));
-                mergedLineCoords.add(lineCoords.get(i + 5));
+                mergedLineCoords.add(lineCoords.getInt(i + 0));
+                mergedLineCoords.add(lineCoords.getInt(i + 1));
+                mergedLineCoords.add(lineCoords.getInt(i + 2));
+                mergedLineCoords.add(lineCoords.getInt(i + 3));
+                mergedLineCoords.add(lineCoords.getInt(i + 4));
+                mergedLineCoords.add(lineCoords.getInt(i + 5));
             }
         }
 
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 b33eab778..85db03fd9 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
@@ -1,5 +1,8 @@
 package net.minecraft.core.world;
 
+import it.unimi.dsi.fastutil.ints.Int2ObjectArrayMap;
+import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
+import it.unimi.dsi.fastutil.ints.Int2ObjectMaps;
 import net.minecraft.core.block.Block;
 import net.minecraft.core.block.BlockLogicPortal;
 import net.minecraft.core.block.Blocks;
@@ -75,15 +78,15 @@ public class Dimension
 		return "Dimension: [ ID: " + id + " Name: " + getTranslatedName() + " ]";
 	}
 
-	private static final Map<Integer, Dimension> dimensionList = new HashMap<>();
+	private static final Int2ObjectMap<Dimension> dimensionList = new Int2ObjectArrayMap<>();
+	private static final Int2ObjectMap<Dimension> dimensionListUnmodifiable = Int2ObjectMaps.unmodifiable(dimensionList);
 
 	public static final Dimension OVERWORLD = new Dimension("overworld", null, 1.0f, null, WorldTypes.OVERWORLD_DEFAULT);
 	public static final Dimension NETHER = new Dimension("nether", OVERWORLD, 0.125f, Blocks.PORTAL_NETHER, WorldTypes.NETHER_DEFAULT);
 	public static final Dimension DRIFT = new Dimension("drift", OVERWORLD, 8.0f, Blocks.PORTAL_DRIFT, WorldTypes.DRIFT_DEFAULT);
 
-	public static Map<Integer, Dimension> getDimensionList()
-	{
-		return Collections.unmodifiableMap(dimensionList);
+	public static Int2ObjectMap<Dimension> getDimensionList() {
+		return dimensionListUnmodifiable;
 	}
 
 	public static void registerDimension(int id, Dimension dimension)
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 d15adc538..fae52fcef 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
@@ -2004,6 +2004,41 @@ public class World implements WorldSource {
         return false;
     }
 
+    public boolean isMaterialInBB(AABB aabb, 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);
+        for(int _x = minX_i; _x < maxX_i; _x++)
+        {
+            for(int _y = minY_i; _y < maxY_i; _y++)
+            {
+                for(int _z = minZ_i; _z < maxZ_i; _z++)
+                {
+                    Block<?> block = Blocks.blocksList[getBlockId(_x, _y, _z)];
+                    if(block != null) {
+                        boolean isMaterial = false;
+                        if (block.getMaterial() == material) {
+                            isMaterial = true;
+                            break;
+                        }
+                        if (!isMaterial) continue;
+
+                        if (aabb.intersects(block.getBlockBoundsFromState(this, _x, _y, _z).move(_x, _y, _z))){
+                            return true;
+                        }
+
+                    }
+                }
+            }
+        }
+
+        return false;
+    }
+
     public boolean isAABBInMaterial(AABB aabb, Material material)
     {
         int i = MathHelper.floor(aabb.minX);
diff --git a/game/core/src/main/java/net/minecraft/core/world/biome/provider/BiomeProvider.java b/game/core/src/main/java/net/minecraft/core/world/biome/provider/BiomeProvider.java
index 35ba89ae4..ef6d83e51 100644
--- a/game/core/src/main/java/net/minecraft/core/world/biome/provider/BiomeProvider.java
+++ b/game/core/src/main/java/net/minecraft/core/world/biome/provider/BiomeProvider.java
@@ -1,45 +1,47 @@
 package net.minecraft.core.world.biome.provider;
 
+import com.mojang.logging.LogUtils;
+import it.unimi.dsi.fastutil.objects.Object2IntArrayMap;
+import it.unimi.dsi.fastutil.objects.Object2IntMap;
 import net.minecraft.core.data.registry.Registries;
 import net.minecraft.core.world.biome.Biome;
-
-import java.util.HashMap;
-import java.util.Map;
+import org.slf4j.Logger;
 
 public abstract class BiomeProvider
 {
-    public Biome getBiome(int x, int y, int z)
+    private static final Logger LOGGER = LogUtils.getLogger();
+    public Biome getBiome(final int x, final int y, final int z)
     {
-        Biome[] out = getBiomes(null, x, y, z, 1, 1, 1);
+        final Biome[] out = getBiomes(null, x, y, z, 1, 1, 1);
         return out[0];
     }
 
-    public double getTemperature(int x, int z)
+    public double getTemperature(final int x, final int z)
     {
-        double[] out = getTemperatures(null, x, z, 1, 1);
+        final double[] out = getTemperatures(null, x, z, 1, 1);
         return out[0];
     }
 
-    public double getHumidity(int x, int z)
+    public double getHumidity(final int x, final int z)
     {
-        double[] out = getHumidities(null, x, z, 1, 1);
+        final double[] out = getHumidities(null, x, z, 1, 1);
         return out[0];
     }
 
-    public double getVariety(int x, int z)
+    public double getVariety(final int x, final int z)
     {
-        double[] out = getVarieties(null, x, z, 1, 1);
+        final double[] out = getVarieties(null, x, z, 1, 1);
         return out[0];
     }
 
 
-    public double getBiomeness(int x, int y, int z)
+    public double getBiomeness(final int x, final int y, final int z)
     {
-        double[] out = getBiomenesses(null, x, y, z, 1, 1, 1);
+        final double[] out = getBiomenesses(null, x, y, z, 1, 1, 1);
         return out[0];
     }
 
-    public Biome[] getBiomes(Biome[] biomes, int x, int y, int z, int xSize, int ySize, int zSize)
+    public Biome[] getBiomes(final Biome[] biomes, final int x, final int y, final int z, final int xSize, final int ySize, final int zSize)
     {
         return getBiomes(biomes, null, null, null, x, y, z, xSize, ySize, zSize);
     }
@@ -58,49 +60,49 @@ public abstract class BiomeProvider
     protected void generateBiomeDistributionStats()
     {
         int lastReport = 0;
-        int sizeChunks = 2048;
+        final int sizeChunks = 2048;
         int chunksSampled = 0;
-        Map<Biome, Integer> biomeOccurrenceMap = new HashMap<>();
+        final Object2IntMap<Biome> biomeOccurrenceMap = new Object2IntArrayMap<>();
         double tempAcc = 0.0;
         double humAcc = 0.0;
 
-        System.out.println("Sampling " + sizeChunks * sizeChunks + " chunks for biome test...");
+        LOGGER.info("Sampling " + sizeChunks * sizeChunks + " chunks for biome test...");
 
         for (int x = -sizeChunks / 2; x < sizeChunks / 2; x++)
         {
             for (int z = -sizeChunks / 2; z < sizeChunks / 2; z++)
             {
-                int pctg = (int) (chunksSampled / (float)(sizeChunks * sizeChunks) * 100);
+                final int pctg = (int) (chunksSampled / (float)(sizeChunks * sizeChunks) * 100);
                 if (pctg != lastReport)
                 {
-                    System.out.println(pctg + "% complete...");
+                    LOGGER.info("{}% complete...", pctg);
                     lastReport = pctg;
                 }
                 tempAcc += getTemperature(x * 16, z * 16);
                 humAcc += getHumidity(x * 16, z * 16);
-                Biome biome = getBiome(x * 16, 64, z * 16);
+                final Biome biome = getBiome(x * 16, 64, z * 16);
                 biomeOccurrenceMap.put(biome, biomeOccurrenceMap.getOrDefault(biome, 0) + 1);
                 chunksSampled++;
             }
         }
 
-        System.out.println("Seed analysis sampling " + sizeChunks * sizeChunks + " chunks:");
-        System.out.println("    Average temperature: " + String.format("%.2f", tempAcc / (float) (sizeChunks * sizeChunks)));
-        System.out.println("    Average humidity: " + String.format("%.2f", humAcc / (float) (sizeChunks * sizeChunks)));
-        System.out.println("    Biome distribution:");
-        for (Biome biome : Registries.BIOMES)
+        LOGGER.info("Seed analysis sampling " + sizeChunks * sizeChunks + " chunks:");
+        LOGGER.info("    Average temperature: {}", String.format("%.2f", tempAcc / (float) (sizeChunks * sizeChunks)));
+        LOGGER.info("    Average humidity: {}", String.format("%.2f", humAcc / (float) (sizeChunks * sizeChunks)));
+        LOGGER.info("    Biome distribution:");
+        for (final Biome biome : Registries.BIOMES)
         {
             float pctg;
             if (biomeOccurrenceMap.containsKey(biome))
             {
-                pctg = biomeOccurrenceMap.get(biome) / (float) (sizeChunks * sizeChunks);
+                pctg = biomeOccurrenceMap.getInt(biome) / (float) (sizeChunks * sizeChunks);
                 pctg *= 100;
             }
             else
             {
                 pctg = 0.0f;
             }
-            System.out.println("        " + Registries.BIOMES.getKey(biome) + ": " + String.format("%.2f", pctg) + "%");
+            LOGGER.info("        {}: {}%", Registries.BIOMES.getKey(biome), String.format("%.2f", pctg));
         }
     }
 }
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 e78616393..0450575ff 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
@@ -1,6 +1,7 @@
 package net.minecraft.core.world.chunk;
 
 import com.mojang.logging.LogUtils;
+import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
 import net.minecraft.core.Global;
 import net.minecraft.core.block.entity.TileEntityDispatcher;
 import net.minecraft.core.block.entity.TileEntity;
@@ -252,7 +253,7 @@ public class ChunkLoaderLegacy
         chunk.humidity = reader.getHumidityMap();
 
         // Read registries
-        Map<Integer, String> biomeRegistry = reader.getBiomeRegistry();
+        Int2ObjectMap<String> biomeRegistry = reader.getBiomeRegistry();
 
         // Read sections
         for (int i = 0; i < ChunkSection.SECTION_SIZE_Y; i++) {
@@ -315,7 +316,7 @@ public class ChunkLoaderLegacy
         return chunk;
     }
 
-    public static void loadChunkSectionFromCompound(ChunkSection section, ChunkReader reader, Map<Integer, String> biomeRegistry) {
+    public static void loadChunkSectionFromCompound(ChunkSection section, ChunkReader reader, Int2ObjectMap<String> biomeRegistry) {
         section.blocks = reader.getBlocks(section.yPosition);
         section.data = reader.getData(section.yPosition);
         section.skylightMap = reader.getSkyLight(section.yPosition);
diff --git a/game/core/src/main/java/net/minecraft/core/world/chunk/reader/ChunkReader.java b/game/core/src/main/java/net/minecraft/core/world/chunk/reader/ChunkReader.java
index d6c98202a..17fb38176 100644
--- a/game/core/src/main/java/net/minecraft/core/world/chunk/reader/ChunkReader.java
+++ b/game/core/src/main/java/net/minecraft/core/world/chunk/reader/ChunkReader.java
@@ -1,6 +1,7 @@
 package net.minecraft.core.world.chunk.reader;
 
 import com.mojang.nbt.tags.CompoundTag;
+import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
 import net.minecraft.core.world.World;
 import net.minecraft.core.world.data.ChunkNibbleArray;
 import net.minecraft.core.world.data.ChunkUnsignedByteArray;
@@ -28,6 +29,6 @@ public abstract class ChunkReader
     public abstract boolean getIsTerrainPopulated();
     public abstract double[] getTemperatureMap();
     public abstract double[] getHumidityMap();
-    public abstract byte[] getBiomeMap(int ySection, Map<Integer, String> biomeRegistry);
-    public abstract Map<Integer, String> getBiomeRegistry();
+    public abstract byte[] getBiomeMap(int ySection, Int2ObjectMap<String> biomeRegistry);
+    public abstract Int2ObjectMap<String> getBiomeRegistry();
 }
diff --git a/game/core/src/main/java/net/minecraft/core/world/chunk/reader/ChunkReaderLegacy.java b/game/core/src/main/java/net/minecraft/core/world/chunk/reader/ChunkReaderLegacy.java
index f5a5f6751..092a9b4fe 100644
--- a/game/core/src/main/java/net/minecraft/core/world/chunk/reader/ChunkReaderLegacy.java
+++ b/game/core/src/main/java/net/minecraft/core/world/chunk/reader/ChunkReaderLegacy.java
@@ -1,6 +1,7 @@
 package net.minecraft.core.world.chunk.reader;
 
 import com.mojang.nbt.tags.CompoundTag;
+import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
 import net.minecraft.core.world.World;
 import net.minecraft.core.world.chunk.Chunk;
 import net.minecraft.core.world.chunk.ChunkSection;
@@ -182,14 +183,14 @@ public class ChunkReaderLegacy
     }
 
     @Override
-    public byte[] getBiomeMap(int ySection, Map<Integer, String> biomeRegistry)
+    public byte[] getBiomeMap(int ySection, Int2ObjectMap<String> biomeRegistry)
     {
         // Not supported
         return null;
     }
 
     @Override
-    public Map<Integer, String> getBiomeRegistry() {
+    public Int2ObjectMap<String> getBiomeRegistry() {
         // Not supported
         return null;
     }
diff --git a/game/core/src/main/java/net/minecraft/core/world/chunk/reader/ChunkReaderVersion1.java b/game/core/src/main/java/net/minecraft/core/world/chunk/reader/ChunkReaderVersion1.java
index d7679969a..a2cc78d2a 100644
--- a/game/core/src/main/java/net/minecraft/core/world/chunk/reader/ChunkReaderVersion1.java
+++ b/game/core/src/main/java/net/minecraft/core/world/chunk/reader/ChunkReaderVersion1.java
@@ -1,6 +1,7 @@
 package net.minecraft.core.world.chunk.reader;
 
 import com.mojang.nbt.tags.CompoundTag;
+import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
 import net.minecraft.core.data.registry.Registries;
 import net.minecraft.core.data.registry.Registry;
 import net.minecraft.core.world.World;
@@ -185,7 +186,7 @@ public class ChunkReaderVersion1
     }
 
     @Override
-    public byte[] getBiomeMap(int ySection, Map<Integer, String> biomeRegistry)
+    public byte[] getBiomeMap(int ySection, Int2ObjectMap<String> biomeRegistry)
     {
         byte[] newBiomes = new byte[Chunk.CHUNK_SIZE_X * (ChunkSection.SECTION_SIZE_Y >> 3) * Chunk.CHUNK_SIZE_Z];
 
@@ -214,7 +215,7 @@ public class ChunkReaderVersion1
     }
 
     @Override
-    public Map<Integer, String> getBiomeRegistry() {
+    public Int2ObjectMap<String> getBiomeRegistry() {
         CompoundTag registriesTag = tag.getCompoundOrDefault("Registries", null);
         CompoundTag biomesTag = null;
         if (registriesTag != null)
diff --git a/game/core/src/main/java/net/minecraft/core/world/chunk/reader/ChunkReaderVersion2.java b/game/core/src/main/java/net/minecraft/core/world/chunk/reader/ChunkReaderVersion2.java
index 5c921eaa3..51b3725c3 100644
--- a/game/core/src/main/java/net/minecraft/core/world/chunk/reader/ChunkReaderVersion2.java
+++ b/game/core/src/main/java/net/minecraft/core/world/chunk/reader/ChunkReaderVersion2.java
@@ -3,6 +3,7 @@ package net.minecraft.core.world.chunk.reader;
 import com.mojang.nbt.tags.CompoundTag;
 import com.mojang.nbt.tags.ListTag;
 import com.mojang.nbt.tags.Tag;
+import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
 import net.minecraft.core.data.registry.Registries;
 import net.minecraft.core.data.registry.Registry;
 import net.minecraft.core.world.World;
@@ -130,7 +131,7 @@ public class ChunkReaderVersion2
     }
 
     @Override
-    public byte[] getBiomeMap(int ySection, Map<Integer, String> biomeRegistry) {
+    public byte[] getBiomeMap(int ySection, Int2ObjectMap<String> biomeRegistry) {
         byte[] biomeMap = null;
         CompoundTag sectionTag = findSection(ySection);
         if (sectionTag != null) {
@@ -157,7 +158,7 @@ public class ChunkReaderVersion2
     }
 
     @Override
-    public Map<Integer, String> getBiomeRegistry() {
+    public Int2ObjectMap<String> getBiomeRegistry() {
         CompoundTag registriesTag = tag.getCompoundOrDefault("Registries", null);
         CompoundTag biomesTag = null;
         if (registriesTag != null)
diff --git a/game/core/src/main/java/net/minecraft/core/world/config/season/SeasonConfigBuilder.java b/game/core/src/main/java/net/minecraft/core/world/config/season/SeasonConfigBuilder.java
index 12295385a..951626226 100644
--- a/game/core/src/main/java/net/minecraft/core/world/config/season/SeasonConfigBuilder.java
+++ b/game/core/src/main/java/net/minecraft/core/world/config/season/SeasonConfigBuilder.java
@@ -1,11 +1,11 @@
 package net.minecraft.core.world.config.season;
 
+import it.unimi.dsi.fastutil.objects.Object2IntArrayMap;
+import it.unimi.dsi.fastutil.objects.Object2IntMap;
 import net.minecraft.core.world.season.Season;
 
 import java.util.ArrayList;
-import java.util.HashMap;
 import java.util.List;
-import java.util.Map;
 
 public class SeasonConfigBuilder
 {
@@ -17,20 +17,20 @@ public class SeasonConfigBuilder
 
     private Type type = null;
     private List<Season> seasons = null;
-    private Map<Season, Integer> seasonLengthMap = null;
+    private Object2IntMap<Season> seasonLengthMap = null;
     private Season singleSeason = null;
 
     protected SeasonConfigBuilder() { }
 
     public SeasonConfig build()
     {
-        if (type == Type.SINGLE && singleSeason != null)
+        if (this.type == Type.SINGLE && this.singleSeason != null)
         {
-            return new SeasonConfigSingle(singleSeason);
+            return new SeasonConfigSingle(this.singleSeason);
         }
-        else if (type == Type.CYCLE && seasons != null && seasonLengthMap != null)
+        else if (this.type == Type.CYCLE && this.seasons != null && this.seasonLengthMap != null)
         {
-            return new SeasonConfigCycle(seasons, seasonLengthMap);
+            return new SeasonConfigCycle(this.seasons, this.seasonLengthMap);
         }
         else
         {
@@ -38,7 +38,7 @@ public class SeasonConfigBuilder
         }
     }
 
-    public SeasonConfigBuilder withSingleSeason(Season season)
+    public SeasonConfigBuilder withSingleSeason(final Season season)
     {
         this.type = Type.SINGLE;
         this.seasons = null;
@@ -48,12 +48,12 @@ public class SeasonConfigBuilder
         return this;
     }
 
-    public SeasonConfigBuilder withSeasonInCycle(Season season, int length)
+    public SeasonConfigBuilder withSeasonInCycle(final Season season, final int length)
     {
         this.type = Type.CYCLE;
         if (this.seasons == null) this.seasons = new ArrayList<>();
         this.seasons.add(season);
-        if (this.seasonLengthMap == null) this.seasonLengthMap = new HashMap<>();
+        if (this.seasonLengthMap == null) this.seasonLengthMap = new Object2IntArrayMap<>();
         this.seasonLengthMap.put(season, length);
         this.singleSeason = null;
 
diff --git a/game/core/src/main/java/net/minecraft/core/world/config/season/SeasonConfigCycle.java b/game/core/src/main/java/net/minecraft/core/world/config/season/SeasonConfigCycle.java
index 903d7c202..df3ebc7e5 100644
--- a/game/core/src/main/java/net/minecraft/core/world/config/season/SeasonConfigCycle.java
+++ b/game/core/src/main/java/net/minecraft/core/world/config/season/SeasonConfigCycle.java
@@ -1,5 +1,7 @@
 package net.minecraft.core.world.config.season;
 
+import it.unimi.dsi.fastutil.objects.Object2IntArrayMap;
+import it.unimi.dsi.fastutil.objects.Object2IntMap;
 import net.minecraft.core.world.season.Season;
 import org.jetbrains.annotations.NotNull;
 
@@ -10,12 +12,12 @@ public class SeasonConfigCycle
     extends SeasonConfig
 {
     private final List<Season> seasons;
-    private final SeasonMapInternal seasonLengthMap;
+    private final Object2IntArrayMap<Season> seasonLengthMap;
 
-    protected SeasonConfigCycle(List<Season> seasons, @NotNull Map<Season, Integer> seasonLengthMap)
+    protected SeasonConfigCycle(List<Season> seasons, @NotNull Object2IntMap<Season> seasonLengthMap)
     {
         this.seasons = seasons;
-        this.seasonLengthMap = new SeasonMapInternal(seasonLengthMap);
+        this.seasonLengthMap = new Object2IntArrayMap<>(seasonLengthMap);
     }
 
     public List<Season> getSeasons()
@@ -27,29 +29,4 @@ public class SeasonConfigCycle
     {
         return seasonLengthMap.getOrDefault(season, 0);
     }
-
-    private static class SeasonMapInternal { // Exists since seasonLengthMap.getOrDefault is slow for how often it can be called
-        private final Season[] seasons;
-        private final int[] lengths;
-        public SeasonMapInternal(final @NotNull Map<Season, Integer> seasonLengthMap) {
-            this.seasons = new Season[seasonLengthMap.size()];
-            this.lengths = new int[seasonLengthMap.size()];
-
-            int i = 0;
-            for (final Map.Entry<Season, Integer> entry : seasonLengthMap.entrySet()) {
-                this.seasons[i] = entry.getKey();
-                this.lengths[i] = entry.getValue();
-                i++;
-            }
-        }
-
-        public int getOrDefault(final Season season, final int defaultValue) {
-            for (int i = 0; i < this.seasons.length; i++) {
-                if (this.seasons[i].equals(season)) {
-                    return this.lengths[i];
-                }
-            }
-            return defaultValue;
-        }
-    }
 }
diff --git a/game/core/src/main/java/net/minecraft/core/world/data/SynchedEntityData.java b/game/core/src/main/java/net/minecraft/core/world/data/SynchedEntityData.java
index 6291b81c6..07c3243ab 100644
--- a/game/core/src/main/java/net/minecraft/core/world/data/SynchedEntityData.java
+++ b/game/core/src/main/java/net/minecraft/core/world/data/SynchedEntityData.java
@@ -1,6 +1,10 @@
 package net.minecraft.core.world.data;
 
 import com.mojang.nbt.tags.CompoundTag;
+import it.unimi.dsi.fastutil.ints.Int2ObjectArrayMap;
+import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
+import it.unimi.dsi.fastutil.objects.Object2IntArrayMap;
+import it.unimi.dsi.fastutil.objects.Object2IntMap;
 import net.minecraft.core.item.ItemStack;
 import net.minecraft.core.net.packet.Packet;
 import net.minecraft.core.world.chunk.ChunkCoordinates;
@@ -35,8 +39,8 @@ public class SynchedEntityData
     public static final int MAX_STRING_SIZE = 1024;
 
     public static final int END_MARKER = 0xFF;
-    private static final HashMap<Class<?>, Integer> DATA_TYPES = new HashMap<>();
-    private final Map<Integer, @NotNull DataItem<?>> itemsById = new HashMap<>();
+    private static final Object2IntMap<Class<?>> DATA_TYPES = new Object2IntArrayMap<>();
+    private final Int2ObjectMap<@NotNull DataItem<?>> itemsById = new Int2ObjectArrayMap<>();
     private boolean isDirty = true;
 
     /**
@@ -48,8 +52,7 @@ public class SynchedEntityData
      */
     public <T> void define(int id, T value, Class<T> valueClass)
     {
-        Integer integer = DATA_TYPES.get(valueClass);
-        if(integer == null)
+        if(!DATA_TYPES.containsKey(valueClass))
         {
             throw new IllegalArgumentException("Unknown data type: " + valueClass);
         }
@@ -67,7 +70,7 @@ public class SynchedEntityData
         }
         else
         {
-            DataItem<T> item = new DataItem<>(integer, id, value);
+            DataItem<T> item = new DataItem<>(DATA_TYPES.getInt(valueClass), id, value);
             itemsById.put(id, item);
         }
     }
diff --git a/game/core/src/main/java/net/minecraft/core/world/generate/chunk/perlin/nether/TerrainGeneratorNether.java b/game/core/src/main/java/net/minecraft/core/world/generate/chunk/perlin/nether/TerrainGeneratorNether.java
index c4cd9da6a..71a31876d 100644
--- a/game/core/src/main/java/net/minecraft/core/world/generate/chunk/perlin/nether/TerrainGeneratorNether.java
+++ b/game/core/src/main/java/net/minecraft/core/world/generate/chunk/perlin/nether/TerrainGeneratorNether.java
@@ -1,5 +1,7 @@
 package net.minecraft.core.world.generate.chunk.perlin.nether;
 
+import it.unimi.dsi.fastutil.objects.Object2IntArrayMap;
+import it.unimi.dsi.fastutil.objects.Object2IntMap;
 import net.minecraft.core.block.Blocks;
 import net.minecraft.core.world.World;
 import net.minecraft.core.world.biome.Biome;
@@ -27,7 +29,7 @@ public class TerrainGeneratorNether
     private Biome lastBiomePosX = null;
     private Biome lastBiomeNegZ = null;
     private Biome lastBiomePosZ = null;
-    private Map<Biome, Integer> fluidLookup = new HashMap<>();
+    private Object2IntMap<Biome> fluidLookup = new Object2IntArrayMap<>();
     private int lastChunkX = Integer.MIN_VALUE;
     private int lastChunkZ = Integer.MIN_VALUE;
     private final @NotNull PerlinNoise noise = new PerlinNoise(0L, 4, 0);
diff --git a/game/core/src/main/java/net/minecraft/core/world/generate/feature/WorldFeatureOre.java b/game/core/src/main/java/net/minecraft/core/world/generate/feature/WorldFeatureOre.java
index b73382f39..0519e1427 100644
--- a/game/core/src/main/java/net/minecraft/core/world/generate/feature/WorldFeatureOre.java
+++ b/game/core/src/main/java/net/minecraft/core/world/generate/feature/WorldFeatureOre.java
@@ -1,5 +1,6 @@
 package net.minecraft.core.world.generate.feature;
 
+import it.unimi.dsi.fastutil.ints.Int2IntArrayMap;
 import net.minecraft.core.block.Block;
 import net.minecraft.core.block.Blocks;
 import net.minecraft.core.util.helper.MathHelper;
@@ -13,7 +14,7 @@ public class WorldFeatureOre extends WorldFeature
 {
     private int minableBlockId;
     private int numberOfBlocks;
-    private final OreMap variantMap;
+    private final Int2IntArrayMap variantMap;
     @MethodParametersAnnotation(names = {"blockId", "numberOfBlocks"})
     public WorldFeatureOre(int blockId, int numberOfBlocks)
     {
@@ -22,7 +23,7 @@ public class WorldFeatureOre extends WorldFeature
         this.variantMap = null;
     }
     @MethodParametersAnnotation(names = {"blockId", "numberOfBlocks", "variantMap"})
-    public WorldFeatureOre(@NotNull OreMap variantMap, int numberOfBlocks)
+    public WorldFeatureOre(@NotNull Int2IntArrayMap variantMap, int numberOfBlocks)
     {
         this.numberOfBlocks = numberOfBlocks;
         this.variantMap = variantMap;
@@ -100,62 +101,4 @@ public class WorldFeatureOre extends WorldFeature
 
         return true;
     }
-
-    // Oremap class, created to quickly map ints to ints without having convert them to Integer Objects, size increasing performance isn't too good and should really only be used in cases where a map is created once then almost never expanded
-    public static class OreMap {
-        private int @NotNull [] keyArr = new int[0];
-        private int @NotNull [] valArr = new int[0];
-
-        private static int @NotNull [] increaseArraySize(final int @NotNull [] array) {
-            final int[] outArr = new int[array.length + 1];
-            System.arraycopy(array, 0, outArr, 0, array.length);
-            return outArr;
-        }
-
-
-        public void put(@NotNull final Block<?> stone, @NotNull final Block<?> ore) {
-            put(stone.id(), ore.id());
-        }
-
-        public void put(final int stoneId, final int oreId) {
-            final int index = indexForKey(stoneId);
-            if (index == -1) {
-                this.keyArr = increaseArraySize(this.keyArr);
-                this.keyArr[this.keyArr.length - 1] = stoneId;
-
-                this.valArr = increaseArraySize(this.valArr);
-                this.valArr[this.valArr.length - 1] = oreId;
-            } else {
-                this.valArr[index] = oreId;
-            }
-        }
-
-        public int get(@NotNull final Block<?> stone) {
-            return get(stone.id());
-        }
-
-        public int get(final int stoneId) {
-            final int index = indexForKey(stoneId);
-            if (index == -1) return index;
-            return this.valArr[index];
-        }
-
-        private int indexForKey(final int stoneId) {
-            for (int i = 0; i < this.keyArr.length; i++) {
-                if (this.keyArr[i] == stoneId) return i;
-            }
-            return -1;
-        }
-
-        public boolean containsKey(@NotNull final Block<?> stone) {
-            return containsKey(stone.id());
-        }
-
-        public boolean containsKey(final int stoneId) {
-            for (int i = 0; i < this.keyArr.length; i++) {
-                if (this.keyArr[i] == stoneId) return true;
-            }
-            return false;
-        }
-    }
 }
diff --git a/game/core/src/main/java/net/minecraft/core/world/generate/feature/tree/WorldFeatureTreePalm.java b/game/core/src/main/java/net/minecraft/core/world/generate/feature/tree/WorldFeatureTreePalm.java
index 4794f7030..5fcb34792 100644
--- a/game/core/src/main/java/net/minecraft/core/world/generate/feature/tree/WorldFeatureTreePalm.java
+++ b/game/core/src/main/java/net/minecraft/core/world/generate/feature/tree/WorldFeatureTreePalm.java
@@ -1,5 +1,9 @@
 package net.minecraft.core.world.generate.feature.tree;
 
+import it.unimi.dsi.fastutil.ints.IntArrayList;
+import it.unimi.dsi.fastutil.ints.IntArraySet;
+import it.unimi.dsi.fastutil.ints.IntList;
+import it.unimi.dsi.fastutil.ints.IntSet;
 import net.minecraft.core.block.Block;
 import net.minecraft.core.block.BlockLogicFlower;
 import net.minecraft.core.block.BlockLogicLeavesBase;
@@ -52,8 +56,8 @@ public class WorldFeatureTreePalm extends WorldFeature {
 	
 	protected int logHeight;
 	
-	protected Set<Integer> intSet = new HashSet<>();
-	protected List<Integer> intList = new ArrayList<>();
+	protected IntSet intSet = new IntArraySet();
+	protected IntList intList = new IntArrayList();
 	@MethodParametersAnnotation(names = {"log", "leaves", "big", "update"})
 	public WorldFeatureTreePalm(Block<?> log, Block<?> leaves, boolean big, boolean update, boolean checkForWater) {
 		this.log = log;
@@ -125,7 +129,7 @@ public class WorldFeatureTreePalm extends WorldFeature {
 		// Check if any blocks are in the way
 		int lastPossibleBlockIndex = intList.size() - 1;
 		for(int i=0; i < intList.size(); i++) {
-			int offset = intList.get(i);
+			int offset = intList.getInt(i);
 			int x = basePos.x + decodeX(offset);
 			int y = basePos.y + decodeY(offset);
 			int z = basePos.z + decodeZ(offset);
@@ -137,7 +141,7 @@ public class WorldFeatureTreePalm extends WorldFeature {
 		}
 		
 		for(int i = lastPossibleBlockIndex; i >= 0; i--) {
-			int offset = intList.get(i);
+			int offset = intList.getInt(i);
 			int x = basePos.x + decodeX(offset);
 			int y = basePos.y + decodeY(offset);
 			int z = basePos.z + decodeZ(offset);
@@ -158,7 +162,7 @@ public class WorldFeatureTreePalm extends WorldFeature {
 		int z = 0;
 		logHeight = lastPossibleBlockIndex + 1;
 		for(int i=0; i < logHeight; i++) {
-			int offset = intList.get(i);
+			int offset = intList.getInt(i);
 			x = basePos.x + decodeX(offset);
 			y = basePos.y + decodeY(offset);
 			z = basePos.z + decodeZ(offset);
@@ -234,7 +238,7 @@ public class WorldFeatureTreePalm extends WorldFeature {
 			createHorizontalLine(angle, leafLength);
 			
 			for(int j=0; j < intList.size(); j++) {
-				int xyz = intList.get(j);
+				int xyz = intList.getInt(j);
 				
 				int x = this.endPos.x + decodeX(xyz);
 				int y = this.endPos.y;
@@ -259,7 +263,7 @@ public class WorldFeatureTreePalm extends WorldFeature {
 			createHorizontalLine(angle, leafLength);
 			
 			for(int j=0; j < intList.size(); j++) {
-				int xyz = intList.get(j);
+				int xyz = intList.getInt(j);
 				
 				int x = this.endPos.x + decodeX(xyz);
 				int y = this.endPos.y;
diff --git a/game/core/src/main/java/net/minecraft/core/world/generate/feature/tree/spooner/WorldFeatureSpoonerTree.java b/game/core/src/main/java/net/minecraft/core/world/generate/feature/tree/spooner/WorldFeatureSpoonerTree.java
index bc326c589..09110cadb 100644
--- a/game/core/src/main/java/net/minecraft/core/world/generate/feature/tree/spooner/WorldFeatureSpoonerTree.java
+++ b/game/core/src/main/java/net/minecraft/core/world/generate/feature/tree/spooner/WorldFeatureSpoonerTree.java
@@ -1,5 +1,6 @@
 package net.minecraft.core.world.generate.feature.tree.spooner;
 
+import it.unimi.dsi.fastutil.ints.IntList;
 import net.minecraft.core.block.Blocks;
 import net.minecraft.core.block.tag.BlockTags;
 import net.minecraft.core.world.World;
@@ -12,7 +13,7 @@ import java.util.Random;
 
 public abstract class WorldFeatureSpoonerTree
     extends WorldFeature {
-    protected static int distToMat(double[] coord, double[] vec, List<Integer> matidxlist, World world, boolean invert, double limit) {
+    protected static int distToMat(double[] coord, double[] vec, IntList matidxlist, World world, boolean invert, double limit) {
         /* travel from cord along vec and return how far it was to a point of matidx
          *
          * the distance is returned in number of iterations. If the edge of the map
diff --git a/game/core/src/main/java/net/minecraft/core/world/pathfinder/PathFinder.java b/game/core/src/main/java/net/minecraft/core/world/pathfinder/PathFinder.java
index ce5c8da06..c889e23fb 100644
--- a/game/core/src/main/java/net/minecraft/core/world/pathfinder/PathFinder.java
+++ b/game/core/src/main/java/net/minecraft/core/world/pathfinder/PathFinder.java
@@ -1,11 +1,14 @@
 package net.minecraft.core.world.pathfinder;
 
+import it.unimi.dsi.fastutil.ints.Int2ObjectArrayMap;
+import it.unimi.dsi.fastutil.ints.Int2ObjectLinkedOpenHashMap;
+import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
+import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
 import net.minecraft.core.block.Block;
 import net.minecraft.core.block.BlockLogicDoor;
 import net.minecraft.core.block.Blocks;
 import net.minecraft.core.entity.Entity;
 import net.minecraft.core.block.material.Material;
-import net.minecraft.core.util.collection.IntHashMap;
 import net.minecraft.core.util.helper.MathHelper;
 import net.minecraft.core.world.WorldSource;
 import org.jetbrains.annotations.Nullable;
@@ -14,13 +17,13 @@ public class PathFinder
 {
     private final WorldSource worldSource;
     private final BinaryHeap openSet;
-    private final IntHashMap<Node> closedSet;
+    private final Int2ObjectMap<Node> closedSet;
     private final Node[] neighbors;
 
     public PathFinder(WorldSource worldSource)
     {
         openSet = new BinaryHeap();
-        closedSet = new IntHashMap<>();
+        closedSet = new Int2ObjectOpenHashMap<>();
         neighbors = new Node[32];
         this.worldSource = worldSource;
     }
diff --git a/game/core/src/main/java/net/minecraft/core/world/save/SaveFile.java b/game/core/src/main/java/net/minecraft/core/world/save/SaveFile.java
index 25407b560..55deba72b 100644
--- a/game/core/src/main/java/net/minecraft/core/world/save/SaveFile.java
+++ b/game/core/src/main/java/net/minecraft/core/world/save/SaveFile.java
@@ -1,5 +1,6 @@
 package net.minecraft.core.world.save;
 
+import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 
@@ -10,7 +11,7 @@ public class SaveFile
     implements Comparable<SaveFile>
 {
 
-    public SaveFile(@NotNull String fileName, @NotNull String displayName, @Nullable LevelData levelData, @NotNull Map<Integer, DimensionData> dimensionData, long lastTimePlayed, long sizeOnDisk, boolean needsConversion)
+    public SaveFile(@NotNull String fileName, @NotNull String displayName, @Nullable LevelData levelData, @NotNull Int2ObjectMap<DimensionData> dimensionData, long lastTimePlayed, long sizeOnDisk, boolean needsConversion)
     {
         this.fileName = Objects.requireNonNull(fileName);
         this.displayName = Objects.requireNonNull(displayName);
@@ -38,7 +39,7 @@ public class SaveFile
     	return levelData;
     }
     @NotNull
-    public Map<Integer, DimensionData> getDimensionData()
+    public Int2ObjectMap<DimensionData> getDimensionData()
     {
         return dimensionData;
     }
@@ -88,7 +89,7 @@ public class SaveFile
     private final String displayName;
     @Nullable
     private final LevelData levelData;
-    private final @NotNull Map<Integer, DimensionData> dimensionData;
+    private final @NotNull Int2ObjectMap<DimensionData> dimensionData;
     private final long lastTimePlayed;
     private final long sizeOnDisk;
     private final boolean needsConversion;
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 e1c6a2cf4..0e29802b1 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
@@ -1,6 +1,8 @@
 package net.minecraft.core.world.save;
 
 import com.mojang.logging.LogUtils;
+import it.unimi.dsi.fastutil.ints.Int2ObjectArrayMap;
+import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
 import net.minecraft.core.lang.I18n;
 import net.minecraft.core.util.helper.MathHelper;
 import com.mojang.nbt.tags.CompoundTag;
@@ -147,7 +149,7 @@ public abstract class SaveFormatBase
                 String worldName;
                 long lastTimePlayed;
                 long size;
-                Map<Integer, DimensionData> dimensionData = new HashMap<>();
+                Int2ObjectMap<DimensionData> dimensionData = new Int2ObjectArrayMap<>();
                 boolean needsConversion = false;
                 if (levelData == null) {
                     worldName = I18n.getInstance().translateKey("save.data.missing.data");
diff --git a/game/core/src/main/java/net/minecraft/core/world/save/SaveFormats.java b/game/core/src/main/java/net/minecraft/core/world/save/SaveFormats.java
index 79e6709e5..7d219878b 100644
--- a/game/core/src/main/java/net/minecraft/core/world/save/SaveFormats.java
+++ b/game/core/src/main/java/net/minecraft/core/world/save/SaveFormats.java
@@ -1,6 +1,8 @@
 package net.minecraft.core.world.save;
 
 import com.mojang.logging.LogUtils;
+import it.unimi.dsi.fastutil.ints.Int2ObjectArrayMap;
+import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
 import net.minecraft.core.world.save.legacy.SaveFormatLegacy;
 import net.minecraft.core.world.save.mcregion.SaveFormat19132;
 import net.minecraft.core.world.save.mcregion.SaveFormat19133;
@@ -14,26 +16,21 @@ import java.util.Map;
 public class SaveFormats
 {
     private static final Logger LOGGER = LogUtils.getLogger();
-    public static Map<Integer, Class<? extends ISaveFormat>> saveFormats;
+    public static final Int2ObjectMap<Class<? extends ISaveFormat>> saveFormats = new Int2ObjectArrayMap<>();
 
-    public static ISaveFormat createSaveFormat(int version, File savesDir)
-    {
+    public static ISaveFormat createSaveFormat(final int version, final File savesDir) {
         if (!saveFormats.containsKey(version)) return null;
 
-        try
-        {
+        try {
             return saveFormats.get(version).getConstructor(File.class).newInstance(savesDir);
         }
-        catch (Exception e)
-        {
+        catch (final Exception e) {
             LOGGER.error("Exception instancing ISaveFormat from '{}'!", version, e);
             return null;
         }
     }
 
-    static
-    {
-        saveFormats = new HashMap<>();
+    static {
         saveFormats.put(0, SaveFormatLegacy.class);
         saveFormats.put(19132, SaveFormat19132.class);
         saveFormats.put(19133, SaveFormat19133.class);
diff --git a/game/core/src/main/java/net/minecraft/core/world/saveddata/SavedDataStorage.java b/game/core/src/main/java/net/minecraft/core/world/saveddata/SavedDataStorage.java
index 0116f218e..f2bb30c14 100644
--- a/game/core/src/main/java/net/minecraft/core/world/saveddata/SavedDataStorage.java
+++ b/game/core/src/main/java/net/minecraft/core/world/saveddata/SavedDataStorage.java
@@ -5,6 +5,8 @@ import com.mojang.nbt.tags.Tag;
 import com.mojang.nbt.tags.CompoundTag;
 import com.mojang.nbt.tags.ShortTag;
 import com.mojang.nbt.NbtIo;
+import it.unimi.dsi.fastutil.objects.Object2ShortMap;
+import it.unimi.dsi.fastutil.objects.Object2ShortOpenHashMap;
 import net.minecraft.core.world.save.LevelStorage;
 import org.slf4j.Logger;
 
@@ -18,13 +20,13 @@ public class SavedDataStorage
     private final LevelStorage storage;
     private final Map<Serializable, SavedData> cache;
     private final List<SavedData> loadedData;
-    private final Map<String, Short> idCounts;
+    private final Object2ShortMap<String> idCounts;
 
     public SavedDataStorage(LevelStorage storage)
     {
         cache = new HashMap<>();
         loadedData = new ArrayList<>();
-        idCounts = new HashMap<>();
+        idCounts = new Object2ShortOpenHashMap<>();
         this.storage = storage;
         loadMetadata();
     }
@@ -156,15 +158,7 @@ public class SavedDataStorage
 
     public int getFreeMetadataFor(String type)
     {
-        Short metadata = idCounts.get(type);
-        if(metadata == null)
-        {
-            metadata = (short) 0;
-        }
-        else
-        {
-            metadata = (short) (metadata + 1);
-        }
+        short metadata = (short) (idCounts.getOrDefault(type, (short) -1) + 1);
         idCounts.put(type, metadata);
         if(storage == null)
         {
@@ -178,7 +172,7 @@ public class SavedDataStorage
                 CompoundTag tag = new CompoundTag();
                 for (String dataType : idCounts.keySet())
                 {
-                    short count = idCounts.get(dataType);
+                    short count = idCounts.getShort(dataType);
                     tag.putShort(dataType, count);
                 }
 
diff --git a/game/server/build.gradle.kts b/game/server/build.gradle.kts
index 212354ef1..213aeba0d 100644
--- a/game/server/build.gradle.kts
+++ b/game/server/build.gradle.kts
@@ -23,6 +23,7 @@ dependencies {
 
     // <core dependencies>
     implementation(libs.jetbrains.annotations)?.let { include(it) }
+    implementation(libs.fastutil)?.let { include(it) }
     implementation(libs.gson)?.let { include(it) }
     implementation(libs.brigadier)?.let { include(it) }
     implementation(libs.bundles.log4j)?.let { include(it) }
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 57928f434..aa7d5dd66 100644
--- a/game/server/src/main/java/net/minecraft/server/MinecraftServer.java
+++ b/game/server/src/main/java/net/minecraft/server/MinecraftServer.java
@@ -3,6 +3,9 @@ package net.minecraft.server;
 import com.mojang.brigadier.exceptions.CommandSyntaxException;
 import com.mojang.logging.LogUtils;
 import com.mojang.nbt.tags.CompoundTag;
+import it.unimi.dsi.fastutil.ints.Int2ObjectArrayMap;
+import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
+import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
 import net.minecraft.core.Global;
 import net.minecraft.core.MinecraftAccessor;
 import net.minecraft.core.achievement.stat.StatList;
@@ -127,14 +130,13 @@ public class MinecraftServer
     public static Logger LOGGER = LogUtils.getLogger();
     public static final String VERSION = Global.VERSION;
     private static MinecraftServer instance;
-    public static HashMap<String, Integer> field_6037_b = new HashMap<>();
 
     public @Nullable Boolean argOffline = null;
     public @Nullable String argWorld = null;
 
     public NetworkListenThread networkServer;
     public PropertyManager propertyManager;
-    public Map<Integer, WorldServer> dimensionWorlds;
+    public Int2ObjectMap<WorldServer> dimensionWorlds;
     public PlayerList playerList;
     private boolean serverRunning;
     public boolean serverStopped;
@@ -143,7 +145,7 @@ public class MinecraftServer
     public int percentDone;
     private final List<IUpdatePlayerListBox> playerListBoxes;
     private final List<ServerCommandEntry> commands;
-    public Map<Integer, EntityTrackerImpl> entityTrackerMap;
+    public Int2ObjectMap<EntityTrackerImpl> entityTrackerMap;
     public boolean onlineMode;
     public boolean pvpOn;
     public boolean allowFlight;
@@ -292,7 +294,7 @@ public class MinecraftServer
             }
         }
 
-        entityTrackerMap = new HashMap<>();
+        entityTrackerMap = new Int2ObjectOpenHashMap<>();
 
         new Registries();
         BiomeProviderOverworld.init();
@@ -360,9 +362,9 @@ public class MinecraftServer
             LOGGER.warn("To change this, set \"online-mode\" to \"true\" in the server.properties file.");
         }
         playerList = new PlayerList(this);
-        for (Map.Entry<Integer, Dimension> entry : Dimension.getDimensionList().entrySet())
+        for (final Int2ObjectMap.Entry<Dimension> entry : Dimension.getDimensionList().int2ObjectEntrySet())
         {
-            entityTrackerMap.put(entry.getKey(), new EntityTrackerImpl(this, entry.getValue()));
+            this.entityTrackerMap.put(entry.getIntKey(), new EntityTrackerImpl(this, entry.getValue()));
         }
         long time = System.nanoTime();
         String lName = argWorld == null ? propertyManager.getStringProperty("level-name", "world") : argWorld;
@@ -506,11 +508,11 @@ public class MinecraftServer
     private void initWorld(ISaveFormat saveFormat, String worldDirName, long l)
     {
         convertWorld(saveFormat, worldDirName);
-        dimensionWorlds = new HashMap<>();
+        dimensionWorlds = new Int2ObjectArrayMap<>();
         SaveHandlerServer saveHandler = new SaveHandlerServer(saveFormat, new File("."), worldDirName, true);
-        for (Map.Entry<Integer, Dimension> entry : Dimension.getDimensionList().entrySet())
+        for (Int2ObjectMap.Entry<Dimension> entry : Dimension.getDimensionList().int2ObjectEntrySet())
         {
-            int dimId = entry.getKey();
+            int dimId = entry.getIntKey();
             Dimension dimension = entry.getValue();
             WorldServer worldServer;
             if (dimId == 0)
@@ -725,21 +727,6 @@ public class MinecraftServer
 
     private void doTick()
     {
-        ArrayList<String> arraylist = new ArrayList<>();
-        for (String s : field_6037_b.keySet()) {
-            int i1 = field_6037_b.get(s);
-            if (i1 > 0) {
-                field_6037_b.put(s, i1 - 1);
-            } else {
-                arraylist.add(s);
-            }
-        }
-
-        for (int i = 0; i < arraylist.size(); i++)
-        {
-            field_6037_b.remove(arraylist.get(i));
-        }
-
         AABB.initializePool();
         Vec3.initializePool();
         deathTime++;
diff --git a/game/server/src/main/java/net/minecraft/server/entity/EntityTrackerImpl.java b/game/server/src/main/java/net/minecraft/server/entity/EntityTrackerImpl.java
index 9be2e54b8..6c5a9c75a 100644
--- a/game/server/src/main/java/net/minecraft/server/entity/EntityTrackerImpl.java
+++ b/game/server/src/main/java/net/minecraft/server/entity/EntityTrackerImpl.java
@@ -1,5 +1,8 @@
 package net.minecraft.server.entity;
 
+import it.unimi.dsi.fastutil.ints.Int2ObjectArrayMap;
+import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
+import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
 import net.minecraft.core.entity.Entity;
 import net.minecraft.core.entity.player.Player;
 import net.minecraft.core.net.entity.EntityTracker;
@@ -7,7 +10,6 @@ import net.minecraft.core.net.entity.EntityTrackerEntry;
 import net.minecraft.core.net.entity.ITrackedEntry;
 import net.minecraft.core.net.entity.NetEntityHandler;
 import net.minecraft.core.net.packet.Packet;
-import net.minecraft.core.util.collection.IntHashMap;
 import net.minecraft.core.world.Dimension;
 import net.minecraft.server.MinecraftServer;
 import net.minecraft.server.entity.player.PlayerServer;
@@ -19,14 +21,14 @@ import java.util.Set;
 
 public class EntityTrackerImpl implements EntityTracker {
     public final Set<EntityTrackerEntryImpl> trackedEntitySet;
-    public final IntHashMap<EntityTrackerEntryImpl> trackedEntityHashTable;
+    public final Int2ObjectMap<EntityTrackerEntryImpl> trackedEntityHashTable;
     public final MinecraftServer mcServer;
     public final int maxTrackingDistanceThreshold;
     public final Dimension dimension;
 
     public EntityTrackerImpl(MinecraftServer minecraftserver, Dimension dimensions) {
         trackedEntitySet = new HashSet<>();
-        trackedEntityHashTable = new IntHashMap<>();
+        trackedEntityHashTable = new Int2ObjectOpenHashMap<>();
         mcServer = minecraftserver;
         dimension = dimensions;
         maxTrackingDistanceThreshold = minecraftserver.playerList.getMaxTrackingDistance();
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 869dd63f7..d7689c58f 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
@@ -1,6 +1,9 @@
 package net.minecraft.server.net;
 
 import com.mojang.logging.LogUtils;
+import it.unimi.dsi.fastutil.ints.Int2ObjectArrayMap;
+import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
+import it.unimi.dsi.fastutil.objects.ObjectSet;
 import net.minecraft.core.achievement.Achievements;
 import net.minecraft.core.block.entity.TileEntity;
 import net.minecraft.core.data.registry.Registries;
@@ -34,7 +37,7 @@ public class PlayerList
     public static Logger logger = LogUtils.getLogger();
     public List<PlayerServer> playerEntities;
     private final MinecraftServer server;
-    private final Map<Integer, PlayerManager> playerManagers;
+    private final Int2ObjectMap<PlayerManager> playerManagers;
     private final Set<UUID> bans;
     private final Set<String> ipBans;
     private final Set<UUID> ops;
@@ -55,14 +58,14 @@ public class PlayerList
         ipBans = new HashSet<>();
         ops = new HashSet<>();
         whitelist = new HashSet<>();
-        playerManagers = new HashMap<>();
+        playerManagers = new Int2ObjectArrayMap<>();
         this.server = server;
         bansFile = server.getFile("banned-players.txt");
         ipBansFile = server.getFile("banned-ips.txt");
         opsFile = server.getFile("ops.txt");
         whitelistFile = server.getFile("white-list.txt");
         int viewDistance = server.propertyManager.getIntProperty("view-distance", 10);
-        for (Integer dim : Dimension.getDimensionList().keySet())
+        for (int dim : Dimension.getDimensionList().keySet())
         {
             playerManagers.put(dim, new PlayerManager(server, dim, viewDistance));
         }
@@ -104,7 +107,7 @@ public class PlayerList
         }
     }
 
-    public void setPlayerManager(Map<Integer, WorldServer> worldServerMap)
+    public void setPlayerManager(Int2ObjectMap<WorldServer> worldServerMap)
     {
         playerIo = worldServerMap.get(0).getSaveHandler().getPlayerFileData();
     }
diff --git a/game/server/src/main/java/net/minecraft/server/net/handler/PacketHandlerServer.java b/game/server/src/main/java/net/minecraft/server/net/handler/PacketHandlerServer.java
index b39251b7a..3ee1d337c 100644
--- a/game/server/src/main/java/net/minecraft/server/net/handler/PacketHandlerServer.java
+++ b/game/server/src/main/java/net/minecraft/server/net/handler/PacketHandlerServer.java
@@ -2,6 +2,8 @@ package net.minecraft.server.net.handler;
 
 import com.mojang.brigadier.exceptions.CommandSyntaxException;
 import com.mojang.logging.LogUtils;
+import it.unimi.dsi.fastutil.ints.Int2ShortArrayMap;
+import it.unimi.dsi.fastutil.ints.Int2ShortMap;
 import net.minecraft.core.block.entity.TileEntity;
 import net.minecraft.core.block.entity.TileEntityFlag;
 import net.minecraft.core.block.entity.TileEntityMobSpawner;
@@ -57,7 +59,7 @@ public class PacketHandlerServer extends PacketHandler
     {
         connectionClosed = false;
         hasMoved = true;
-        guiIdMap = new HashMap<>();
+        guiIdMap = new Int2ShortArrayMap();
         mcServer = minecraftserver;
         netManager = networkManager;
         networkManager.setNetHandler(this);
@@ -873,6 +875,6 @@ public class PacketHandlerServer extends PacketHandler
     private double lastPosY;
     private double lastPosZ;
     private boolean hasMoved;
-    private final Map<Integer, Short> guiIdMap;
+    private final Int2ShortMap guiIdMap;
 
 }
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 6356ee414..719b54ce5 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
@@ -3,9 +3,10 @@ package net.minecraft.server.world;
 import java.util.ArrayList;
 import java.util.List;
 
+import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
+import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
 import net.minecraft.core.Global;
 import net.minecraft.core.block.entity.TileEntity;
-import net.minecraft.core.util.collection.IntHashMap;
 import net.minecraft.core.world.*;
 import net.minecraft.core.entity.Entity;
 import net.minecraft.core.entity.player.Player;
@@ -25,7 +26,7 @@ public class WorldServer extends World
     public WorldServer(MinecraftServer minecraftserver, LevelStorage isavehandler, String name, int dimensionId, WorldType worldType, long seed)
     {
         super(isavehandler, name, seed, Dimension.getDimensionList().get(dimensionId), worldType);
-        entityIntHashMap = new IntHashMap<>();
+        entityIntHashMap = new Int2ObjectOpenHashMap<>();
         mcServer = minecraftserver;
     }
 
@@ -238,6 +239,6 @@ public class WorldServer extends World
     public ChunkProviderServer chunkProviderServer;
     public boolean dontSave;
     public MinecraftServer mcServer;
-    private final IntHashMap<Entity> entityIntHashMap;
+    private final Int2ObjectMap<Entity> entityIntHashMap;
     private long lastWeatherSend = System.currentTimeMillis();
 }
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 e5ba04ba6..f32caa13c 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
@@ -1,6 +1,10 @@
 package net.minecraft.server.world.chunk.provider;
 
 import com.mojang.logging.LogUtils;
+import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
+import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
+import it.unimi.dsi.fastutil.ints.IntOpenHashSet;
+import it.unimi.dsi.fastutil.ints.IntSet;
 import net.minecraft.core.world.ProgressListener;
 import net.minecraft.core.world.chunk.provider.IChunkProvider;
 import net.minecraft.server.world.WorldServer;
@@ -15,20 +19,20 @@ public class ChunkProviderServer
     implements IChunkProvider
 {
     private static final Logger LOGGER = LogUtils.getLogger();
-    private final Set<Integer> droppedChunksSet;
+    private final IntSet droppedChunksSet;
     private final Chunk emptyChunk;
     public ChunkGenerator chunkGenerator;
     private final IChunkLoader chunkLoader;
     public boolean chunkLoadOverride;
-    private final Map<Integer, Chunk> chunkMap;
+    private final Int2ObjectMap<Chunk> chunkMap;
     private final List<Chunk> chunkList;
     private final WorldServer world;
 
     public ChunkProviderServer(WorldServer world, IChunkLoader chunkLoader, ChunkGenerator chunkGenerator)
     {
-        droppedChunksSet = new HashSet<>();
+        droppedChunksSet = new IntOpenHashSet();
         chunkLoadOverride = false;
-        chunkMap = new HashMap<>();
+        chunkMap = new Int2ObjectOpenHashMap<>();
         chunkList = new ArrayList<>();
         emptyChunk = new EmptyChunk(world, 0, 0);
         this.world = world;
@@ -247,7 +251,7 @@ public class ChunkProviderServer
             {
                 if(!droppedChunksSet.isEmpty())
                 {
-                    Integer integer = droppedChunksSet.iterator().next();
+                    int integer = droppedChunksSet.iterator().nextInt();
                     Chunk chunk = chunkMap.get(integer);
                     saveChunkToFile(chunk);
                     chunk.onUnload();
diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml
index b3d9e4852..cdbd9729e 100644
--- a/gradle/libs.versions.toml
+++ b/gradle/libs.versions.toml
@@ -5,6 +5,7 @@ lwjgl = "3.3.4"
 [libraries]
 jetbrains-annotations = { module = "org.jetbrains:annotations", version = "24.0.0" }
 gson = { module = "com.google.code.gson:gson", version = "2.10.1" }
+fastutil = { module = "it.unimi.dsi:fastutil", version = "8.5.15" }
 brigadier = { module = "com.github.Better-than-Adventure:bta-brigadier", version = "1.0.2"}
 slf4j-api = { module = "org.slf4j:slf4j-api", version = "2.0.7" }
 log4j-core = { module = "org.apache.logging.log4j:log4j-core", version.ref = "log4j" }
diff --git a/util/datagen/src/main/java/net/minecraft/datagen/SmeltingGenerator.java b/util/datagen/src/main/java/net/minecraft/datagen/SmeltingGenerator.java
index fda6420f2..efd246dc4 100644
--- a/util/datagen/src/main/java/net/minecraft/datagen/SmeltingGenerator.java
+++ b/util/datagen/src/main/java/net/minecraft/datagen/SmeltingGenerator.java
@@ -26,9 +26,8 @@ public class SmeltingGenerator {
 
         sharedRecipe("raw_iron_to_iron_ingot", Items.ORE_RAW_IRON.getDefaultStack(), Items.INGOT_IRON.getDefaultStack());
         sharedRecipe("raw_gold_to_gold_ingot", Items.ORE_RAW_GOLD.getDefaultStack(), Items.INGOT_GOLD.getDefaultStack());
-
-        sharedRecipe("dough_to_bread", Items.DOUGH.getDefaultStack(), Items.FOOD_BREAD.getDefaultStack());
-
+        
+        furnaceRecipe("dough_to_bread", Items.DOUGH.getDefaultStack(), Items.FOOD_BREAD.getDefaultStack());
         furnaceRecipe("fish_raw_to_fish_cooked", Items.FOOD_FISH_RAW.getDefaultStack(), Items.FOOD_FISH_COOKED.getDefaultStack());
         furnaceRecipe("porkchop_raw_to_porkchop_cooked", Items.FOOD_PORKCHOP_RAW.getDefaultStack(), Items.FOOD_PORKCHOP_COOKED.getDefaultStack());
         furnaceRecipe("venison_raw_to_venison_cooked", Items.FOOD_VENISON_RAW.getDefaultStack(), Items.FOOD_VENISON_COOKED.getDefaultStack());
diff --git a/util/datagen/src/main/java/net/minecraft/datagen/WorkbenchGenerator.java b/util/datagen/src/main/java/net/minecraft/datagen/WorkbenchGenerator.java
index d6238118b..0e40ec441 100644
--- a/util/datagen/src/main/java/net/minecraft/datagen/WorkbenchGenerator.java
+++ b/util/datagen/src/main/java/net/minecraft/datagen/WorkbenchGenerator.java
@@ -1266,7 +1266,7 @@ class WorkbenchGenerator {
             .setShape(
                 "#X#",
                 "III")
-            .addInput('#', Items.STICK)
+            .addInput('#', Blocks.TORCH_REDSTONE_ACTIVE)
             .addInput('X', Items.DUST_REDSTONE)
             .addInput('I', "minecraft:stones")
             .create("redstone_repeater", new ItemStack(Items.REPEATER, 1));
diff --git a/util/seed-viewer/build.gradle.kts b/util/seed-viewer/build.gradle.kts
index ed88b92e6..73f710b26 100644
--- a/util/seed-viewer/build.gradle.kts
+++ b/util/seed-viewer/build.gradle.kts
@@ -22,6 +22,7 @@ dependencies {
     testImplementation("org.junit.jupiter:junit-jupiter")
 
     implementation(libs.brigadier)?.let { include(it) }
+    implementation(libs.fastutil)?.let { include(it) }
 
     implementation(project(":game:core"))?.let { include(it) }
     implementation(project(":util:logging"))?.let { include(it) }
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 91030b157..4de727b4c 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
@@ -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 it.unimi.dsi.fastutil.ints.Int2ObjectMap;
 import net.minecraft.core.world.ProgressListener;
 import net.minecraft.core.world.World;
 import net.minecraft.core.world.chunk.Chunk;
@@ -88,7 +89,7 @@ public class ChunkLoader implements IChunkProvider {
         chunk.isTerrainPopulated = reader.getIsTerrainPopulated();
         chunk.temperature = reader.getTemperatureMap();
         chunk.humidity = reader.getHumidityMap();
-        Map<Integer, String> biomeRegistry = reader.getBiomeRegistry();
+        Int2ObjectMap<String> biomeRegistry = reader.getBiomeRegistry();
 
         for(int i = 0; i < Chunk.CHUNK_SECTIONS; ++i) {
             ChunkLoaderLegacy.loadChunkSectionFromCompound(chunk.getSection(i), reader, biomeRegistry);
