81 lines
3.3 KiB
C#
81 lines
3.3 KiB
C#
namespace HSchool.Simulation;
|
||
|
||
/// <summary>Tunables of the authoritative simulation. Bound from the <c>Simulation</c> config section.</summary>
|
||
public sealed class SimulationOptions
|
||
{
|
||
public const string SectionName = "Simulation";
|
||
|
||
private DateTime _defaultStartDate = new(2012, 3, 31, 6, 0, 0, DateTimeKind.Utc);
|
||
|
||
/// <summary>Fixed simulation steps per second.</summary>
|
||
public int TickRate { get; set; } = 20;
|
||
|
||
/// <summary>How many schools one player may own at the same time.</summary>
|
||
public int MaxSchools { get; set; } = 2;
|
||
|
||
/// <summary>How many school workers the process may run at once.</summary>
|
||
public int MaxSchoolsTotal { get; set; } = 16;
|
||
|
||
/// <summary>Base speed of the game clock: real seconds are multiplied by this many game minutes.</summary>
|
||
public double GameMinutesPerRealSecond { get; set; } = 1d;
|
||
|
||
/// <summary>Prefilled start of a new school; the client shows it in the creation form.</summary>
|
||
public DateTime DefaultStartDate
|
||
{
|
||
get => _defaultStartDate;
|
||
|
||
// Configuration binding yields Kind=Unspecified, which serializes without a "Z" and makes
|
||
// the browser read the date in its own time zone. The game calendar is always UTC.
|
||
set => _defaultStartDate = DateTime.SpecifyKind(value, DateTimeKind.Utc);
|
||
}
|
||
|
||
/// <summary>
|
||
/// Directory for per-school save files. Relative paths are resolved against the content root.
|
||
/// </summary>
|
||
public string SavesDirectory { get; set; } = "saves";
|
||
|
||
/// <summary>
|
||
/// Directory of mod packs (<c>core</c> and optional add-ons). Relative paths are resolved
|
||
/// against the content root.
|
||
/// </summary>
|
||
public string ModsDirectory { get; set; } = "mods";
|
||
|
||
/// <summary>
|
||
/// How often a running school writes its clock to disk. Create and shutdown write
|
||
/// immediately; the tick itself never does.
|
||
/// </summary>
|
||
public int SaveIntervalSeconds { get; set; } = 30;
|
||
|
||
/// <summary>
|
||
/// Shortest gap between two saves caused by pause or speed. A client can send those as fast
|
||
/// as the socket allows, and each one used to be a file write on the school's own thread.
|
||
/// </summary>
|
||
public int MinSaveIntervalMilliseconds { get; set; } = 1000;
|
||
|
||
/// <summary>
|
||
/// Monthly payroll the player may commit. Hire and subject assignment that would exceed it
|
||
/// are rejected immediately; money itself does not move.
|
||
/// </summary>
|
||
public float MonthlyPayrollCap { get; set; } = 100_000f;
|
||
|
||
/// <summary>
|
||
/// How many people may change destination in one tick. Overflow waits for the next tick
|
||
/// instead of being dropped — a queue, not a cutoff.
|
||
/// </summary>
|
||
public int MaxDecisionsPerTick { get; set; } = 64;
|
||
|
||
/// <summary>
|
||
/// Working days from Monday. Five is Mon–Fri; six adds Saturday; seven is every day.
|
||
/// </summary>
|
||
public int SchoolWeekDays { get; set; } = 5;
|
||
|
||
/// <summary>Length of one fixed step.</summary>
|
||
public double FixedDeltaTime => 1d / TickRate;
|
||
|
||
public TimeSpan TickInterval => TimeSpan.FromSeconds(1d / TickRate);
|
||
|
||
public TimeSpan SaveInterval => TimeSpan.FromSeconds(SaveIntervalSeconds);
|
||
|
||
public TimeSpan MinSaveInterval => TimeSpan.FromMilliseconds(MinSaveIntervalMilliseconds);
|
||
}
|