feat: improved ops-strip with faction and stations

This commit is contained in:
2026-03-18 00:40:44 -04:00
parent ad5f733b3e
commit 00a008bda5
16 changed files with 341 additions and 175 deletions

View File

@@ -169,7 +169,7 @@ public sealed partial class SimulationEngine
ship.History,
ship.CurrentAction,
ship.SpatialState)).ToList(),
world.Factions.Select(ToFactionDelta).Select(faction => new FactionSnapshot(
world.Factions.Select(faction => ToFactionDelta(faction, FindFactionCommander(world, faction.Id))).Select(faction => new FactionSnapshot(
faction.Id,
faction.Label,
faction.Color,
@@ -179,7 +179,9 @@ public sealed partial class SimulationEngine
faction.GoodsProduced,
faction.ShipsBuilt,
faction.ShipsLost,
faction.DefaultPolicySetId)).ToList());
faction.DefaultPolicySetId,
faction.GoapState,
faction.GoapPriorities)).ToList());
}
public void PrimeDeltaBaseline(SimulationWorld world)
@@ -231,7 +233,7 @@ public sealed partial class SimulationEngine
foreach (var faction in world.Factions)
{
faction.LastDeltaSignature = BuildFactionSignature(faction);
faction.LastDeltaSignature = BuildFactionSignature(faction, FindFactionCommander(world, faction.Id));
}
}
@@ -402,19 +404,25 @@ public sealed partial class SimulationEngine
var deltas = new List<FactionDelta>();
foreach (var faction in world.Factions)
{
var signature = BuildFactionSignature(faction);
var commander = FindFactionCommander(world, faction.Id);
var signature = BuildFactionSignature(faction, commander);
if (signature == faction.LastDeltaSignature)
{
continue;
}
faction.LastDeltaSignature = signature;
deltas.Add(ToFactionDelta(faction));
deltas.Add(ToFactionDelta(faction, commander));
}
return deltas;
}
private static CommanderRuntime? FindFactionCommander(SimulationWorld world, string factionId) =>
world.Commanders.FirstOrDefault(c =>
c.FactionId == factionId &&
string.Equals(c.Kind, CommanderKind.Faction, StringComparison.Ordinal));
private static string BuildNodeSignature(ResourceNodeRuntime node) =>
$"{node.SystemId}|{node.Position.X:0.###}|{node.Position.Y:0.###}|{node.Position.Z:0.###}|{node.AnchorNodeId}|{node.OreRemaining:0.###}";
@@ -508,8 +516,13 @@ public sealed partial class SimulationEngine
.OrderBy(entry => entry.Key, StringComparer.Ordinal)
.Select(entry => $"{entry.Key}:{entry.Value:0.###}"));
private static string BuildFactionSignature(FactionRuntime faction) =>
$"{faction.Credits:0.###}|{faction.PopulationTotal:0.###}|{faction.OreMined:0.###}|{faction.GoodsProduced:0.###}|{faction.ShipsBuilt}|{faction.ShipsLost}|{faction.DefaultPolicySetId}";
private static string BuildFactionSignature(FactionRuntime faction, CommanderRuntime? commander)
{
var goapSig = commander?.LastGoalPriorities is { } prios
? string.Join(",", prios.Select(p => $"{p.Name}:{p.Priority:0.##}"))
: string.Empty;
return $"{faction.Credits:0.###}|{faction.PopulationTotal:0.###}|{faction.OreMined:0.###}|{faction.GoodsProduced:0.###}|{faction.ShipsBuilt}|{faction.ShipsLost}|{faction.DefaultPolicySetId}|{goapSig}";
}
private static ResourceNodeDelta ToNodeDelta(ResourceNodeRuntime node) => new(
node.Id,
@@ -755,17 +768,44 @@ public sealed partial class SimulationEngine
.Select(entry => new InventoryEntry(entry.Key, entry.Value))
.ToList();
private static FactionDelta ToFactionDelta(FactionRuntime faction) => new(
faction.Id,
faction.Label,
faction.Color,
faction.Credits,
faction.PopulationTotal,
faction.OreMined,
faction.GoodsProduced,
faction.ShipsBuilt,
faction.ShipsLost,
faction.DefaultPolicySetId);
private static FactionDelta ToFactionDelta(FactionRuntime faction, CommanderRuntime? commander)
{
FactionGoapStateSnapshot? goapState = null;
IReadOnlyList<FactionGoapPrioritySnapshot>? goapPriorities = null;
if (commander?.LastPlanningState is { } ps)
{
goapState = new FactionGoapStateSnapshot(
ps.MilitaryShipCount,
ps.MinerShipCount,
ps.TransportShipCount,
ps.ConstructorShipCount,
ps.ControlledSystemCount,
ps.TargetSystemCount,
ps.HasShipFactory,
ps.OreStockpile,
ps.RefinedMetalsStockpile);
}
if (commander?.LastGoalPriorities is { } prios)
{
goapPriorities = prios.Select(p => new FactionGoapPrioritySnapshot(p.Name, p.Priority)).ToList();
}
return new FactionDelta(
faction.Id,
faction.Label,
faction.Color,
faction.Credits,
faction.PopulationTotal,
faction.OreMined,
faction.GoodsProduced,
faction.ShipsBuilt,
faction.ShipsLost,
faction.DefaultPolicySetId,
goapState,
goapPriorities);
}
private static ShipSpatialStateSnapshot ToShipSpatialStateSnapshot(ShipSpatialStateRuntime state) => new(
state.SpaceLayer,