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

@ -219,7 +219,7 @@ public sealed class LiveEntityNetworkOnPositionCollapseMatrixTests
// ── Scenario 2: landing packet (the preserved rows 2a/2b asymmetry) ─
[Fact]
public void LandingPacket_PlayerGuid_QueueClearedNoShadowPublish_316Preserved()
public void LandingPacket_PlayerGuid_QueueClearedAndShadowPublished()
{
using var fixture = new Fixture(PlayerGuid);
EntityPhysicsHost host = fixture.InstallHost();
@ -253,14 +253,13 @@ public sealed class LiveEntityNetworkOnPositionCollapseMatrixTests
// Row 2a, PRESERVED for player guids: the interp queue IS cleared.
Assert.False(fixture.Remote.Interp.IsActive);
// Row 2b / #316, PRESERVED (NOT fixed): the shadow is NOT
// republished for a player-guid landing — it stays at whatever it
// was before this packet.
// #316: the same resolved landing pose must publish to collision in
// this packet, not wait for a later physics tick to self-heal.
ShadowEntry shadowEntry = Assert.Single(
fixture.Shadows.AllEntriesForDebug(),
entry => entry.EntityId == fixture.Entity.Id);
Assert.Equal(spawnShadowPos, shadowEntry.Position);
Assert.NotEqual(landingPos, shadowEntry.Position);
Assert.Equal(landingPos, shadowEntry.Position);
Assert.NotEqual(spawnShadowPos, shadowEntry.Position);
// AP-135's cell-adopt bookkeeping still ran (via the post-routing
// wire-cell adopt, not suppressed for AirborneSnap).
@ -574,6 +573,26 @@ public sealed class LiveEntityNetworkOnPositionCollapseMatrixTests
_ = host;
}
[Fact]
public void PositionPackVelocity_DoesNotOverwriteAuthoritativeBodyVelocity()
{
using var fixture = new Fixture(CreatureGuid);
Vector3 authoritativeVectorUpdate = new(4f, 5f, 6f);
fixture.Remote.Body.Velocity = authoritativeVectorUpdate;
// Retail's airborne/non-teleport Position arm performs no placement,
// isolating the PositionPack velocity rule from contact resolution.
fixture.Controller.OnPosition(fixture.Update(
new Vector3(12f, 14f, SpawnHeight + 2f),
SourceCell,
teleportSequence: 1,
guid: CreatureGuid,
isGrounded: false,
velocity: new Vector3(0.7f, 0.2f, -0.1f)));
Assert.Equal(authoritativeVectorUpdate, fixture.Remote.Body.Velocity);
}
// ── Sabotage check (contract §5, one-time, manual) ──────────────────
//
// Performed by hand during implementation, not committed as a test (a

View file

@ -12,7 +12,7 @@ namespace AcDream.App.Tests.Physics;
public sealed class LiveEntityOrdinaryPhysicsUpdaterTests
{
private const uint Guid = 0x70000071u;
private const uint Guid = 0x50000071u;
private const uint SourceCell = 0xA9B40039u;
private const uint DestinationCell = 0xAAB40001u;
@ -37,7 +37,8 @@ public sealed class LiveEntityOrdinaryPhysicsUpdaterTests
Rotation = Quaternion.Identity,
MeshRefs = Array.Empty<MeshRef>(),
ParentCellId = SourceCell,
});
},
isLocalPlayer: true);
WorldEntity entity = Assert.IsType<WorldEntity>(record.WorldEntity);
var remote = new AcDream.Runtime.Physics.RemoteMotion
@ -84,6 +85,17 @@ public sealed class LiveEntityOrdinaryPhysicsUpdaterTests
Assert.True(entity.Position.X > 192f);
Assert.Equal(entity.Position, record.PhysicsBody.Position);
Assert.Equal(epoch, record.ObjectClockEpoch);
// #320: retiring the landblock the player walked out of must not
// sweep the still-live player into a DeferredCell park. Before the
// ordinary-cell commit existed, FullCellId remained SourceCell and
// this exact retirement selected the player as an affected spatial
// root.
live.Physics.SetPosition.ParkCollisionResidents(
SourceCell,
includeOutdoorCells: true);
Assert.Equal(DestinationCell, record.FullCellId);
Assert.True(live.Physics.IsSpatialRoot(record.Canonical));
}
[Fact]