diff --git a/Docs/Vault/02_Game_Design/Combat_Attack_Feel_Guidelines.md b/Docs/Vault/02_Game_Design/Combat_Attack_Feel_Guidelines.md index 7fc95eabf..8ca53a22c 100644 --- a/Docs/Vault/02_Game_Design/Combat_Attack_Feel_Guidelines.md +++ b/Docs/Vault/02_Game_Design/Combat_Attack_Feel_Guidelines.md @@ -213,13 +213,15 @@ anticipation floors per G1; one **signature silhouette pose** per kind's windup | # | Fork | Recommendation | Status | |---|---|---|---| -| 1 | **Damage at contact tick** (G2.1) — light melee gains ~0.2 s real windup | DO — it's the honest heavy-weapon model; feel-test behind a knob | ☐ operator | -| 2 | **Reach retune** (G2.2) — `MeleeRange` 2.6→2.2, finisher reach ×1.5→×1.25 | DO with #1 as one package | ☐ operator | -| 3 | **Weapon scale ×1.25 + tip trail** (G2.3) | DO — cheapest honesty win | ☐ operator | -| 4 | Victim-vibrate + finisher hold ladder (G5) | DO — pure presentation | ☐ operator | -| 5 | Input buffer 6–10t (G7) — a small predicted-sim change | DO after #1 lands (same system) | ☐ operator | -| 6 | Class cancel policies (G7) — Bathynaut commit / Harpooner crisp | Ratify as design law | ☐ operator | +| 1 | **Damage at contact tick** (G2.1) — light melee gains ~0.2 s real windup | DO — it's the honest heavy-weapon model; feel-test behind a knob | ✅ SHIPPED 07-20 (`MeleeCleavePending` schedule-and-consume; knob `MeleeContactTicks`, 0 = legacy) | +| 2 | **Reach retune** (G2.2) — `MeleeRange` 2.6→2.2, finisher reach ×1.5→×1.25 | DO with #1 as one package | ✅ SHIPPED 07-20 (`MeleeFinisherRangeMult` knob 30) | +| 3 | **Weapon scale ×1.25 + tip trail** (G2.3) | DO — cheapest honesty win | ✅ SHIPPED 07-20 (axe ×1.25; blade-smear ribbon; arc reveal ends AT contact) | +| 4 | Victim-vibrate + finisher hold ladder (G5) | DO — pure presentation | ✅ hold ladder SHIPPED (`FinisherHoldFrames`); **vibrate CUT** — Rukhanka folds the render child's inverse transform into skinning, an offset is a no-op (review C8); follow-up = additive anim layer | +| 5 | Input buffer 6–10t (G7) — a small predicted-sim change | DO after #1 lands (same system) | ✅ SHIPPED 07-20 (`BufferedAttackTick` GhostField; unlock-edge validity, batch-slack 4) | +| 6 | Class cancel policies (G7) — Bathynaut commit / Harpooner crisp | Ratify as design law | ✅ LAW + Bathynaut side SHIPPED (dash refused pre-contact); Harpooner side lands with the Harpooner | | 7 | Hades frame-count follow-up session (fill the research gap) | Optional, low priority | ☐ operator | +> Implementation record: [[2026-07-20_Melee_Feel_Forks_B]] (design review `wf_000bc247`: 19 confirmed findings folded in, 5 refuted). + *Checklist for any new attack/ability (the doc in one box):* declare G1 ticks → G2 volume==visual==timing → G3 color → G4 loudness tier → G5 impact tier → G6 cast grammar → G7 buffer/cancel policy → (enemy) G8 decal+pose. diff --git a/Docs/Vault/07_Sessions/2026/2026-07-20_Melee_Feel_Forks_B.md b/Docs/Vault/07_Sessions/2026/2026-07-20_Melee_Feel_Forks_B.md new file mode 100644 index 000000000..297b8fa01 --- /dev/null +++ b/Docs/Vault/07_Sessions/2026/2026-07-20_Melee_Feel_Forks_B.md @@ -0,0 +1,62 @@ +# 2026-07-20 (B) — Melee feel forks 1–6 implemented (guidelines G2/G5/G7) + +**Operator approved forks 1–6** of [[Combat_Attack_Feel_Guidelines]]. Feature-track netcode slice → ★ pre-code +adversarial review (`wf_000bc247`, 3 lenses + per-finding refutation critics: **19 confirmed / 5 refuted**), then +serial implementation of the review-hardened plan. + +## What shipped + +**Fork 1 — damage at the contact tick (G2.1).** The server cleave now resolves when the blade LANDS, not at the +swing press: `MeleeCleavePending` (server-only, baked zeroed on the player) is the AttackWindup schedule-and-consume +idiom — stamped `SwingStartTick + MeleeTiming.ContactTicks(step, knob)`, fired on a wrap-safe elapsed compare +(tick-batch-proof), consumed by zeroing, **flushed early if a chained swing would overwrite it** (review C0/C12: no +knob combination can lose a cleave). Payload builds from LIVE state at fire time (`BuildCleave`) — the cast-turn +steers the cone until contact. Per-step contacts: 16/10/20t (base knob `MeleeContactTicks` 16, **0 = legacy +immediate** — the sentinel the mechanics tests pin). +- Review kills incorporated: the original hashmap latch design (throws on first swing C2/C5; loses chained cleaves + C0/C3) was replaced wholesale by the entity-local idiom (C11). + +**Fork 2 — reach honesty (G2.2).** `MeleeRange` 2.6 → **2.2 m**; new `MeleeFinisherRangeMult` (**1.25**, knob 30) +scales finisher REACH only — `MeleeFinisherMult` (1.5) keeps damage/recover/knockback. Arcs (local + remote) use it. + +**Fork 3 — weapon + smear (G2.3).** Axe rebaked at **×1.25**; a **blade-smear ribbon** (thin elevated band riding +the arc's leading edge, `BuildSlashInto` angular-window mode — review C18: one shared builder) plus the ground arc +whose **sweep-reveal now completes AT the live contact tick** (life derives from the knob per step — review C13; +remote arcs too). + +**Fork 4 — impact ladder (G5), vibrate CUT.** `TryHold(frames)` parameterized (review C17: one hold path); +finisher-connect holds `FeelConfig.FinisherHoldFrames` (5). **Victim-vibrate was cut**: review C8 verified Rukhanka +folds the SMR render child's `LocalTransform` INVERSE into the skin matrices — offsetting it does nothing on +skinned enemies. Follow-up channel: an additive anim layer or bone-space offset. + +**Fork 5 — input buffer (G7).** `[GhostField] MeleeCombo.BufferedAttackTick` (predicted, rollback-restored — +review C9 verified sound): a press in the lock's last `MeleeBufferTicks` (8, knob 29, 0 = off) fires the chain at +unlock. **Validity anchors to the UNLOCK edge with `MeleeTiming.BatchSlackTicks` (4)** — press-anchored validity +drops edge presses under the server's default tick-batch of 4 (review C1). + +**Fork 6 — the Bathynaut commits (G7).** DashSystem refuses a dash start while a swing is PRE-contact +(`TickWindowMath.SwingActive` over the contact window — review C15 reuse); post-contact recovery dash-cancel stays. +Implemented as a **ComponentLookup, not a query add** — a query add would have silently emptied three existing +dash test suites (review C4). + +**Connect-cue honesty (review C14):** the client's melee connect package (bite burst/thunk/FOV kick/rumble/finisher +hold/arc brighten) moved from the swing edge to the **contact tick** (`EvaluateMeleeConnect`, aim recomputed live). + +## Validation + +- L1 console error-free. **L2: 414/414** (411 legacy through the pins + 3 new: contact-tick-exactly-once, + buffered-chain-at-unlock, dash-law pre/post-contact). +- **Live server proof** (guardian sampling, injected real attack): SwingStartTick 5968 → pending stamped **5984 + (= +16)** → enemy HP 200 → 164 **exactly at tick 5984**, pending consumed same tick, no refire; damage 36 = base + 30 × the Warrior melee seed (live stat folding at resolve ✔). Under observed tick-batching (~4/frame). +- L3 captures: ×1.25 axe reads; arc + smear track the sweep. Smear re-toned post-capture (thinner band 0.25 rad, + innerFrac 0.7, alpha 0.7) — reads as a streak, not a pane; operator eyes-on will fine-tune. + +## Wire/bake churn (accepted) + +`BufferedAttackTick` GhostField + 3 `DebugTuningReport` fields = ghost + RpcCollection hash change (dev peers +rebuild together, MPPM same-build); `MeleeCleavePending` baked on Player.prefab (non-replicated); knobs 29–31 +(Count 32); pinned-legacy contract in `MeleeComboTests` (contact 0 / buffer 0 / finRange 1.8). + +**Next:** operator eyes/ears-on — cadence (`MeleeContactTicks`/`MeleeRecoverTicks`/`MeleeBufferTicks` knobs), +smear look, finisher hold weight. DebugOverlay rows for the 3 new knobs = a 5-minute add on request.