Give Troll King 5 crystals (was 0) to signal the crystal economy from
the first boss kill, and halve crystal_focus cost from 100 to 50 so it
is reachable within the first zone's boss chain (#173).
Increase production multiplier base from 1.25 to 1.3 so each prestige
provides more perceptible run-time reduction in the P1-P30 window where
the treadmill effect was most pronounced (#174).
Reduce income_10 cost 30k→22.5k and income_11 80k→60k (25% cut each)
to ease the late-prestige runestone cliff without collapsing the timeline.
Change prestige milestone bonus from linear (n×25) to quadratic (n²×25)
so high-prestige milestones feel meaningful (P100 = 10k stones).
Replace linear prestige combat multiplier (1 + count×0.1) with exponential
(4^count) in both the tick engine and server-side boss route. Without this
the final boss (2×10^145 HP) was unreachable by ~112 orders of magnitude;
base-4 makes it achievable around P190, consistent with the 6-month target.
Quest max reduced from 168h to 24h (÷7 scaling).
Exploration max reduced from 144h to 12h (÷12 scaling).
Zone 1 quest durations restored to original short values (1–30min).
All inline duration comments updated to reflect new values.
Adds enablePrestigeAnnouncements to ProfileSettings (defaults to true).
The prestige route now checks this setting before posting the Discord
webhook, and the edit profile modal exposes a toggle in the Sounds &
Notifications section so players can opt out.
Closes#169
Players blocked on zone progression had days where all three daily
challenges (bossesDefeated, questsCompleted, prestige) required
progression they couldn't make. Always including a clicks challenge
ensures at least one challenge is completable regardless of where
the player is in the game.
Raise runestonesPerPrestigeLevel from 10 to 15. Early-game players
were earning only 10-20 runestones per prestige, making the upgrade
shop feel out of reach. This boost helps mid-game without affecting
the cap behaviour (cbrt formula still prevents AFK windfalls).
Add 150 crystals to shadow_mere and 500 to witch_coven quest rewards.
Double shadow_marshes boss crystal drops (700->1500, 1500->3000, 3000->6000)
to provide meaningful crystal flow for players reaching Shadow Marshes.
The zone unlocks at 1.5M CP (storm_citadel), making the 5M CP entry
quest unreachable for most players. 2M CP is achievable with Arcane
Scholar and Dragon Rider adventurers without being trivial.
Adds an optimistic lock on the prestige route so that a second concurrent
request for the same state is rejected with 409 rather than firing the
Discord announcement twice. Also adds missing branch-coverage tests for
debug.ts to satisfy the 100% threshold.
Closes#162
Ten upgrades were dropping 1-2 zones after the adventurer they buff was
no longer meaningful. Moved apprentice_1 to goblin_camp, militia_1 to
haunted_mine, knight_1 to frozen_wastes, peasant_2 to glacier_tomb,
peasant_3 to shadow_mere, and pulled the T27-30 upgrades
(astral_sovereign_1, primordial_mage_1, reality_warden_1,
infinity_ranger_1) and cosmos_knight_1 into their adventurer's own zone.
The auto-buy adventurers toggle was silently reset to false on every
prestige because it was not included in the list of automation preferences
carried forward into the fresh state. This mirrors the existing handling
for autoBoss and autoQuest.
Closes#156
Distributes the nine unassigned adventurer-specific upgrade rewards
across Crystalline Spire through Eternal Throne bosses that previously
had empty upgradeRewards arrays, ensuring all adventurer upgrades are
obtainable via boss drops.
- #141: Already resolved in prior commits (celestial_focus 4.25×,
void_conduit 10.5×, crystal_matrix 7.5× all exceed free-drop tier)
- #142: Add primal_omega_lens cross-zone click_power recipe at 1.38×,
matching the eternal_omega combat ceiling and closing the gap above
the zone-17 cap of 1.25×
- #143: Already resolved in prior commits (elder_bark_shield 1.12×,
void_fragment_amulet 1.15×, soul_bound_catalyst 1.20× all buffed)
- #144: Raise philosophers_stone click 2.25×→2.5× to differentiate from
eternal_flame; raise crystal_shard click 1.55×→1.65× so the
volcanic_forger set trinket beats void_compass (1.6×)
- #145: Militia goldPerSecond already fixed; raise celestial_guard
baseCost 1.4T→1.8T, smoothing tier 14→15 from 4.67× to 6× and
removing the jarring tier 15→16 wall (7.14×→5.56×)
- #147: Guard all patch functions with hasChanged before incrementing
sync counter to prevent inflation on no-op patches
- #148: Clear stale HMAC signature after each boss fight so subsequent
auto-saves do not send a mismatched signature
- #146: Auto-unlock adventurer-specific upgrades in applyTick when
their adventurer count > 0; show recruit hint in upgrade panel
- #149: Add Essence/s row to resource bar dropdown
- #150: Fix broken auto-quest CP reduce formula; centralise via
computePartyCombatPower which applies all multipliers correctly
- #151: Cap auto-buy at 100 for non-max-tier adventurers; max tier
(highest level unlocked) remains uncapped
- #152: Export computePartyCombatPower from tick, applying global
upgrades, prestige, equipment, set bonuses, echo, crafted, and
companion multipliers; use it in resource bar and boss panel
- Added glacier_tomb (200K combat, 2.5hr) between frozen_wastes and ice_caves
- Added frozen_throne (3M combat, 7hr) after storm_citadel
- Updated ice_caves prerequisite to chain from glacier_tomb
- Frozen Peaks now has 5 quests, in line with other zones
Closes#139
## Summary
- Grants the Elysian Discord role to players on login/registration and persists an `inGuild` flag on the Player record
- Connects to the Discord Gateway via WebSocket to keep `inGuild` in sync as players join or leave the server
- Shows a dismissible "Join our community" modal to players who are not yet in the guild
- Hardens `inGuild` exposure through the load endpoint and game context
- Moves all non-secret Discord IDs (guild, role, client, redirect URI) out of env vars and into hardcoded constants; removes them from `prod.env`
## Test plan
- [ ] Lint, build, and test pipeline passes (100% coverage maintained)
- [ ] New player auth grants Elysian role and sets `inGuild: true`
- [ ] Existing player auth re-attempts role grant and updates `inGuild`
- [ ] Join community modal appears for players not in the guild
- [ ] Modal does not reappear within the same browser session after dismissal
- [ ] Gateway correctly sets `inGuild: true/false` on member add/remove events
✨ This issue was created with help from Hikari~ 🌸
Reviewed-on: #134
Co-authored-by: Hikari <hikari@nhcarrigan.com>
Co-committed-by: Hikari <hikari@nhcarrigan.com>
## Summary
- Sync New Content now **injects** missing entries AND **patches canonical fields** on all existing entries to match current defaults
- Adventurers: stats (baseCost, combatPower, goldPerSecond, essencePerSecond, name, class, level)
- Quests: duration, prerequisites, combat requirement, rewards
- Bosses: HP, damage, rewards, prestige requirement, upgrade rewards
- Zones: unlock conditions (boss/quest required)
- Upgrades: multiplier, costs
- Equipment: bonus, cost, set membership
- Achievements: condition, reward
- Crafting: multipliers recomputed from `craftedRecipeIds` so recipe balance changes apply retroactively
Closes#126
## Test plan
- [ ] On an existing save, click Sync New Content and verify the notification reports patched counts for all content types
- [ ] Verify that rebalanced adventurer/boss/upgrade stats are reflected in the UI after syncing
- [ ] Verify that player-owned state (counts, unlock status, boss HP, quest status) is preserved after syncing
- [ ] Verify crafting multipliers are correct after syncing if any recipes were previously crafted
✨ This issue was created with help from Hikari~ 🌸
Reviewed-on: #130
Co-authored-by: Hikari <hikari@nhcarrigan.com>
Co-committed-by: Hikari <hikari@nhcarrigan.com>
## Summary
- Fix `NaN` displayed in Sync New Content / Force Unlock notifications by guarding against undefined counts
- Poll server for exploration claimability before showing Collect button to prevent client/server desync
- Return authoritative materials list from craft API to prevent client desync causing false affordability
- Add test coverage for `sync-new-content` and `explore/claimable` endpoints
Closes#125Closes#127Closes#128
## Test plan
- [ ] Trigger a sync with new content and verify the notification shows a real count instead of `NaN`
- [ ] Start an exploration, wait for it to complete, and verify the Collect button only appears after the server confirms claimable
- [ ] Attempt to craft a recipe and verify the material counts in the UI update to match the server's authoritative values
✨ This issue was created with help from Hikari~ 🌸
Reviewed-on: #129
Co-authored-by: Hikari <hikari@nhcarrigan.com>
Co-committed-by: Hikari <hikari@nhcarrigan.com>
Adds a new debug panel button that injects any adventurers, quests,
bosses, equipment, upgrades, achievements, zones, and exploration areas
that exist in the current game data but are missing from an existing
player save (e.g. content added after the save was first created).
## Summary
Comprehensive balance pass addressing 20 tickets (#103–#122) plus one audit-discovered fix (#123), ensuring no player soft-locks and aligning all content counts with achievements and progression milestones.
### Changes
- **Equipment** (#103–#111): Differentiated all stat pairs so every piece has a unique bonus combination; added missing stats to `eternal_flame` and increased `eternal_prism` multiplier to justify cost tier
- **Recipes** (#112–#115): Added 4 cross-zone crafting recipes requiring materials from multiple zones to incentivise exploration breadth
- **Achievements** (#116–#118): Aligned `fully_equipped` (40→65), `quest_eternal` (72→95), and `boss_eternal` (60→72) thresholds with actual content counts; updated `devourer_slayer` description
- **Quest CP scaling** (#120–#122): Verified and corrected combat power requirements across all zones to follow consistent 4×/4× progression pattern
- **Zone file ordering** (#123): Swapped Frozen Peaks and Shadow Marshes quest sections so file order matches the actual unlock chain (no gameplay change)
### Tickets Closed
Closes#103Closes#104Closes#105Closes#106Closes#107Closes#108Closes#109Closes#110Closes#111Closes#112Closes#113Closes#114Closes#115Closes#116Closes#117Closes#118Closes#120Closes#121Closes#122Closes#123✨ This PR was created with help from Hikari~ 🌸
Reviewed-on: #124
Co-authored-by: Hikari <hikari@nhcarrigan.com>
Co-committed-by: Hikari <hikari@nhcarrigan.com>
## Summary
Addresses all community feedback tickets from the last deploy, plus several UI improvements made during the same session.
### Bug fixes & balance
- **#97** — Fix auto-adventurer tier priority: sort by combat power instead of current cost so the highest-tier affordable unit is always purchased
- **#98** — Add Dark Templar adventurer (80k CP) to bridge the Volcanic Depths progression wall; rewire upgrade and quest rewards accordingly
- **#99** — Reorder and buff Shadow Assassin (55k CP, level 12) so Witch Coven feels rewarding rather than a regression
- **#100** — Display effective Gold/s (all multipliers applied) in the resource bar
- **#101** — Add Peasant tier 2 (10x, essence) and tier 3 (50x, crystals) upgrades for meaningful late-game scaling
### Other fixes
- Sync game state to server before auto-boss challenges (matching manual challenge behaviour)
- Refresh Discord avatar hash on every game load via bot token so stale CDN URLs are corrected automatically
### UI improvements
- Replace Donate / Discord / Support / View Profile / Edit Profile buttons with a single avatar dropdown menu
- Collapse all resources except Gold into a click-to-toggle dropdown; orange alert dot appears when a hidden resource is capped
## Closes
Closes#97Closes#98Closes#99Closes#100Closes#101
Reviewed-on: #102
Co-authored-by: Hikari <hikari@nhcarrigan.com>
Co-committed-by: Hikari <hikari@nhcarrigan.com>
Closes#95
## Summary
`void_walker` adventurers (130K combat power each) were locked behind `fire_temple`, which requires 4.8B combat power. The best adventurer available before completing that quest was `arcane_scholar` at 45K CP each — meaning players needed ~107K arcane scholars to break through, versus ~37K if they had void walkers. Classic chicken-and-egg wall.
## Changes
- Moved `void_walker` adventurer reward from `fire_temple` to `lava_flows` (the entry quest to Volcanic Depths, no CP requirement)
- Added 40M gold reward to `fire_temple` to replace the removed adventurer unlock
Players now unlock `void_walker` as soon as they enter the zone, giving them the combat power boost before they need to grind toward the temple.
✨ This issue was created with help from Hikari~ 🌸
Reviewed-on: #96
Co-authored-by: Hikari <hikari@nhcarrigan.com>
Co-committed-by: Hikari <hikari@nhcarrigan.com>
The force-unlock debug route now scans completed quests for adventurer rewards and ensures those tiers are marked as unlocked in game state.
The UI and API response type both surface the new `adventurersUnlocked` count alongside the existing zone/quest/boss/exploration counts.
Closes#88✨ This PR was created with help from Hikari~ 🌸
Reviewed-on: #93
Co-authored-by: Hikari <hikari@nhcarrigan.com>
Co-committed-by: Hikari <hikari@nhcarrigan.com>
## Summary
Fixes#85. Quest combat power requirements for Shadow Marshes, Volcanic Depths, and Astral Void were all drastically too low, breaking the zone progression curve.
### Root Cause
All three zones appear to have had their `combatPowerRequired` values entered at the wrong magnitude. Shadow Marshes was using K values where M was intended; Volcanic Depths and Astral Void were similarly off, resulting in later zones being trivially easier than earlier ones.
### Changes
| Zone | Before | After |
|---|---|---|
| Shadow Marshes | 5K / 20K / 80K / 300K | 5M / 20M / 80M / 300M |
| Volcanic Depths | 2M / 8M / 30M / 120M | 1.2B / 4.8B / 18B / 72B |
| Astral Void | 50M / 200M / 800M / 3B | 300B / 1.2T / 4.8T / 18T |
### Progression
All values now maintain a consistent ~×4 multiplier within each zone and ~×4 jump between zones, matching the established pattern from Verdant Vale through Frozen Peaks.
✨ This PR was created with help from Hikari~ 🌸
Reviewed-on: #90
Co-authored-by: Hikari <hikari@nhcarrigan.com>
Co-committed-by: Hikari <hikari@nhcarrigan.com>
## Summary
Closes#62
Adds five **Essence Infusion** upgrades (I–V) to give essence an ongoing meaningful use deep into a prestige run, when gold upgrades are all purchased and essence reserves are in the trillions with nowhere to go:
| Upgrade | Cost | Multiplier |
|---|---|---|
| Essence Infusion I | 1T essence | ×2 global |
| Essence Infusion II | 5T essence | ×2 global |
| Essence Infusion III | 25T essence | ×2 global |
| Essence Infusion IV | 100T essence | ×3 global |
| Essence Infusion V | 500T essence | ×5 global |
All five start `unlocked: true` (no prerequisite boss or quest required) and cost zero gold and zero crystals — they are purely essence sinks. Combined, they provide a ×120 global income multiplier for players willing to pour their essence reserves into the guild. The About panel's Upgrades section is also updated to inform players these exist.
CDN art assets will need to be generated for IDs `essence_sink_1` through `essence_sink_5` in the `upgrades` folder.
✨ This issue was created with help from Hikari~ 🌸
Reviewed-on: #77
Co-authored-by: Hikari <hikari@nhcarrigan.com>
Co-committed-by: Hikari <hikari@nhcarrigan.com>
## Summary
Closes#61
- Adds the **Autonomous Recruitment** prestige upgrade (50 runestones) to both the API and web data files
- Adds `autoAdventurer?: boolean` to the `GameState` type for backwards-compatible saves
- Adds tick-loop logic in GameContext that automatically purchases the highest-tier unlocked adventurer the player can afford each frame when the toggle is enabled
- Adds `toggleAutoAdventurer` callback and exposes it through the context
- Adds toggle UI in the Prestige Shop (mirrors the existing Auto-Prestige toggle pattern)
- Updates the How to Play guide in the About panel to document the new automation feature
✨ This issue was created with help from Hikari~ 🌸
Reviewed-on: #76
Co-authored-by: Hikari <hikari@nhcarrigan.com>
Co-committed-by: Hikari <hikari@nhcarrigan.com>
## Summary
Two improvements to the equipment system in one PR:
### Balance fixes (closes#54)
Full equipment audit revealed 9 items with duplicated stats, regressions, or purchasable items weaker than free boss drops:
| Item | Change | Reason |
|---|---|---|
| Void Conduit | 4x → 7x combat | 100M essence sink was equal to a zone-6 boss drop |
| Void Edge | 2.75x → 3.25x combat | Purchasable was weaker than free Celestial Blade (3x) |
| Astral Robe | 2.25x → 2.75x gold | Boss drop was weaker than purchasable Titan's Aegis (2.5x) |
| Philosopher's Stone | 2x → 2.25x click | Duplicated Frost Crystal's click multiplier |
| Eternal Flame | 1.15x → 1.25x gold | Gold regressed vs Philosopher's Stone (1.25x) |
| Celestial Focus | 2.5x → 3x click | 20M essence sink was weaker than free Angel's Halo (2.75x click + 1.3x gold) |
| Abyssal Tome | 3x → 3.75x gold | 50M essence sink was equal to free Heaven's Mantle (3x) |
| Crystal Matrix | 4x → 4.75x gold | 20M crystal sink was equal to free Sinslayer Aegis (4x) |
| Infernal Gem | 3.5x → 4x click | 5M crystal sink was identical to free Prism Eye |
### Equipment sorting (closes#55)
Equipment cards within each slot now render in ascending order of combined bonus power — the sum of all multiplier bonuses — so stronger items always appear further down the list. Hybrid items such as Volcanic Plate sort correctly without needing a per-slot primary stat.
## Test plan
- [ ] All purchasable weapons/armour/trinkets now exceed the stats of the highest free boss drop at their tier
- [ ] No duplicate stat values between adjacent items in the same progression track
- [ ] Equipment cards within each slot render weakest → strongest
- [ ] Hybrid multi-stat items sort sensibly alongside single-stat items
- [ ] Full pipeline green (lint + build + tests at 100% coverage)
✨ This PR was created with help from Hikari~ 🌸
Reviewed-on: #69
Co-authored-by: Hikari <hikari@nhcarrigan.com>
Co-committed-by: Hikari <hikari@nhcarrigan.com>
## Summary
- Bosses defeated before `bountyRunestonesClaimed` was introduced had `status: "defeated"` but the field `undefined`
- After prestige, the preservation check (`=== true`) missed these bosses, so the first-kill bounty was re-awarded on the next run
- Now also treats `status === "defeated"` as proof the bounty was already earned, covering the migration case
## Test plan
- [ ] Existing test: `preserves bountyRunestonesClaimed flag on bosses across prestige` — still passes
- [ ] New test: `sets bountyRunestonesClaimed on bosses defeated before the flag was introduced` — covers the legacy save migration path
- [ ] Full coverage maintained at 100%
Closes#52✨ This PR was created with help from Hikari~ 🌸
Reviewed-on: #67
Co-authored-by: Hikari <hikari@nhcarrigan.com>
Co-committed-by: Hikari <hikari@nhcarrigan.com>