diff --git a/js/Demo/demoMod.js b/js/Demo/demoMod.js
deleted file mode 100644
index ee3c3ee..0000000
--- a/js/Demo/demoMod.js
+++ /dev/null
@@ -1,83 +0,0 @@
-let modInfo = {
-	name: "The Modding Tree",
-	id: "modbase",
-	pointsName: "points",
-	modFiles: ["Demo/layers/c.js", "Demo/layers/f.js", "Demo/layers/a.js", "Demo/demoTree.js"],
-
-
-	discordName: "",
-	discordLink: "",
-	initialStartPoints: new Decimal (10), // Used for hard resets and new players
-	offlineLimit: 1,  // In hours
-}
-
-// Set your version in num and name
-let VERSION = {
-	num: "2.6.6",
-	name: "Fixed Reality",
-}
-
-let changelog = `<h1>Changelog:</h1><br>
-	<h3>v0.0</h3><br>
-		- Added things.<br>
-		- Added stuff.`
-
-let winText = `Congratulations! You have reached the end and beaten this game, but for now...`
-// 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)
-var doNotCallTheseFunctionsEveryTick = ["doReset", "buy", "onPurchase", "blowUpEverything"]
-
-function getStartPoints(){
-    return new Decimal(modInfo.initialStartPoints)
-}
-
-// Determines if it should show points/sec
-function canGenPoints(){
-	return hasUpgrade("c", 11)
-}
-
-// Calculate points/sec!
-function getPointGen() {
-	if(!canGenPoints())
-		return new Decimal(0)
-
-	let gain = new Decimal(1)
-	if (hasUpgrade("c", 12)) gain = gain.times(upgradeEffect("c", 12))
-	return gain
-}
-
-// You can add non-layer related variables that should to into "player" and be saved here, along with default values
-function addedPlayerData() { return {
-	weather: "Yes",
-	happiness: new Decimal(72),
-}}
-
-// Display extra things at the top of the page
-var displayThings = [
-	function() {if (player.points.eq(69)) return "Tee hee!"},
-	function() {if (player.f.points.gt(1)) return `You have ${player.f.points} farm points. (Which do nothing.)`},
-	function() {if (inChallenge("c", 11)) return "The game is currently <h1>0%</h1> harder."},
-]
-
-// Determines when the game "ends"
-function isEndgame() {
-	return player.points.gte(new Decimal("11"))
-}
-
-
-
-// Less important things beyond this point!
-
-// Style for the background, can be a function
-var backgroundStyle = {
-}
-
-// You can change this if you have things that can be messed up by long tick lengths
-function maxTickLength() {
-	return(3600) // Default is 1 hour which is just arbitrarily large
-}
-
-// Use this if you need to undo inflation from an older version. If the version is older than the version that fixed the issue,
-// you can cap their current resources with this.
-function fixOldSave(oldVersion){
-}
diff --git a/js/Demo/demoTree.js b/js/Demo/demoTree.js
deleted file mode 100644
index c60cfe0..0000000
--- a/js/Demo/demoTree.js
+++ /dev/null
@@ -1,55 +0,0 @@
-// treeLayout will override the default tree's layout if used
-var layoutInfo = {
-    startTab: "c",
-    startNavTab: "tree-tab",
-
-	showTree: true,
-
-    //treeLayout: ""
-
-    
-}
-
-// A "ghost" layer which offsets f in the tree
-addNode("spook", {
-    row: 1,
-    layerShown: "ghost",
-}, 
-)
-
-
-// A "ghost" layer which offsets f in the tree
-addNode("g", {
-    symbol: "TH",
-    branches: [["c", "red", 4]],
-    color: '#6d3678',
-    layerShown: true,
-    canClick() {return player.points.gte(10)},
-    tooltip: "Thanos your points",
-    tooltipLocked: "Thanos your points",
-    onClick() {player.points = player.points.div(2)
-    console.log(this.layer)}
-
-}, 
-)
-
-
-// A "ghost" layer which offsets f in the tree
-addNode("h", {
-    branches: ["g"],
-    layerShown: true,
-    tooltip() {return "Restore your points to " + player.c.otherThingy},
-    tooltipLocked() {return "Restore your points to " + player.c.otherThingy},
-    row: "side",
-    canClick() {return player.points.lt(player.c.otherThingy)},
-    onClick() {player.points = new Decimal(player.c.otherThingy)}
-}, 
-)
-
-addLayer("tree-tab", {
-    tabFormat: [["tree", function() {return (layoutInfo.treeLayout ? layoutInfo.treeLayout : TREE_LAYERS)}]],
-    previousTab: "",
-    leftTab: true,
-                style() {return  {'background-color': '#222222'}},
-
-})
\ No newline at end of file
diff --git a/js/Demo/layers/a.js b/js/Demo/layers/a.js
deleted file mode 100644
index 6e391c9..0000000
--- a/js/Demo/layers/a.js
+++ /dev/null
@@ -1,65 +0,0 @@
-
-// A side layer with achievements, with no prestige
-addLayer("a", {
-    startData() { return {
-        unlocked: true,
-        points: new Decimal(0),
-    }},
-    color: "yellow",
-    resource: "achievement power", 
-    row: "side",
-    tooltip() { // Optional, tooltip displays when the layer is locked
-        return ("Achievements")
-    },
-    achievementPopups: true,
-    achievements: {
-        11: {
-            image: "discord.png",
-            name: "Get me!",
-            done() {return true}, // This one is a freebie
-            goalTooltip: "How did this happen?", // Shows when achievement is not completed
-            doneTooltip: "You did it!", // Showed when the achievement is completed
-        },
-        12: {
-            name: "Impossible!",
-            done() {return false},
-            goalTooltip: "Mwahahaha!", // Shows when achievement is not completed
-            doneTooltip: "HOW????", // Showed when the achievement is completed
-            textStyle: {'color': '#04e050'},
-        },
-        13: {
-            name: "EIEIO",
-            done() {return player.f.points.gte(1)},
-            tooltip: "Get a farm point.\n\nReward: The dinosaur is now your friend (you can max Farm Points).", // Showed when the achievement is completed
-            onComplete() {console.log("Bork bork bork!")}
-        },
-    },
-    midsection: ["grid", "blank"],
-    grid: {
-        maxRows: 3,
-        rows: 2,
-        cols: 2,
-        getStartData(id) {
-            return id
-        },
-        getUnlocked(id) { // Default
-            return true
-        },
-        getCanClick(data, id) {
-            return player.points.eq(10)
-        },
-        getStyle(data, id) {
-            return {'background-color': '#'+ (data*1234%999999)}
-        },
-        onClick(data, id) { // Don't forget onHold
-            player[this.layer].grid[id]++
-        },
-        getTitle(data, id) {
-            return "Gridable #" + id
-        },
-        getDisplay(data, id) {
-            return data
-        },
-    },
-},
-)
\ No newline at end of file
diff --git a/js/Demo/layers/c.js b/js/Demo/layers/c.js
deleted file mode 100644
index 5ab4685..0000000
--- a/js/Demo/layers/c.js
+++ /dev/null
@@ -1,396 +0,0 @@
-var testTree = [["f", "c"],
-["g", "spook", "h"]]
-
-addLayer("c", {
-        layer: "c", // This is assigned automatically, both to the layer and all upgrades, etc. Shown here so you know about it
-        name: "Candies", // This is optional, only used in a few places, If absent it just uses the layer id.
-        symbol: "C", // This appears on the layer's node. Default is the id with the first letter capitalized
-        position: 0, // Horizontal position within a row. By default it uses the layer id and sorts in alphabetical order
-        startData() { return {
-            unlocked: true,
-			points: new Decimal(0),
-            best: new Decimal(0),
-            total: new Decimal(0),
-            buyables: {}, // You don't actually have to initialize this one
-            beep: false,
-            thingy: "pointy",
-            otherThingy: 10,
-            drop: "drip",
-        }},
-        color: "#4BDC13",
-        requires: new Decimal(10), // Can be a function that takes requirement increases into account
-        resource: "lollipops", // Name of prestige currency
-        baseResource: "points", // Name of resource prestige is based on
-        baseAmount() {return player.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.5, // Prestige currency exponent
-        base: 5, // Only needed for static layers, base of the formula (b^(x^exp))
-        roundUpCost: false, // True if the cost needs to be rounded up (use when baseResource is static?)
-
-        // For normal layers, gain beyond [softcap] points is put to the [softcapPower]th power
-        softcap: new Decimal(1e100), 
-        softcapPower: new Decimal(0.5), 
-        canBuyMax() {}, // Only needed for static layers with buy max
-        gainMult() { // Calculate the multiplier for main currency from bonuses
-            mult = new Decimal(1)
-            if (hasUpgrade(this.layer, 166)) mult = mult.times(2) // These upgrades don't exist
-			if (hasUpgrade(this.layer, 120)) mult = mult.times(upgradeEffect(this.layer, 120))
-            return mult
-        },
-        gainExp() { // Calculate the exponent on main currency from bonuses
-            return new Decimal(1)
-        },
-        row: 0, // Row the layer is in on the tree (0 is the first row)
-        effect() {
-            return { // Formulas for any boosts inherent to resources in the layer. Can return a single value instead of an object if there is just one effect
-            waffleBoost: (true == false ? 0 : Decimal.pow(player[this.layer].points, 0.2)),
-            icecreamCap: (player[this.layer].points * 10)
-        }},
-        effectDescription() { // Optional text to describe the effects
-            eff = this.effect();
-            eff.waffleBoost = eff.waffleBoost.times(buyableEffect(this.layer, 11).first)
-            return "which are boosting waffles by "+format(eff.waffleBoost)+" and increasing the Ice Cream cap by "+format(eff.icecreamCap)
-        },
-        infoboxes:{
-            coolInfo: {
-                title: "Lore",
-                titleStyle: {'color': '#FE0000'},
-                body: "DEEP LORE!",
-                bodyStyle: {'background-color': "#0000EE"}
-            }
-        },
-        milestones: {
-            0: {requirementDescription: "3 Lollipops",
-                done() {return player[this.layer].best.gte(3)}, // Used to determine when to give the milestone
-                effectDescription: "Unlock the next milestone",
-            },
-            1: {requirementDescription: "4 Lollipops",
-                unlocked() {return hasMilestone(this.layer, 0)},
-                done() {return player[this.layer].best.gte(4)},
-                effectDescription: "You can toggle beep and boop (which do nothing)",
-                toggles: [
-                    ["c", "beep"], // Each toggle is defined by a layer and the data toggled for that layer
-                    ["f", "boop"]],
-                style() {                     
-                    if(hasMilestone(this.layer, this.id)) return {
-                        'background-color': '#1111DD' 
-                }},
-                },
-        },
-        challenges: {
-
-		    11: {
-                name: "Fun",
-                completionLimit: 3,
-			    challengeDescription() {return "Makes the game 0% harder<br>"+challengeCompletions(this.layer, this.id) + "/" + this.completionLimit + " completions"},
-                unlocked() { return player[this.layer].best.gt(0) },
-                goalDescription: 'Have 20 points I guess',
-                canComplete() {
-                    return player.points.gte(20)
-                },
-                rewardEffect() {
-                    let ret = player[this.layer].points.add(1).tetrate(0.02)
-                    return ret;
-                },
-                rewardDisplay() { return format(this.rewardEffect())+"x" },
-                countsAs: [12, 21], // Use this for if a challenge includes the effects of other challenges. Being in this challenge "counts as" being in these.
-                rewardDescription: "Says hi",
-                onComplete() {console.log("hiii")}, // Called when you successfully complete the challenge
-                onEnter() {console.log("So challenging")},
-                onExit() {console.log("Sweet freedom!")},
-
-            },
-        }, 
-        upgrades: {
-
-            11: {
-                title: "Generator of Genericness",
-                description: "Gain 1 Point every second.",
-                cost: new Decimal(1),
-                unlocked() { return player[this.layer].unlocked }, // The upgrade is only visible when this is true
-                branches: [12],
-                tooltip: "hi",
-            },
-            12: {
-                description: "Point generation is faster based on your unspent Lollipops.",
-                cost: new Decimal(1),
-                unlocked() { return (hasUpgrade(this.layer, 11))},
-                effect() { // Calculate bonuses from the upgrade. Can return a single value or an object with multiple values
-                    let ret = player[this.layer].points.add(1).pow(player[this.layer].upgrades.includes(24)?1.1:(player[this.layer].upgrades.includes(14)?0.75:0.5)) 
-                    if (ret.gte("1e20000000")) ret = ret.sqrt().times("1e10000000")
-                    return ret;
-                },
-                effectDisplay() { return format(this.effect())+"x" }, // Add formatting to the effect
-            },
-            13: {
-                unlocked() { return (hasUpgrade(this.layer, 12))},
-                onPurchase() { // This function triggers when the upgrade is purchased
-                    player[this.layer].unlockOrder = 0
-                },
-                style() {
-                    if (hasUpgrade(this.layer, this.id)) return {
-                    'background-color': '#1111dd' 
-                    }
-                    else if (!canAffordUpgrade(this.layer, this.id)) {
-                        return {
-                            'background-color': '#dd1111' 
-                        }
-                    } // Otherwise use the default
-                },
-                canAfford(){return player.points.lte(7)},
-                pay(){player.points = player.points.add(7)},
-                fullDisplay: "Only buyable with less than 7 points, and gives you 7 more. Unlocks a secret subtab."
-            },
-            22: {
-                title: "This upgrade doesn't exist",
-                description: "Or does it?.",
-                currencyLocation() {return player[this.layer].buyables}, // The object in player data that the currency is contained in
-                currencyDisplayName: "exhancers", // Use if using a nonstandard currency
-                currencyInternalName: 11, // Use if using a nonstandard currency
-
-                cost: new Decimal(3),
-                unlocked() { return player[this.layer].unlocked }, // The upgrade is only visible when this is true
-            },
-        },
-        buyables: {
-            showRespec: true,
-            respec() { // Optional, reset things and give back your currency. Having this function makes a respec button appear
-                player[this.layer].points = player[this.layer].points.add(player[this.layer].spentOnBuyables) // A built-in thing to keep track of this but only keeps a single value
-                resetBuyables(this.layer)
-                doReset(this.layer, true) // Force a reset
-            },
-            respecText: "Respec Thingies", // Text on Respec button, optional
-            respecMessage: "Are you sure? Respeccing these doesn't accomplish much.",
-            11: {
-                title: "Exhancers", // Optional, displayed at the top in a larger font
-                cost(x) { // cost for buying xth buyable, can be an object if there are multiple currencies
-                    if (x.gte(25)) x = x.pow(2).div(25)
-                    let cost = Decimal.pow(2, x.pow(1.5))
-                    return cost.floor()
-                },
-                effect(x) { // Effects of owning x of the items, x is a decimal
-                    let eff = {}
-                    if (x.gte(0)) eff.first = Decimal.pow(25, x.pow(1.1))
-                    else eff.first = Decimal.pow(1/25, x.times(-1).pow(1.1))
-                
-                    if (x.gte(0)) eff.second = x.pow(0.8)
-                    else eff.second = x.times(-1).pow(0.8).times(-1)
-                    return eff;
-                },
-                display() { // Everything else displayed in the buyable button after the title
-                    let data = tmp[this.layer].buyables[this.id]
-                    return "Cost: " + format(data.cost) + " lollipops\n\
-                    Amount: " + player[this.layer].buyables[this.id] + "/4\n\
-                    Adds + " + format(data.effect.first) + " things and multiplies stuff by " + format(data.effect.second)
-                },
-                unlocked() { return player[this.layer].unlocked }, 
-                canAfford() {
-                    return player[this.layer].points.gte(tmp[this.layer].buyables[this.id].cost)},
-                buy() { 
-                    cost = tmp[this.layer].buyables[this.id].cost
-                    player[this.layer].points = player[this.layer].points.sub(cost)	
-                    player[this.layer].buyables[this.id] = player[this.layer].buyables[this.id].add(1)
-                    player[this.layer].spentOnBuyables = player[this.layer].spentOnBuyables.add(cost) // This is a built-in system that you can use for respeccing but it only works with a single Decimal value
-                },
-                buyMax() {}, // You'll have to handle this yourself if you want
-                style: {'height':'222px'},
-                purchaseLimit: new Decimal(4),
-                sellOne() {
-                    let amount = getBuyableAmount(this.layer, this.id)
-                    if (amount.lte(0)) return // Only sell one if there is at least one
-                    setBuyableAmount(this.layer, this.id, amount.sub(1))
-                    player[this.layer].points = player[this.layer].points.add(this.cost)
-                },
-            },
-        },
-        doReset(resettingLayer){ // Triggers when this layer is being reset, along with the layer doing the resetting. Not triggered by lower layers resetting, but is by layers on the same row.
-            if(layers[resettingLayer].row > this.row) layerDataReset(this.layer, ["points"]) 
-        },
-        layerShown() {return true}, // Condition for when layer appears on the tree
-        automate() {
-        }, // Do any automation inherent to this layer if appropriate
-        resetsNothing() {return false},
-        onPrestige(gain) {
-            return
-        }, // Useful for if you gain secondary resources or have other interesting things happen to this layer when you reset it. You gain the currency after this function ends.
-
-        hotkeys: [
-            {key: "c", description: "C: reset for lollipops or whatever", onPress(){if (canReset(this.layer)) doReset(this.layer)}},
-            {key: "ctrl+c", description: "Ctrl+c: respec things", onPress(){respecBuyables(this.layer)}, unlocked() {return hasUpgrade('c', '22')}}  ,
-        ],
-        increaseUnlockOrder: [], // Array of layer names to have their order increased when this one is first unlocked
-
-        microtabs: {
-            stuff: {
-                first: {
-                    content: ["upgrades", ["display-text", function() {return "confirmed<br>" + player.c.drop}], ["drop-down", ["drop", ["drip", "drop"]]]]
-                },
-                second: {
-                    embedLayer: "f",
-
-                    content: [["upgrade", 11],
-                            ["row", [["upgrade", 11], "blank", "blank", ["upgrade", 11],]],
-                        
-                        ["display-text", function() {return "double confirmed"}]]
-                },
-            },
-            otherStuff: {
-                // There could be another set of microtabs here
-            }
-        },
-
-        bars: {
-            longBoi: {
-                fillStyle: {'background-color' : "#FFFFFF"},
-                baseStyle: {'background-color' : "#696969"},
-                textStyle: {'color': '#04e050'},
-                borderStyle() {return {}},
-                direction: RIGHT,
-                width: 300,
-                height: 30,
-                progress() {
-                    return (player.points.add(1).log(10).div(10)).toNumber()
-                },
-                display() {
-                    return format(player.points) + " / 1e10 points"
-                },
-                unlocked: true,
-
-            },
-            tallBoi: {
-                fillStyle: {'background-color' : "#4BEC13"},
-                baseStyle: {'background-color' : "#000000"},
-                textStyle: {'text-shadow': '0px 0px 2px #000000'},
-
-                borderStyle() {return {'border-width': "7px"}},
-                direction: UP,
-                width: 50,
-                height: 200,
-                progress() {
-                    return player.points.div(100)
-                },
-                display() {
-                    return formatWhole((player.points.div(1)).min(100)) + "%"
-                },
-                unlocked: true,
-
-            },
-            flatBoi: {
-                fillStyle: {'background-color' : "#FE0102"},
-                baseStyle: {'background-color' : "#222222"},
-                textStyle: {'text-shadow': '0px 0px 2px #000000'},
-
-                borderStyle() {return {}},
-                direction: UP,
-                width: 100,
-                height: 30,
-                progress() {
-                    return player.c.points.div(50)
-                },
-                unlocked: true,
-
-            },
-        },
-        
-        // Optional, lets you format the tab yourself by listing components. You can create your own components in v.js.
-        tabFormat: {
-            "main tab": {
-                buttonStyle() {return  {'color': 'orange'}},
-                shouldNotify: true,
-                content:
-                    ["main-display",
-                    "prestige-button", "resource-display",
-                    ["blank", "5px"], // Height
-                    ["raw-html", function() {return "<button onclick='console.log(`yeet`); makeParticles(textParticle)'>'HI'</button>"}],
-                    ["display-text", "Name your points!"],
-                    ["text-input", "thingy"],
-                    ["display-text",
-                        function() {return 'I have ' + format(player.points) + ' ' + player[this.layer].thingy + ' points!'},
-                        {"color": "red", "font-size": "32px", "font-family": "Comic Sans MS"}],
-                    "h-line", "milestones", "blank", "upgrades", "challenges"],
-                glowColor: "blue",
-
-            },
-            thingies: {
-                prestigeNotify: true,
-                style() {return  {'background-color': '#222222'}},
-                buttonStyle() {return {'border-color': 'orange'}},
-                content:[ 
-                    "buyables", "blank",
-                    ["row", [
-                        ["toggle", ["c", "beep"]], ["blank", ["30px", "10px"]], // Width, height
-                        ["display-text", function() {return "Beep"}], "blank", ["v-line", "200px"],
-                        ["column", [
-                            ["prestige-button", "", {'width': '150px', 'height': '80px'}],
-                            ["prestige-button", "", {'width': '100px', 'height': '150px'}],
-                        ]], 
-                    ], {'width': '600px', 'height': '350px', 'background-color': 'green', 'border-style': 'solid'}],
-                    "blank",
-                    ["display-image", "discord.png"],],
-            },
-            jail: {
-                style() {return  {'background-color': '#222222'}},
-
-                content: [
-                    ["infobox", "coolInfo"],
-                    ["bar", "longBoi"], "blank",
-                    ["row", [
-                        ["column", [
-                            ["display-text", "Sugar level:", {'color': 'teal'}],  "blank", ["bar", "tallBoi"]],
-                        {'background-color': '#555555', 'padding': '15px'}],
-                        "blank",
-                        ["column", [
-                        ["display-text", "idk"],
-                        ["blank", ['0', '50px']], ["bar", "flatBoi"]
-                        ]],
-                    ]],
-                    "blank", ["display-text", "It's jail because \"bars\"! So funny! Ha ha!"],["tree", testTree], 
-                ],
-            },
-            illuminati: {
-                unlocked() {return (hasUpgrade("c", 13))},
-                content:[
-                    ["raw-html", function() {return "<h1> C O N F I R M E D </h1>"}], "blank",
-                    ["microtabs", "stuff", {'width': '600px', 'height': '350px', 'background-color': 'brown', 'border-style': 'solid'}],
-                    ["display-text", "Adjust how many points H gives you!"],
-                    ["slider", ["otherThingy", 1, 30]], "blank", ["upgrade-tree", [[11], 
-                    [12, 22, 22, 11]]]
-                ]
-            }
-
-        },
-        style() {return {
-           //'background-color': '#3325CC' 
-        }},
-        nodeStyle() {return { // Style on the layer node
-            'color': '#3325CC',
-            'text-decoration': 'underline',
-            'font-family': 'cursive'
-        }},
-        glowColor: "orange", // If the node is highlighted, it will be this color (default is red)
-        componentStyles: {
-            "challenge"() {return {'height': '200px'}},
-            "prestige-button"() {return {'color': '#AA66AA'}},
-        },
-        tooltip() { // Optional, tooltip displays when the layer is unlocked
-            let tooltip = formatWhole(player[this.layer].points) + " " + this.resource
-            if (player[this.layer].buyables[11].gt(0)) tooltip += "<br><i><br><br><br>" + formatWhole(player[this.layer].buyables[11]) + " Exhancers</i>"
-            return tooltip
-        },
-        shouldNotify() { // Optional, layer will be highlighted on the tree if true.
-                         // Layer will automatically highlight if an upgrade is purchasable.
-            return (player.c.buyables[11] == 1)
-        },
-        marked: "discord.png",
-        resetDescription: "Melt your points into ",
-})
-
-const textParticle = {
-    spread: 20,
-    gravity: 0,
-    time: 3,
-    speed: 0,
-    text: function() { return "<h1 style='color:yellow'>" + format(player.points)},
-    offset: 30,
-    fadeInTime: 1,
-}
\ No newline at end of file
diff --git a/js/Demo/layers/f.js b/js/Demo/layers/f.js
deleted file mode 100644
index 7bfce45..0000000
--- a/js/Demo/layers/f.js
+++ /dev/null
@@ -1,147 +0,0 @@
-// This layer is mostly minimal but it uses a custom prestige type and a clickable
-addLayer("f", {
-    infoboxes:{
-        coolInfo: {
-            title: "Lore",
-            titleStyle: {'color': '#FE0000'},
-            body: "DEEP LORE!",
-            bodyStyle: {'background-color': "#0000EE"}
-        }
-    },
-
-    startData() { return {
-        unlocked: false,
-        points: new Decimal(0),
-        boop: false,
-        clickables: {[11]: "Start"}, // Optional default Clickable state
-    }},
-    color: "#FE0102",
-    requires() {return new Decimal(10)}, 
-    resource: "farm points", 
-    baseResource: "points", 
-    baseAmount() {return player.points},
-    type: "static",
-    exponent: 0.5,
-    base: 3,
-    roundUpCost: true,
-    canBuyMax() {return false},
-    //directMult() {return new Decimal(player.c.otherThingy)},
-
-    row: 1,
-    layerShown() {return true}, 
-    branches: ["c"], // When this layer appears, a branch will appear from this layer to any layers here. Each entry can be a pair consisting of a layer id and a color.
-
-    tooltipLocked() { // Optional, tooltip displays when the layer is locked
-        return ("This weird farmer dinosaur will only see you if you have at least " + this.requires() + " points. You only have " + formatWhole(player.points))
-    },
-    midsection: [
-        "blank", ['display-image', 'https://images.beano.com/store/24ab3094eb95e5373bca1ccd6f330d4406db8d1f517fc4170b32e146f80d?auto=compress%2Cformat&dpr=1&w=390'],
-        ["display-text", "Bork bork!"]
-    ],
-    // The following are only currently used for "custom" Prestige type:
-    prestigeButtonText() { //Is secretly HTML
-        if (!this.canBuyMax()) return "Hi! I'm a <u>weird dinosaur</u> and I'll give you a Farm Point in exchange for all of your points and lollipops! (At least " + formatWhole(tmp[this.layer].nextAt) + " points)"
-        if (this.canBuyMax()) return "Hi! I'm a <u>weird dinosaur</u> and I'll give you <b>" + formatWhole(tmp[this.layer].resetGain) + "</b> Farm Points in exchange for all of your points and lollipops! (You'll get another one at " + formatWhole(tmp[this.layer].nextAtDisp) + " points)"
-    },
-    getResetGain() {
-        return getResetGain(this.layer, useType = "static")
-    },
-    getNextAt(canMax=false) { //  
-        return getNextAt(this.layer, canMax, useType = "static")
-    },
-    canReset() {
-        return tmp[this.layer].baseAmount.gte(tmp[this.layer].nextAt)
-    },
-    // This is also non minimal, a Clickable!
-    clickables: {
-
-        masterButtonPress() {
-            if (getClickableState(this.layer, 11) == "Borkened...")
-                player[this.layer].clickables[11] = "Start"
-        },
-        masterButtonText() {return (getClickableState(this.layer, 11) == "Borkened...") ? "Fix the clickable!" : "Does nothing"}, // Text on Respec button, optional
-        11: {
-            title: "Clicky clicky!", // Optional, displayed at the top in a larger font
-            display() { // Everything else displayed in the buyable button after the title
-                let data = getClickableState(this.layer, this.id)
-                return "Current state:<br>" + data
-            },
-            unlocked() { return player[this.layer].unlocked }, 
-            canClick() {
-                return getClickableState(this.layer, this.id) !== "Borkened..."},
-            onClick() { 
-                switch(getClickableState(this.layer, this.id)){
-                    case "Start":
-                        player[this.layer].clickables[this.id] = "A new state!"
-                        break;
-                    case "A new state!":
-                        player[this.layer].clickables[this.id] = "Keep going!"
-                        break;
-                    case "Keep going!":
-                        player[this.layer].clickables[this.id] = "Maybe that's a bit too far..."
-                        break;                        
-                    case "Maybe that's a bit too far...":
-                        makeParticles(coolParticle, 4)
-                        player[this.layer].clickables[this.id] = "Borkened..."
-                        break;
-                    default:
-                        player[this.layer].clickables[this.id] = "Start"
-                        break;
-                }
-            },
-            onHold(){
-                console.log("Clickkkkk...")
-            },
-            style() {
-                switch(getClickableState(this.layer, this.id)){
-                    case "Start":
-                        return {'background-color': 'green'}
-                        break;
-                    case "A new state!":
-                        return {'background-color': 'yellow'}
-                        break;
-                    case "Keep going!":
-                        return {'background-color': 'orange'}
-                        break;                        
-                    case "Maybe that's a bit too far...":
-                        return {'background-color': 'red'}
-                        break;
-                    default:
-                        return {}
-                        break;
-            }},
-        },
-    },
-
-}, 
-)
-
-const coolParticle = {
-    image:"options_wheel.png",
-    spread: 20,
-    gravity: 2,
-    time: 3,
-    rotation (id) {
-        return 20 * (id - 1.5) + (Math.random() - 0.5) * 10
-    },
-    dir() {
-        return (Math.random() - 0.5) * 10
-    },
-    speed() {
-        return (Math.random() + 1.2) * 8 
-    },
-    onClick() {
-        console.log("yay")
-    },
-    onMouseOver() {
-        console.log("hi")
-    },
-    onMouseLeave() {
-        console.log("bye")
-    },
-    update() {
-        //this.width += 1
-        //setDir(this, 135)
-    },
-    layer: 'f',
-}
\ No newline at end of file
diff --git a/js/levels.js b/js/levels.js
index a29c697..4ec3f44 100644
--- a/js/levels.js
+++ b/js/levels.js
@@ -2,34 +2,53 @@ 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)
 }
-function getNextAlphaCost(points = player.p.points) {
+function getAlphaCost(points = player.p.points) {
     return getAlphaLevel(points).pow_base(1.1).mul(11).sub(10)
 }
+function getAlphaEffect(points = player.p.points) {
+    return getAlphaLevel(points).mul(getAlphaRankEffect(points).add(0.05))
+}
 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)
 }
-function getNextBetaCost(points = player.p.points) {
+function getBetaCost(points = player.p.points) {
     return getBetaLevel(points).pow_base(1.25).mul(25).sub(20)
 }
+function getBetaEffect(points = player.p.points) {
+    return getBetaLevel(points).mul(getBetaRankEffect(points).add(0.05)).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)
 }
-function getNextGammaCost(points = player.p.points) {
+function getGammaCost(points = player.p.points) {
     return getGammaLevel(points).pow_base(1.5).mul(45).sub(30)
 }
+function getGammaEffect(points = player.p.points) {
+    return getGammaLevel(points).div(getGammaRankEffect(points).add(1/15)).add(1)
+}
 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)
 }
-function getNextDeltaCost(points = player.p.points) {
+function getDeltaCost(points = player.p.points) {
     return getDeltaLevel(points).pow_base(2).mul(60).sub(30)
 }
+function getDeltaEffect(points = player.p.points) {
+    return getDeltaLevel(points).mul(getDeltaRankEffect(points).add(0.1)).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)
 }
-function getNextEpsilonCost(points = player.p.points) {
+function getEpsilonCost(points = player.p.points) {
     return getEpsilonLevel(points).pow_base(2.5).mul(250).sub(100).div(3)
+}
+function getEpsilonEffect(points = player.p.points) {
+    return getEpsilonLevel(points).mul(getEpsilonRankEffect(points).add(0.025)).add(1)
+}
+
+function getTotalLevel() {
+    return getAlphaLevel().add(getBetaLevel()).add(getGammaLevel()).add(getDeltaLevel()).add(getEpsilonLevel())
 }
\ No newline at end of file
diff --git a/js/mod.js b/js/mod.js
index e2882e8..836adc2 100644
--- a/js/mod.js
+++ b/js/mod.js
@@ -3,7 +3,7 @@ let modInfo = {
 	id: "nif/pbic",
 	author: "Nif",
 	pointsName: "points",
-	modFiles: ["levels.js", "progress.js", "tree.js"],
+	modFiles: ["ranks.js", "levels.js", "progress.js", "tree.js"],
 
 	discordName: "",
 	discordLink: "",
@@ -20,7 +20,8 @@ let VERSION = {
 let changelog = `<h1>Changelog:</h1><br><br>
 	<h3>v0/a1</h3><br>
 		- Added progress points.<br>
-		- Added bars Alpha to Epsilon.<br>`
+		- Added bars Alpha to Epsilon.<br>
+		- Added Ranks.<br>`
 
 let winText = `Download 100% complete.<br><br>You won! Congratulations!<br>Beyond this point may be unbalanced, proceed with caution!`
 
@@ -41,11 +42,11 @@ function canGenPoints(){
 function getPointGen() {
 	if(!canGenPoints()) return new Decimal(0)
 
-	let gain = getAlphaLevel().div(20)
-	gain = gain.mul(getBetaLevel().div(20).add(1))
-	gain = gain.mul(getGammaLevel().div(15).add(1))
-	gain = gain.mul(getDeltaLevel().div(10).add(1))
-	gain = gain.pow(getEpsilonLevel().div(40).add(1))
+	let gain = getAlphaEffect()
+		.mul(getBetaEffect())
+		.mul(getGammaEffect())
+		.mul(getDeltaEffect())
+		.pow(getEpsilonEffect())
 	return gain
 }
 
diff --git a/js/progress.js b/js/progress.js
index dc2741a..9217737 100644
--- a/js/progress.js
+++ b/js/progress.js
@@ -33,10 +33,21 @@ addLayer("p", {
             direction: RIGHT,
             width: 300,
             height: 50,
-            progress() { return player[this.layer].points.div(getNextAlphaCost()) },
+            progress() { return player[this.layer].points.div(getAlphaCost()) },
             display() {
-                return "Alpha - Level " + getAlphaLevel() + " (" + player[this.layer].points + "/" + getNextAlphaCost()
-                    + ")<br>Effect: +" + getAlphaLevel().div(20) + " to point gen."
+                return "Alpha - Level " + getAlphaLevel() + " (" + player[this.layer].points + "/" + getAlphaCost()
+                    + ")<br>Effect: +" + getAlphaEffect() + " to point gen."
+            },
+            fillStyle: {backgroundColor: "#0c6949"}
+        },
+        alphaRank: {
+            direction: RIGHT,
+            width: 300,
+            height: 50,
+            progress() { return getAlphaLevel().div(getAlphaRankCost()) },
+            display() {
+                return "Alpha - Rank " + getAlphaRank() + " (" + getAlphaLevel() + "/" + getAlphaRankCost()
+                    + ")<br>Effect: +" + getAlphaRankEffect() + " to Alpha base."
             },
             fillStyle: {backgroundColor: "#0c6949"}
         },
@@ -44,10 +55,21 @@ addLayer("p", {
             direction: RIGHT,
             width: 300,
             height: 50,
-            progress() { return player[this.layer].points.div(getNextBetaCost()) },
+            progress() { return player[this.layer].points.div(getBetaCost()) },
             display() {
-                return "Beta - Level " + getBetaLevel() + " (" + player[this.layer].points + "/" + getNextBetaCost()
-                    + ")<br>Effect: x" + getBetaLevel().div(20).add(1) + " to point gen."
+                return "Beta - Level " + getBetaLevel() + " (" + player[this.layer].points + "/" + getBetaCost()
+                    + ")<br>Effect: x" + getBetaEffect() + " to point gen."
+            },
+            fillStyle: {backgroundColor: "#0c6949"}
+        },
+        betaRank: {
+            direction: RIGHT,
+            width: 300,
+            height: 50,
+            progress() { return getBetaLevel().div(getBetaRankCost()) },
+            display() {
+                return "Beta - Rank " + getBetaRank() + " (" + getBetaLevel() + "/" + getBetaRankCost()
+                    + ")<br>Effect: +" + getBetaRankEffect() + " to Beta base."
             },
             fillStyle: {backgroundColor: "#0c6949"}
         },
@@ -55,10 +77,21 @@ addLayer("p", {
             direction: RIGHT,
             width: 300,
             height: 50,
-            progress() { return player[this.layer].points.div(getNextGammaCost()) },
+            progress() { return player[this.layer].points.div(getGammaCost()) },
             display() {
-                return "Gamma - Level " + getGammaLevel() + " (" + player[this.layer].points + "/" + getNextGammaCost()
-                    + ")<br>Effect: x" + getGammaLevel().div(15).add(1) + " to point gen."
+                return "Gamma - Level " + getGammaLevel() + " (" + player[this.layer].points + "/" + getGammaCost()
+                    + ")<br>Effect: x" + getGammaEffect() + " to point gen."
+            },
+            fillStyle: {backgroundColor: "#0c6949"}
+        },
+        gammaRank: {
+            direction: RIGHT,
+            width: 300,
+            height: 50,
+            progress() { return getGammaLevel().div(getGammaRankCost()) },
+            display() {
+                return "Gamma - Rank " + getGammaRank() + " (" + getGammaLevel() + "/" + getGammaRankCost()
+                    + ")<br>Effect: +" + getGammaRankEffect() + " to Gamma base."
             },
             fillStyle: {backgroundColor: "#0c6949"}
         },
@@ -66,10 +99,21 @@ addLayer("p", {
             direction: RIGHT,
             width: 300,
             height: 50,
-            progress() { return player[this.layer].points.div(getNextDeltaCost()) },
+            progress() { return player[this.layer].points.div(getDeltaCost()) },
             display() {
-                return "Delta - Level " + getDeltaLevel() + " (" + player[this.layer].points + "/" + getNextDeltaCost()
-                    + ")<br>Effect: x" + getDeltaLevel().div(10).add(1) + " to point gen."
+                return "Delta - Level " + getDeltaLevel() + " (" + player[this.layer].points + "/" + getDeltaCost()
+                    + ")<br>Effect: x" + getDeltaEffect() + " to point gen."
+            },
+            fillStyle: {backgroundColor: "#0c6949"}
+        },
+        deltaRank: {
+            direction: RIGHT,
+            width: 300,
+            height: 50,
+            progress() { return getDeltaLevel().div(getDeltaRankCost()) },
+            display() {
+                return "Delta - Rank " + getDeltaRank() + " (" + getDeltaLevel() + "/" + getDeltaRankCost()
+                    + ")<br>Effect: +" + getDeltaRankEffect() + " to Delta base."
             },
             fillStyle: {backgroundColor: "#0c6949"}
         },
@@ -77,10 +121,21 @@ addLayer("p", {
             direction: RIGHT,
             width: 300,
             height: 50,
-            progress() { return player[this.layer].points.div(getNextEpsilonCost()) },
+            progress() { return player[this.layer].points.div(getEpsilonCost()) },
             display() {
-                return "Epsilon - Level " + getEpsilonLevel() + " (" + player[this.layer].points + "/" + getNextEpsilonCost()
-                    + ")<br>Effect: ^" + getEpsilonLevel().div(40).add(1) + " to point gen."
+                return "Epsilon - Level " + getEpsilonLevel() + " (" + player[this.layer].points + "/" + getEpsilonCost()
+                    + ")<br>Effect: ^" + getEpsilonEffect() + " to point gen."
+            },
+            fillStyle: {backgroundColor: "#0c6949"}
+        },
+        epsilonRank: {
+            direction: RIGHT,
+            width: 300,
+            height: 50,
+            progress() { return getEpsilonLevel().div(getEpsilonRankCost()) },
+            display() {
+                return "Epsilon - Rank " + getEpsilonRank() + " (" + getEpsilonLevel() + "/" + getEpsilonRankCost()
+                    + ")<br>Effect: +" + getEpsilonRankEffect() + " to Epsilon base."
             },
             fillStyle: {backgroundColor: "#0c6949"}
         },
@@ -90,17 +145,34 @@ addLayer("p", {
             player[this.layer].levels.epsilon = player[this.layer].levels.epsilon.add(1)
         }
     },
+    microtabs: {
+        progress: {
+            level: {
+                content: [
+                    ["bar", "alpha"],
+                    ["bar", "beta"],
+                    ["bar", "gamma"],
+                    ["bar", "delta"],
+                    ["bar", "epsilon"]
+                ]
+            },
+            rank: {
+                content: [
+                    ["bar", "alphaRank"],
+                    ["bar", "betaRank"],
+                    ["bar", "gammaRank"],
+                    ["bar", "deltaRank"],
+                    ["bar", "epsilonRank"],
+                ]
+            }
+        }
+    },
     tabFormat: [
         "main-display",
         "prestige-button",
         "blank",
-        "h-line",
         "blank",
-        ["bar", "alpha"],
-        ["bar", "beta"],
-        ["bar", "gamma"],
-        ["bar", "delta"],
-        ["bar", "epsilon"],
+        ["microtabs", "progress"],
     ],
     layerShown(){return true}
 })
diff --git a/js/ranks.js b/js/ranks.js
new file mode 100644
index 0000000..0566347
--- /dev/null
+++ b/js/ranks.js
@@ -0,0 +1,54 @@
+function getAlphaRank(points = player.p.points) {
+    if (Decimal.eq(points, 0)) return new Decimal(0)
+    return getAlphaLevel(points).div(20).floor()
+}
+function getAlphaRankCost(points = player.p.points) {
+    return getAlphaRank(points).add(1).mul(20)
+}
+function getAlphaRankEffect(points = player.p.points) {
+    return getAlphaRank(points).div(100)
+}
+function getBetaRank(points = player.p.points) {
+    if (Decimal.eq(points, 0)) return new Decimal(0)
+    return getBetaLevel(points).div(20).floor()
+}
+function getBetaRankCost(points = player.p.points) {
+    return getBetaRank(points).add(1).mul(20)
+}
+function getBetaRankEffect(points = player.p.points) {
+    return getBetaRank(points).div(100)
+}
+function getGammaRank(points = player.p.points) {
+    if (Decimal.eq(points, 0)) return new Decimal(0)
+    return getGammaLevel(points).div(20).floor()
+}
+function getGammaRankCost(points = player.p.points) {
+    return getGammaRank(points).add(1).mul(20)
+}
+function getGammaRankEffect(points = player.p.points) {
+    return getGammaRank(points).div(200).mul(3)
+}
+function getDeltaRank(points = player.p.points) {
+    if (Decimal.eq(points, 0)) return new Decimal(0)
+    return getDeltaLevel(points).div(20).floor()
+}
+function getDeltaRankCost(points = player.p.points) {
+    return getDeltaRank(points).add(1).mul(20)
+}
+function getDeltaRankEffect(points = player.p.points) {
+    return getDeltaRank(points).div(50)
+}
+function getEpsilonRank(points = player.p.points) {
+    if (Decimal.eq(points, 0)) return new Decimal(0)
+    return getEpsilonLevel(points).div(20).floor()
+}
+function getEpsilonRankCost(points = player.p.points) {
+    return getEpsilonRank(points).add(1).mul(20)
+}
+function getEpsilonRankEffect(points = player.p.points) {
+    return getEpsilonRank(points).div(100)
+}
+
+function getTotalRank() {
+    return getAlphaRank().add(getBetaRank()).add(getGammaRank()).add(getDeltaRank()).add(getEpsilonRank())
+}
\ No newline at end of file