diff --git a/js/files.js b/js/files.js
new file mode 100644
index 0000000..9f9d7e9
--- /dev/null
+++ b/js/files.js
@@ -0,0 +1,59 @@
+addLayer("f", {
+    name: "files", // This is optional, only used in a few places, If absent it just uses the layer id.
+    symbol: "🗎", // This appears on the layer's node. Default is the id with the first letter capitalized
+    position: 1, // Horizontal position within a row. By default it uses the layer id and sorts in alphabetical order
+    startData() { return {
+        unlocked: false,
+		points: new Decimal(0),
+		total: new Decimal(0)
+    }},
+    color: "#7f1bae",
+    requires: new Decimal(20000), // Can be a function that takes requirement increases into account
+    resource: "files", // Name of prestige currency
+    baseResource: "progress points", // Name of resource prestige is based on
+    baseAmount() {return player.p.points}, // Get the current amount of baseResource
+    type: "normal", // normal: cost to gain currency depends on amount gained. static: cost depends on how much you already have
+    exponent: 0.2, // Prestige currency exponent
+    gainMult() { // Calculate the multiplier for main currency from bonuses
+        return new Decimal(1)
+    },
+    gainExp() { // Calculate the exponent on main currency from bonuses
+        return new Decimal(1)
+    },
+    row: 1, // Row the layer is in on the tree (0 is the first row)
+    displayRow: 0,
+    hotkeys: [
+        {key: "f", description: "F: Reset for files", onPress(){if (canReset(this.layer)) doReset(this.layer)}},
+    ],
+    milestones: {
+        0: {
+            requirementDescription: "1 total File.",
+            effectDescription() {
+                return "Total levels boost point gen.<br>Effect: x" + getTotalLevel().add(1).log(5).add(1) + "."
+            },
+            done() { return player.f.total.gte(1) }
+        },
+        1: {
+            requirementDescription: "2 total Files.",
+            effectDescription: "Triple point gen.",
+            done() { return player.f.total.gte(2) }
+        },
+        2: {
+            requirementDescription: "3 total Files.",
+            effectDescription: "Multiply PP requirement by 0.9x.",
+            done() { return player.f.total.gte(3) }
+        },
+        3: {
+            requirementDescription: "4 total Files.",
+            effectDescription: "Square point gen. if over 1/s.",
+            done() { return player.f.total.gte(4) }
+        },
+        4: {
+            requirementDescription: "5 total Files.",
+            effectDescription: "Total ranks boost point gen.<br>Effect: ^" + getTotalRank().div(2).add(1) + ".",
+            done() { return player.f.total.gte(5) }
+        },
+    },
+    layerShown(){ return player.p.points.gte(15000) || player[this.layer].unlocked },
+    branches: ['p']
+})
diff --git a/js/levels.js b/js/levels.js
index 756d6b0..652fab9 100644
--- a/js/levels.js
+++ b/js/levels.js
@@ -5,66 +5,67 @@ function inverseCumulativeExponential(base, levels) {
     return Decimal.sub(base, 1).mul(levels).add(1).log(base)
 }
 
-function getAlphaLevel(points = player.p.points) {
+function getAlphaLevel(points = null) {
+    if (points === null && player === null) return new Decimal(0)
     if (Decimal.eq(points, 0)) return new Decimal(0)
     return inverseCumulativeExponential(1.1, Decimal.pow(points, buyableEffect('p', 13).pow(-1))).floor()
 }
-function getAlphaCost(points = player.p.points) {
+function getAlphaCost(points = null) {
     return cumulativeExponential(1.1, getAlphaLevel(points)).pow(buyableEffect('p', 13))
 }
-function getAlphaEffect(points = player.p.points) {
+function getAlphaEffect(points = null) {
     return getAlphaLevel(points).mul(getAlphaRankEffect(points).add(1/20))
 }
-function getBetaLevel(points = player.p.points) {
+function getBetaLevel(points = null) {
     if (Decimal.eq(points, 0)) return new Decimal(0)
     return inverseCumulativeExponential(1.25, Decimal.div(Decimal.pow(points, buyableEffect('p', 13).pow(-1)), 5)).floor()
 }
-function getBetaCost(points = player.p.points) {
+function getBetaCost(points = null) {
     return cumulativeExponential(1.25, getBetaLevel(points)).mul(5).pow(buyableEffect('p', 13))
 }
-function getBetaEffect(points = player.p.points) {
+function getBetaEffect(points = null) {
     return getBetaLevel(points).mul(getBetaRankEffect(points).add(1/20)).add(1)
 }
-function getGammaLevel(points = player.p.points) {
+function getGammaLevel(points = null) {
     if (Decimal.eq(points, 0)) return new Decimal(0)
     return inverseCumulativeExponential(1.5, Decimal.div(Decimal.pow(points, buyableEffect('p', 13).pow(-1)), 15)).floor()
 }
-function getGammaCost(points = player.p.points) {
+function getGammaCost(points = null) {
     return cumulativeExponential(1.5, getGammaLevel(points)).mul(15).pow(buyableEffect('p', 13))
 }
-function getGammaEffect(points = player.p.points) {
-    return Decimal.add(player.p.points, 1).log(Decimal.pow(50, buyableEffect('p', 12))).add(1).pow(
+function getGammaEffect(points = null) {
+    return Decimal.add(null, 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) {
+function getDeltaLevel(points = null) {
     if (Decimal.eq(points, 0)) return new Decimal(0)
     return inverseCumulativeExponential(2, Decimal.div(Decimal.pow(points, buyableEffect('p', 13).pow(-1)), 30)).floor()
 }
-function getDeltaCost(points = player.p.points) {
+function getDeltaCost(points = null) {
     return cumulativeExponential(2, getDeltaLevel(points)).mul(30).pow(buyableEffect('p', 13))
 }
-function getDeltaEffect(points = player.p.points) {
+function getDeltaEffect(points = null) {
     return getDeltaLevel(points).mul(getDeltaRankEffect(points).add(1/5)).add(1)
 }
-function getEpsilonLevel(points = player.p.points) {
+function getEpsilonLevel(points = null) {
     if (Decimal.eq(points, 0)) return new Decimal(0)
     return inverseCumulativeExponential(2.5, Decimal.div(Decimal.pow(points, buyableEffect('p', 13).pow(-1)), 50)).floor()
 }
-function getEpsilonCost(points = player.p.points) {
+function getEpsilonCost(points = null) {
     return cumulativeExponential(2.5, getEpsilonLevel(points)).mul(50).pow(buyableEffect('p', 13))
 }
-function getEpsilonEffect(points = player.p.points) {
+function getEpsilonEffect(points = null) {
     return getEpsilonLevel(points).mul(getEpsilonRankEffect(points).add(1/10)).add(1)
 }
-function getZetaLevel(points = player.p.points) {
+function getZetaLevel(points = null) {
     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) {
+function getZetaCost(points = null) {
     return cumulativeExponential(3, getZetaLevel(points)).mul(80).pow(buyableEffect('p', 13))
 }
-function getZetaEffect(points = player.p.points) {
+function getZetaEffect(points = null) {
     return getZetaLevel(points).mul(getZetaRankEffect().add(1/3)).add(1)
 }
 
diff --git a/js/mod.js b/js/mod.js
index 56a9a47..395ef71 100644
--- a/js/mod.js
+++ b/js/mod.js
@@ -3,7 +3,7 @@ let modInfo = {
 	id: "nif/pbic",
 	author: "Nif",
 	pointsName: "points",
-	modFiles: ["ranks.js", "levels.js", "progress.js", "tree.js"],
+	modFiles: ["ranks.js", "levels.js", "progress.js", "files.js", "tree.js"],
 
 	discordName: "",
 	discordLink: "",
@@ -23,7 +23,9 @@ let changelog = `<h1>Changelog:</h1><br><br>
 		- Added bars Alpha to Zeta.<br>
 		- Added Ranks.<br>
 		- Added Buyables.<br>
-		- Endgame: 500 Progress Points.<br>`
+		- Added Files.<br>
+		- Added 5 File milestones.<br>
+		- Endgame: 6 Files.<br>`
 
 let winText = `Download 100% complete.<br><br>You won! Congratulations!<br>Beyond this point may be unbalanced / incomplete, proceed with caution!`
 
@@ -43,14 +45,21 @@ function canGenPoints(){
 // Calculate points/sec!
 function getPointGen() {
 	if(!canGenPoints()) return new Decimal(0)
-
+	// additive
 	let gain = getAlphaEffect()
-		.mul(getBetaEffect())
-		.mul(getGammaEffect())
-		.mul(getDeltaEffect())
-		.mul(getZetaEffect())
-		.pow(getEpsilonEffect())
-	gain = softcap(gain, 1000, d => d.add(1).log(1.2).add(1))
+	// multiplicative
+	gain = gain.mul(getBetaEffect())
+	gain = gain.mul(getGammaEffect())
+	gain = gain.mul(getDeltaEffect())
+	gain = gain.mul(getZetaEffect())
+	if (hasMilestone('f', 0)) gain = gain.mul(getTotalLevel().add(1).log(5).add(1))
+	if (hasMilestone('f', 1)) gain = gain.mul(3)
+	if (hasMilestone('f', 3) && gain.gte(1)) gain = gain.pow(2)
+	// exponentiative
+	gain = gain.pow(getEpsilonEffect())
+	if (hasMilestone('f', 4)) gain = gain.pow(getTotalRank().div(2).add(1))
+	// softcaps
+	gain = softcap(gain, 1000, d => d.add(1).log(2))
 	return gain
 }
 
@@ -64,7 +73,7 @@ var displayThings = [
 
 // Determines when the game "ends"
 function isEndgame() {
-	return getTotalRank().gte(25)
+	return player.f.points.gte(6)
 }
 
 
diff --git a/js/progress.js b/js/progress.js
index 01a9cf7..13f0f9c 100644
--- a/js/progress.js
+++ b/js/progress.js
@@ -7,7 +7,11 @@ addLayer("p", {
 		points: new Decimal(0)
     }},
     color: "#0c6949",
-    requires: new Decimal(1), // Can be a function that takes requirement increases into account
+    requires() {
+        let req = new Decimal(1)
+        if (hasMilestone('f', 2)) { req = req.mul(0.9) }
+        return req
+    }, // Can be a function that takes requirement increases into account
     resource: "progress points", // Name of prestige currency
     baseResource: "points", // Name of resource prestige is based on
     baseAmount() {return player.points}, // Get the current amount of baseResource
diff --git a/js/ranks.js b/js/ranks.js
index 85b9089..1257e2f 100644
--- a/js/ranks.js
+++ b/js/ranks.js
@@ -50,7 +50,7 @@ function getEpsilonRankEffect(points = player.p.points) {
 }
 function getZetaRank(points = player.p.points) {
     if (Decimal.eq(points, 0)) return new Decimal(0)
-    return getZetaLevel(points).div(8).floor()
+    return getZetaLevel(points).div(7).floor()
 }
 function getZetaRankCost(points = player.p.points) {
     return getZetaRank(points).add(1).mul(7)
@@ -58,6 +58,7 @@ function getZetaRankCost(points = player.p.points) {
 function getZetaRankEffect(points = player.p.points) {
     return getZetaRank(points).div(5)
 }
+
 function getTotalRank() {
     return getAlphaRank().add(getBetaRank()).add(getGammaRank()).add(getDeltaRank()).add(getEpsilonRank()).add(getZetaRank())
 }
\ No newline at end of file