refactor(backend): align api namespaces and project name

This commit is contained in:
2026-03-19 17:44:53 -04:00
parent a281d37fb4
commit 07a3142316
35 changed files with 191 additions and 169 deletions

View File

@@ -1,4 +1,4 @@
namespace SpaceGame.Simulation.Api.Contracts; namespace SpaceGame.Api.Contracts;
public sealed record StarSnapshot( public sealed record StarSnapshot(
string Kind, string Kind,

View File

@@ -1,4 +1,4 @@
namespace SpaceGame.Simulation.Api.Contracts; namespace SpaceGame.Api.Contracts;
public sealed record Vector3Dto(float X, float Y, float Z); public sealed record Vector3Dto(float X, float Y, float Z);

View File

@@ -1,4 +1,4 @@
namespace SpaceGame.Simulation.Api.Contracts; namespace SpaceGame.Api.Contracts;
public sealed record MarketOrderSnapshot( public sealed record MarketOrderSnapshot(
string Id, string Id,

View File

@@ -1,4 +1,4 @@
namespace SpaceGame.Simulation.Api.Contracts; namespace SpaceGame.Api.Contracts;
public sealed record FactionGoapStateSnapshot( public sealed record FactionGoapStateSnapshot(
int MilitaryShipCount, int MilitaryShipCount,

View File

@@ -1,4 +1,4 @@
namespace SpaceGame.Simulation.Api.Contracts; namespace SpaceGame.Api.Contracts;
public sealed record InventoryEntry( public sealed record InventoryEntry(
string ItemId, string ItemId,

View File

@@ -1,4 +1,4 @@
namespace SpaceGame.Simulation.Api.Contracts; namespace SpaceGame.Api.Contracts;
public sealed record ShipSnapshot( public sealed record ShipSnapshot(
string Id, string Id,

View File

@@ -1,4 +1,4 @@
namespace SpaceGame.Simulation.Api.Contracts; namespace SpaceGame.Api.Contracts;
public sealed record WorldSnapshot( public sealed record WorldSnapshot(
string Label, string Label,

View File

@@ -1,6 +1,6 @@
using System.Text.Json.Serialization; using System.Text.Json.Serialization;
namespace SpaceGame.Simulation.Api.Data; namespace SpaceGame.Api.Data;
public sealed class ConstructionDefinition public sealed class ConstructionDefinition
{ {

View File

@@ -1,7 +1,7 @@
using FastEndpoints; using FastEndpoints;
using SpaceGame.Simulation.Api.Simulation; using SpaceGame.Api.Simulation;
namespace SpaceGame.Simulation.Api.Handlers; namespace SpaceGame.Api.Handlers;
public sealed class GetWorldHandler(WorldService worldService) : EndpointWithoutRequest public sealed class GetWorldHandler(WorldService worldService) : EndpointWithoutRequest
{ {

View File

@@ -1,7 +1,7 @@
using FastEndpoints; using FastEndpoints;
using SpaceGame.Simulation.Api.Simulation; using SpaceGame.Api.Simulation;
namespace SpaceGame.Simulation.Api.Handlers; namespace SpaceGame.Api.Handlers;
public sealed class GetWorldHealthHandler(WorldService worldService) : EndpointWithoutRequest public sealed class GetWorldHealthHandler(WorldService worldService) : EndpointWithoutRequest
{ {

View File

@@ -1,7 +1,7 @@
using FastEndpoints; using FastEndpoints;
using SpaceGame.Simulation.Api.Simulation; using SpaceGame.Api.Simulation;
namespace SpaceGame.Simulation.Api.Handlers; namespace SpaceGame.Api.Handlers;
public sealed class ResetWorldHandler(WorldService worldService) : EndpointWithoutRequest public sealed class ResetWorldHandler(WorldService worldService) : EndpointWithoutRequest
{ {

View File

@@ -1,6 +1,6 @@
using FastEndpoints; using FastEndpoints;
namespace SpaceGame.Simulation.Api.Handlers; namespace SpaceGame.Api.Handlers;
public sealed class RootRedirectHandler : EndpointWithoutRequest public sealed class RootRedirectHandler : EndpointWithoutRequest
{ {

View File

@@ -1,9 +1,9 @@
using System.Text.Json; using System.Text.Json;
using FastEndpoints; using FastEndpoints;
using SpaceGame.Simulation.Api.Contracts; using SpaceGame.Api.Contracts;
using SpaceGame.Simulation.Api.Simulation; using SpaceGame.Api.Simulation;
namespace SpaceGame.Simulation.Api.Handlers; namespace SpaceGame.Api.Handlers;
public sealed class StreamWorldHandler(WorldService worldService) : EndpointWithoutRequest public sealed class StreamWorldHandler(WorldService worldService) : EndpointWithoutRequest
{ {

View File

@@ -1,5 +1,5 @@
using FastEndpoints; using FastEndpoints;
using SpaceGame.Simulation.Api.Simulation; using SpaceGame.Api.Simulation;
var builder = WebApplication.CreateBuilder(args); var builder = WebApplication.CreateBuilder(args);

View File

@@ -1,4 +1,7 @@
namespace SpaceGame.Simulation.Api.Simulation; using SpaceGame.Api.Simulation.Engine;
using SpaceGame.Api.Simulation.Model;
namespace SpaceGame.Api.Simulation.AI;
// ─── Planning State ──────────────────────────────────────────────────────────── // ─── Planning State ────────────────────────────────────────────────────────────

View File

@@ -1,4 +1,7 @@
namespace SpaceGame.Simulation.Api.Simulation; using SpaceGame.Api.Simulation.Engine;
using SpaceGame.Api.Simulation.Model;
namespace SpaceGame.Api.Simulation.AI;
public abstract class GoapAction<TState> public abstract class GoapAction<TState>
{ {

View File

@@ -1,10 +1,13 @@
namespace SpaceGame.Simulation.Api.Simulation; using SpaceGame.Api.Simulation.Engine;
using SpaceGame.Api.Simulation.Model;
namespace SpaceGame.Api.Simulation.AI;
internal interface IShipBehaviorState internal interface IShipBehaviorState
{ {
string Kind { get; } string Kind { get; }
void Plan(SimulationEngine engine, ShipRuntime ship, SimulationWorld world); void Plan(SimulationEngine engine, ShipRuntime ship, SimulationWorld world);
void ApplyEvent(SimulationEngine engine, ShipRuntime ship, SimulationWorld world, string controllerEvent); void ApplyEvent(SimulationEngine engine, ShipRuntime ship, SimulationWorld world, string controllerEvent);
} }

View File

@@ -1,38 +1,41 @@
namespace SpaceGame.Simulation.Api.Simulation; using SpaceGame.Api.Simulation.Engine;
using SpaceGame.Api.Simulation.Model;
namespace SpaceGame.Api.Simulation.AI;
internal sealed class ShipBehaviorStateMachine internal sealed class ShipBehaviorStateMachine
{ {
private readonly IReadOnlyDictionary<string, IShipBehaviorState> states; private readonly IReadOnlyDictionary<string, IShipBehaviorState> states;
private readonly IShipBehaviorState fallbackState; private readonly IShipBehaviorState fallbackState;
private ShipBehaviorStateMachine(IReadOnlyDictionary<string, IShipBehaviorState> states, IShipBehaviorState fallbackState) private ShipBehaviorStateMachine(IReadOnlyDictionary<string, IShipBehaviorState> states, IShipBehaviorState fallbackState)
{ {
this.states = states; this.states = states;
this.fallbackState = fallbackState; this.fallbackState = fallbackState;
} }
public static ShipBehaviorStateMachine CreateDefault() public static ShipBehaviorStateMachine CreateDefault()
{
var idleState = new IdleShipBehaviorState();
var knownStates = new IShipBehaviorState[]
{ {
var idleState = new IdleShipBehaviorState();
var knownStates = new IShipBehaviorState[]
{
idleState, idleState,
new PatrolShipBehaviorState(), new PatrolShipBehaviorState(),
new ResourceHarvestShipBehaviorState("auto-mine", "ore", "mining"), new ResourceHarvestShipBehaviorState("auto-mine", "ore", "mining"),
new ConstructStationShipBehaviorState(), new ConstructStationShipBehaviorState(),
}; };
return new ShipBehaviorStateMachine( return new ShipBehaviorStateMachine(
knownStates.ToDictionary(state => state.Kind, StringComparer.Ordinal), knownStates.ToDictionary(state => state.Kind, StringComparer.Ordinal),
idleState); idleState);
} }
public void Plan(SimulationEngine engine, ShipRuntime ship, SimulationWorld world) => public void Plan(SimulationEngine engine, ShipRuntime ship, SimulationWorld world) =>
Resolve(ship.DefaultBehavior.Kind).Plan(engine, ship, world); Resolve(ship.DefaultBehavior.Kind).Plan(engine, ship, world);
public void ApplyEvent(SimulationEngine engine, ShipRuntime ship, SimulationWorld world, string controllerEvent) => public void ApplyEvent(SimulationEngine engine, ShipRuntime ship, SimulationWorld world, string controllerEvent) =>
Resolve(ship.DefaultBehavior.Kind).ApplyEvent(engine, ship, world, controllerEvent); Resolve(ship.DefaultBehavior.Kind).ApplyEvent(engine, ship, world, controllerEvent);
private IShipBehaviorState Resolve(string kind) => private IShipBehaviorState Resolve(string kind) =>
states.TryGetValue(kind, out var state) ? state : fallbackState; states.TryGetValue(kind, out var state) ? state : fallbackState;
} }

View File

@@ -1,4 +1,7 @@
namespace SpaceGame.Simulation.Api.Simulation; using SpaceGame.Api.Simulation.Engine;
using SpaceGame.Api.Simulation.Model;
namespace SpaceGame.Api.Simulation.AI;
internal sealed class IdleShipBehaviorState : IShipBehaviorState internal sealed class IdleShipBehaviorState : IShipBehaviorState
{ {

View File

@@ -1,4 +1,7 @@
namespace SpaceGame.Simulation.Api.Simulation; using SpaceGame.Api.Simulation.Engine;
using SpaceGame.Api.Simulation.Model;
namespace SpaceGame.Api.Simulation.AI;
// ─── Planning State ──────────────────────────────────────────────────────────── // ─── Planning State ────────────────────────────────────────────────────────────

View File

@@ -1,30 +1,30 @@
namespace SpaceGame.Simulation.Api.Simulation; namespace SpaceGame.Api.Simulation.Model;
public sealed class MarketOrderRuntime public sealed class MarketOrderRuntime
{ {
public required string Id { get; init; } public required string Id { get; init; }
public required string FactionId { get; init; } public required string FactionId { get; init; }
public string? StationId { get; init; } public string? StationId { get; init; }
public string? ConstructionSiteId { get; init; } public string? ConstructionSiteId { get; init; }
public required string Kind { get; init; } public required string Kind { get; init; }
public required string ItemId { get; init; } public required string ItemId { get; init; }
public float Amount { get; init; } public float Amount { get; init; }
public float RemainingAmount { get; set; } public float RemainingAmount { get; set; }
public float Valuation { get; set; } public float Valuation { get; set; }
public float? ReserveThreshold { get; set; } public float? ReserveThreshold { get; set; }
public string? PolicySetId { get; set; } public string? PolicySetId { get; set; }
public string State { get; set; } = MarketOrderStateKinds.Open; public string State { get; set; } = MarketOrderStateKinds.Open;
public string LastDeltaSignature { get; set; } = string.Empty; public string LastDeltaSignature { get; set; } = string.Empty;
} }
public sealed class PolicySetRuntime public sealed class PolicySetRuntime
{ {
public required string Id { get; init; } public required string Id { get; init; }
public required string OwnerKind { get; init; } public required string OwnerKind { get; init; }
public required string OwnerId { get; init; } public required string OwnerId { get; init; }
public string TradeAccessPolicy { get; set; } = "owner-and-allies"; public string TradeAccessPolicy { get; set; } = "owner-and-allies";
public string DockingAccessPolicy { get; set; } = "owner-and-allies"; public string DockingAccessPolicy { get; set; } = "owner-and-allies";
public string ConstructionAccessPolicy { get; set; } = "owner-only"; public string ConstructionAccessPolicy { get; set; } = "owner-only";
public string OperationalRangePolicy { get; set; } = "unrestricted"; public string OperationalRangePolicy { get; set; } = "unrestricted";
public string LastDeltaSignature { get; set; } = string.Empty; public string LastDeltaSignature { get; set; } = string.Empty;
} }

View File

@@ -1,36 +1,36 @@
namespace SpaceGame.Simulation.Api.Simulation; namespace SpaceGame.Api.Simulation.Model;
public sealed class ClaimRuntime public sealed class ClaimRuntime
{ {
public required string Id { get; init; } public required string Id { get; init; }
public required string FactionId { get; init; } public required string FactionId { get; init; }
public required string SystemId { get; init; } public required string SystemId { get; init; }
public required string CelestialId { get; init; } public required string CelestialId { get; init; }
public string? CommanderId { get; set; } public string? CommanderId { get; set; }
public DateTimeOffset PlacedAtUtc { get; init; } public DateTimeOffset PlacedAtUtc { get; init; }
public DateTimeOffset ActivatesAtUtc { get; set; } public DateTimeOffset ActivatesAtUtc { get; set; }
public string State { get; set; } = ClaimStateKinds.Placed; public string State { get; set; } = ClaimStateKinds.Placed;
public float Health { get; set; } public float Health { get; set; }
public string LastDeltaSignature { get; set; } = string.Empty; public string LastDeltaSignature { get; set; } = string.Empty;
} }
public sealed class ConstructionSiteRuntime public sealed class ConstructionSiteRuntime
{ {
public required string Id { get; init; } public required string Id { get; init; }
public required string FactionId { get; init; } public required string FactionId { get; init; }
public required string SystemId { get; init; } public required string SystemId { get; init; }
public required string CelestialId { get; init; } public required string CelestialId { get; init; }
public required string TargetKind { get; init; } public required string TargetKind { get; init; }
public required string TargetDefinitionId { get; init; } public required string TargetDefinitionId { get; init; }
public string? BlueprintId { get; set; } public string? BlueprintId { get; set; }
public string? ClaimId { get; set; } public string? ClaimId { get; set; }
public string? StationId { get; set; } public string? StationId { get; set; }
public Dictionary<string, float> Inventory { get; } = new(StringComparer.Ordinal); public Dictionary<string, float> Inventory { get; } = new(StringComparer.Ordinal);
public Dictionary<string, float> RequiredItems { get; } = new(StringComparer.Ordinal); public Dictionary<string, float> RequiredItems { get; } = new(StringComparer.Ordinal);
public Dictionary<string, float> DeliveredItems { get; } = new(StringComparer.Ordinal); public Dictionary<string, float> DeliveredItems { get; } = new(StringComparer.Ordinal);
public HashSet<string> AssignedConstructorShipIds { get; } = new(StringComparer.Ordinal); public HashSet<string> AssignedConstructorShipIds { get; } = new(StringComparer.Ordinal);
public HashSet<string> MarketOrderIds { get; } = new(StringComparer.Ordinal); public HashSet<string> MarketOrderIds { get; } = new(StringComparer.Ordinal);
public float Progress { get; set; } public float Progress { get; set; }
public string State { get; set; } = ConstructionSiteStateKinds.Planned; public string State { get; set; } = ConstructionSiteStateKinds.Planned;
public string LastDeltaSignature { get; set; } = string.Empty; public string LastDeltaSignature { get; set; } = string.Empty;
} }

View File

@@ -1,73 +1,75 @@
namespace SpaceGame.Simulation.Api.Simulation; using SpaceGame.Api.Simulation.AI;
namespace SpaceGame.Api.Simulation.Model;
public sealed class FactionRuntime public sealed class FactionRuntime
{ {
public required string Id { get; init; } public required string Id { get; init; }
public required string Label { get; init; } public required string Label { get; init; }
public required string Color { get; init; } public required string Color { get; init; }
public float Credits { get; set; } public float Credits { get; set; }
public float PopulationTotal { get; set; } public float PopulationTotal { get; set; }
public float OreMined { get; set; } public float OreMined { get; set; }
public float GoodsProduced { get; set; } public float GoodsProduced { get; set; }
public int ShipsBuilt { get; set; } public int ShipsBuilt { get; set; }
public int ShipsLost { get; set; } public int ShipsLost { get; set; }
public HashSet<string> CommanderIds { get; } = new(StringComparer.Ordinal); public HashSet<string> CommanderIds { get; } = new(StringComparer.Ordinal);
public string? DefaultPolicySetId { get; set; } public string? DefaultPolicySetId { get; set; }
public string LastDeltaSignature { get; set; } = string.Empty; public string LastDeltaSignature { get; set; } = string.Empty;
} }
public sealed class CommanderRuntime public sealed class CommanderRuntime
{ {
public required string Id { get; init; } public required string Id { get; init; }
public required string Kind { get; set; } public required string Kind { get; set; }
public required string FactionId { get; init; } public required string FactionId { get; init; }
public string? ParentCommanderId { get; set; } public string? ParentCommanderId { get; set; }
public string? ControlledEntityId { get; set; } public string? ControlledEntityId { get; set; }
public string? PolicySetId { get; set; } public string? PolicySetId { get; set; }
public string? Doctrine { get; set; } public string? Doctrine { get; set; }
public List<string> Goals { get; } = []; public List<string> Goals { get; } = [];
public HashSet<string> ActiveDirectives { get; } = new(StringComparer.Ordinal); public HashSet<string> ActiveDirectives { get; } = new(StringComparer.Ordinal);
public string? ActiveGoalName { get; set; } public string? ActiveGoalName { get; set; }
public string? ActiveActionName { get; set; } public string? ActiveActionName { get; set; }
public float ReplanTimer { get; set; } public float ReplanTimer { get; set; }
public bool NeedsReplan { get; set; } = true; public bool NeedsReplan { get; set; } = true;
public CommanderBehaviorRuntime? ActiveBehavior { get; set; } public CommanderBehaviorRuntime? ActiveBehavior { get; set; }
public CommanderOrderRuntime? ActiveOrder { get; set; } public CommanderOrderRuntime? ActiveOrder { get; set; }
public CommanderTaskRuntime? ActiveTask { get; set; } public CommanderTaskRuntime? ActiveTask { get; set; }
public HashSet<string> SubordinateCommanderIds { get; } = new(StringComparer.Ordinal); public HashSet<string> SubordinateCommanderIds { get; } = new(StringComparer.Ordinal);
public bool IsAlive { get; set; } = true; public bool IsAlive { get; set; } = true;
public FactionPlanningState? LastPlanningState { get; set; } public FactionPlanningState? LastPlanningState { get; set; }
public IReadOnlyList<(string Name, float Priority)>? LastGoalPriorities { get; set; } public IReadOnlyList<(string Name, float Priority)>? LastGoalPriorities { get; set; }
} }
public sealed class CommanderBehaviorRuntime public sealed class CommanderBehaviorRuntime
{ {
public required string Kind { get; set; } public required string Kind { get; set; }
public string? Phase { get; set; } public string? Phase { get; set; }
public string? NodeId { get; set; } public string? NodeId { get; set; }
public string? StationId { get; set; } public string? StationId { get; set; }
public string? ModuleId { get; set; } public string? ModuleId { get; set; }
public string? AreaSystemId { get; set; } public string? AreaSystemId { get; set; }
public int PatrolIndex { get; set; } public int PatrolIndex { get; set; }
} }
public sealed class CommanderOrderRuntime public sealed class CommanderOrderRuntime
{ {
public required string Kind { get; init; } public required string Kind { get; init; }
public OrderStatus Status { get; set; } = OrderStatus.Accepted; public OrderStatus Status { get; set; } = OrderStatus.Accepted;
public string? TargetEntityId { get; set; } public string? TargetEntityId { get; set; }
public string? DestinationNodeId { get; set; } public string? DestinationNodeId { get; set; }
public required string DestinationSystemId { get; init; } public required string DestinationSystemId { get; init; }
public required Vector3 DestinationPosition { get; init; } public required Vector3 DestinationPosition { get; init; }
} }
public sealed class CommanderTaskRuntime public sealed class CommanderTaskRuntime
{ {
public required string Kind { get; set; } public required string Kind { get; set; }
public WorkStatus Status { get; set; } = WorkStatus.Pending; public WorkStatus Status { get; set; } = WorkStatus.Pending;
public string? TargetEntityId { get; set; } public string? TargetEntityId { get; set; }
public string? TargetSystemId { get; set; } public string? TargetSystemId { get; set; }
public string? TargetNodeId { get; set; } public string? TargetNodeId { get; set; }
public Vector3? TargetPosition { get; set; } public Vector3? TargetPosition { get; set; }
public float Threshold { get; set; } public float Threshold { get; set; }
} }

View File

@@ -1,6 +1,6 @@
using SpaceGame.Simulation.Api.Data; using SpaceGame.Api.Data;
namespace SpaceGame.Simulation.Api.Simulation; namespace SpaceGame.Api.Simulation.Model;
public sealed class ShipRuntime public sealed class ShipRuntime
{ {

View File

@@ -1,4 +1,4 @@
namespace SpaceGame.Simulation.Api.Simulation; namespace SpaceGame.Api.Simulation.Model;
public enum SpatialNodeKind public enum SpatialNodeKind
{ {

View File

@@ -1,4 +1,4 @@
namespace SpaceGame.Simulation.Api.Simulation; namespace SpaceGame.Api.Simulation.Model;
public static class SimulationUnits public static class SimulationUnits
{ {

View File

@@ -1,6 +1,6 @@
using SpaceGame.Simulation.Api.Data; using SpaceGame.Api.Data;
namespace SpaceGame.Simulation.Api.Simulation; namespace SpaceGame.Api.Simulation.Model;
public sealed class SimulationWorld public sealed class SimulationWorld
{ {

View File

@@ -1,6 +1,6 @@
using SpaceGame.Simulation.Api.Data; using SpaceGame.Api.Data;
namespace SpaceGame.Simulation.Api.Simulation; namespace SpaceGame.Api.Simulation.Model;
public sealed class SystemRuntime public sealed class SystemRuntime
{ {

View File

@@ -1,4 +1,4 @@
namespace SpaceGame.Simulation.Api.Simulation; namespace SpaceGame.Api.Simulation.Model;
public sealed class StationRuntime public sealed class StationRuntime
{ {

View File

@@ -1,4 +1,4 @@
namespace SpaceGame.Simulation.Api.Simulation; namespace SpaceGame.Api.Simulation.Model;
public readonly record struct Vector3(float X, float Y, float Z) public readonly record struct Vector3(float X, float Y, float Z)
{ {

View File

@@ -1,4 +1,4 @@
namespace SpaceGame.Simulation.Api.Simulation; namespace SpaceGame.Api.Simulation;
public sealed class OrbitalSimulationOptions public sealed class OrbitalSimulationOptions
{ {

View File

@@ -1,4 +1,4 @@
namespace SpaceGame.Simulation.Api.Simulation; namespace SpaceGame.Api.Simulation;
public sealed class SimulationHostedService(WorldService worldService) : BackgroundService public sealed class SimulationHostedService(WorldService worldService) : BackgroundService
{ {

View File

@@ -1,4 +1,4 @@
namespace SpaceGame.Simulation.Api.Simulation; namespace SpaceGame.Api.Simulation;
public sealed class WorldGenerationOptions public sealed class WorldGenerationOptions
{ {

View File

@@ -1,8 +1,10 @@
using System.Threading.Channels; using System.Threading.Channels;
using Microsoft.Extensions.Options; using Microsoft.Extensions.Options;
using SpaceGame.Simulation.Api.Contracts; using SpaceGame.Api.Contracts;
using SpaceGame.Api.Simulation.Engine;
using SpaceGame.Api.Simulation.Model;
namespace SpaceGame.Simulation.Api.Simulation; namespace SpaceGame.Api.Simulation;
public sealed class WorldService( public sealed class WorldService(
IWebHostEnvironment environment, IWebHostEnvironment environment,
@@ -11,7 +13,7 @@ public sealed class WorldService(
{ {
private const int DeltaHistoryLimit = 256; private const int DeltaHistoryLimit = 256;
private readonly object _sync = new(); private readonly Lock _sync = new();
private readonly OrbitalSimulationSnapshot _orbitalSimulation = new(orbitalSimulationOptions.Value.SimulatedSecondsPerRealSecond); private readonly OrbitalSimulationSnapshot _orbitalSimulation = new(orbitalSimulationOptions.Value.SimulatedSecondsPerRealSecond);
private readonly ScenarioLoader _loader = new(environment.ContentRootPath, worldGenerationOptions.Value); private readonly ScenarioLoader _loader = new(environment.ContentRootPath, worldGenerationOptions.Value);
private readonly SimulationEngine _engine = new(orbitalSimulationOptions.Value); private readonly SimulationEngine _engine = new(orbitalSimulationOptions.Value);