From b571555e2a2ac2637366e200924f769d9168dd70 Mon Sep 17 00:00:00 2001 From: Nibu Date: Sat, 7 Nov 2026 15:00:22 +0000 Subject: [PATCH] ship-authoring stats --top-speed adds the VelocityLimit a bare hull lacks create without --like makes a hull with no behaviors, Validate refuses a ship hull without a VelocityLimit, and stats --top-speed refused any hull without exactly one: no command could give such a hull a top speed. The first --top-speed now adds the one limit; two or more are still refused. Co-Authored-By: Claude Sonnet 5.5 --- tests/Aetheria.Shared.Tests/ShipProductTests.cs | 6 ++++-- tools/AetherDb/ShipAuthoringCommands.cs | 7 +++++-- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/tests/Aetheria.Shared.Tests/ShipProductTests.cs b/tests/Aetheria.Shared.Tests/ShipProductTests.cs index bb358c4df..f2326ed82 100644 --- a/tests/Aetheria.Shared.Tests/ShipProductTests.cs +++ b/tests/Aetheria.Shared.Tests/ShipProductTests.cs @@ -353,8 +353,6 @@ public sealed class ShipProductTests : IDisposable RefusedAndUntouched(path, "--mass", "5", "--mass", "6"); // A valid flag beside a bad one writes nothing. RefusedAndUntouched(path, "--mass", "5", "--durability", "-2"); - RefusedAndUntouched(bare, "--top-speed", "50"); - RefusedAndUntouched(bare, "--mass", "5", "--top-speed", "50"); // Two VelocityLimits leave no one top speed to set. RefusedAndUntouched(twin, "--top-speed", "50"); @@ -385,6 +383,10 @@ public sealed class ShipProductTests : IDisposable Assert.Equal((1f, 0f, 8000f), (ShipAuthoringStore.Load(path).Hull.Mass, ShipAuthoringStore.Load(path).Hull.Drag, ShipAuthoringStore.Load(path).Hull.Durability)); Assert.Equal(0, Run("stats", bare, "--armor", "12").Code); Assert.Equal(12f, ShipAuthoringStore.Load(bare).Hull.Armor); + // A hull with no top speed (create without --like) gets its one VelocityLimit from the first --top-speed. + Assert.Equal(0, Run("stats", bare, "--top-speed", "50").Code); + var added = ShipAuthoringStore.Load(bare).Hull.Behaviors.OfType().Single().TopSpeed; + Assert.Equal((50f, 50f), (added.Min, added.Max)); } [Fact] diff --git a/tools/AetherDb/ShipAuthoringCommands.cs b/tools/AetherDb/ShipAuthoringCommands.cs index bce7eda08..9f8f1c41c 100644 --- a/tools/AetherDb/ShipAuthoringCommands.cs +++ b/tools/AetherDb/ShipAuthoringCommands.cs @@ -110,8 +110,11 @@ public static class ShipAuthoringCommands var (hull, ship, _) = ShipAuthoringStore.Load(args[1]); if (stats.TryGetValue("--top-speed", out var topSpeed)) { - var limits = (hull.Behaviors ?? new List()).OfType().ToArray(); - if (limits.Length != 1) throw new InvalidOperationException($"{ship.Id}: --top-speed needs exactly one VelocityLimit on the hull; it has {limits.Length}."); + hull.Behaviors ??= new List(); + var limits = hull.Behaviors.OfType().ToList(); + // A hull made without --like has none, and Validate refuses a ship hull without one: the first --top-speed adds it. + if (limits.Count == 0) { limits.Add(new VelocityLimitData()); hull.Behaviors.Add(limits[0]); } + if (limits.Count != 1) throw new InvalidOperationException($"{ship.Id}: --top-speed needs at most one VelocityLimit on the hull; it has {limits.Count}."); // A fixed top speed, as every shipped hull authors one (Min equal to Max); its terms are kept. limits[0].TopSpeed.Min = limits[0].TopSpeed.Max = topSpeed; } -- 2.47.3