Diagnostic spawn dump revealed the player character arrives with
`low=0 high=-1 framerate=30.00 partFrames=33`. The -1 is ACViewer's
"play the whole animation" sentinel (see
references/ACViewer/.../Physics/Animation/AnimSequenceNode.cs:96-113
set_animation_id). My Phase 6.1 code used the raw int values, so
the downstream registration filter evaluated `HighFrame(-1) > LowFrame(0)`
as false and threw away every animated entity whose AnimData used the
sentinel — which, from the live dump, appears to be basically all of
them.
MotionResolver.GetIdleCycle now does the same four-step clamp ACViewer
does: -1 HighFrame → NumFrames-1, clamp LowFrame and HighFrame to
NumFrames-1, and collapse to LowFrame if LowFrame > HighFrame. The
IdleCycle carried up to GameWindow is always in terms of real frame
indices the playback loop can step through. Static poses (framerate==0
or single frame after resolution) still skip registration correctly.
168 tests green.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>