Session 17: Sound Toggle (mute/unmute with persistence) Added

This commit is contained in:
2026-08-25 02:17:50 +00:00
parent cc1fa6bc4d
commit b9068e2029
5 changed files with 133 additions and 18 deletions
+28
View File
@@ -468,3 +468,31 @@ Wrote a headless Node.js test (`/opt/data/idle-game-test/buy-all-buildings-test.
- Potential new building tiers or prestige milestones / new prestige upgrades.
- Sound variations or background music.
- Consider a "Buy Max" toggle (buy one-at-a-time vs bulk) or per-building Buy Max count display.
---
### Session 17 - 2026-08-25 (Morning)
**Status:** ✅ Sound Toggle (mute/unmute with persistence) Added
#### What was done:
- Followed up on Sessions 14-16's recurring "sound variations / background music" next-goal by adding a **footer Sound toggle button**. The game already had a full Web Audio sound-effect system (click arpeggio, purchase chime, achievement fanfare, prestige whoosh, golden-bloom shimmer in `js/audio.js`), but there was no way to turn it off — once the audio context started on first click, it could never be silenced. This is a real usability gap for, e.g., playing at night or in a shared space.
- Added `soundEnabled: true` to `Game.state` and made **every** sound effect flow through a single new method `Game.playSound(effect)` (effects: 'click', 'purchase', 'achievement', 'prestige', 'goldenBloom'). The method returns early when `soundEnabled` is false, so muting reliably silences all effects. Replaced every direct `Audio.play*()` call site in `game.js`, `prestige.js`, and `achievements.js` with `Game.playSound(...)`.
- Guarded the initial `Audio.init()` on `if (this.state.soundEnabled)` so a muted player's browser never creates an audio context at all.
- Added a footer **Sound** toggle button (`#sound-btn`) next to the existing Autosave toggle, reusing the `.toggle-btn` styling. It shows 🔊/🔇 icons (instead of ON/OFF text), toggles `state.soundEnabled`, persists the preference to `localStorage('cosmicGardenSound')`, shows a notification, and — when unmute-ing — re-initializes/resumes the audio context (a click gesture satisfies the browser's autoplay policy).
- Added `Game.syncSoundButton()` which reflects the current preference on the footer button's visual state; called it at the end of `init()` so a muted player sees a muted button on reload even though the HTML defaults to enabled.
- Restored the persisted sound preference in `loadState()` **outside** the `if (saved)` block so it applies whether or not a per-slot save exists, and preserved `soundEnabled` across `reset()` and the empty-slot branch of `switchSlot()` (mirroring the existing `autoSave` handling).
#### Files modified:
- `js/game.js` - added `soundEnabled` state; `playSound()` + `syncSoundButton()` methods; guarded `Audio.init()`; sound-toggle event listener; routed all 6 audio call sites through `Game.playSound`; restored pref in `loadState()`; preserved across `reset()`/`switchSlot()`
- `js/prestige.js` - routed prestige + prestige-upgrade sounds through `Game.playSound()`
- `js/achievements.js` - routed achievement sound through `Game.playSound()`
- `index.html` - added Sound toggle button to the footer
- `dev-journal.md` - appended Session 17 entry
#### Verification:
Wrote a headless Node.js test (`/opt/data/idle-game-test/sound-toggle-test.mjs`) that loads the real `game.js` in-process with DOM/audio/localStorage stubs. **29/29 checks pass**, covering: default-on state, correct effect routing when enabled, total silence for all five effects when muted, unknown-effect safety, toggle button flipping preference + persisting to localStorage + showing notifications + updating 🔊/🔇 icon and `.on` class, restoring the muted/enabled preference from `loadState()` both with and without a save on disk, `reset()` preserving the preference across both states, and `syncSoundButton()` visual state. All existing suites re-ran clean with no regressions: buy-max 6/6, buy-all-upgrades 24/24, golden-bloom 22/22, prestige-buy-max 22/22, slot-preview 22/22, buy-all-buildings 31/31. All modified JS files pass `node --check`.
#### Next goals:
- 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.