diff --git a/js/levels.js b/js/levels.js
index 5b69ccf..756d6b0 100644
--- a/js/levels.js
+++ b/js/levels.js
@@ -1,55 +1,74 @@
+function cumulativeExponential(base, levels) {
+    return Decimal.add(levels, 1).pow_base(base).sub(1).div(Decimal.sub(base, 1))
+}
+function inverseCumulativeExponential(base, levels) {
+    return Decimal.sub(base, 1).mul(levels).add(1).log(base)
+}
+
 function getAlphaLevel(points = player.p.points) {
     if (Decimal.eq(points, 0)) return new Decimal(0)
-    return Decimal.add(points, 10).div(11).log(1.1).add(1).floor().max(0)
+    return inverseCumulativeExponential(1.1, Decimal.pow(points, buyableEffect('p', 13).pow(-1))).floor()
 }
 function getAlphaCost(points = player.p.points) {
-    return getAlphaLevel(points).pow_base(1.1).mul(11).sub(10)
+    return cumulativeExponential(1.1, getAlphaLevel(points)).pow(buyableEffect('p', 13))
 }
 function getAlphaEffect(points = player.p.points) {
-    return getAlphaLevel(points).mul(getAlphaRankEffect(points).add(0.05))
+    return getAlphaLevel(points).mul(getAlphaRankEffect(points).add(1/20))
 }
 function getBetaLevel(points = player.p.points) {
     if (Decimal.eq(points, 0)) return new Decimal(0)
-    return Decimal.add(points, 20).div(25).log(1.25).add(1).floor().max(0)
+    return inverseCumulativeExponential(1.25, Decimal.div(Decimal.pow(points, buyableEffect('p', 13).pow(-1)), 5)).floor()
 }
 function getBetaCost(points = player.p.points) {
-    return getBetaLevel(points).pow_base(1.25).mul(25).sub(20)
+    return cumulativeExponential(1.25, getBetaLevel(points)).mul(5).pow(buyableEffect('p', 13))
 }
 function getBetaEffect(points = player.p.points) {
-    return getBetaLevel(points).mul(getBetaRankEffect(points).add(0.05)).add(1)
+    return getBetaLevel(points).mul(getBetaRankEffect(points).add(1/20)).add(1)
 }
 function getGammaLevel(points = player.p.points) {
     if (Decimal.eq(points, 0)) return new Decimal(0)
-    return Decimal.add(points, 30).div(45).log(1.5).add(1).floor().max(0)
+    return inverseCumulativeExponential(1.5, Decimal.div(Decimal.pow(points, buyableEffect('p', 13).pow(-1)), 15)).floor()
 }
 function getGammaCost(points = player.p.points) {
-    return getGammaLevel(points).pow_base(1.5).mul(45).sub(30)
+    return cumulativeExponential(1.5, getGammaLevel(points)).mul(15).pow(buyableEffect('p', 13))
 }
 function getGammaEffect(points = player.p.points) {
-    return Decimal.add(player.p.points, 100).log(100)
-        .pow(getGammaLevel(points).mul(getGammaRankEffect(points).add(0.05)).add(1))
+    return Decimal.add(player.p.points, 1).log(Decimal.pow(50, buyableEffect('p', 12))).add(1).pow(
+        getGammaLevel(points).mul(getGammaRankEffect(points).add(1/10))
+    )
 }
 function getDeltaLevel(points = player.p.points) {
     if (Decimal.eq(points, 0)) return new Decimal(0)
-    return Decimal.add(points, 30).div(60).log(2).add(1).floor().max(0)
+    return inverseCumulativeExponential(2, Decimal.div(Decimal.pow(points, buyableEffect('p', 13).pow(-1)), 30)).floor()
 }
 function getDeltaCost(points = player.p.points) {
-    return getDeltaLevel(points).pow_base(2).mul(60).sub(30)
+    return cumulativeExponential(2, getDeltaLevel(points)).mul(30).pow(buyableEffect('p', 13))
 }
 function getDeltaEffect(points = player.p.points) {
-    return getDeltaLevel(points).mul(getDeltaRankEffect(points).add(0.2)).add(1)
+    return getDeltaLevel(points).mul(getDeltaRankEffect(points).add(1/5)).add(1)
 }
 function getEpsilonLevel(points = player.p.points) {
     if (Decimal.eq(points, 0)) return new Decimal(0)
-    return Decimal.mul(points, 3).add(100).div(250).log(2.5).add(1).floor().max(0)
+    return inverseCumulativeExponential(2.5, Decimal.div(Decimal.pow(points, buyableEffect('p', 13).pow(-1)), 50)).floor()
 }
 function getEpsilonCost(points = player.p.points) {
-    return getEpsilonLevel(points).pow_base(2.5).mul(250).sub(100).div(3)
+    return cumulativeExponential(2.5, getEpsilonLevel(points)).mul(50).pow(buyableEffect('p', 13))
 }
 function getEpsilonEffect(points = player.p.points) {
-    return getEpsilonLevel(points).mul(getEpsilonRankEffect(points).add(0.1)).add(1)
+    return getEpsilonLevel(points).mul(getEpsilonRankEffect(points).add(1/10)).add(1)
+}
+function getZetaLevel(points = player.p.points) {
+    if (Decimal.eq(points, 0)) return new Decimal(0)
+    return inverseCumulativeExponential(3, Decimal.div(Decimal.pow(points, buyableEffect('p', 13).pow(-1)), 80)).floor()
+}
+function getZetaCost(points = player.p.points) {
+    return cumulativeExponential(3, getZetaLevel(points)).mul(80).pow(buyableEffect('p', 13))
+}
+function getZetaEffect(points = player.p.points) {
+    return getZetaLevel(points).mul(getZetaRankEffect().add(1/3)).add(1)
 }
 
 function getTotalLevel() {
     return getAlphaLevel().add(getBetaLevel()).add(getGammaLevel()).add(getDeltaLevel()).add(getEpsilonLevel())
+        .add(getZetaLevel())
 }
\ No newline at end of file
diff --git a/js/mod.js b/js/mod.js
index 584ac8c..56a9a47 100644
--- a/js/mod.js
+++ b/js/mod.js
@@ -13,18 +13,19 @@ let modInfo = {
 
 // Set your version in num and name
 let VERSION = {
-	num: "0/a1",
-	name: "You guys wanted it.",
+	num: "1",
+	name: "The first release.",
 }
 
 let changelog = `<h1>Changelog:</h1><br><br>
-	<h3>v0/a1</h3><br>
+	<h3>v1</h3><br>
 		- Added progress points.<br>
-		- Added bars Alpha to Epsilon.<br>
+		- Added bars Alpha to Zeta.<br>
 		- Added Ranks.<br>
+		- Added Buyables.<br>
 		- Endgame: 500 Progress Points.<br>`
 
-let winText = `Download 100% complete.<br><br>You won! Congratulations!<br>Beyond this point may be unbalanced, proceed with caution!`
+let winText = `Download 100% complete.<br><br>You won! Congratulations!<br>Beyond this point may be unbalanced / incomplete, proceed with caution!`
 
 // If you add new functions anywhere inside of a layer, and those functions have an effect when called, add them here.
 // (The ones here are examples, all official functions are already taken care of)
@@ -47,7 +48,9 @@ function getPointGen() {
 		.mul(getBetaEffect())
 		.mul(getGammaEffect())
 		.mul(getDeltaEffect())
+		.mul(getZetaEffect())
 		.pow(getEpsilonEffect())
+	gain = softcap(gain, 1000, d => d.add(1).log(1.2).add(1))
 	return gain
 }
 
@@ -61,7 +64,7 @@ var displayThings = [
 
 // Determines when the game "ends"
 function isEndgame() {
-	return player.p.points.gte(500)
+	return getTotalRank().gte(25)
 }
 
 
diff --git a/js/progress.js b/js/progress.js
index 0131942..01a9cf7 100644
--- a/js/progress.js
+++ b/js/progress.js
@@ -42,7 +42,7 @@ addLayer("p", {
             progress() { return getAlphaLevel().div(getAlphaRankCost()) },
             display() {
                 return "Alpha - Rank " + getAlphaRank() + " (" + getAlphaLevel() + "/" + getAlphaRankCost()
-                    + ")<br>Effect: +" + getAlphaRankEffect() + " to Alpha effect."
+                    + ")<br>Effect: +" + getAlphaRankEffect() + " to Alpha effect base."
             },
             fillStyle: {backgroundColor: "#0c6949"},
         },
@@ -65,7 +65,7 @@ addLayer("p", {
             progress() { return getBetaLevel().div(getBetaRankCost()) },
             display() {
                 return "Beta - Rank " + getBetaRank() + " (" + getBetaLevel() + "/" + getBetaRankCost()
-                    + ")<br>Effect: +" + getBetaRankEffect() + " to Beta effect."
+                    + ")<br>Effect: +" + getBetaRankEffect() + " to Beta effect base."
             },
             fillStyle: {backgroundColor: "#0c6949"},
             unlocked() { return getAlphaLevel().gte(1) }
@@ -113,7 +113,7 @@ addLayer("p", {
             progress() { return getDeltaLevel().div(getDeltaRankCost()) },
             display() {
                 return "Delta - Rank " + getDeltaRank() + " (" + getDeltaLevel() + "/" + getDeltaRankCost()
-                    + ")<br>Effect: +" + getDeltaRankEffect() + " to Delta effect."
+                    + ")<br>Effect: +" + getDeltaRankEffect() + " to Delta effect base."
             },
             fillStyle: {backgroundColor: "#0c6949"},
             unlocked() { return getGammaLevel().gte(1) }
@@ -137,17 +137,41 @@ addLayer("p", {
             progress() { return getEpsilonLevel().div(getEpsilonRankCost()) },
             display() {
                 return "Epsilon - Rank " + getEpsilonRank() + " (" + getEpsilonLevel() + "/" + getEpsilonRankCost()
-                    + ")<br>Effect: +" + getEpsilonRankEffect() + " to Epsilon effect."
+                    + ")<br>Effect: +" + getEpsilonRankEffect() + " to Epsilon effect base."
             },
             fillStyle: {backgroundColor: "#0c6949"},
             unlocked() { return getDeltaLevel().gte(1) }
         },
+        zeta: {
+            direction: RIGHT,
+            width: 300,
+            height: 50,
+            progress() { return player[this.layer].points.div(getZetaCost()) },
+            display() {
+                return "Zeta - Level " + getZetaLevel() + " (" + player[this.layer].points + "/" + getZetaCost()
+                    + ")<br>Effect: x" + getZetaEffect() + " to point gen."
+            },
+            fillStyle: {backgroundColor: "#0c6949"},
+            unlocked() { return getEpsilonLevel().gte(1) }
+        },
+        zetaRank: {
+            direction: RIGHT,
+            width: 300,
+            height: 50,
+            progress() { return getZetaLevel().div(getZetaRankCost()) },
+            display() {
+                return "Zeta - Rank " + getZetaRank() + " (" + getZetaLevel() + "/" + getZetaRankCost()
+                    + ")<br>Effect: +" + getZetaRankEffect() + " to Zeta effect base."
+            },
+            fillStyle: {backgroundColor: "#0c6949"},
+            unlocked() { return getEpsilonLevel().gte(1) }
+        },
     },
     buyables: {
         11: {
             title: "More progress",
-            effect() { return Decimal.pow(1.25, getBuyableAmount(this.layer, this.id)) },
-            cost() { return Decimal.mul(getBuyableAmount(this.layer, this.id), 5).add(50) },
+            effect() { return Decimal.pow(1.1, getBuyableAmount(this.layer, this.id)) },
+            cost() { return Decimal.pow(getBuyableAmount(this.layer, this.id), 1.2).mul(5).add(50) },
             display() {
                 return "Increase progress point gain.<br><br>Amount: " + getBuyableAmount(this.layer, this.id)
                     + ".<br>Effect: " + this.effect(getBuyableAmount(this.layer, this.id)) + "x.<br>Cost: "
@@ -155,6 +179,30 @@ addLayer("p", {
             },
             canAfford() { return Decimal.gte(getTotalLevel(), this.cost()) },
             buy() { addBuyables(this.layer, this.id, 1) }
+        },
+        12: {
+            title: "Rebased",
+            effect() { return Decimal.pow(0.95, getBuyableAmount(this.layer, this.id)) },
+            cost() { return Decimal.pow(getBuyableAmount(this.layer, this.id), 1.4).mul(10).add(80) },
+            display() {
+                return "Decrease Gamma effect base.<br><br>Amount: " + getBuyableAmount(this.layer, this.id)
+                    + ".<br>Effect: ^" + this.effect(getBuyableAmount(this.layer, this.id)) + ".<br>Cost: "
+                    + this.cost(getBuyableAmount(this.layer, this.id)) + " total levels."
+            },
+            canAfford() { return Decimal.gte(getTotalLevel(), this.cost()) },
+            buy() { addBuyables(this.layer, this.id, 1) }
+        },
+        13: {
+            title: "Shorter bars",
+            effect() { return Decimal.pow(0.98, getBuyableAmount(this.layer, this.id)) },
+            cost() { return Decimal.pow(getBuyableAmount(this.layer, this.id), 1.6).mul(15).add(130) },
+            display() {
+                return "Decrease all level costs.<br><br>Amount: " + getBuyableAmount(this.layer, this.id)
+                    + ".<br>Effect: ^" + this.effect(getBuyableAmount(this.layer, this.id)) + ".<br>Cost: "
+                    + this.cost(getBuyableAmount(this.layer, this.id)) + " total levels."
+            },
+            canAfford() { return Decimal.gte(getTotalLevel(), this.cost()) },
+            buy() { addBuyables(this.layer, this.id, 1) }
         }
     },
     tabFormat: {
@@ -171,7 +219,8 @@ addLayer("p", {
                 ["bar", "beta"],
                 ["bar", "gamma"],
                 ["bar", "delta"],
-                ["bar", "epsilon"]
+                ["bar", "epsilon"],
+                ["bar", "zeta"]
             ]
         },
         ranks: {
@@ -187,7 +236,8 @@ addLayer("p", {
                 ["bar", "betaRank"],
                 ["bar", "gammaRank"],
                 ["bar", "deltaRank"],
-                ["bar", "epsilonRank"]
+                ["bar", "epsilonRank"],
+                ["bar", "zetaRank"]
             ],
             unlocked() { return getAlphaLevel().gte(18) }
         },
diff --git a/js/ranks.js b/js/ranks.js
index ff022a9..85b9089 100644
--- a/js/ranks.js
+++ b/js/ranks.js
@@ -10,45 +10,54 @@ function getAlphaRankEffect(points = player.p.points) {
 }
 function getBetaRank(points = player.p.points) {
     if (Decimal.eq(points, 0)) return new Decimal(0)
-    return getBetaLevel(points).div(17.5).floor()
+    return getBetaLevel(points).div(15).floor()
 }
 function getBetaRankCost(points = player.p.points) {
-    return getBetaRank(points).add(1).mul(17.5)
+    return getBetaRank(points).add(1).mul(15)
 }
 function getBetaRankEffect(points = player.p.points) {
     return getBetaRank(points).div(100).mul(3)
 }
 function getGammaRank(points = player.p.points) {
     if (Decimal.eq(points, 0)) return new Decimal(0)
-    return getGammaLevel(points).div(15).floor()
+    return getGammaLevel(points).div(12).floor()
 }
 function getGammaRankCost(points = player.p.points) {
-    return getGammaRank(points).add(1).mul(15)
+    return getGammaRank(points).add(1).mul(12)
 }
 function getGammaRankEffect(points = player.p.points) {
-    return getGammaRank(points).div(50)
+    return getGammaRank(points).div(15)
 }
 function getDeltaRank(points = player.p.points) {
     if (Decimal.eq(points, 0)) return new Decimal(0)
-    return getDeltaLevel(points).div(12.5).floor()
+    return getDeltaLevel(points).div(10).floor()
 }
 function getDeltaRankCost(points = player.p.points) {
-    return getDeltaRank(points).add(1).mul(12.5)
+    return getDeltaRank(points).add(1).mul(10)
 }
 function getDeltaRankEffect(points = player.p.points) {
     return getDeltaRank(points).div(20)
 }
 function getEpsilonRank(points = player.p.points) {
     if (Decimal.eq(points, 0)) return new Decimal(0)
-    return getEpsilonLevel(points).div(10).floor()
+    return getEpsilonLevel(points).div(8).floor()
 }
 function getEpsilonRankCost(points = player.p.points) {
-    return getEpsilonRank(points).add(1).mul(10)
+    return getEpsilonRank(points).add(1).mul(8)
 }
 function getEpsilonRankEffect(points = player.p.points) {
-    return getEpsilonRank(points).div(100).mul(12)
+    return getEpsilonRank(points).div(10)
+}
+function getZetaRank(points = player.p.points) {
+    if (Decimal.eq(points, 0)) return new Decimal(0)
+    return getZetaLevel(points).div(8).floor()
+}
+function getZetaRankCost(points = player.p.points) {
+    return getZetaRank(points).add(1).mul(7)
+}
+function getZetaRankEffect(points = player.p.points) {
+    return getZetaRank(points).div(5)
 }
-
 function getTotalRank() {
-    return getAlphaRank().add(getBetaRank()).add(getGammaRank()).add(getDeltaRank()).add(getEpsilonRank())
+    return getAlphaRank().add(getBetaRank()).add(getGammaRank()).add(getDeltaRank()).add(getEpsilonRank()).add(getZetaRank())
 }
\ No newline at end of file
diff --git a/js/utils.js b/js/utils.js
index f56ca9c..5f64e60 100644
--- a/js/utils.js
+++ b/js/utils.js
@@ -409,4 +409,10 @@ function gridRun(layer, func, data, id) {
 	}
 	else
 		return layers[layer].grid[func];
+}
+
+// Small functions
+function softcap(number, after, method) {
+	if (Decimal.lt(number, after)) { return new Decimal(number) }
+	else { return method(Decimal.sub(number, after)).add(after) }
 }
\ No newline at end of file