diff --git a/src/main/java/com/volmit/iris/util/math/Spiral.java b/src/main/java/com/volmit/iris/util/math/Spiral.java
new file mode 100644
index 000000000..6dd93e383
--- /dev/null
+++ b/src/main/java/com/volmit/iris/util/math/Spiral.java
@@ -0,0 +1,102 @@
+/*
+ * Iris is a World Generator for Minecraft Bukkit Servers
+ * Copyright (c) 2021 Arcane Arts (Volmit Software)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+package com.volmit.iris.util.math;
+
+import lombok.AllArgsConstructor;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.Iterator;
+
+/**
+ * Represents a spiraler which can start from any point within Long.MAX_VALUE by Long.MAX_VALUE and iterate anywhere.
+ */
+public record Spiral(Position2 start, long max) implements Iterable {
+ @SuppressWarnings("ConstantConditions")
+ public static Position2 next(Position2 p) {
+ int x = p.getX();
+ int z = p.getZ();
+ int ax = Math.abs(x);
+ int az = Math.abs(z);
+
+ if (x == 0 && z == 0) {
+ return p.add(1, 0);
+ }
+
+ if (ax == az) {
+ if (x > 0 && z > 0) return left(p);
+ else if (x < 0 && z > 0) return down(p);
+ else if (x < 0 && z < 0) return right(p);
+ else if (x > 0 && z < 0) return up(p);
+ } else {
+ if (x > z && ax > az) return up(p);
+ else if (x < z && ax < az) return left(p);
+ else if (x < z && ax > az) return down(p);
+ else if (x > z && ax < az) return right(p);
+ }
+
+ return p;
+ }
+
+ public static Spiral from(Position2 p, long iterations)
+ {
+ return new Spiral(p, iterations);
+ }
+
+ private static Position2 down(Position2 p) {
+ return p.add(0, -1);
+ }
+
+ private static Position2 up(Position2 p) {
+ return p.add(0, 1);
+ }
+
+ private static Position2 left(Position2 p) {
+ return p.add(-1, 0);
+ }
+
+ private static Position2 right(Position2 p) {
+ return p.add(1, 0);
+ }
+
+ @NotNull
+ @Override
+ public Iterator iterator() {
+ return new SpiralIterator(0, this, start);
+ }
+
+ @AllArgsConstructor
+ static class SpiralIterator implements Iterator {
+ private long itr = 0;
+ private final Spiral s;
+ private Position2 cursor;
+
+ @Override
+ public boolean hasNext() {
+ return itr < s.max();
+ }
+
+ @Override
+ public Position2 next() {
+ Position2 m = cursor;
+ cursor = Spiral.next(cursor);
+ itr++;
+ return m;
+ }
+ }
+}