Files
Emberfall/STATUS.md
T
bepis f1ae7b3119 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
2026-10-20 17:46:18 +11:00

153 lines
11 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# STATUS.md — Living Progress Tracker
> **Agent rules for this file**
> - Update it at the end of EVERY step. Do not skip.
> - Only tick a box when the step's **Acceptance** line is actually verified.
> - Add problems you could not fix to **Known Issues** instead of hiding them.
> - Keep Session Log entries to one or two lines.
## Current Focus
- **Phase:** 4
- **Step:** 4.4
- **Blocked?** No
- **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`) | ✅ 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 |
---
## Phase 0 — Scaffold
- [x] **0.1** `npm init`, install deps from NOTES.md §2, add scripts: `start`, `dev` (node --watch), `test`, `migrate`, `seed`.
*Acceptance:* `npm install` succeeds; scripts exist in package.json.
- [x] **0.2** `src/config/index.js` loads `.env` (use `process.loadEnvFile` or `dotenv`), validates required vars, exports a frozen config object.
*Acceptance:* missing SESSION_SECRET in production throws a clear error.
- [x] **0.3** `src/db/index.js` opens SQLite (WAL mode, foreign_keys ON) and exports the handle. `scripts/migrate.js` runs numbered `.sql` files from `src/db/migrations/` in order and records them in a `_migrations` table.
*Acceptance:* `npm run migrate` twice in a row is safe (second run does nothing).
- [x] **0.4** `src/app.js` (builds Express app, no listen) + `src/server.js` (listens). Add helmet, JSON body parser (limit 10kb), static `public/`, `GET /api/health` → `{ok:true}`, central error handler (see CODING_STANDARDS).
*Acceptance:* `curl localhost:3000/api/health` returns `{"ok":true}`.
- [x] **0.5** First test: health endpoint via `node:test` + `fetch` against `app` on an ephemeral port (see TESTING.md).
*Acceptance:* `npm test` passes.
## Phase 1 — Accounts & Sessions (docs: DATABASE, API, SECURITY)
- [x] **1.1** Migration `001_users.sql` (users table).
- [x] **1.2** `src/services/authService.js`: `register`, `verifyLogin`. bcryptjs cost 10–12. Case-insensitive unique username.
- [x] **1.3** Session middleware (httpOnly, sameSite=lax, secure in production, SQLite-backed store) + `requireAuth` middleware.
- [x] **1.4** Routes: `POST /api/auth/register`, `POST /api/auth/login`, `POST /api/auth/logout`, `GET /api/auth/me`. Zod validation. Rate limit login/register.
- [x] **1.5** Pages `public/login.html`, `public/register.html` + `public/js/auth.js`.
- [x] **1.6** Tests: register ok, duplicate username, bad password, login ok/fail, `me` requires session, logout clears session.
*Acceptance (phase):* can register, log in, refresh page and stay logged in, restart server and stay logged in, log out.
## Phase 2 — Hero Creation & Profile (docs: GAME_DESIGN §Classes, DATABASE, BALANCE)
- [x] **2.1** Migration `002_characters.sql`.
- [x] **2.2** `src/game/classes.js` (class base stats) + `src/game/stats.js` (derived stats). Unit tests.
- [x] **2.3** `POST /api/character` (create; one per user), `GET /api/character` (full profile incl. derived stats and current energy).
- [x] **2.4** `public/create-hero.html`, `public/game.html` (dashboard shell with stats panel).
*Acceptance:* new user is redirected to create-hero; after creation, dashboard shows stats.
## 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.
- [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)
- [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.
## Phase 5 — Inventory & Equipment (docs: GAME_DESIGN §Items, DATABASE)
- [ ] **5.1** Migration `004_inventory.sql`.
- [ ] **5.2** Services + routes: list inventory, equip, unequip (slots: weapon, armor, trinket). Equipment modifies derived stats.
- [ ] **5.3** Stackable consumables: `POST /api/inventory/use` (health potion heals; energy tonic restores energy, capped).
- [ ] **5.4** UI: inventory grid, equipment panel, tooltips with stats.
## Phase 6 — Shop & Economy (docs: GAME_DESIGN §Economy)
- [ ] **6.1** `GET /api/shop`, `POST /api/shop/buy`, `POST /api/shop/sell`. Sell value = 40% of base price. Gold can never go negative.
- [ ] **6.2** Level-gated shop stock. UI page.
- [ ] **6.3** Tests: buy with insufficient gold, sell equipped item (must be rejected), concurrent double-buy safety (transaction).
## Phase 7 — Expeditions (Offline Progress) (docs: GAME_DESIGN §Time, §Expeditions)
- [ ] **7.1** Migration `005_expeditions.sql`. Expedition definitions in seed data.
- [ ] **7.2** `POST /api/expeditions/start`, `GET /api/expeditions/active`, `POST /api/expeditions/claim`. Only one active expedition per hero. Claim rejected before `ends_at`.
- [ ] **7.3** UI: start panel, progress bar, claim button.
*Acceptance:* start → close browser → return after duration → claim → rewards granted exactly once.
## Phase 8 — Leaderboards & Social-lite (docs: GAME_DESIGN §Leaderboards)
- [ ] **8.1** `GET /api/leaderboard?type=level|gold|kills` top 50, with pagination param.
- [ ] **8.2** Public profile `GET /api/heroes/:name` (no private data).
- [ ] **8.3** UI page.
## Phase 9 — Hardening & Polish (docs: SECURITY, UI_GUIDE, TESTING)
- [ ] **9.1** Walk the SECURITY.md checklist; fix gaps.
- [ ] **9.2** Add `npm run seed:dev` creating a demo account and hero.
- [ ] **9.3** Global error pages / friendly UI error toasts. Loading states.
- [ ] **9.4** Mobile-responsive pass (see UI_GUIDE).
- [ ] **9.5** Final full run of "Definition of playable" from NOTES.md §7. Record results below.
- [ ] **9.6** Update README with real run instructions.
## Stretch Goals (only after Phase 9)
- [ ] S1 Async PvP duels (attack another hero's *snapshot*; cooldown; rating).
- [ ] S2 Skills / talent points spent on level-up.
- [ ] S3 Guilds (create, join, leave, guild board).
- [ ] S4 Player market (list/buy items between players, 5% tax gold sink).
- [ ] S5 Daily login reward + daily quests.
- [ ] S6 In-game chat via polling (no websockets).
- [ ] S7 Achievements.
---
## Known Issues
| # | Area | Description | Severity | Status | Found in step |
|---|------|-------------|----------|--------|---------------|
| _none yet_ | | | | | |
Severity: `blocker` / `major` / `minor` / `cosmetic`. Status: `open` / `fixing` / `wontfix` / `fixed`.
## Technical Debt / TODOs
- _none yet_
## Open Questions (for the human)
- _none yet_
## Decisions Made (short; long form goes in docs/DECISIONS.md)
- _none yet_
## Test Summary
| Suite | Passing | Failing | Last run |
|---|---|---|---|
| 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
- 2026-10-20 | 0.4 | Created `src/utils/errors.js`, `src/app.js` (helmet, JSON parser, static, health, error handler) + `src/server.js` | `curl localhost:3000/api/health` → `{"ok":true}`
- 2026-10-20 | 0.5 | Created `tests/health.test.js` — boots app on ephemeral port, hits /api/health | `npm test` passes (1/1)
- 2026-10-20 | 1.1 | Created `src/db/migrations/001_users.sql` | migration applies clean
- 2026-10-20 | 1.2 | Created `src/services/authService.js`: register + verifyLogin with bcrypt cost 12, timing-safe | service loads
- 2026-10-20 | 1.3 | Created `src/middleware/session.js`: better-sqlite3-session-store, requireAuth | middleware loads
- 2026-10-20 | 1.4 | Created `src/routes/auth.js` with Zod validation, rate limiting; integrated into app.js | app loads
- 2026-10-20 | 1.5 | Created `public/login.html`, `public/register.html`, `public/css/main.css`, `public/js/auth.js`, `login.js`, `register.js` | static files served
- 2026-10-20 | 1.6 | Created `tests/helpers.js` + `tests/auth.test.js` (6 tests) | 6/6 auth tests pass
- 2026-10-20 | 2.1 | Created `src/db/migrations/002_characters.sql` | migration applies clean
- 2026-10-20 | 2.2 | Created `src/game/classes.js`, `src/game/stats.js` + unit tests (23 tests) | 23/23 pass
- 2026-10-20 | 2.3 | Created `src/services/characterService.js`, `src/routes/character.js`; integrated into app.js | app loads
- 2026-10-20 | 2.4 | Created `public/create-hero.html`, `public/game.html`, `public/js/create-hero.js`, `public/js/game.js` | app loads