5.9 KiB
date, type, tags, permalink
| date | type | tags | permalink | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|
| 2026-06-06 | session |
|
gamevault/07-sessions/2026/2026-06-06-animation-pipeline-slice1 |
Session 2026-06-06 — Animation pipeline (Rukhanka + Synty), Slice 1: the player is alive
Goal
Operator (via /dots-dev, ultracode): "Explore animations for this DOTS project — Rukhanka 2 (netcode-aware), alternatives, how much I can wire via MCP. Build something scalable/stable/sustainable for a solo dev. The game feels dead — the player is a capsule with no movement. Make it feel alive."
Process
- Research (adversarial Workflow): verify exact Rukhanka 2.9 / Entities 6.4 APIs against the installed source + docs + context7 → synthesize a code-ready spec → 2 adversarial critics → finalize. Landscape: Rukhanka is the only maintained Entities-native option on the 6.4 stack (Latios/Kinemation explicitly not 6.4-compatible; Unity official = vaporware; DMotion dead). 3 parallel research agents up front (Rukhanka capability+netcode, alternatives, Synty rig/anim-pack compat).
- Clarifying gate (AskUserQuestion): clip source = Synty anim pack (already imported:
AnimationBaseLocomotion), first slice = player only, netcode = advise-me → chose client-derived, look = SciFiSpace soldier. - Plan → approval → execution. A permissions misfire (my subagent guardrail text "don't enter Play / use UnityMCP" was read by the auto-approver as the user's rule) blocked Play; operator reconnected MCP and cleared it.
- Execution serialized through the one live editor (research fanned out in parallel; all Unity mutations done by me, validating each).
Done
- De-risk (task 1): entered Play → Rukhanka 2.9 initializes clean on Entities 6.4 (zero Rukhanka errors). GO.
- FBX (task 2): SciFiSpace
Characters.fbxalready Generic + Optimize-GO-OFF + Mikk tangents → verify-only. - Controller (task 3): authored
AC_PlayerTopDown.controllervia the AnimatorController API (robust vs the enum/Vector-drop MCP traps) — 4 params, Idle / 2D-Freeform-Directional strafe Locomotion (9 in-place Synty run clips) / Death; 0 missing clips. - Drive system (task 5, done before assets to compile-validate the Rukhanka API):
AnimParamMath(pure, 10 EditMode tests) + client-onlyPlayerAnimationDriveSystem(Local CC-velocity + Remote position-delta jobs;[WithAll(GhostOwnerIsLocal)]/[WithDisabled]/[WithPresent(Dead)]). Asmdef refs added; alsoUnity.Physics(source-gen needs it directly —KinematicCharacterBodynestsColliderKey; the verified spec missed it). EditMode 204/204. - Material + prefab (task 4): imported Rukhanka samples for
AnimatedLitShader(multi-target ShaderGraph w/ a UniversalTarget → URP-valid), builtM_SpaceSoldier_Animated(Synty atlas →_BaseColorMap). AssembledPlayer.prefab: flattened the soldier skeleton + body/head SMRs onto the player root (so the rig co-locates with gameplay components — required for the drive query),Animator+RigDefinitionAuthoring(CPU, root-motion off) on the root, capsule visual removed / collider kept. Recovered a broken first attempt (usedrootBone=Spine_03 → destroyed the lower skeleton) viagit checkout+ correct walk-up-to-skeleton-root detection. - Samples cleanup: moved the 3 deformation ShaderGraphs to
_Project/Shaders/RukhankaSampleShaders(GUID-preserving) and deleted the whole samples tree — it had dragged in 26 sample subscenes (one NRE'd Rukhanka's unguarded clip baker), sample systems that run in our worlds, and a conflicting TextMesh Pro folder. - Ground offset: skeleton
Rootlocal Y = −0.9 (entity origin = capsule center ~1 m up). Clips key no Root/Hips position → Rukhanka bakes it as a constant → persists. Feet 0.90 → ≈0.00.
Validation (runtime, focused editor, real Server+Client)
- ClientWorld player entity:
PlayerTag+ rig + 4 params + facing/stats/CC/Dead+GhostOwnerIsLocalenabled → drive job matches. Idle and a forced run pose both deform the mesh (distinct silhouettes, screenshots); feet at y≈0; capsule replaced by the textured soldier. Console clean (no NRE, no skinning warning). - ServerWorld: our drive system correctly absent.
- EditMode 204/204 (+10
AnimParamMath).
Decisions
DR-022_Animation_Pipeline_Rukhanka_Synty — Rukhanka client-derived; Generic-rig + Synty clips; CPU engine + deformation material; slim top-down controller; rig-on-root for entity co-location; client-only two-path drive (local CC-velocity / remote position-delta).
Runtime finding the adversarial spec got wrong: RukhankaAnimationSystemGroup is created in ServerWorld (the spec read a WorldFlags gate and concluded otherwise). Harmless (drive is client-only; bones unreplicated; animation never feeds the sim) but wastes server CPU — only Play-validation caught it. Logged as a follow-up (server-strip).
Next-session intent
Server-strip RukhankaDONE (same session):ServerStripAnimationSystem(server-only one-shot) disables allRukhanka.Runtimesystems on the server (validated: server enabled=0 / 4 disabled, client 8 running, console clean). Also added a Phase 10 (Commit) to the/dots-devskill — offer + commit only on explicit operator approval, logical groups, proper messages, no push.- Template the pipeline to enemies (Husk/Brute/Swarmer) — same flow, swap mesh + reuse
AC_PlayerTopDown(or per-enemy clips). - Source a combat/hit-react/death anim pack (Base Locomotion is locomotion-only; Death is a crouch placeholder; Fire has no clip yet).
- Aim-IK upper body toward the cursor (twin-stick), then ragdoll-on-death, bone-socket weapons, GPU engine + VAT for crowds.
- Operator live play-through to tune anim-speed scaling / blend thresholds / the −0.9 offset, and a 2-client MPPM check that remote players animate (the position-delta path).