Your Replicanti cap has been removed due to the second {{ scrambledText }} milestone.
diff --git a/src/core/celestials/pelle/pelle.js b/src/core/celestials/pelle/pelle.js
index 36e4d2216c..9e5d5dbd18 100644
--- a/src/core/celestials/pelle/pelle.js
+++ b/src/core/celestials/pelle/pelle.js
@@ -191,7 +191,7 @@ export const Pelle = {
},
get uselessTimeStudies() {
- return [32, 33, 41, 51, 61, 62, 121, 122, 123, 141, 142, 143, 192, 213];
+ return [32, 33, 41, 51, 61, 62, 121, 122, 123, 141, 142, 143, 213];
},
get disabledRUPGs() {
@@ -217,7 +217,7 @@ export const Pelle = {
? Currency.eternityPoints.value.plus(1).pow(0.3)
: DC.D1,
replication: isActive("replication")
- ? 10 ** 53 ** (PelleRifts.vacuum.percentage)
+ ? Math.min(1e308, 10 ** 53 ** (PelleRifts.vacuum.percentage))
: 1,
dilation: isActive("dilation")
? Decimal.pow(player.dilation.totalTachyonGalaxies, 1.5).max(1)
@@ -241,7 +241,7 @@ export const Pelle = {
return `Eternity Point gain ${formatX(Currency.eternityPoints.value.plus(1).pow(0.3), 2)}
(based on current EP)`;
case "replication":
- return `Replication speed ${formatX(10 ** 53 ** (PelleRifts.vacuum.percentage), 2)} \
+ return `Replication speed ${formatX(Math.min(1e308, 10 ** 53 ** (PelleRifts.vacuum.percentage)), 2)} \
(based on ${wordShift.wordCycle(PelleRifts.vacuum.name)})`;
case "dilation":
return `Dilated Time gain ${formatX(Decimal.pow(player.dilation.totalTachyonGalaxies, 1.5).max(1), 2)}
diff --git a/src/core/perks.js b/src/core/perks.js
index d1e5ac491a..b611fd2501 100644
--- a/src/core/perks.js
+++ b/src/core/perks.js
@@ -58,6 +58,14 @@ class PerkState extends SetPurchasableMechanicState {
GameCache.buyablePerks.invalidate();
EventHub.dispatch(GAME_EVENT.PERK_BOUGHT);
}
+
+ purchase() {
+ if (this.label === "ACHNR" && RealityUpgrade(8).isLockingMechanics) {
+ RealityUpgrade(8).tryShowWarningModal();
+ return;
+ }
+ super.purchase();
+ }
}
export const Perk = mapGameDataToObject(
diff --git a/src/core/secret-formula/achievements/normal-achievements.js b/src/core/secret-formula/achievements/normal-achievements.js
index 624e762101..e031a3cb84 100644
--- a/src/core/secret-formula/achievements/normal-achievements.js
+++ b/src/core/secret-formula/achievements/normal-achievements.js
@@ -1339,7 +1339,7 @@ export const normalAchievements = [
checkEvent: GAME_EVENT.INFINITY_CHALLENGE_COMPLETED,
// Weirdly specific reward? Yes, its V's ST bonus because we forgot to disable it
// when balancing Pelle and only realised too late.
- get reward() { return `All Antimatter Dimensions are raised to ${formatPow(1.0812403840463596, 0, 3)}`; },
+ get reward() { return `All Antimatter Dimensions are raised to ${formatPow(1.0812403840463596, 0, 3)}.`; },
effect: 1.0812403840463596
},
{
diff --git a/src/core/secret-formula/celestials/pelle-upgrades.js b/src/core/secret-formula/celestials/pelle-upgrades.js
index 80fd7dfcb3..a480a44f21 100644
--- a/src/core/secret-formula/celestials/pelle-upgrades.js
+++ b/src/core/secret-formula/celestials/pelle-upgrades.js
@@ -102,7 +102,7 @@ export const pelleUpgrades = {
},
dimBoostResetsNothing: {
id: 7,
- description: "Dimension Boosts no longer reset anything",
+ description: "Dimension Boosts no longer reset anything. Galaxies only reset Dimension Boosts.",
cost: 1e11,
formatCost,
},
diff --git a/src/core/secret-formula/reality/reality-upgrades.js b/src/core/secret-formula/reality/reality-upgrades.js
index 8ddecdbcc4..a4d1c14926 100644
--- a/src/core/secret-formula/reality/reality-upgrades.js
+++ b/src/core/secret-formula/reality/reality-upgrades.js
@@ -105,7 +105,8 @@ export const realityUpgrades = [
checkRequirement: () => !player.reality.gainedAutoAchievements,
checkEvent: GAME_EVENT.ETERNITY_RESET_BEFORE,
canLock: true,
- // We don't have lockEvent because the modal can never show up for this upgrade
+ // This lock event can only be seen if you are attempting to get ACHNR with the lock on, so we can specify ACHNR here
+ lockEvent: "gain an automatic achievement (through ACHNR)",
description: "Tachyon Particle gain is boosted based on Achievement multiplier",
effect: () => Math.sqrt(Achievements.power),
formatEffect: value => formatX(value, 2, 2)
@@ -346,7 +347,7 @@ export const realityUpgrades = [
checkRequirement: () => MachineHandler.gainedRealityMachines.gte(5000) &&
Glyphs.activeWithoutCompanion.length === 0,
canLock: true,
- lockEvent: "equip a non-Companion Glyph",
+ lockEvent: () => `equip a non-Companion Glyph or Reality below ${formatInt(5000)} RM`,
checkEvent: GAME_EVENT.REALITY_RESET_BEFORE,
description: "Gain another Glyph slot",
effect: () => 1
diff --git a/src/game.js b/src/game.js
index 41a77d0f5e..37a6bdaf77 100644
--- a/src/game.js
+++ b/src/game.js
@@ -924,9 +924,9 @@ export function simulateTime(seconds, real, fast) {
const infinitiedMilestone = getInfinitiedMilestoneReward(totalGameTime * 1000);
const eternitiedMilestone = getEternitiedMilestoneReward(totalGameTime * 1000);
- if (eternitiedMilestone.gt(0)) {
+ if (eternitiedMilestone.gt(0) && !Pelle.isDoomed) {
Currency.eternities.add(eternitiedMilestone);
- } else if (infinitiedMilestone.gt(0)) {
+ } else if (infinitiedMilestone.gt(0) && !Pelle.isDoomed) {
Currency.infinities.add(infinitiedMilestone);
} else {
Currency.eternityPoints.add(getOfflineEPGain(seconds * 1000));
From 6a79b78502e9ae6a83d67eb0446b238392a98712 Mon Sep 17 00:00:00 2001
From: HexaVault <44529573+HexaVault@users.noreply.github.com>
Date: Sun, 7 Jun 2026 23:35:42 +0100
Subject: [PATCH 15/44] more fixes
---
.../antimatter-dimensions/AntimatterDimensionProgressBar.vue | 2 +-
src/components/tabs/celestial-pelle/PelleUpgrade.vue | 2 +-
src/core/automator/automator-backend.js | 1 +
src/core/secret-formula/catchup-resources.js | 2 +-
src/core/secret-formula/celestials/pelle-upgrades.js | 4 ++--
src/core/secret-formula/celestials/rifts.js | 2 +-
src/core/secret-formula/h2p.js | 3 ++-
7 files changed, 9 insertions(+), 7 deletions(-)
diff --git a/src/components/tabs/antimatter-dimensions/AntimatterDimensionProgressBar.vue b/src/components/tabs/antimatter-dimensions/AntimatterDimensionProgressBar.vue
index 5993219f88..563d2d3e40 100644
--- a/src/components/tabs/antimatter-dimensions/AntimatterDimensionProgressBar.vue
+++ b/src/components/tabs/antimatter-dimensions/AntimatterDimensionProgressBar.vue
@@ -34,7 +34,7 @@ export default {
// than normal and therefore default filling won't be meaningful. Since challenges get completed or abandoned from
// the inside outwards, we show the goals in that priority as well. It only makes sense to check cel6 and not the
// others because pre-cel3 completion it'll default to e4000 and cel4/5 don't have meaningful single goals
- const inSpecialRun = Player.isInAntimatterChallenge || EternityChallenge.isRunning || player.dilation.active ||
+ const inSpecialRun = Player.isInAntimatterChallenge || EternityChallenge.isRunning || (player.dilation.active && !Pelle.isDoomed) ||
Laitela.isRunning;
if (inSpecialRun) {
if (Player.isInAntimatterChallenge) {
diff --git a/src/components/tabs/celestial-pelle/PelleUpgrade.vue b/src/components/tabs/celestial-pelle/PelleUpgrade.vue
index 3491f7def7..7f462834cc 100644
--- a/src/components/tabs/celestial-pelle/PelleUpgrade.vue
+++ b/src/components/tabs/celestial-pelle/PelleUpgrade.vue
@@ -96,7 +96,7 @@ export default {
this.galaxyCap = GalaxyGenerator.generationCap;
const genDB = GameDatabase.celestials.pelle.galaxyGeneratorUpgrades;
this.notAffordable = (this.config === genDB.additive || this.config === genDB.multiplicative) &&
- (Decimal.gt(this.upgrade.cost, this.galaxyCap - GalaxyGenerator.generatedGalaxies + player.galaxies));
+ (Decimal.gt(this.upgrade.cost, this.galaxyCap - GalaxyGenerator.spentGalaxies + player.galaxies));
},
secondsUntilCost(rate) {
const value = this.galaxyGenerator ? player.galaxies + GalaxyGenerator.galaxies : Currency.realityShards.value;
diff --git a/src/core/automator/automator-backend.js b/src/core/automator/automator-backend.js
index 2004c5201e..8b5fba87c7 100644
--- a/src/core/automator/automator-backend.js
+++ b/src/core/automator/automator-backend.js
@@ -799,6 +799,7 @@ export const AutomatorBackend = {
// program flow to do something else other than simply advancing to the next line
switch (this.runCurrentCommand()) {
case AUTOMATOR_COMMAND_STATUS.NEXT_TICK_SAME_INSTRUCTION:
+ case AUTOMATOR_COMMAND_STATUS.SAME_INSTRUCTION:
break;
case AUTOMATOR_COMMAND_STATUS.HALT:
this.stop();
diff --git a/src/core/secret-formula/catchup-resources.js b/src/core/secret-formula/catchup-resources.js
index 7a21becc84..e500a0fadf 100644
--- a/src/core/secret-formula/catchup-resources.js
+++ b/src/core/secret-formula/catchup-resources.js
@@ -235,7 +235,7 @@ export const catchupResources = [
{
name: "Tesseracts",
id: 30,
- requiredStage: PROGRESS_STAGE.ENSLAVED,
+ requiredStage: PROGRESS_STAGE.V,
description: `Infinity Dimensions cannot be purchased indefinitely and all but the 8th have a hard limit for how
many times they can be purchased. Each Tesseract permanently increases this limit by a large amount.`
},
diff --git a/src/core/secret-formula/celestials/pelle-upgrades.js b/src/core/secret-formula/celestials/pelle-upgrades.js
index a480a44f21..50d963485a 100644
--- a/src/core/secret-formula/celestials/pelle-upgrades.js
+++ b/src/core/secret-formula/celestials/pelle-upgrades.js
@@ -176,7 +176,7 @@ export const pelleUpgrades = {
id: 19,
description: "Eternity Challenge completions no longer reset on Armageddon",
cost: 1e26,
- formatCost,
+ formatCost,c
},
dilationUpgradesNoReset: {
id: 20,
@@ -192,7 +192,7 @@ export const pelleUpgrades = {
},
replicantiGalaxyEM40: {
id: 22,
- description: "Replicanti Galaxies no longer reset anything they normally reset",
+ description: "Replicanti Galaxies no longer reset anything they normally reset, but still reduce Replicanti.",
cost: 1e30,
formatCost,
}
diff --git a/src/core/secret-formula/celestials/rifts.js b/src/core/secret-formula/celestials/rifts.js
index 7d882869e4..54174c62b0 100644
--- a/src/core/secret-formula/celestials/rifts.js
+++ b/src/core/secret-formula/celestials/rifts.js
@@ -158,7 +158,7 @@ export const pelleRifts = {
{
resource: "recursion",
requirement: 0.10,
- description: "Dimensional Boosts are more powerful based on EC completions",
+ description: "Dimension Boosts are more powerful based on EC completions",
effect: () => Math.max(100 * EternityChallenges.completions ** 2, 1) *
Math.max(1e4 ** (EternityChallenges.completions - 40), 1),
formatEffect: x => `Dimension Boost power ${formatX(x, 2, 2)}`
diff --git a/src/core/secret-formula/h2p.js b/src/core/secret-formula/h2p.js
index f71eeb56a4..76c233cc21 100644
--- a/src/core/secret-formula/h2p.js
+++ b/src/core/secret-formula/h2p.js
@@ -635,7 +635,8 @@ amount of antimatter before you can attempt them.
info: () => `
Replicanti are another resource you unlock at ${format(DC.E140)} IP. Rather
than producing something else, Replicanti actually produces
itself up to a maximum of
-${formatPostBreak(Number.MAX_VALUE, 2)}. Replicanti are produced at their own pace, unaffected by Tickspeed Upgrades.
+${formatPostBreak(Number.MAX_VALUE, 2)}${TimeStudy(192).isBought ? ", which is removed due to Time Study 192" : ""}.
+Replicanti are produced at their own pace, unaffected by Tickspeed Upgrades.
Each individual Replicanti has a certain chance (initially ${formatPercents(0.01)}) of producing another Replicanti
every Replicanti tick (initially every second), and both of these can be upgraded by spending IP.
From afa2f22af3ce29d054fafcb1d7d34dc67cb6d33e Mon Sep 17 00:00:00 2001
From: HexaVault <44529573+HexaVault@users.noreply.github.com>
Date: Sun, 7 Jun 2026 23:40:27 +0100
Subject: [PATCH 16/44] sacrifice while enslaved
---
src/core/sacrifice.js | 2 ++
1 file changed, 2 insertions(+)
diff --git a/src/core/sacrifice.js b/src/core/sacrifice.js
index 00c5c65355..6c15358402 100644
--- a/src/core/sacrifice.js
+++ b/src/core/sacrifice.js
@@ -19,6 +19,7 @@ export class Sacrifice {
if (DimBoost.purchasedBoosts < 5) return `Requires ${formatInt(5)} Dimension Boosts`;
if (AntimatterDimension(8).totalAmount.eq(0)) return "No 8th Antimatter Dimensions";
if (this.nextBoost.lte(1)) return `${formatX(1)} multiplier`;
+ if (Enslaved.isRunning) return "This Reality does not allow Sacrifices"
if (Player.isInAntimatterChallenge) return "Challenge goal reached";
return "Need to Crunch";
}
@@ -34,6 +35,7 @@ export class Sacrifice {
if (EternityChallenge(3).isRunning) return "Eternity Challenge 3";
if (DimBoost.purchasedBoosts < 5) return `Requires ${formatInt(5)} Dimension Boosts`;
if (AntimatterDimension(8).totalAmount.eq(0)) return "No 8th Antimatter Dimensions";
+ if (Enslaved.isRunning) return "This Reality does not allow Sacrifices"
if (Player.isInAntimatterChallenge) return "Challenge goal reached";
return "Need to Crunch";
}
From a0f251564c8461eeeee8c97b8fc4bf87bd4de138 Mon Sep 17 00:00:00 2001
From: HexaVault <44529573+HexaVault@users.noreply.github.com>
Date: Sun, 7 Jun 2026 23:43:49 +0100
Subject: [PATCH 17/44] codefactor
---
.../time-study-modal-preview/PseudoTimeStudyButton.vue | 6 +++---
.../AntimatterDimensionProgressBar.vue | 4 ++--
src/core/sacrifice.js | 4 ++--
src/core/secret-formula/celestials/pelle-upgrades.js | 2 +-
src/core/secret-formula/reality/reality-upgrades.js | 2 +-
5 files changed, 9 insertions(+), 9 deletions(-)
diff --git a/src/components/modals/time-study-modal-preview/PseudoTimeStudyButton.vue b/src/components/modals/time-study-modal-preview/PseudoTimeStudyButton.vue
index ef171dfcf6..14d94b611c 100644
--- a/src/components/modals/time-study-modal-preview/PseudoTimeStudyButton.vue
+++ b/src/components/modals/time-study-modal-preview/PseudoTimeStudyButton.vue
@@ -86,8 +86,8 @@ export default {
methods: {
update() {
const study = this.study;
- const isCurrentlyUseless = this.study.id == 192 && Pelle.isDoomed && PelleRifts.vacuum.milestones[1];
- this.isUseless = Pelle.isDoomed && (isCurrentlyUseless || Pelle.uselessTimeStudies.includes(this.study.id));
+ const isCurrentlyUseless = this.study.id === 192 && Pelle.isDoomed && PelleRifts.vacuum.milestones[1];
+ this.isUseless = Pelle.isDoomed && (isCurrentlyUseless || Pelle.uselessTimeStudies.includes(this.study.id));
this.isBought = ForceBoughtState.getState(this.forceIsBought, study.isBought);
this.doomedRealityStudy = study.type === TIME_STUDY_TYPE.DILATION && study.id === 6 && Pelle.isDoomed;
},
@@ -134,7 +134,7 @@ export default {
position: absolute;
top: 0;
left: 0;
- background: rgba(255, 214, 11, 0.8);
+ background: rgb(255, 214, 11, 0.8);
border-radius: var(--var-border-radius, inherit);
animation: a-new-import 3s infinite;
}
diff --git a/src/components/tabs/antimatter-dimensions/AntimatterDimensionProgressBar.vue b/src/components/tabs/antimatter-dimensions/AntimatterDimensionProgressBar.vue
index 563d2d3e40..50754cd32b 100644
--- a/src/components/tabs/antimatter-dimensions/AntimatterDimensionProgressBar.vue
+++ b/src/components/tabs/antimatter-dimensions/AntimatterDimensionProgressBar.vue
@@ -34,8 +34,8 @@ export default {
// than normal and therefore default filling won't be meaningful. Since challenges get completed or abandoned from
// the inside outwards, we show the goals in that priority as well. It only makes sense to check cel6 and not the
// others because pre-cel3 completion it'll default to e4000 and cel4/5 don't have meaningful single goals
- const inSpecialRun = Player.isInAntimatterChallenge || EternityChallenge.isRunning || (player.dilation.active && !Pelle.isDoomed) ||
- Laitela.isRunning;
+ const inSpecialRun = Player.isInAntimatterChallenge || EternityChallenge.isRunning ||
+ (player.dilation.active && !Pelle.isDoomed) || Laitela.isRunning;
if (inSpecialRun) {
if (Player.isInAntimatterChallenge) {
setProgress(Currency.antimatter.value, Player.antimatterChallenge.goal, "Percentage to Challenge goal");
diff --git a/src/core/sacrifice.js b/src/core/sacrifice.js
index 6c15358402..0d07731a11 100644
--- a/src/core/sacrifice.js
+++ b/src/core/sacrifice.js
@@ -19,7 +19,7 @@ export class Sacrifice {
if (DimBoost.purchasedBoosts < 5) return `Requires ${formatInt(5)} Dimension Boosts`;
if (AntimatterDimension(8).totalAmount.eq(0)) return "No 8th Antimatter Dimensions";
if (this.nextBoost.lte(1)) return `${formatX(1)} multiplier`;
- if (Enslaved.isRunning) return "This Reality does not allow Sacrifices"
+ if (Enslaved.isRunning) return "This Reality does not allow Sacrifices";
if (Player.isInAntimatterChallenge) return "Challenge goal reached";
return "Need to Crunch";
}
@@ -35,7 +35,7 @@ export class Sacrifice {
if (EternityChallenge(3).isRunning) return "Eternity Challenge 3";
if (DimBoost.purchasedBoosts < 5) return `Requires ${formatInt(5)} Dimension Boosts`;
if (AntimatterDimension(8).totalAmount.eq(0)) return "No 8th Antimatter Dimensions";
- if (Enslaved.isRunning) return "This Reality does not allow Sacrifices"
+ if (Enslaved.isRunning) return "This Reality does not allow Sacrifices";
if (Player.isInAntimatterChallenge) return "Challenge goal reached";
return "Need to Crunch";
}
diff --git a/src/core/secret-formula/celestials/pelle-upgrades.js b/src/core/secret-formula/celestials/pelle-upgrades.js
index 50d963485a..5b3efb8095 100644
--- a/src/core/secret-formula/celestials/pelle-upgrades.js
+++ b/src/core/secret-formula/celestials/pelle-upgrades.js
@@ -176,7 +176,7 @@ export const pelleUpgrades = {
id: 19,
description: "Eternity Challenge completions no longer reset on Armageddon",
cost: 1e26,
- formatCost,c
+ formatCost,
},
dilationUpgradesNoReset: {
id: 20,
diff --git a/src/core/secret-formula/reality/reality-upgrades.js b/src/core/secret-formula/reality/reality-upgrades.js
index a4d1c14926..c88b7b5415 100644
--- a/src/core/secret-formula/reality/reality-upgrades.js
+++ b/src/core/secret-formula/reality/reality-upgrades.js
@@ -105,7 +105,7 @@ export const realityUpgrades = [
checkRequirement: () => !player.reality.gainedAutoAchievements,
checkEvent: GAME_EVENT.ETERNITY_RESET_BEFORE,
canLock: true,
- // This lock event can only be seen if you are attempting to get ACHNR with the lock on, so we can specify ACHNR here
+ // This lock event can only be seen if you are attempting to get ACHNR with the lock on, so we can state ACHNR here
lockEvent: "gain an automatic achievement (through ACHNR)",
description: "Tachyon Particle gain is boosted based on Achievement multiplier",
effect: () => Math.sqrt(Achievements.power),
From 36dc940db581868f6cac68109000d75e614ba20d Mon Sep 17 00:00:00 2001
From: HexaVault <44529573+HexaVault@users.noreply.github.com>
Date: Sun, 7 Jun 2026 23:46:53 +0100
Subject: [PATCH 18/44] added note about enslaved disabling sacrifice
---
src/core/celestials/celestials.js | 3 ++-
src/core/secret-formula/celestials/ra.js | 6 +++---
2 files changed, 5 insertions(+), 4 deletions(-)
diff --git a/src/core/celestials/celestials.js b/src/core/celestials/celestials.js
index 4378b994f2..1491bdfa07 100644
--- a/src/core/celestials/celestials.js
+++ b/src/core/celestials/celestials.js
@@ -46,7 +46,8 @@ GameDatabase.celestials.descriptions = [
Tachyon Particle production and Dilated Time production are severely reduced.
Time Theorem generation from Dilation Glyphs is disabled.
Certain challenge goals are increased.
- Stored game time is discharged at a reduced effectiveness (exponent^${format(0.55, 2, 2)}).`;
+ Stored game time is discharged at a reduced effectiveness (exponent^${format(0.55, 2, 2)}).
+ Dimensional Sacrifice is Disabled.`;
}
},
{
diff --git a/src/core/secret-formula/celestials/ra.js b/src/core/secret-formula/celestials/ra.js
index 7fec67580f..c68b049455 100644
--- a/src/core/secret-formula/celestials/ra.js
+++ b/src/core/secret-formula/celestials/ra.js
@@ -111,7 +111,7 @@ export const ra = {
unlockGlyphAlchemy: {
id: 8,
reward: `Unlock Glyph Alchemy, which adds alchemical resources you can increase by Refining Glyphs. You unlock
- more resources through Effarig levels. Access through a new Reality tab.`,
+ more resources through Effarig levels. Access through a new Reality tab`,
pet: "effarig",
level: 2,
displayIcon: `
`
@@ -186,7 +186,7 @@ export const ra = {
autoPulseTime: {
id: 17,
reward: () => `Black Hole charging now only uses ${formatPercents(0.99)} of your game speed and you can
- automatically discharge ${formatPercents(0.01)} of your stored game time every ${formatInt(5)} ticks.`,
+ automatically discharge ${formatPercents(0.01)} of your stored game time every ${formatInt(5)} ticks`,
pet: "enslaved",
level: 10,
displayIcon: `
`,
@@ -240,7 +240,7 @@ export const ra = {
},
vXP: {
id: 23,
- reward: "All Memory Chunks produce more Memories based on total Celestial levels.",
+ reward: "All Memory Chunks produce more Memories based on total Celestial levels",
effect: () => 1 + Ra.totalPetLevel / 50,
pet: "v",
level: 5,
From c154e6d4fb94560a1599e89e504bb22b77b1d0a4 Mon Sep 17 00:00:00 2001
From: HexaVault <44529573+HexaVault@users.noreply.github.com>
Date: Mon, 8 Jun 2026 00:44:53 +0100
Subject: [PATCH 19/44] fixes
---
src/core/celestials/celestials.js | 2 +-
src/core/secret-formula/celestials/quotes/ra.js | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/core/celestials/celestials.js b/src/core/celestials/celestials.js
index 1491bdfa07..abf6b60948 100644
--- a/src/core/celestials/celestials.js
+++ b/src/core/celestials/celestials.js
@@ -47,7 +47,7 @@ GameDatabase.celestials.descriptions = [
Time Theorem generation from Dilation Glyphs is disabled.
Certain challenge goals are increased.
Stored game time is discharged at a reduced effectiveness (exponent^${format(0.55, 2, 2)}).
- Dimensional Sacrifice is Disabled.`;
+ Dimensional Sacrifice is disabled.`;
}
},
{
diff --git a/src/core/secret-formula/celestials/quotes/ra.js b/src/core/secret-formula/celestials/quotes/ra.js
index 69be62b769..9a0e3e93c8 100644
--- a/src/core/secret-formula/celestials/quotes/ra.js
+++ b/src/core/secret-formula/celestials/quotes/ra.js
@@ -37,7 +37,7 @@ export const raQuotes = {
id: 4,
requirement: () => Ra.pets.effarig.level >= 2,
lines: [
- "Eff... a... rig",
+ "Eff... a... rig...",
"I remember Effarig being friendly.",
]
},
From 81848c5f8eda1b25bd39a08029be2cee328f992d Mon Sep 17 00:00:00 2001
From: HexaVault <44529573+HexaVault@users.noreply.github.com>
Date: Wed, 10 Jun 2026 22:18:14 +0100
Subject: [PATCH 20/44] dev changes, fix bad code, iu and sing text changes,
ec6 while enslaved, broken effectDisplay code
---
src/components/EffectDisplay.vue | 9 ++-
.../EternityChallengeStartModal.vue | 5 ++
.../ModernAntimatterDimensionsTab.vue | 6 +-
src/core/devtools.js | 80 ++++++++++---------
.../celestials/singularity-milestones.js | 2 +-
.../reality/imaginary-upgrades.js | 2 +-
src/core/storage/migrations.js | 3 +
src/core/storage/storage.js | 14 +++-
8 files changed, 72 insertions(+), 49 deletions(-)
diff --git a/src/components/EffectDisplay.vue b/src/components/EffectDisplay.vue
index 2b9ccae876..e6eadf1403 100644
--- a/src/components/EffectDisplay.vue
+++ b/src/components/EffectDisplay.vue
@@ -32,7 +32,8 @@ export default {
// Number.MAX_VALUE doesn't really matter here, but we need it because
// undefined values are not allowed for data properties
cap: Number.MAX_VALUE,
- hasCap: false
+ hasCap: false,
+ effect: ""
};
},
computed: {
@@ -46,7 +47,10 @@ export default {
return `${this.reachedCap && !this.ignoreCapped ? "Capped" : this.label}: `;
},
effectDisplay() {
- return this.formatEffect(this.reachedCap ? this.cap : this.effectValue);
+ if (this.effectValue || this.reachedCap)
+ // eslint-disable-next-line vue/no-side-effects-in-computed-properties
+ this.effect = this.formatEffect(this.reachedCap ? this.cap : this.effectValue);
+ return this.effect;
}
},
watch: {
@@ -60,6 +64,7 @@ export default {
this.isVisible = effect !== undefined && formatEffect !== undefined;
if (!this.isVisible) return;
this.formatEffect = formatEffect;
+ this.effectValue = undefined;
if (isNumber(effect)) {
this.effectValue = effect;
diff --git a/src/components/modals/challenges/EternityChallengeStartModal.vue b/src/components/modals/challenges/EternityChallengeStartModal.vue
index 7ccafe89bf..8f2986c9c3 100644
--- a/src/components/modals/challenges/EternityChallengeStartModal.vue
+++ b/src/components/modals/challenges/EternityChallengeStartModal.vue
@@ -42,6 +42,11 @@ export default {
if (typeof conditionOfChallenge === "function") {
conditionOfChallenge = conditionOfChallenge();
}
+ if (this.challenge._config.scrambleText) {
+ conditionOfChallenge = conditionOfChallenge
+ .replace("*", this.challenge._config.scrambleText[1]);
+ // eslint-disable-next-line vue/no-side-effects-in-computed-properties
+ }
return `Inside this Eternity Challenge, ${conditionOfChallenge}`;
}
},
diff --git a/src/components/tabs/antimatter-dimensions/ModernAntimatterDimensionsTab.vue b/src/components/tabs/antimatter-dimensions/ModernAntimatterDimensionsTab.vue
index bfd8031b3b..4452d7dd61 100644
--- a/src/components/tabs/antimatter-dimensions/ModernAntimatterDimensionsTab.vue
+++ b/src/components/tabs/antimatter-dimensions/ModernAntimatterDimensionsTab.vue
@@ -86,11 +86,13 @@ export default {
this.multiplierText = `Buy 10 Dimension purchase multiplier: ${formatX(this.buy10Mult, 2, 2)}`;
if (!isSacrificeUnlocked) return;
- this.isFullyAutomated = Autobuyer.sacrifice.isActive && Achievement(118).isEffectActive && Sacrifice.meetsNonBoostConditions;
+ this.isFullyAutomated = Autobuyer.sacrifice.isActive && Achievement(118).isEffectActive &&
+ Sacrifice.meetsNonBoostConditions;
this.isSacrificeAffordable = this.isFullyAutomated || Sacrifice.canSacrifice;
this.currentSacrifice.copyFrom(Sacrifice.totalBoost);
this.sacrificeBoost.copyFrom(Sacrifice.nextBoost);
- this.disabledCondition = this.isFullyAutomated ? Sacrifice.nonBoostDisabledCondition || Sacrifice.disabledCondition;
+ this.disabledCondition = this.isFullyAutomated ? Sacrifice.nonBoostDisabledCondition
+ : Sacrifice.disabledCondition;
const sacText = this.isSacrificeUnlocked
? ` | Dimensional Sacrifice multiplier: ${formatX(this.currentSacrifice, 2, 2)}`
: "";
diff --git a/src/core/devtools.js b/src/core/devtools.js
index 0ee652f5ab..7ec6da2d02 100644
--- a/src/core/devtools.js
+++ b/src/core/devtools.js
@@ -2,6 +2,7 @@ import { sha512_256 } from "js-sha512";
import { DC } from "./constants";
import FullScreenAnimationHandler from "./full-screen-animation-handler";
+import { deepmergeAll } from "../utility/deepmerge";
/* eslint-disable no-console */
// Disabling no-console here seems
@@ -17,37 +18,6 @@ dev.giveAllAchievements = function() {
for (const achievement of allAchievements) achievement.unlock();
};
-// Know that both dev.doubleEverything and dev.tripleEverything are both broken
-// with this error https://i.imgur.com/ZMEBNTv.png
-
-dev.doubleEverything = function() {
- Object.keys(player).forEach(key => {
- if (typeof player[key] === "number") player[key] *= 2;
- if (typeof player[key] === "object" && player[key].constructor !== Object) player[key] = player[key].times(2);
- if (typeof player[key] === "object" && !isFinite(player[key])) {
- Object.keys(player[key]).forEach(key2 => {
- if (typeof player[key][key2] === "number") player[key][key2] *= 2;
- if (typeof player[key][key2] === "object" && player[key][key2].constructor !== Object)
- player[key][key2] = player[key][key2].times(2);
- });
- }
- });
-};
-
-dev.tripleEverything = function() {
- Object.keys(player).forEach(key => {
- if (typeof player[key] === "number") player[key] *= 3;
- if (typeof player[key] === "object" && player[key].constructor !== Object) player[key] = player[key].times(3);
- if (typeof player[key] === "object" && !isFinite(player[key])) {
- Object.keys(player[key]).forEach(key3 => {
- if (typeof player[key][key3] === "number") player[key][key3] *= 3;
- if (typeof player[key][key3] === "object" && player[key][key3].constructor !== Object)
- player[key][key3] = player[key][key3].times(3);
- });
- }
- });
-};
-
dev.barrelRoll = function() {
FullScreenAnimationHandler.display("a-barrel-roll", 5);
};
@@ -67,18 +37,50 @@ dev.cancerize = function() {
Notation.emoji.setAsCurrent();
};
-dev.fixSave = function() {
- const save = JSON.stringify(player, GameSaveSerializer.jsonConverter);
- const fixed = save.replace(/NaN/gui, "10");
- const saveData = JSON.parse(fixed);
- if (!saveData || GameStorage.checkPlayerObject(saveData) !== "") {
- Modal.message.show("Could not fix the save.");
- return;
+// Iterates through every item in A and B
+// If A has a broken value in anyway, it will set it to the value in B
+// This could fail if saves are irrepairably damaged, but still worth trying.
+function fixSaveIterator(value, value2) {
+ for (const item in value) {
+ if (value[item] instanceof Decimal && value2[item] !== undefined) {
+ if (value2[item].neq(0)) {
+ // Under some cases, this could reset legitimate values, but this is a very rare (and safe) edge-case
+ if (value[item].lt(0) || value[item].exponent > 8e15)
+ value[item] = value2[item];
+ } else if (value[item].exponent > 8e15)
+ value[item] = value2[item];
+ }
+ if (value[item] instanceof Number && value2[item] !== undefined) {
+ if (value2[item] === 0) {
+ if (value[item] > 1e300) {
+ value[item] = value2[item];
+ }
+ } else if (value[item] > 1e300 || value[item] < 0)
+ value[item] = value2[item];
+ }
+ if ((value[item] instanceof Object || value[item] instanceof Array) &&
+ !(value[item] instanceof Decimal) && value2[item] !== undefined)
+ value[item] = fixSaveIterator(value[item], value2[item]);
+ if (value[item] === undefined && value2[item] !== undefined)
+ value[item] = value2[item];
+ // If neither the save nor the default player object can figure out what this prop is, we probably dont need to keep it
+ if (value[item] === undefined && value2[item] === undefined)
+ delete value[item]
}
- GameStorage.loadPlayerObject(saveData);
+ return value;
+};
+
+// This attempts to forcibly fix all player values, and override the existing save
+// This isn't the best persay, but frankly its worth having, because saves do inevitably break.
+dev.fixSave = function(save) {
+ player = deepmergeAll([Player.defaultStart, save ?? player])
+ player = fixSaveIterator(player, Player.defaultStart);
GameStorage.save();
};
+// If true, it will attempt to run dev.fixSave on importing a broken save
+dev.attemptFixImports = false
+
dev.updateTDCosts = function() {
for (let tier = 1; tier < 9; tier++) {
const dim = TimeDimension(tier);
diff --git a/src/core/secret-formula/celestials/singularity-milestones.js b/src/core/secret-formula/celestials/singularity-milestones.js
index 644169fd43..5c8e1c9db2 100644
--- a/src/core/secret-formula/celestials/singularity-milestones.js
+++ b/src/core/secret-formula/celestials/singularity-milestones.js
@@ -265,7 +265,7 @@ export const singularityMilestones = {
start: 8e33,
repeat: 0,
limit: 1,
- description: "Dilated Time boosts Dark Matter production",
+ description: "Dilated Time boosts Dark Matter and Dark Energy production",
effect: () => Math.pow(1.6, Decimal.log10(Currency.dilatedTime.value.plus(1)) / 1000),
effectFormat: x => formatX(x, 2, 2),
upgradeDirection: LAITELA_UPGRADE_DIRECTION.BOOSTS_LAITELA,
diff --git a/src/core/secret-formula/reality/imaginary-upgrades.js b/src/core/secret-formula/reality/imaginary-upgrades.js
index 9b063c4cdb..da529160af 100644
--- a/src/core/secret-formula/reality/imaginary-upgrades.js
+++ b/src/core/secret-formula/reality/imaginary-upgrades.js
@@ -140,7 +140,7 @@ export const imaginaryUpgrades = [
checkEvent: GAME_EVENT.GAME_TICK_AFTER,
description: "Increase Imaginary Machine Cap based on Imaginary Upgrades purchased",
effect: () => 1 + ImaginaryUpgrades.totalRebuyables / 20 + ImaginaryUpgrades.totalSinglePurchase / 2,
- formatEffect: value => `${formatX(value, 2, 1)}`,
+ formatEffect: value => `${formatX(value, 2, 2)}`,
isDisabledInDoomed: true
},
{
diff --git a/src/core/storage/migrations.js b/src/core/storage/migrations.js
index 9d28da06be..e70c787249 100644
--- a/src/core/storage/migrations.js
+++ b/src/core/storage/migrations.js
@@ -419,6 +419,9 @@ export const migrations = {
// This update has a rebalance that assumes the 3rd dilation repeatable is unpurchasable in cel7
if (player.celestials.pelle.doomed) player.dilation.rebuyables[3] = 0;
+ },
+ 25.1: player => {
+ delete player.infinity;
}
},
diff --git a/src/core/storage/storage.js b/src/core/storage/storage.js
index c2a32a946c..1439f79ffc 100644
--- a/src/core/storage/storage.js
+++ b/src/core/storage/storage.js
@@ -420,18 +420,24 @@ export const GameStorage = {
Cloud.resetTempState();
},
+ // eslint-disable-next-line complexity
loadPlayerObject(playerObject) {
this.saved = 0;
const checkString = this.checkPlayerObject(playerObject);
if (playerObject === Player.defaultStart || checkString !== "") {
- if (DEV && checkString !== "") {
+ if (DEV && checkString !== "" && !dev.attemptFixImports) {
// eslint-disable-next-line no-console
console.log(`Savefile was invalid and has been reset - ${checkString}`);
}
- player = deepmergeAll([{}, Player.defaultStart]);
- player.records.gameCreatedTime = Date.now();
- player.lastUpdate = Date.now();
+
+ if (dev.attemptFixImports) {
+ dev.fixSave(playerObject)
+ } else {
+ player = deepmergeAll([{}, Player.defaultStart]);
+ player.records.gameCreatedTime = Date.now();
+ player.lastUpdate = Date.now();
+ }
if (DEV) {
devMigrations.setLatestTestVersion(player);
}
From b1e8093cbf0862a4bb7c21012d7a959f8c433a32 Mon Sep 17 00:00:00 2001
From: HexaVault <44529573+HexaVault@users.noreply.github.com>
Date: Thu, 11 Jun 2026 19:46:26 +0100
Subject: [PATCH 21/44] nc3 title fix
---
src/core/secret-formula/challenges/normal-challenges.js | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/core/secret-formula/challenges/normal-challenges.js b/src/core/secret-formula/challenges/normal-challenges.js
index cd9974ec4d..5c15611715 100644
--- a/src/core/secret-formula/challenges/normal-challenges.js
+++ b/src/core/secret-formula/challenges/normal-challenges.js
@@ -37,7 +37,7 @@ export const normalChallenges = [
description:
`the 1st Antimatter Dimension is heavily weakened, but gets an uncapped exponentially increasing multiplier.
This multiplier resets after Dimension Boosts and Antimatter Galaxies.`,
- name: "3rd Antimatter Dimension",
+ name: "3rd Antimatter Dimension Autobuyer",
reward: "Upgradeable 3rd Antimatter Dimension Autobuyer",
lockedAt: DC.D0,
},
From ec31c9fd9a59247e80b0fdc7d38a42133cab4c3a Mon Sep 17 00:00:00 2001
From: HexaVault <44529573+HexaVault@users.noreply.github.com>
Date: Thu, 11 Jun 2026 19:48:41 +0100
Subject: [PATCH 22/44] fix some codefactor
---
src/core/devtools.js | 17 ++++++++++-------
1 file changed, 10 insertions(+), 7 deletions(-)
diff --git a/src/core/devtools.js b/src/core/devtools.js
index 7ec6da2d02..b9729cb33b 100644
--- a/src/core/devtools.js
+++ b/src/core/devtools.js
@@ -1,8 +1,9 @@
import { sha512_256 } from "js-sha512";
+import { deepmergeAll } from "../utility/deepmerge";
+
import { DC } from "./constants";
import FullScreenAnimationHandler from "./full-screen-animation-handler";
-import { deepmergeAll } from "../utility/deepmerge";
/* eslint-disable no-console */
// Disabling no-console here seems
@@ -40,6 +41,7 @@ dev.cancerize = function() {
// Iterates through every item in A and B
// If A has a broken value in anyway, it will set it to the value in B
// This could fail if saves are irrepairably damaged, but still worth trying.
+// eslint-disable-next-line complexity
function fixSaveIterator(value, value2) {
for (const item in value) {
if (value[item] instanceof Decimal && value2[item] !== undefined) {
@@ -56,30 +58,31 @@ function fixSaveIterator(value, value2) {
value[item] = value2[item];
}
} else if (value[item] > 1e300 || value[item] < 0)
- value[item] = value2[item];
+ value[item] = value2[item];
}
if ((value[item] instanceof Object || value[item] instanceof Array) &&
!(value[item] instanceof Decimal) && value2[item] !== undefined)
value[item] = fixSaveIterator(value[item], value2[item]);
if (value[item] === undefined && value2[item] !== undefined)
value[item] = value2[item];
- // If neither the save nor the default player object can figure out what this prop is, we probably dont need to keep it
+ // If neither the save nor the default player object can figure out what this prop is,
+ // we probably dont need to keep it
if (value[item] === undefined && value2[item] === undefined)
- delete value[item]
+ delete value[item];
}
return value;
-};
+}
// This attempts to forcibly fix all player values, and override the existing save
// This isn't the best persay, but frankly its worth having, because saves do inevitably break.
dev.fixSave = function(save) {
- player = deepmergeAll([Player.defaultStart, save ?? player])
+ player = deepmergeAll([Player.defaultStart, save ?? player]);
player = fixSaveIterator(player, Player.defaultStart);
GameStorage.save();
};
// If true, it will attempt to run dev.fixSave on importing a broken save
-dev.attemptFixImports = false
+dev.attemptFixImports = false;
dev.updateTDCosts = function() {
for (let tier = 1; tier < 9; tier++) {
From 1f3c04fceee4b747211b9aab5bdea524f7a82f27 Mon Sep 17 00:00:00 2001
From: HexaVault <44529573+HexaVault@users.noreply.github.com>
Date: Sat, 13 Jun 2026 16:03:35 +0100
Subject: [PATCH 23/44] check for "infinity" props asw, and allow import(x) to
actually work
---
src/core/storage/storage.js | 22 +++++++++++++++-------
1 file changed, 15 insertions(+), 7 deletions(-)
diff --git a/src/core/storage/storage.js b/src/core/storage/storage.js
index 1439f79ffc..5fc6bf2f6b 100644
--- a/src/core/storage/storage.js
+++ b/src/core/storage/storage.js
@@ -156,9 +156,17 @@ export const GameStorage = {
return;
}
const newPlayer = GameSaveSerializer.deserialize(saveData);
+ // If we're attempting to fix imports anyways
if (this.checkPlayerObject(newPlayer) !== "") {
- Modal.message.show("Could not load the save (format unrecognized or invalid).");
- return;
+ // If we are repairing imports, and the player object fail starts with B, we know it is because
+ // there are some broken player objects that might be repairable. If we are fixing, we can therefore
+ // attempt to forcibly fix the broken save anyways.
+ if (dev.attemptFixImports && this.checkPlayerObject(newPlayer)[0] === "B") {
+ Modal.message.show("Save format is damaged, attempting save repairal");
+ } else {
+ Modal.message.show("Could not load the save (format unrecognized or invalid).");
+ return;
+ }
}
this.oldBackupTimer = player.backupTimer;
Modal.hideAll();
@@ -220,13 +228,13 @@ export const GameStorage = {
hasNaN = hasNaN || thisNaN;
break;
case "number":
- thisNaN = Number.isNaN(prop);
+ thisNaN = Number.isNaN(prop) || !Number.isFinite(prop);
hasNaN = hasNaN || thisNaN;
if (thisNaN) invalidProps.push(`${path}.${key}`);
break;
case "string":
- // If we're attempting to import, all NaN entries will still be strings
- thisNaN = prop === "NaN";
+ // If we're attempting to import, all NaN or infinity entries will still be strings
+ thisNaN = prop === "NaN" || prop === "infinity";
hasNaN = hasNaN || thisNaN;
if (thisNaN) invalidProps.push(`${path}.${key}`);
break;
@@ -237,7 +245,7 @@ export const GameStorage = {
checkNaN(save, "player");
if (invalidProps.length === 0) return "";
- return `${quantify("NaN player property", invalidProps.length)} found:
+ return `${quantify("Broken player property", invalidProps.length)} found:
${invalidProps.join(", ")}`;
},
@@ -432,7 +440,7 @@ export const GameStorage = {
}
if (dev.attemptFixImports) {
- dev.fixSave(playerObject)
+ dev.fixSave(playerObject);
} else {
player = deepmergeAll([{}, Player.defaultStart]);
player.records.gameCreatedTime = Date.now();
From 4db0176ece1ca5aac059ca32b024b9afcdcc5b3d Mon Sep 17 00:00:00 2001
From: HexaVault <44529573+HexaVault@users.noreply.github.com>
Date: Tue, 16 Jun 2026 20:57:07 +0100
Subject: [PATCH 24/44] drp now uses formatMachines, add pelle upgrades to AG
reset text, up maxlen to 140
---
.eslintrc.json | 2 +-
.../ClassicAntimatterGalaxyRow.vue | 6 ++++--
.../ModernAntimatterGalaxyRow.vue | 6 ++++--
src/core/secret-formula/discord-rich-presence.js | 11 ++++++-----
4 files changed, 15 insertions(+), 10 deletions(-)
diff --git a/.eslintrc.json b/.eslintrc.json
index 545ec52910..8fe9aedcb8 100644
--- a/.eslintrc.json
+++ b/.eslintrc.json
@@ -189,7 +189,7 @@
"max-len": [
"warn",
{
- "code": 120
+ "code": 140
}
],
"max-params": "warn",
diff --git a/src/components/tabs/antimatter-dimensions/ClassicAntimatterGalaxyRow.vue b/src/components/tabs/antimatter-dimensions/ClassicAntimatterGalaxyRow.vue
index a2700b090a..e12ce70e0f 100644
--- a/src/components/tabs/antimatter-dimensions/ClassicAntimatterGalaxyRow.vue
+++ b/src/components/tabs/antimatter-dimensions/ClassicAntimatterGalaxyRow.vue
@@ -39,8 +39,10 @@ export default {
buttonText() {
if (this.lockText !== null) return this.lockText;
const reset = [];
- if (!Achievement(111).isEffectActive) reset.push("Dimensions");
- if (!Achievement(143).isEffectActive) reset.push("Dimension Boosts");
+ // eslint-disable-next-line max-len
+ if (!Achievement(111).isEffectActive && !PelleUpgrade.dimBoostResetsNothing.canBeApplied) reset.push("Dimensions");
+ // eslint-disable-next-line max-len
+ if (!Achievement(143).isEffectActive && !PelleUpgrade.galaxyNoResetDimboost.canBeApplied) reset.push("Dimension Boosts");
return reset.length === 0
? `Increase the power of Tickspeed upgrades`
: `Reset your ${makeEnumeration(reset)} to increase the power of Tickspeed upgrades`;
diff --git a/src/components/tabs/antimatter-dimensions/ModernAntimatterGalaxyRow.vue b/src/components/tabs/antimatter-dimensions/ModernAntimatterGalaxyRow.vue
index 593b141fa5..0ed85eadb2 100644
--- a/src/components/tabs/antimatter-dimensions/ModernAntimatterGalaxyRow.vue
+++ b/src/components/tabs/antimatter-dimensions/ModernAntimatterGalaxyRow.vue
@@ -34,8 +34,10 @@ export default {
buttonText() {
if (this.lockText !== null) return this.lockText;
const reset = [];
- if (!Achievement(111).isEffectActive) reset.push("Dimensions");
- if (!Achievement(143).isEffectActive) reset.push("Dimension Boosts");
+ // eslint-disable-next-line max-len
+ if (!Achievement(111).isEffectActive && !PelleUpgrade.dimBoostResetsNothing.canBeApplied) reset.push("Dimensions");
+ // eslint-disable-next-line max-len
+ if (!Achievement(143).isEffectActive && !PelleUpgrade.galaxyNoResetDimboost.canBeApplied) reset.push("Dimension Boosts");
return reset.length === 0
? `Increase the power of Tickspeed upgrades`
: `Reset your ${makeEnumeration(reset)} to increase the power of Tickspeed upgrades`;
diff --git a/src/core/secret-formula/discord-rich-presence.js b/src/core/secret-formula/discord-rich-presence.js
index ac0fa7bce9..b20735a1d0 100644
--- a/src/core/secret-formula/discord-rich-presence.js
+++ b/src/core/secret-formula/discord-rich-presence.js
@@ -11,10 +11,11 @@ function formatInt(value) {
function formatMachines(realPart, imagPart) {
const parts = [];
- if (Decimal.neq(realPart, 0)) parts.push(format(realPart, 2));
+ if (Decimal.neq(realPart, 0)) parts.push(`${format(realPart, 2)}`);
if (Decimal.neq(imagPart, 0)) parts.push(`${format(imagPart, 2, 2)}i`);
- if (Decimal.eq(realPart, 0) && Decimal.eq(imagPart, 0)) return format(0);
- return parts.join(" + ");
+ if (Decimal.eq(realPart, 0) && Decimal.eq(imagPart, 0)) return `${format(0)} Machines`;
+ // This is the way it is displayed in sidebar aswell.
+ return `${parts.join(" + ")} Machines`;
}
// This is used for Discord Rich Presence, the information which shows up on a person's profile badge in Discord if
@@ -232,7 +233,7 @@ export const discordRichPresence = {
name: () => Ra.displayName,
hasReached: () => MachineHandler.isIMUnlocked,
mainResource: () =>
- `${format(player.reality.realityMachines)} RM + ${format(player.reality.imaginaryMachines, 2)} iM`,
+ formatMachines(player.reality.realityMachines, player.reality.imaginaryMachines),
resourceList: [
() => `Best GL: ${formatInt(player.records.bestReality.glyphLevel)}`,
() => `Ra Levels: ${Ra.pets.all.map(p => formatInt(p.level)).join("/")}`
@@ -242,7 +243,7 @@ export const discordRichPresence = {
name: () => Laitela.displayName,
hasReached: () => Laitela.isUnlocked,
mainResource: () =>
- `${format(player.reality.realityMachines)} RM + ${format(player.reality.imaginaryMachines, 2)} iM`,
+ formatMachines(player.reality.realityMachines, player.reality.imaginaryMachines),
resourceList: [
() => `Best GL: ${formatInt(player.records.bestReality.glyphLevel)}`,
() => quantify("Singularity", player.celestials.laitela.singularities, 2, 0, format)],
From 393fd133a6d383f636890a22ddbea58750032d2d Mon Sep 17 00:00:00 2001
From: HexaVault <44529573+HexaVault@users.noreply.github.com>
Date: Tue, 16 Jun 2026 21:38:41 +0100
Subject: [PATCH 25/44] notation bug, sort out storage being overzealous with
"broken" properties
---
src/components/DescriptionDisplay.vue | 7 ++++++-
.../tabs/imaginary-upgrades/ImaginaryUpgradeButton.vue | 4 ++++
.../tabs/reality-upgrades/RealityUpgradeButton.vue | 4 ++++
.../eternity/time-studies/normal-time-studies.js | 5 ++++-
src/core/secret-formula/reality/imaginary-upgrades.js | 1 +
src/core/secret-formula/reality/reality-upgrades.js | 5 +++++
src/core/storage/storage.js | 2 +-
7 files changed, 25 insertions(+), 3 deletions(-)
diff --git a/src/components/DescriptionDisplay.vue b/src/components/DescriptionDisplay.vue
index 3c8da71ffe..78d7adb630 100644
--- a/src/components/DescriptionDisplay.vue
+++ b/src/components/DescriptionDisplay.vue
@@ -26,6 +26,11 @@ export default {
type: String,
required: false,
default: ""
+ },
+ numberPrefixed: {
+ type: Boolean,
+ required: false,
+ default: false
}
},
data() {
@@ -56,7 +61,7 @@ export default {
const description = config?.description;
// Descriptions in config entries are occasionally used both as standalone statements and mid-sentence,
// so we explicitly capitalize them here because this only shows up in standalone places
- const capitalize = str => str.charAt(0).toUpperCase() + str.slice(1);
+ const capitalize = str => (this.numberPrefixed ? str : str.charAt(0).toUpperCase() + str.slice(1));
this.isVisible = description !== undefined;
if (!this.isVisible) return;
diff --git a/src/components/tabs/imaginary-upgrades/ImaginaryUpgradeButton.vue b/src/components/tabs/imaginary-upgrades/ImaginaryUpgradeButton.vue
index 6687dbf211..a53ec8b95d 100644
--- a/src/components/tabs/imaginary-upgrades/ImaginaryUpgradeButton.vue
+++ b/src/components/tabs/imaginary-upgrades/ImaginaryUpgradeButton.vue
@@ -38,6 +38,9 @@ export default {
config() {
return this.upgrade.config;
},
+ prefixedWithNumber() {
+ return Boolean(this.config.prefixedNumber);
+ },
classObject() {
return {
"c-reality-upgrade-btn--useless": this.upgrade.pelleDisabled,
@@ -113,6 +116,7 @@ export default {
diff --git a/src/components/tabs/reality-upgrades/RealityUpgradeButton.vue b/src/components/tabs/reality-upgrades/RealityUpgradeButton.vue
index 03531d541c..52bca42929 100644
--- a/src/components/tabs/reality-upgrades/RealityUpgradeButton.vue
+++ b/src/components/tabs/reality-upgrades/RealityUpgradeButton.vue
@@ -38,6 +38,9 @@ export default {
config() {
return this.upgrade.config;
},
+ prefixedWithNumber() {
+ return Boolean(this.config.prefixedNumber);
+ },
classObject() {
return {
"c-reality-upgrade-btn--useless": this.isUseless,
@@ -106,6 +109,7 @@ export default {
diff --git a/src/core/secret-formula/eternity/time-studies/normal-time-studies.js b/src/core/secret-formula/eternity/time-studies/normal-time-studies.js
index 0b0877e143..dd77b543f6 100644
--- a/src/core/secret-formula/eternity/time-studies/normal-time-studies.js
+++ b/src/core/secret-formula/eternity/time-studies/normal-time-studies.js
@@ -103,7 +103,10 @@ export const normalTimeStudies = [
requirement: [31],
reqType: TS_REQUIREMENT_TYPE.AT_LEAST_ONE,
description: () => `All Galaxies give a ${formatX(DC.D1_2, 1, 1)} multiplier to Infinity Points gained`,
- effect: () => DC.D1_2.pow(Replicanti.galaxies.total + player.galaxies + player.dilation.totalTachyonGalaxies),
+ effect: () => {
+ const gain = DC.D1_2.pow(Replicanti.galaxies.total + player.galaxies + player.dilation.totalTachyonGalaxies);
+ return gain.gt(1e50) && Effarig.isRunning && Effarig.currentStage === EFFARIG_STAGES.ETERNITY ? DC.E50 : gain;
+ },
formatEffect: value => formatX(value, 2, 1)
},
{
diff --git a/src/core/secret-formula/reality/imaginary-upgrades.js b/src/core/secret-formula/reality/imaginary-upgrades.js
index da529160af..09c097846d 100644
--- a/src/core/secret-formula/reality/imaginary-upgrades.js
+++ b/src/core/secret-formula/reality/imaginary-upgrades.js
@@ -102,6 +102,7 @@ export const imaginaryUpgrades = [
name: "Suspicion of Interference",
id: 11,
cost: 5e7,
+ prefixedNumber: true,
requirement: () => `${format(1e90)} total Relic Shards
(You have ${format(player.celestials.effarig.relicShards, 2)})`,
hasFailed: () => false,
diff --git a/src/core/secret-formula/reality/reality-upgrades.js b/src/core/secret-formula/reality/reality-upgrades.js
index c88b7b5415..37c1c0037e 100644
--- a/src/core/secret-formula/reality/reality-upgrades.js
+++ b/src/core/secret-formula/reality/reality-upgrades.js
@@ -152,6 +152,7 @@ export const realityUpgrades = [
name: "The Boundless Flow",
id: 11,
cost: 50,
+ prefixedNumber: true,
requirement: () => `${format(Currency.infinitiesBanked.value, 2)}/${format(DC.E12)} Banked Infinities`,
checkRequirement: () => Currency.infinitiesBanked.exponent >= 12,
checkEvent: [GAME_EVENT.ETERNITY_RESET_AFTER, GAME_EVENT.REALITY_FIRST_UNLOCKED],
@@ -196,6 +197,7 @@ export const realityUpgrades = [
name: "The Eternal Flow",
id: 14,
cost: 50,
+ prefixedNumber: true,
requirement: () => `${format(Currency.eternities.value, 2)}/${format(1e7)} Eternities`,
checkRequirement: () => Currency.eternities.gte(1e7),
checkEvent: [GAME_EVENT.ETERNITY_RESET_AFTER, GAME_EVENT.REALITY_FIRST_UNLOCKED],
@@ -291,6 +293,7 @@ export const realityUpgrades = [
name: "Parity of Singularity",
id: 20,
cost: 1500,
+ prefixedNumber: true,
requirement: () => `${formatInt(100)} days total play time after unlocking the Black Hole
(Currently: ${Time.timeSinceBlackHole.toStringShort(false)})`,
hasFailed: () => !BlackHole(1).isUnlocked && Currency.realityMachines.lt(100),
@@ -305,6 +308,7 @@ export const realityUpgrades = [
name: "Cosmic Conglomerate",
id: 21,
cost: 100000,
+ prefixedNumber: true,
requirement: () => `${formatInt(Replicanti.galaxies.total + player.galaxies +
player.dilation.totalTachyonGalaxies)}/${formatInt(2800)} total Galaxies from all types`,
checkRequirement: () =>
@@ -317,6 +321,7 @@ export const realityUpgrades = [
name: "Temporal Transcendence",
id: 22,
cost: 100000,
+ prefixedNumber: true,
requirement: () => `${format(Currency.timeShards.value, 1)}/${format(DC.E28000)} Time Shards`,
checkRequirement: () => Currency.timeShards.exponent >= 28000,
checkEvent: GAME_EVENT.GAME_TICK_AFTER,
diff --git a/src/core/storage/storage.js b/src/core/storage/storage.js
index 5fc6bf2f6b..fc2fa5e50a 100644
--- a/src/core/storage/storage.js
+++ b/src/core/storage/storage.js
@@ -234,7 +234,7 @@ export const GameStorage = {
break;
case "string":
// If we're attempting to import, all NaN or infinity entries will still be strings
- thisNaN = prop === "NaN" || prop === "infinity";
+ thisNaN = prop === "NaN";
hasNaN = hasNaN || thisNaN;
if (thisNaN) invalidProps.push(`${path}.${key}`);
break;
From b9049e2fc0a2487ed351eaa19af854bedeff1627 Mon Sep 17 00:00:00 2001
From: HexaVault <44529573+HexaVault@users.noreply.github.com>
Date: Tue, 16 Jun 2026 21:47:47 +0100
Subject: [PATCH 26/44] fix undefined attempted during automator log
---
src/core/automator/automator-commands.js | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/core/automator/automator-commands.js b/src/core/automator/automator-commands.js
index 0dfade642a..c3feda3060 100644
--- a/src/core/automator/automator-commands.js
+++ b/src/core/automator/automator-commands.js
@@ -459,15 +459,15 @@ export const AutomatorCommands = [
const prestigeToken = ctx.PrestigeEvent[0].tokenType;
return () => {
const available = prestigeToken.$prestigeAvailable();
+ const prestigeName = ctx.PrestigeEvent[0].image.toUpperCase();
if (!available) {
if (!nowait) return AUTOMATOR_COMMAND_STATUS.NEXT_TICK_SAME_INSTRUCTION;
- AutomatorData.logCommandEvent(`${ctx.PrestigeEvent.image} attempted, but skipped due to NOWAIT`,
+ AutomatorData.logCommandEvent(`${prestigeName} attempted, but skipped due to NOWAIT`,
ctx.startLine);
return AUTOMATOR_COMMAND_STATUS.NEXT_INSTRUCTION;
}
if (respec) prestigeToken.$respec();
prestigeToken.$prestige();
- const prestigeName = ctx.PrestigeEvent[0].image.toUpperCase();
AutomatorData.logCommandEvent(`${prestigeName} triggered (${findLastPrestigeRecord(prestigeName)})`,
ctx.startLine);
// In the prestigeToken.$prestige() line above, performing a reality reset has code internal to the call
From e2cd0f8bd67fcf39695ec756a2d513fa551ff3c2 Mon Sep 17 00:00:00 2001
From: HexaVault <44529573+HexaVault@users.noreply.github.com>
Date: Tue, 23 Jun 2026 12:20:56 +0100
Subject: [PATCH 27/44] fix spelling, r187 now correctly states dilating time,
not unlocking time, disable DAB when doomed
---
src/core/celestials/pelle/pelle.js | 2 +-
src/core/secret-formula/achievements/normal-achievements.js | 2 +-
src/core/secret-formula/celestials/navigation.js | 2 +-
3 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/src/core/celestials/pelle/pelle.js b/src/core/celestials/pelle/pelle.js
index 9e5d5dbd18..7ee250a2f4 100644
--- a/src/core/celestials/pelle/pelle.js
+++ b/src/core/celestials/pelle/pelle.js
@@ -200,7 +200,7 @@ export const Pelle = {
get uselessPerks() {
return [10, 12, 13, 14, 15, 16, 17, 30, 40, 41, 42, 43, 44, 45, 46, 51, 52,
- 53, 60, 61, 62, 80, 81, 82, 83, 100, 103, 104, 105, 106, 201, 202, 203, 204];
+ 53, 60, 61, 62, 80, 81, 82, 83, 100, 103, 104, 105, 106, 107, 201, 202, 203, 204];
},
get specialGlyphEffect() {
diff --git a/src/core/secret-formula/achievements/normal-achievements.js b/src/core/secret-formula/achievements/normal-achievements.js
index e031a3cb84..d9111f45e2 100644
--- a/src/core/secret-formula/achievements/normal-achievements.js
+++ b/src/core/secret-formula/achievements/normal-achievements.js
@@ -1365,7 +1365,7 @@ export const normalAchievements = [
{
id: 187,
name: "The One with Dilated Time",
- description: "Unlock Dilation while Doomed.",
+ description: "Dilate Time while Doomed.",
checkRequirement: () => PelleStrikes.dilation.hasStrike,
checkEvent: GAME_EVENT.PELLE_STRIKE_UNLOCKED,
// We forgot to disable a singularity milestone while balancing Pelle; now it's disabled
diff --git a/src/core/secret-formula/celestials/navigation.js b/src/core/secret-formula/celestials/navigation.js
index 56f9377fd4..2d3473ddfa 100644
--- a/src/core/secret-formula/celestials/navigation.js
+++ b/src/core/secret-formula/celestials/navigation.js
@@ -1528,7 +1528,7 @@ export const celestialNavigation = {
if (player.celestials.laitela.fastestCompletion > 30 && Laitela.difficultyTier < 0) return [
dmdText,
- `Beat Lai'tela's Reality in less that ${format(30)} seconds`
+ `Beat Lai'tela's Reality in less than ${format(30)} seconds`
];
return [
dmdText,
From 53a7280c2c5378e6650a94c4c2c01feb4b6cc460 Mon Sep 17 00:00:00 2001
From: HexaVault <44529573+HexaVault@users.noreply.github.com>
Date: Tue, 23 Jun 2026 12:22:44 +0100
Subject: [PATCH 28/44] only show animation note modal once, not showing if the
game has been beaten atleast once
---
src/components/modals/prestige/BigCrunchModal.vue | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/components/modals/prestige/BigCrunchModal.vue b/src/components/modals/prestige/BigCrunchModal.vue
index cf20ef3138..f2126f23f5 100644
--- a/src/components/modals/prestige/BigCrunchModal.vue
+++ b/src/components/modals/prestige/BigCrunchModal.vue
@@ -17,7 +17,7 @@ export default {
},
computed: {
isFirstInfinity() {
- return !PlayerProgress.infinityUnlocked();
+ return !PlayerProgress.infinityUnlocked() && player.records.fullGameCompletions === 0;
},
message() {
const info = this.isFirstInfinity ? this.firstInfinityInfo : ``;
From 37129b25e499bb4373a7c044af8cd6d3b653c4d7 Mon Sep 17 00:00:00 2001
From: HexaVault <44529573+HexaVault@users.noreply.github.com>
Date: Tue, 23 Jun 2026 12:27:25 +0100
Subject: [PATCH 29/44] recenter nameless icon
---
public/stylesheets/styles.css | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/public/stylesheets/styles.css b/public/stylesheets/styles.css
index 65880c8e5c..ecc9ded2b1 100644
--- a/public/stylesheets/styles.css
+++ b/public/stylesheets/styles.css
@@ -6545,7 +6545,7 @@ kbd {
.c-enslaved-run-button__icon__sigil {
position: absolute;
top: -3.7rem;
- right: -0.2rem;
+ right: -0.45rem;
font-size: 14.8rem;
transform: rotate(45deg);
}
From 13780edd35d1c5a36dcc9aac19ddddafd7e8241b Mon Sep 17 00:00:00 2001
From: HexaVault <44529573+HexaVault@users.noreply.github.com>
Date: Tue, 23 Jun 2026 12:29:32 +0100
Subject: [PATCH 30/44] fixed shiftclick showing ecs early
---
src/core/time-studies/ec-time-study.js | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/core/time-studies/ec-time-study.js b/src/core/time-studies/ec-time-study.js
index 1ab118e4a4..91edb9a043 100644
--- a/src/core/time-studies/ec-time-study.js
+++ b/src/core/time-studies/ec-time-study.js
@@ -13,7 +13,6 @@ export class ECTimeStudyState extends TimeStudyState {
purchase(auto) {
if (GameEnd.creditsEverClosed) return false;
- EternityChallenge(this.id).hasUnlocked = true;
const clickTime = Date.now();
if (this.isBought && player.challenge.eternity.current === 0 && !auto) {
@@ -30,6 +29,7 @@ export class ECTimeStudyState extends TimeStudyState {
// If you haven't bought it and can buy it, reset the time of click, and
// send you into the EC, deduct your resources, and move you to the EC tab if that isn't disabled
ui.lastClickTime = 0;
+ EternityChallenge(this.id).hasUnlocked = true;
player.challenge.eternity.unlocked = this.id;
if (!auto) {
From e50ccb6dd9068b16fbcf48a686758d4d6595a960 Mon Sep 17 00:00:00 2001
From: HexaVault <44529573+HexaVault@users.noreply.github.com>
Date: Tue, 23 Jun 2026 12:30:30 +0100
Subject: [PATCH 31/44] fix blind
---
src/core/themes.js | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/core/themes.js b/src/core/themes.js
index ef86e43161..93fbbb1bfd 100644
--- a/src/core/themes.js
+++ b/src/core/themes.js
@@ -16,7 +16,7 @@ export const Theme = function Theme(name, config) {
this.isSecret = config.isSecret;
this.isDefault = function() {
- return name === "Normal";
+ return name === "Normal" || name === "S9";
};
this.isAvailable = function() {
From 60e872cafe23f5c3d594e5228f9ec4befcb4c449 Mon Sep 17 00:00:00 2001
From: HexaVault <44529573+HexaVault@users.noreply.github.com>
Date: Tue, 23 Jun 2026 12:50:39 +0100
Subject: [PATCH 32/44] set sidebar currency to currency 2 (antimatter) on
reset, to prevent it being on a locked currency, or displaying END after
reset
---
.../ui-modes/modern/ModernSidebarCurrency.vue | 12 +++++++++++-
1 file changed, 11 insertions(+), 1 deletion(-)
diff --git a/src/components/ui-modes/modern/ModernSidebarCurrency.vue b/src/components/ui-modes/modern/ModernSidebarCurrency.vue
index adc44a1a9a..e93f9b590e 100644
--- a/src/components/ui-modes/modern/ModernSidebarCurrency.vue
+++ b/src/components/ui-modes/modern/ModernSidebarCurrency.vue
@@ -5,7 +5,9 @@ export default {
return {
sidebarID: 0,
resourceName: "",
- resourceValue: new Decimal(0)
+ resourceValue: new Decimal(0),
+ fullGameCompletions: 0,
+ hasInit: false
};
},
computed: {
@@ -26,6 +28,14 @@ export default {
},
methods: {
update() {
+ if (!this.hasInit) {
+ this.fullGameCompletions = player.records.fullGameCompletions;
+ this.hasInit = true;
+ }
+ if (this.fullGameCompletions !== player.records.fullGameCompletions) {
+ player.options.sidebarResourceID = 2;
+ this.fullGameCompletions = player.records.fullGameCompletions;
+ }
this.sidebarID = player.options.sidebarResourceID;
this.resourceName = this.resource.resourceName ?? this.resource.optionName;
this.resourceValue.copyFrom(this.resource.value());
From 63c2d106bedd4e7fc0aaf64ee2b259d4dcf373a1 Mon Sep 17 00:00:00 2001
From: HexaVault <44529573+HexaVault@users.noreply.github.com>
Date: Tue, 23 Jun 2026 12:53:10 +0100
Subject: [PATCH 33/44] fixed sacrifice boost not actually needing the ra
unlock to function
---
src/core/celestials/ra/ra.js | 1 +
1 file changed, 1 insertion(+)
diff --git a/src/core/celestials/ra/ra.js b/src/core/celestials/ra/ra.js
index 5d84bc4edb..46050b3a20 100644
--- a/src/core/celestials/ra/ra.js
+++ b/src/core/celestials/ra/ra.js
@@ -418,6 +418,7 @@ export const GlyphAlteration = {
return this.isUnlocked && this.getSacrificePower(type) >= this.boostingThreshold;
},
sacrificeBoost(type) {
+ if (!GlyphAlteration.isBoosted(type)) return 0;
const capped = Math.clampMax(this.getSacrificePower(type), GlyphSacrificeHandler.maxSacrificeForEffects);
return Math.log10(Math.clampMin(capped / this.boostingThreshold, 1)) / 2;
},
From 5bcfb95aff76a63d152987df479ff9b8b0e69913 Mon Sep 17 00:00:00 2001
From: HexaVault <44529573+HexaVault@users.noreply.github.com>
Date: Tue, 23 Jun 2026 12:55:50 +0100
Subject: [PATCH 34/44] fix UNTIL not checking higher in the stack, resulting
in until
{
+ const state = frame.commandState;
+ if (state && state.prestigeLevel !== undefined) {
+ state.prestigeLevel = Math.max(state.prestigeLevel, flag);
+ }
+ });
}
EventHub.logic.on(GAME_EVENT.BIG_CRUNCH_AFTER, () => prestigeNotify(T.Infinity.$prestigeLevel));
From 269fa0496f36d1a13ce138b9ae479b5f284f3bb1 Mon Sep 17 00:00:00 2001
From: HexaVault <44529573+HexaVault@users.noreply.github.com>
Date: Tue, 23 Jun 2026 13:12:43 +0100
Subject: [PATCH 35/44] spelling
---
src/core/secret-formula/celestials/effarig.js | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/core/secret-formula/celestials/effarig.js b/src/core/secret-formula/celestials/effarig.js
index e837b4f187..aaf35b01f0 100644
--- a/src/core/secret-formula/celestials/effarig.js
+++ b/src/core/secret-formula/celestials/effarig.js
@@ -51,7 +51,7 @@ export const effarigUnlocks = {
id: 5,
label: "Eternity",
get description() {
- return ` Eternities generates Infinities
+ return ` Eternities generate Infinities
Infinity Points are no longer limited in any way in Effarig's Reality
You have unlocked The Nameless Ones`;
},
From 4cc6496f844a7e20b86c9511b0733befe0c3f876 Mon Sep 17 00:00:00 2001
From: HexaVault <44529573+HexaVault@users.noreply.github.com>
Date: Tue, 23 Jun 2026 13:17:16 +0100
Subject: [PATCH 36/44] fix tab capitalisation
---
src/core/secret-formula/tabs.js | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/core/secret-formula/tabs.js b/src/core/secret-formula/tabs.js
index 376688d56c..53f06b5fb5 100644
--- a/src/core/secret-formula/tabs.js
+++ b/src/core/secret-formula/tabs.js
@@ -89,7 +89,7 @@ export const tabs = [
},
{
key: "challenges",
- name: "Challenge records",
+ name: "Challenge Records",
symbol: "",
component: "ChallengeRecordsTab",
condition: () =>
From fa9f7ffb83e67dae89ed47e4518f679032f33b70 Mon Sep 17 00:00:00 2001
From: HexaVault <44529573+HexaVault@users.noreply.github.com>
Date: Tue, 23 Jun 2026 13:22:26 +0100
Subject: [PATCH 37/44] comments
---
src/core/themes.js | 26 ++++++++++++++------------
1 file changed, 14 insertions(+), 12 deletions(-)
diff --git a/src/core/themes.js b/src/core/themes.js
index 93fbbb1bfd..b1f259d890 100644
--- a/src/core/themes.js
+++ b/src/core/themes.js
@@ -133,6 +133,8 @@ Theme.create = function(name, settings) {
return new Theme(name, config);
};
+/* eslint-disable no-inline-comments */
+/* eslint-disable line-comment-position */
export const Themes = {
all: [
/* eslint-disable no-multi-spaces */
@@ -145,18 +147,18 @@ export const Themes = {
Theme.create("Inverted Metro", { metro: true, }),
Theme.create("AMOLED", { dark: true, }),
Theme.create("AMOLED Metro", { dark: true, metro: true, }),
- Theme.create("S1", { animated: true, secret: true, }),
- Theme.create("S2", { secret: true, }),
- Theme.create("S3", { secret: true, }),
- Theme.create("S4", { secret: true, }),
- Theme.create("S5", { secret: true, }),
- Theme.create("S6", { dark: true, animated: true, secret: true, }),
- Theme.create("S7", { metro: true, secret: true, }),
- Theme.create("S8", { metro: true, secret: true, }),
- Theme.create("S9", { secret: true, }),
- Theme.create("S10", { dark: true, metro: true, animated: true, secret: true, }),
- Theme.create("S11", { dark: true, animated: true, secret: true, }),
- Theme.create("S12", { secret: true, }),
+ Theme.create("S1", { animated: true, secret: true, }), // Christmas
+ Theme.create("S2", { secret: true, }), // Finnish
+ Theme.create("S3", { secret: true, }), // Confused
+ Theme.create("S4", { secret: true, }), // Design
+ Theme.create("S5", { secret: true, }), // Nicolas
+ Theme.create("S6", { dark: true, animated: true, secret: true, }), // Galactic
+ Theme.create("S7", { metro: true, secret: true, }), // Work
+ Theme.create("S8", { metro: true, secret: true, }), // Bliss
+ Theme.create("S9", { secret: true, }), // Blind
+ Theme.create("S10", { dark: true, metro: true, animated: true, secret: true, }), // Stellar
+ Theme.create("S11", { dark: true, animated: true, secret: true, }), // Blob
+ Theme.create("S12", { secret: true, }), // Aero
/* eslint-enable no-multi-spaces */
],
From 350c16b418ea796254ac238a8f7d94597fed1f76 Mon Sep 17 00:00:00 2001
From: HexaVault <44529573+HexaVault@users.noreply.github.com>
Date: Sat, 4 Jul 2026 21:51:54 +0100
Subject: [PATCH 38/44] r116 description now includes the idea of 0 infinities,
stop spawning 2 offline ui modals, achievement count is now correctly colored
in away entry
---
src/components/GameUiComponentFixed.vue | 1 -
src/components/modals/AwayProgressEntry.vue | 2 +-
src/core/secret-formula/achievements/normal-achievements.js | 2 +-
3 files changed, 2 insertions(+), 3 deletions(-)
diff --git a/src/components/GameUiComponentFixed.vue b/src/components/GameUiComponentFixed.vue
index 1dd0a95293..bff4ba5634 100644
--- a/src/components/GameUiComponentFixed.vue
+++ b/src/components/GameUiComponentFixed.vue
@@ -89,7 +89,6 @@ export default {
v-else-if="view.modal.current"
:modal="view.modal.current"
/>
-
diff --git a/src/components/modals/AwayProgressEntry.vue b/src/components/modals/AwayProgressEntry.vue
index c232c80e44..333f5b2c48 100644
--- a/src/components/modals/AwayProgressEntry.vue
+++ b/src/components/modals/AwayProgressEntry.vue
@@ -161,7 +161,7 @@ export default {
}
.c-modal-away-progress__realities,
-.c-modal-away-progress__achievement-count,
+.c-modal-away-progress__achievement-amount,
.c-modal-away-progress__reality-machines,
.c-modal-away-progress__imaginary-machines {
color: var(--color-reality);
diff --git a/src/core/secret-formula/achievements/normal-achievements.js b/src/core/secret-formula/achievements/normal-achievements.js
index d9111f45e2..887c05b39b 100644
--- a/src/core/secret-formula/achievements/normal-achievements.js
+++ b/src/core/secret-formula/achievements/normal-achievements.js
@@ -808,7 +808,7 @@ export const normalAchievements = [
{
id: 116,
name: "Do I really need to infinity",
- get description() { return `Eternity with only ${formatInt(1)} Infinity.`; },
+ get description() { return `Eternity with no more than ${formatInt(1)} Infinity.`; },
checkRequirement: () => Currency.infinities.lte(1),
checkEvent: GAME_EVENT.ETERNITY_RESET_BEFORE,
reward: "Multiplier to Infinity Points based on Infinities.",
From 29f92bf55f910b3fe37e37d66ed34b25d911f95d Mon Sep 17 00:00:00 2001
From: HexaVault <44529573+HexaVault@users.noreply.github.com>
Date: Sat, 4 Jul 2026 21:54:16 +0100
Subject: [PATCH 39/44] fix rep galaxy modal stating division if r126 is
unlocked but does not apply (doom)
---
src/components/modals/prestige/ReplicantiGalaxyModal.vue | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/components/modals/prestige/ReplicantiGalaxyModal.vue b/src/components/modals/prestige/ReplicantiGalaxyModal.vue
index 5e34799080..97d49345be 100644
--- a/src/components/modals/prestige/ReplicantiGalaxyModal.vue
+++ b/src/components/modals/prestige/ReplicantiGalaxyModal.vue
@@ -31,7 +31,7 @@ export default {
methods: {
update() {
this.replicanti.copyFrom(player.replicanti.amount);
- this.divideReplicanti = Achievement(126).isUnlocked;
+ this.divideReplicanti = Achievement(126).canBeApplied;
this.canBeBought = Replicanti.galaxies.gain;
if (this.replicanti.lt(Number.MAX_VALUE)) this.emitClose();
},
From 9bb6a4bf0eeea1b566f3eaa8efc998fbff31098b Mon Sep 17 00:00:00 2001
From: HexaVault <44529573+HexaVault@users.noreply.github.com>
Date: Sat, 4 Jul 2026 21:55:48 +0100
Subject: [PATCH 40/44] fix b tags
---
public/stylesheets/styles.css | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/public/stylesheets/styles.css b/public/stylesheets/styles.css
index ecc9ded2b1..36db398749 100644
--- a/public/stylesheets/styles.css
+++ b/public/stylesheets/styles.css
@@ -50,6 +50,12 @@ html {
/* css vars */
+/* stylelint-disable-next-line max-line-length */
+/* we use tags all over the place in order to indicate boldness, but a change has made this not work. Rather than replace all cases, we can use this shortcut */
+b {
+ font-weight: bold;
+}
+
#ui {
display: flex;
justify-content: center;
From 9ac1cfa6d18f18a0e6d1638bc3cdde221068c649 Mon Sep 17 00:00:00 2001
From: HexaVault <44529573+HexaVault@users.noreply.github.com>
Date: Sat, 4 Jul 2026 21:59:04 +0100
Subject: [PATCH 41/44] fix celnav hiding lai reality destruction flavor text,
having no singularities no longer causes singularity section to be slighly
wider than section below.
---
public/stylesheets/styles.css | 2 +-
src/core/secret-formula/celestials/navigation.js | 3 ++-
2 files changed, 3 insertions(+), 2 deletions(-)
diff --git a/public/stylesheets/styles.css b/public/stylesheets/styles.css
index 36db398749..079c2ad87c 100644
--- a/public/stylesheets/styles.css
+++ b/public/stylesheets/styles.css
@@ -7760,7 +7760,7 @@ kbd {
}
.o-laitela-run-button--large {
- width: 44rem;
+ width: 46rem;
}
.o-laitela-matter-amount {
diff --git a/src/core/secret-formula/celestials/navigation.js b/src/core/secret-formula/celestials/navigation.js
index 2d3473ddfa..fc76982435 100644
--- a/src/core/secret-formula/celestials/navigation.js
+++ b/src/core/secret-formula/celestials/navigation.js
@@ -1826,7 +1826,8 @@ export const celestialNavigation = {
if (complete === 1) {
return [
"Unlock Pelle",
- "The Celestial of Antimatter"
+ "The Celestial of Antimatter",
+ "Lai'tela's Reality has been destroyed"
];
}
let laitelaString = `${format(Currency.eternityPoints.value)} / ${format("1e4000")} EP`;
From 7ca1fb29d1bd625f73015b209823e1bae3b3dd60 Mon Sep 17 00:00:00 2001
From: HexaVault <44529573+HexaVault@users.noreply.github.com>
Date: Sat, 4 Jul 2026 23:24:40 +0100
Subject: [PATCH 42/44] Fix button in backup modal being borked, changelog
---
public/stylesheets/styles.css | 17 ++++
.../modals/options/BackupWindowModal.vue | 2 +-
src/core/secret-formula/changelog.js | 77 +++++++++++++++++++
src/core/storage/storage.js | 2 +-
4 files changed, 96 insertions(+), 2 deletions(-)
diff --git a/public/stylesheets/styles.css b/public/stylesheets/styles.css
index 079c2ad87c..010fd13732 100644
--- a/public/stylesheets/styles.css
+++ b/public/stylesheets/styles.css
@@ -2757,6 +2757,23 @@ br {
cursor: pointer;
}
+.c-file-import-backup {
+ width: 14.5rem;
+ height: 2.55rem;
+ position: absolute;
+ bottom: 5.5rem;
+ left: 31.3rem;
+ opacity: 0;
+ margin: -1.9rem -2rem;
+}
+
+.c-file-import-backup::before {
+ content: " ";
+ font-size: 100rem;
+ padding: 10rem 20rem;
+ cursor: pointer;
+}
+
/* #region l-options-grid */
.l-options-grid {
diff --git a/src/components/modals/options/BackupWindowModal.vue b/src/components/modals/options/BackupWindowModal.vue
index b0dfa34d68..deab6fbb49 100644
--- a/src/components/modals/options/BackupWindowModal.vue
+++ b/src/components/modals/options/BackupWindowModal.vue
@@ -101,7 +101,7 @@ export default {
+List of changes/fixes:
+
+- Fixed Sacrifice stating it was automated if Achievement 118/Sacrifce was disabled, under some conditions.
+- Fixed Achievement 143 not specifying that it only effects Antimatter Galaxies.
+- Fixed manual purchases of the 2xIP rebuyable upgrade resulting in being capped 1 upgrade too early,
+resulting in the player missing out on a small boost to make the multiplier a nice 1e1,000,000.
+- Fixed the Prestiges column in the Prestige Runs tab rounding prestiges overzealously,
+resulting in being able to have "1 Realities".
+- Changed some cases where "High Contrast" glyph colors were not used intentionally, resulting in inconsistent glyph coloring.
+- Fixed being able to Reality for less than 5000 Reality Machiones while having the Synthetic Symbolism upgrade lock active.
+- Properly disabled the Eternity Milestones for 200 and 1000 Eternities while Doomed.
+- Fixed the second boost from the Vacuum Rift always applying while Doomed, even when the Rift is drained. In turn, enabled ts192
+when this boost is disabled, in order to mitigate any significant changes to balancing.
+- Fixed being able to bypass the Paradoxically Atain upgrade lock by obtaining ACHNR. Doing so now will give a warning,
+like all other activities that result in breaking the conditions of a lock.
+- Added a note that Galaxies are also afected by the Pelle Upgrade that causes Dimension Boosts to no longer reset resources
+- Fixed Automator statements occasionally being skipped for no reason.
+- Fixed the Galaxy Generator stating that some Galaxy upgrades were never affordable, as it did not take into account galaxies
+that the player already has, but has not spent.
+- Moved Tesseracts to require a V unlock before being shown in the content catchup, rather than unlocking The Nameless Ones', in order to
+prevent the player from pre-emptively accessing certain h2p pages.
+- Added flavor text to the Sacrifice button while in The Nameless Ones' Reality.
+- Added a note to The Nameless Ones' Reality about Sacrifice being disabled.
+- Removed internal "doubleEverything" and "tripleEverything" dev functions, as they were dysfunctional.
+- Replaced internal "fixSave" dev function to a more successful/powerful version.
+- Fixed the Singularity Upgrade which boosts Dark Energy and Dark Matter based on Dilated Time not stating the boost to Dark Energy.
+- Removed useless internal argument which were never used.
+- Increased the precision of the Imaginary Upgrade "Transcience of Information" to allow a visible change when purchasing
+Rebuyable Imaginary Upgrades.
+- Renamed the 3rd Autobuyer challenge to "3rd Antimatter Dimension Autobuyer Challenge" from "3rd Antimatter Dimension Challenge" in order
+to maintain consistancy with all other Normal Challenges.
+- Fixed the Discord Rich Presence formatting Reality/Imaginary Machines weirdly and inconsistently.
+- Fixed cases where some Reality Upgrade requirements were prefixed with a number rather than a letter, causing certain notations which
+start with a character, rather than a number, to be incorrectly capitalised.
+- Fixed the automator stating "undefined attempted" whenever a nowait would result in a prestige command being skipped.
+- Fixed automator until not working with prestige events as intended.
+- Fixed cases where Blind theme was not edge-cased like Normal theme, resulting in the Blind theme having inconsistent coloring to
+the Normal theme in some cases.
+- Fixed being able to use the shift-click fast buy on Eternity Challenges, that you could not afford or unlock, still resulting in the
+Eternity Challenge being "unlocked" internally, and therefore showing in the Eternity Challenges tab pre-emptively.
+- Fixed the sigil for The Nameless Ones' Reality being slightly off center.
+- Disabled the DAB perk while doomed, to remain consistent with DAS and DAU.
+- Stopped showing the modal that pops up on your first Infinity, stating that you can disable animations, showing up if the player
+already has atleast 1 game completion.
+- Achievement 116 now states that you need to Eternity with no more than 1 Infinity, to include the possibility of 0 Infinities.
+- Fixed the modal that shows up on Replicanti Galaxy purchase (when confirmation is enabled) from stating that your Replicanti will be
+divided by 1.79e308 rather than reset to 0 while Doomed.
+- Fixed the Achievement Count line, when showing you the progress made while offline, not being flavored correctly.
+- Fixed some text not being bolded properly due to using depreciated tags.
+- Fixed flavor text, stating that "Lai'tela's Reality has been destroyed", disappearing once you are able to unlock Omniprescent
+Obliteration, as it was inconsistent with all other Reality flavor text.
+- Fixed the section of the Lai'tela tab below the Singularities part being slightly thinner if you had yet to have a Signularity and
+therefore unlock Singularity Milestones.
+- Fixed the confirmation modal showing an asterisk when entering Eternity Challenge 6 while in The Nameless Ones' Reality, instead of
+scrambled text.
+- Capped the Replicanti Glyph Doomed effect being able to become Infinite and breaking Replianti, by capping it at 1e308.
+- Capped ts41 in Effarig's Reality during the Eternity layer to 1e50.
+- Doomed Achievement 187 (r187) now properly states that its unlock condition is Dilating Time while Dooming, not Unlocking Dilation.
+- Fixed the import button in the Automatic Backups Menu having its click detection at the bottom of the page,
+and being broken anyways.
+- Fixed accidentally spawning 2 offline progress modals rather than 1
+- Fixed the Antimatter Galaxy button sometimes incorrectly stating that certain things would not be reset, when they would be.
+- Fixed cases where changing an upgrade but not having a change to its effect would result in the old effect formatting being shown
+untill the player reloaded the subtab (i.e. by changing away and back).
+- Added a note to the h2p tab for Replicanti if ts192 is unlocked.
+- Fixed the progress bar at the bottom of the Antimatter Dimensions tab not working properly when in Dilation while Doomed, and showing
+the progress to gaining more TP, rather than the progress to the Galaxy Generator.
+
- Fixed some spelling/punctuation, and standardized it elsewhere.
+
+
+`
+ },
{
date: [2024, 8, 12],
name: "Hi Ra",
diff --git a/src/core/storage/storage.js b/src/core/storage/storage.js
index fc2fa5e50a..97d3d64c09 100644
--- a/src/core/storage/storage.js
+++ b/src/core/storage/storage.js
@@ -400,7 +400,7 @@ export const GameStorage = {
const id = Number(backupKey);
const storageKey = this.backupDataKey(this.currentSlot, id);
localStorage.setItem(storageKey, GameSaveSerializer.serialize(backupData[backupKey]));
- this.backupTimeData[id] = {
+ this.lastBackupTimes[id] = {
backupTimer: backupData.time[id].backupTimer,
date: backupData.time[id].date,
};
From 5c51e69296003e321f24b4f6943a05c2a70ab954 Mon Sep 17 00:00:00 2001
From: HexaVault <44529573+HexaVault@users.noreply.github.com>
Date: Sun, 5 Jul 2026 11:54:26 +0100
Subject: [PATCH 43/44] Fix prestige rows being slightly too thin
---
.../tabs/past-prestige-runs/PastPrestigeRunsContainer.vue | 4 ++--
src/core/secret-formula/changelog.js | 4 +++-
2 files changed, 5 insertions(+), 3 deletions(-)
diff --git a/src/components/tabs/past-prestige-runs/PastPrestigeRunsContainer.vue b/src/components/tabs/past-prestige-runs/PastPrestigeRunsContainer.vue
index b392ef8cd1..73217df061 100644
--- a/src/components/tabs/past-prestige-runs/PastPrestigeRunsContainer.vue
+++ b/src/components/tabs/past-prestige-runs/PastPrestigeRunsContainer.vue
@@ -294,9 +294,9 @@ export default {
display: block;
border: 0.05rem solid #999999;
color: var(--color-text);
- width: 100%;
+ width: 100.2%;
padding: 0.2rem 0;
- margin: -0.1rem;
+ margin: -0.05rem;
}
.l-no-records {
diff --git a/src/core/secret-formula/changelog.js b/src/core/secret-formula/changelog.js
index 95a587607c..dc221f8504 100644
--- a/src/core/secret-formula/changelog.js
+++ b/src/core/secret-formula/changelog.js
@@ -79,7 +79,9 @@ and being broken anyways.
untill the player reloaded the subtab (i.e. by changing away and back).
Added a note to the h2p tab for Replicanti if ts192 is unlocked.
Fixed the progress bar at the bottom of the Antimatter Dimensions tab not working properly when in Dilation while Doomed, and showing
-the progress to gaining more TP, rather than the progress to the Galaxy Generator.
+the progress to gaining more TP, rather than the progress to the Galaxy Generator.
+Fixed rows of tables in the Past Prestige Runs subtab being very slightly thinner then normal if it had stated that you had not done X
+amount of a prestige yet.
Fixed some spelling/punctuation, and standardized it elsewhere.
From 376e80d844d58a4494548e215bb677ae6380ab6b Mon Sep 17 00:00:00 2001
From: HexaVault <44529573+HexaVault@users.noreply.github.com>
Date: Sun, 5 Jul 2026 12:05:14 +0100
Subject: [PATCH 44/44] tpyos
---
src/core/secret-formula/changelog.js | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/src/core/secret-formula/changelog.js b/src/core/secret-formula/changelog.js
index dc221f8504..aa5526ed52 100644
--- a/src/core/secret-formula/changelog.js
+++ b/src/core/secret-formula/changelog.js
@@ -15,7 +15,7 @@ export const changelog = [
If you see this, please let whoever pushed this PR know that the date needs changing & this text removed. Thanks in advance - Hexa.
List of changes/fixes:
-- Fixed Sacrifice stating it was automated if Achievement 118/Sacrifce was disabled, under some conditions.
+- Fixed Sacrifice stating it was automated if Achievement 118/Sacrifice was disabled, under some conditions.
- Fixed Achievement 143 not specifying that it only effects Antimatter Galaxies.
- Fixed manual purchases of the 2xIP rebuyable upgrade resulting in being capped 1 upgrade too early,
resulting in the player missing out on a small boost to make the multiplier a nice 1e1,000,000.
@@ -110,9 +110,9 @@ amount of a prestige yet.
Bugfixes:
-- Fixed a BH pulse does not apply during offline progess
-- Fixed a BH inversion is active while it is being disabled
-- Fixed a BH inversion slider is visible while it is being disabled
+- Fixed BH pulse not applying during offline progess
+- Fixed a case where BH inversion is active while it is disabled
+- Fixed a case where BH inversion slider is visible while it is disabled
`