diff --git a/docs/!general-info.md b/docs/!general-info.md
index acd0279..2f8dbf3 100644
--- a/docs/!general-info.md
+++ b/docs/!general-info.md
@@ -1,8 +1,11 @@
# The-Modding-Tree
-The main way to add content is through creating layers. You can either add a layer directly in the layers object in layers.js, or declare it separately and then do "`addLayer(layername, layerdata)`" (good for breaking things up into smaller files). The existing layers are just examples and can be freely deleted. sampleLayers.js has even more features and comments in it. You can use those as references and a base for your own layers.
+The main way to add content is through creating layers. You can either add a layer directly in the layers object in layersSupportjs,
+or declare it in another file and then do "`addLayer(layername, layerdata)`"
+(good for breaking things up into smaller files). The existing layers are just examples and can be freely deleted.
+You can use those as references and a base for your own layers.
-**You will also need to add layer nodes to the tree in the HTML, look for where it says "Modify the tree in the table below!"** While you're there, you can also edit the modInfo at the top to change the name for your mod.
+**You will also need to add layer nodes to the tree in the HTML, look for where it says "Modify the tree in the table below!"** While you're there, you can also edit the modInfo at the top to change the name for your mod and some other settings. A unique modId will prevent your mod's saves from conflicting with other mods.
Most of the time, you won't need to dive deep into the code to create things, but you still can if you really want to.
diff --git a/docs/basic-layer-breakdown.md b/docs/basic-layer-breakdown.md
index e19e3a9..4250626 100644
--- a/docs/basic-layer-breakdown.md
+++ b/docs/basic-layer-breakdown.md
@@ -1,6 +1,8 @@
# Basic layer breakdown
-This is a very minimal layer with minimal features. Most things will require additional features:
+This is a very minimal layer with minimal features. Most things will require additional features.
+If you're curious about "() =>", it's a weird notation that lets you use either a value or function in the same slot,
+and treats it like a function. If you're using an actual function there, you can replace it with the normal notation.
```js
p: {
@@ -10,16 +12,15 @@ This is a very minimal layer with minimal features. Most things will require add
// If you add non-standard Decimal variables, look at convertToDecimal
}},
- color: "#FE0102", // The color for this layer, which affects many elements
+ color:() => "#FE0102", // The color for this layer, which affects many elements
resource: "prestige points", // The name of this layer's main prestige resource
row: 0, // The row this layer is on (0 is the first row)
baseResource: "points", // The name of the resource your prestige gain is based on
baseAmount() {return player.points}, // A function to return the current value of that resource
- requires() {return new Decimal(200)}, // A function returning the amount of the base needed to
- // gain 1 of the prestige currency. Also the amount required
- // to unlock the layer.
+ requires:() => new Decimal(200)}, // The amount of the base needed to gain 1 of the prestige currency.
+ // Also the amount required to unlock the layer.
type: "normal", // Determines the formula used for calculating prestige currency.
exponent: 0.5, // "normal" prestige gain is (currency^exponent)
diff --git a/docs/buyables.md b/docs/buyables.md
index d0a3137..592c9b1 100644
--- a/docs/buyables.md
+++ b/docs/buyables.md
@@ -13,7 +13,7 @@ Buyables should be formatted like this:
Having this function makes a respec button appear
respecText: **optional**, text that appears on the respec button
11: {
- desc: "Blah",
+ desc:() => "Blah",
etc
}
etc
@@ -23,6 +23,7 @@ Buyables should be formatted like this:
Features:
- title: **optional**, displayed at the top in a larger font
+ It can also be a function that returns updating text.
- cost(x): cost for buying xth buyable, can be an object if there are multiple currencies
@@ -30,7 +31,7 @@ Features:
for having x of this buyable. Can return a value or an object containing multiple values.
- display(): A function returning everything that should be displayed on the rebuyable after the title, likely
- including the description, amount bought, cost, and current effect
+ including the description, amount bought, cost, and current effect.
- unl(): A function returning a bool to determine if the buyable is visible or not.
@@ -38,4 +39,8 @@ Features:
- buy(): A function that implements buying one of the buyable.
-- buyMax(): **optional**, A function that implements buying as many of the buyable as possible.
\ No newline at end of file
+- buyMax(): **optional**, A function that implements buying as many of the buyable as possible.
+
+- layer: **Assigned automagically**. It's the same value as the name of this layer, so you can do player[this.layer].points or similar
+
+- id: **Assigned automagically**. It's the id for this buyable.
\ No newline at end of file
diff --git a/docs/challenges.md b/docs/challenges.md
index 8bd704a..01de2b3 100644
--- a/docs/challenges.md
+++ b/docs/challenges.md
@@ -7,7 +7,7 @@ Challenges are stored in the following format:
rows: # of rows
cols: # of columns
11: {
- name: "Ouch",
+ name:() => "Ouch",
etc
}
etc
@@ -20,19 +20,22 @@ or has completed the challenge, respectively. These are useful for implementing
Each challenge should have an id where the first digit is the row and the second digit is the column.
Individual upgrades can have these features:
-- name: Name of the challenge
+- name: Name of the challenge, can be a string or a function
- desc: A description of what makes the challenge a challenge. *You will need to implement these elsewhere*
+ It can also be a function that returns updating text.
- reward: A description of the reward's effect. *You will also have to implement the effect where it is applied.*
+ It can also be a function that returns updating text.
- effect(): **optional**, A function that calculates and returns the current values of any bonuses from the reward.
Can return a value or an object containing multiple values.
-- effectDisp(effects): **optional**, A function that returns a display of the current effects of the reward with
+- effectDisplay(effects): **optional**, A function that returns a display of the current effects of the reward with
formatting. Default behavior is to just display the a number appropriately formatted.
- goal: A Decimal for the cost of the upgrade. By default, the goal is in basic Points.
+ The goal can also be a function if its value changes.
- unl(): A function returning a bool to determine if the challenge is visible or not.
@@ -48,3 +51,6 @@ By default, challenges use basic Points for the goal. You can change that using
If it's part of a layer, omit.
+- layer: **Assigned automagically**. It's the same value as the name of this layer, so you can do player[this.layer].points or similar
+
+- id: **Assigned automagically**. It's the id for this challenge.
\ No newline at end of file
diff --git a/docs/custom-tab-layouts.md b/docs/custom-tab-layouts.md
index 186425b..d8b6562 100644
--- a/docs/custom-tab-layouts.md
+++ b/docs/custom-tab-layouts.md
@@ -19,20 +19,25 @@ which applies its style to the component.
These are the existing components, but you can create more in v.js:
-- display-text: Displays some text. The argument is a function which returns the text to display.
+- display-text: Displays some text. The argument is the text to display. It can also be a function that returns updating text.
-- raw-html: Displays some HTML. The argument is a function which returns the HTML. It doesn't work with many vue things.
+- raw-html: Displays some HTML. The argument is the HTML as a string, or a function that returns updating HTML.
+ It doesn't work with many vue things.
- blank: An empty newline
- main-display: The text that displays the main currency for the layer and its effects.
-- prestige-button: The argument is a function that returns what the prestige button should say before the amount of
- currency you will gain.
+- prestige-button: The argument is a string that the prestige button should say before the amount of
+ currency you will gain. It can also be a function that returns updating text.
- upgrades, milestones, challs: Display the upgrades, milestones, and challenges for a layer, as appropriate.
- buyables: Display all of the buyables for this layer, as appropriate. The argument optional, and is the size of the
boxes in pixels.
-- toggle: A toggle button that toggles a bool value. The data is a pair that identifies what bool to toggle, [layer, id]
\ No newline at end of file
+- toggle: A toggle button that toggles a bool value. The data is a pair that identifies what bool to toggle, [layer, id]
+
+
+Tip: use readData on things you're displaying! If the data is a function, it will return the result of calling it.
+ Otherwise, it will return the data itself. This lets you use dynamic values, while keeping constant values convenient.
\ No newline at end of file
diff --git a/docs/layer-features.md b/docs/layer-features.md
index c8a982d..1ec74ac 100644
--- a/docs/layer-features.md
+++ b/docs/layer-features.md
@@ -10,6 +10,9 @@ Key:
# Layer Definition features
+- layer: **Assigned automagically**. It's the same value as the name of this layer, so you can do player[this.layer].points or similar
+ to access the save value. It makes copying code to new layers easier. It is also assigned to all upgrades and buyables and such.
+
- startData(): A function to return the default save data for this layer. Add any variables you have to it.
Any nonstandard Decimal variables need to be added to convertToDecimal as well.
Standard values:
@@ -32,7 +35,8 @@ Key:
Can return a value or an object containing multiple values.
*You will also have to implement the effect where it is applied.*
-- effectDescription(): **optional**, A function that returns a description of this effect
+- effectDescription: **optional**, A function that returns a description of this effect.
+ If the text stays constant, it can just be a string.
- layerShown(): A function returning a bool which determines if this layer's node should be visible on the tree.
@@ -46,6 +50,7 @@ Key:
```
- style: A CSS object containing any CSS that should affect this layer's whole tab.
+ Can also be a function returning a dynamic CSS object.
- tabFormat: Use this if you want to add extra things to your tab or change the layout.
@@ -72,9 +77,9 @@ Key:
- baseAmount(): A function that gets the current value of the base resource.
-- requires(): A function returning the amount of the base needed to gain 1 of the prestige currency.
+- requires: A Decimal, the amount of the base needed to gain 1 of the prestige currency.
Also the amount required to unlock the layer.
- You might make the value increase if another layer was unlocked first (based on "order").
+ You can instead make this a function, to make it harder if another layer was unlocked first (based on "order").
- type: Determines which prestige formula you use.
"normal": The amount of currency you gain is independent of its current amount (like Prestige).
diff --git a/docs/milestones.md b/docs/milestones.md
index 83a00d5..874c899 100644
--- a/docs/milestones.md
+++ b/docs/milestones.md
@@ -5,7 +5,7 @@ Milestones should be formatted like this:
```js
milestones: {
0: {
- requirementDesc: "123 waffles",
+ requirementDesc:() => "123 waffles",
}
etc
}
@@ -16,8 +16,10 @@ You can use inChall(layer, id) and hasChall(layer, id) to determine if the playe
Milestone features:
- requirementDesc: A string describing the requirement for unlocking this milestone. Suggestion: Use a "total".
+ It can also be a function that returns updating text.
- effectDesc: A string describing the reward for having the milestone. *You will have to implement the reward elsewhere.*
+ It can also be a function that returns updating text.
- done(): A function returning a boolean to determine if the milestone has been fulfilled.
@@ -25,4 +27,8 @@ Milestone features:
The toggles can toggle a given boolean value in a layer.
It is defined as an array of paired items, one pair per toggle. The first is the internal name of the layer
the value being toggled is stored in, and the second is the internal name of the variable to toggle.
- (e.g. [["b", "auto"], ["g", "auto"])
\ No newline at end of file
+ (e.g. [["b", "auto"], ["g", "auto"])
+
+- layer: **Assigned automagically**. It's the same value as the name of this layer, so you can do player[this.layer].points or similar
+
+- id: **Assigned automagically**. It's the id for this milestone.
diff --git a/docs/upgrades.md b/docs/upgrades.md
index bc493a5..e58f347 100644
--- a/docs/upgrades.md
+++ b/docs/upgrades.md
@@ -7,7 +7,7 @@ Upgrades are stored in the following format:
rows: # of rows
cols: # of columns
11: {
- desc: "Blah",
+ desc:() => "Blah",
etc
}
etc
@@ -20,12 +20,16 @@ Hint: Basic point gain is calculated in game.js's "getPointGain".
Each upgrade should have an id where the first digit is the row and the second digit is the column.
Individual upgrades can have these features:
+- title: **optional**, displayed at the top in a larger font
+ It can also be a function that returns updating text.
+
- desc: A description of the upgrade's effect. *You will also have to implement the effect where it is applied.*
+ It can also be a function that returns updating text.
- effect(): **optional**, A function that calculates and returns the current values of any bonuses from the upgrade.
Can return a value or an object containing multiple values.
-- effectDisp(effects): **optional**, A function that returns a display of the current effects of the upgrade with
+- effectDisplay(effects): **optional**, A function that returns a display of the current effects of the upgrade with
formatting. Default behavior is to just display the a number appropriately formatted.
- cost: A Decimal for the cost of the upgrade. By default, upgrades cost the main prestige currency for the layer.
@@ -41,4 +45,6 @@ By default, upgrades use the main prestige currency for the layer. You can inclu
- currencyLayer: **optional**, the internal name of the layer that currency is stored in.
If it's not in a layer (like Points), omit.
+- layer: **Assigned automagically**. It's the same value as the name of this layer, so you can do player[this.layer].points or similar
+- id: **Assigned automagically**. It's the id for this upgrade.
\ No newline at end of file
diff --git a/index.html b/index.html
index a01bede..46c9f0f 100644
--- a/index.html
+++ b/index.html
@@ -13,6 +13,7 @@
+
@@ -44,7 +45,14 @@
-
+
v1.2: This Changes Everything!
+
+
Many layer features can now be static values or functions. (This made some notations change, which will break things)
+
You can now use the "this" keyword, to make code easier to transfer when making new layers. Also added "this.layer", which is the current layer's name, and works on existing subfeatures (e.g. individual upgrades) as well! Subfeatures also have "this.id".
+
Fixed a big save issue. If you use a unique mod id, your save will never conflict with other mods.
+
Added a configurable offline time limit in modinfo at the top of index.html. (default 1 hour)
+
Added a few minor features, and updated the docs with new information.
+
v1.1.1
You can define hotkeys in layer config.
@@ -140,7 +148,7 @@
-
+
diff --git a/js/game.js b/js/game.js
index 9b9d214..3d38522 100644
--- a/js/game.js
+++ b/js/game.js
@@ -5,8 +5,8 @@ var NaNalert = false;
var gameEnded = false;
let VERSION = {
- num: "1.1.1",
- name: "Enhanced Edition"
+ num: "1.2",
+ name: "This changes everything!"
}
function startPlayerBase() {
@@ -293,7 +293,7 @@ function getNextAt(layer) {
}
function nodeShown(layer) {
- if (layers[layer].layerShown()) return true
+ if (tmp.layerShown[layer]) return true
switch(layer) {
case "idk":
return player.l.unl
@@ -405,7 +405,7 @@ function respecBuyables(layer) {
function canAffordUpg(layer, id) {
upg = layers[layer].upgrades[id]
- cost = upg.cost
+ cost = tmp.upgrades[layer][id].cost
return canAffordPurchase(layer, upg, cost)
}
@@ -421,7 +421,6 @@ function hasChall(layer, id){
return (player[layer].challs.includes(id))
}
-
function canAffordPurchase(layer, thing, cost) {
if (thing.currencyInternalName){
let name = thing.currencyInternalName
@@ -443,22 +442,23 @@ function buyUpg(layer, id) {
if (!layers[layer].upgrades[id].unl()) return
if (player[layer].upgrades.includes(id)) return
upg = layers[layer].upgrades[id]
+ cost = tmp.upgrades[layer][id].cost
if (upg.currencyInternalName){
let name = upg.currencyInternalName
if (upg.currencyLayer){
let lr = upg.currencyLayer
- if (player[lr][name].lt(upg.cost)) return
- player[lr][name] = player[lr][name].sub(upg.cost)
+ if (player[lr][name].lt(cost)) return
+ player[lr][name] = player[lr][name].sub(cost)
}
else {
- if (player[name].lt(upg.cost)) return
- player[name] = player[name].sub(upg.cost)
+ if (player[name].lt(cost)) return
+ player[name] = player[name].sub(cost)
}
}
else {
- if (player[layer].points.lt(upg.cost)) return
- player[layer].points = player[layer].points.sub(upg.cost)
+ if (player[layer].points.lt(cost)) return
+ player[layer].points = player[layer].points.sub(cost)
}
player[layer].upgrades.push(id);
if (upg.onPurchase != undefined)
@@ -467,8 +467,8 @@ function buyUpg(layer, id) {
function buyBuyable(layer, id) {
if (!player[layer].unl) return
- if (!layers[layer].buyables[id].unl()) return
- if (!layers[layer].buyables[id].canAfford()) return
+ if (!tmp.buyables[layer][id].unl) return
+ if (!tmp.buyables[layer][id].canAfford) return
layers[layer].buyables[id].buy()
}
@@ -517,7 +517,7 @@ function canCompleteChall(layer, x)
let name = chall.currencyInternalName
if (chall.currencyLayer){
let lr = chall.currencyLayer
- return !(player[lr][name].lt(chall.goal))
+ return !(player[lr][name].lt(readData(chall.goal)))
}
else {
return !(player[name].lt(chall.cost))
@@ -719,21 +719,6 @@ function switchTheme() {
resizeCanvas()
}
-function updateHotkeys()
-{
- hotkeys = {};
- for (layer in layers){
- hk = layers[layer].hotkeys
- if (hk){
- for (id in hk){
- hotkeys[hk[id].key] = hk[id]
- hotkeys[hk[id].key].layer = layer
- }
- }
- }
-}
-updateHotkeys()
-
document.onkeydown = function(e) {
if (player===undefined) return;
if (gameEnded&&!player.keepGoing) return;
diff --git a/js/layerSupport.js b/js/layerSupport.js
new file mode 100644
index 0000000..525dcb8
--- /dev/null
+++ b/js/layerSupport.js
@@ -0,0 +1,85 @@
+var layers = {}
+
+function layerShown(layer){
+ return layers[layer].layerShown();
+}
+
+var LAYERS = Object.keys(layers);
+
+var hotkeys = {};
+
+function updateHotkeys()
+{
+ hotkeys = {};
+ for (layer in layers){
+ hk = layers[layer].hotkeys
+ if (hk){
+ for (id in hk){
+ hotkeys[hk[id].key] = hk[id]
+ hotkeys[hk[id].key].layer = layer
+ }
+ }
+ }
+}
+
+var ROW_LAYERS = {}
+
+function updateLayers(){
+ LAYERS = Object.keys(layers);
+ ROW_LAYERS = {}
+ for (layer in layers){
+ layers[layer].layer = layer
+ if (layers[layer].upgrades){
+ for (thing in layers[layer].upgrades){
+ if (!isNaN(thing)){
+ layers[layer].upgrades[thing].id = thing
+ layers[layer].upgrades[thing].layer = layer
+ }
+ }
+ }
+ if (layers[layer].milestones){
+ for (thing in layers[layer].milestones){
+ if (!isNaN(thing)){
+ layers[layer].milestones[thing].id = thing
+ layers[layer].milestones[thing].layer = layer
+ }
+ }
+ }
+ if (layers[layer].challs){
+ for (thing in layers[layer].challs){
+ if (!isNaN(thing)){
+ layers[layer].challs[thing].id = thing
+ layers[layer].challs[thing].layer = layer
+ }
+ }
+ }
+ if (layers[layer].buyables){
+ layers[layer].buyables.layer = layer
+ for (thing in layers[layer].buyables){
+ if (!isNaN(thing)){
+ layers[layer].buyables[thing].id = thing
+ layers[layer].buyables[thing].layer = layer
+
+ }
+ }
+ }
+
+ row = layers[layer].row
+ if(!ROW_LAYERS[row]) ROW_LAYERS[row] = {}
+ ROW_LAYERS[row][layer]=layer;
+ }
+ updateHotkeys()
+}
+
+function addLayer(layerName, layerData){ // Call this to add layers from a different file!
+ layers[layerName] = layerData
+ updateLayers()
+}
+
+// If data is a function, return the result of calling it. Otherwise, return the data.
+function readData(data, args=null){
+ if (!!(data && data.constructor && data.call && data.apply))
+ return data(args);
+ else
+ return data;
+}
\ No newline at end of file
diff --git a/js/layers.js b/js/layers.js
index b90474e..9ac447e 100644
--- a/js/layers.js
+++ b/js/layers.js
@@ -1,5 +1,5 @@
-var layers = {
- c: {
+addLayer("c", {
+ layer: "c", // This is assigned automatically, both to the layer and all upgrades, etc. Shown here so you know about it
startData() { return {
unl: true,
points: new Decimal(0),
@@ -8,75 +8,98 @@ var layers = {
buyables: {}, // You don't actually have to initialize this one
beep: false,
}},
- color: "#4BEC13",
- requires() {return new Decimal(10)}, // Can be a function that takes requirement increases into account
+ color:() => "#4BEC13",
+ requires:() => new Decimal(10), // Can be a function that takes requirement increases into account
resource: "lollipops", // Name of prestige currency
baseResource: "candies", // Name of resource prestige is based on
- baseAmount() {return player.points},
+ 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))
- resCeil: false, // True if the resource needs to be rounded up
- canBuyMax() {}, // Only needed for static layers
- gainMult() {
+ resCeil: false, // True if the cost needs to be rounded up (use when baseResource is static?)
+ canBuyMax() {}, // Only needed for static layers with buy max
+ gainMult() { // Calculate the multiplier for main currency from bonuses
mult = new Decimal(1)
- if (player.c.upgrades.includes(21)) mult = mult.times(2)
- if (player.c.upgrades.includes(23)) mult = mult.times(LAYER_UPGS.c[23].currently())
+ if (player[this.layer].upgrades.includes(21)) mult = mult.times(2)
+ if (player[this.layer].upgrades.includes(23)) mult = mult.times(this.upgrades[23].currently())
return mult
},
- gainExp() {
+ gainExp() { // Calculate the exponent on main currency from bonuses
return new Decimal(1)
},
- row: 0,
- 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.c.points, 0.2)),
- icecreamCap: (player.c.points * 10)
+ 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() {
- eff = layers.c.effect();
+ effectDescription() { // Optional text to describe the effects
+ eff = this.effect;
return "which are boosting waffles by "+format(eff.waffleBoost)+" and increasing the Ice Cream cap by "+format(eff.icecreamCap)
},
milestones: {
- 0: {requirementDesc: "3 Lollipops",
- done() {return player.c.best.gte(3)},
- effectDesc: "Makes this green",
+ 0: {requirementDesc:() => "3 Lollipops",
+ done() {return player[this.layer].best.gte(3)}, // Used to determine when to give the milestone
+ effectDesc:() => "Makes this green",
},
- 1: {requirementDesc: "4 Lollipops",
- done() {return player.c.best.gte(4)},
- effectDesc: "You can toggle beep and boop (which do nothing)",
+ 1: {requirementDesc:() => "4 Lollipops",
+ done() {return player[this.layer].best.gte(4)},
+ effectDesc:() => "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
+ [this.layer, "beep"], // Each toggle is defined by a layer and the data toggled for that layer
["f", "boop"]],
}
},
+ challs: {
+ rows: 1,
+ cols: 1,
+ 11: {
+ name:() => "Fun",
+ desc:() => "Makes the game 0% harder",
+ unl() { return player[this.layer].best.gt(0) },
+ goal:() => new Decimal("20"),
+ currencyDisplayName: "lollipops", // Use if using a nonstandard currency
+ currencyInternalName: "points", // Use if using a nonstandard currency
+ currencyLayer: this.layer, // Leave empty if not in a layer
+ effect() {
+ let ret = player[this.layer].points.add(1).tetrate(0.02)
+ return ret;
+ },
+ effectDisplay(x) { return format(x)+"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.
+ reward:() => "Says hi",
+ onComplete() {console.log("hiii")} // Called when you complete the challenge
+ },
+ },
upgrades: {
rows: 1,
cols: 3,
11: {
- desc: "Gain 1 Candy every second.",
- cost: new Decimal(1),
- unl() { return player.c.unl },
+ title:() => "Generator of Genericness",
+ desc:() => "Gain 1 Point every second.",
+ cost:() => new Decimal(1),
+ unl() { return player[this.layer].unl }, // The upgrade is only visible when this is true
},
12: {
- desc: "Candy generation is faster based on your unspent Lollipops.",
- cost: new Decimal(1),
- unl() { return player.c.upgrades.includes(11) },
- effect() {
- let ret = player.c.points.add(1).pow(player.c.upgrades.includes(24)?1.1:(player.c.upgrades.includes(14)?0.75:0.5))
+ desc:() => "Candy generation is faster based on your unspent Lollipops.",
+ cost:() => new Decimal(1),
+ unl() { return player[this.layer].upgrades.includes(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;
},
- effDisp(fx) { return format(fx)+"x" },
+ effectDisplay(fx) { return format(fx)+"x" }, // Add formatting to the effect
},
13: {
- desc: "Make this layer act like you bought it first.",
- cost: new Decimal(69),
+ desc:() => "Make this layer act like you bought it first.",
+ cost:() => new Decimal(69),
currencyDisplayName: "candies", // Use if using a nonstandard currency
currencyInternalName: "points", // Use if using a nonstandard currency
currencyLayer: "", // Leave empty if not in a layer "e.g. points"
- unl() { return player.c.upgrades.includes(12) },
- onPurchase() {
- player.c.order = 0
+ unl() { return player[this.layer].upgrades.includes(12) },
+ onPurchase() { // This function triggers when the upgrade is purchased
+ player[this.layer].order = 0
}
},
},
@@ -84,13 +107,13 @@ var layers = {
rows: 1,
cols: 1,
respec() { // Optional, reset things and give back your currency. Having this function makes a respec button appear
- player.c.points = player.c.points.add(player.c.spentOnBuyables) // A built-in thing to keep track of this but only keeps a single value
- resetBuyables("c")
- doReset("c", true) // Force a reset
+ 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
+ respecText:() => "Respec Thingies", // Text on Respec button, optional
11: {
- title: "Exhancers", // Optional, displayed at the top in a larger font
+ 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))
@@ -105,66 +128,71 @@ var layers = {
else eff.second = x.times(-1).pow(0.8).times(-1)
return eff;
},
- display (){
- let data = tmp.buyables.c["11"]
+ display() { // Everything else displayed in the buyable button after the title
+ let data = tmp.buyables[this.layer]["11"]
return "Cost: " + format(data.cost) + " lollipops\n\
- Amount: " + player.c.buyables["11"] + "\n\
- Adds + " + format(data.effects.first) + " things and multiplies stuff by " + format(data.effects.second)
+ Amount: " + player[this.layer].buyables["11"] + "\n\
+ Adds + " + format(data.effect.first) + " things and multiplies stuff by " + format(data.effect.second)
},
- unl() { return player.c.unl },
- canAfford() {return player.c.points.gte(tmp.buyables.c[11].cost)},
- buy() {
- cost = tmp.buyables.c[11].cost
- player.c.points = player.c.points.sub(cost)
- player.c.buyables[11] = player.c.buyables[11].add(1)
- player.c.spentOnBuyables = player.c.spentOnBuyables.add(cost) // This is a built-in system that you can use for respeccing but it only works with a single Decimal value
+ unl() { return player[this.layer].unl },
+ canAfford() {
+ return player[this.layer].points.gte(tmp.buyables["c"][11].cost)},
+ buy() {
+ cost = tmp.buyables[this.layer][11].cost
+ player[this.layer].points = player[this.layer].points.sub(cost)
+ player[this.layer].buyables[11] = player[this.layer].buyables[11].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
},
},
- doReset(layer){
- if(layers[layer].row > layers["c"].row) fullLayerReset('c') // This is actually the default behavior
+ 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) fullLayerReset(this.layer) // This is actually the default behavior
},
convertToDecimal() {
- // Convert any layer-specific values (besides points, total, and best) to Decimal
+ // Convert any layer-specific Decimal values (besides points, total, and best) from String to Decimal (used when loading save)
},
- layerShown() {return true}, // Condition for when layer appears
+ layerShown() {return true}, // Condition for when layer appears on the tree
update(diff) {
- if (player.c.upgrades.includes(11)) player.points = player.points.add(tmp.pointGen.times(diff)).max(0)
+ if (player[this.layer].upgrades.includes(11)) player.points = player.points.add(tmp.pointGen.times(diff)).max(0)
}, // Do any gameloop things (e.g. resource generation) inherent to this layer
automate() {
}, // Do any automation inherent to this layer if appropriate
updateTemp() {
- }, // Do any necessary temp updating
+ }, // Do any necessary temp updating, not that important usually
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", desc: "C: reset for lollipops or whatever", onPress(){if (player.c.unl) doReset("c")}},
- {key: "ctrl+c", desc: "Ctrl+c: respec things", onPress(){if (player.c.unl) respecBuyables("c")}},
+ {key: this.layer, desc: "C: reset for lollipops or whatever", onPress(){if (player[this.layer].unl) doReset(this.layer)}},
+ {key: "ctrl+" + this.layer, desc: "Ctrl+c: respec things", onPress(){if (player[this.layer].unl) respecBuyables(this.layer)}},
],
incr_order: [], // Array of layer names to have their order increased when this one is first unlocked
// Optional, lets you format the tab yourself by listing components. You can create your own components in v.js.
tabFormat: ["main-display",
- ["prestige-button", function(){return "Melt your points into "}],
+ ["prestige-button", function() {return "Melt your points into "}],
["raw-html", function() {return ""}],
["display-text",
function() {return 'I have ' + format(player.points) + ' pointy points!'},
{"color": "red", "font-size": "32px", "font-family": "Comic Sans MS"}],
["buyables", "150px"],
- ["toggle", ["c", "beep"]],
- "milestones", "upgrades"],
- style: {
+ ["toggle", [this.layer, "beep"]],
+ "milestones", "upgrades", "challs"],
+ style() {return {
'background-color': 'blue'
- },
- },
+ }},
+})
- f: {
+addLayer("f", {
startData() { return {
unl: false,
points: new Decimal(0),
boop: false,
}},
- color: "#FE0102",
+ color:() => "#FE0102",
requires() {return new Decimal(200)},
resource: "farm points",
baseResource: "candies",
@@ -181,35 +209,6 @@ var layers = {
layerShown() {return true},
branches: [["c", 1]] // Each pair corresponds to a line added to the tree when this node is unlocked. The letter is the other end of the line, and the number affects the color, 1 is default
},
-}
-
-function layerShown(layer){
- return layers[layer].layerShown();
-}
-
-var LAYERS = Object.keys(layers);
-
-var hotkeys = {};
+)
-
-var ROW_LAYERS = {}
-for (layer in layers){
- row = layers[layer].row
- if(!ROW_LAYERS[row]) ROW_LAYERS[row] = {}
-
- ROW_LAYERS[row][layer]=layer;
-}
-
-function addLayer(layerName, layerData){ // Call this to add layers from a different file!
- layers[layerName] = layerData
- LAYERS = Object.keys(layers);
- ROW_LAYERS = {}
- for (layer in layers){
- row = layers[layer].row
- if(!ROW_LAYERS[row]) ROW_LAYERS[row] = {}
-
- ROW_LAYERS[row][layer]=layer;
- }
- updateHotkeys()
-}
\ No newline at end of file
diff --git a/js/temp.js b/js/temp.js
index ff81b49..d057bde 100644
--- a/js/temp.js
+++ b/js/temp.js
@@ -1,6 +1,6 @@
function updateTemp() {
-
if (!tmp.challActive) {tmp.challActive = {}}
+ if (!tmp.challs) tmp.challs = {}
for (layer in layers) {
if(layers[layer].challs !== undefined){
tmp.challActive[layer] = {}
@@ -8,7 +8,20 @@ function updateTemp() {
}
}
+ if (!tmp.upgrades) tmp.upgrades = {}
+ for (layer in layers) {
+ if(layers[layer].upgrades !== undefined){
+ updateUpgradeTemp(layer)
+ }
+ }
+ if (!tmp.milestones) tmp.milestones = {}
+ for (layer in layers) {
+ if(layers[layer].milestones !== undefined){
+ updateMilestoneTemp(layer)
+ }
+ }
+
if (!tmp.layerEffs) tmp.layerEffs = {}
for (layer in layers) if (layers[layer].effect) tmp.layerEffs[layer] = layers[layer].effect()
@@ -17,12 +30,8 @@ function updateTemp() {
if (!tmp.buyables) tmp.buyables = {}
for (layer in layers) if (layers[layer].buyables) {
- if (!tmp.buyables[layer]) tmp.buyables[layer] = {}
- for (id in player[layer].buyables){
- if (!tmp.buyables[layer][id]) tmp.buyables[layer][id] = {}
- tmp.buyables[layer][id]
- tmp.buyables[layer][id].cost = layers[layer].buyables[id].cost(player[layer].buyables[id])
- tmp.buyables[layer][id].effects = layers[layer].buyables[id].effect(player[layer].buyables[id])
+ if(layers[layer].buyables !== undefined){
+ updateBuyableTemp(layer)
}
}
@@ -31,13 +40,23 @@ function updateTemp() {
if (!tmp.resetGain) tmp.resetGain = {}
if (!tmp.nextAt) tmp.nextAt = {}
if (!tmp.layerAmt) tmp.layerAmt = {}
+ if (!tmp.layerColor) tmp.layerColor = {}
+ if (!tmp.layerShown) tmp.layerShown = {}
+ if (!tmp.effectDescription) tmp.effectDescription = {}
+ if (!tmp.style) tmp.style = {}
+
for (layer in layers) {
+ if (layers[layer].color) tmp.layerColor[layer] = layers[layer].color()
+ if (layers[layer].style) tmp.style[layer] = layers[layer].style()
+ tmp.layerShown[layer] = layers[layer].layerShown()
tmp.layerAmt[layer] = layers[layer].baseAmount()
tmp.gainMults[layer] = layers[layer].gainMult()
tmp.gainExp[layer] = layers[layer].gainExp()
tmp.resetGain[layer] = getResetGain(layer)
tmp.nextAt[layer] = getNextAt(layer)
+ if (layers[layer].effectDescription) tmp.effectDescription[layer] = layers[layer].effectDescription()
+
}
tmp.pointGen = getPointGen()
@@ -49,6 +68,7 @@ function updateTemp() {
function updateChallTemp(layer) {
if (player[layer] === undefined) return
+ if (!tmp.challs[layer]) tmp.challs[layer] = {}
let data = tmp.challActive[layer]
let data2 = layers[layer].challs
@@ -56,8 +76,72 @@ function updateChallTemp(layer) {
for (let row = 1; row <= data2.rows; row++) {
for (let col = 1; col <= data2.cols; col++) {
let id = row * 10 + col
+ tmp.challs[layer][id] = {}
+ tmp.challs[layer][id].unl = data2[id].unl()
+ if(data2[id].name) tmp.challs[layer][id].name = data2[id].name()
+ if(data2[id].desc) tmp.challs[layer][id].desc = data2[id].desc()
+ if(data2[id].reward) tmp.challs[layer][id].reward = data2[id].reward()
+ if(data2[id].effect) tmp.challs[layer][id].effect = data2[id].effect()
+ if(data2[id].effectDisplay) tmp.challs[layer][id].effectDisplay = data2[id].effectDisplay(tmp.challs[layer][id].effect)
+ tmp.challs[layer][id].goal = data2[id].goal()
+
+
if (customActive ? data2.active(id) : player[layer].active == id) data[id] = 1
else delete data[id]
}
}
+}
+
+function updateUpgradeTemp(layer) {
+ if (player[layer] === undefined) return
+ if (!tmp.upgrades[layer]) tmp.upgrades[layer] = {}
+
+ let data2 = layers[layer].upgrades
+ for (let row = 1; row <= data2.rows; row++) {
+ for (let col = 1; col <= data2.cols; col++) {
+ let id = row * 10 + col
+ tmp.upgrades[layer][id] = {}
+ tmp.upgrades[layer][id].unl = data2[id].unl()
+ if(data2[id].title) tmp.upgrades[layer][id].title = data2[id].title()
+ if(data2[id].effect) tmp.upgrades[layer][id].effect = data2[id].effect()
+ if(data2[id].effectDisplay) tmp.upgrades[layer][id].effectDisplay = data2[id].effectDisplay(tmp.upgrades[layer][id].effect)
+ if(data2[id].desc) tmp.upgrades[layer][id].desc = data2[id].desc()
+
+ tmp.upgrades[layer][id].cost = data2[id].cost()
+
+ }
+ }
+}
+
+function updateMilestoneTemp(layer) {
+ if (player[layer] === undefined) return
+ if (!tmp.milestones[layer]) tmp.milestones[layer] = {}
+
+ let data2 = layers[layer].milestones
+ for (id in data2) {
+ tmp.milestones[layer][id] = {}
+ tmp.milestones[layer][id].done = data2[id].done()
+ if(data2[id].requirementDesc) tmp.milestones[layer][id].requirementDesc = data2[id].requirementDesc()
+ if(data2[id].effectDesc) tmp.milestones[layer][id].effectDesc = data2[id].effectDesc()
+ }
+}
+
+function updateBuyableTemp(layer) {
+ if (player[layer] === undefined) return
+ if (!tmp.buyables[layer]) tmp.buyables[layer] = {}
+ let data2 = layers[layer].buyables
+ if(data2.respecText) tmp.buyables[layer].respecText = data2.respecText()
+ for (let row = 1; row <= data2.rows; row++) {
+ for (let col = 1; col <= data2.cols; col++) {
+ let id = row * 10 + col
+ let amt = player[layer].buyables[id]
+ tmp.buyables[layer][id] = {}
+ tmp.buyables[layer][id].unl = data2[id].unl()
+ if(data2[id].effect) tmp.buyables[layer][id].effect = data2[id].effect(amt)
+ tmp.buyables[layer][id].cost = data2[id].cost(amt)
+ tmp.buyables[layer][id].canAfford = data2[id].canAfford()
+ if(data2[id].title) tmp.buyables[layer][id].title = data2[id].title()
+ if(data2[id].display) tmp.buyables[layer][id].display = data2[id].display()
+ }
+ }
}
\ No newline at end of file
diff --git a/js/v.js b/js/v.js
index 489a039..8fecd99 100644
--- a/js/v.js
+++ b/js/v.js
@@ -16,12 +16,12 @@ function loadVue() {
v-bind:class="{
treeNode: true,
[layer]: true,
- hidden: !layers[layer].layerShown(),
- locked: !player[layer].unl && !tmp.layerAmt[layer].gte(tmp.layerReqs[layer]),
+ hidden: !tmp.layerShown[layer],
+ locked: player[layer].unl && !tmp.layerAmt[layer].gte(tmp.layerReqs[layer]),
can: layerUnl(layer),
}"
v-bind:style="{
- 'background-color': layers[layer].color,
+ 'background-color': tmp.layerColor[layer],
}">
{{abb}}
@@ -34,13 +34,13 @@ function loadVue() {
@@ -124,12 +128,12 @@ function loadVue() {
template: `
`
@@ -139,7 +143,7 @@ function loadVue() {
Vue.component('display-text', {
props: ['layer', 'data'],
template: `
- {{data()}}
+ {{readData(data)}}
`
})
@@ -147,7 +151,7 @@ function loadVue() {
Vue.component('raw-html', {
props: ['layer', 'data'],
template: `
-
+
`
})
@@ -164,7 +168,6 @@ function loadVue() {
data: {
player,
tmp,
- layers,
Decimal,
format,
formatWhole,
diff --git a/sampleLayers.js b/sampleLayers.js
deleted file mode 100644
index c7574d9..0000000
--- a/sampleLayers.js
+++ /dev/null
@@ -1,213 +0,0 @@
-var layers = {
- c: {
- startData() { return {
- unl: true,
- points: new Decimal(0),
- best: new Decimal(0),
- total: new Decimal(0),
- order: 0, // Used for tracking other relevant layers unlocked before this one
- beep:false,
- }},
- color: "#4BEC13",
- requires() {return new Decimal(10)}, // Can be a function that takes requirement increases into account
- resource: "lollipops", // Name of prestige currency
- baseResource: "candies", // Name of resource prestige is based on
- baseAmount() {return player.points},
- 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))
- resCeil: false, // True if the resource needs to be rounded up
- canBuyMax() {}, // Only needed for static layers
- gainMult() {
- mult = new Decimal(1)
- if (player.c.upgrades.includes(21)) mult = mult.times(2)
- if (player.c.upgrades.includes(23)) mult = mult.times(LAYER_UPGS.c[23].currently())
- return mult
- },
- gainExp() {
- return new Decimal(1)
- },
- row: 0,
- 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.c.points, 0.2)),
- icecreamCap: (player.c.points * 10)
- }},
- effectDescription() {
- eff = layers.c.effect();
- return "which are boosting waffles by "+format(eff.waffleBoost)+" and increasing the Ice Cream cap by "+format(eff.icecreamCap)
- },
- doReset(layer){
- if(layers[layer].row > layers["c"].row) fullLayerReset('c') // This is actually the default behavior
- },
- upgrades: {
- rows: 1,
- cols: 3,
- 11: {
- desc: "Gain 1 Candy every second.",
- cost: new Decimal(1),
- unl() { return player.c.unl },
- },
- 12: {
- desc: "Candy generation is faster based on your unspent Lollipops.",
- cost: new Decimal(1),
- unl() { return player.c.upgrades.includes(11) },
- effect() {
- let ret = player.c.points.add(1).pow(player.c.upgrades.includes(24)?1.1:(player.c.upgrades.includes(14)?0.75:0.5))
- if (ret.gte("1e20000000")) ret = ret.sqrt().times("1e10000000")
- return ret;
- },
- effDisp(fx) { return format(fx)+"x" },
- },
- 13: {
- desc: "Make this layer act like you bought it first.",
- cost: new Decimal(69),
- currencyDisplayName: "candies", // Use if using a nonstandard currency
- currencyInternalName: "points", // Use if using a nonstandard currency
- currencyLayer: "", // Leave empty if not in a layer "e.g. points"
- unl() { return player.c.upgrades.includes(12) },
- onPurchase() {
- player.c.order = 0
- }
- },
- },
- milestones: {
- 0: {requirementDesc: "3 Lollipops",
- done() {return player.c.best.gte(3)},
- effectDesc: "Makes this green",
- },
- 1: {requirementDesc: "4 Lollipops",
- done() {return player.c.best.gte(4)},
- effectDesc: "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"]
- ],
- }
- },
- challs: {
- rows: 1,
- cols: 1,
- 11: {
- name: "Fun",
- desc: "Makes the game 0% harder",
- unl() { return player.c.best.gt(0) },
- goal: new Decimal("20"),
- currencyDisplayName: "lollipops", // Use if using a nonstandard currency
- currencyInternalName: "points", // Use if using a nonstandard currency
- currencyLayer: "c", // Leave empty if not in a layer
- effect() {
- let ret = player.c.points.add(1).tetrate(0.02)
- return ret;
- },
- effDisp(x) { return format(x)+"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.
- reward: "Says hi",
- onComplete() {console.log("hiii")} // Called when you complete the challenge
- },
- },
- buyables: {
- rows: 1,
- cols: 1,
- respec() { // Optional, reset things and give back your currency. Having this function makes a respec button appear
- player.c.points = player.c.points.add(player.c.spentOnBuyables) // A built-in thing to keep track of this but only keeps a single value
- resetBuyables("c")
- doReset("c", true) // Force a reset
- },
- respecText: "Respec Thingies", // Text on Respec button, optional
- 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 (){
- let data = tmp.buyables.c["11"]
- return "Cost: " + format(data.cost) + " lollipops\n\
- Amount: " + player.c.buyables["11"] + "\n\
- Adds + " + format(data.effects.first) + " things and multiplies stuff by " + format(data.effects.second)
- },
- unl() { return player.c.unl },
- canAfford() {return player.c.points.gte(tmp.buyables.c[11].cost)},
- buy() {
- cost = tmp.buyables.c[11].cost
- player.c.points = player.c.points.sub(cost)
- player.c.buyables[11] = player.c.buyables[11].add(1)
- player.c.spentOnBuyables = player.c.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
- },
- },
- convertToDecimal() {
- // Convert any layer-specific values (besides points, total, and best) to Decimal after loading
- },
- layerShown() {return true}, // Condition for when layer appears
- update(diff) {
- if (player.c.upgrades.includes(11)) player.points = player.points.add(tmp.pointGen.times(diff)).max(0)
- }, // Do any gameloop things (e.g. resource generation) inherent to this layer
- automate() {}, // Do any automation inherent to this layer if appropriate
- updateTemp() {}, // Do any necessary temp updating
- 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", desc: "C: reset for lollipops or whatever", onPress(){if (player.c.unl) doReset("c")}},
- {key: "ctrl+c", desc: "Ctrl+c: respec things", onPress(){if (player.c.unl) respecBuyables("c")}},
- ],
- incr_order: [], // Array of layer names to have their order increased when this one is first unlocked
- branches: [], // Each pair corresponds to a line added to the tree when this node is unlocked. The letter is the other end of the line, and the number affects the color, 1 is default
-
- // Optional, lets you format the tab yourself by listing components. You can create more in v.js.
- tabFormat: ["main-display",
- ["prestige-button", function(){return "Melt your points into "}],
- ["raw-html", function() {return ""}],
- ["display-text",
- function() {return 'I have ' + format(player.points) + ' pointy points!'},
- {"color": "red", "font-size": "32px", "font-family": "Comic Sans MS"}],
- "blank",
- ["toggle", ["c", "beep"]],
- "milestones", "blank", "blank", "upgrades"] ,
- style: {
- 'background-color': 'blue'
- },
- },
- f: { // This layer contains a more minimal set of things, besides a branch and "boop"
- startData() { return {
- unl: false,
- points: new Decimal(0),
- boop: false,
- }},
- color: "#FE0102",
- requires() {return new Decimal(200)},
- resource: "stuff",
- baseResource: "points",
- baseAmount() {return player.points},
- type: "normal",
- exponent: 0.5,
- gainMult() {
- return new Decimal(1)
- },
- gainExp() {
- return new Decimal(1)
- },
- row: 1,
- layerShown() {return true}, // Condition for when layer appears
- branches: [["c", 1]] // Each pair corresponds to a line added to the tree when this node is unlocked. The letter is the other end of the line, and the number affects the color, 1 is default
- },
-}
-
-function layerShown(layer){
- return layers[layer].layerShown();
-}
-
-const LAYERS = Object.keys(layers);
\ No newline at end of file