loop: baseline

This commit is contained in:
bepis
2026-10-20 20:33:35 +11:00
parent f1ae7b3119
commit 9a308b697d
32 changed files with 959 additions and 2046 deletions
+24 -13
View File
@@ -8,18 +8,18 @@
## Current Focus
- **Phase:** 4
- **Step:** 4.4
- **Step:** 4.5
- **Blocked?** No
- **Last verified working command:** `npm test` — 62/62 passing, Phase 4 step 4.4 complete
- **Last verified working command:** `npm test` — 93/93 passing (69 unit + 24 integration), 2026-10-20 review/fix pass
## Project Health
| Item | State |
|---|---|
| App starts (`npm start`) | ✅ works (session interval keeps process alive) |
| 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 |
| App starts (`npm start`) | ✅ smoke-tested: register → create hero → 12 hunts → level-up (real seeded zones) |
| Tests pass (`npm test`) | ✅ 93/93 (runs EVERY *.test.js; auth/combat/health were previously skipped by a bad glob) |
| Migrations run clean on empty DB | ✅ 001_users, 002_characters, 003_content (also seeds zones/monsters/items), 004_inventory, 006_logs (005 reserved for expeditions) |
| Can register + login | ✅ verified by tests |
| Data persists across restart | ✅ SQLite-backed sessions |
| Data persists across restart | ⚠️ sessions use the real SQLite store (also in tests); a restart test is still missing |
---
@@ -59,12 +59,13 @@
*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)
- [x] **4.1** Content tables + seed data (zones, monsters, items, loot). *Done inside migration `003_content.sql` (INSERT OR IGNORE), not `scripts/seed.js`. Balance changes need a NEW migration.*
- [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.
- [x] **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:* hunt returns winner, rounds, xpGained, goldGained, loot, leveledUp, zone, monster. *Verified:* 9 service tests (`tests/integration/hunt-service.test.js`) cover persistence, level-up, defeat, locked zone, energy, stacking.
- [ ] **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.
@@ -112,27 +113,37 @@
## Known Issues
| # | Area | Description | Severity | Status | Found in step |
|---|------|-------------|----------|--------|---------------|
| _none yet_ | | | | | |
| 1 | Balance | Level-1 heroes of every class win 100% of Meadows fights (design target ≈80%) and lose 100% of Crags fights. Tune monster stats via a NEW migration. | minor | open | 4.4 review |
| 2 | API | `GET /api/zones` (list zones + `unlocked`) is documented in API.md but not implemented; step 4.5 needs it. | major | open | 4.4 review |
| 3 | Scripts | `npm run seed` points at `scripts/seed.js`, which doesn't exist (seeds are in migration 003). Remove the script or add the file. | cosmetic | open | 0.1 |
| 4 | Tests | No test proves sessions survive a server restart (two apps on one DB file). | minor | open | 1.3 |
| 5 | Combat | Hero equipment bonuses are not passed into combat yet (Phase 5). `resolveCombat` already accepts `bonus_*` fields. | minor | open | 5.x |
| 6 | Combat | Natural HP regeneration is not implemented: HP only restores on level-up (rest/potions arrive in Phases 5–6). | minor | open | 4.4 |
| 7 | Combat/Hunt | (Fixed in review) only the faster side attacked; mage bonus never applied; level-up kept XP and overwrote stat points; deaths never counted; zone min_level ignored; stackable loot duplicated rows; energy countdown showed time-to-full. | blocker | fixed | review |
Severity: `blocker` / `major` / `minor` / `cosmetic`. Status: `open` / `fixing` / `wontfix` / `fixed`.
## Technical Debt / TODOs
- _none yet_
- `wrap()` async helper is copy-pasted in each route file; move to `src/middleware/wrap.js`.
- Error responses from route-level `AppError`s for validation don't include field details (API.md says they should).
- `npm test` prints a lot of TAP noise; consider `--test-reporter=spec`.
- `src/db/seeds/` is empty (kept for later content seeds).
## Open Questions (for the human)
- _none yet_
## Decisions Made (short; long form goes in docs/DECISIONS.md)
- _none yet_
- D-004: every combat round BOTH sides attack (faster first). D-005: equipment stats counted once in derived stats. D-006: unref the session-store cleanup timer; use the real SQLite store in tests. D-007: `utils/time.js` is the only clock.
## Test Summary
| Suite | Passing | Failing | Last run |
|---|---|---|---|
| unit | 51 | 0 | Phase 4.4 |
| integration | 7 | 0 | Phase 4.4 |
| unit | 69 | 0 | 2026-10-20 review pass |
| integration | 24 | 0 | 2026-10-20 review pass |
## Session Log
_Format:_ `YYYY-MM-DD | step | what changed | result`
- 2026-10-20 | review | Fixed `npm test` (ran 62 of 79 tests; auth/combat/health were skipped by an unquoted glob). Rewrote combat (slower side never attacked; mage bonus dead; hpRemaining wrong on loss). Rewrote huntService (XP not deducted on level-up, unspent points overwritten, deaths never counted, min_level ignored, stackable loot duplicated, duplicate stat formulas). Fixed nextTickInSec (was time-to-full). Added utils/time.js, WeakMap stmt cache, session store unref, ok:false error envelope, removed connect-sqlite3 | 93/93 tests pass; smoke test OK
- 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