generated from nhcarrigan/template
b0227c17095360e653a4ad1bf183995802605ccd
64 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
b0227c1709 |
chore: update minor and patch dependencies (#237)
## Summary - Bumped minor/patch versions for `@hono/node-server`, `@types/node`, `@types/react`, `@types/react-dom`, `@vitejs/plugin-react`, `hono`, `jsdom`, `react`, `react-dom`, `tsx`, and `vite` - Full pipeline (lint → build → test) confirmed passing ## Held back - **TypeScript** — held at 5.8.2; 6.x is incompatible with the current `@nhcarrigan/eslint-config` - **Vitest** — held at 3.x; 4.x changes v8 coverage pragma handling, needs investigation - **Prisma** — held at 6.x; 7.x requires a `prisma.config.ts` migration ✨ This PR was created with help from Hikari~ 🌸 Reviewed-on: #237 Co-authored-by: Hikari <hikari@nhcarrigan.com> Co-committed-by: Hikari <hikari@nhcarrigan.com> |
||
|
|
de5570b5fc
|
fix: filter third-party script errors from frontend telemetry | ||
|
|
133c81fefe
|
chore: bump schema version to 2 for v0.4.0 balance pass | ||
|
|
1408e067b7
|
release: v0.4.0 | ||
|
|
666a5b2d6d |
fix: runestone formula, prestige/transcendence rebalance, exploration fixes, and comprehensive balance audit (#135)
## What changed and why ### Runestone formula (`prestige.ts`) - Swapped `sqrt` for `cbrt` — much stronger diminishing returns for large gold values - Added base cap of **200** (→ ~1,125 max with all upgrades at 5.625× multiplier) - Prevents extended AFK sessions from producing runestone windfalls that allow immediate upgrade purchasing and rapid prestige chaining ### Prestige threshold formula (`prestige.ts`) - Old: `1,000,000 × 5^n` — exponential, grows impossibly fast, prestige 10+ takes years - New: `1,000,000 × (n+1)²` — polynomial, peaks at ~1 day/run around P8–10, then gets *easier* as the production multiplier overtakes it - Removed `thresholdScaleFactor` constant (no longer needed) ### Production multiplier (`prestige.ts`) - Old: `1.15^n` - New: `1.25^n` — compounds faster, ensures the polynomial threshold eventually gets easy in the late game ### Boss prestige requirements (`bosses.ts`) - Rescaled proportionally from 0–88 range to 0–20 range - The Absolute One now requires prestige **20** (was 88), making transcendence reachable in a few weeks of idle play ### Echo formula (`transcendence.ts`) - Constant changed from 853 → **224** - At the target prestige of 20: `floor(224 / sqrt(20)) = 50 echoes` per transcendence (no meta upgrades) - With all echo_meta upgrades (3.75× total): up to **187 echoes** per transcendence ### Transcendence upgrade costs (`transcendenceUpgrades.ts`) - Old total: **866 echoes** → New total: **400 echoes** (roughly halved across all categories) - Apotheosis still requires **all 15 upgrades** purchased ### Balance fixes (closes #141, #142, #143, #144, #145) - Equipment: `philosophers_stone` click multiplier 2.25→2.5, `crystal_shard` 1.55→1.65 (#144) - Recipes: added `primal_omega_lens` cross-zone click_power recipe at 1.38× (#142) - Adventurers: `celestial_guard` base cost adjusted to smooth tier 14→15→16 cost curve (#145) ### Quest reward rebalancing (closes #136, #137) - Shadow Marshes: buffed `shadow_mere`, `witch_coven`, `plague_ruins` rewards to match combat requirements (#136) - Astral Void: added gold to `void_rift`, increased rewards across all Astral Void quests (#137) ### Boss reward additions (closes #138, #139, #140) - Assigned 9 unassigned adventurer-specific upgrades to Crystalline Spire through Eternal Throne bosses that had empty `upgradeRewards` arrays (#140) ### Combat power documentation (closes #153) - Expanded JSDoc on `computePartyCombatPower` to clarify companion `bossDamage` multiplier behaviour ### Effective adventurer stats (closes #154) - Added `computeEffectiveAdventurerStats` to `tick.ts` and updated `AdventurerCard` to display effective post-multiplier stats ### Adventurer upgrade timing (closes #158) - Audited every adventurer-specific upgrade reward — upgrades now land within the same progression window where that adventurer tier is still a meaningful contributor ### Sync and save fixes (closes #147, #148, #151) - Fixed sync new content count to report only genuinely changed items (#147) - Fixed signature mismatch after first auto-boss completion (#148) - Added auto-buy cap (100) on non-max-tier adventurers (#151) ### Auto-adventurer persistence (closes #156) - Auto-buy preference now preserved across prestige resets ### Broken CDN image (closes #159) - Uploaded missing `auto_adventurer.jpg` to CDN ### Codex unlock hints (closes #146) - Locked codex entries now display a hint generated from `sourceType` and `sourceId` ### Exploration bug fixes (closes #160, #161) - Fixed auto-save race condition discarding exploration materials collected mid-tick (#160) - Fixed exploration areas failing to unlock when zone was unlocked via boss kill or quest completion (#161) ### Concurrent prestige fix (closes #162) - Added optimistic locking via `updatedAt` — concurrent prestige requests return 409 ### Prestige UX (closes #163) - Added `reloadSilent` to game context — no loading screen flash after prestige ### Balance adjustments (closes #164, #165, #166, #167) - Reduced `shadow_mere` CP requirement 5,000,000 → 2,000,000 (#164) - Buffed crystal drops from Shadow Marshes bosses and quests (#165) - Increased runestone yield from 10 → 15 per prestige level (#166) - Daily challenge set always includes a clicks challenge (#167) ### Progression QoL (closes #168, #169) - Added `computeProjectedRunestones()` and persistent `+N On Prestige` resource bar row (#168) - Added `enablePrestigeAnnouncements` setting per player (#169) --- ## Comprehensive balance audit (closes #187, #191, #192, #193, #194, #195, #196, #197, #198) ### Crystal economy fixes - Zeroed crystal rewards for all Zone 7+ boss drops (Celestial Reaches onwards) — crystals are an early/mid-game currency and should not flow freely into the endgame (#187) - Zeroed crystal rewards for all Zone 9+ quest rewards (Infernal Court onwards) — same rationale (#191) ### Achievement additions and fixes - Added quest milestone achievements at 75 quests (10,000 crystals) and 100 quests (15,000 crystals) - Added boss milestone achievement at 50 bosses (15,000 crystals) - Added prestige milestone achievements at P50, P100, P150, P200 — rewarding **runestones** rather than crystals to match the late-game economy - Added gold milestone achievements through 1e90 gold earned - Fixed `quest_eternal` condition from 122 → **112** (actual quest count) — was permanently impossible (#197) - Fixed `fully_equipped` condition from 65 → **78** (actual equipment count after new items) (#197) - Fixed `devourer_slayer` description to remove incorrect zone reference ### Upgrade balance - Fixed Essence Guild multiplier 1.5× → **2×** — was identical to the cheaper Merchant Alliance for 5× the cost (#194) - Raised Void Ascendancy crystal cost 10M → **50M** — was trivially cheap compared to the parallel Celestial Mandate upgrade (100B essence + 50T gold) (#195) - Fixed Sunken Temple quest rewards (gold 2M → 60M, essence 1,500 → 25,000, crystals 75 → 400) — was rewarding less than its easier prerequisite Witch Coven (#193) ### Equipment balance - Buffed Eternal Prism stats to click 5×, combat **3×**, gold **2.5×** — was only marginally better than the free Eternity Stone boss drop for 100M crystals (#196) ### Missing content - Created **13 missing equipment items** for Zones 15–18 (primordial_chaos through the_absolute) that were referenced by late-game boss `equipmentRewards` arrays but never existed in `equipment.ts` (#198): - `chaos_mantle`, `titan_core` (Primordial Chaos) - `expanse_blade`, `void_armour_mk2` (Infinite Expanse) - `cosmos_blade`, `reality_plate` (Reality Forge) - `maelstrom_edge`, `cosmic_plate` (Cosmic Maelstrom) - `primeval_blade`, `ancient_aegis` (Primeval Sanctum) - `absolute_blade`, `eternity_plate`, `omniversal_core` (The Absolute) - Stats scale from combat 14× / gold 9× (Zone 15) up to combat 28× / gold 20× for the final boss drops ### Type system - Extended `AchievementReward` type to support `runestones` field - Updated tick engine achievement processing to award both crystals and runestones --- ## Target progression timeline (optimal play, ~16h/day idle) - First cycle to P20: ~375h (~3.3 weeks) - Each subsequent cycle gets faster as echo upgrades boost income/combat/threshold - Expected **~5 transcendences** before apotheosis at 50–187 echoes/transcendence - **~6 months** to apotheosis for a dedicated player ## Test plan - [ ] Lint, build, and test pipeline passes (100% coverage maintained) - [ ] Prestige threshold at P0 is still 1,000,000 gold - [ ] Prestige runs feel ~1 day long around P8–10 and get easier after - [ ] The Absolute One is locked until prestige 20 - [ ] Transcendence at P20 awards 50 echoes (no meta upgrades) - [ ] All 15 transcendence upgrades cost 400 echoes total - [ ] Bosses in Zones 7+ drop 0 crystals; Zones 1–6 retain crystal drops - [ ] Quests in Zones 9+ reward 0 crystals; Zones 1–8 retain crystal rewards - [ ] Sunken Temple rewards more gold/essence/crystals than Witch Coven - [ ] Essence Guild gives 2× income (stronger than Merchant Alliance 1.5×) - [ ] Void Ascendancy costs 50M crystals - [ ] Eternal Prism stats are click 5×, combat 3×, gold 2.5× - [ ] Late-game bosses (primordial_titan through the_absolute_one) drop equipment on kill - [ ] `quest_eternal` achievement requires 112 quests - [ ] `fully_equipped` achievement requires 78 equipment pieces - [ ] P50/P100/P150/P200 prestige achievements reward runestones - [ ] Adventurer cards show effective post-multiplier stats - [ ] Exploration areas unlock correctly when their zone is unlocked - [ ] Concurrent prestige requests return 409 - [ ] No loading screen flash after prestige - [ ] Daily challenge set always includes a clicks challenge - [ ] Resource bar shows `+N On Prestige` runestone preview ✨ This PR was crafted with help from Hikari~ 🌸 Reviewed-on: #135 Co-authored-by: Hikari <hikari@nhcarrigan.com> Co-committed-by: Hikari <hikari@nhcarrigan.com>v0.4.0 |
||
|
|
9926e7f639
|
release: v0.3.2
|
||
|
|
6bf1ac5e7d |
feat: grant Elysian role on auth and prompt non-members to join (#134)
## 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> |
||
|
|
b48beef474 |
feat: sync and patch all content stats on existing saves (#130)
## 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> |
||
|
|
6e573bea14 |
chore: more feedback fixes (#129)
## 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 #125 Closes #127 Closes #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> |
||
|
|
790d35420f
|
fix: patch quest and boss rewards on sync to restore unlock conditions | ||
|
|
9f9edae45e
|
release: v0.3.1
|
||
|
|
a7a255dab6
|
fix: sort injected entries by canonical defaults order after sync | ||
|
|
e92cf3c9a1
|
feat: add sync new content debug tool
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). |
||
|
|
26d30c271d
|
release: v0.3.0
|
||
|
|
34d07bec95 |
balance: comprehensive game balance pass (#103-#123) (#124)
## 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 #103 Closes #104 Closes #105 Closes #106 Closes #107 Closes #108 Closes #109 Closes #110 Closes #111 Closes #112 Closes #113 Closes #114 Closes #115 Closes #116 Closes #117 Closes #118 Closes #120 Closes #121 Closes #122 Closes #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> |
||
|
|
3ac1d566cb |
chore: community feedback fixes and UI improvements (#102)
## 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 #97 Closes #98 Closes #99 Closes #100 Closes #101 Reviewed-on: #102 Co-authored-by: Hikari <hikari@nhcarrigan.com> Co-committed-by: Hikari <hikari@nhcarrigan.com> |
||
|
|
7bd6b2d3e3
|
release: v0.2.1
|
||
|
|
354b7e372e |
fix: break fire_temple combat power wall (#96)
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> |
||
|
|
dc1782bec9 |
chore: add auto-adventurer toggle to adventurer panel header (#94)
The auto-adventurer toggle is now surfaced directly in the adventurer shop panel header, mirroring the auto-boss button. It only renders when the `auto_adventurer` prestige upgrade has been purchased, so players who have not reached prestige see no change. Closes #89 ✨ This PR was created with help from Hikari~ 🌸 Reviewed-on: #94 Co-authored-by: Hikari <hikari@nhcarrigan.com> Co-committed-by: Hikari <hikari@nhcarrigan.com> |
||
|
|
635c630e49 |
fix: adventurer unlocks not applied by force-unlock tool (#93)
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> |
||
|
|
bb60ae3390 |
fix: auto-quest continues after quest failure (#92)
## Summary Fixes #87. When a quest failed, the tick loop detected the failure and turned auto-quest off so the "player could reassess". This meant every quest failure required the player to manually re-enable the toggle. ## Root Cause The tick applies quest failure by resetting the quest to `status: "available"` with `lastFailedAt` set. Auto-quest picks up `available` quests automatically — so turning off auto-quest on failure was entirely unnecessary, it just broke the loop. ## Fix Remove the auto-quest-off-on-failure block entirely. The quest returns to `available` immediately after failure, so auto-quest naturally retries on the next tick. Players can still disable it manually if they want to stop. ✨ This PR was created with help from Hikari~ 🌸 Reviewed-on: #92 Co-authored-by: Hikari <hikari@nhcarrigan.com> Co-committed-by: Hikari <hikari@nhcarrigan.com> |
||
|
|
ee47c1e8c9 |
fix: auto-boss no longer halts on client/server save race condition (#91)
## Summary Fixes #86. When the client state is ahead of the server save, the auto-boss tick would receive a "Boss is not currently available" error from the API. This error was already acknowledged as an expected race condition and suppressed from telemetry — but it was still setting the error state and turning auto-boss off. ## Root Cause The `catch` handler treated all errors identically: set `autoBossError`, turn off `autoBoss`. The race-condition case should instead silently skip so the next tick can retry naturally. ## Fix When the error is `"Boss is not currently available"`, return early from the `catch` handler. The `finally` block still runs, resetting `isAutoBossingReference.current = false`, so the next tick retries cleanly. ✨ This PR was created with help from Hikari~ 🌸 Reviewed-on: #91 Co-authored-by: Hikari <hikari@nhcarrigan.com> Co-committed-by: Hikari <hikari@nhcarrigan.com> |
||
|
|
2236d1dc9f |
fix: correct quest combat power requirements for SM, VD, and AV (#90)
## 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> |
||
|
|
621f594018
|
release: v0.2.0
|
||
|
|
1e845b14ce |
chore: UI clarity improvements (#84)
## Summary - Move quest failure explanation to a static note above the quest list (cards now show failure % only) - Show zone unlock requirements (boss + quest) on the Boss and Quest panels, matching the existing Exploration panel behaviour - Display combat power per adventurer on adventurer cards, alongside gold/s and essence/s ✨ This issue was created with help from Hikari~ 🌸 Reviewed-on: #84 Co-authored-by: Hikari <hikari@nhcarrigan.com> Co-committed-by: Hikari <hikari@nhcarrigan.com> |
||
|
|
81ae1f18e1 |
chore: clarify equipment combat bonus applies to boss fights only (#83)
## Summary Resolves player confusion about equipment combat bonuses not affecting quest combat power. The behaviour is by design — combat multipliers only apply to boss DPS — but this was never communicated anywhere. - **Equipment bonus labels** now read `+X% Boss Combat` instead of `+X% Combat` (both individual items and set bonuses) - **About panel** — both equipment entries updated to explicitly state that combat bonuses only affect boss fights, and that quest combat power is determined solely by adventurers No game logic changed. Closes #81 ✨ This PR was created with help from Hikari~ 🌸 Reviewed-on: #83 Co-authored-by: Hikari <hikari@nhcarrigan.com> Co-committed-by: Hikari <hikari@nhcarrigan.com> |
||
|
|
0057cfeaaa |
feat: communicate quest failure mechanics in the UI (#82)
## Summary Addresses recurring community confusion about quests failing — multiple players asked whether it was a bug or intended behaviour with no in-game explanation. - **Exports `zoneFailureChance`** from `tick.ts` so the quest panel can read it - **Quest cards** now show a `🎲 X% failure chance` note on all available quests, with a brief explanation that a failure resets the quest with no rewards - **"Last attempt failed" hint** now reads `"⚠️ Last attempt failed — no rewards were granted."` so players understand the consequence immediately - **About panel** updated to document the failure mechanic, including the 10%–40% range across zones Closes #80 ✨ This PR was created with help from Hikari~ 🌸 Reviewed-on: #82 Co-authored-by: Hikari <hikari@nhcarrigan.com> Co-committed-by: Hikari <hikari@nhcarrigan.com> |
||
|
|
161127dc21 |
chore: audit frontend error reporting to exclude expected behaviours (#79)
## Summary Audits all `logError` call sites in `gameContext.tsx` and suppresses telemetry for expected business logic rejections, eliminating alert fatigue without hiding real errors. ### Changes per call site | Context | Before | After | |---|---|---| | `auto_save` | Logged all non-signature errors | Network failures silently swallowed — next tick retries | | `auto_prestige` | Logged eligibility failures | Silently ignored — eligibility re-checked every tick | | `auto_boss` | Logged all errors | Filters out `"Boss is not currently available"` (race condition); other errors still logged | | `challenge_boss` | Logged all errors | Filters out `"Boss is not currently available"` (race condition); other errors still logged | | `start_exploration` | Logged then rethrew | Removed useless try/catch — error propagates to UI naturally | | `collect_exploration` | Logged then rethrew | Removed useless try/catch — error propagates to UI naturally | Genuine errors (`buy_prestige_upgrade`, `transcend`, `apotheosis`, `buy_echo_upgrade`, `craft_recipe`) are unchanged — they still fire telemetry. Closes #73 ✨ This PR was created with help from Hikari~ 🌸 Reviewed-on: #79 Co-authored-by: Hikari <hikari@nhcarrigan.com> Co-committed-by: Hikari <hikari@nhcarrigan.com> |
||
|
|
a8a465f293 |
feat: display leaderboard update frequency in the UI (#78)
## Summary Adds a note below the leaderboard subtitle informing players that rankings update when they prestige. This addresses a recurring community question from `tau.deusmortis` and `minjo70`. Closes #63 ✨ This PR was created with help from Hikari~ 🌸 Reviewed-on: #78 Co-authored-by: Hikari <hikari@nhcarrigan.com> Co-committed-by: Hikari <hikari@nhcarrigan.com> |
||
|
|
79c4b99e8a |
feat: add essence infusion upgrades as late-prestige essence sink (#77)
## 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> |
||
|
|
3d114f63d7 |
feat: post-prestige automation (auto-adventurer) (#76)
## 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> |
||
|
|
911e089a9e |
feat: document upgrade stacking behaviour as multiplicative (#75)
## Summary - Adds a `💡` stacking note directly in the upgrade panel below the progress counter so players see it without visiting the About page - Updates the About panel's Upgrades how-to-play entry to replace the vague "compound with each other" with explicit multiplicative stacking language, including an example (two ×2 upgrades = ×4) and a note that global upgrades multiply on top of adventurer-specific ones ## Test plan - [ ] Verify the stacking note appears in the upgrade panel below the progress counter - [ ] Verify the About panel Upgrades entry reflects the updated wording - [ ] Confirm lint, build, and tests all pass Closes #60 Reviewed-on: #75 Co-authored-by: Hikari <hikari@nhcarrigan.com> Co-committed-by: Hikari <hikari@nhcarrigan.com> |
||
|
|
14de87d765 |
feat: communicate exploration zone unlock conditions in-game (#74)
## Summary - Locked exploration zones now show a `🔒 This zone is locked. Unlock exploration by:` hint above the area list, with the specific `⚔️ Defeat: {boss}` and `📜 Complete: {quest}` required - Updated the About panel's Exploration how-to-play entry to document the zone unlock rule explicitly - No new data required — unlock conditions are read directly from `zone.unlockBossId` and `zone.unlockQuestId` already in state ## Test plan - [ ] Verify locked exploration zones display the correct boss and quest unlock hints - [ ] Verify already-unlocked zones show no hint - [ ] Verify starter zone (no unlock conditions) shows no hint - [ ] Verify the About panel Exploration entry reflects the updated description - [ ] Confirm lint, build, and tests all pass Closes #59 Reviewed-on: #74 Co-authored-by: Hikari <hikari@nhcarrigan.com> Co-committed-by: Hikari <hikari@nhcarrigan.com> |
||
|
|
c4b4fba4c9 |
feat: display current party combat power as a persistent stat (#72)
## Summary - Adds a `⚔️ Combat Power` entry to the always-visible resource bar - Value is computed client-side as the sum of each adventurer's `combatPower × count` - No new props required — computed directly from `state` via the existing `useGame()` hook - Players can now see their combat strength at a glance before attempting boss fights or quests ## Test plan - [ ] Verify the Combat Power stat appears in the resource bar - [ ] Verify the value increases as more adventurers are recruited - [ ] Verify the value displays correctly with `formatNumber` for large numbers - [ ] Confirm lint, build, and tests all pass Closes #58 Reviewed-on: #72 Co-authored-by: Hikari <hikari@nhcarrigan.com> Co-committed-by: Hikari <hikari@nhcarrigan.com> |
||
|
|
d723656743 |
feat: show progress toward unlock conditions on achievement cards (#71)
## Summary
- Adds a `getCurrentProgress` helper that mirrors the tick engine's achievement-checking logic to compute the player's current progress for each condition type
- Locked achievement cards now display a `<progress>` bar and a numeric `{current} / {target}` label so players can see exactly how close they are to each achievement
- Unlocked achievements are unaffected — no progress bar shown once earned
## Test plan
- [ ] Verify locked achievement cards display a progress bar and numeric label
- [ ] Verify the progress values match what the tick engine uses for unlock checking
- [ ] Verify unlocked achievement cards show no progress bar
- [ ] Confirm lint, build, and tests all pass
Closes #57
Reviewed-on: #71
Co-authored-by: Hikari <hikari@nhcarrigan.com>
Co-committed-by: Hikari <hikari@nhcarrigan.com>
|
||
|
|
7e10757e68 |
feat: show affected adventurer name on upgrade cards (#70)
## Summary - Adds a `🗡️ Affects: {Name}` label to upgrade cards that target a specific adventurer - Resolves player confusion caused by class-based language (e.g. "doubles cleric output") without specifying which adventurer tiers count as that class - Label appears in all three card states: available, purchased, and locked ## Test plan - [ ] Verify adventurer-targeted upgrade cards display the correct adventurer name - [ ] Verify global, click, boss, and prestige upgrade cards show no affects label - [ ] Confirm lint, build, and tests all pass Closes #56 Reviewed-on: #70 Co-authored-by: Hikari <hikari@nhcarrigan.com> Co-committed-by: Hikari <hikari@nhcarrigan.com> |
||
|
|
ca2edb090e |
fix: correct equipment balance and sort items by stat power (#69)
## 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> |
||
|
|
cfcf763ce3 |
fix: use server-computed endsAt for exploration timer to prevent clock drift (#68)
## Summary - Exploration timers showed more time than the area's stated duration when the server clock was ahead of the client's - The timer was derived from `startedAt = endsAt - durationMs`, then computed as `durationSeconds - (clientNow - startedAt) / 1000` — any server/client clock skew directly inflated the result - Now stores `endsAt` (the server-computed completion timestamp) directly in `ExplorationAreaState` and computes the timer as `(endsAt - Date.now()) / 1000`, which is immune to clock drift - Old saves without `endsAt` fall back gracefully to the previous `startedAt`-based calculation ## Test plan - [ ] Start a new exploration — timer should show exactly the area's stated duration (no more "1h area shows 1h15m") - [ ] Refresh the page mid-exploration — timer should resume from the correct remaining time (using server-anchored `endsAt`) - [ ] Old saves with `startedAt` but no `endsAt` should still display a timer via the fallback path Closes #53 ✨ This PR was created with help from Hikari~ 🌸 Reviewed-on: #68 Co-authored-by: Hikari <hikari@nhcarrigan.com> Co-committed-by: Hikari <hikari@nhcarrigan.com> |
||
|
|
aede55a13d |
fix: preserve runestone bounty flag for legacy defeated bosses (#67)
## 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> |
||
|
|
744cbf121f |
fix: preserve autoQuest and autoBoss settings across prestige (#66)
## Summary - `buildPostPrestigeState` was constructing the post-prestige `GameState` from `initialGameState`, which hard-codes `autoQuest` and `autoBoss` to `false` - Neither flag was being carried forward, so both automation settings silently reset after every prestige - Now both values are explicitly preserved from `currentState` (with `?? false` fallback for safety) Closes #51 ✨ This issue was created with help from Hikari~ 🌸 Reviewed-on: #66 Co-authored-by: Hikari <hikari@nhcarrigan.com> Co-committed-by: Hikari <hikari@nhcarrigan.com> |
||
|
|
03b6c847b3 |
feat: debug panel with force unlocks and hard reset (#65)
## Summary - Adds a new **Debug** tab to the game UI with two self-service tools for players with broken save state - **Force Unlocks**: scans the player's save and grants any zones, quests, bosses, and exploration areas they've earned but that are still locked — shows a breakdown of what was unlocked (or reports nothing needed fixing) - **Hard Reset**: wipes progress back to a fresh save (preserving lifetime stats), guarded behind a confirmation modal to prevent accidental clicks ## Files added - `apps/api/src/routes/debug.ts` — two POST endpoints (`/force-unlocks`, `/hard-reset`) - `apps/web/src/components/game/debugPanel.tsx` — the Debug tab UI - `apps/web/src/components/ui/confirmationModal.tsx` — reusable confirmation modal ## Files modified - `apps/api/src/index.ts` — registers the debug router - `packages/types/src/interfaces/api.ts` — adds `ForceUnlocksResponse` type - `packages/types/src/index.ts` — exports the new type - `apps/web/src/api/client.ts` — adds `forceUnlocks()` and `debugHardReset()` API calls - `apps/web/src/context/gameContext.tsx` — wires both functions into game context - `apps/web/src/components/game/gameLayout.tsx` — adds the Debug tab - `apps/web/src/styles.css` — styles for action buttons, cards, result messages, and confirmation modal ✨ This PR was created with help from Hikari~ 🌸 Reviewed-on: #65 Co-authored-by: Hikari <hikari@nhcarrigan.com> Co-committed-by: Hikari <hikari@nhcarrigan.com> |
||
|
|
219d299e9f |
fix: force sync before boss fight and surface challenge errors to UI (#64)
Closes #50 ## Summary - Calls `forceSync()` before every boss challenge so the server always fights against the player's live state (equipped items, upgrades, etc.) rather than a potentially stale snapshot - Adds a `bossError` state that captures and displays error messages from failed manual boss challenges in the boss panel, matching the existing `autoBossError` display pattern ✨ This PR was created with help from Hikari~ 🌸 Reviewed-on: #64 Co-authored-by: Hikari <hikari@nhcarrigan.com> Co-committed-by: Hikari <hikari@nhcarrigan.com> |
||
|
|
9e5b8ed972 |
deps: update typescript to 5.9.3 (#32)
## Dependency Update Updates **typescript** from `5.8.2` to `5.9.3`. ### Type devDependencies ### Changelog ## Changelog ### v5.9.3 Note: this tag was recreated to point at the correct commit. The npm package contained the correct content. For release notes, check out the [release announcement](https://devblogs.microsoft.com/typescript/announcing-typescript-5-9/) * [fixed issues query for Typescript 5.9.0 (Beta)](https://github.com/Microsoft/TypeScript/issues?utf8=%E2%9C%93&q=milestone%3A%22TypeScript+5.9.0%22+is%3Aclosed+). * [fixed issues query for Typescript 5.9.1 (RC)](https://github.com/Microsoft/TypeScript/issues?utf8=%E2%9C%93&q=milestone%3A%22TypeScript+5.9.1%22+is%3Aclosed+). * *No specific changes for TypeScript 5.9.2 (Stable)* * [fixed issues query for Typescript 5.9.3 (Stable)](https://github.com/Microsoft/TypeScript/issues?utf8=%E2%9C%93&q=milestone%3A%22TypeScript+5.9.3%22+is%3Aclosed+). Downloads are available on: * [npm](https://www.npmjs.com/package/typescript) ### v5.9.2 Note: this tag was recreated to point at the correct commit. The npm package contained the correct content. For release notes, check out the [release announcement](https://devblogs.microsoft.com/typescript/announcing-typescript-5-9/) * [fixed issues query for Typescript 5.9.0 (Beta)](https://github.com/Microsoft/TypeScript/issues?utf8=%E2%9C%93&q=milestone%3A%22TypeScript+5.9.0%22+is%3Aclosed+). * [fixed issues query for Typescript 5.9.1 (RC)](https://github.com/Microsoft/TypeScript/issues?utf8=%E2%9C%93&q=milestone%3A%22TypeScript+5.9.1%22+is%3Aclosed+). * *No specific changes for TypeScript 5.9.2 (Stable)* Downloads are available on: * [npm](https://www.npmjs.com/package/typescript) ### v5.9-rc Note: this tag was recreated to point at the correct commit. The npm package contained the correct content. For release notes, check out the [release announcement](https://devblogs.microsoft.com/typescript/announcing-typescript-5-9-rc/) * [fixed issues query for Typescript 5.9.0 (Beta)](https://github.com/Microsoft/TypeScript/issues?utf8=%E2%9C%93&q=milestone%3A%22TypeScript+5.9.0%22+is%3Aclosed+). * [fixed issues query for Typescript 5.9.1 (RC)](https://github.com/Microsoft/TypeScript/issues?utf8=%E2%9C%93&q=milestone%3A%22TypeScript+5.9.1%22+is%3Aclosed+). Downloads are available on: * [npm](https://www.npmjs.com/package/typescript) ### v5.9-beta Note: this tag was recreated to point at the correct commit. The npm package contained the correct content. For release notes, check out the [release announcement](https://devblogs.microsoft.com/typescript/announcing-typescript-5-9-beta/). * [fixed issues query for Typescript 5.9.0 (Beta)](https://github.com/Microsoft/TypeScript/issues?utf8=%E2%9C%93&q=milestone%3A%22TypeScript+5.9.0%22+is%3Aclosed+). Downloads are available on: * [npm](https://www.npmjs.com/package/typescript) ### v5.8.3 Note: this tag was recreated to point at the correct commit. The npm package contained the correct content. For release notes, check out the [release announcement](https://devblogs.microsoft.com/typescript/announcing-typescript-5-8/). * [fixed issues query for Typescript 5.8.0 (Beta)](https://github.com/Microsoft/TypeScript/issues?utf8=%E2%9C%93&q=milestone%3A%22TypeScript+5.8.0%22+is%3Aclosed+). * [fixed issues query for Typescript 5.8.1 (RC)](https://github.com/Microsoft/TypeScript/issues?utf8=%E2%9C%93&q=milestone%3A%22TypeScript+5.8.1%22+is%3Aclosed+). * [fixed issues query for Typescript 5.8.2 (Stable)](https://github.com/Microsoft/TypeScript/issues?utf8=%E2%9C%93&q=milestone%3A%22TypeScript+5.8.2%22+is%3Aclosed+). * [fixed issues query for Typescript 5.8.3 (Stable)](https://github.com/Microsoft/TypeScript/issues?utf8=%E2%9C%93&q=milestone%3A%22TypeScript+5.8.3%22+is%3Aclosed+). Downloads are available on: * [npm](https://www.npmjs.com/package/typescript) --- ✨ This PR was created by Minori, your friendly dependency updater! 🌸 Reviewed-on: #32 Co-authored-by: Minori <minori@nhcarrigan.com> Co-committed-by: Minori <minori@nhcarrigan.com> |
||
|
|
a20cf3ef87
|
release: v0.1.2 | ||
|
|
9860a2cb1f |
feat: persist crafting zone selection in sessionStorage (#49)
## Summary - Applies the same sticky-zone pattern from #48 to the crafting panel (`elysium_craft_zone` key in sessionStorage) - Introduces a `handleZoneSelect` wrapper so sessionStorage is updated alongside React state on every zone change - Gracefully falls back to `verdant_vale` if no stored value exists ## Test plan - [x] Lint — zero errors, zero warnings - [x] Build — all packages build cleanly - [ ] Manual: select a non-default zone in the crafting panel, navigate away and back — zone should still be selected - [ ] Manual: log out and back in — zone should reset to Verdant Vale ✨ This PR was created with help from Hikari~ 🌸 Reviewed-on: #49 Co-authored-by: Hikari <hikari@nhcarrigan.com> Co-committed-by: Hikari <hikari@nhcarrigan.com>v0.1.2 |
||
|
|
404b31bd13 |
fix: persist UI preferences across navigation and sessions (#48)
## Summary - **#35** — Adventure multiplier selection is now persisted in `localStorage` (`"elysium_batch_size"`). The chosen batch size is restored automatically on the next visit, with a graceful fallback to `1` for missing or unrecognisable values. - **#36** — Zone selection in the boss panel and quest panel is now persisted in `sessionStorage` (`"elysium_boss_zone"` / `"elysium_quest_zone"`). The selected zone survives navigation within a session and resets cleanly when the session ends, defaulting to Verdant Vale if no stored value exists. ## Test plan - [x] Lint — zero errors, zero warnings - [x] Build — all packages build cleanly - [x] Tests — 415 tests passing, 100% coverage across all packages - [ ] Manual: select a non-default batch size, refresh the page — multiplier should be restored - [ ] Manual: switch to a non-default zone in the boss panel, navigate away and back — zone should still be selected - [ ] Manual: repeat for the quest panel - [ ] Manual: log out and back in — zone selection should reset to Verdant Vale ✨ This PR was created with help from Hikari~ 🌸 Reviewed-on: #48 Co-authored-by: Hikari <hikari@nhcarrigan.com> Co-committed-by: Hikari <hikari@nhcarrigan.com> |
||
|
|
d0790890ee |
fix: preserve all-time stats, achievements, and boss first-kill across prestige (#47)
Resolves #37, resolves #38, and resolves #39 — three related bugs where prestige incorrectly reset data that should survive all prestige resets. ## Changes ### fix: preserve lifetime player stats across prestige (#37) After prestige, `GameState.player.lifetime*` fields were stale — they reflected values from *before* the current run. The Prisma Player record was incremented correctly, but the GameState JSON saved to the DB had old values, so the UI showed wrong all-time totals on reload. `buildPostPrestigeState` now computes the run-stat contributions (bosses defeated, quests completed, adventurers recruited, achievements unlocked, gold earned, clicks) and folds them into the fresh player object before writing the prestige state. ### fix: preserve achievements across prestige (#38) `buildPostPrestigeState` was reconstructing achievements from `defaultAchievements` (via `initialGameState`), resetting all unlocked achievements on every prestige. Achievements are now carried forward from `currentState.achievements` instead. ### fix: preserve boss first-kill state across prestige (#39) Added `bountyRunestonesClaimed?: boolean` to the `Boss` type. The boss challenge route now: - Only awards the first-kill bounty runestones if `bountyRunestonesClaimed !== true` - Sets `bountyRunestonesClaimed = true` on first defeat `buildPostPrestigeState` maps the fresh boss list and carries the `bountyRunestonesClaimed` flag forward from the current state, so the bounty is never re-awarded in subsequent prestige runs. The boss panel badge is also hidden for bosses whose bounty is already claimed. ## Test Coverage All three fixes include new tests covering the new behaviours. API coverage remains at 100%. ✨ This PR was created with help from Hikari~ 🌸 Reviewed-on: #47 Co-authored-by: Hikari <hikari@nhcarrigan.com> Co-committed-by: Hikari <hikari@nhcarrigan.com> |
||
|
|
4d7e624358 |
fix: turn off auto-boss/auto-quest on failure and surface status (#46)
## Summary - Auto-boss now turns itself **off** when a boss fight is **lost**, so the player can reassess rather than the system silently looping. A "🤖 Last fight: [Boss] — ❌ Lost" status line appears in the boss panel. - Auto-boss also turns off (with an ⚠️ error message) when the API call fails outright (e.g. party has no adventurers), replacing the previous behaviour of silently hammering the API every animation frame. - Auto-quest now turns itself **off** whenever a quest fails the random-chance check, detected inside the tick's `setState` callback immediately after `applyTick`. - `autoBoss: false` and `autoQuest: false` are now part of `initialGameState`, so these fields persist through save/load cycles from the very first session — preventing a race window where the boss-route DB write could strip them before the first auto-save. - `toggleAutoBoss` clears both `autoBossLastResult` and `autoBossError` on each toggle so the panel always reflects the current session cleanly. ## Test plan - [x] `pnpm lint` — 0 errors, 0 warnings - [x] `pnpm build` — all packages clean - [x] `pnpm test` — 100% coverage maintained across the board Closes #40 ✨ This issue was created with help from Hikari~ 🌸 Reviewed-on: #46 Co-authored-by: Hikari <hikari@nhcarrigan.com> Co-committed-by: Hikari <hikari@nhcarrigan.com> |
||
|
|
ac94f67797 |
fix: send webhook milestone notifications silently (#45)
## Summary - Adds `flags: 4096` (`MessageFlags.SUPPRESS_NOTIFICATIONS`) to the Discord webhook payload in `postMilestoneWebhook` - Milestone announcements (prestige, transcendence, apotheosis) will now appear in the channel without triggering desktop or mobile push notifications - Defines the magic number as a documented `suppressNotifications` constant for self-documentation - Updates the webhook test to assert `flags: 4096` is present in the outgoing payload Closes #41 ## Test plan - [ ] Lint passes: `pnpm lint` - [ ] Build passes: `pnpm build` - [ ] Tests pass with 100% coverage: `pnpm test` - [ ] Trigger a prestige/transcendence/apotheosis in-game and verify the Discord webhook message arrives without pinging anyone ✨ This issue was created with help from Hikari~ 🌸 Reviewed-on: #45 Co-authored-by: Hikari <hikari@nhcarrigan.com> Co-committed-by: Hikari <hikari@nhcarrigan.com> |
||
|
|
a36c8e72a5 |
feat: error handling, logging, analytics, OG tags, and sticky sidebar (#44)
## Summary
- Add comprehensive try/catch error handling across all API routes, middleware, and the Hono global error handler, piping every unhandled error to the `@nhcarrigan/logger` service to prevent silent crashes and unhandled Promise rejections
- Add a `logError` utility on the frontend that forwards errors through the overridden `console.error` to the backend telemetry endpoint; apply it to every silent `catch {}` block in the game context, sound, notification, and clipboard utilities, and wrap the React tree in an `ErrorBoundary`
- Add Plausible analytics, Open Graph + Twitter Card meta tags, Tree-Nation widget, and Google Ads to `index.html`
- Make the game sidebar sticky with a `--resource-bar-height` CSS custom property offset so it stays viewport-height without overlapping the resource bar; reset sticky behaviour in the mobile responsive override
## Test plan
- [ ] Lint passes: `pnpm lint`
- [ ] Build passes: `pnpm build`
- [ ] Verify errors thrown in API routes appear in the logger service rather than crashing the process
- [ ] Verify frontend errors appear in the `/api/fe/error` backend log
- [ ] Verify Open Graph tags render correctly when sharing the URL
- [ ] Verify Plausible analytics fires on page load
- [ ] Verify Tree-Nation badge renders in the sidebar
- [ ] Verify sidebar stays fixed while the main content scrolls on desktop
- [ ] Verify mobile layout is unaffected
✨ This issue was created with help from Hikari~ 🌸
Reviewed-on: #44
Co-authored-by: Hikari <hikari@nhcarrigan.com>
Co-committed-by: Hikari <hikari@nhcarrigan.com>
|