step 10.11: done

This commit is contained in:
bepis
2026-10-23 02:33:16 +11:00
parent e124266c76
commit 08d880ab73
9 changed files with 451 additions and 20 deletions
+4 -3
View File
@@ -8,9 +8,9 @@
## Current Focus
- **Phase:** 10
- **Step:** 10.11 — Natural HP regeneration: +1% max HP/min, lazy computation, new migration adds hp_updated_at
- **Step:** 10.12 — Equipment must matter in combat: ONE getEquipmentBonuses function, integrate into huntService, getCharacterProfile, potion capping, shop/inventory previews
- **Blocked?** No
- **Last verified working command:** `npm test` — 227/227 passing (85 unit + 142 integration incl. 5 rest endpoint tests), 2026-10-23 step 10.10
- **Last verified working command:** `npm test` — 245/245 passing (97 unit + 148 integration incl. 12 hp unit + 6 hp regen integration), 2026-10-23 step 10.11
## Project Health
| Item | State |
@@ -171,8 +171,9 @@
- [x] **10.10** Add `POST /api/character/rest` (API.md, BALANCE.md §Rest): costs `level * 5` gold, heals to full max HP. Errors: `NOTHING_TO_HEAL` (422) if HP is already full, `INSUFFICIENT_GOLD` (422). One transaction. Add a "Rest (N gold)" button to the dashboard.
*Acceptance:* tests: HP 10/135 level 3 with gold 100 → HP 135, gold 85; full HP → 422 and gold unchanged; gold 5 → 422; HP unchanged on failure.
*Verified:* 5 integration tests (happy heal, full HP rejection, insufficient gold, cross-user isolation, level scaling); `rest()` in characterService.js with one transaction; `handleRest` in character routes; mounted in app.js; dashboard button in game.html/game.js with CSS styles; hidden when HP at max. 227/227 tests pass.
- [ ] **10.11** Natural HP regeneration (GAME_DESIGN §Time): +1% of max HP per minute, computed lazily like energy. New migration (next unused number) adds `hp_updated_at INTEGER` (backfill existing rows with `energy_updated_at`). Add a pure function `computeHp(current, maxHp, updatedAtMs, nowMs)` in `src/game/hp.js` with unit tests (partial minute, cap at max, clock backwards, large gap). Apply it before the HP check in hunting, in `getCharacterProfile`, in potion use, and in rest. Heals/damage must set `hp_updated_at = now`.
- [x] **10.11** Natural HP regeneration (GAME_DESIGN §Time): +1% of max HP per minute, computed lazily like energy. New migration (next unused number) adds `hp_updated_at INTEGER` (backfill existing rows with `energy_updated_at`). Add a pure function `computeHp(current, maxHp, updatedAtMs, nowMs)` in `src/game/hp.js` with unit tests (partial minute, cap at max, clock backwards, large gap). Apply it before the HP check in hunting, in `getCharacterProfile`, in potion use, and in rest. Heals/damage must set `hp_updated_at = now`.
*Acceptance:* unit tests for `computeHp`; integration test: hero at 1 HP, 30 minutes later hunting is allowed again (≥ 20% of max HP restored by lazy regen, using `time.setNow`). A defeated hero can no longer soft-lock.
*Verified:* 12 unit tests for `computeHp`; 6 integration tests (30-min regen ≥20%, fresh char hp_updated_at set, rest sets hp_updated_at, <1min no change, cap at maxHp, potion applies regen before heal); migration 007 adds column; computeHp integrated in huntService, characterService (getCharacterProfile + rest), inventoryService (potion use), expeditionService (claim). 245/245 tests pass.
- [ ] **10.12** Equipment must matter in combat. Create ONE `getEquipmentBonuses(characterId)` function (sum of `bonus_str/agi/int/vit/attack/defense` over equipped items) and use it in `huntService` (pass the totals to `resolveCombat` as `bonus_*`), in `getCharacterProfile` (derived stats), in potion max-HP capping, and in the shop/inventory stat previews. Delete the copy-pasted aggregation code in `shopService.js` and `inventoryService.js`.
*Acceptance:* deterministic tests with a constant rng: the first hero hit is exactly higher with an equipped weapon than without; `GET /api/character` `derived.attack` includes the weapon bonus; equipment `bonus_vit` raises max HP exactly once; grep shows only one aggregation implementation.
- [ ] **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.