chore: add .editorconfig and consistent formatting for backend projects
Adds an `.editorconfig` file with C# and project-specific conventions. Applies consistent indentation and formatting across backend handlers, runtime models, and AI services.
This commit is contained in:
@@ -3,146 +3,146 @@ namespace SpaceGame.Api.Simulation.Core;
|
||||
|
||||
public sealed class SimulationEngine
|
||||
{
|
||||
private readonly OrbitalSimulationOptions _orbitalSimulation;
|
||||
private readonly OrbitalStateUpdater _orbitalStateUpdater;
|
||||
private readonly InfrastructureSimulationService _infrastructureSimulation;
|
||||
private readonly GeopoliticalSimulationService _geopolitics;
|
||||
private readonly CommanderPlanningService _commanderPlanning;
|
||||
private readonly PlayerFactionService _playerFaction;
|
||||
private readonly StationSimulationService _stationSimulation;
|
||||
private readonly StationLifecycleService _stationLifecycle;
|
||||
private readonly ShipAiService _shipAi;
|
||||
private readonly SimulationProjectionService _projection;
|
||||
private readonly OrbitalSimulationOptions _orbitalSimulation;
|
||||
private readonly OrbitalStateUpdater _orbitalStateUpdater;
|
||||
private readonly InfrastructureSimulationService _infrastructureSimulation;
|
||||
private readonly GeopoliticalSimulationService _geopolitics;
|
||||
private readonly CommanderPlanningService _commanderPlanning;
|
||||
private readonly PlayerFactionService _playerFaction;
|
||||
private readonly StationSimulationService _stationSimulation;
|
||||
private readonly StationLifecycleService _stationLifecycle;
|
||||
private readonly ShipAiService _shipAi;
|
||||
private readonly SimulationProjectionService _projection;
|
||||
|
||||
public SimulationEngine(OrbitalSimulationOptions? orbitalSimulation = null)
|
||||
{
|
||||
_orbitalSimulation = orbitalSimulation ?? new OrbitalSimulationOptions();
|
||||
_orbitalStateUpdater = new OrbitalStateUpdater(_orbitalSimulation);
|
||||
_infrastructureSimulation = new InfrastructureSimulationService();
|
||||
_geopolitics = new GeopoliticalSimulationService();
|
||||
_commanderPlanning = new CommanderPlanningService();
|
||||
_playerFaction = new PlayerFactionService();
|
||||
_stationSimulation = new StationSimulationService();
|
||||
_stationLifecycle = new StationLifecycleService(_stationSimulation);
|
||||
_shipAi = new ShipAiService();
|
||||
_projection = new SimulationProjectionService(_orbitalSimulation);
|
||||
}
|
||||
|
||||
public WorldDelta Tick(SimulationWorld world, float deltaSeconds, long sequence)
|
||||
{
|
||||
var nowUtc = DateTimeOffset.UtcNow;
|
||||
var events = new List<SimulationEventRecord>();
|
||||
var simulationDeltaSeconds = deltaSeconds * MathF.Max(world.Balance.SimulationSpeedMultiplier, 0.01f);
|
||||
world.GeneratedAtUtc = nowUtc;
|
||||
|
||||
world.OrbitalTimeSeconds += simulationDeltaSeconds * _orbitalSimulation.SimulatedSecondsPerRealSecond;
|
||||
|
||||
_orbitalStateUpdater.Update(world);
|
||||
_infrastructureSimulation.UpdateClaims(world, events);
|
||||
_infrastructureSimulation.UpdateConstructionSites(world, events);
|
||||
_geopolitics.Update(world, simulationDeltaSeconds, events);
|
||||
_commanderPlanning.UpdateCommanders(world, simulationDeltaSeconds, events);
|
||||
_playerFaction.Update(world, simulationDeltaSeconds, events);
|
||||
_stationLifecycle.UpdateStations(world, simulationDeltaSeconds, events);
|
||||
|
||||
foreach (var ship in world.Ships.ToList())
|
||||
public SimulationEngine(OrbitalSimulationOptions? orbitalSimulation = null)
|
||||
{
|
||||
if (ship.Health <= 0f)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var previousPosition = ship.Position;
|
||||
_shipAi.UpdateShip(world, ship, simulationDeltaSeconds, events);
|
||||
ship.Velocity = ship.Position.Subtract(previousPosition).Divide(simulationDeltaSeconds);
|
||||
_orbitalSimulation = orbitalSimulation ?? new OrbitalSimulationOptions();
|
||||
_orbitalStateUpdater = new OrbitalStateUpdater(_orbitalSimulation);
|
||||
_infrastructureSimulation = new InfrastructureSimulationService();
|
||||
_geopolitics = new GeopoliticalSimulationService();
|
||||
_commanderPlanning = new CommanderPlanningService();
|
||||
_playerFaction = new PlayerFactionService();
|
||||
_stationSimulation = new StationSimulationService();
|
||||
_stationLifecycle = new StationLifecycleService(_stationSimulation);
|
||||
_shipAi = new ShipAiService();
|
||||
_projection = new SimulationProjectionService(_orbitalSimulation);
|
||||
}
|
||||
|
||||
_orbitalStateUpdater.SyncSpatialState(world);
|
||||
CleanupDestroyedEntities(world, events);
|
||||
return _projection.BuildDelta(world, sequence, events);
|
||||
}
|
||||
|
||||
public WorldSnapshot BuildSnapshot(SimulationWorld world, long sequence) =>
|
||||
_projection.BuildSnapshot(world, sequence);
|
||||
|
||||
public void PrimeDeltaBaseline(SimulationWorld world) =>
|
||||
_projection.PrimeDeltaBaseline(world);
|
||||
|
||||
internal static float GetShipCargoAmount(ShipRuntime ship) =>
|
||||
SimulationRuntimeSupport.GetShipCargoAmount(ship);
|
||||
|
||||
private static void CleanupDestroyedEntities(SimulationWorld world, ICollection<SimulationEventRecord> events)
|
||||
{
|
||||
foreach (var ship in world.Ships.Where(candidate => candidate.Health <= 0f).ToList())
|
||||
public WorldDelta Tick(SimulationWorld world, float deltaSeconds, long sequence)
|
||||
{
|
||||
CreateWreck(world, "ship", ship.Id, ship.SystemId, ship.Position, ship.Definition.CargoCapacity + (ship.Definition.MaxHealth * 0.08f));
|
||||
world.Ships.Remove(ship);
|
||||
if (ship.DockedStationId is not null && world.Stations.FirstOrDefault(station => station.Id == ship.DockedStationId) is { } dockedStation)
|
||||
{
|
||||
dockedStation.DockedShipIds.Remove(ship.Id);
|
||||
dockedStation.DockingPadAssignments.Remove(ship.AssignedDockingPadIndex ?? -1);
|
||||
}
|
||||
var nowUtc = DateTimeOffset.UtcNow;
|
||||
var events = new List<SimulationEventRecord>();
|
||||
var simulationDeltaSeconds = deltaSeconds * MathF.Max(world.Balance.SimulationSpeedMultiplier, 0.01f);
|
||||
world.GeneratedAtUtc = nowUtc;
|
||||
|
||||
if (world.Factions.FirstOrDefault(candidate => candidate.Id == ship.FactionId) is { } faction)
|
||||
{
|
||||
faction.ShipsLost += 1;
|
||||
}
|
||||
world.OrbitalTimeSeconds += simulationDeltaSeconds * _orbitalSimulation.SimulatedSecondsPerRealSecond;
|
||||
|
||||
if (ship.CommanderId is not null && world.Commanders.FirstOrDefault(candidate => candidate.Id == ship.CommanderId) is { } commander)
|
||||
{
|
||||
commander.IsAlive = false;
|
||||
}
|
||||
_orbitalStateUpdater.Update(world);
|
||||
_infrastructureSimulation.UpdateClaims(world, events);
|
||||
_infrastructureSimulation.UpdateConstructionSites(world, events);
|
||||
_geopolitics.Update(world, simulationDeltaSeconds, events);
|
||||
_commanderPlanning.UpdateCommanders(world, simulationDeltaSeconds, events);
|
||||
_playerFaction.Update(world, simulationDeltaSeconds, events);
|
||||
_stationLifecycle.UpdateStations(world, simulationDeltaSeconds, events);
|
||||
|
||||
events.Add(new SimulationEventRecord("ship", ship.Id, "destroyed", $"{ship.Definition.Label} was destroyed.", DateTimeOffset.UtcNow));
|
||||
foreach (var ship in world.Ships.ToList())
|
||||
{
|
||||
if (ship.Health <= 0f)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var previousPosition = ship.Position;
|
||||
_shipAi.UpdateShip(world, ship, simulationDeltaSeconds, events);
|
||||
ship.Velocity = ship.Position.Subtract(previousPosition).Divide(simulationDeltaSeconds);
|
||||
}
|
||||
|
||||
_orbitalStateUpdater.SyncSpatialState(world);
|
||||
CleanupDestroyedEntities(world, events);
|
||||
return _projection.BuildDelta(world, sequence, events);
|
||||
}
|
||||
|
||||
foreach (var station in world.Stations.Where(candidate => candidate.Health <= 0f).ToList())
|
||||
public WorldSnapshot BuildSnapshot(SimulationWorld world, long sequence) =>
|
||||
_projection.BuildSnapshot(world, sequence);
|
||||
|
||||
public void PrimeDeltaBaseline(SimulationWorld world) =>
|
||||
_projection.PrimeDeltaBaseline(world);
|
||||
|
||||
internal static float GetShipCargoAmount(ShipRuntime ship) =>
|
||||
SimulationRuntimeSupport.GetShipCargoAmount(ship);
|
||||
|
||||
private static void CleanupDestroyedEntities(SimulationWorld world, ICollection<SimulationEventRecord> events)
|
||||
{
|
||||
CreateWreck(world, "station", station.Id, station.SystemId, station.Position, station.MaxHealth * 0.12f);
|
||||
world.Stations.Remove(station);
|
||||
foreach (var ship in world.Ships.Where(candidate => candidate.Health <= 0f).ToList())
|
||||
{
|
||||
CreateWreck(world, "ship", ship.Id, ship.SystemId, ship.Position, ship.Definition.CargoCapacity + (ship.Definition.MaxHealth * 0.08f));
|
||||
world.Ships.Remove(ship);
|
||||
if (ship.DockedStationId is not null && world.Stations.FirstOrDefault(station => station.Id == ship.DockedStationId) is { } dockedStation)
|
||||
{
|
||||
dockedStation.DockedShipIds.Remove(ship.Id);
|
||||
dockedStation.DockingPadAssignments.Remove(ship.AssignedDockingPadIndex ?? -1);
|
||||
}
|
||||
|
||||
if (station.CelestialId is not null && world.Celestials.FirstOrDefault(candidate => candidate.Id == station.CelestialId) is { } celestial)
|
||||
{
|
||||
celestial.OccupyingStructureId = null;
|
||||
}
|
||||
if (world.Factions.FirstOrDefault(candidate => candidate.Id == ship.FactionId) is { } faction)
|
||||
{
|
||||
faction.ShipsLost += 1;
|
||||
}
|
||||
|
||||
foreach (var claim in world.Claims.Where(candidate => candidate.CelestialId == station.CelestialId))
|
||||
{
|
||||
claim.Health = 0f;
|
||||
claim.State = ClaimStateKinds.Destroyed;
|
||||
}
|
||||
if (ship.CommanderId is not null && world.Commanders.FirstOrDefault(candidate => candidate.Id == ship.CommanderId) is { } commander)
|
||||
{
|
||||
commander.IsAlive = false;
|
||||
}
|
||||
|
||||
foreach (var site in world.ConstructionSites.Where(candidate => candidate.StationId == station.Id))
|
||||
{
|
||||
site.State = ConstructionSiteStateKinds.Destroyed;
|
||||
}
|
||||
events.Add(new SimulationEventRecord("ship", ship.Id, "destroyed", $"{ship.Definition.Label} was destroyed.", DateTimeOffset.UtcNow));
|
||||
}
|
||||
|
||||
events.Add(new SimulationEventRecord("station", station.Id, "destroyed", $"{station.Label} was destroyed.", DateTimeOffset.UtcNow));
|
||||
}
|
||||
}
|
||||
foreach (var station in world.Stations.Where(candidate => candidate.Health <= 0f).ToList())
|
||||
{
|
||||
CreateWreck(world, "station", station.Id, station.SystemId, station.Position, station.MaxHealth * 0.12f);
|
||||
world.Stations.Remove(station);
|
||||
|
||||
private static void CreateWreck(SimulationWorld world, string sourceKind, string sourceEntityId, string systemId, Vector3 position, float amount)
|
||||
{
|
||||
var itemId = world.ItemDefinitions.ContainsKey("scrapmetal")
|
||||
? "scrapmetal"
|
||||
: world.ItemDefinitions.ContainsKey("rawscrap")
|
||||
? "rawscrap"
|
||||
: world.ItemDefinitions.Keys.OrderBy(id => id, StringComparer.Ordinal).FirstOrDefault();
|
||||
if (itemId is null || amount <= 0.01f)
|
||||
{
|
||||
return;
|
||||
if (station.CelestialId is not null && world.Celestials.FirstOrDefault(candidate => candidate.Id == station.CelestialId) is { } celestial)
|
||||
{
|
||||
celestial.OccupyingStructureId = null;
|
||||
}
|
||||
|
||||
foreach (var claim in world.Claims.Where(candidate => candidate.CelestialId == station.CelestialId))
|
||||
{
|
||||
claim.Health = 0f;
|
||||
claim.State = ClaimStateKinds.Destroyed;
|
||||
}
|
||||
|
||||
foreach (var site in world.ConstructionSites.Where(candidate => candidate.StationId == station.Id))
|
||||
{
|
||||
site.State = ConstructionSiteStateKinds.Destroyed;
|
||||
}
|
||||
|
||||
events.Add(new SimulationEventRecord("station", station.Id, "destroyed", $"{station.Label} was destroyed.", DateTimeOffset.UtcNow));
|
||||
}
|
||||
}
|
||||
|
||||
world.Wrecks.Add(new WreckRuntime
|
||||
private static void CreateWreck(SimulationWorld world, string sourceKind, string sourceEntityId, string systemId, Vector3 position, float amount)
|
||||
{
|
||||
Id = $"wreck-{sourceKind}-{sourceEntityId}",
|
||||
SourceKind = sourceKind,
|
||||
SourceEntityId = sourceEntityId,
|
||||
SystemId = systemId,
|
||||
Position = position,
|
||||
ItemId = itemId,
|
||||
RemainingAmount = amount,
|
||||
MaxAmount = amount,
|
||||
});
|
||||
}
|
||||
var itemId = world.ItemDefinitions.ContainsKey("scrapmetal")
|
||||
? "scrapmetal"
|
||||
: world.ItemDefinitions.ContainsKey("rawscrap")
|
||||
? "rawscrap"
|
||||
: world.ItemDefinitions.Keys.OrderBy(id => id, StringComparer.Ordinal).FirstOrDefault();
|
||||
if (itemId is null || amount <= 0.01f)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
world.Wrecks.Add(new WreckRuntime
|
||||
{
|
||||
Id = $"wreck-{sourceKind}-{sourceEntityId}",
|
||||
SourceKind = sourceKind,
|
||||
SourceEntityId = sourceEntityId,
|
||||
SystemId = systemId,
|
||||
Position = position,
|
||||
ItemId = itemId,
|
||||
RemainingAmount = amount,
|
||||
MaxAmount = amount,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user