NEO-95: fix Bruno elite attack — multi-poll snapshot timeline

AdvanceAll runs only on npc-runtime-snapshot GET with a 5s delta cap;
sleep then combat-health alone never applied telegraph damage.
pull/133/head
VinPropane 2026-05-28 23:49:59 -04:00
parent fb70777453
commit c96fb2d26a
3 changed files with 11 additions and 6 deletions

View File

@ -5,8 +5,9 @@ meta {
} }
docs { docs {
E5M2-09 AC smoke: lock prototype_npc_elite, damaging cast, wait attackCooldownSeconds (5.0s) + telegraphWindupSeconds (2.5s), GET combat-health. E5M2-09 AC smoke: lock prototype_npc_elite, damaging cast, poll npc-runtime-snapshot through
Integration tests own precise timing via FakeClock; Bruno uses sleep(8000) against dev server real clock. attackCooldownSeconds (5.0s) + telegraphWindupSeconds (2.5s), then GET combat-health.
Lazy AdvanceAll caps at 5.0s per poll — need two snapshot GETs after cast (same as FakeClock integration test).
} }
script:pre-request { script:pre-request {
@ -61,7 +62,11 @@ script:pre-request {
await axios.get(`${baseUrl}/game/world/npc-runtime-snapshot`); await axios.get(`${baseUrl}/game/world/npc-runtime-snapshot`);
await sleep(8000); await sleep(5000);
await axios.get(`${baseUrl}/game/world/npc-runtime-snapshot`);
await sleep(2500);
await axios.get(`${baseUrl}/game/world/npc-runtime-snapshot`);
bru.setVar("neo95CastBody", JSON.stringify(castBody)); bru.setVar("neo95CastBody", JSON.stringify(castBody));
} }

View File

@ -5,5 +5,5 @@ meta {
docs { docs {
NEO-95: GET /game/players/{id}/combat-health — session player combat HP after NPC telegraph resolve. NEO-95: GET /game/players/{id}/combat-health — session player combat HP after NPC telegraph resolve.
Pre-request scripts call POST /game/__dev/combat-targets-fixture so CI survives ability-cast folder pollution. Pre-request scripts call POST /game/__dev/combat-targets-fixture so CI survives ability-cast folder pollution.
Elite attack smoke (seq 2) uses sleep(8000) against real dev server clock; integration tests use FakeClock. Elite attack smoke (seq 2) polls npc-runtime-snapshot twice (5s + 2.5s waits) before combat-health GET — AdvanceAll delta cap 5.0s requires multi-poll timeline like integration tests.
} }

View File

@ -115,7 +115,7 @@ t=7.5 GET npc-runtime-snapshot (AdvanceAll) → windup complete, damage applied,
1. Reset fixture (**`combat-targets-reset-helper.js`**). 1. Reset fixture (**`combat-targets-reset-helper.js`**).
2. Bind slot 0 **`prototype_pulse`**, lock **`prototype_npc_elite`**, damaging cast. 2. Bind slot 0 **`prototype_pulse`**, lock **`prototype_npc_elite`**, damaging cast.
3. Poll **`GET /game/world/npc-runtime-snapshot`** until elite past windup (real-time wait or sleep ≥ **7.5 s** against dev server). 3. Poll **`GET /game/world/npc-runtime-snapshot`** after cast, wait **≥ 5.0 s**, poll again, wait **≥ 2.5 s**, poll again (lazy **`AdvanceAll`** delta cap **5.0 s** — single sleep is insufficient for elite **7.5 s** cycle).
4. **`GET /game/players/dev-local-1/combat-health`** — assert **`currentHp === 75`**. 4. **`GET /game/players/dev-local-1/combat-health`** — assert **`currentHp === 75`**.
## Files to add ## Files to add
@ -173,4 +173,4 @@ No `docs/manual-qa/NEO-95.md`. No Godot tests.
| **Multiple NPCs same holder** | Each telegraph completion applies its own **`attackDamage`** independently — deterministic, no cap in prototype. | **adopted** | | **Multiple NPCs same holder** | Each telegraph completion applies its own **`attackDamage`** independently — deterministic, no cap in prototype. | **adopted** |
| **`AdvanceAll` signature change** | Add **`IPlayerCombatHealthStore?`** or required param; update snapshot GET + all tests. | **adopted** | | **`AdvanceAll` signature change** | Add **`IPlayerCombatHealthStore?`** or required param; update snapshot GET + all tests. | **adopted** |
| **`player_death` telemetry** | Comment-only hook at HP **0**; full event wiring deferred to E9.M1 / future player death story. | **adopted** | | **`player_death` telemetry** | Comment-only hook at HP **0**; full event wiring deferred to E9.M1 / future player death story. | **adopted** |
| **Bruno real-time wait** | Integration tests own timing precision; Bruno may use **`sleep(8000)`** against dev server — document in `.bru` docs block (NEO-94 pattern). | **adopted** | | **Bruno real-time wait** | Integration tests own timing precision; Bruno must **multi-poll** **`npc-runtime-snapshot`** (5s + 2.5s waits) before combat-health GET — **`AdvanceAll`** delta cap prevents single-sleep timeline. | **adopted** |