The animation that was the bind pose 149 times
Characters slid around the level frozen. The rigs were fine, the clip was playing, and nothing moved.
The pack does contain an animation. It has 149 keyframes over five seconds, and zero of its channels differ between the first frame and the last. It is the bind pose, sampled 149 times.
What I had claimed earlier
When I built the model converter I wrote that it "exports a 30Hz-sampled animation clip".
That was mechanically true and substantively worthless. I had checked that animation channels existed and had the right shape. I had not checked that any value in them changed.
There is a general form of this mistake worth naming: verifying the presence of data rather than its content. A channel with 149 identical keyframes satisfies every structural assertion you would naturally write. Row counts, types, ranges, non-null: all fine. The only assertion that catches it is whether the first value differs from the last, which is the one assertion that feels too obvious to write.
So the poses are computed
No animation tooling on this machine and no clips to import, so the walk cycle is generated: a function taking stride phase and speed, returning joint angles. Every value is a named constant that can be tuned.
The phase and speed were already being derived from replicated positions, which matters for a reason beyond convenience. The client is told position, facing, and whether armour is visible. Nothing else.
A walk cycle is safe to derive from that, because an opponent watching you could work it out by eye. A reload pose would not be, because it would tell you something you cannot see, and the wire deliberately does not carry it. So there isn't one. The information budget shapes which animations can exist at all.
Two things about the rig I assumed wrong
Both were measured rather than reasoned about, after reasoning failed.
Bones extend along local X, not Y. The usual convention is Y. This rig's lower leg sits at (0.399, 0, 0) from the upper leg. Resolving the bind chain to world space, a forward swing of the right thigh is a rotation about local Z.
The rig is mirrored. The left thigh's local Z maps to world +1 where the right maps to −1. So equal local angles already swing the legs in opposite world directions.
Which means the obvious assertion, that the left thigh angle is the negation of the right, is wrong here, and code written to satisfy it produces a body hopping with both legs together. The test instead asserts where the limb ends up in world space, using the rig's real bind quaternions read out of the file rather than plausible-looking invented ones.
That distinction cost real time later in the day, so it is worth stating plainly: invented quaternions that look reasonable will fail against correct code, and you cannot tell which of the two is wrong by staring at either.
Two tests that passed by accident
The first pose tests sampled the stride at phase 0.25. That is a zero crossing of the triangle wave driving the cycle, not an extreme, so they were comparing 0.0 against 0.0 and passing.
Moved to phase 0.5, where the values are actually at their limits.
Standing them up
Two more pose bugs, both found by looking at a render rather than by any test.
One leg was permanently vertical. The knees took opposite halves of the wave while the thighs above them both took the same half and let the rig's own mirroring separate them. That is a second mirroring stacked on the rig's, so on one leg the two cancelled and the knee never bent at all.
The arms stuck straight out sideways. The rig binds in a T-pose. Measured, the shoulder bones point along world X while the leg bones point down the body. So the legs start where a standing figure wants them and the arms do not. Rotating about a swing axis without first bringing the arms down leaves them exactly where they were bound.
That was invisible to every unit test, because all the angles were correct relative to a rest pose that was never applied.
And the fix had a sign error that was equally invisible: a positive rest angle folds the arms up over the head, which looks worse than the T-pose did. Both the correct and the inverted value are "rotated by 1.45 radians from bind" as far as an assertion on magnitude can tell. Only asserting where the bone ends up separates them.
Then measuring it in motion
A still frame shows the rest pose, so the stride itself was still unverified. A test now runs the real gait tracker against a body moving at full speed and checks every joint reaches its configured amplitude.
Writing it caught the units being wrong, in the test rather than the code. The tracker computes speed as distance over the snapshot period, because that is how the client feeds it. Calling it every frame divides one frame's distance by one snapshot's period.
A body sprinting at 7 m/s was observed at 1.17, and the entire gait scaled down with it. The thigh swung 0.048 radians: under three degrees, which on screen is indistinguishable from a frozen skeleton sliding along the floor. Which is exactly the bug this whole day started with, arrived at from a completely different direction.
The test now feeds positions at the snapshot rate and asserts on the observed speed as well as the swing, so anything that quietly rescales the gait fails there rather than in play.