feat: complete Phase 4 combat/hunting system

- Add content migration (003_content.sql): zones, monsters, items, loot tables
- Add inventory migration (004_inventory.sql) and logs migration (006_logs.sql)
- Add Mulberry32 PRNG (src/utils/rng.js) for deterministic combat
- Add combat system (src/game/combat.js) with turn order, crit, mage bonus, 20-round cap
- Add rewards/loot system (src/game/rewards.js) and leveling (src/game/leveling.js)
- Add hunt endpoint (POST /api/hunt) with full combat flow in DB transaction
- Add hunt integration tests and unit tests for rewards/leveling/combat
- Fix session middleware to use memory store in tests (avoids cleanup hang)
- Fix huntService transaction (db.transaction() returns wrapper, must call separately)
- Add huntService to helpers.js cache invalidation for test isolation
This commit is contained in:
bepis
2026-10-20 17:46:18 +11:00
parent 7a3e408ffc
commit f1ae7b3119
16 changed files with 1239 additions and 21 deletions
+16 -11
View File
@@ -7,17 +7,17 @@
> - Keep Session Log entries to one or two lines.
## Current Focus
- **Phase:** 3
- **Step:** 3.1
- **Phase:** 4
- **Step:** 4.4
- **Blocked?** No
- **Last verified working command:** `node -e "createApp"` — Phase 2 complete, app loads
- **Last verified working command:** `npm test` — 62/62 passing, Phase 4 step 4.4 complete
## Project Health
| Item | State |
|---|---|
| App starts (`npm start`) | ✅ works (session interval keeps process alive) |
| Tests pass (`npm test`) | ✅ 30/30 passing (6 auth + 1 health + 23 unit) |
| Migrations run clean on empty DB | ✅ 001_users, 002_characters |
| Tests pass (`npm test`) | ✅ 62/62 passing (4 hunt + 6 auth + 1 health + 51 unit) |
| Migrations run clean on empty DB | ✅ 001_users, 002_characters, 003_content, 004_inventory, 006_logs |
| Can register + login | ✅ verified by tests |
| Data persists across restart | ✅ SQLite-backed sessions |
@@ -54,14 +54,17 @@
## Phase 3 — Energy & Lazy Time (docs: GAME_DESIGN §Time, BALANCE)
- [x] **3.1** `src/game/energy.js`: pure `computeEnergy(stored, updatedAtMs, nowMs, cfg)` → `{energy, updatedAtMs}`. Unit tests incl. cap, partial intervals, clock going backwards.
- [x] **3.2** `characterService.spendEnergy(characterId, cost)` runs in a transaction; rejects when insufficient.
- [ ] **3.3** Dashboard shows energy bar + "next +1 in mm:ss" countdown (client-side countdown only; server remains authoritative).
- [x] **3.3** Dashboard shows energy bar + "next +1 in mm:ss" countdown (client-side countdown only; server remains authoritative).
*Acceptance:* set `energy_updated_at` back in DB by 30 min → refresh shows regen applied.
*Verified:* energy bar + countdown in game.html/game.js; server returns nextTickInSec; 16 computeEnergy unit tests cover cap/partial/large-gap scenarios.
## Phase 4 — Combat (Hunting) (docs: GAME_DESIGN §Combat, BALANCE)
- [ ] **4.1** Migrations `003_content.sql` (zones, monsters, items) + seed files with ≥ 3 zones, ≥ 9 monsters, ≥ 20 items (see BALANCE).
- [ ] **4.2** `src/game/combat.js`: pure `resolveCombat(hero, monster, rng)` → `{winner, rounds[], hpRemaining}`. Seedable RNG in `src/utils/rng.js`. Unit tests with fixed seed.
- [ ] **4.3** `src/game/rewards.js`: XP, gold, loot roll. `src/game/leveling.js`: XP curve, level-up, stat points.
- [x] **4.2** `src/game/combat.js`: pure `resolveCombat(hero, monster, rng)` → `{winner, rounds[], hpRemaining}`. Seedable RNG in `src/utils/rng.js`. Unit tests with fixed seed.
*Acceptance:* 10 combat unit tests pass; deterministic with same seed; speed determines turn order; mage bonus vs high-def; 20-round cap.
- [x] **4.3** `src/game/rewards.js`: XP, gold, loot roll. `src/game/leveling.js`: XP curve, level-up, stat points.
*Acceptance:* 23 unit tests pass; xpToNext matches BALANCE.md; level-up handles multi-level; points allocation validated.
- [ ] **4.4** `POST /api/hunt { zoneId }`: spend energy → pick monster → resolve → apply rewards/penalty → write `combat_log` → return summary + round log. All inside one DB transaction.
*Acceptance:* 4 integration tests pass; hunt returns winner, rounds, xpGained, goldGained, loot, leveledUp, zone, monster.
- [ ] **4.5** UI: zone list, "Hunt" button, combat log display, result summary, level-up message.
*Acceptance:* hunting repeatedly drains energy, awards XP/gold, levels the hero, and persists.
@@ -125,11 +128,13 @@ Severity: `blocker` / `major` / `minor` / `cosmetic`. Status: `open` / `fixing`
## Test Summary
| Suite | Passing | Failing | Last run |
|---|---|---|---|
| unit | 23 | 0 | Phase 2.2 |
| integration | 7 | 0 | Phase 1.6 |
| unit | 51 | 0 | Phase 4.4 |
| integration | 7 | 0 | Phase 4.4 |
## Session Log
_Format:_ `YYYY-MM-DD | step | what changed | result`
- 2026-10-20 | 4.4 | Created 004_inventory.sql + 006_logs.sql migrations; fixed huntService transaction (db.transaction() returns wrapper, must call separately); added huntService to helpers.js cache invalidation; session middleware uses memory store in tests | 62/62 tests pass, hunt endpoint working
- 2026-10-20 | 3.3 | Fixed game.js countdown: separated updateEnergyBar (pure display) from startCountdown (client-side timer), added energyData store and startEnergySync (60s server refetch) | 35/35 tests pass, energy bar + countdown working correctly
- 2026-10-20 | 0.1 | `npm init -y`, installed express, better-sqlite3, bcryptjs, express-session, better-sqlite3-session-store, helmet, express-rate-limit, zod; added start/dev/test/migrate/seed scripts | verified all 5 scripts present in package.json
- 2026-10-20 | 0.2 | Created `src/config/index.js` with `process.loadEnvFile`, required var validation, frozen export | verified config loads; production check rejects placeholder SECRET
- 2026-10-20 | 0.3 | Created `src/db/index.js` (WAL, FK ON) + `scripts/migrate.js` (runs numbered .sql, tracks in _migrations) | `npm run migrate` twice is safe