Session 14: Buy All Upgrades (bulk-buy for upgrades) + empty-slot boost leak fix

- 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.
This commit is contained in:
2026-08-24 01:30:10 +00:00
parent b532f5a15c
commit 34074b8e65
5 changed files with 160 additions and 3 deletions
+28
View File
@@ -386,3 +386,31 @@ Wrote a headless Node.js test (`/opt/data/idle-game-test/slot-preview-test.mjs`)
- 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.