Commit Graph

7 Commits

Author SHA1 Message Date
kronic eeaf8a4247 Pronounced combat animation: 3-swing sword combo, per-class specials, sword in hand
BLENDER (5 new/re-authored clips, all full-body, mirrored-left-arm axes
FIXED - Synty L shoulders mirror X/twist vs R, verified by axis probes):
- A_Swing_R2L / A_Swing_L2R (0.47s): horizontal slash + backhand with real
  anticipation (torso wound 25 deg), 2-frame strikes, follow-through past
  the target.
- A_Swing_Finisher (0.60s): overhead crash with a crouch drop into impact.
- A_Special_Slam (0.53s): two-handed ground slam - the Warrior cone finally
  LOOKS like a cone attack.
- A_Fire_OneHand re-authored punchier (cock -> full-extension thrust with
  torso commit -> recoil kick).
Export lesson: Blender 4.4 slotted actions - reassigning animation_data.
action does NOT bind the slot; force animation_data.action_slot before
export/render or you bake a stale pose.

CONTROLLER: MeleeSwing (one clip for everything) replaced by Swing1/2/3
keyed on new ComboStep int param (replicated MeleeCombo.Step); Fire gated
!IsCone (Ranger shot), new SpecialSlam state on IsFiring+IsCone (Warrior).

DRIVE SYSTEM: writes ComboStep from the replicated combo step and IsCone
from the replicated AbilityRef -> AbilityDatabase blob archetype (works for
remote teammates too).

SWORD: SM_Wep_Sword_01 (SciFiSpace - same pack/atlas as the soldier) as a
mesh-sub-asset child of Hand_R, grip rot (90,0,0) tuned live against the
running entity. Required RigDefinitionAuthoring boneEntityStrippingMode
Automatic -> None so the hand bone entity exists + is posed (stripped bones
never animate attachments). Play-verified: the energy blade rides the fist.

456/456 EditMode.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-06 21:18:07 -07:00
kronic b7db292987 Blender-authored clips: real death fall, fire thrust, dash lean, hit-react (Phase 1 anim triage)
Four clips authored programmatically in Blender on the PolygonSyntyCharacter
skeleton (full-body keys per pose, numeric world-space verification of the
fall: hips 0.88->0.14m) and exported per-action FBX (Key All Bones, Force
Start/End Keying, FBX Units Scale). Imported as HUMANOID - the project's
pipeline is Human rigs (CharactersAvatar isHuman=true; CLAUDE.md's 'Generic'
note was stale), so muscle-space retargeting plays these on the player AND
every monster rig with zero bone-path matching. CopyFromOther failed on the
Blender-added 'Armature' node (hierarchy mismatch) -> CreateFromThisModel;
root motion fully baked into pose (the CC owns the transform).

- A_Death_FallBack (0.90s = exactly the 54-tick corpse window): recoil ->
  fall -> flat on the back -> settle. Wired as the Death state on BOTH
  controllers, replacing the crouch-idle placeholder.
- A_Fire_OneHand (0.4s): new IsFiring param + Fire state on the player
  controller; PlayerAnimationDriveSystem routes FireActive to it (melee owns
  IsAttacking again).
- A_Dash_Lean (0.33s): new IsDashing param + Dash state; driven from the
  local player's predicted DashState window (not replicated -> remotes skip).
- A_HitReact (0.27s): imported + avatar'd, wiring deferred (needs a
  replicated hit-tick source; body flash covers the read today).

456/456 EditMode; Play-validated: forced IsDead renders the soldier flat on
the ground in-game (Blender->FBX->Humanoid->Rukhanka chain proven), Fire
state enters and plays; console clean.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-06 20:44:21 -07:00
kronic 1224fd97f8 Fix: attack animation sank the model into the floor (Rukhanka partial-clip collapse)
An attack clip that keys ONLY the Root bone makes Rukhanka collapse every un-keyed bone (Hips/Spine/legs) to identity for the duration of the state -> the body folds halfway into the floor (player MeleeSwing + enemy Attack; writeDefaultValues does NOT prevent it -- confirmed since even a pure yaw, which is height-preserving, still sank). Fix: build the attack clips FROM the full idle pose (every bone keyed) + a Root YAW twist on top, so nothing is un-keyed. Applied to both runtime clips (PlayerMeleeSwing/EnemyAttackWindup) and both editor recipes (PlayerRigTools/EnemyRigTools) so rebuilds stay correct. Operator-verified in Play.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-11 00:35:39 -07:00
kronic 1b07a6b07f Fix: attack animation collapsed the model into the floor (partial Root clip + WDV)
The procedural attack clips key only the Root bone, but the Attack/MeleeSwing states had writeDefaultValues=true -> a partial (Root-only) clip resets every un-keyed bone (Hips/Spine/legs) to Rukhanka defaults (~identity), collapsing the body into the floor (player + enemy). Root carries the mesh-positioning offset (localPos -0.90, identity rot) while Hips/Spine carry the authored orientation. Fix: writeDefaultValues=false on the attack states (leave un-keyed bones in pose, only lean the Root). Patched both controllers + both recipes (PlayerRigTools/EnemyRigTools) so a rebuild can't regress. Rule: partial bone-subset overlay clips => writeDefaultValues=false.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-10 23:42:44 -07:00
kronic 352bf3322d Combat: melee swing animation + live range slash-arc VFX (MC-4 polish)
Rukhanka swing animation: PlayerRigTools builds a procedural Root-bone PlayerMeleeSwing.anim and adds an IsAttacking param + MeleeSwing state to AC_PlayerTopDown (mirroring the enemy attack recipe -- no authored Synty Generic melee clip exists). PlayerAnimationDriveSystem pulses IsAttacking from the replicated MeleeCombo swing window (local + remote, NetworkTick wrap-safe, re-triggers per chained hit). CombatFeedbackSystem flashes a procedural cone slash-arc mesh matching the LIVE cleave range + half-angle on each swing (finisher wider/warmer) -- the arc IS the range telegraph. Addresses 'range isn't clear + no animation'.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-10 17:45:33 -07:00
kronic 2fcff9a7a1 Animate enemies: client-derived Rukhanka rigs (Werewolf/Kaiju Husks)
Extends the DR-022 player pipeline to Husk enemies. A Husk is an ownerless
interpolated ghost = structurally a remote player, so the new client-only
EnemyAnimationDriveSystem mirrors PlayerAnimationDriveSystem's remote path:
velocity from LocalTransform-delta (prevPos cache, pruned every frame), facing
from LocalTransform.Rotation (AnimParamMath.PlanarForward), maxSpeed from baked
EnemyStats, IsAttacking from the already-replicated AttackWindup telegraph. No
new [GhostField], no server/asmdef/ghost-hash change.

Monster-mash roster: Werewolf (Grunt), Werewolf-Undead (Swarmer), Kaiju (Brute),
built by the reusable, GUID-preserving EnemyRigTools editor tool (materials +
AC_EnemyTopDown + EnemyAttackWindup clip + 3 rigged prefabs). WaveSystem now
preserves the baked variant Scale (was reset to 1 by LocalTransform.FromPosition).

See DR-023. EditMode 208/208; validated in Play (rigs skin, scales replicate,
locomotion + attack telegraph drive correctly).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-06 23:30:03 -07:00
kronic 951b7ec273 Animate the player: Rukhanka skeletal locomotion (client-derived)
Replace the capsule with a rigged Synty SciFiSpace soldier driven by Rukhanka 2.9 (netcode replication off; animation derived client-side from replicated state). Adds a slim top-down AnimatorController (idle / 2D-strafe locomotion / death) from Synty clips; client-only PlayerAnimationDriveSystem (local CC-velocity + remote position-delta paths); AnimParamMath (+10 EditMode tests); ServerStripAnimationSystem (disables Rukhanka on the server, zero server-side animation). Client.asmdef gains Rukhanka.Runtime/CharacterController/Physics. EditMode 204/204; Play-validated. See DR-022.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-06 18:18:11 -07:00