From 0ae6aa12b2d09e281f45b5b48ece5172e534bdc0 Mon Sep 17 00:00:00 2001 From: Hikari Date: Tue, 24 Mar 2026 20:44:25 -0700 Subject: [PATCH] fix: rewrite prestige/transcendence formula and rebalance progression --- apps/api/src/data/bosses.ts | 108 +++++++++---------- apps/api/src/data/transcendenceUpgrades.ts | 30 +++--- apps/api/src/services/prestige.ts | 11 +- apps/api/src/services/transcendence.ts | 2 +- apps/api/test/routes/transcendence.spec.ts | 2 +- apps/api/test/services/prestige.spec.ts | 17 +-- apps/api/test/services/transcendence.spec.ts | 16 ++- 7 files changed, 98 insertions(+), 88 deletions(-) diff --git a/apps/api/src/data/bosses.ts b/apps/api/src/data/bosses.ts index 16f6b16..b8323ee 100644 --- a/apps/api/src/data/bosses.ts +++ b/apps/api/src/data/bosses.ts @@ -353,7 +353,7 @@ export const defaultBosses: Array = [ id: "seraph_guardian", maxHp: 500_000_000, name: "The Seraph Guardian", - prestigeRequirement: 6, + prestigeRequirement: 1, status: "locked", upgradeRewards: [ "click_4" ], zoneId: "celestial_reaches", @@ -371,7 +371,7 @@ export const defaultBosses: Array = [ id: "fallen_archangel", maxHp: 2_000_000_000, name: "The Fallen Archangel", - prestigeRequirement: 7, + prestigeRequirement: 2, status: "locked", upgradeRewards: [], zoneId: "celestial_reaches", @@ -389,7 +389,7 @@ export const defaultBosses: Array = [ id: "divine_judge", maxHp: 8_000_000_000, name: "The Divine Judge", - prestigeRequirement: 8, + prestigeRequirement: 2, status: "locked", upgradeRewards: [ "divine_covenant" ], zoneId: "celestial_reaches", @@ -407,7 +407,7 @@ export const defaultBosses: Array = [ id: "celestial_titan", maxHp: 30_000_000_000, name: "The Celestial Titan", - prestigeRequirement: 9, + prestigeRequirement: 2, status: "locked", upgradeRewards: [], zoneId: "celestial_reaches", @@ -425,7 +425,7 @@ export const defaultBosses: Array = [ id: "the_first_light", maxHp: 100_000_000_000, name: "The First Light", - prestigeRequirement: 10, + prestigeRequirement: 2, status: "locked", upgradeRewards: [], zoneId: "celestial_reaches", @@ -444,7 +444,7 @@ export const defaultBosses: Array = [ id: "depth_leviathan", maxHp: 250_000_000_000, name: "The Depth Leviathan", - prestigeRequirement: 9, + prestigeRequirement: 2, status: "locked", upgradeRewards: [], zoneId: "abyssal_trench", @@ -462,7 +462,7 @@ export const defaultBosses: Array = [ id: "kraken_elder", maxHp: 1_000_000_000_000, name: "The Elder Kraken", - prestigeRequirement: 10, + prestigeRequirement: 2, status: "locked", upgradeRewards: [ "abyssal_pact" ], zoneId: "abyssal_trench", @@ -480,7 +480,7 @@ export const defaultBosses: Array = [ id: "abyssal_colossus", maxHp: 4_000_000_000_000, name: "The Abyssal Colossus", - prestigeRequirement: 11, + prestigeRequirement: 2, status: "locked", upgradeRewards: [], zoneId: "abyssal_trench", @@ -498,7 +498,7 @@ export const defaultBosses: Array = [ id: "the_deep_one", maxHp: 15_000_000_000_000, name: "The Deep One", - prestigeRequirement: 12, + prestigeRequirement: 3, status: "locked", upgradeRewards: [ "global_4" ], zoneId: "abyssal_trench", @@ -516,7 +516,7 @@ export const defaultBosses: Array = [ id: "elder_abomination", maxHp: 50_000_000_000_000, name: "The Elder Abomination", - prestigeRequirement: 13, + prestigeRequirement: 3, status: "locked", upgradeRewards: [], zoneId: "abyssal_trench", @@ -535,7 +535,7 @@ export const defaultBosses: Array = [ id: "demon_prince", maxHp: 120_000_000_000_000, name: "The Demon Prince", - prestigeRequirement: 12, + prestigeRequirement: 3, status: "locked", upgradeRewards: [], zoneId: "infernal_court", @@ -553,7 +553,7 @@ export const defaultBosses: Array = [ id: "hellfire_titan", maxHp: 500_000_000_000_000, name: "The Hellfire Titan", - prestigeRequirement: 13, + prestigeRequirement: 3, status: "locked", upgradeRewards: [ "celestial_mandate" ], zoneId: "infernal_court", @@ -571,7 +571,7 @@ export const defaultBosses: Array = [ id: "lord_of_sin", maxHp: 2_000_000_000_000_000, name: "The Lord of Sin", - prestigeRequirement: 14, + prestigeRequirement: 3, status: "locked", upgradeRewards: [], zoneId: "infernal_court", @@ -589,7 +589,7 @@ export const defaultBosses: Array = [ id: "infernal_sovereign", maxHp: 6_000_000_000_000_000, name: "The Infernal Sovereign", - prestigeRequirement: 15, + prestigeRequirement: 3, status: "locked", upgradeRewards: [ "click_5" ], zoneId: "infernal_court", @@ -607,7 +607,7 @@ export const defaultBosses: Array = [ id: "the_fallen", maxHp: 8_000_000_000_000_000, name: "The Fallen", - prestigeRequirement: 16, + prestigeRequirement: 4, status: "locked", upgradeRewards: [], zoneId: "infernal_court", @@ -626,7 +626,7 @@ export const defaultBosses: Array = [ id: "prism_golem", maxHp: 2e16, name: "The Prism Golem", - prestigeRequirement: 15, + prestigeRequirement: 3, status: "locked", upgradeRewards: [], zoneId: "crystalline_spire", @@ -644,7 +644,7 @@ export const defaultBosses: Array = [ id: "crystal_drake", maxHp: 8e16, name: "The Crystal Drake", - prestigeRequirement: 16, + prestigeRequirement: 4, status: "locked", upgradeRewards: [ "void_ascendancy" ], zoneId: "crystalline_spire", @@ -662,7 +662,7 @@ export const defaultBosses: Array = [ id: "the_faceted", maxHp: 3e17, name: "The Faceted", - prestigeRequirement: 17, + prestigeRequirement: 4, status: "locked", upgradeRewards: [], zoneId: "crystalline_spire", @@ -680,7 +680,7 @@ export const defaultBosses: Array = [ id: "diamond_colossus", maxHp: 1e18, name: "The Diamond Colossus", - prestigeRequirement: 18, + prestigeRequirement: 4, status: "locked", upgradeRewards: [], zoneId: "crystalline_spire", @@ -698,7 +698,7 @@ export const defaultBosses: Array = [ id: "crystal_sovereign", maxHp: 4e18, name: "The Crystal Sovereign", - prestigeRequirement: 19, + prestigeRequirement: 4, status: "locked", upgradeRewards: [], zoneId: "crystalline_spire", @@ -717,7 +717,7 @@ export const defaultBosses: Array = [ id: "void_herald", maxHp: 1e19, name: "The Void Herald", - prestigeRequirement: 18, + prestigeRequirement: 4, status: "locked", upgradeRewards: [], zoneId: "void_sanctum", @@ -735,7 +735,7 @@ export const defaultBosses: Array = [ id: "eternal_shade", maxHp: 5e19, name: "The Eternal Shade", - prestigeRequirement: 19, + prestigeRequirement: 4, status: "locked", upgradeRewards: [ "divine_harmony" ], zoneId: "void_sanctum", @@ -753,7 +753,7 @@ export const defaultBosses: Array = [ id: "the_unmaker", maxHp: 2e20, name: "The Unmaker", - prestigeRequirement: 20, + prestigeRequirement: 5, status: "locked", upgradeRewards: [], zoneId: "void_sanctum", @@ -771,7 +771,7 @@ export const defaultBosses: Array = [ id: "void_progenitor", maxHp: 8e20, name: "The Void Progenitor", - prestigeRequirement: 21, + prestigeRequirement: 5, status: "locked", upgradeRewards: [], zoneId: "void_sanctum", @@ -789,7 +789,7 @@ export const defaultBosses: Array = [ id: "void_emperor", maxHp: 3e21, name: "The Void Emperor", - prestigeRequirement: 22, + prestigeRequirement: 5, status: "locked", upgradeRewards: [], zoneId: "void_sanctum", @@ -808,7 +808,7 @@ export const defaultBosses: Array = [ id: "throne_warden", maxHp: 1e22, name: "The Throne Warden", - prestigeRequirement: 21, + prestigeRequirement: 5, status: "locked", upgradeRewards: [], zoneId: "eternal_throne", @@ -826,7 +826,7 @@ export const defaultBosses: Array = [ id: "eternal_knight", maxHp: 5e22, name: "The Eternal Knight", - prestigeRequirement: 22, + prestigeRequirement: 5, status: "locked", upgradeRewards: [ "infernal_fury" ], zoneId: "eternal_throne", @@ -844,7 +844,7 @@ export const defaultBosses: Array = [ id: "the_undying", maxHp: 2e23, name: "The Undying", - prestigeRequirement: 23, + prestigeRequirement: 5, status: "locked", upgradeRewards: [], zoneId: "eternal_throne", @@ -862,7 +862,7 @@ export const defaultBosses: Array = [ id: "apex_sovereign", maxHp: 8e23, name: "The Apex Sovereign", - prestigeRequirement: 24, + prestigeRequirement: 5, status: "locked", upgradeRewards: [], zoneId: "eternal_throne", @@ -880,7 +880,7 @@ export const defaultBosses: Array = [ id: "the_apex", maxHp: 3e24, name: "The Apex", - prestigeRequirement: 25, + prestigeRequirement: 6, status: "locked", upgradeRewards: [], zoneId: "eternal_throne", @@ -899,7 +899,7 @@ export const defaultBosses: Array = [ id: "chaos_wyrm", maxHp: 1e26, name: "The Chaos Wyrm", - prestigeRequirement: 26, + prestigeRequirement: 6, status: "locked", upgradeRewards: [], zoneId: "primordial_chaos", @@ -917,7 +917,7 @@ export const defaultBosses: Array = [ id: "creation_engine", maxHp: 5e27, name: "The Creation Engine", - prestigeRequirement: 27, + prestigeRequirement: 6, status: "locked", upgradeRewards: [ "aether_weaver_1" ], zoneId: "primordial_chaos", @@ -935,7 +935,7 @@ export const defaultBosses: Array = [ id: "entropy_avatar", maxHp: 2e29, name: "The Entropy Avatar", - prestigeRequirement: 29, + prestigeRequirement: 7, status: "locked", upgradeRewards: [], zoneId: "primordial_chaos", @@ -953,7 +953,7 @@ export const defaultBosses: Array = [ id: "primordial_titan", maxHp: 8e30, name: "The Primordial Titan", - prestigeRequirement: 31, + prestigeRequirement: 7, status: "locked", upgradeRewards: [], zoneId: "primordial_chaos", @@ -972,7 +972,7 @@ export const defaultBosses: Array = [ id: "expanse_drifter", maxHp: 3e33, name: "The Expanse Drifter", - prestigeRequirement: 33, + prestigeRequirement: 8, status: "locked", upgradeRewards: [ "titan_warrior_1" ], zoneId: "infinite_expanse", @@ -990,7 +990,7 @@ export const defaultBosses: Array = [ id: "horizon_beast", maxHp: 1e37, name: "The Horizon Beast", - prestigeRequirement: 35, + prestigeRequirement: 8, status: "locked", upgradeRewards: [], zoneId: "infinite_expanse", @@ -1008,7 +1008,7 @@ export const defaultBosses: Array = [ id: "infinity_construct", maxHp: 5e40, name: "The Infinity Construct", - prestigeRequirement: 37, + prestigeRequirement: 8, status: "locked", upgradeRewards: [], zoneId: "infinite_expanse", @@ -1026,7 +1026,7 @@ export const defaultBosses: Array = [ id: "expanse_sovereign", maxHp: 2e44, name: "The Expanse Sovereign", - prestigeRequirement: 39, + prestigeRequirement: 9, status: "locked", upgradeRewards: [], zoneId: "infinite_expanse", @@ -1045,7 +1045,7 @@ export const defaultBosses: Array = [ id: "forge_guardian", maxHp: 8e47, name: "The Forge Guardian", - prestigeRequirement: 41, + prestigeRequirement: 9, status: "locked", upgradeRewards: [ "nexus_sage_1" ], zoneId: "reality_forge", @@ -1063,7 +1063,7 @@ export const defaultBosses: Array = [ id: "reality_shaper", maxHp: 4e52, name: "The Reality Shaper", - prestigeRequirement: 44, + prestigeRequirement: 10, status: "locked", upgradeRewards: [], zoneId: "reality_forge", @@ -1081,7 +1081,7 @@ export const defaultBosses: Array = [ id: "creation_prime", maxHp: 2e57, name: "The Creation Prime", - prestigeRequirement: 47, + prestigeRequirement: 11, status: "locked", upgradeRewards: [], zoneId: "reality_forge", @@ -1099,7 +1099,7 @@ export const defaultBosses: Array = [ id: "reality_architect", maxHp: 8e61, name: "The Reality Architect", - prestigeRequirement: 49, + prestigeRequirement: 11, status: "locked", upgradeRewards: [], zoneId: "reality_forge", @@ -1118,7 +1118,7 @@ export const defaultBosses: Array = [ id: "storm_colossus", maxHp: 4e65, name: "The Storm Colossus", - prestigeRequirement: 51, + prestigeRequirement: 12, status: "locked", upgradeRewards: [], zoneId: "cosmic_maelstrom", @@ -1136,7 +1136,7 @@ export const defaultBosses: Array = [ id: "force_prime", maxHp: 2e71, name: "The Force Prime", - prestigeRequirement: 54, + prestigeRequirement: 12, status: "locked", upgradeRewards: [], zoneId: "cosmic_maelstrom", @@ -1154,7 +1154,7 @@ export const defaultBosses: Array = [ id: "maelstrom_god", maxHp: 1e77, name: "The Maelstrom God", - prestigeRequirement: 57, + prestigeRequirement: 13, status: "locked", upgradeRewards: [], zoneId: "cosmic_maelstrom", @@ -1172,7 +1172,7 @@ export const defaultBosses: Array = [ id: "cosmic_annihilator", maxHp: 5e82, name: "The Cosmic Annihilator", - prestigeRequirement: 59, + prestigeRequirement: 13, status: "locked", upgradeRewards: [], zoneId: "cosmic_maelstrom", @@ -1191,7 +1191,7 @@ export const defaultBosses: Array = [ id: "ancient_sentinel", maxHp: 2e88, name: "The Ancient Sentinel", - prestigeRequirement: 61, + prestigeRequirement: 14, status: "locked", upgradeRewards: [ "astral_sovereign_1" ], zoneId: "primeval_sanctum", @@ -1209,7 +1209,7 @@ export const defaultBosses: Array = [ id: "time_elder", maxHp: 1e95, name: "The Time Elder", - prestigeRequirement: 65, + prestigeRequirement: 15, status: "locked", upgradeRewards: [], zoneId: "primeval_sanctum", @@ -1227,7 +1227,7 @@ export const defaultBosses: Array = [ id: "origin_beast", maxHp: 8e101, name: "The Origin Beast", - prestigeRequirement: 69, + prestigeRequirement: 16, status: "locked", upgradeRewards: [], zoneId: "primeval_sanctum", @@ -1245,7 +1245,7 @@ export const defaultBosses: Array = [ id: "primeval_god", maxHp: 5e108, name: "The Primeval God", - prestigeRequirement: 74, + prestigeRequirement: 17, status: "locked", upgradeRewards: [], zoneId: "primeval_sanctum", @@ -1264,7 +1264,7 @@ export const defaultBosses: Array = [ id: "absolute_herald", maxHp: 2e116, name: "The Absolute Herald", - prestigeRequirement: 76, + prestigeRequirement: 17, status: "locked", upgradeRewards: [ "primordial_mage_1" ], zoneId: "the_absolute", @@ -1282,7 +1282,7 @@ export const defaultBosses: Array = [ id: "void_convergence", maxHp: 1e125, name: "The Void Convergence", - prestigeRequirement: 79, + prestigeRequirement: 18, status: "locked", upgradeRewards: [], zoneId: "the_absolute", @@ -1300,7 +1300,7 @@ export const defaultBosses: Array = [ id: "eternal_end", maxHp: 5e134, name: "The Eternal End", - prestigeRequirement: 83, + prestigeRequirement: 19, status: "locked", upgradeRewards: [], zoneId: "the_absolute", @@ -1318,7 +1318,7 @@ export const defaultBosses: Array = [ id: "the_absolute_one", maxHp: 2e145, name: "The Absolute One", - prestigeRequirement: 88, + prestigeRequirement: 20, status: "locked", upgradeRewards: [], zoneId: "the_absolute", diff --git a/apps/api/src/data/transcendenceUpgrades.ts b/apps/api/src/data/transcendenceUpgrades.ts index cd4f301..8cfac04 100644 --- a/apps/api/src/data/transcendenceUpgrades.ts +++ b/apps/api/src/data/transcendenceUpgrades.ts @@ -11,7 +11,7 @@ export const defaultTranscendenceUpgrades: Array = [ // ── Income multipliers ────────────────────────────────────────────────────── { category: "income", - cost: 5, + cost: 2, description: "The echoes of past runs linger, amplifying your guild's income by 25%.", id: "echo_income_1", @@ -20,7 +20,7 @@ export const defaultTranscendenceUpgrades: Array = [ }, { category: "income", - cost: 10, + cost: 4, description: "Your transcendent experience resonates through your guild, boosting income by 50%.", id: "echo_income_2", @@ -29,7 +29,7 @@ export const defaultTranscendenceUpgrades: Array = [ }, { category: "income", - cost: 20, + cost: 8, description: "The harmony of multiple timelines surges through your guild, doubling its income.", id: "echo_income_3", @@ -38,7 +38,7 @@ export const defaultTranscendenceUpgrades: Array = [ }, { category: "income", - cost: 40, + cost: 16, description: "Ethereal energy overflows from your transcendence, tripling your guild's income.", id: "echo_income_4", @@ -47,7 +47,7 @@ export const defaultTranscendenceUpgrades: Array = [ }, { category: "income", - cost: 80, + cost: 32, description: "The infinite chorus of every run you've ever played amplifies your guild fivefold.", id: "echo_income_5", @@ -58,7 +58,7 @@ export const defaultTranscendenceUpgrades: Array = [ // ── Combat multipliers ────────────────────────────────────────────────────── { category: "combat", - cost: 5, + cost: 2, description: "Memories of countless battles harden your adventurers, increasing party DPS by 25%.", id: "echo_combat_1", @@ -67,7 +67,7 @@ export const defaultTranscendenceUpgrades: Array = [ }, { category: "combat", - cost: 15, + cost: 6, description: "Veterans of transcendence know how to fight smarter, boosting party DPS by 50%.", id: "echo_combat_2", @@ -76,7 +76,7 @@ export const defaultTranscendenceUpgrades: Array = [ }, { category: "combat", - cost: 35, + cost: 12, description: "Your warriors carry the strength of every fallen timeline, doubling party DPS.", id: "echo_combat_3", @@ -87,7 +87,7 @@ export const defaultTranscendenceUpgrades: Array = [ // ── Prestige threshold reductions ────────────────────────────────────────── { category: "prestige_threshold", - cost: 8, + cost: 3, description: "Experience from past lives shortens the road to prestige — threshold reduced by 10%.", id: "echo_prestige_threshold_1", @@ -96,7 +96,7 @@ export const defaultTranscendenceUpgrades: Array = [ }, { category: "prestige_threshold", - cost: 20, + cost: 6, description: "You've walked this path so many times you know every shortcut — threshold reduced by 20%.", id: "echo_prestige_threshold_2", @@ -107,7 +107,7 @@ export const defaultTranscendenceUpgrades: Array = [ // ── Prestige runestone multipliers ───────────────────────────────────────── { category: "prestige_runestones", - cost: 8, + cost: 3, description: "Transcendent insight attunes you to the runestones, earning 50% more per prestige.", id: "echo_prestige_runestones_1", @@ -116,7 +116,7 @@ export const defaultTranscendenceUpgrades: Array = [ }, { category: "prestige_runestones", - cost: 20, + cost: 6, description: "You have mastered the art of runestone crafting, doubling your prestige runestone yield.", id: "echo_prestige_runestones_2", @@ -127,7 +127,7 @@ export const defaultTranscendenceUpgrades: Array = [ // ── Echo meta multipliers ─────────────────────────────────────────────────── { category: "echo_meta", - cost: 50, + cost: 25, description: "Your transcendence resonates deeper, amplifying future echo yields by 25%.", id: "echo_meta_1", @@ -136,7 +136,7 @@ export const defaultTranscendenceUpgrades: Array = [ }, { category: "echo_meta", - cost: 150, + cost: 75, description: "Each loop of existence makes the next more powerful — future echo yields +50%.", id: "echo_meta_2", @@ -145,7 +145,7 @@ export const defaultTranscendenceUpgrades: Array = [ }, { category: "echo_meta", - cost: 400, + cost: 200, description: "You have mastered the infinite spiral of transcendence, doubling all future echo yields.", id: "echo_meta_3", diff --git a/apps/api/src/services/prestige.ts b/apps/api/src/services/prestige.ts index 41dbd43..dad8ce3 100644 --- a/apps/api/src/services/prestige.ts +++ b/apps/api/src/services/prestige.ts @@ -15,7 +15,6 @@ import type { } from "@elysium/types"; const basePrestigeGoldThreshold = 1_000_000; -const thresholdScaleFactor = 5; const runestonesPerPrestigeLevel = 10; const milestoneInterval = 5; const milestoneRunestonesPerInterval = 25; @@ -29,7 +28,8 @@ const maxBaseRunestones = 200; /** * Calculates the gold threshold required for the next prestige. - * Formula: BASE * SCALE_FACTOR^prestigeCount — each prestige makes the next threshold harder. + * Formula: BASE * (count + 1)^2 — polynomial growth that peaks around prestige 8–10 + * then gets easier as the production multiplier overtakes it. * @param prestigeCount - The current number of prestiges completed. * @param thresholdMultiplier - An optional echo-upgrade multiplier applied to the threshold. * @returns The gold amount required to prestige. @@ -40,7 +40,7 @@ const calculatePrestigeThreshold = ( ): number => { return ( basePrestigeGoldThreshold - * Math.pow(thresholdScaleFactor, prestigeCount) + * Math.pow(prestigeCount + 1, 2) * thresholdMultiplier ); }; @@ -146,14 +146,15 @@ const calculateRunestones = (parameters: RunestoneParameters): number => { /** * Calculates the new prestige production multiplier. - * Formula: 1.15^prestigeCount — exponential scaling per prestige. + * Formula: 1.25^prestigeCount — exponential scaling per prestige that eventually + * overtakes the polynomial threshold growth, making late prestiges progressively easier. * @param prestigeCount - The new prestige count. * @returns The production multiplier for the new prestige level. */ const calculateProductionMultiplier = ( prestigeCount: number, ): number => { - return Math.pow(1.15, prestigeCount); + return Math.pow(1.25, prestigeCount); }; /** diff --git a/apps/api/src/services/transcendence.ts b/apps/api/src/services/transcendence.ts index ebda467..463ef62 100644 --- a/apps/api/src/services/transcendence.ts +++ b/apps/api/src/services/transcendence.ts @@ -20,7 +20,7 @@ const finalBossId = "the_absolute_one"; /** * Base constant used in the echo yield formula. */ -const echoFormulaConstant = 853; +const echoFormulaConstant = 224; const getCategoryMultiplier = ( purchasedIds: Array, diff --git a/apps/api/test/routes/transcendence.spec.ts b/apps/api/test/routes/transcendence.spec.ts index 270c5e5..9aba6e2 100644 --- a/apps/api/test/routes/transcendence.spec.ts +++ b/apps/api/test/routes/transcendence.spec.ts @@ -158,7 +158,7 @@ describe("transcendence route", () => { const res = await post("/buy-upgrade", { upgradeId: "echo_income_1" }); expect(res.status).toBe(200); const body = await res.json() as { echoesRemaining: number; purchasedUpgradeIds: string[] }; - expect(body.echoesRemaining).toBe(95); // 100 - 5 + expect(body.echoesRemaining).toBe(98); // 100 - 2 expect(body.purchasedUpgradeIds).toContain("echo_income_1"); }); diff --git a/apps/api/test/services/prestige.spec.ts b/apps/api/test/services/prestige.spec.ts index b3a9c39..1638781 100644 --- a/apps/api/test/services/prestige.spec.ts +++ b/apps/api/test/services/prestige.spec.ts @@ -55,15 +55,18 @@ const makeMinimalState = (overrides: Partial = {}): GameState => describe("calculatePrestigeThreshold", () => { it("returns base threshold at count 0", () => { + // base × (0+1)^2 = 1_000_000 × 1 = 1_000_000 expect(calculatePrestigeThreshold(0)).toBe(1_000_000); }); - it("returns 5× at count 1", () => { - expect(calculatePrestigeThreshold(1)).toBe(5_000_000); + it("returns 4× base at count 1", () => { + // base × (1+1)^2 = 1_000_000 × 4 = 4_000_000 + expect(calculatePrestigeThreshold(1)).toBe(4_000_000); }); - it("returns 25× at count 2", () => { - expect(calculatePrestigeThreshold(2)).toBe(25_000_000); + it("returns 9× base at count 2", () => { + // base × (2+1)^2 = 1_000_000 × 9 = 9_000_000 + expect(calculatePrestigeThreshold(2)).toBe(9_000_000); }); it("applies threshold multiplier correctly", () => { @@ -128,12 +131,12 @@ describe("calculateProductionMultiplier", () => { expect(calculateProductionMultiplier(0)).toBe(1); }); - it("returns 1.15 at count 1", () => { - expect(calculateProductionMultiplier(1)).toBeCloseTo(1.15); + it("returns 1.25 at count 1", () => { + expect(calculateProductionMultiplier(1)).toBeCloseTo(1.25); }); it("scales exponentially", () => { - expect(calculateProductionMultiplier(10)).toBeCloseTo(Math.pow(1.15, 10)); + expect(calculateProductionMultiplier(10)).toBeCloseTo(Math.pow(1.25, 10)); }); }); diff --git a/apps/api/test/services/transcendence.spec.ts b/apps/api/test/services/transcendence.spec.ts index 8876f3a..f9a47ac 100644 --- a/apps/api/test/services/transcendence.spec.ts +++ b/apps/api/test/services/transcendence.spec.ts @@ -97,20 +97,21 @@ describe("isEligibleForTranscendence", () => { describe("calculateEchoes", () => { it("handles prestige count of 0 by treating it as 1", () => { - // safeCount = max(0, 1) = 1; floor(853 / sqrt(1)) = 853 - expect(calculateEchoes(0, 1)).toBe(853); + // safeCount = max(0, 1) = 1; floor(224 / sqrt(1)) = 224 + expect(calculateEchoes(0, 1)).toBe(224); }); it("calculates echoes at count 1", () => { - expect(calculateEchoes(1, 1)).toBe(853); + // floor(224 / sqrt(1)) = 224 + expect(calculateEchoes(1, 1)).toBe(224); }); it("decreases echoes with higher prestige count", () => { const echoesAt1 = calculateEchoes(1, 1); const echoesAt4 = calculateEchoes(4, 1); expect(echoesAt4).toBeLessThan(echoesAt1); - // floor(853 / sqrt(4)) = floor(853 / 2) = 426 - expect(echoesAt4).toBe(426); + // floor(224 / sqrt(4)) = floor(224 / 2) = 112 + expect(echoesAt4).toBe(112); }); it("applies echoMetaMultiplier", () => { @@ -118,6 +119,11 @@ describe("calculateEchoes", () => { const withMult = calculateEchoes(1, 2); expect(withMult).toBe(base * 2); }); + + it("returns 50 echoes at the target prestige 20", () => { + // floor(224 / sqrt(20)) = floor(224 / 4.472) = floor(50.09) = 50 + expect(calculateEchoes(20, 1)).toBe(50); + }); }); describe("buildPostTranscendenceState", () => {