Problem
An animation clip can register successfully (registerRuntimeAnimationClips) even when none of its channels resolve against the target skeleton's joint paths — e.g. a namespace prefix mismatch ("skel:LeftArm" vs "LeftArm") or a hierarchy mismatch (differing parent chains) between the exported clip and the skeleton it's bound to. In that case the clip is added to animationComponent.animationClips and plays back without error, but every joint samples from its rest pose (CompiledAnimationClip.Channel.animated == false for all channels) — the character silently doesn't animate.
There's currently no validation step that reports this clearly. The caller sees a clip selected and playing (currentAnimation set, currentTime advancing) with no visible motion and no error, which makes a namespace/hierarchy export mismatch hard to diagnose — it looks identical to "the clip has no keyframes" or "the pose is correct but tiny," not "the paths never matched."
Proposed fix
- When a clip is registered (or first compiled against a skeleton via
AnimationComponent.compiledClip), check whether at least one channel actually resolved to an animated joint.
- If zero channels matched, surface this clearly instead of silently succeeding — e.g. a new
handleError case (mirroring the existing .noAnimationClip pattern in Systems/ErrorHandlingSystem.swift) that names the clip, the entity, and ideally a hint that no joint path in the clip matched the skeleton (common cause: namespace prefix or hierarchy mismatch).
- Consider whether registration should still succeed (so partial/intentional no-op clips aren't blocked) or whether this should only be a loud diagnostic, not a hard failure.
Acceptance criteria
Context
Surfaced while reviewing PR #1316 (animation playback helpers / one-shot clip fixes) — that PR addresses a separate root-motion wrapping bug (now closed by #1314/#1316) but does not touch clip registration or joint-path validation, so this is tracked separately.
Problem
An animation clip can register successfully (
registerRuntimeAnimationClips) even when none of its channels resolve against the target skeleton's joint paths — e.g. a namespace prefix mismatch ("skel:LeftArm"vs"LeftArm") or a hierarchy mismatch (differing parent chains) between the exported clip and the skeleton it's bound to. In that case the clip is added toanimationComponent.animationClipsand plays back without error, but every joint samples from its rest pose (CompiledAnimationClip.Channel.animated == falsefor all channels) — the character silently doesn't animate.There's currently no validation step that reports this clearly. The caller sees a clip selected and playing (
currentAnimationset,currentTimeadvancing) with no visible motion and no error, which makes a namespace/hierarchy export mismatch hard to diagnose — it looks identical to "the clip has no keyframes" or "the pose is correct but tiny," not "the paths never matched."Proposed fix
AnimationComponent.compiledClip), check whether at least one channel actually resolved to an animated joint.handleErrorcase (mirroring the existing.noAnimationClippattern inSystems/ErrorHandlingSystem.swift) that names the clip, the entity, and ideally a hint that no joint path in the clip matched the skeleton (common cause: namespace prefix or hierarchy mismatch).Acceptance criteria
.noAnimationClip) and names the clip/entity involved.Context
Surfaced while reviewing PR #1316 (animation playback helpers / one-shot clip fixes) — that PR addresses a separate root-motion wrapping bug (now closed by #1314/#1316) but does not touch clip registration or joint-path validation, so this is tracked separately.