fix: complete retail parity stability pass
All checks were successful
CI / linux-portable (push) Successful in 3m41s
CI / windows-gate (push) Successful in 6m49s
CI / release (push) Successful in 3m22s

This commit is contained in:
Erik 2026-08-28 20:01:39 +02:00
parent d3df4cb20a
commit f7aa8e0eb7
131 changed files with 7765 additions and 1190 deletions

View file

@ -381,6 +381,50 @@ public sealed class LiveEntityAnimationPresenterTests
Assert.Equal(0.5f, fixture.State.CurrFrame);
}
[Fact]
public void LegacyCycle_WrapsAndInterpolatesThroughSharedRetailPlayback()
{
var fixture = Build(partCount: 1);
fixture.State.Sequencer = null;
fixture.State.LowFrame = 0;
fixture.State.HighFrame = 2;
fixture.State.Framerate = 2f;
fixture.State.CurrFrame = 2.5f;
var animation = new Animation();
foreach (float x in new[] { 0f, 10f, 20f })
{
var frame = new AnimationFrame(1);
frame.Frames.Add(new Frame
{
Origin = new Vector3(x, 0f, 0f),
Orientation = Quaternion.Identity,
});
animation.PartFrames.Add(frame);
}
fixture.State.Animation = animation;
var schedule = new LiveEntityAnimationSchedule(
SequenceFrames: null,
LegacyAdvanceSeconds: 0.5f,
ComposeParts: true,
fixture.Record,
fixture.Entity,
fixture.State,
fixture.Record.ObjectClockEpoch,
fixture.Record.ProjectionMutationVersion,
fixture.State.PresentationRevision);
var presenter = Presenter(fixture.Live, new EntityEffectPoseRegistry(), new Context());
presenter.Present(new Dictionary<RuntimeEntityKey, LiveEntityAnimationSchedule>
{
[fixture.Record.ProjectionKey!.Value] = schedule,
});
// Legacy arithmetic: 2.5 + (0.5 * 2) = 3.5, wrapped over the
// inclusive 0..2 span to 0.5, then interpolated halfway 0 -> 10.
Assert.Equal(0.5f, fixture.State.CurrFrame);
Assert.Equal(new Vector3(5f, 0f, 0f), fixture.Entity.MeshRefs[0].PartTransform.Translation);
}
private static LiveEntityAnimationPresenter Presenter(
LiveEntityRuntime live,
EntityEffectPoseRegistry poses,