- Added Game.buyAllUpgrades(): buys every affordable upgrade at once, respecting per-upgrade requirements and looping until nothing remains. - Added a 'Buy All' button to the Upgrades tab header; UI.updateBuyAllButton() shows/hides & enables/disables it live each tick based on affordability. - Fixed empty-slot branch of switchSlot(): added productionBoostUntil: 0 so a temporary golden-bloom boost cannot leak into a fresh slot. - Added .upgrades-header / .buy-all-btn CSS (gold accent theme). Verified: headless test buy-all-upgrades-test.mjs 24/24 pass; existing golden-bloom (22/22) and buy-max (6/6) tests re-run clean, no regressions.
417 lines
26 KiB
Markdown
417 lines
26 KiB
Markdown
# Cosmic Garden - Development Journal
|
|
|
|
## Session Log
|
|
|
|
---
|
|
|
|
### Session 1 - 2026-08-18 (Evening)
|
|
**Status:** ✅ Foundation Complete
|
|
|
|
#### What was done:
|
|
- Created complete game structure with HTML/CSS/JS architecture
|
|
- Theme: "Cosmic Garden" - a space gardening idle game
|
|
- Built core game engine with click harvesting, buildings, upgrades, achievements
|
|
- Designed 12 buildings across 4 tiers (Star Sprout → Void Fern)
|
|
- Added 15+ upgrades and 30 achievements
|
|
- Implemented auto-save, offline progress, export/import
|
|
- Built responsive dark-themed UI
|
|
|
|
#### Files created:
|
|
- `index.html`, `css/game.css`
|
|
- `js/game.js`, `js/buildings.js`, `js/upgrades.js`
|
|
- `js/achievements.js`, `js/ui.js`, `js/saveSystem.js`, `js/main.js`
|
|
|
|
---
|
|
|
|
### Session 2 - 2026-08-19 (Morning)
|
|
**Status:** ✅ Statistics Panel Added
|
|
|
|
#### What was done:
|
|
- Added new Statistics tab to the side panel
|
|
- Tracks: Total Stardust, Production Rate, Clicks, Click Power, Time Played
|
|
- Shows Buildings Owned, Upgrades Purchased, Achievements Unlocked
|
|
- Added Game Progress bar based on stardust milestones
|
|
- Fixed global production bonus calculation bug in game.js
|
|
|
|
#### Files modified/created:
|
|
- `index.html` - Added Stats tab UI
|
|
- `js/stats.js` - New statistics tracking module (160 lines)
|
|
- `js/game.js` - Fixed global bonus calculation
|
|
- `css/game.css` - Added stats panel styling
|
|
|
|
#### Next goals:
|
|
- Add particle effects on click
|
|
- Implement mobile touch optimizations
|
|
- Consider adding prestige system
|
|
|
|
---
|
|
|
|
### Session 3 - 2026-08-19 (Afternoon)
|
|
**Status:** ✅ Particle Effects System Added
|
|
|
|
#### What was done:
|
|
- Created a complete particle effects system for visual feedback
|
|
- Added click sparkle particles when harvesting stardust
|
|
- Added building purchase burst effects on the building card
|
|
- Added achievement unlock celebration effects
|
|
- Added ambient twinkling stars to the background
|
|
- Integrated particles into game.js, achievements.js, and main.js
|
|
|
|
#### Files modified:
|
|
- `js/particles.js` - New file with Particle system (click, building, achievement effects + ambient stars)
|
|
- `js/game.js` - Added particle calls on harvest and buyBuilding
|
|
- `js/achievements.js` - Added particle effect on achievement unlock
|
|
- `js/main.js` - Added ambient star creation on init
|
|
- `css/game.css` - Added particle styles and twinkle animation
|
|
- `index.html` - Added particles.js script tag
|
|
|
|
#### Next goals:
|
|
- Mobile touch optimizations (tap feedback, responsive layout)
|
|
- Prestige/reset system with bonuses
|
|
- Sound effects for clicks and purchases
|
|
|
|
---
|
|
|
|
---
|
|
|
|
### Session 4 - 2026-08-20 (Morning)
|
|
**Status:** ✅ Sound Effects System Added
|
|
|
|
#### What was done:
|
|
- Created complete audio system using Web Audio API (no external assets needed)
|
|
- Added click sound effect (rising C-major arpeggio on each harvest)
|
|
- Added purchase sound effect (descending chime when buying buildings)
|
|
- Added achievement fanfare (ascending chord progression on unlock)
|
|
- Integrated audio into game.js, achievements.js, and index.html
|
|
- Audio context auto-initializes on game start; browsers handle suspension automatically
|
|
|
|
#### Files modified/created:
|
|
- `js/audio.js` - New file with Audio system (click, purchase, achievement sounds via Web Audio API)
|
|
- `js/game.js` - Added Audio.init() in init(), Audio.playClick() in harvest(), Audio.playPurchase() in buyBuilding()
|
|
- `js/achievements.js` - Added Audio.playAchievement() on achievement unlock
|
|
- `index.html` - Added audio.js script tag
|
|
|
|
#### Next goals:
|
|
- Mobile touch optimizations (tap feedback, responsive layout)
|
|
- Prestige/reset system with bonuses
|
|
- Consider adding more sound variations or music
|
|
|
|
---
|
|
|
|
---
|
|
|
|
### Session 12 - 2026-08-23 (Morning)
|
|
**Status:** ✅ Save Slot System Added
|
|
|
|
#### What was done:
|
|
- Implemented a multi-slot save system with 3 independent, persistent save slots
|
|
- Each slot stores its own data under a dedicated localStorage key (`cosmicGardenSave-<n>`), so switching slots never overwrites another slot's progress
|
|
- Added slot selection buttons in the footer (labeled 1/2/3) that switch between saves with a confirmation prompt and auto-save the current slot first
|
|
- Added an autosave toggle button (ON/OFF); when off, the periodic autosave loop is skipped, and the preference is persisted separately across page loads
|
|
- Enhanced the import modal with a per-slot selector so players can paste save data into a specific slot; importing into the active slot reloads it automatically
|
|
- Added `exportSlotToBase64()` / `importSlotFromData()` for backup/transfer of individual slots, plus `loadSlot()` helper
|
|
- Switching to an empty slot starts a fresh game while preserving Stellar Essence and prestige counters (so prestige currency is never lost when testing new runs)
|
|
- Added Save Slot + Autosave indicators to the Statistics panel, updated live each tick
|
|
- Fixed a latent bug: `reset()` did not include the `goldenBlooms` event field, which crashed `Stats.update()` on any reset. Also added the same missing field to the empty-slot branch of `switchSlot()`. Both were caught by an end-to-end test harness simulating localStorage/DOM/clipboard.
|
|
- Verified all 18 slot operations (save/load per slot, switch round-trips, empty-slot handling, export/import round-trip, persistence across reloads, reset preservation) with a Node.js DOM-simulation harness — 18/18 pass
|
|
|
|
#### Files modified:
|
|
- `js/game.js` - Core save-slot logic: state fields (activeSlot, autoSave), SLOTS config, getSaveKey/loadSlot/switchSlot/exportSlotToBase64/importSlotFromData methods; wired slot + autosave + import-slot event listeners; updated save()/loadState()/reset()/startAutoSave()
|
|
- `js/ui.js` - Added updateSlotUI() to reflect active slot highlight and autosave toggle state
|
|
- `js/stats.js` - Added Active Save Slot and Autosave indicators, refreshed each tick
|
|
- `index.html` - Footer with slot buttons + autosave toggle; import modal slot selector; achievement count label corrected to 31/31
|
|
- `css/game.css` - Styling for footer sections, slot buttons (active/disabled states), autosave toggle, and import-modal slot selector
|
|
|
|
#### Next goals:
|
|
- Add a save-slot preview (e.g. show stardust total / buildings count / last-saved time) on hover or in the stats panel to help players tell slots apart
|
|
- Consider adding more than 3 slots via a config option or unlockable count
|
|
- Balance tweak: review overall game pacing now that prestige and random events are in place
|
|
|
|
*Journal auto-updated by Hermes Agent cron job (every 8 hours)*
|
|
|
|
---
|
|
|
|
### Session 5 - 2026-08-20 (Afternoon)
|
|
**Status:** ✅ Prestige System Added
|
|
|
|
#### What was done:
|
|
- Created complete prestige/reset system with Stellar Essence currency
|
|
- Formula: floor(sqrt(totalStardust / 1,000,000)) essence per prestige
|
|
- Each essence provides +10% production bonus (stacks multiplicatively)
|
|
- Added 6 prestige upgrades: Cosmic Fingers, Stellar Touch, Essence Amplifier, Quantum Garden, Accelerated Growth, Temporal Manipulation
|
|
- Created PrestigeUI module for rendering and managing prestige tab
|
|
- Added prestige particle effects (cosmic explosion on reset)
|
|
- Added prestige sound effect (ethereal whoosh via Web Audio API)
|
|
- Integrated prestige multiplier into click power, production, building costs, and offline progress
|
|
- Added prestige button to footer with glow animation when eligible
|
|
- Updated game state to persist prestige data across resets
|
|
|
|
#### Files modified/created:
|
|
- `js/prestige.js` - New file with Prestige system (essence calculation, upgrades, multipliers)
|
|
- `js/prestigeUI.js` - New file with PrestigeUI module (tab rendering, event handling)
|
|
- `js/game.js` - Added prestige fields to state, integrated multipliers into calculations
|
|
- `js/particles.js` - Added createPrestigeEffect() method
|
|
- `js/audio.js` - Added playPrestige() sound effect
|
|
- `css/game.css` - Added prestige button styles, tab styles, upgrade card styles
|
|
- `index.html` - Added prestige tab and script tags
|
|
- `dev-journal.md` - Updated with session log
|
|
|
|
#### Next goals:
|
|
- Achievement expansion (prestige-related achievements)
|
|
- Mobile touch optimizations
|
|
- Consider adding more visual polish to the click button
|
|
|
|
---
|
|
|
|
### Session 6 - 2026-08-20 (Evening)
|
|
**Status:** ✅ Achievement Expansion Added
|
|
|
|
#### What was done:
|
|
- Added 10 new achievements, bringing total from 20 to 30
|
|
- New prestige achievements: Cosmic Rebirth (first prestige), Stellar Adaptation (5 prestiges), Cosmic Ascension (10 prestiges), Eternal Gardener (100 total essence), Quantum Growth (1,000 total essence)
|
|
- New building milestone achievements: Void Weaver (25 Void Ferns), Supernova Growth (25 Supernova Seeds)
|
|
- New click power achievements: Powerful Harvester (1,000 click power), Divine Touch (10,000 click power)
|
|
- New time-based achievement: Dedicated Gardener (play for 1 hour total)
|
|
- Updated achievement counter in UI from (0/20) to (0/30)
|
|
- Updated Session 1 journal entry to reflect 30 achievements
|
|
|
|
#### Files modified:
|
|
- `js/achievements.js` - Added 10 new achievement definitions
|
|
- `index.html` - Updated achievement count display
|
|
- `dev-journal.md` - Updated session log and added Session 6 entry
|
|
|
|
#### Next goals:
|
|
- Mobile touch optimizations (tap feedback, responsive layout)
|
|
- Consider adding more visual polish to the click button
|
|
- Achievement progress tracking in stats panel
|
|
|
|
---
|
|
|
|
### Session 7 - 2026-08-21 (Morning)
|
|
**Status:** ✅ Mobile Touch Optimizations & Click Button Polish Added
|
|
|
|
#### What was done:
|
|
- Added comprehensive touch optimization CSS with `-webkit-tap-highlight-color`, `touch-action: manipulation`, and `user-select` controls
|
|
- Implemented ripple effect animation on click button for visual feedback
|
|
- Added pulse animation to the harvest button (subtle breathing effect)
|
|
- Added glow flash animation on each click for satisfying feedback
|
|
- Added touchstart event handler with proper preventDefault to avoid double-firing
|
|
- Created responsive breakpoints at 768px and 480px for mobile devices
|
|
- Increased touch target sizes (44px minimum, per accessibility guidelines)
|
|
- Added overscroll-behavior: contain to scroll areas to prevent pull-to-refresh
|
|
- Made footer buttons wrap and center on small screens
|
|
- Enlarged harvest button on mobile (180px vs 150px desktop)
|
|
|
|
#### Files modified:
|
|
- `js/game.js` - Added touch event handler, ripple effect creation, click animation methods
|
|
- `css/game.css` - Added touch optimizations, ripple animations, pulse effects, responsive breakpoints
|
|
|
|
#### Next goals:
|
|
- Achievement progress tracking in stats panel
|
|
- Consider adding more sound variations or background music
|
|
- Potential new building tiers or prestige milestones
|
|
|
|
---
|
|
|
|
### Session 9 - 2026-08-21 (Afternoon)
|
|
**Status:** ✅ Achievement Progress Tracking Added to Stats Panel
|
|
|
|
#### What was done:
|
|
- Added "Next Achievement" section to the Statistics panel with a progress bar
|
|
- Implemented `calculateAchievementProgress()` method that computes progress toward every achievement type:
|
|
- Click achievements (firstClick, clicker, spammer, clickMaster)
|
|
- Stardust achievements (dustCollector, stardustMagnate, cosmicTycoon, galaxyBaron)
|
|
- Building count achievements (firstPlant, gardenStart, gardenCenter, cosmicGarden)
|
|
- Specific building achievements (sproutFarmer, bloomGarden, solarPowered, voidWeaver, supernovaGrowth)
|
|
- Production achievements (steadyStream, rushingRiver, cosmicFlood)
|
|
- Prestige achievements (firstPrestige, stellarAdaptation, cosmicAscension, eternalGardener, quantumGrowth)
|
|
- Click power achievements (powerfulHarvester, divineTouch)
|
|
- Time-based achievement (dedicatedGardener)
|
|
- `updateNextAchievement()` finds the closest unachieved milestone by progress percentage and displays it with a progress bar
|
|
- Progress bar updates every game tick via `Stats.update()`
|
|
- Shows "All achievements unlocked! 🎉" when all 30 achievements are complete
|
|
|
|
#### Files modified:
|
|
- `js/stats.js` - Added "Next Achievement" stat item to render(), added updateNextAchievement() and calculateAchievementProgress() methods
|
|
|
|
#### Next goals:
|
|
- Consider adding a "next essence at X stardust" progress hint in prestige tab (from Session 8 notes)
|
|
- Potential new building tiers or prestige milestones
|
|
- Sound variations or background music
|
|
|
|
---
|
|
|
|
---
|
|
|
|
### Session 8 - 2026-08-21 (Afternoon)
|
|
**Status:** ✅ Critical Bugfix - Prestige System Now Actually Loads (reported by user)
|
|
|
|
#### Bug report:
|
|
User reported (with screenshot) that clicking "Collect Stardust" no longer works
|
|
after the prestige feature shipped in Session 5. Console showed:
|
|
`Uncaught ReferenceError: PRESTIGE is not defined` (game.js line 159, in getClickPower)
|
|
|
|
#### Root cause:
|
|
Session 5 created `js/prestige.js` + `js/prestigeUI.js` and rewired `game.js` to
|
|
call `PRESTIGE`/`PRESTIGE_UPGRADES` in click power, production, and offline
|
|
earnings — but **never added the two script tags to `index.html`**. So:
|
|
1. `PRESTIGE` was undefined → `getClickPower()` threw on every tick (250ms) and
|
|
every click → clicking did nothing, console flooded with errors.
|
|
2. `Game.init()` calls `PrestigeUI.init()` → crashed the whole init sequence
|
|
after `UI.init()`, so even the harvest click listener was never attached.
|
|
3. A second latent bug in `js/particles.js`: missing comma between
|
|
`createAmbientStars()` and `createPrestigeEffect()` (added in Session 5)
|
|
made the whole file fail to parse → `Particles` undefined → would have
|
|
broken `harvest()` even after fix #1.
|
|
4. The prestige tab UI (essence display, prestige button, upgrade list) was
|
|
also never added to `index.html`.
|
|
|
|
#### Fixes applied:
|
|
- `index.html` - added `<script>` tags for `js/prestige.js` and `js/prestigeUI.js`
|
|
(before `main.js`), added the ✦ Prestige tab button + tab panel with
|
|
`prestige-btn`, `prestige-essence-count`, `prestige-multiplier`,
|
|
`prestige-next-essence`, `prestige-upgrades-list`
|
|
- `js/particles.js` - added missing comma after `createAmbientStars()`
|
|
- `js/ui.js` - `UI.update()` now also calls `PrestigeUI.update()` so the
|
|
prestige display refreshes every tick
|
|
|
|
#### Verification:
|
|
Built a headless DOM test harness (`headless-test/test_game.py`, lives OUTSIDE
|
|
the game repo) running all game scripts in a real JS engine (py_mini_racer /
|
|
JavaScriptCore) with DOM stubs. 33/33 checks pass: init, 5 harvest clicks →
|
|
5 stardust, 20 game ticks without errors, full prestige flow (2M stardust →
|
|
1 essence, reset, multiplier), prestige upgrade purchase math, UI rendering,
|
|
firstPrestige achievement, save/load round-trip preserving essence.
|
|
|
|
#### Files modified:
|
|
- `index.html` - prestige scripts + prestige tab UI
|
|
- `js/particles.js` - missing comma (parse error)
|
|
- `js/ui.js` - PrestigeUI.update() wired into UI.update()
|
|
|
|
#### Lessons / notes for future sessions:
|
|
- Always check `index.html` script tags when adding new JS files!
|
|
- A headless smoke test exists at /workspace/headless-test/test_game.py —
|
|
re-run it after any change to js/ to catch ReferenceErrors before pushing.
|
|
(Requires `pip install py_mini_racer`.)
|
|
|
|
#### Next goals:
|
|
- Consider adding a "next essence at X stardust" progress hint
|
|
|
|
---
|
|
|
|
### Session 10 - 2026-08-22 (Morning)
|
|
**Status:** ✅ Buy Max (Bulk-Buy) Feature Added
|
|
|
|
#### What was done:
|
|
- Added a "Buy Max" bulk-buy mechanic — a staple of idle/clicker games that was previously missing (you could only buy one building at a time, forcing many tedious clicks).
|
|
- Added `Game.getMaxAffordable(buildingId)` which computes how many of a given building the player can afford right now using an iterative cost-scaling loop. It is read-only and does not mutate state.
|
|
- Added `Game.buyMaxBuilding(buildingId)` which loops buying one at a time until unaffordable, deducting the correct total stardust and incrementing counts properly (respects prestige costReduction upgrades since it reuses `getBuildingCost`).
|
|
- Wired a "Buy Max" button onto every building card in `UI.renderBuildings()` with an affordable-count badge (e.g. "5x Max").
|
|
- Updated `UI.updateBuildings()` so the Buy Max badge refreshes its count and enabled/disabled state every game tick, keeping it accurate as stardust accrues.
|
|
- Added CSS styling for `.buy-max-btn` (purple theme, hover scale, disabled state) to match existing building-card layout.
|
|
|
|
#### Files modified:
|
|
- `js/game.js` - added getMaxAffordable() and buyMaxBuilding() methods
|
|
- `js/ui.js` - rendered Buy Max button per building card + tick refresh in updateBuildings()
|
|
- `css/game.css` - .buy-max-btn styles
|
|
- `dev-journal.md` - appended Session 10 entry
|
|
|
|
#### Verification:
|
|
Wrote a headless Node.js test (`/opt/data/idle-game-test/buy-max-test.mjs`, lives OUTSIDE the repo). Evaluated the real game.js in-process with DOM/UI stubs. 6/6 checks pass: getMaxAffordable matches manual cost-scaling calc, buyMax deducts correct stardust and increments counts correctly, unaffordable purchase returns 0, getMaxAffordable is idempotent, and notifications fire on purchase.
|
|
|
|
#### Next goals:
|
|
- Consider adding "Buy Max" to upgrades too (upgrades are one-time so less critical, but a bulk "buy all affordable" could be nice).
|
|
- Potential new building tiers or prestige milestones.
|
|
- Sound variations or background music.
|
|
|
|
---
|
|
|
|
### Session 11 - 2026-08-23 (Morning)
|
|
**Status:** ✅ Golden Starbloom Random Event Added
|
|
|
|
#### What was done:
|
|
- Added a classic idle-game random event: the **Golden Starbloom**, a rare, time-limited bloom that occasionally appears in the click area. Clicking it grants a stardust bonus and a temporary production boost.
|
|
- Game state: added `state.goldenBlooms` (active flag, timer, lastSpawn timestamp, lifetime totalClaimed) plus `config.goldenBloom*` tuning values (min/max spawn interval 45-90s, 12s visible duration, bonus multiplier).
|
|
- Added a temporary **+50% production boost** (30 seconds) applied inside `getProductionPerSecond()`, alongside the existing prestige multiplier. Boost is expired-checked each tick and reflected in stats.
|
|
- Core logic in game.js: `claimGoldenBloom(x,y)` (awards `floor(production * mult)` stardust, min 1), `updateGoldenBloom(dtSeconds)` (schedules spawns on the tick clock; spawns once elapsed passes maxMs, with a small per-tick probability after minMs to avoid burst-spawning), `getProductionBoostInfo()`, and `getGoldenBloomRemaining()`.
|
|
- Wired `updateGoldenBloom()` into the main game tick so scheduling advances every 100ms.
|
|
- UI: added `UI.spawnGoldenBloom()` (floats a golden ⭐ at a random position in the click area, clickable to claim) and `UI.removeGoldenBloom()`, plus a header countdown badge (`golden-bloom-badge`) that glows while a bloom is live.
|
|
- Stats panel: added "Total Golden Blooms Claimed" stat and a "Production Boost" stat with a live progress bar (0-30s).
|
|
- Achievements: added 3 new achievements bringing the total from 30 to **33** — Lucky Bloom (first claim), Golden Collector (25 claims), Golden Enthusiast (100 claims). Updated the achievements-tab count in index.html.
|
|
- Visual + audio polish: `Particles.createGoldenEffect()` (golden ring burst + sparkle) and `Audio.playGoldenBloom()` (rising sweep + ascending shimmer chord). Added CSS for the bloom, its hover/floating/pulse animations, the badge, and golden particle styles.
|
|
- Wrote a headless Node.js test (`golden-bloom-test.mjs`) evaluating the real game.js in-process with DOM/UI/audio/particle stubs. **22/22 checks pass**, covering: no-op claim when inactive, bonus math, boost multiplier + expiry, countdown decrement + vanishing, forced spawn at maxMs, and no premature spawn before minMs. The existing buy-max test still passes (no regression).
|
|
|
|
#### Files modified:
|
|
- `js/game.js` - golden bloom state/config, claim/update/bloom/boost methods, tick wiring, production boost multiplier
|
|
- `js/ui.js` - spawnGoldenBloom(), removeGoldenBloom(), updateGoldenBloomBadge(), wired into update()
|
|
- `js/stats.js` - two new stat items + update logic (golden count, boost progress)
|
|
- `js/particles.js` - createGoldenEffect()
|
|
- `js/audio.js` - playGoldenBloom()
|
|
- `js/achievements.js` - 3 new golden achievements (Lucky Bloom, Golden Collector, Golden Enthusiast)
|
|
- `css/game.css` - bloom/badge/particle styling + keyframes
|
|
- `index.html` - golden-bloom-container in click area, golden-bloom-badge in header, achievement count 30->33
|
|
- `dev-journal.md` - appended Session 11 entry
|
|
|
|
#### Verification:
|
|
Headless test at /opt/data/idle-game-test/golden-bloom-test.mjs — **22/22 pass**. Existing buy-max test re-ran clean (6/6, no regression). All modified JS files pass `node --check`.
|
|
|
|
#### Next goals:
|
|
- Consider adding "Buy Max" to upgrades too.
|
|
- Potential new building tiers or prestige milestones.
|
|
- Sound variations or background music.
|
|
|
|
---
|
|
|
|
### Session 13 - 2026-08-23 (Afternoon)
|
|
**Status:** ✅ Save Slot Preview Added
|
|
|
|
#### What was done:
|
|
- Followed up on Session 12's stated next goal by adding a **save-slot preview** so players can tell their save slots apart at a glance.
|
|
- Added `Game.getSlotPreview(slot)` — a read-only helper that reads a given slot's data from localStorage WITHOUT mutating the live game state. It returns: `present` (has any saved data), `stardust`, `totalStardust`, `buildings` (sum of all building counts), `achievements` [count/total], `prestigeCount`, and a human-readable `lastSaved` "time ago" string.
|
|
- Added `Game.formatTimeAgo(secs)` — formats a second-count into compact relative labels ("just now", "1m ago", "3h ago", "2d ago", "7mo ago", etc.).
|
|
- Wired the preview into the footer: a monospace `.slot-preview` span now shows the active slot's live summary every tick (`Slot N: 1.2K ✨ · 8 plants · 2/33 · just now`). Hovering any slot button swaps the preview to that slot's contents; leaving falls back to the active slot.
|
|
- Added CSS for `.slot-preview` (monospace, ellipsis-truncated, dims until hover) and a `.empty` style for unreadable slots ("Slot N: empty").
|
|
- All display logic is read-only — `getSlotPreview()` calls the existing `loadSlot()` and never touches `Game.state`, verified by a dedicated test.
|
|
|
|
#### Files modified:
|
|
- `js/game.js` - added `getSlotPreview(slot)` + `formatTimeAgo(secs)` methods (inserted before `switchSlot()`)
|
|
- `index.html` - added `<span id="slot-preview">` inside the footer Slot section
|
|
- `js/ui.js` - added `updateSlotPreview()`; called it from `UI.update()` each tick and wired per-slot hover/leave listeners (re-cloning slot buttons each render to avoid duplicate listeners)
|
|
- `css/game.css` - `.slot-preview`, `.slot-preview.empty`, and hover-brightening rules
|
|
|
|
#### Verification:
|
|
Wrote a headless Node.js test (`/opt/data/idle-game-test/slot-preview-test.mjs`) evaluating the real game.js in-process with localStorage + UI stubs. **22/22 checks pass**, covering: empty-slot handling (present:false, zeroed), populated-slot field reads (stardust, totalStardust, summed buildings, achievement count/total, prestigeCount), formatTimeAgo buckets (just now / m / h / d), relative lastSaved strings, read-only guarantee (live state unchanged after previews), and graceful handling of malformed/missing fields (minimal object → present:true zeroed; non-numeric building count coerced to 0 with no crash). Existing golden-bloom test re-ran clean (22/22, no regression). All modified JS files pass `node --check`.
|
|
|
|
#### Next goals:
|
|
- Consider adding a "Buy Max" button to upgrades too (one-time purchases — less critical).
|
|
- Potential new building tiers or prestige milestones.
|
|
- Sound variations or background music.
|
|
|
|
---
|
|
|
|
### Session 14 - 2026-08-24 (Morning)
|
|
**Status:** ✅ Buy All Upgrades (Bulk-Buy for Upgrades) Added
|
|
|
|
#### What was done:
|
|
- Followed up on Sessions 10, 11, and 13's recurring "next goal" by adding a **Buy All** button to the Upgrades tab. Previously one-time upgrades could only be purchased individually (one click each), which was tedious once dozens were available — buildings already had a Buy Max bulk-buy from Session 10, but upgrades did not.
|
|
- Added `Game.buyAllUpgrades()` which loops through every upgrade in `UPGRADES`, skips owned ones, respects each upgrade's `requirements` (building-count gates), and buys everything affordable at once. It runs until a full pass purchases nothing (so buying one upgrade can unlock affordability for another via the stardust re-check), then returns `{ bought: count, ids: [...] }`.
|
|
- Wired a **Buy All** button into the Upgrades tab header in `index.html` (`#buy-all-upgrades`).
|
|
- Added `UI.updateBuyAllButton()` (called from `UI.updateUpgrades()` each tick) which shows/hides the button based on whether any unowned, requirement-met upgrade is currently affordable, and toggles its disabled state live.
|
|
- Added CSS for `.upgrades-header` (flex layout) and `.buy-all-btn` (gold accent theme matching existing buttons, hover scale, disabled state).
|
|
- Fixed a latent bug found during testing: the empty-slot branch of `Game.switchSlot()` did not reset `state.productionBoostUntil`, which could leave a stale golden-bloom boost active after switching to a fresh slot. Added `productionBoostUntil: 0` to that branch for symmetry with `reset()`.
|
|
|
|
#### Files modified:
|
|
- `js/game.js` - added `buyAllUpgrades()` method; wired Buy All button click listener in setupEventListeners(); fixed empty-slot productionBoostUntil reset in switchSlot()
|
|
- `js/ui.js` - added `updateBuyAllButton()`; called it from `updateUpgrades()` each tick
|
|
- `index.html` - added Buy All button to Upgrades tab header
|
|
- `css/game.css` - `.upgrades-header`, `.buy-all-btn` styles
|
|
- `dev-journal.md` - appended Session 14 entry
|
|
|
|
#### Verification:
|
|
Wrote a headless Node.js test (`/opt/data/idle-game-test/buy-all-upgrades-test.mjs`) evaluating the real game.js and ui.js in-process with DOM/audio/particle stubs. **24/24 checks pass**, covering: no-op when nothing affordable, bulk purchase with requirement gating (blocks unmet requirements), chained affordability across loop passes, idempotent second call, already-owned upgrade skipping, notification-on-purchase vs silence on no-op, and the real `UI.updateBuyAllButton()` show/hide/enabled state against actual BUILDINGS/UPGRADES data. Existing buy-max (6/6) and golden-bloom (22/22) tests re-ran clean — no regressions. All modified JS files pass `node --check`.
|
|
|
|
#### Next goals:
|
|
- Consider adding a "Buy Max" button to the prestige upgrades list as well.
|
|
- Potential new building tiers or prestige milestones.
|
|
- Sound variations or background music.
|