Task 0 baseline cleanup. Removes the temporary A8 step-disable diag toggles (A8Diag* properties + ACDREAM_A8_DIAG_* env reads) that the A8 batch left behind in RuntimeOptions, and unwraps their guards in GameWindow.RenderInsideOutAcdream so every guarded draw (Step 2 punch, Step 3 EnvCell-opaque + IndoorPass, Step 4 terrain + outdoor scenery, portal depth-clamp) now runs unconditionally. RuntimeOptionsTests drops the matching assertions. The ACDREAM_PROBE_VIS apparatus (EmitDrawOrderProbe / EmitStencilProbe / EmitBuildingsProbe / EmitEnvCellProbe) is preserved untouched. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
102 lines
4.4 KiB
C#
102 lines
4.4 KiB
C#
using System;
|
|
using System.Globalization;
|
|
|
|
namespace AcDream.App;
|
|
|
|
/// <summary>
|
|
/// Typed bundle of startup-time configuration read from the process
|
|
/// environment. Built once in <c>Program.cs</c> and passed to
|
|
/// <c>GameWindow</c> so the rest of the app reads its config through
|
|
/// strongly-typed fields instead of scattered
|
|
/// <c>Environment.GetEnvironmentVariable</c> calls.
|
|
/// </summary>
|
|
/// <remarks>
|
|
/// <para>
|
|
/// <strong>Scope:</strong> startup-time only — values that don't change
|
|
/// once the window is up. Runtime diagnostic toggles
|
|
/// (e.g. <c>ACDREAM_DUMP_MOTION</c>, <c>ACDREAM_PROBE_*</c>) belong in
|
|
/// diagnostic owner classes (see <c>AcDream.Core.Physics.PhysicsDiagnostics</c>
|
|
/// for the template), not here.
|
|
/// </para>
|
|
/// <para>
|
|
/// See <c>docs/architecture/code-structure.md</c> §2 Rule 4 for the
|
|
/// rule that drove this extraction, and §4 Step 1 for the broader
|
|
/// extraction sequence this is the first cut of.
|
|
/// </para>
|
|
/// </remarks>
|
|
public sealed record RuntimeOptions(
|
|
string DatDir,
|
|
bool LiveMode,
|
|
string LiveHost,
|
|
int LivePort,
|
|
string? LiveUser,
|
|
string? LivePass,
|
|
bool DevTools,
|
|
bool DumpMoveTruth,
|
|
bool NoAudio,
|
|
bool EnableSkyPesDebug,
|
|
int HidePartIndex,
|
|
bool RetailCloseDegrades,
|
|
bool DumpSceneryZ,
|
|
bool DumpLiveSpawns,
|
|
int? LegacyStreamRadius)
|
|
{
|
|
/// <summary>
|
|
/// Build options from the process environment. Used by
|
|
/// <c>Program.cs</c> at startup.
|
|
/// </summary>
|
|
public static RuntimeOptions FromEnvironment(string datDir)
|
|
=> Parse(datDir, Environment.GetEnvironmentVariable);
|
|
|
|
/// <summary>
|
|
/// Build options from a custom environment getter. Used by tests to
|
|
/// inject controlled env values without touching the process
|
|
/// environment.
|
|
/// </summary>
|
|
/// <param name="datDir">Resolved dat-file directory.</param>
|
|
/// <param name="env">Function returning the value for an env-var
|
|
/// name, or <c>null</c> when unset.</param>
|
|
public static RuntimeOptions Parse(string datDir, Func<string, string?> env)
|
|
{
|
|
if (datDir is null) throw new ArgumentNullException(nameof(datDir));
|
|
if (env is null) throw new ArgumentNullException(nameof(env));
|
|
|
|
return new RuntimeOptions(
|
|
DatDir: datDir,
|
|
LiveMode: IsExactlyOne(env("ACDREAM_LIVE")),
|
|
LiveHost: env("ACDREAM_TEST_HOST") ?? "127.0.0.1",
|
|
LivePort: TryParseInt(env("ACDREAM_TEST_PORT")) ?? 9000,
|
|
LiveUser: NullIfEmpty(env("ACDREAM_TEST_USER")),
|
|
LivePass: NullIfEmpty(env("ACDREAM_TEST_PASS")),
|
|
DevTools: IsExactlyOne(env("ACDREAM_DEVTOOLS")),
|
|
DumpMoveTruth: IsExactlyOne(env("ACDREAM_DUMP_MOVE_TRUTH")),
|
|
NoAudio: IsExactlyOne(env("ACDREAM_NO_AUDIO")),
|
|
EnableSkyPesDebug: IsExactlyOne(env("ACDREAM_ENABLE_SKY_PES")),
|
|
HidePartIndex: TryParseInt(env("ACDREAM_HIDE_PART")) ?? -1,
|
|
// Default-on: any value other than the literal string "0" enables
|
|
// retail close-detail degrades. Set ACDREAM_RETAIL_CLOSE_DEGRADES=0
|
|
// only for before/after diagnostic comparisons.
|
|
RetailCloseDegrades: !string.Equals(env("ACDREAM_RETAIL_CLOSE_DEGRADES"), "0", StringComparison.Ordinal),
|
|
DumpSceneryZ: IsExactlyOne(env("ACDREAM_DUMP_SCENERY_Z")),
|
|
DumpLiveSpawns: IsExactlyOne(env("ACDREAM_DUMP_LIVE_SPAWNS")),
|
|
// Legacy override for ACDREAM_STREAM_RADIUS. Caller applies it on
|
|
// top of the quality preset's radii. Null when unset or invalid.
|
|
LegacyStreamRadius: TryParseNonNegativeInt(env("ACDREAM_STREAM_RADIUS")));
|
|
}
|
|
|
|
/// <summary>True iff live-mode credentials are present and valid for connecting.</summary>
|
|
public bool HasLiveCredentials =>
|
|
LiveMode && !string.IsNullOrEmpty(LiveUser) && !string.IsNullOrEmpty(LivePass);
|
|
|
|
private static bool IsExactlyOne(string? s)
|
|
=> string.Equals(s, "1", StringComparison.Ordinal);
|
|
|
|
private static string? NullIfEmpty(string? s)
|
|
=> string.IsNullOrEmpty(s) ? null : s;
|
|
|
|
private static int? TryParseInt(string? s)
|
|
=> int.TryParse(s, NumberStyles.Integer, CultureInfo.InvariantCulture, out var v) ? v : null;
|
|
|
|
private static int? TryParseNonNegativeInt(string? s)
|
|
=> TryParseInt(s) is { } v && v >= 0 ? v : null;
|
|
}
|