From 4e873773feec6961ea54f263d5bf4a41fa1f45ba Mon Sep 17 00:00:00 2001 From: Hermes Agent Date: Tue, 25 Aug 2026 10:33:27 +0000 Subject: [PATCH] Session 18: Prestige Progress Bar (live visual progress toward next Stellar Essence) --- css/game.css | 45 +++++++++++++++++++++++++++++++++++++++++++++ dev-journal.md | 24 ++++++++++++++++++++++++ index.html | 10 ++++++++++ js/prestigeUI.js | 34 ++++++++++++++++++++++++++++++++++ 4 files changed, 113 insertions(+) diff --git a/css/game.css b/css/game.css index 0814732..44e952a 100644 --- a/css/game.css +++ b/css/game.css @@ -1060,6 +1060,51 @@ h2, h3 { font-weight: bold; } +/* Prestige Progress Bar */ +.prestige-progress { + margin-bottom: 8px; +} + +.prestige-progress-label { + display: flex; + justify-content: space-between; + align-items: center; + color: var(--text-secondary); + font-size: 0.8rem; + margin-bottom: 5px; +} + +.prestige-progress-label #prestige-progress-pct { + color: var(--accent-purple); + font-weight: bold; +} + +.prestige-progress-bar { + width: 100%; + height: 12px; + background: var(--bg-card-2, var(--text-muted)); + border-radius: 6px; + overflow: hidden; + border: 1px solid var(--border-color); +} + +.prestige-progress-fill { + height: 100%; + width: 0%; + background: linear-gradient(90deg, var(--accent-purple), #b366ff); + border-radius: 6px; + transition: width 0.25s ease-out; +} + +.prestige-progress-fill.filling { + animation: prestigeGlow 1.5s ease-in-out infinite; +} + +@keyframes prestigeGlow { + 0%, 100% { filter: brightness(1); } + 50% { filter: brightness(1.25); } +} + /* Prestige Upgrade Cards */ #prestige-upgrades-list { display: flex; diff --git a/dev-journal.md b/dev-journal.md index 29fe978..42083cf 100644 --- a/dev-journal.md +++ b/dev-journal.md @@ -496,3 +496,27 @@ Wrote a headless Node.js test (`/opt/data/idle-game-test/sound-toggle-test.mjs`) - Consider adding a mute-state persistence across slots explicitly tested via the UI (currently preserved in state; could add a dedicated test that switches slots and checks the button). - Potential new building tiers or prestige milestones / new prestige upgrades. - Background music track or per-effect volume sliders. + +--- + +### Session 18 - 2026-08-25 (Morning) +**Status:** ✅ Prestige Progress Bar Added + +#### What was done: +- Followed up on Sessions 14-17's recurring "prestige milestones" next-goal by adding a **live prestige progress bar** to the Prestige tab. The tab already showed a static "Next prestige: N ✦" number (the essence you'd gain right now), but players had no visual sense of how close they were to earning their next Stellar Essence — a staple idle-game UX element that makes the prestige loop feel rewarding between resets. +- New math derived from the existing `PRESTIGE.calculateEssence()` formula: essence level e = floor(sqrt(totalStardust / 1e6)), so tier e begins at e²·1M stardust and tier (e+1) begins at (e+1)²·1M. The bar fills linearly across a tier's stardust range and resets to 0% exactly when a new essence level is reached, so it stays perfectly consistent with `calculateEssence()` (verified: at 999,999 total → 100%, at 1,000,000 → 0% and essence = 1). +- Added the DOM in index.html: a `.prestige-progress` block with a "Prestige progress / N%" label row and a `.prestige-progress-bar` track + `.prestige-progress-fill` bar (purple gradient) inserted between the existing "Next prestige" line and the explanatory paragraph. +- Added CSS (.prestige-progress, .prestige-progress-label, .prestige-progress-bar, .prestige-progress-fill) matching the existing prestige card theme: purple gradient fill, subtle border, 0.25s ease-out width transition, and a gentle pulsing glow (keyframes `prestigeGlow`) applied only while 0% < progress < 100%, so a freshly-emptied bar sits still after prestige. +- Added `PrestigeUI.updatePrestigeProgress()` (read-only: mutates DOM only) and wired it into `PrestigeUI.update()` right after the "Next prestige" number, so the bar refreshes every tick alongside the other prestige stats. + +#### Files modified: +- `index.html` - added `.prestige-progress` block (label + percentage + progress bar) in Prestige tab +- `css/game.css` - `.prestige-progress*` styles + `.prestige-progress-fill.filling` glow keyframes +- `js/prestigeUI.js` - added `updatePrestigeProgress()` method; called it from `update()` each tick + +#### Verification: +Wrote a headless Node.js test (`/opt/data/idle-game-test/prestige-progress-bar-test.cjs`) that loads the REAL game.js, prestige.js, and prestigeUI.js in-process via node:vm with DOM/UI/audio/particle stubs. **20/20 checks pass**, covering: empty-state (0%), mid-tier fill (500K→50%, 2M→33%, 6.5M→50%), tier boundary behavior (999,999→100% no glow, 1M→0% reset with essence=1), the glow class toggling correctly (active only while 0 Next prestige: 0 ✦ + +
+
+ Prestige progress + 0% +
+
+
+
+

Requires 1M total stardust for the first ✦. Prestige resets stardust, buildings and upgrades — but keeps essence and diff --git a/js/prestigeUI.js b/js/prestigeUI.js index e1bd7d9..0e2e93d 100644 --- a/js/prestigeUI.js +++ b/js/prestigeUI.js @@ -115,6 +115,11 @@ const PrestigeUI = { nextEl.textContent = nextEssence; } + // Prestige progress bar: how far total stardust is toward the next + // Stellar Essence level. essence(e) = floor(sqrt(totalStardust/1e6)), + // so tier e needs e^2*1M stardust and tier (e+1) needs (e+1)^2*1M. + this.updatePrestigeProgress(); + // Update prestige button state const prestigeBtn = document.getElementById('prestige-btn'); if (prestigeBtn) { @@ -134,6 +139,35 @@ const PrestigeUI = { this.updateBuyMaxPrestigeButton(); }, + /** + * Update the prestige progress bar showing how close total stardust is to + * earning the next Stellar Essence. essence level e = floor(sqrt(totalStardust/1e6)), + * so tier e begins at e^2*1M and tier (e+1) begins at (e+1)^2*1M; the bar + * fills linearly across that tier's stardust range and resets to 0% exactly + * when a new essence level is reached. Read-only: mutates only DOM. + */ + updatePrestigeProgress() { + const totalStardust = Game.state.totalStardust || 0; + const e = Math.floor(Math.sqrt(totalStardust / 1e6)); + const tierFloor = e * e * 1e6; + const tierCeil = (e + 1) * (e + 1) * 1e6; + const progress = Math.min(1, Math.max(0, (totalStardust - tierFloor) / (tierCeil - tierFloor))); + + const fillEl = document.getElementById('prestige-progress-fill'); + if (fillEl) { + const pct = Math.round(progress * 100); + fillEl.style.width = `${pct}%`; + // Only apply the pulsing glow while there is progress to show, so a + // freshly-emptied bar (e.g. right after prestige) sits still. + fillEl.classList.toggle('filling', pct > 0 && pct < 100); + } + + const pctLabel = document.getElementById('prestige-progress-pct'); + if (pctLabel) { + pctLabel.textContent = `${Math.round(progress * 100)}%`; + } + }, + /** * Show/hide and enable/disable the "Buy Max" prestige-upgrades button * depending on whether at least one unowned, requirement-met prestige