Skip to content

feat(animation): two visual player states — normal & attack pose (FLO-474)#119

Closed
Fl0p wants to merge 1 commit into
mainfrom
flo-474-player-attack-pose
Closed

feat(animation): two visual player states — normal & attack pose (FLO-474)#119
Fl0p wants to merge 1 commit into
mainfrom
flo-474-player-attack-pose

Conversation

@Fl0p

@Fl0p Fl0p commented Jun 21, 2026

Copy link
Copy Markdown
Collaborator

What & why

FLO-468 (board): the player should look clearly different while attacking — ideally a raised-arms second model swapped in on the swing.

Codebase reality (verified, not as remembered): the player is now a single rig-less GLB (korovany_hero_player-default.glb, FLO-443 — src/scenes/survivorAvatar.ts), animated procedurally on the visual root. There is no raised-arms GLB in public/models, so a literal two-GLB swap isn't possible today. The repo's animation philosophy is explicitly transform-based, no rigs (docs/guide/procedural-animation.md).

So this delivers the requested two-state read the documented way: a committed full-body attack pose layered on the existing melee phase, giving two unmistakably-distinct silhouettes (normal idle/move ↔ attack strike).

Change

src/game/animation/proceduralAnimator.ts — attack pose by melee phase, driven on the visual root:

  • windup: wind back (−0.28 rad) + rise (+7 cm) — telegraph
  • active: sharp forward chop (+0.62 rad, well beyond the ≤0.12 rad movement lean) + weight drop (−5 cm) + existing +18 cm lunge
  • recovery: settles (+0.20 rad)

Pitch is added to the base lean and rise/dip to the bob, so the strike reads even while advancing. Applies to both the forest and human-lands scenes automatically (both feed attackPhase through CharacterController). Zero asset cost.

A literal raised-arms second model (pose-baked or rigged GLB) remains a future asset ticket through Iris → Pygmalion — it would drop in behind the same attackPhase contract.

Verification

  • npx vitest run proceduralAnimator.test.ts28 passed (7 new cases proving the two distinct states: idle-neutral, windup-back+rise, active-chop, opposite windup/active pitch, recovery-settle, chop-on-the-move, binding drives the node).
  • npm run lint ✅ · npm run build
  • docs/guide/procedural-animation.md updated (states table + rationale).

Notes for reviewers

  • Visual quality / silhouette read is best judged in-engine — flagging Iris for a UX look. Melee active window is short (~0.10 s), so the deterministic pose math + tests are the primary proof; no headless screenshot of the strike frame.

🤖 Generated with Claude Code

…O-474)

The board asked for a player who looks clearly different while attacking
(ideally a raised-arms second model). The shipped hero is a single rig-less
GLB and no raised-arms variant exists, so a literal two-GLB swap isn't
possible today. Instead the attack now reads as a committed full-body chop
driven on the visual root via the existing procedural animator: windup winds
back and rises, the active frame pitches sharply forward (+0.62 rad, well
beyond the <=0.12 rad movement lean) and drops the weight, recovery settles.

Result: two unmistakably-distinct silhouettes (normal idle/move <-> attack
strike) tied to the melee phase, at zero asset cost — applies to both the
forest and human-lands scenes since both feed attackPhase through the
controller. A literal raised-arms second model remains a future asset ticket.

- proceduralAnimator: attack pitch added to leanX, rise/dip to bobY, by phase
- 7 new Vitest cases proving the two distinct states
- docs/guide/procedural-animation.md: updated states table + rationale

Co-Authored-By: Wayland <wayland@agents.flopbut.local>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@Fl0p

Fl0p commented Jun 21, 2026

Copy link
Copy Markdown
Collaborator Author

Superseded by the CTO's Option B decision on FLO-474 — author a dedicated strike-pose GLB (korovany_hero_player-attack.glb, Pygmalion blocker 32fd708f) and swap by combat state, since the board wants two distinct models, not a one-model procedural pose.

Closing rather than merging so this doesn't land against that decision. Branch flo-474-player-attack-pose is preserved — the full-body chop commit (animator pitch by melee phase, +28 tests) composes cleanly with the model swap (raised-arms GLB + forward chop pitch reads even more dynamic), so it can be cherry-picked as a complement during the swap-wiring step if desired. Not reverting any landed code.

@Fl0p Fl0p closed this Jun 21, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant