diff --git a/js/layers.js b/js/layers.js
index 7e595e4982..1147edd157 100644
--- a/js/layers.js
+++ b/js/layers.js
@@ -19,7 +19,9 @@ addLayer("p", {
if (hasUpgrade("b", 11)) mult = mult.times(upgradeEffect("b", 11));
if (hasUpgrade("g", 11)) mult = mult.times(upgradeEffect("g", 11));
if (player.t.unlocked) mult = mult.times(tmp.t.enEff);
- if (player.e.unlocked) mult = mult.times(tmp.e.buyables[11].effect.first);
+ // At the start of the the game, effects may be uninitialised,
+ // returning Decimal.dOne instead of the expected object.
+ if (player.e.unlocked) mult = mult.times(tmp.e.buyables[11].effect.first ?? Decimal.dOne);
if (player.s.unlocked) mult = mult.times(buyableEffect("s", 11));
if (hasUpgrade("e", 12)) mult = mult.times(upgradeEffect("e", 12));
if (hasUpgrade("b", 31)) mult = mult.times(upgradeEffect("b", 31));
@@ -310,7 +312,9 @@ addLayer("b", {
if (hasUpgrade("b", 12)) base = base.plus(upgradeEffect("b", 12));
if (hasUpgrade("b", 13)) base = base.plus(upgradeEffect("b", 13));
if (hasUpgrade("t", 11)) base = base.plus(upgradeEffect("t", 11));
- if (hasUpgrade("e", 11)) base = base.plus(upgradeEffect("e", 11).b);
+ // At the start of the the game, upgradeEffects might be uninitialised,
+ // returning Decimal.dOne instead of the expected object.
+ if (hasUpgrade("e", 11)) base = base.plus(upgradeEffect("e", 11).b ?? Decimal.dZero);
if (player.e.unlocked) base = base.plus(layers.e.buyables[11].effect().second);
if (player.s.unlocked) base = base.plus(buyableEffect("s", 12));
if (hasUpgrade("t", 25)) base = base.plus(upgradeEffect("t", 25));
@@ -582,7 +586,9 @@ addLayer("g", {
// ADD
if (hasUpgrade("g", 12)) base = base.plus(upgradeEffect("g", 12));
if (hasUpgrade("g", 13)) base = base.plus(upgradeEffect("g", 13));
- if (hasUpgrade("e", 11)) base = base.plus(upgradeEffect("e", 11).g);
+ // At the start of the the game, upgradeEffects might be uninitialised,
+ // returning Decimal.dOne instead of the expected object.
+ if (hasUpgrade("e", 11)) base = base.plus(upgradeEffect("e", 11).g ?? Decimal.dZero);
if (player.e.unlocked) base = base.plus(layers.e.buyables[11].effect().second);
if (player.s.unlocked) base = base.plus(buyableEffect("s", 12));
@@ -909,7 +915,10 @@ addLayer("t", {
autoExt: false,
}},
color: "#006609",
- requires() { return new Decimal(1e120).times(Decimal.pow("1e180", Decimal.pow(player[this.layer].unlockOrder, 1.415038))) }, // Can be a function that takes requirement increases into account
+ requires() {
+ // At the start of the game, unlockOrder might be undefined.
+ return new Decimal(1e120).times(Decimal.pow("1e180", Decimal.pow(player[this.layer].unlockOrder ?? 0, 1.415038)))
+ }, // Can be a function that takes requirement increases into account
resource: "time capsules", // Name of prestige currency
baseResource: "points", // Name of resource prestige is based on
baseAmount() {return player.points}, // Get the current amount of baseResource
@@ -2485,7 +2494,9 @@ addLayer("sb", {
if (player.o.unlocked) base = base.times(buyableEffect("o", 12));
if (((Array.isArray(tmp.ma.mastered))?tmp.ma.mastered.includes('b'):false) && hasUpgrade("b", 12)) base = base.times(upgradeEffect("b", 12).max(1));
if (((Array.isArray(tmp.ma.mastered))?tmp.ma.mastered.includes('b'):false) && hasUpgrade("b", 13)) base = base.times(upgradeEffect("b", 13).max(1));
- base = base.times(tmp.n.dustEffs.blue);
+ // At the start of the the game, dustEffs might not be initialized,
+ // returning Decimal.dOne instead of the expected object.
+ base = base.times(tmp.n.dustEffs.blue ?? Decimal.dOne);
if (((Array.isArray(tmp.ma.mastered))?tmp.ma.mastered.includes("h"):false) && hasChallenge("h", 12)) base = base.times(player.hs.points.plus(1));
if (player.en.unlocked) base = base.pow(tmp.en.swEff);
if (player.c.unlocked && tmp.c) base = base.pow(tmp.c.eff5);
@@ -2632,7 +2643,9 @@ addLayer("h", {
exponent() { return new Decimal(((Array.isArray(tmp.ma.mastered))?tmp.ma.mastered.includes(this.layer):false)?.2:.125) }, // Prestige currency exponent
gainMult() { // Calculate the multiplier for main currency from bonuses
mult = new Decimal(1)
- if (hasUpgrade("q", 14)) mult = mult.times(upgradeEffect("q", 14).h);
+ // At the start of the the game, upgradeEffects might be uninitialised,
+ // returning Decimal.dOne instead of the expected object.
+ if (hasUpgrade("q", 14)) mult = mult.times(upgradeEffect("q", 14).h ?? Decimal.dOne);
if (player.m.unlocked) mult = mult.times(((Array.isArray(tmp.ma.mastered))?tmp.ma.mastered.includes("m"):false)?tmp.m.mainHexEff:tmp.m.hexEff);
if (hasUpgrade("ba", 22)) mult = mult.times(tmp.ba.negBuff);
return mult
@@ -2808,7 +2821,9 @@ addLayer("h", {
currencyInternalName: "points",
rewardDescription() { return "Timeless completions boost Super Generator Power gain based on your time "+(hasUpgrade("ss", 33)?"playing this game.":"in this Row 4 reset.") },
rewardEffect() {
- let eff = Decimal.div(9, Decimal.add((hasUpgrade("ss", 33)?(player.timePlayed||0):player.q.time), 1).cbrt().pow(hasUpgrade("ss", 23)?(-1):1)).plus(1).pow(challengeCompletions("h", 31)).times(tmp.n.realDustEffs2?tmp.n.realDustEffs2.blueOrange:new Decimal(1)).pow(((Array.isArray(tmp.ma.mastered))?tmp.ma.mastered.includes(this.layer):false)?5:1);
+ // At the start of the the game, dustEffs might be uninitialised,
+ // returning Decimal.dOne instead of the expected object.
+ let eff = Decimal.div(9, Decimal.add((hasUpgrade("ss", 33)?(player.timePlayed||0):player.q.time), 1).cbrt().pow(hasUpgrade("ss", 23)?(-1):1)).plus(1).pow(challengeCompletions("h", 31)).times(tmp.n.realDustEffs2.blueOrange ?? Decimal.dOne).pow(((Array.isArray(tmp.ma.mastered))?tmp.ma.mastered.includes(this.layer):false)?5:1);
if (!eff.eq(eff)) eff = new Decimal(1);
return eff;
},
@@ -2851,7 +2866,9 @@ addLayer("h", {
currencyInternalName: "points",
rewardDescription: "Option D completions multiply the Time Energy gain base.",
rewardEffect() {
- let eff = softcap("option_d", Decimal.pow(100, Decimal.pow(challengeCompletions("h", 32), 2))).times(tmp.n.realDustEffs2?tmp.n.realDustEffs2.blueOrange:new Decimal(1));
+ // At the start of the the game, dustEffs might be uninitialised,
+ // returning Decimal.dOne instead of the expected object.
+ let eff = softcap("option_d", Decimal.pow(100, Decimal.pow(challengeCompletions("h", 32), 2))).times(tmp.n.realDustEffs2.blueOrange ?? Decimal.dOne);
if (!eff.eq(eff)) eff = new Decimal(1);
return eff;
},
@@ -2938,7 +2955,9 @@ addLayer("q", {
exponent() { return new Decimal(((Array.isArray(tmp.ma.mastered))?tmp.ma.mastered.includes(this.layer):false)?.008:.0075) }, // Prestige currency exponent
gainMult() { // Calculate the multiplier for main currency from bonuses
mult = new Decimal(1)
- if (hasUpgrade("q", 14)) mult = mult.times(upgradeEffect("q", 14).q);
+ // At the start of the the game, upgradeEffects might be uninitialised,
+ // returning Decimal.dOne instead of the expected object.
+ if (hasUpgrade("q", 14)) mult = mult.times(upgradeEffect("q", 14).q || Decimal.dOne);
mult = mult.times(improvementEffect("q", 33));
if (player.m.unlocked) mult = mult.times(((Array.isArray(tmp.ma.mastered))?tmp.ma.mastered.includes("m"):false)?tmp.m.mainHexEff:tmp.m.hexEff);
if (hasUpgrade("ba", 22)) mult = mult.times(tmp.ba.negBuff);
@@ -3650,7 +3669,8 @@ addLayer("o", {
title: "Solar Cores",
gain() { return player.o.points.div(2).root(1.5).pow(tmp.o.buyableGainExp).floor() },
effect() {
- let amt = player[this.layer].buyables[this.id].times(tmp.o.multiplyBuyables)
+ // At the start of the the game, multiplyBuyables might be undefined.
+ let amt = player[this.layer].buyables[this.id].times(tmp.o.multiplyBuyables ?? Decimal.dZero)
amt = softcap("solCores2", softcap("solCores", amt));
return Decimal.pow(hasUpgrade("ss", 22)?(amt.plus(1).pow(tmp.o.solPow).cbrt()):(amt.plus(1).pow(tmp.o.solPow).log10().plus(1)), ((Array.isArray(tmp.ma.mastered))?tmp.ma.mastered.includes(this.layer):false)?1.1:1)
},
@@ -3678,7 +3698,10 @@ addLayer("o", {
12: {
title: "Tachoclinal Plasma",
gain() { return player.o.points.div(100).times(player.o.energy.div(2500)).root(3.5).pow(tmp.o.buyableGainExp).floor() },
- effect() { return Decimal.pow(hasUpgrade("p", 24)?Decimal.pow(10, player[this.layer].buyables[this.id].times(tmp.o.multiplyBuyables).plus(1).log10().cbrt()):(player[this.layer].buyables[this.id].times(tmp.o.multiplyBuyables).plus(1).pow(tmp.o.solPow).log10().plus(1).log10().times(10).plus(1)), ((Array.isArray(tmp.ma.mastered))?tmp.ma.mastered.includes(this.layer):false)?1.1:1) },
+ effect() {
+ // At the start of the game, multiplyBuyables might be undefined.
+ return Decimal.pow(hasUpgrade("p", 24)?Decimal.pow(10, player[this.layer].buyables[this.id].times(tmp.o.multiplyBuyables ?? Decimal.dZero).plus(1).log10().cbrt()):(player[this.layer].buyables[this.id].times(tmp.o.multiplyBuyables).plus(1).pow(tmp.o.solPow).log10().plus(1).log10().times(10).plus(1)), ((Array.isArray(tmp.ma.mastered))?tmp.ma.mastered.includes(this.layer):false)?1.1:1)
+ },
display() { // Everything else displayed in the buyable button after the title
let data = tmp[this.layer].buyables[this.id]
let display = ("Sacrifice all of your Solarity & Solar Energy for "+formatWhole(tmp[this.layer].buyables[this.id].gain)+" Tachoclinal Plasma\n"+
@@ -3703,7 +3726,10 @@ addLayer("o", {
13: {
title: "Convectional Energy",
gain() { return player.o.points.div(1e3).times(player.o.energy.div(2e5)).times(player.ss.subspace.div(10)).root(6.5).pow(tmp.o.buyableGainExp).floor() },
- effect() { return player[this.layer].buyables[this.id].times(tmp.o.multiplyBuyables).plus(1).pow(tmp.o.solPow).log10().plus(1).pow(2.5).pow(((Array.isArray(tmp.ma.mastered))?tmp.ma.mastered.includes(this.layer):false)?27.5:1) },
+ effect() {
+ // At the start of the game, multiplyBuyables might be undefined.
+ return player[this.layer].buyables[this.id].times(tmp.o.multiplyBuyables ?? Decimal.dZero).plus(1).pow(tmp.o.solPow).log10().plus(1).pow(2.5).pow(((Array.isArray(tmp.ma.mastered))?tmp.ma.mastered.includes(this.layer):false)?27.5:1)
+ },
display() { // Everything else displayed in the buyable button after the title
let data = tmp[this.layer].buyables[this.id]
let display = ("Sacrifice all of your Solarity, Solar Energy, & Subspace for "+formatWhole(tmp[this.layer].buyables[this.id].gain)+" Convectional Energy\n"+
@@ -3730,7 +3756,8 @@ addLayer("o", {
title: "Coronal Waves",
gain() { return player.o.points.div(1e5).root(5).times(player.o.energy.div(1e30).root(30)).times(player.ss.subspace.div(1e8).root(8)).times(player.q.energy.div("1e675").root(675)).pow(tmp.o.buyableGainExp).floor() },
effect() {
- let eff = player[this.layer].buyables[this.id].times(tmp.o.multiplyBuyables).plus(1).pow(tmp.o.solPow).log10().plus(1).log10();
+ // At the start of the game, multiplyBuyables might be undefined.
+ let eff = player[this.layer].buyables[this.id].times(tmp.o.multiplyBuyables ?? Decimal.dZero).plus(1).pow(tmp.o.solPow).log10().plus(1).log10();
eff = softcap("corona", eff);
if (hasUpgrade("hn", 24)) eff = eff.times(2);
if ((Array.isArray(tmp.ma.mastered))?tmp.ma.mastered.includes(this.layer):false) eff = eff.times(1.4);
@@ -3763,7 +3790,8 @@ addLayer("o", {
title: "Noval Remnants",
gain() { return player.o.buyables[11].div(1e150).pow(3).pow(tmp.o.buyableGainExp).floor() },
effect() {
- return player[this.layer].buyables[this.id].times(tmp.o.multiplyBuyables).plus(1).pow(tmp.o.solPow).log10().root(10).times(((Array.isArray(tmp.ma.mastered))?tmp.ma.mastered.includes(this.layer):false)?1.4:1).plus(1)
+ // At the start of the game, multiplyBuyables might be undefined.
+ return player[this.layer].buyables[this.id].times(tmp.o.multiplyBuyables ?? Decimal.dZero).plus(1).pow(tmp.o.solPow).log10().root(10).times(((Array.isArray(tmp.ma.mastered))?tmp.ma.mastered.includes(this.layer):false)?1.4:1).plus(1)
},
display() {
let data = tmp[this.layer].buyables[this.id]
@@ -3788,7 +3816,8 @@ addLayer("o", {
title: "Nuclear Forges",
gain() { return player.o.buyables[11].div(1e175).times(player.o.energy.div("1e2500").root(10)).pow(tmp.o.buyableGainExp).floor() },
effect() {
- return player[this.layer].buyables[this.id].times(tmp.o.multiplyBuyables).plus(1).pow(tmp.o.solPow).log10().plus(1).log10().root(2.5).times(((Array.isArray(tmp.ma.mastered))?tmp.ma.mastered.includes(this.layer):false)?1.4:1)
+ // At the start of the game, multiplyBuyables might be undefined.
+ return player[this.layer].buyables[this.id].times(tmp.o.multiplyBuyables ?? Decimal.dZero).plus(1).pow(tmp.o.solPow).log10().plus(1).log10().root(2.5).times(((Array.isArray(tmp.ma.mastered))?tmp.ma.mastered.includes(this.layer):false)?1.4:1)
},
display() {
let data = tmp[this.layer].buyables[this.id]
@@ -3814,7 +3843,8 @@ addLayer("o", {
title: "Blueshifted Flares",
gain() { return player.o.points.div("1e400").pow(10).pow(tmp.o.buyableGainExp).floor() },
effect() {
- return player[this.layer].buyables[this.id].times(tmp.o.multiplyBuyables).plus(1).pow(tmp.o.solPow).log10().plus(1).log10().root(5).div(10).times(((Array.isArray(tmp.ma.mastered))?tmp.ma.mastered.includes(this.layer):false)?1.9:1)
+ // At the start of the game, multiplyBuyables might be undefined.
+ return player[this.layer].buyables[this.id].times(tmp.o.multiplyBuyables ?? Decimal.dZero).plus(1).pow(tmp.o.solPow).log10().plus(1).log10().root(5).div(10).times(((Array.isArray(tmp.ma.mastered))?tmp.ma.mastered.includes(this.layer):false)?1.9:1)
},
display() {
let data = tmp[this.layer].buyables[this.id]
@@ -3839,7 +3869,8 @@ addLayer("o", {
title: "Combustion Gas",
gain() { return player.o.energy.div("1e200000").root(100).pow(tmp.o.buyableGainExp).floor() },
effect() {
- return player[this.layer].buyables[this.id].times(tmp.o.multiplyBuyables).plus(1).pow(tmp.o.solPow).log10().plus(1).log10().plus(1).log10().div(1.6).times(((Array.isArray(tmp.ma.mastered))?tmp.ma.mastered.includes(this.layer):false)?1.9:1).plus(1)
+ // At the start of the game, multiplyBuyables might be undefined.
+ return player[this.layer].buyables[this.id].times(tmp.o.multiplyBuyables ?? Decimal.dZero).plus(1).pow(tmp.o.solPow).log10().plus(1).log10().plus(1).log10().div(1.6).times(((Array.isArray(tmp.ma.mastered))?tmp.ma.mastered.includes(this.layer):false)?1.9:1).plus(1)
},
display() {
let data = tmp[this.layer].buyables[this.id]
@@ -3864,7 +3895,8 @@ addLayer("o", {
title: "Thermonuclear Reactants",
gain() { return player.o.points.div("1e500").pow(10).pow(tmp.o.buyableGainExp).floor() },
effect() {
- return player[this.layer].buyables[this.id].times(tmp.o.multiplyBuyables).plus(1).pow(tmp.o.solPow).log10().plus(1).log10().plus(1).log10().div(3).times(((Array.isArray(tmp.ma.mastered))?tmp.ma.mastered.includes(this.layer):false)?1.9:1);
+ // At the start of the game, multiplyBuyables might be undefined.
+ return player[this.layer].buyables[this.id].times(tmp.o.multiplyBuyables || Decimal.dZero).plus(1).pow(tmp.o.solPow).log10().plus(1).log10().plus(1).log10().div(3).times(((Array.isArray(tmp.ma.mastered))?tmp.ma.mastered.includes(this.layer):false)?1.9:1);
},
display() {
let data = tmp[this.layer].buyables[this.id]
@@ -4161,7 +4193,9 @@ addLayer("m", {
gainMult() { // Calculate the multiplier for main currency from bonuses
mult = new Decimal(1);
if (hasAchievement("a", 74)) mult = mult.times(challengeEffect("h", 32));
- return mult.times(tmp.n.realDustEffs2?tmp.n.realDustEffs2.purpleBlue:new Decimal(1));
+ // At the start of the the game, dustEffs might be uninitialised,
+ // returning Decimal.dOne instead of the expected object.
+ return mult.times(tmp.n.realDustEffs2.purpleBlue ?? Decimal.dOne);
},
gainExp() { // Calculate the exponent on main currency from bonuses
return new Decimal(1)
@@ -4560,7 +4594,9 @@ addLayer("ba", {
dirBase() { return player.ba.points.times(10) },
posGainMult() {
let mult = new Decimal(1);
- if (hasUpgrade("ba", 24)) mult = mult.times(upgradeEffect("ba", 24).pos);
+ // At the start of the the game, upgradeEffects might be uninitialised,
+ // returning Decimal.dOne instead of the expected object.
+ if (hasUpgrade("ba", 24)) mult = mult.times(upgradeEffect("ba", 24).pos ?? Decimal.dOne);
return mult;
},
posGain() { return Decimal.pow(tmp.ba.dirBase, (hasMilestone("hn", 2)&&player.ma.current!="ba")?1:player.ba.allotted).times((hasMilestone("hn", 2)&&player.ma.current!="ba")?1:(player.ba.allotted)).times(tmp.ba.posGainMult) },
@@ -4575,7 +4611,15 @@ addLayer("ba", {
posNerf() { return tmp.ba.noNerfs?new Decimal(1):(player.ba.pos.plus(1).sqrt().pow(inChallenge("h", 41)?100:1)) },
negGainMult() {
let mult = new Decimal(1);
- if (hasUpgrade("ba", 24)) mult = mult.times(upgradeEffect("ba", 24).neg);
+ // At the start of the the game, upgradeEffects might be uninitialised,
+ // returning Decimal.dOne instead of the expected object.
+ // That Decimal has a .neg method, which is easily confusable for the
+ // .neg property of the intended object! Only apply the effect if
+ // .neg _isn't_ a function.
+ if (hasUpgrade("ba", 24)) {
+ const effect = upgradeEffect("ba", 24).neg;
+ if (typeof effect !== "function") mult = mult.times(effect);
+ }
return mult;
},
negGain() { return Decimal.pow(tmp.ba.dirBase, (hasMilestone("hn", 2)&&player.ma.current!="ba")?1:(1-player.ba.allotted)).times((hasMilestone("hn", 2)&&player.ma.current!="ba")?1:(1-player.ba.allotted)).times(tmp.ba.negGainMult) },
@@ -4888,7 +4932,9 @@ addLayer("ps", {
if (tmp.ps.buyables[11].effects.damned) mult = mult.times(tmp.ps.buyables[11].effects.damned||1);
if (player.i.buyables[11].gte(1)) mult = mult.times(buyableEffect("s", 16));
if (player.c.unlocked) mult = mult.times(tmp.c.eff4);
- return mult.times(tmp.n.dustEffs.purple);
+ // At the start of the the game, dustEffs might be uninitialised,
+ // returning Decimal.dOne instead of the expected object.
+ return mult.times(tmp.n.dustEffs.purple ?? Decimal.dOne);
},
soulGain() {
let gain = (((Array.isArray(tmp.ma.mastered))?tmp.ma.mastered.includes(this.layer):false)?Decimal.pow(tmp.ps.soulGainExp, player.ps.points):Decimal.pow(player.ps.points, tmp.ps.soulGainExp)).div(9.4).times(layers.ps.soulGainMult());
@@ -4912,7 +4958,11 @@ addLayer("ps", {
let eff = player.ps.souls.plus(1).pow(layers.ps.soulEffExp());
return eff;
},
- powerGain() { return player.ps.souls.plus(1).times(tmp.ps.buyables[21].effect).times(tmp.n.dustEffs.purple) },
+ powerGain() {
+ // At the start of the the game, dustEffs might be uninitialised,
+ // returning Decimal.dOne instead of the expected object.
+ return player.ps.souls.plus(1).times(tmp.ps.buyables[21].effect).times(tmp.n.dustEffs.purple ?? Decimal.dOne)
+ },
powerExp() { return player.ps.points.sqrt().times(tmp.ps.buyables[21].effect) },
tabFormat: {
"Main Tab": {