diff --git a/game/client/build.gradle.kts b/game/client/build.gradle.kts
index 6f5d97f6e..1e0862be2 100644
--- a/game/client/build.gradle.kts
+++ b/game/client/build.gradle.kts
@@ -83,8 +83,8 @@ dependencies {
 }
 
 java {
-    sourceCompatibility = JavaVersion.VERSION_1_8
-    targetCompatibility = JavaVersion.VERSION_1_8
+    sourceCompatibility = JavaVersion.VERSION_17
+    targetCompatibility = JavaVersion.VERSION_17
 }
 
 //region Tasks
@@ -313,9 +313,9 @@ tasks.cyclonedxBom {
 tasks.withType(JavaCompile::class.java) {
     options.isIncremental = false
     options.encoding = "UTF-8"
-    if (JavaVersion.current() != JavaVersion.VERSION_1_8) {
+    if (JavaVersion.current() != JavaVersion.VERSION_17) {
         options.compilerArgs.add("--release")
-        options.compilerArgs.add("8")
+        options.compilerArgs.add("17")
     }
 }
 
diff --git a/game/client/instance/patches/net.minecraft.json b/game/client/instance/patches/net.minecraft.json
index 884924ace..ccb092435 100644
--- a/game/client/instance/patches/net.minecraft.json
+++ b/game/client/instance/patches/net.minecraft.json
@@ -7,7 +7,7 @@
     ],
     "formatVersion": 1,
     "compatibleJavaMajors": [
-        8, 17
+        17
     ],
     "compatibleJavaName": "java-runtime-gamma",
     "mainJar": {
diff --git a/game/core/build.gradle.kts b/game/core/build.gradle.kts
index 6b45882d5..e9a266e5e 100644
--- a/game/core/build.gradle.kts
+++ b/game/core/build.gradle.kts
@@ -45,8 +45,8 @@ dependencies {
 
 
 java {
-    sourceCompatibility = JavaVersion.VERSION_1_8
-    targetCompatibility = JavaVersion.VERSION_1_8
+    sourceCompatibility = JavaVersion.VERSION_17
+    targetCompatibility = JavaVersion.VERSION_17
 }
 
 //region Tasks
@@ -130,9 +130,9 @@ fun genProtocol(version: String, channel: String): String {
 tasks.withType(JavaCompile::class.java) {
     options.isIncremental = false
     options.encoding = "UTF-8"
-    if (JavaVersion.current() != JavaVersion.VERSION_1_8) {
+    if (JavaVersion.current() != JavaVersion.VERSION_17) {
         options.compilerArgs.add("--release")
-        options.compilerArgs.add("8")
+        options.compilerArgs.add("17")
     }
 }
 
diff --git a/game/core/src/main/java/net/minecraft/core/util/helper/MathHelper.java b/game/core/src/main/java/net/minecraft/core/util/helper/MathHelper.java
index 0d4bec236..8983428c0 100644
--- a/game/core/src/main/java/net/minecraft/core/util/helper/MathHelper.java
+++ b/game/core/src/main/java/net/minecraft/core/util/helper/MathHelper.java
@@ -42,6 +42,10 @@ public class MathHelper
         return d >= (double)truncated ? truncated : truncated - 1;
     }
 
+    public static int floorIntDiv(final int a, final int b) {
+        return floor((double) a / (double) b);
+    }
+
     public static int ceil(double d)
     {
         int truncated = (int)d;
@@ -158,18 +162,34 @@ public class MathHelper
         return value - Math.floor(value/n) * n;
     }
 
+    /**
+     * Performs the Smoothstep function on the given inputs, producing a sigmoid appearance.
+     * <p>
+     * See: <a href="https://en.wikipedia.org/wiki/Smoothstep">Wikipedia</a>
+     * <img src="https://upload.wikimedia.org/wikipedia/commons/thumb/5/57/Smoothstep_and_Smootherstep.svg/320px-Smoothstep_and_Smootherstep.svg.png"/>
+     */
     public static float smoothstep(final float value, final float min, final float max) {
         final float v = clamp((value - min) / (max - min), 0.0f, 1.0f);
 
         return v * v * (3.0f - 2.0f * v);
     }
 
+    /**
+     * A smoother version of the Smoothstep function. Ken Perlin strikes again.
+     */
     public static float smootherstep(final float value, final float min, final float max) {
         final float v = clamp((value - min) / (max - min), 0.0f, 1.0f);
 
         return v * v * v * (v * (6.0f * v - 15.0f) + 10.0f);
     }
 
+    /**
+     * Performs the Cantor pairing function on the inputs, producing a number that is unique for any pair of inputs.
+     */
+    public static int cantor(final int a, final int b) {
+        return ((a + b) * (a + b + 1)) / 2 + b;
+    }
+
     private static final float[] SIN_TABLE;
 
     public static final float PI = (float)Math.PI;
diff --git a/game/core/src/main/java/net/minecraft/core/util/pool/ObjectPool.java b/game/core/src/main/java/net/minecraft/core/util/pool/ObjectPool.java
index b633a533d..63eb7709d 100644
--- a/game/core/src/main/java/net/minecraft/core/util/pool/ObjectPool.java
+++ b/game/core/src/main/java/net/minecraft/core/util/pool/ObjectPool.java
@@ -72,11 +72,13 @@ public class ObjectPool<T extends Poolable<T>> {
      * @return An instance of T to be used.
      */
     public @NotNull T get() {
-        if (this.poolPointer >= this.pool.size()) {
-            this.pool.add(this.factory.createDefault());
-        }
+//        if (this.poolPointer >= this.pool.size()) {
+//            this.pool.add(this.factory.createDefault());
+//        }
+//
+//        return this.pool.get(this.poolPointer++);
 
-        return this.pool.get(this.poolPointer++);
+        return this.getUnpooled();
     }
 
     /**
diff --git a/game/core/src/main/java/net/minecraft/core/world/pos/ChunkPos.java b/game/core/src/main/java/net/minecraft/core/world/pos/ChunkPos.java
new file mode 100644
index 000000000..296231e86
--- /dev/null
+++ b/game/core/src/main/java/net/minecraft/core/world/pos/ChunkPos.java
@@ -0,0 +1,73 @@
+package net.minecraft.core.world.pos;
+
+import net.minecraft.core.entity.Entity;
+import net.minecraft.core.util.helper.Direction;
+import net.minecraft.core.util.helper.MathHelper;
+import net.minecraft.core.world.chunk.Chunk;
+import org.jetbrains.annotations.NotNull;
+
+public final class ChunkPos {
+    public int x;
+    public int z;
+
+    public ChunkPos(final int x, final int z) {
+        this.x = x;
+        this.z = z;
+    }
+
+    public ChunkPos(final @NotNull TilePos tilePos) {
+        this(
+            MathHelper.floorIntDiv(tilePos.x, Chunk.CHUNK_SIZE_X),
+            MathHelper.floorIntDiv(tilePos.z, Chunk.CHUNK_SIZE_Z)
+        );
+    }
+
+    public ChunkPos(final @NotNull Entity entity) {
+        this(
+            MathHelper.floor(entity.x / (double) Chunk.CHUNK_SIZE_X),
+            MathHelper.floor(entity.z / (double) Chunk.CHUNK_SIZE_Z)
+        );
+    }
+
+    public @NotNull TilePos toTilePos(final @NotNull ChunkTilePos chunkTilePos) {
+        return new TilePos(this, chunkTilePos);
+    }
+
+    public @NotNull ChunkPos add(final int x, final int z) {
+        return new ChunkPos(this.x + x, this.z + z);
+    }
+
+    public @NotNull ChunkPos add(final @NotNull ChunkPos other) {
+        return new ChunkPos(this.x + other.x, this.z + other.z);
+    }
+
+    public @NotNull ChunkPos add(final @NotNull Direction direction, final int distance) {
+        return new ChunkPos(this.x + direction.getOffsetX() * distance, this.z + direction.getOffsetZ() * distance);
+    }
+
+    public @NotNull ChunkPos add(final @NotNull Direction direction) {
+        return this.add(direction, 1);
+    }
+
+    public @NotNull ChunkPos sub(final int x, final int z) {
+        return new ChunkPos(this.x - x, this.z - z);
+    }
+
+    public @NotNull ChunkPos sub(final @NotNull ChunkPos other) {
+        return new ChunkPos(this.x - other.x, this.z - other.z);
+    }
+
+    @Override
+    public boolean equals(final Object obj) {
+        if (!(obj instanceof final @NotNull ChunkPos other)) {
+            return false;
+        } else {
+            return this.x == other.x && this.z == other.z;
+        }
+    }
+
+    @Override
+    public int hashCode() {
+        return MathHelper.cantor(this.x, this.z);
+    }
+}
diff --git a/game/core/src/main/java/net/minecraft/core/world/pos/ChunkTilePos.java b/game/core/src/main/java/net/minecraft/core/world/pos/ChunkTilePos.java
new file mode 100644
index 000000000..c579e6c2e
--- /dev/null
+++ b/game/core/src/main/java/net/minecraft/core/world/pos/ChunkTilePos.java
@@ -0,0 +1,83 @@
+package net.minecraft.core.world.pos;
+
+import net.minecraft.core.entity.Entity;
+import net.minecraft.core.util.helper.Direction;
+import net.minecraft.core.util.helper.MathHelper;
+import net.minecraft.core.util.phys.Vec3;
+import net.minecraft.core.world.chunk.Chunk;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+public final class ChunkTilePos {
+    public int x;
+    public int y;
+    public int z;
+
+    public ChunkTilePos(final int x, final int y, final int z) {
+        this.x = Integer.remainderUnsigned(x, Chunk.CHUNK_SIZE_X);
+        this.y = y;
+        this.z = Integer.remainderUnsigned(z, Chunk.CHUNK_SIZE_Z);
+    }
+
+    public ChunkTilePos(final float x, final float y, final float z) {
+        this(MathHelper.floor(x), MathHelper.floor(y), MathHelper.floor(z));
+    }
+
+    public ChunkTilePos(final double x, final double y, final double z) {
+        this(MathHelper.floor(x), MathHelper.floor(y), MathHelper.floor(z));
+    }
+
+    public ChunkTilePos(final @NotNull TilePos tilePos) {
+        this(tilePos.x, tilePos.y, tilePos.z);
+    }
+
+    public ChunkTilePos(final @NotNull Vec3 vec) {
+        this(vec.x, vec.y, vec.z);
+    }
+
+    public ChunkTilePos(final @NotNull Entity entity) {
+        this(entity.x, entity.y, entity.z);
+    }
+
+    public @NotNull TilePos toTilePos(final @NotNull ChunkPos chunkPos) {
+        return new TilePos(chunkPos, this);
+    }
+
+    public @NotNull ChunkTilePos add(final int x, final int y, final int z) {
+        return new ChunkTilePos(this.x + x, this.y + y, this.z + z);
+    }
+
+    public @NotNull ChunkTilePos add(final @NotNull TilePos other) {
+        return new ChunkTilePos(this.x + other.x, this.y + other.y, this.z + other.z);
+    }
+
+    public @NotNull ChunkTilePos add(final @NotNull Direction direction, final int distance) {
+        return new ChunkTilePos(this.x + direction.getOffsetX() * distance, this.y + direction.getOffsetY() * distance, this.z + direction.getOffsetZ() * distance);
+    }
+
+    public @NotNull ChunkTilePos add(final @NotNull Direction direction) {
+        return this.add(direction, 1);
+    }
+
+    public @NotNull ChunkTilePos sub(final int x, final int y, final int z) {
+        return new ChunkTilePos(this.x - x, this.y - y, this.z - z);
+    }
+
+    public @NotNull ChunkTilePos sub(final @NotNull TilePos other) {
+        return new ChunkTilePos(this.x - other.x, this.y - other.y, this.z - other.z);
+    }
+
+    @Override
+    public boolean equals(final @Nullable Object obj) {
+        if (!(obj instanceof final @NotNull ChunkTilePos other)) {
+            return false;
+        } else {
+            return this.x == other.x && this.y == other.y && this.z == other.z;
+        }
+    }
+
+    @Override
+    public int hashCode() {
+        return MathHelper.cantor(MathHelper.cantor(this.x, this.y), this.z);
+    }
+}
diff --git a/game/core/src/main/java/net/minecraft/core/world/pos/TilePos.java b/game/core/src/main/java/net/minecraft/core/world/pos/TilePos.java
new file mode 100644
index 000000000..ee02ec8eb
--- /dev/null
+++ b/game/core/src/main/java/net/minecraft/core/world/pos/TilePos.java
@@ -0,0 +1,87 @@
+package net.minecraft.core.world.pos;
+
+import net.minecraft.core.entity.Entity;
+import net.minecraft.core.util.helper.Direction;
+import net.minecraft.core.util.helper.MathHelper;
+import net.minecraft.core.util.phys.Vec3;
+import net.minecraft.core.world.chunk.Chunk;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+public final class TilePos {
+    public int x;
+    public int y;
+    public int z;
+
+    public TilePos(final int x, final int y, final int z) {
+        this.x = x;
+        this.y = y;
+        this.z = z;
+    }
+
+    public TilePos(final float x, final float y, final float z) {
+        this(MathHelper.floor(x), MathHelper.floor(y), MathHelper.floor(z));
+    }
+
+    public TilePos(final double x, final double y, final double z) {
+        this(MathHelper.floor(x), MathHelper.floor(y), MathHelper.floor(z));
+    }
+
+    public TilePos(final @NotNull ChunkPos chunkPos, final @NotNull ChunkTilePos chunkTilePos) {
+        this(chunkPos.x * Chunk.CHUNK_SIZE_X + chunkTilePos.x, chunkTilePos.y, chunkPos.z * Chunk.CHUNK_SIZE_Z + chunkTilePos.z);
+    }
+
+    public TilePos(final @NotNull Vec3 vec) {
+        this(vec.x, vec.y, vec.z);
+    }
+
+    public TilePos(final @NotNull Entity entity) {
+        this(entity.x, entity.y, entity.z);
+    }
+
+    public @NotNull ChunkPos toChunkPos() {
+        return new ChunkPos(this);
+    }
+
+    public @NotNull ChunkTilePos toChunkTilePos() {
+        return new ChunkTilePos(this);
+    }
+
+    public @NotNull TilePos add(final int x, final int y, final int z) {
+        return new TilePos(this.x + x, this.y + y, this.z + z);
+    }
+
+    public @NotNull TilePos add(final @NotNull TilePos other) {
+        return new TilePos(this.x + other.x, this.y + other.y, this.z + other.z);
+    }
+
+    public @NotNull TilePos add(final @NotNull Direction direction, final int distance) {
+        return new TilePos(this.x + direction.getOffsetX() * distance, this.y + direction.getOffsetY() * distance, this.z + direction.getOffsetZ() * distance);
+    }
+
+    public @NotNull TilePos add(final @NotNull Direction direction) {
+        return this.add(direction, 1);
+    }
+
+    public @NotNull TilePos sub(final int x, final int y, final int z) {
+        return new TilePos(this.x - x, this.y - y, this.z - z);
+    }
+
+    public @NotNull TilePos sub(final @NotNull TilePos other) {
+        return new TilePos(this.x - other.x, this.y - other.y, this.z - other.z);
+    }
+
+    @Override
+    public boolean equals(final @Nullable Object obj) {
+        if (!(obj instanceof final @NotNull TilePos other)) {
+            return false;
+        } else {
+            return this.x == other.x && this.y == other.y && this.z == other.z;
+        }
+    }
+
+    @Override
+    public int hashCode() {
+        return MathHelper.cantor(MathHelper.cantor(this.x, this.y), this.z);
+    }
+}
diff --git a/game/server/build.gradle.kts b/game/server/build.gradle.kts
index 213aeba0d..4b7f02f51 100644
--- a/game/server/build.gradle.kts
+++ b/game/server/build.gradle.kts
@@ -34,8 +34,8 @@ dependencies {
 
 
 java {
-    sourceCompatibility = JavaVersion.VERSION_1_8
-    targetCompatibility = JavaVersion.VERSION_1_8
+    sourceCompatibility = JavaVersion.VERSION_17
+    targetCompatibility = JavaVersion.VERSION_17
 }
 
 //region Tasks
@@ -71,9 +71,9 @@ val buildJar by tasks.registering(ShadowJar::class) {
 tasks.withType(JavaCompile::class.java) {
     options.isIncremental = false
     options.encoding = "UTF-8"
-    if (JavaVersion.current() != JavaVersion.VERSION_1_8) {
+    if (JavaVersion.current() != JavaVersion.VERSION_17) {
         options.compilerArgs.add("--release")
-        options.compilerArgs.add("8")
+        options.compilerArgs.add("17")
     }
 }
 //endregion
diff --git a/util/isom/build.gradle.kts b/util/isom/build.gradle.kts
index d14ca559f..137e5a7df 100644
--- a/util/isom/build.gradle.kts
+++ b/util/isom/build.gradle.kts
@@ -61,8 +61,8 @@ val run by tasks.registering(JavaExec::class) {
 //endregion
 
 java {
-    sourceCompatibility = JavaVersion.VERSION_1_8
-    targetCompatibility = JavaVersion.VERSION_1_8
+    sourceCompatibility = JavaVersion.VERSION_17
+    targetCompatibility = JavaVersion.VERSION_17
 }
 
 tasks.test {
diff --git a/util/logging/build.gradle.kts b/util/logging/build.gradle.kts
index ee3683f2a..b956f75a5 100644
--- a/util/logging/build.gradle.kts
+++ b/util/logging/build.gradle.kts
@@ -18,8 +18,8 @@ dependencies {
 }
 
 java {
-    sourceCompatibility = JavaVersion.VERSION_1_8
-    targetCompatibility = JavaVersion.VERSION_1_8
+    sourceCompatibility = JavaVersion.VERSION_17
+    targetCompatibility = JavaVersion.VERSION_17
 }
 
 tasks.withType(Jar::class.java) {
diff --git a/util/nbt/build.gradle.kts b/util/nbt/build.gradle.kts
index b73d22a8e..828790f72 100644
--- a/util/nbt/build.gradle.kts
+++ b/util/nbt/build.gradle.kts
@@ -18,8 +18,8 @@ dependencies {
 }
 
 java {
-    sourceCompatibility = JavaVersion.VERSION_1_8
-    targetCompatibility = JavaVersion.VERSION_1_8
+    sourceCompatibility = JavaVersion.VERSION_17
+    targetCompatibility = JavaVersion.VERSION_17
 }
 
 tasks.withType(Jar::class.java) {
diff --git a/util/seed-viewer/build.gradle.kts b/util/seed-viewer/build.gradle.kts
index 73f710b26..0a64b8598 100644
--- a/util/seed-viewer/build.gradle.kts
+++ b/util/seed-viewer/build.gradle.kts
@@ -35,8 +35,8 @@ dependencies {
 }
 
 java {
-    sourceCompatibility = JavaVersion.VERSION_1_8
-    targetCompatibility = JavaVersion.VERSION_1_8
+    sourceCompatibility = JavaVersion.VERSION_17
+    targetCompatibility = JavaVersion.VERSION_17
 }
 
 //region Tasks
diff --git a/util/stellar/build.gradle.kts b/util/stellar/build.gradle.kts
index a8b5eebc0..f69f57ca4 100644
--- a/util/stellar/build.gradle.kts
+++ b/util/stellar/build.gradle.kts
@@ -31,9 +31,9 @@ val run by tasks.registering(JavaExec::class) {
 tasks.withType(JavaCompile::class.java) {
     options.isIncremental = false
     options.encoding = "UTF-8"
-    if (JavaVersion.current() != JavaVersion.VERSION_1_8) {
+    if (JavaVersion.current() != JavaVersion.VERSION_17) {
         options.compilerArgs.add("--release")
-        options.compilerArgs.add("8")
+        options.compilerArgs.add("17")
     }
 }
 //endregion
\ No newline at end of file
