Commit Graph

11 Commits

Author SHA1 Message Date
kronic 0ff11fe2a9 Enemy hit-reacts: React/Stagger anim tiers off Health-drop edges (the Rukhanka-safe flinch)
SwordCombat React (1.4x, 0.3s pulse) + Stagger (1.2x, 0.55s) as Any-State
states on AC_EnemyTopDown via EnemyRigTools.WireEnemyHitReacts; driven by
EnemyAnimationDriveSystem's cache (now Pos/Hp/ReactUntil/Heavy) off
replicated Health drops. Windup-honesty gate: light reacts require
!IsAttacking (a sub-poise hit never visually cancels a live windup);
the heavy tier tracks the server's B2 poise break (stagger threshold 50
= finisher staggers, light flinches at the locked tuning). Knobs:
HitReactSeconds (0=off) / HitStaggerSeconds / HitReactStaggerDamage.
Replaces the review-cut positional vibrate (Rukhanka inverse-fold no-op).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-21 00:28:11 -07:00
kronic ce0faafb72 HEAVY FEEL LOCKED: the A/B winner folded into defaults, clips retimed to zero contact drift
recover 36 / dmg 36 (DPS 60 held) / contact 20 (20/12/25 per step) /
grace 28 / buffer 10 / move-commit 0.25; arc 0.8, finisher hold 7,
connect kick 1.1. Clip state speeds retimed 1.0/0.85/0.88 so the VISUAL
blade contact matches the damage tick exactly (audit: zero drift; probe:
gaps 36/36/54, contacts +20/+12/+25 measured). Step-3 contact sits 1
tick under CastFacingTicks 26 (documented coupling). baseline profile =
the locked defaults; heavy-committed kept as the record.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-21 00:13:49 -07:00
kronic 7b65912f30 Melee feel overhaul: SwordCombat anims at heavy cadence, salvage axe, damage-at-contact + buffer + dash law (guidelines forks 1-6)
07-18/19/20 arc: LightCombo01/HeavyCombo01 clips onto Swing1-3/Slam at
~natural speed (26-tick window, 30-tick recover, DPS-held damage retune),
Menacing01 combat idle (InCombat), SM_Wep_Axe_Large_01 rigid-skinned to
Hand_R at x1.25, LANTERN FX retone + blade-smear ribbon. Forks 1-6 per
Combat_Attack_Feel_Guidelines (design review wf_000bc247): cleave resolves
at the CONTACT tick (MeleeCleavePending schedule-and-consume, knob 31,
0=legacy; connect cues moved to contact), MeleeRange 2.2 + reach-only
finisher mult 1.25 (knob 30), BufferedAttackTick GhostField input buffer
(knob 29, unlock-edge validity), dash refused pre-contact (lookup-based).
Tests: MeleeComboTests pin legacy knobs; +3 fork tests (414 green); live
server proof: HP drop exactly at swing+16 under tick batching.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-20 21:03:18 -07:00
kronic 7571091394 LANTERN feel pass (DR-052 + gap list): SoD facing, underwater feel, Bathynaut kit, walk/run gait, suit lamp + new Synty anim packs
- SoD facing: PlayerFacing = body-yaw only (move-facing / cast-turn / idle-hold); every fire
  direction re-sourced to FacingMath.ResolveAim (pre-code review blocking catch); TickWindowMath
  shared windows with Movement-skip; reticle/FX coupled to the damage direction; cursor-dash kept.
- Underwater feel: sharpness 15->6, turn 720->360, MoveSpeed 6->4.2; TuningKnob 26-28
  (0 = no-override sentinels, dev-protocol bump on DebugTuningReport); stride footsteps + silt +
  cadence floor; bubbles; underwater ambience bed + distant groans; camera drag + dev scroll zoom.
- Bathynaut kit in-engine: dome/tank/shoulder-lamp + bare head grafted (GraftSmr rigid rebase,
  RecalculateTangents); EmissiveGloamSkinned shader (Rukhanka deformation); shoulder lamp CASTS
  (warm steady spot on body yaw).
- Gait: two-ring walk/run FreeformDirectional tree (walk @0.35, run @1.0) + blended-natural
  StrideScale; additive Posture(Bank) + Lead(chest-lead) layers; idle = AnimationIdles Base;
  banking driven from facing turn rate; flat terrain (Env_SeabedKit seabed squashed - CC is planar).
- New packs: Synty AnimationIdles + AnimationSwordCombat (combat pass queued) + SyntyPropBoneTool;
  four authored clips (sway/trudge/banks/lean) + Anim_Player_Underwater.blend + suit-kit FBX.
- Validation: 411/411 EditMode green; Play smokes (server==client facing, Aim-true projectile,
  bank/stride live-sampled, lamp beam verified); pre-code + post-impl adversarial reviews applied.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-16 13:56:02 -07:00
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