From c7dcf178f3cc7ee6519b842dd6ec5b1ab3a5ce44 Mon Sep 17 00:00:00 2001 From: Meta Vens Date: Sun, 11 Oct 2026 08:44:04 +0200 Subject: [PATCH] ThrustAllocator: cold and warm starts agree on the hull that stopped early The finding's fixture (Synthetic(8, 7005), the seeded random walk through its eighth intent) compares a warm allocator with a fresh one at every step. Fails on the 0.4.0 pin, passes on 0.4.1. Builds. Co-Authored-By: Claude Opus 5.5 --- .../ThrustAllocatorTests.cs | 33 +++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/tests/Aetheria.Shared.Tests/ThrustAllocatorTests.cs b/tests/Aetheria.Shared.Tests/ThrustAllocatorTests.cs index 7e36f5569..705590f27 100644 --- a/tests/Aetheria.Shared.Tests/ThrustAllocatorTests.cs +++ b/tests/Aetheria.Shared.Tests/ThrustAllocatorTests.cs @@ -265,6 +265,39 @@ public class ThrustAllocatorTests } } + // A cruiser-like hull, n thrusters each pushing along one body axis with a lever-arm yaw (the finding's fixture + // generator: Synthetic(8, 7005)). + static float3[] Synthetic(int n, int seed) + { + var rng = new Random(seed); + var cols = new float3[n]; + for (var i = 0; i < n; i++) + { + var a = 20f + 40f * (float)rng.NextDouble(); + var yaw = (float)(rng.NextDouble() * 2 - 1) * 120f; + var dir = rng.Next(10); + cols[i] = dir < 4 ? Col(0, a, yaw) : dir < 6 ? Col(0, -a, yaw) : dir < 8 ? Col(a, 0, yaw) : Col(-a, 0, yaw); + } + return cols; + } + + // Finding solver-converged-early: on this hull a fresh allocator's eighth intent of a seeded random walk stopped at a + // non-optimal point (throttle 7 at 1.0 against .922 warm). The answer is the same from a cold and from a warm start. + [Fact] + public void ColdAndWarmStartsAgreeOnTheHullThatStoppedEarly() + { + var hull = Synthetic(8, 7005); + var rng = new Random(5); + var warm = new ThrustAllocator(); + for (var step = 0; step < 8; step++) + { + float x = (float)rng.NextDouble() * 2 - 1, y = (float)rng.NextDouble() * 2 - 1, turn = (float)rng.NextDouble() * 2 - 1; + var fromWarm = Solve(warm, hull, x, y, turn); + var fromCold = Solve(hull, x, y, turn); + for (var i = 0; i < hull.Length; i++) Assert.True(MathF.Abs(fromWarm[i] - fromCold[i]) <= 1e-5f, $"step {step}: throttle {i} {fromCold[i]} cold vs {fromWarm[i]} warm"); + } + } + [Fact] public void EqualThrustersShareTheDemand() {