From b406b6b6a38adec3630a62271bd409ddbfab00db Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Wed, 10 Jun 2026 06:01:09 +0000 Subject: [PATCH] Add unit tests for N-entity and player-agnostic capabilities Added tests to verify the game engine correctly handles an arbitrary number of entities (e.g. 1, 100) and player counts in the rollback controller (e.g. 1, 4). Also tests GameState.CopyFrom handles mismatching entity counts gracefully. Co-authored-by: Ghostmonday <207882092+Ghostmonday@users.noreply.github.com> --- tests/DeterministicSim.Engine.Tests.csproj | 1 + tests/unit/core/EntityAgnosticTests.cs | 130 +++++++++++++++++++++ 2 files changed, 131 insertions(+) create mode 100644 tests/unit/core/EntityAgnosticTests.cs diff --git a/tests/DeterministicSim.Engine.Tests.csproj b/tests/DeterministicSim.Engine.Tests.csproj index ca14eb3..10e4f42 100644 --- a/tests/DeterministicSim.Engine.Tests.csproj +++ b/tests/DeterministicSim.Engine.Tests.csproj @@ -34,6 +34,7 @@ + diff --git a/tests/unit/core/EntityAgnosticTests.cs b/tests/unit/core/EntityAgnosticTests.cs new file mode 100644 index 0000000..4ecf879 --- /dev/null +++ b/tests/unit/core/EntityAgnosticTests.cs @@ -0,0 +1,130 @@ +using DeterministicSim.Engine.Core; +using DeterministicSim.Engine.Net; +using Xunit; +using System.Runtime.CompilerServices; + +namespace DeterministicSim.Engine.Tests.Core; + +public class EntityAgnosticTests +{ + [Fact] + public void GameState_1Entity_InitializesCorrectly() + { + var state = new GameState(1); + Assert.Equal(1, state.EntityCount); + + state.SetPosX(0, 100); + state.SetPosY(0, 200); + + Assert.Equal(100, state.GetPosX(0)); + Assert.Equal(200, state.GetPosY(0)); + Assert.True(state.IsActive(0)); // Should be active by default + } + + [Fact] + public void GameState_100Entities_InitializesCorrectly() + { + var state = new GameState(100); + Assert.Equal(100, state.EntityCount); + + for (int i = 0; i < 100; i++) + { + state.SetPosX(i, i * 10); + state.SetPosY(i, i * 20); + state.SetVelX(i, i * 2); + state.SetVelY(i, i * 3); + state.SetActive(i, i % 2 == 0); + } + + for (int i = 0; i < 100; i++) + { + Assert.Equal(i * 10, state.GetPosX(i)); + Assert.Equal(i * 20, state.GetPosY(i)); + Assert.Equal(i * 2, state.GetVelX(i)); + Assert.Equal(i * 3, state.GetVelY(i)); + Assert.Equal(i % 2 == 0, state.IsActive(i)); + } + } + + [Fact] + public void GameState_CopyFrom_MismatchEntityCount_HandlesGracefully() + { + var src = new GameState(10); + for(int i = 0; i < 10; i++) + { + src.SetPosX(i, i * 100); + } + + var dst = new GameState(5); + dst.CopyFrom(src); + + // Should only copy up to Math.Min(src.EntityCount, dst.EntityCount) + for(int i = 0; i < 5; i++) + { + Assert.Equal(i * 100, dst.GetPosX(i)); + } + + var dst2 = new GameState(15); + dst2.CopyFrom(src); + for(int i = 0; i < 10; i++) + { + Assert.Equal(i * 100, dst2.GetPosX(i)); + } + for(int i = 10; i < 15; i++) + { + Assert.Equal(0, dst2.GetPosX(i)); + } + } + + [Fact] + public void RollbackController_1Player_WorksCorrectly() + { + var config = RollbackConfig.Default(); + config.PlayerCount = 1; + + var controller = new RollbackController(config); + + var inputFrame = new InputFrame(1, 1); + inputFrame.SetPlayerInputs(0, 42); + + controller.SaveInputs(1, inputFrame); + + var storedFrame = controller.GetInputs(1); + Assert.Equal(1, storedFrame.PlayerCount); + Assert.Equal(42, storedFrame.GetPlayerInputs(0)); + + controller.SaveState(1); + var state = controller.GetState(1); + Assert.NotNull(state); + Assert.Equal(1, state!.EntityCount); + } + + [Fact] + public void RollbackController_4Players_WorksCorrectly() + { + var config = RollbackConfig.Default(); + config.PlayerCount = 4; + + var controller = new RollbackController(config); + + var inputFrame = new InputFrame(1, 4); + inputFrame.SetPlayerInputs(0, 10); + inputFrame.SetPlayerInputs(1, 20); + inputFrame.SetPlayerInputs(2, 30); + inputFrame.SetPlayerInputs(3, 40); + + controller.SaveInputs(1, inputFrame); + + var storedFrame = controller.GetInputs(1); + Assert.Equal(4, storedFrame.PlayerCount); + Assert.Equal(10, storedFrame.GetPlayerInputs(0)); + Assert.Equal(20, storedFrame.GetPlayerInputs(1)); + Assert.Equal(30, storedFrame.GetPlayerInputs(2)); + Assert.Equal(40, storedFrame.GetPlayerInputs(3)); + + controller.SaveState(1); + var state = controller.GetState(1); + Assert.NotNull(state); + Assert.Equal(4, state!.EntityCount); + } +}