Refactor world bootstrap and allow empty startup worlds
This commit is contained in:
165
apps/backend/Universe/Simulation/BalanceService.cs
Normal file
165
apps/backend/Universe/Simulation/BalanceService.cs
Normal file
@@ -0,0 +1,165 @@
|
||||
using Microsoft.Extensions.Options;
|
||||
|
||||
namespace SpaceGame.Api.Universe.Simulation;
|
||||
|
||||
public sealed class BalanceService : IBalanceService
|
||||
{
|
||||
private readonly Lock _sync = new();
|
||||
private BalanceOptions _current;
|
||||
|
||||
public BalanceService(IOptions<BalanceOptions> defaults)
|
||||
{
|
||||
_current = Sanitize(defaults.Value);
|
||||
}
|
||||
|
||||
public float SimulationSpeedMultiplier
|
||||
{
|
||||
get
|
||||
{
|
||||
lock (_sync)
|
||||
{
|
||||
return _current.SimulationSpeedMultiplier;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public float YPlane
|
||||
{
|
||||
get
|
||||
{
|
||||
lock (_sync)
|
||||
{
|
||||
return _current.YPlane;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public float ArrivalThreshold
|
||||
{
|
||||
get
|
||||
{
|
||||
lock (_sync)
|
||||
{
|
||||
return _current.ArrivalThreshold;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public float MiningRate
|
||||
{
|
||||
get
|
||||
{
|
||||
lock (_sync)
|
||||
{
|
||||
return _current.MiningRate;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public float MiningCycleSeconds
|
||||
{
|
||||
get
|
||||
{
|
||||
lock (_sync)
|
||||
{
|
||||
return _current.MiningCycleSeconds;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public float TransferRate
|
||||
{
|
||||
get
|
||||
{
|
||||
lock (_sync)
|
||||
{
|
||||
return _current.TransferRate;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public float DockingDuration
|
||||
{
|
||||
get
|
||||
{
|
||||
lock (_sync)
|
||||
{
|
||||
return _current.DockingDuration;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public float UndockingDuration
|
||||
{
|
||||
get
|
||||
{
|
||||
lock (_sync)
|
||||
{
|
||||
return _current.UndockingDuration;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public float UndockDistance
|
||||
{
|
||||
get
|
||||
{
|
||||
lock (_sync)
|
||||
{
|
||||
return _current.UndockDistance;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public BalanceOptions GetCurrent()
|
||||
{
|
||||
lock (_sync)
|
||||
{
|
||||
return Clone(_current);
|
||||
}
|
||||
}
|
||||
|
||||
public BalanceOptions Update(BalanceOptions candidate)
|
||||
{
|
||||
lock (_sync)
|
||||
{
|
||||
_current = Sanitize(candidate);
|
||||
return Clone(_current);
|
||||
}
|
||||
}
|
||||
|
||||
private static BalanceOptions Clone(BalanceOptions value)
|
||||
{
|
||||
return new BalanceOptions
|
||||
{
|
||||
SimulationSpeedMultiplier = value.SimulationSpeedMultiplier,
|
||||
YPlane = value.YPlane,
|
||||
ArrivalThreshold = value.ArrivalThreshold,
|
||||
MiningRate = value.MiningRate,
|
||||
MiningCycleSeconds = value.MiningCycleSeconds,
|
||||
TransferRate = value.TransferRate,
|
||||
DockingDuration = value.DockingDuration,
|
||||
UndockingDuration = value.UndockingDuration,
|
||||
UndockDistance = value.UndockDistance,
|
||||
};
|
||||
}
|
||||
|
||||
private static BalanceOptions Sanitize(BalanceOptions candidate)
|
||||
{
|
||||
static float finiteOr(float value, float fallback) =>
|
||||
float.IsFinite(value) ? value : fallback;
|
||||
|
||||
return new BalanceOptions
|
||||
{
|
||||
SimulationSpeedMultiplier = MathF.Max(0.01f, finiteOr(candidate.SimulationSpeedMultiplier, 1f)),
|
||||
YPlane = MathF.Max(0f, finiteOr(candidate.YPlane, 0f)),
|
||||
ArrivalThreshold = MathF.Max(0.1f, finiteOr(candidate.ArrivalThreshold, 16f)),
|
||||
MiningRate = MathF.Max(0f, finiteOr(candidate.MiningRate, 10f)),
|
||||
MiningCycleSeconds = MathF.Max(0.1f, finiteOr(candidate.MiningCycleSeconds, 10f)),
|
||||
TransferRate = MathF.Max(0f, finiteOr(candidate.TransferRate, 56f)),
|
||||
DockingDuration = MathF.Max(0.1f, finiteOr(candidate.DockingDuration, 1.2f)),
|
||||
UndockingDuration = MathF.Max(0.1f, finiteOr(candidate.UndockingDuration, 1.2f)),
|
||||
UndockDistance = MathF.Max(0f, finiteOr(candidate.UndockDistance, 42f)),
|
||||
};
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user