diff --git a/HANDOFF.md b/HANDOFF.md index 62a107c..ad45c23 100644 --- a/HANDOFF.md +++ b/HANDOFF.md @@ -5,7 +5,7 @@ ## 1. Where we are - **Last completed step:** 10.17 — Leaderboard UI built (`leaderboard.html` + `leaderboard.js`), nav links (Game, Shop, Leaderboard, Logout) added to all logged-in pages (game.html, shop.html, create-hero.html, leaderboard.html) -- **Next step:** Phase 10.18 — (next) +- **Next step:** Phase 10.18 — Balance pass via NEW migration (scripts/sim-balance.js + tune monster stats/XP) - **Updated:** 2026-10-23 - **Was the last session cut off mid-task?** No @@ -33,6 +33,7 @@ - `GET /api/zones` documented in API.md but not implemented. - Mobile nav uses emoji icons (⚔️ 🏕️ 🎒) — verify they render acceptably on all platforms. - Characters start with 50g default (DB constraint) — tests must account for this baseline. +- Level-1 heroes of every class win 100% of Meadows fights (design target ≈80%) — needs balance tuning in step 10.18. ## 5. Decisions & deviations from the docs - D-004..D-007, D-014..D-021 in `docs/DECISIONS.md` @@ -94,7 +95,11 @@ - **10.17:** Hero names in the leaderboard are rendered dynamically by JS, so tests should check the JS code pattern (not static HTML) for profile link generation. ## 7. Next-step briefing -- **Next step: 10.18** — (pending) -- The leaderboard page is fully functional with tabs, pagination, and profile links. -- All logged-in pages now have consistent navigation (Game, Shop, Leaderboard, Logout). -- The link-checker test passes with no exceptions. +- **Next step: 10.18** — Balance pass via NEW migration +- Create `scripts/sim-balance.js`: seeded simulation (fixed rng seed), creates hero per class, auto-allocates points, sells loot, rests/uses potions, prints win rates and hunts-to-level metrics. +- Tune monster stats and XP via a NEW migration until all targets hold for all three classes: + - Level-1 vs Meadows: 70–90% wins. Level-1 vs Crags: ≤15% wins. + - Level-5 vs Forest: 50–75% wins. Level-10 vs Crags: 50–75% wins. + - Hunts L1→5: 40–70. L1→10: 150–300. + - No class >15pp above another in any zone. +- Add test asserting Meadows level-1 win rate within 70–90% with fixed seed. diff --git a/STATUS.md b/STATUS.md index f8bb0e7..14c987d 100644 --- a/STATUS.md +++ b/STATUS.md @@ -8,7 +8,7 @@ ## Current Focus - **Phase:** 10 -- **Step:** 10.18 — (next) +- **Step:** 10.18 — Balance pass via NEW migration - **Blocked?** No - **Last verified working command:** `npm test` — 284/284 passing (97 unit + 187 integration incl. 11 step-10.17 tests), 2026-10-23 step 10.17 @@ -180,9 +180,6 @@ - [x] **10.13** Starter kit (GAME_DESIGN §Items): `createCharacter` grants, in the same transaction, one class-appropriate common weapon (warrior Rusty Sword, mage Apprentice Staff, ranger Hunter's Shortbow) already equipped in the weapon slot, plus 2 Minor Healing Potions. *Acceptance:* tests per class: inventory has exactly the weapon (equipped) and 2 potions (one stack row, quantity 2); derived attack includes the weapon. *Verified:* 4 new integration tests (warrior/mage/ranger starter kit + duplicate-name rejection); `STARTER_WEAPONS` map in `characterService.js`; `grantKit` transaction inserts equipped weapon + 2 potions; `grantItem` helpers in inventory/shop tests updated to stack with existing rows; 10+ existing tests updated to account for starter kit baseline; 253/253 tests pass. -- [x] **10.17** Build `public/leaderboard.html` + `public/js/leaderboard.js`: tabs Level/Gold/Kills, rank, hero name (link to profile.html?name=...), class, value; `textContent` only. Add nav links (Game, Shop, Leaderboard, Logout) to header of every logged-in page. Remove temporary link-checker exception from 10.5. - *Acceptance:* leaderboard page loads, tabs switch, entries render with profile links; nav links on game.html, shop.html, create-hero.html, leaderboard.html; link-checker passes. - *Verified:* 11 integration tests (4 nav-link checks, 3 page-structure, 1 code-quality, 3 API integration); `leaderboard.html` with tabs/table/pagination; `leaderboard.js` uses createElement + textContent only, no innerHTML; nav-links CSS added to main.css; nav links added to game.html, shop.html, create-hero.html, leaderboard.html; 284/284 tests pass. ### E. Economy - [x] **10.14** Fix material sell prices. The code uses `defaultRate * heroLevel / itemMinLevel`; BALANCE.md says price depends on the ITEM's level: common `2 × min_level`, uncommon `4 × min_level`, rare `8 × min_level` (epic `16×`, legendary `32×`; log this extension in DECISIONS.md), minimum 1. Note BALANCE.md's table says Drake Scale sells for 90g but its formula gives 112g: follow the formula and correct the table. Use ONE function (`materialSellPrice` in `src/game/rewards.js`) for the shop list AND for selling. *Acceptance:* tests: Rat Tail sells for 2g at hero level 1, 10 and 50; Drake Scale (rare, level 14) sells for 112g at any hero level; shop-listed price equals the amount actually paid. @@ -195,8 +192,9 @@ *Acceptance:* anonymous request → 200; response contains no user id/username/password; SQL injection in `type` → 400; `page=-1` and `page=abc` → 400. *Verified:* `requireAuth` removed from leaderboard route in `src/app.js`; hero profile was already public; 9 new integration tests (3 leaderboard anonymous access, 1 no-private-fields, 3 validation: SQL injection/page=-1/page=abc, 2 hero profile anonymous access); updated existing leaderboard test "rejects request without authentication" → "is accessible without authentication" (expects 200); 273/273 tests pass. *Acceptance:* tests: anonymous request → 200; response contains no user id / username / password fields; `type=gold;DROP TABLE users` → 400; `page=-1` and `page=abc` → 400. -- [ ] **10.17** Build `public/leaderboard.html` + `public/js/leaderboard.js`: tabs Level / Gold / Kills, rank, hero name (linking to `profile.html?name=...`), class, value; `textContent` only. Add nav links (Game, Shop, Leaderboard, Logout) to the header of every logged-in page. Remove any temporary link-checker exception from 10.5. +- [x] **10.17** Build `public/leaderboard.html` + `public/js/leaderboard.js`: tabs Level / Gold / Kills, rank, hero name (linking to `profile.html?name=...`), class, value; `textContent` only. Add nav links (Game, Shop, Leaderboard, Logout) to the header of every logged-in page. Remove any temporary link-checker exception from 10.5. *Acceptance:* link-checker test passes with no exceptions; the leaderboard page works logged-out and logged-in. + *Verified:* 11 integration tests (4 nav-link checks, 3 page-structure, 1 code-quality, 3 API integration); `leaderboard.html` with tabs/table/pagination; `leaderboard.js` uses createElement + textContent only, no innerHTML; nav-links CSS added to main.css; nav links added to game.html, shop.html, create-hero.html, leaderboard.html; no link-checker exceptions remain; 284/284 tests pass. ### G. Balance - [ ] **10.18** Balance pass via a NEW migration (never edit `003_content.sql`). First add `scripts/sim-balance.js`: a seeded simulation (fixed rng seed) that creates a hero per class, auto-allocates points to the class's primary stat, sells loot and rests/uses potions sensibly, and prints (a) win rate per zone at levels 1, 5, 10, (b) hunts to reach level 5 and level 10. Then tune monster stats and XP via the migration until all targets hold for all three classes: - Level-1 hero vs Meadows: **70–90%** wins. Level-1 hero vs Crags: **≤ 15%** wins. @@ -242,11 +240,12 @@ Severity: `blocker` / `major` / `minor` / `cosmetic`. Status: `open` / `fixing` ## Test Summary | Suite | Passing | Failing | Last run | |---|---|---|---| -| unit | 97 | 0 | 2026-10-23 step 10.16 | -| integration | 176 | 0 | 2026-10-23 step 10.16 (9 public leaderboard/profile tests) | +| unit | 97 | 0 | 2026-10-23 step 10.17 | +| integration | 187 | 0 | 2026-10-23 step 10.17 (11 leaderboard tests) | ## Session Log _Format:_ `YYYY-MM-DD | step | what changed | result` +- 2026-10-23 | 10.17 | Ticked step 10.17 (was already implemented in prior run): removed duplicate B-section 10.17 entry, ticked F-section 10.17 with full verification notes; leaderboard.html+leaderboard.js exist, nav links on all logged-in pages, no link-checker exceptions; 284/284 tests pass - 2026-10-23 | 10.16 | Removed `requireAuth` from `GET /api/leaderboard` in `src/app.js` (now public); hero profile was already public; updated existing "rejects request without authentication" → "is accessible without authentication" in leaderboard.test.js; 9 new integration tests (anonymous access, no-private-fields, validation: SQL injection/page=-1/page=abc, hero profile anonymous) | 273/273 tests pass - 2026-10-23 | 10.14 | Material sell prices now use item-level formula: `materialSellPrice(rarity, itemMinLevel)` in `shopService.js` replaces old `defaultRate * heroLevel / itemMinLevel`; BALANCE.md table corrected (Drake Scale 90g→112g, Wolf Pelt 5g→4g, Spider Silk 12g→20g, Imp Horn 30g→40g); fix for sell exhausting row (CHECK constraint `quantity >= 1` prevented decrement to 0 — now deletes row when sale qty equals row qty); 7 new integration tests; existing shop tests updated to item-level prices | 260/260 tests pass - 2026-10-23 | 10.8 | Added `POST /api/character/allocate` endpoint: zod `.strictObject` with optional stat fields + `.refine` requiring at least one; service in `characterService.js` validates input, uses `allocatePoints` from `leveling.js`, computes `remainingPoints = character.unspent_points - total`, updates in transaction; 12 new integration tests (6 HTTP + 6 direct service) | 214/214 tests pass