The client reads 161 ACDREAM_* environment variables across 79 files. Only about 25 were written down, and the audit found the documentation drifting in both directions: CLAUDE.md still advertised ACDREAM_RUN_SKILL / ACDREAM_JUMP_SKILL (deleted; skills are server-authoritative now, and the jump fallback is 300, not the documented 200), while flags with real side effects had no description at all. docs/launch-options.md documents every one by lifecycle — production, command line, measurement, automation, permanent diagnostics, temporary probes, deprecated, retired — with a mandatory side-effects column. That column is the point: #432 cost three days of taxed measurements because ACDREAM_AUTOMATION_ARTIFACT_DIR reads like an output path and also builds a per-frame diagnostics referee, and ACDREAM_STREAM_RADIUS silently measures a streaming window production never uses. Rows now say so. Other surprises the audit surfaced and recorded: ACDREAM_DUMP_SCENERY_Z swaps in a duplicate scenery-placement path rather than only logging, ACDREAM_PROBE_VIS silently also enables ACDREAM_PROBE_ENVCELL, and ACDREAM_DUMP_ENTITY's id list doubles as an unrelated probe's watchlist. LaunchOptionsDocumentationTests enforces it, because a hand-maintained list of 161 flags is stale within a week: an undocumented flag fails, and so does a documented row whose read site was deleted. It scans string literals rather than GetEnvironmentVariable call shapes — the startup path reads through an injected delegate, so a call-shaped pattern silently missed ACDREAM_LIVE, ACDREAM_PAK_PATH and every other production flag. A third test freezes per-file direct-read debt by exact count (20 files outside the owner classes), so structure rules 4 and 5 can be paid down but not regressed. CLAUDE.md's 94-line env-var section becomes a 16-line pointer, and its stale test-character paragraph is corrected. Also fixed, all doc-vs-code mismatches the audit proved: - RenderingDiagnostics.FrameProfEnabled described a GPU-query self-disable that Campaign V slice V11 deleted. - Two comments named ACDREAM_RENDER_BACKEND as a live co-requisite; it died with the OpenGL backend. - EnvCellRenderer.CollectCellAuditLines and its ACDREAM_A8_AUDIT doc: the method had no caller anywhere and its documented caller never existed. Filed rather than fixed, to keep this a documentation change: #434 (the DebugPanel/DebugVM surface is never constructed, so ~40 "runtime-toggleable" comments are false and 35 env reads are unreachable) and #435 (17 temporary probes outlived their closed investigations; 14 more name no owner). Full hermetic suite 12,202 passed / 0 failed. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
88 KiB
acdream launch options — operator reference
Every environment variable and command-line argument the acdream client reads, what it does, and what else it changes about the run.
This is an operator's reference, not user documentation. Players never set these: the launcher owns installation and login, and the in-client Options panel (F11) owns settings. If a flag here looks like something a player would want, that is a signal it belongs in the Options panel, not a signal to document it better.
How to use this document
- Running the client for yourself? Read Production launch and stop.
- Taking a measurement? Read Production launch, then read the Side effects column of every flag you are about to set. A flag that changes what you are measuring is the normal case, not the exception.
- Adding a flag? Add its row in the same commit.
LaunchOptionsDocumentationTestsfails the build otherwise — in both directions, so deleting a read site without deleting its row fails too.
Why the side-effects column exists
Two flags in this list were believed to be inert and were not:
ACDREAM_AUTOMATION_ARTIFACT_DIRreads like an output path. It also constructs a per-frame diagnostics referee that re-enabled a retired render pass, costing ~6 MB and ~14 ms every frame — three days of performance measurements were silently taxed before anyone noticed (#432).ACDREAM_STREAM_RADIUSreads like a radius knob. It forces the near radius, only ever raises the far radius, and is then silently discarded by any later quality apply — so a measurement taken with it set is measuring a window production never uses.
Assume a flag has a side effect until its row says otherwise.
Conventions
=1means the code tests for exactly the string1. Settingtrue,yes, or0does not enable such a flag (and0does not disable one whose test is "is the variable present").- Default is the behavior when the variable is unset.
- Kind is one of:
| Kind | Meaning |
|---|---|
production |
Ordinary configuration; safe in a real run. |
measurement |
Profiling/instrumentation. Read the side effects before trusting numbers taken with it on. |
automation |
Drives scripted runs; usually implies extra machinery. |
permanent-probe |
A diagnostic toggle owned by a subsystem's diagnostics class. Expected to persist. |
temporary-probe |
Tied to an open investigation. Deleted with its issue — never build tooling on one. |
deprecated |
Superseded. Do not use for new work. |
Production launch
The canonical connected launch against a local ACE server. PowerShell, because the DAT path contains an apostrophe:
$env:ACDREAM_DAT_DIR = "$env:USERPROFILE\Documents\Asheron's Call"
$env:ACDREAM_LIVE = "1"
$env:ACDREAM_TEST_HOST = "127.0.0.1"
$env:ACDREAM_TEST_PORT = "9000"
$env:ACDREAM_TEST_USER = "testaccount"
$env:ACDREAM_TEST_PASS = "testpassword"
$env:ACDREAM_RETAIL_UI = "1"
dotnet run --project src\AcDream.App\AcDream.App.csproj --no-build -c Release
| Flag | Value | What it does | Side effects | Default | Read by |
|---|---|---|---|---|---|
ACDREAM_A2C |
unset/"" keep preset; "0"/"false"/"False"/"FALSE" → off; any other non-empty → on |
Overrides preset's AlphaToCoverage blend flag |
Changes MSAA alpha-to-coverage blending mode for foliage/translucent draws — a visual-behavior change, not just perf | preset's AlphaToCoverage (High/Ultra=true, Low/Medium=false) |
QualitySettings.WithEnvOverrides (QualityPreset.cs:52) |
ACDREAM_AC_DIR |
=<path> |
Points at a real retail AC install dir; loads <dir>/controls/controls.ini to source retail keybind display strings for the retained UI. |
Only has any effect when ACDREAM_RETAIL_UI=1 (retained UI composed). Unset → ControlsIni.Parse(string.Empty), an empty (not error) controls table — silent, no fallback file is searched. |
unset (null) → empty controls table | RuntimeOptions.AcDir → InteractionRetainedUiComposition.cs:610 |
ACDREAM_ANISOTROPIC |
=<int> (int.TryParse, invariant) |
Overrides preset's AnisotropicLevel texture filtering |
Changes GPU texture sampling filter level (visual sharpness), not just perf | preset's AnisotropicLevel (Low=4, Medium=8, High/Ultra=16) |
QualitySettings.WithEnvOverrides (QualityPreset.cs:49) |
ACDREAM_CACHE_DIR |
=<path> |
Overrides the resolved cache-root directory (used for DiagnosticsDirectory, etc.) |
none beyond redirecting cache I/O | Windows: %LOCALAPPDATA%\acdream\cache; Linux: $XDG_CACHE_HOME/acdream or ~/.cache/acdream |
ApplicationPathSet.Resolve (ApplicationPathSet.cs:83), via IApplicationPathEnvironment seam |
ACDREAM_CAMERA_ALIGN_SLOPE |
=0 disables (anything else/unset = on) |
selects whether the chase camera basis tilts to the player's 5-frame averaged velocity vs staying flat/horizontal on slopes | alters camera orientation / rendered view every frame; startup-only in practice (its DebugPanel/DebugVM mirror is unreachable — #434) | true (on) | AcDream.Core.Rendering.CameraDiagnostics.AlignToSlope |
ACDREAM_CAMERA_COLLIDE |
=0 disables (anything else/unset = on) |
selects whether the chase camera sweeps a 0.3 m collision sphere from head-pivot to eye and stops at the first wall (retail spring-arm) | alters camera position every frame (camera can clip into geometry when disabled); startup-only | true (on) | CameraDiagnostics.CollideCamera |
ACDREAM_CONFIG_DIR |
=<path> |
Overrides the resolved config-root directory (settings.json, keybinds.json) |
none beyond redirecting config I/O | Windows: %APPDATA%\acdream; Linux: $XDG_CONFIG_HOME/acdream or ~/.config/acdream |
ApplicationPathSet.Resolve (ApplicationPathSet.cs:79), via IApplicationPathEnvironment seam |
ACDREAM_DATA_DIR |
=<path> |
Overrides the resolved data-root directory (logs, screenshots, plugins) | none beyond redirecting data I/O | Windows: %LOCALAPPDATA%\acdream; Linux: $XDG_DATA_HOME/acdream or ~/.local/share/acdream |
ApplicationPathSet.Resolve (ApplicationPathSet.cs:81), via IApplicationPathEnvironment seam |
ACDREAM_DAT_DIR |
=<path> |
Fallback dat-directory when no positional argument is given. App: single read at Program.cs:58. Cli: read independently per-subcommand (each subcommand does args.ElementAtOrDefault(N) ?? Env.GetEnvironmentVariable("ACDREAM_DAT_DIR")) plus once more for the default (no-subcommand) asset-inventory mode at line 152. |
Two of the four Program.cs line numbers in the raw grep (91, 135) are not reads — they're the literal string ACDREAM_DAT_DIR inside Log.Error usage-text messages, not GetEnvironmentVariable calls. Only line 58 is a real read in AcDream.App. |
none — hard usage error (exit 2) if unset and no positional arg | Program.cs:58 (App); Cli/Program.cs:24,35,47,59,71,84,113,125,137,152 (every Cli subcommand) |
ACDREAM_DISPLAY_PROTOCOL |
="auto" / "x11" / "wayland" (case-insensitive, trimmed); any other value throws InvalidOperationException at startup |
Linux-only: forces the GLFW 3.4 platform-init hint (X11 vs Wayland vs auto) before any window is created; ignored entirely on Windows (always Windows protocol) |
An invalid value is fatal at startup (throws before any window exists), not a silent fallback | unset → auto-detected from XDG_SESSION_TYPE/WAYLAND_DISPLAY/DISPLAY, falling back to GLFW Automatic |
GraphicalWindowBackendSelection.Resolve (GraphicalWindowBackendSelection.cs:26-58) |
ACDREAM_FAR_RADIUS |
=<int> |
Overrides preset's FarRadius (outer streaming/reveal window, landblocks) |
Enlarging changes streaming memory budget and what's resident/rendered — CLAUDE.md: leave unset for measurement/gate runs (same family as legacy ACDREAM_STREAM_RADIUS) |
preset's FarRadius (Low=5, Medium=8, High=12, Ultra=15) |
QualitySettings.WithEnvOverrides (QualityPreset.cs:47) |
ACDREAM_LIVE |
=1 (exactly the literal string "1") |
Core switch: connect to a live ACE server instead of running offline/no-connect. | The 4 non-RuntimeOptions.cs line numbers in the raw grep are all comments or log-message text, not reads — SessionStartComposition.cs:39 is inside the string "live: ACDREAM_LIVE set but TEST_USER/TEST_PASS missing; skipping"; Program.cs:126 is inside a --session-config override log line; GameWindow.cs:614,627 are doc comments. The only actual parse is RuntimeOptions.cs:141. Requires ACDREAM_TEST_USER/ACDREAM_TEST_PASS too (HasLiveCredentials) or the session silently reports MissingCredentials and skips. Forced to effectively-on (LiveMode=true) unconditionally by --session-config launches regardless of this var. |
false |
RuntimeOptions.LiveMode → SessionStartComposition.cs (log text only), Program.cs:126 (log text only), GameWindow.cs:614,627 (comments only), consumed for real via RuntimeOptions.HasLiveCredentials and WorldSession/GameRuntime session-start gating |
ACDREAM_MAX_COMPLETIONS_PER_FRAME |
=<int> |
Overrides preset's per-frame streaming-completion throughput cap | Directly changes the streaming admission budget measured by perf/completion gates — do not vary during a measurement run | preset's value (Low=2, Medium=3, High=4, Ultra=6) | QualitySettings.WithEnvOverrides (QualityPreset.cs:59) |
ACDREAM_MSAA_SAMPLES |
=<int> (0/2/4/8) |
Overrides preset's MSAA sample count | Changes GPU multisample anti-aliasing (visual + GPU-cost change) | preset's MsaaSamples (Low=0, Medium=2, High/Ultra=4) |
QualitySettings.WithEnvOverrides (QualityPreset.cs:48) |
ACDREAM_NEAR_RADIUS |
=<int> |
Overrides preset's NearRadius (inner streaming ring radius) |
Changes the streaming/render window size — CLAUDE.md: leave unset for measurement/gate runs | preset's NearRadius (Low=2, Medium=3, High=4, Ultra=5) |
QualitySettings.WithEnvOverrides (QualityPreset.cs:46) |
ACDREAM_NO_AUDIO |
=1 |
Suppresses OpenAL device init entirely (headless / driver-broken machines). | Fail-open design: even without this flag, a missing/broken OpenAL driver already makes IsAvailable=false and all Play* calls no-ops — this flag is the explicit, deliberate version of the same fallback. When set, LiveSessionWorldRuntime.WorldAudio is null and logout-audio reset/resume steps no-op. |
false |
RuntimeOptions.NoAudio → GameWindow.cs:1430 → ContentEffectsAudioCompositionPhase → OpenAlAudioEngine.cs (fail-open doc), LiveSessionRuntimeFactory.cs:71 (WorldAudio gate) |
ACDREAM_PAK_PATH |
=<path> |
Overrides the path to the prepared machine-local asset bake (acdream.pak) that production world-mesh streaming reads through IPreparedAssetSource. |
none beyond the obvious | unset → <datDir>/acdream.pak |
RuntimeOptions.PreparedAssetPath → ContentEffectsAudioComposition.cs:53,372,379, GameWindow.cs:1420 |
ACDREAM_RESIDENCY_ALPHA_SCRATCH_MIB |
=<int MiB> (>0, else default; overflow-checked) |
Byte ceiling for the retail alpha (translucency) draw queue's scratch buffer | Shrinking below production working set changes translucency-queue eviction/reflow behavior — not comparable to a default-budget perf run | 16 MiB | ResidencyBudgetOptions.Parse (ResidencyBudgetOptions.cs:88-89), flows through RuntimeOptions.ResidencyBudgets→AlphaScratchBudgetProfile.Create→RetailAlphaQueue ctor (GameWindow.cs:721-725) |
ACDREAM_RESIDENCY_ANIMATION_ENTRIES |
=<int> (>0, else default) |
Entry-count ceiling for the retained animation-data cache | Changes cache eviction cadence for animation data — a perf/memory measurement under a non-default value is not representative | 512 | ResidencyBudgetOptions.Parse (:82-84) |
ACDREAM_RESIDENCY_ANIMATION_MIB |
=<int MiB> (>0, else default) |
Byte ceiling for the retained animation-data cache | Same cache-behavior-change caveat as the entries variant | 64 MiB | ResidencyBudgetOptions.Parse (:79-81) |
ACDREAM_RESIDENCY_AUDIO_MIB |
=<int MiB> (>0, else default) |
Byte ceiling for the retained audio-buffer cache | Shrinking can force more frequent audio buffer re-decode/eviction | 32 MiB | ResidencyBudgetOptions.Parse (:85-87), consumed by ContentEffectsAudioComposition.cs |
ACDREAM_RESIDENCY_COMPOSITE_PHYSICAL_MIB |
=<int MiB> (>0, else default) |
Byte ceiling for physically-resident composite (character palette/texture) GPU memory | Changes composite-texture eviction pressure — not representative of production if varied during a measurement run | 128 MiB | ResidencyBudgetOptions.Parse (:67-69), consumed by TextureCache.cs |
ACDREAM_RESIDENCY_COMPOSITE_UNOWNED_MIB |
=<int MiB> (>0, else default) |
Byte ceiling for unowned/retained (not currently referenced) composite textures kept for reuse | Same eviction-pressure caveat | 64 MiB | ResidencyBudgetOptions.Parse (:70-72), consumed by TextureCache.cs |
ACDREAM_RESIDENCY_MESH_GPU_MIB |
=<int MiB> (>0, else default) |
Byte ceiling for GPU-resident object mesh data | The single largest residency budget (1024 MiB default) — shrinking it directly forces more mesh re-upload/eviction; do not vary during an FPS/GPU-memory measurement run | 1024 MiB | ResidencyBudgetOptions.Parse (:49-51), consumed by ObjectMeshManager.cs/WbDrawDispatcher.cs |
ACDREAM_RESIDENCY_MESH_STAGING_ENTRIES |
=<int> (>0, else default) |
Entry-count ceiling for the mesh upload staging cache | Changes staging-buffer churn/eviction cadence | 256 | ResidencyBudgetOptions.Parse (:64-66) |
ACDREAM_RESIDENCY_MESH_STAGING_MIB |
=<int MiB> (>0, else default) |
Byte ceiling for the mesh upload staging cache | Same staging-churn caveat | 128 MiB | ResidencyBudgetOptions.Parse (:61-63) |
ACDREAM_RESIDENCY_MESH_UNOWNED_ENTRIES |
=<int> (>0, else default) |
Entry-count ceiling for unowned (retained-for-reuse) object mesh entries | Changes mesh-cache eviction cadence | 50 | ResidencyBudgetOptions.Parse (:52-54) |
ACDREAM_RESIDENCY_PREPARED_MESH_ENTRIES |
=<int> (>0, else default) |
Entry-count ceiling for the CPU-side "prepared mesh" cache (post-classification, pre-upload) | Changes eviction cadence for prepared-mesh CPU memory | 100 | ResidencyBudgetOptions.Parse (:58-60) |
ACDREAM_RESIDENCY_PREPARED_MESH_MIB |
=<int MiB> (>0, else default) |
Byte ceiling for the CPU-side prepared-mesh cache | Same eviction-cadence caveat | 128 MiB | ResidencyBudgetOptions.Parse (:55-57) |
ACDREAM_RESIDENCY_STANDALONE_UNOWNED_ENTRIES |
=<int> (>0, else default) |
Entry-count ceiling for unowned standalone (non-composite) texture entries | Changes standalone-texture eviction cadence | 256 | ResidencyBudgetOptions.Parse (:76-78), consumed by TextureCache.cs |
ACDREAM_RESIDENCY_STANDALONE_UNOWNED_MIB |
=<int MiB> (>0, else default) |
Byte ceiling for unowned standalone texture memory | Same eviction-cadence caveat | 32 MiB | ResidencyBudgetOptions.Parse (:73-75) |
ACDREAM_RETAIL_CHASE |
=0 disables (anything else/unset = on) |
selects the retail-faithful RetailChaseCamera vs. the legacy rigid-follow ChaseCamera |
swaps the entire active camera implementation — changes camera motion/feel; startup-only in practice (its DebugPanel/DebugVM mirror is unreachable — #434) | true (retail camera on) | CameraDiagnostics.UseRetailChaseCamera |
ACDREAM_RETAIL_CLOSE_DEGRADES |
inverted: ="0" disables; any other value (incl. unset) enables |
Default-on real gameplay behavior: applies retail's close-range LOD mesh-part swap (GfxObjDegradeResolver) to humanoid setups (issue #47), matching retail's close-detail degrade. |
Inverted default (opposite of every other boolean flag in this table — presence of the literal string "0" is what disables it, not presence of "1" enabling it). Documented explicitly as "set only for before/after diagnostic comparisons" — so although default-on production behavior, its disable path exists purely for A/B measurement. |
true (enabled) unless value is exactly "0" |
RuntimeOptions.RetailCloseDegrades → DatLiveEntityProjectionMaterializer.cs:275-276,480-498 |
ACDREAM_RETAIL_UI |
=1 |
Switches on the retained retail UI host tree (UiHost/UiRoot, D.2b). Without it, no retained UI is composed at all — e.g. no chargen Appearance page, no Summary page. |
Forced to true unconditionally for every --session-config / launcher launch (RuntimeOptions.cs:282, "a session-config launch IS a product launch — the retail UI is the shipped UI, not a dev option"), regardless of this env var's value — the env var only matters for the bare env-var dev-flow launch path. |
false for the env-var dev flow; true always for --session-config launches |
RuntimeOptions.RetailUi → LivePresentationComposition.cs:1108-1131 (gates retained-UI mount via InteractionRetainedUiComposition), GameWindow.cs:455,566 (comments), RuntimeOptions.cs:277 |
ACDREAM_TEST_HOST |
=<host> |
ACE server hostname for live-mode connect. | none | "127.0.0.1" |
RuntimeOptions.LiveHost (RuntimeOptions.cs:142) |
ACDREAM_TEST_PASS |
=<string> |
ACE account password for live-mode connect. | Redacted in RuntimeOptions.ToString()/diagnostic printing by design (PrintMembers override, RuntimeOptions.cs:326-342) — defense-in-depth so it can never leak into a log/exception via the record's default printing. |
null (empty → HasLiveCredentials false) |
RuntimeOptions.LivePass (RuntimeOptions.cs:145) |
ACDREAM_TEST_PORT |
=<int> |
ACE server port for live-mode connect. | none | 9000 |
RuntimeOptions.LivePort (RuntimeOptions.cs:143) |
ACDREAM_TEST_USER |
=<string> |
ACE account name for live-mode connect. | none | null (empty → HasLiveCredentials false) |
RuntimeOptions.LiveUser (RuntimeOptions.cs:144) |
ACDREAM_VULKAN_DEVICE |
=<int> (decimal index) or =<substring> (case-insensitive device-name match) |
Overrides automatic Vulkan physical-device selection (normally: discrete > integrated > virtual > CPU, tie-broken by device-local heap size) — for multi-GPU machines. | A bare-digits value is matched as an index ONLY (never falls through to substring match) specifically because digits like "7" are substrings of real device names ("AMD Radeon RX 9070 XT") — a fallback would silently select the wrong device by coincidence. An override matching nothing falls back to the automatic choice (does not fail startup) and records why in the capability report. |
null → automatic ranked choice |
RuntimeOptions.VulkanDeviceOverride → VulkanPhysicalDeviceSelection.Choose (VulkanPhysicalDeviceSelection.cs:54-100), consumed at VulkanGraphicsContext.cs:207,322 |
Command-line arguments
AcDream.App
| Arg | What it does | Side effects |
|---|---|---|
<dat-directory> (positional) |
Dat directory; outranks ACDREAM_DAT_DIR. |
Not read at all once --session-config is present. |
--session-config <path> |
The launcher's launch path: endpoint, account, credential reference, character selector, status file, plugins, login commands. | Overrides ACDREAM_LIVE and every ACDREAM_TEST_* (logged at startup). Diagnostic flags stay env-controlled. Missing value is a startup error. |
AcDream.Headless
Its usage banner matches the parser exactly. validate loads and checks a
config without connecting; run connects.
| Arg | What it does | Side effects |
|---|---|---|
validate | run (positional) |
Selects the mode; must be the first argument. | Anything else is a parse error. |
--config <path> |
The versioned headless session-configuration document. Required. | — |
--config-dir / --data-dir / --cache-dir <path> |
Override each portable path root. | Merged over the config document's own process.paths; the command line wins. |
-user / --user, -password / --password |
Direct single-session credentials, bypassing the config's credential source. | Plaintext in the process command line — prefer the config's credential reference. |
--help / -h (or no args) |
Prints usage, exits 0. | — |
AcDream.Launcher
| Arg | What it does | Side effects |
|---|---|---|
--verify-publish |
Packaging smoke probe: parses arguments and exits 0 without opening a display or resolving user paths. | — |
--config-dir / --data-dir / --cache-dir <absolute path> |
Override each path root. | All three or none — supplying a subset is an error. Must be absolute. |
--update-manifest-uri <uri> |
Points the self-updater at a different release manifest (test-feed seam). | Must be https:// (or loopback http://). Changes where updates come from — do not point a real install at a test feed. |
--acdream-self-update-helper-v1, --acdream-self-update-confirm-v1 |
Internal re-exec markers for the self-update handoff. | Not user-facing; never pass these by hand. |
AcDream.Cli
A dat-dump and measurement tool dispatched by a positional subcommand
(args[0]); no --flag options. Most subcommands take a dat directory and
fall back to ACDREAM_DAT_DIR.
- Measurement:
summarize-frame-history <frames.csv> <checkpoints.jsonl> <markers.log> <out.json>,compare-screenshots <expected.png> <actual.png> <out.json> [channelTolerance=2] [maxDifferentFraction=0.001] [mask.png],probe <in.png> <x0> <y0> <x1> <y1>. - Dat inspection: no subcommand (asset-type inventory),
dump-vitals-bars,dump-vitals-layout [0xLayoutId],list-ui-layouts [0xRootType],dump-sprite-sheet <0xId,...>,dump-font-atlas [0xFontId] [sample] [outBase],dump-edges <0xId>,export-ui-sprite <0xId> [out.png]. - Mockup rendering:
render-vitals-mockup [out.png],mock-selbar [out.png],crop <in.png> <x> <y> <w> <h> <zoom> <out.png>.
Measurement and profiling
| Flag | Value | What it does | Side effects | Default | Read by |
|---|---|---|---|---|---|
ACDREAM_CAPTURE_RESOLVE |
=<path> |
appends one JSON-Lines record (full before/after PhysicsBody snapshot) per player-side ResolveWithTransition call, filtered to IsPlayer movers |
real per-tick allocation (snapshot object graph + System.Text.Json serialize) and buffered file I/O (AutoFlush=false) for the local player only; will skew any perf measurement of local-player physics while active; feeds CellarUpTrajectoryReplayTests fixtures |
unset (off) | AcDream.Core.Physics.PhysicsResolveCapture (CapturePath) |
ACDREAM_COLLISION_SHADOW_DIR |
=<dir> |
output directory for Slice I5 graph/flat collision-shadow mismatch artifacts | only takes effect when ACDREAM_COLLISION_SHADOW_EVERY>0; directory creation + file writes on mismatch |
<CurrentDirectory>/.test-out/collision-shadow |
PhysicsDiagnostics.CollisionShadowArtifactDirectory |
ACDREAM_COLLISION_SHADOW_EVERY |
=<positive int> |
when >0 and the cache is constructed with requirePreparedCollision:false, arms a CollisionShadowVerifier that re-runs the graph-vs-flat collision referee every Nth traversal entry (PhysicsDataCache ctor) |
extra CPU on sampled ticks + mismatch-artifact file I/O; graph path stays authoritative regardless of mismatch (doc-asserted, not independently verified here) — does not change production physics results, but does add work when active | 0 (disabled) |
PhysicsDiagnostics.CollisionShadowSampleEvery (parsed via ParsePositiveInt, non-positive → 0) |
ACDREAM_DAY_GROUP |
=<int> |
Forces Dereth's day-group (weather preset) selection instead of the retail hash-based pick, "useful for visually A/B-testing each weather preset against retail" (own doc comment). | Dead second read: the SkyDescLoader.cs:252 raw read only feeds SelectDayGroupIndex, which is only called from ActiveDayGroup(double) and the DefaultDayGroup property — and grepping all of src/ finds zero production call sites for either. That whole path is unreachable; only the typed RuntimeOptions.ForcedDayGroupIndex → Runtime path is live. Bounds differ too: the typed path only checks >= 0 (TryParseNonNegativeInt) and Runtime clamps out-of-range to null; the dead Core-layer path checks forced >= 0 && forced < DayGroups.Count directly. SkyState.cs:400,403 are doc-comment mentions only, not reads. |
unset → normal server/date-driven hash selection | RuntimeOptions.ForcedDayGroupIndex (typed) → GameWindow.cs:718 → WorldEnvironmentController → RuntimeWorldEnvironmentState (Runtime, live path); also raw Environment.GetEnvironmentVariable at SkyDescLoader.cs:252 (Core layer, separate parse) |
ACDREAM_DISABLE_TIER1_CACHE |
="1" (ordinal exact match; anything else = enabled) |
A/B diagnostic that forces every static (non-animated) entity through the slow per-entity classification path, bypassing the Tier-1 classification cache (#53) |
Materially changes per-frame CPU cost for entity classification — a perf/FPS measurement taken with this set is NOT representative of production and must not be compared against a normal run | unset (cache enabled) | WbDrawDispatcher ctor field _tier1CacheDisabled (WbDrawDispatcher.cs:473-474) |
ACDREAM_FRAME_HISTORY |
=<path> |
opts into a per-frame CSV history capture (frame idx, timestamps, per-stage CPU us, GPU us, alloc bytes) alongside the aggregated 5 s [frame-prof] report |
allocates a List<FrameHistoryRecord> with ~131,072-record (~9 MiB) initial capacity, growing further for longer captures (~72 B/record, ~43 MB/hour at 165 fps) held in memory for the whole run; CSV write happens ONLY at Dispose/shutdown (no frame-thread I/O); only takes effect while ACDREAM_FRAME_PROF is ALSO on |
unset (off) | RenderingDiagnostics.FrameHistoryPath / AcDream.App.Diagnostics.FrameProfiler |
ACDREAM_ORBIT_DISTANCE_METERS |
=<float>, must be finite and >0 |
Diagnostic-only initial distance for the offline orbit camera, so deterministic renderer acceptance captures land inside a finite shadow reach. | Own doc comment: "used by deterministic renderer acceptance captures." Rejects non-finite/non-positive values silently (parses to null, camera default used). |
null (unset) → normal camera default |
RuntimeOptions.InitialOrbitDistanceMeters → GameWindow.cs:1412 → offline orbit-camera composition |
ACDREAM_ORBIT_PITCH_DEGREES |
=<float>, clamped [-89, 89] |
Diagnostic-only initial orbit camera elevation. | Values outside [-89,89] or non-finite are silently rejected (→ null, default kept) rather than clamped. |
null |
RuntimeOptions.InitialOrbitPitchDegrees → GameWindow.cs:1414 |
ACDREAM_ORBIT_YAW_DEGREES |
=<float>, must be finite |
Diagnostic-only initial orbit camera heading. | Non-finite values silently rejected (→ null). |
null |
RuntimeOptions.InitialOrbitYawDegrees → GameWindow.cs:1413 |
ACDREAM_PROBE_REVEAL_RADIUS |
=<int>=1 (unparsable or <1 → override absent; floor is 1, not 0) |
#280 A/B measurement probe: forces the OUTDOOR reveal gate to use this landblock radius instead of the derived streaming window (near radius clamped to it), so a route can be measured with the pre-#280 behavior (=1, old OutdoorNeighborhoodRadius) vs. current |
Changes what gets revealed, not just measured — genuinely resizes the reveal/visible window used by the live reveal gate. CLAUDE.md: "Leave it unset for any measurement or gate run — with it set you are measuring a different window than production." =0 is rejected by the parser specifically because it would hang the very A/B route it exists to measure (RequiredRenderRadius==0 fails invalid-readiness-shape). Not a user setting, not in Settings/RuntimeOptions, not persisted. |
unset (derivation in charge, no override) | StreamingDiagnostics.RevealRadiusOverride (StreamingDiagnostics.cs:25-27,76-80), applied by StreamingDiagnostics.ApplyRevealRadiusOverride |
ACDREAM_PROBE_WORLD_FRAME |
=1 |
gates one [world-frame] agree line per projected conversion in DatLiveEntityProjectionMaterializer, recording the world-frame center both LiveWorldOriginState (App) and Runtime's physics-state owner used (issue #283, "measurement only; it never gates placement") |
print-only | off | PhysicsDiagnostics.ProbeWorldFrameEnabled |
ACDREAM_SKY_PHASE_SECONDS |
=<float> (any finite value; negative accepted, taken mod 1 per axis) |
Campaign V slice V7 instrument-determinism pin: freezes the sky's cloud-sheet UV scroll to a fixed elapsed-seconds value instead of wall-clock time, so two launches of a differential/offline gate agree about cloud position. | Non-obvious dual effect: this ONE var pins TWO independently-designed clocks that happen to share a name-adjacent purpose — the sky renderer's cloud scroll (SkyRenderer.AnimationPhaseSecondsOverride) AND, since Campaign VM slice VM6, the atmospheric post-process graph's foliage-wind clock (_windClockSecondsOverride). A gate that only knows about "sky clouds" and sets this to freeze them will also freeze foliage-wind evolution — deliberately snapped-to-target on the first advance per an A6 review fix, but still a second surface a naive reader wouldn't expect this var to touch. Distinct from ACDREAM_DAY_GROUP/ACDREAM_WORLD_TIME, which pin the OTHER sky clock (day group/sun angle) — retail's clouds drift independently of the calendar date by design. |
null → wall-clock driven (every ordinary run) |
RuntimeOptions.SkyAnimationPhaseSeconds → SkyRenderer.cs:79,85 (cloud UV scroll) and AtmosphericPostProcessGraph.cs:560,586,671 (foliage-wind clock) |
ACDREAM_STREAM_WORK_COMPLETIONS |
=<int> (>0, else default) |
Per-frame ceiling on streaming completion admissions on the update thread | Class doc comment states explicitly: this whole ACDREAM_STREAM_WORK_* family "exists for A/B measurement only" — not a user/production setting. Directly changes streaming throughput per frame; do not compare a measurement taken with this set against a default run. |
64 | StreamingWorkBudgetOptions.Parse (StreamingWorkBudgetOptions.cs:56-58) |
ACDREAM_STREAM_WORK_CPU_MIB |
=<int MiB> (>0, else default) |
Per-frame ceiling on adopted (newly resident) CPU bytes on the update thread | A/B-measurement-only family; changes per-frame CPU admission budget | 8 MiB | StreamingWorkBudgetOptions.Parse (:59-61) |
ACDREAM_STREAM_WORK_DEST_RESERVE_PERCENT |
=<float percent>, exclusive 0 < x < 100, else default; stored as fraction (percent/100) |
Fraction of the per-frame work budget reserved for the active reveal destination lane vs. background streaming | A/B-measurement-only family; reallocates frame budget between destination-lane and background streaming work, changing reveal-latency characteristics | 0.75 (75%) | StreamingWorkBudgetOptions.Parse/ParseReservePercent (:71-73,154-169) |
ACDREAM_STREAM_WORK_ENTITY_OPS |
=<int> (>0, else default) |
Per-frame ceiling on entity-cursor operations (small ops, e.g. one dictionary/index write each) on the update thread | A/B-measurement-only family. Doc comment: elapsed-time ceiling (ACDREAM_STREAM_WORK_MS) remains the authoritative CPU guard — this is a secondary cap, deliberately loose (leaves >90% of the time budget unused at default) |
4,096 | StreamingWorkBudgetOptions.Parse (:62-64) |
ACDREAM_STREAM_WORK_GL_RETIRE_OPS |
=<int> (>0, else default) |
Per-frame ceiling on GL/GPU resource-retirement operations on the update thread | A/B-measurement-only family; changes retirement cadence, which changes when GPU memory is actually reclaimed | 64 | StreamingWorkBudgetOptions.Parse (:68-70) |
ACDREAM_STREAM_WORK_GPU_MIB |
=<int MiB> (>0, else default) |
Per-frame ceiling on GPU upload bytes on the update thread | A/B-measurement-only family; directly changes per-frame upload throughput | 8 MiB | StreamingWorkBudgetOptions.Parse (:65-67) |
ACDREAM_STREAM_WORK_HOLD_DEST_MS |
=<double ms> (>0 and finite, else default 8.0) |
Absolute (not quality-scaled) time ceiling for destination-lane work during a portal/login hold; never shrinks a profile whose own ceiling is already ≥ this value | Explicitly documented as "NOT a user setting... exists for A/B measurement only, matching the rest of the ACDREAM_STREAM_WORK_* family" — do not set outside a deliberate hold-latency A/B comparison |
8.0 ms | StreamingWorkBudgetOptions.Parse (:74-76); HoldDestinationCeilingMilliseconds widens the frame meter via StreamingWorkBudget.WidenForDestinationHold while a destination reservation hides the world behind the authored tunnel (#418) |
ACDREAM_STREAM_WORK_MS |
=<double ms> (>0 and finite, else default) |
Per-frame elapsed-time ceiling for update-thread streaming work — "the authoritative CPU guard" per the entity-ops comment | A/B-measurement-only family; this is the primary per-frame time budget for streaming — changing it changes both perceived streaming latency and measured frame cost | 2.0 ms | StreamingWorkBudgetOptions.Parse (:53-55) |
ACDREAM_UNCAPPED_RENDER |
=1 |
Removes the normal VSync/refresh-rate software pacer, so the render loop runs as fast as the GPU/CPU allow. | Own doc comment (RuntimeOptions.cs:147-150): "Normal presentation is always bounded by VSync or a refresh-rate software pacer. This explicit diagnostic is the sole way to measure truly uncapped renderer throughput." Not representative of what a real player experiences — exists purely for throughput measurement. |
false → VSync/pacer-bounded |
RuntimeOptions.UncappedRendering → GameWindow.cs:765 → DisplayFramePacingController; also VulkanBringUpHost.cs:75 |
ACDREAM_WB_DIAG |
=1 (raw string.Equals ordinal compare) |
(a) GameWindow: gates the [FRAME-DIAG] render-thread entity-upload-distribution report; (b) WbDrawDispatcher: gates BeginRhiTimer/SampleRhiTimers, wrapping the opaque/detail/transparent draw passes in extra Vulkan GPU timer-scope queries and periodically logging a [WB-DIAG] CPU/GPU median/p95 report |
adds extra per-pass GPU timestamp queries every frame while on — genuine measurement overhead; NOT read through RenderingDiagnostics or any diagnostics-owner class, unlike every other flag in this set — flag for whitelisting (see Notes #2); the flag's supposed interaction with ACDREAM_FRAME_PROF's GPU query is stale documentation (see Notes #1) |
unset (off) | read directly at WbDrawDispatcher.cs:2061-2064 (every Draw()/BeginEntityDispatch call, i.e. effectively per frame, NOT cached) and cached once as a readonly field at GameWindow.cs:153-156 |
ACDREAM_WORLD_TIME |
=<float>, accepted only in [0, 1) |
Campaign V slice V7 instrument-determinism pin: freezes the Dereth day fraction (and therefore sun direction, sky keyframe, and every lit surface) instead of following the server clock. | Outranks BOTH the server TimeSync clock and the /time slash command's SetDebugTime (which is deliberately transient — the next TimeSync clears it); this pin does not clear. Distinct axis from ACDREAM_DAY_GROUP (day-group/weather-preset selection) and ACDREAM_SKY_PHASE_SECONDS (cloud scroll + foliage wind) — the calendar DATE still advances, only the intra-day fraction freezes. Anything outside [0,1) (including negative, unparseable, or unset) leaves the server clock alone entirely — no partial/clamped behavior. |
null → server clock |
RuntimeOptions.PinnedWorldDayFraction → GameWindow.cs:720 → WorldEnvironmentController → Runtime.WorldTime.PinnedDayFraction |
Automation
A scripted route run adds three things at once — a session config so the client self-selects a character, a route script, and an artifact directory:
$env:ACDREAM_UI_PROBE_SCRIPT = "$scratch\route.txt"
$env:ACDREAM_AUTOMATION_ARTIFACT_DIR = "$scratch\artifacts"
$env:ACDREAM_FRAME_PROF = "1"
$env:ACDREAM_FRAME_HISTORY = "$scratch\frames.csv"
& $exe --session-config "$scratch\session.json"
Two traps this recipe exists to document:
- Without
--session-config, the client stops at character select and the route never runs. The session JSON supplies the endpoint, account, and a characterindexfor auto-selection. ACDREAM_AUTOMATION_ARTIFACT_DIRis not free. It constructs the render-scene oracle, which fingerprints every resident entity every frame. The allocation cost was fixed in #432, but the CPU walk remains — automation-run frame rates are diagnostics-loaded and must only be compared against other automation runs, never against a plain run. Some route verbs (wait world-*) additionally do nothing unless this is set.
| Flag | Value | What it does | Side effects | Default | Read by |
|---|---|---|---|---|---|
ACDREAM_AUTOMATION_ARTIFACT_DIR |
=<path> |
Output directory for the retail-UI automation probe's checkpoint JSON + screenshot PNG artifacts; gates whether the full WorldLifecycleAutomationController (checkpoint/screenshot/render-pack-automation capable) is composed at all vs. the cheaper facts-only WorldRevealFactsAutomationRuntime fallback (wait world-ready/visible verbs work either way per issue #415's fix; checkpoint/screenshot verbs report "requires ACDREAM_AUTOMATION_ARTIFACT_DIR" without it). |
Known #432 surprise, confirmed still live: FrameRootComposition.cs:349-353 — AutomationArtifactDirectory is not null (together with RetainedUi?.Screenshots is not null) unconditionally constructs a CurrentRenderSceneOracle and a RenderSceneShadowComparisonController — a per-frame diagnostics referee — regardless of whether any checkpoint/screenshot is ever actually requested that session. Merely setting this var for its "just an output path" purpose pays the per-frame comparison cost for the whole run. |
unset (null) → facts-only automation runtime, no per-frame referee constructed | RuntimeOptions.AutomationArtifactDirectory → FrameRootComposition.cs:351,543-627, WorldLifecycleAutomationController.cs, RetailUiAutomationScriptRunner.cs:108 |
ACDREAM_AUTOMATION_EXACT_FRAMEBUFFER |
=1 |
Forces the graphical host to use the persisted display resolution as the initial size of a borderless window at creation, so the OS window manager cannot clamp a decorated window to the desktop work area — needed for pixel-exact automated screenshot comparison. | Changes window chrome (borderless) at startup — a visible difference from an ordinary launch, not just an internal measurement knob. | false → normal decorated window |
RuntimeOptions.ExactAutomationFramebuffer → GameWindow.cs:852 (CreateStartupWindowOptions) |
ACDREAM_BAKE_PUBLISH_NONCE_V1 |
=<32-hex GUID "N" format> |
Launcher-to-bake-child authorization token: when present and valid, the bake child takes a cross-process publish file lock + writes an authorization file before atomic publication (serializes with launcher recovery) | If present but fails IsValidNonce (not a 32-char Guid "N"), throws InvalidOperationException and aborts the bake. When absent, bake runs unguarded (standalone mode). Never set this manually outside the launcher's own child-process spawn. |
unset (standalone unguarded bake) | BakePublicationGuardPaths.cs:12, read by BakePublicationGuard.AcquireIfRequested (AcDream.Bake/BakePublicationGuard.cs:18); set by BakeProcessRunner.cs:150/162 |
ACDREAM_NET_DROP_DIR |
="out"/"in"/anything-else (incl. unset) → Both (case-insensitive) |
Selects which direction(s) — outbound, inbound, or both — the deterministic loss-injection decorator drops | Only takes effect when ACDREAM_NET_DROP_PCT>0 (decorator is structurally absent otherwise). Drives real datagram loss on the live connection — the injection point for tools/run-connected-loss-gate.ps1. Never set during a normal/measurement run. |
Both |
NetDiagnostics.NetDropDir (NetDiagnostics.cs:88-90,98-104), consumed by LossyTransportDecorator.WrapIfConfigured (Transport/LossyTransportDecorator.cs:21-22), also read at WorldSession.cs:901-907 (comment only) |
ACDREAM_NET_DROP_PCT |
=<int 0-100> (out-of-range or unparsable → 0) |
Percent chance (post-handshake-arming, per droppable datagram) that the deterministic LossyTransportDecorator drops a packet in the configured direction(s) |
Fault injection. >0 wraps the real socket transport in a packet-dropping decorator for the whole session — genuinely breaks/delays delivery to exercise N1-N4 reliable-transport recovery. At 0 the decorator is never constructed (zero structural cost). Must be 0/unset for any normal run or non-loss-gate measurement. |
0 (off, decorator absent) |
NetDiagnostics.NetDropPercent (NetDiagnostics.cs:60-69,92-96), consumed by LossyTransportDecorator.WrapIfConfigured (:21), wired at WorldSession.cs:901-907 |
ACDREAM_NET_DROP_SEED |
=<int> (unparsable → 1) |
PRNG seed for the loss decorator (outbound seeded with seed, inbound with ~seed) — same seed reproduces an identical drop pattern |
Only matters when ACDREAM_NET_DROP_PCT>0; makes fault injection deterministic/reproducible for the connected loss gate |
1 |
NetDiagnostics.NetDropSeed (NetDiagnostics.cs:75-82), consumed by LossyTransportDecorator (:21-22) |
ACDREAM_OPEN_CHARGEN |
=1 |
Campaign CC slice CC4 interim env/test-only seam: opens the character-creation screen (gmCharGenMainUI) automatically once Runtime's chargen view goes active, bypassing the real retail Create-Character-button transition. Fires once per mount (_openOnStartConsumed latch). |
Own doc comment explicitly calls this "interim env/test-only" — Campaign CC (closed 2026-08-16, user-accepted) later wired the real Create button with its roster<55-slot ghost gate, so this flag is now a bypass of that gate for automation/testing rather than the only way in. | false |
RuntimeOptions.OpenCharacterCreationOnStart → CharacterCreationUiController.cs:21,524-530 |
ACDREAM_UI_PROBE_DUMP |
=1 |
Enables the retail-UI automation probe's diagnostic dump path and feeds RetailUiProbeBindings/RetailUiAutomationScriptRunner. Also part of RuntimeOptions.UiProbeEnabled (`UiProbeDump \ |
\ | UiProbeScript is set`). | RuntimeOptions.UiProbeDump → LivePresentationComposition.cs:1465-1495, InteractionRetainedUiComposition.cs:1092-1100 |
ACDREAM_UI_PROBE_SCRIPT |
=<path> |
Path to a script file the RetailUiAutomationScriptRunner executes against the retained UI (pointer/semantic-input command playback) for scripted UI regression testing. |
Also flips RuntimeOptions.UiProbeEnabled true even without ACDREAM_UI_PROBE_DUMP=1. |
null |
RuntimeOptions.UiProbeScript → InteractionRetainedUiComposition.cs:1094 |
ACDREAM_VULKAN_FORCE_UNSUPPORTED |
=<feature-name> (case-insensitive property name, e.g. MultiDrawIndirect) |
Test knob (Slice V5): clears one named required Vulkan feature from the capability record to synthetically fail the gate, so the NotSupportedException → exit-code-4 → report path can be exercised on hardware that actually supports everything. |
Deliberately breaks Vulkan startup when set to a matched feature name — this is a "make it fail on purpose" gate-testing flag, never appropriate for a normal or measurement run. | null → real capabilities used unmodified |
RuntimeOptions.VulkanForcedUnsupportedFeature → VulkanCapabilityRecord.Without (VulkanCapabilityRecord.cs:113-119), consumed at VulkanGraphicsContext.cs:339 |
ACDREAM_VULKAN_PROBE |
=1 |
Runs the standalone Vulkan capability-probe/bring-up harness (opens its own window, runs the capability gate, presents synthetic V6c/V6d verification scenes, captures one screenshot) instead of the real client composition host, then exits. | Its class doc (VulkanBringUpHost.cs:11) is stale — claims it additionally requires ACDREAM_RENDER_BACKEND=vulkan, which is no longer read anywhere (see that flag's row); in the current code this flag ALONE gates entry (GameWindow.cs:828: if (_options.VulkanCapabilityProbe)). |
false → normal composition host |
RuntimeOptions.VulkanCapabilityProbe → GameWindow.cs:828 → VulkanBringUpHost |
ACDREAM_VULKAN_PROBE_FRAMES |
=<int> (non-negative) |
Bounds the bring-up probe harness to N presented frames so it can run unattended in CI, instead of presenting until a human closes the window. | The frame budget never cuts a pending screenshot capture short — the loop stays open until the screenshot has been attempted even past the budget, so an unattended run's whole product (a PNG) is guaranteed. Zero (unset/unparseable/explicit 0) keeps the interactive wait-for-close behavior. |
0 → interactive (wait for window close) |
RuntimeOptions.VulkanCapabilityProbeFrames → VulkanBringUpHost.cs:141-249 |
Permanent diagnostics
| Flag | Value | What it does | Side effects | Default | Read by |
|---|---|---|---|---|---|
ACDREAM_CAPTURE_PLAYER_QUANTA |
=<path> (any non-whitespace path) |
Opt-in JSON-Lines trace of every admitted player physics quantum (position/orientation/velocity/contact-plane snapshots at each stage boundary of CPhysicsObj::UpdateObjectInternal) |
Appends+flushes one JSON line per physics quantum to the file (real file I/O on the physics tick when enabled); disabled path costs one static string null/empty check, no allocation. Read once into a mutable static property (settable via ResetForTest) rather than a typed options object. |
unset (disabled, zero-alloc) | PlayerPhysicsQuantumCapture static class (AcDream.Runtime/Gameplay/PlayerPhysicsQuantumCapture.cs:22) |
ACDREAM_DUMP_MOTION |
=1 |
prints UM/[UM_STALE]/[MOTIONDONE]/VU.land/raw-hex wire dump lines tracing inbound UpdateMotion handling, remote ground-contact edges, and motion-done callbacks (bug-a/#32 stuck-cast subthread is temporary; core trace is long-lived) |
print-only, but the raw-site reads in LiveEntityNetworkUpdateController.cs and UpdateMotion.cs fire on EVERY inbound motion/UM event (not cached) — Environment.GetEnvironmentVariable call per packet even when off; UpdateMotion.cs's branch additionally builds a StringBuilder hex dump when on. Rule-5 violation (raw reads outside a diagnostics-owner class) at 5+ call sites |
off | THREE independent readers: PhysicsDiagnostics.DumpMotionEnabled (owner, appears unconsumed — see Notes), AnimationPresentationDiagnostics.FromEnvironment() (App owner record, cached once at startup, consumed by LiveEntityAnimationPresenter), and raw Environment.GetEnvironmentVariable reads scattered across LiveEntityNetworkUpdateController.cs (4 sites) + Core.Net/Messages/UpdateMotion.cs:163 + Runtime/Physics/RuntimeRemotePhysicsUpdater.cs:630 |
ACDREAM_DUMP_PLAYSCRIPT |
="1" (ordinal) |
Traces PhysicsScript playback: missing/empty script resolution, malformed StartTime entries, and other [pes]-prefixed hook-dispatch events |
print-only (Console.WriteLine) at all 4 use sites (:85-86,136,300,328) |
unset (off) | PhysicsScriptRunner.DiagEnabled (PhysicsScriptRunner.cs:61-62) — per-instance settable property seeded from the env var, not a shared static diagnostics-owner class |
ACDREAM_DUMP_SURFACES |
="1" (ordinal) |
One-shot (per session) surface-format histogram dump for the atlas-opportunity audit — fires once after _dumpFrameCounter>=600 OnRender ticks AND _uploadMetadata.Count>=100 uploaded textures; writes to the host diagnostics directory |
Doc comment claims "Zero cost when off" but _uploadMetadata[name]=(w,h,fmt) (TextureCache.cs:1042) is written unconditionally on every texture upload regardless of the flag — real (small) always-on dictionary-write cost. TickSurfaceHistogramDumpIfEnabled also re-reads Environment.GetEnvironmentVariable every OnRender frame (not cached) until the one-shot fires. Dump-write failures are caught and logged to stderr, not fatal. |
unset (off) | TextureCache (TextureCache.cs:102-113 fields, gate at TextureCache.cs:802-812, dump at TextureCache.cs:814-829), Phase N.6 slice 1 |
ACDREAM_FRAME_PROF |
=1 |
master toggle for the frame profiler: CPU frame time, GPU time samples, per-stage CPU attribution, per-frame alloc/GC, [frame-prof] report every ~5 s (doc: "permanent apparatus ... do not strip with session probes") |
when on, samples GC.GetAllocatedBytesForCurrentThread() and stage-scope timing every frame (cheap, by design); its own XML doc claims a GPU-query self-disable tied to ACDREAM_WB_DIAG=1 that FrameProfiler.cs says no longer exists — see Notes #1; startup-only in practice (its DebugPanel/DebugVM mirror is unreachable — #434) |
false (off) | RenderingDiagnostics.FrameProfEnabled / FrameProfiler |
ACDREAM_PROBE_ENVCELL |
=1 |
emits one [envcells] line per indoor frame: CellsRendered/TrianglesDrawn + ourBldgs/otherBldgs/filter counts (phase a8 relic; its own render pass was removed but the probe was kept) |
print-only; implicitly turned on whenever ACDREAM_PROBE_VIS is on (getter is `_probeEnvCellEnabled \ |
\ | RenderingDiagnostics.ProbeEnvCellEnabled (backing field OR'd with ProbeVisibilityEnabled) |
ACDREAM_PROBE_INDOOR_ALL |
=1 |
master switch that reads as AND / writes as cascade across Walk, Lookup, Upload, Xform, Cull | print-only (every underlying probe is print-only); startup-only in practice (its DebugPanel/DebugVM mirror is unreachable — #434) | false (off) | RenderingDiagnostics.IndoorAll (cascades to the 5 flags below) |
ACDREAM_PROBE_INDOOR_CULL |
=1 (also set by ACDREAM_PROBE_INDOOR_ALL=1) |
emits [indoor-cull] per culled cell entity with cull reason (visibleCellIds-miss / frustum / landblock) |
print-only; startup-only (its DebugPanel/DebugVM mirror is unreachable — #434) | false (off) | RenderingDiagnostics.ProbeIndoorCullEnabled |
ACDREAM_PROBE_INDOOR_LOOKUP |
=1 (also via ACDREAM_PROBE_INDOOR_ALL) |
emits [indoor-lookup] per visible cell entity/sec: render-data hit/miss, IsSetup, parts-hit/parts-miss tallies |
print-only; startup-only (its DebugPanel/DebugVM mirror is unreachable — #434) | false (off) | RenderingDiagnostics.ProbeIndoorLookupEnabled |
ACDREAM_PROBE_INDOOR_UPLOAD |
=1 (also via ACDREAM_PROBE_INDOOR_ALL) |
emits [indoor-upload] requested/completed lines per EnvCell id at WbMeshAdapter's staged-drain time |
print-only; startup-only (its DebugPanel/DebugVM mirror is unreachable — #434) | false (off) | RenderingDiagnostics.ProbeIndoorUploadEnabled |
ACDREAM_PROBE_INDOOR_WALK |
=1 (also via ACDREAM_PROBE_INDOOR_ALL) |
emits [indoor-walk] per visible cell entity/sec: world position, parent cell, landblock/AABB-visible flags, "drew" flag |
print-only; startup-only (its DebugPanel/DebugVM mirror is unreachable — #434) | false (off) | RenderingDiagnostics.ProbeIndoorWalkEnabled |
ACDREAM_PROBE_INDOOR_XFORM |
=1 (also via ACDREAM_PROBE_INDOOR_ALL) |
emits [indoor-xform] per visible cell entity/sec: cell-geometry SetupPart's composed world-matrix translation |
print-only; startup-only (its DebugPanel/DebugVM mirror is unreachable — #434) | false (off) | RenderingDiagnostics.ProbeIndoorXformEnabled |
ACDREAM_PROBE_LOGIN_FRAMES |
="1" |
Per-completed-frame login/portal-wormhole presentation classification (world/tunnel/black/void); logs [login-frames] on each classification transition |
print-only. "Not a user setting; not in RuntimeOptions; not persisted" (doc comment). | unset (off) | RenderPresentationDiagnostics.ProbeLoginFrames (LoginPresentationFrameProbe.cs:28-29), consumed by LoginPresentationFrameProbe.Process |
ACDREAM_PROBE_NET |
="1" |
Emits [net-out] (per outbound reliable message), [net-tick] (1 Hz WorldSession.Tick summary incl. reliable-transport rates), [net-final] (cumulative stats at Dispose), and [cmd-gate] (generation-gated command rejections) |
print-only. Doc comment: "the counters themselves increment unconditionally in TransportStats; only the string work is gated" — i.e. the underlying stats tracking has a small always-on cost independent of this flag, but this flag itself gates only string/console formatting. |
unset (off) | NetDiagnostics.ProbeNet (NetDiagnostics.cs:56-57), issue #260 probe family |
ACDREAM_PROBE_RESOLVE |
=1 |
gates one structured [resolve] line per PhysicsEngine.ResolveWithTransition call (in/target/out position+cell, ok-vs-partial, grounded/contact status, wall normal, walkable-polygon validity, responsible entity) (l.2a slice 1, general-purpose resolver probe) |
print-only, ~30 Hz per moving entity while on | off | PhysicsDiagnostics.ProbeResolveEnabled |
ACDREAM_PROBE_REVEAL |
="1" |
While a reveal destination's composite warmup is incomplete, emits one [composite-warmup] line/second: pending queue depth, scan state, upload-budget gate, first few unresolved GfxObj ids |
print-only | unset (off) | NetDiagnostics.ProbeReveal (NetDiagnostics.cs:115-116), issue #260 |
ACDREAM_PROBE_REVEAL_TIMING |
="1" |
Wall-clock attribution of each login/portal reveal hold: [reveal-timing] lines for begin/first-true readiness edges (render/composites/collision/gate/materialized) with elapsed ms, 1 Hz progress, and one SUMMARY line at viewport reveal |
print-only; doc comment: "never constructed unless the probe env is set, changes no behavior, and costs one branch per Evaluate poll otherwise" (i.e. genuinely near-zero cost when off — confirmed, RevealTimingProbe object itself is null when disabled) |
unset (off) | StreamingDiagnostics.ProbeRevealTiming (StreamingDiagnostics.cs:65-66), consumed by LandblockPresentationPipeline.cs:69, PublicationTimingProbe.cs:34, RevealTimingProbe.cs (construction gated) |
ACDREAM_PROBE_SOUND_WIRE |
="1" |
One line per inbound server Sound event (0xF750) and per wire-sound play decision, with the drop reason when nothing plays — used to determine whether missing interior soundscapes are server- or client-side |
print-only, consumed at AudioHookSink.cs:159 and EntityEffectController.cs:123 |
unset (off) | AudioDiagnostics.ProbeWireSoundsEnabled (AudioDiagnostics.cs:20-21) |
ACDREAM_PROBE_USEABILITY_FALLBACK |
=1 |
gates a per-call log of IsUseableTarget calls that take the null-useability fallback path (creature/door/lifestone passes) (measures a real ace-vs-retail data gap, not a bug investigation) |
print-only; measures how often ACE ships entities without _useability set |
off | PhysicsDiagnostics.ProbeUseabilityFallbackEnabled |
ACDREAM_PROBE_VIS |
=1 |
emits [vis] line on root-cell CHANGE: visible cell ids, OutsideView poly/plane counts, per-cell plane counts, scissor-fallback count (phase u.2d repurposed the flag; its DebugPanel mirror is unreachable — #434) |
print-only; ALSO implicitly enables the separate ACDREAM_PROBE_ENVCELL probe (its getter ORs with this flag — see Notes #3); startup-only in practice (its DebugPanel/DebugVM mirror is unreachable — #434) |
false (off) | RenderingDiagnostics.ProbeVisibilityEnabled |
ACDREAM_REMOTE_VEL_DIAG |
=1 |
prints per-UM/per-tick remote-velocity and animation-cycle diagnostic lines; Runtime/Physics/RemoteMotion.cs carries diagnostic-only fields (PrevServerPos, PrevServerPosTime, MaxRootMotionSpeedSinceLastUP, LastOmegaDiagLogTime) unconditionally on every remote — small fixed per-instance memory regardless of the flag, not gated (long-lived remote-velocity/animation diagnostic, commit a.1) |
print-only, but the raw-site reads in LiveEntityNetworkUpdateController.cs fire on every UM/tick even when off (rule-5 violation, Environment.GetEnvironmentVariable call per event, 6+ call sites) |
off | THREE readers: AnimationPresentationDiagnostics.FromEnvironment() (App owner record, cached at startup, consumed by LiveEntityAnimationPresenter for [SEQSTATE]/[CURRNODE]/other part-diagnostic lines, throttled to 1/sec/entity) + raw Environment.GetEnvironmentVariable reads scattered across LiveEntityNetworkUpdateController.cs (6+ sites: [UM_RAW], [FWD_WIRE], [VEL_DIAG], [UPCYCLE_SRC], [UM_STALE]) + RemoteServerControlledVelocityCycle.cs:68 ([UPCYCLE]) |
Temporary probes
Each row names the issue that owns it. A temporary probe is deleted in the same commit as its investigation's fix — if you find one here whose issue is closed, the strip was missed; delete both.
Probe debt, measured 2026-08-24: 64 temporary probes exist. They cite 21 distinct issues, and 14 of those are already closed — 17 rows below are apparatus whose investigation ended without the strip. A further 14 rows name no owning issue at all, which is worse: nobody can tell when they are safe to remove. Tracked as #435; do not add to the pile. Every probe here still costs a branch on its hot path even when unset, and a handful re-read the environment per frame rather than caching (see their side-effects column).
| Flag | Owning investigation | Value | What it does | Side effects | Read by |
|---|---|---|---|---|---|
ACDREAM_A8_DUMP_PV |
(unattributed) | =1 |
Dumps local→NDC→clipped portal geometry (first 2 Build calls per distinct camera cell) |
print-only (Console.WriteLine) |
PortalVisibilityBuilder.cs:270-271 (static field, not a diagnostics-owner class) |
ACDREAM_AIRBORNE_DIAG |
#42 | =1 |
prints [SWEEP]/[SWEEP-OBJ] lines tracing airborne-sweep XY drift, only when !isOnGround |
print-only; re-reads the env var (Environment.GetEnvironmentVariable) on every airborne resolve/candidate instead of caching — minor per-call overhead when the flag is unset too |
raw reads in PhysicsEngine.cs:2300 + TransitionTypes.cs:3905 (issue #42) |
ACDREAM_CLIP_DEBUG |
#176 | =1 |
forces the EnvCell SHELL pass to map every instance to clip slot 0 (no-clip) instead of its cell's portal-slice region | ALTERS RENDERED OUTPUT: shells draw whole/unclipped instead of trimmed — a visual isolation mode, not a log-only probe; no DebugPanel mirror | RenderingDiagnostics.ClipDebugNoShellTrim |
ACDREAM_DUMP_APPEARANCE |
#5 | ="1" |
Logs every 0xF625 ObjDescEvent + 0xF7DB UpdateObject with body length, target guid, hex preview — used to debug remote-player appearance asymmetry |
print-only (Console.WriteLine) |
WorldSession static field DumpAppearanceEnabled (WorldSession.cs:792-793), raw scattered read, issue #5 diagnostic |
ACDREAM_DUMP_CELLS |
#98 | =<comma list of hex cell ids> |
one-shot JSON dump of any cached EnvCell whose id matches the list, to ProbeDumpCellsPath (issue #98 fixture capture) |
file I/O once per matching cell id (no-op on repeat); fixture-generation tool, not a perf-neutral no-op when ids are listed | PhysicsDiagnostics.ProbeDumpCellIds (ParseHexIdList) |
ACDREAM_DUMP_CELLS_DIR |
(unattributed) | =<dir> |
overrides the output directory for ACDREAM_DUMP_CELLS |
print/file-path only; no effect unless ACDREAM_DUMP_CELLS is also set |
PhysicsDiagnostics.ProbeDumpCellsPath |
ACDREAM_DUMP_CLOTHING |
(unattributed) | =1 |
Print-only: dumps clothing/part-swap diagnostics for a spawned entity when its setup has ≥10 mesh parts (humanoids). Gated additionally on part count even when the flag is on. | print-only |
RuntimeOptions.DumpClothing → DatLiveEntityProjectionMaterializer.cs:251-258,1190 |
ACDREAM_DUMP_EDGE_SLIDE |
(unattributed) | =1 |
gates five edge-slide: trace lines (stepdown-failed, stepdown-branch-enter, phase2, branch, cliffslide) inside the L.4-diag edge-slide/cliff-slide code path |
print-only; property re-reads Environment.GetEnvironmentVariable on EVERY call (not cached in a field) — repeated env lookups during edge-slide resolution when active; raw read outside any diagnostics-owner class (rule-5 candidate) |
Transition.DumpEdgeSlideEnabled (private expression-bodied property in TransitionTypes.cs, raw read) |
ACDREAM_DUMP_ENTITY |
#119 | comma-separated hex ids, optional 0x prefix, malformed segments ignored |
per-entity HYDRATE/DRAW/WALK-REJECT trace for a watchlist of Setup/GfxObj source ids across LandblockBuildFactory, WbDrawDispatcher |
print-only; every call site fast-exits on Count==0. The same id set is ALSO reused (undocumented in its own XML doc) as the watchlist for the ACDREAM_PROBE_OUTSTAGE [outstage-own] per-entity verdict probe — see Notes |
RenderingDiagnostics.DumpEntitySourceIds |
ACDREAM_DUMP_GFXOBJS |
#98 | =<comma list of hex GfxObj ids> |
one-shot JSON dump of any cached GfxObj's polygon table + BSP root metadata matching the list, to ProbeDumpGfxObjsPath (issue #98 fixture capture) |
file I/O once per matching id (no-op on repeat) | PhysicsDiagnostics.ProbeDumpGfxObjIds (ParseHexIdList) |
ACDREAM_DUMP_GFXOBJS_DIR |
(unattributed) | =<dir> |
overrides the output directory for ACDREAM_DUMP_GFXOBJS |
print/file-path only; no effect unless ACDREAM_DUMP_GFXOBJS is also set |
PhysicsDiagnostics.ProbeDumpGfxObjsPath |
ACDREAM_DUMP_LIVE_SPAWNS |
(unattributed) | =1 |
Print-only: logs every live CreateObject spawn as it's processed, plus DROP lines when a setup dat id is missing. |
print-only |
RuntimeOptions.DumpLiveSpawns → DatLiveEntityProjectionMaterializer.cs:161-226, SessionPlayerComposition.cs:566,712 |
ACDREAM_DUMP_MOVE_TRUTH |
(unattributed) | =1 |
Print-only: records the local player's last outbound movement wire truth (position, cell, contact byte, velocity) for comparing what was actually sent vs. local physics state. Early-returns with zero cost when disabled. | print-only |
RuntimeOptions.DumpMoveTruth → GameWindow.cs:795 → MovementTruthDiagnosticController |
ACDREAM_DUMP_OPCODES |
#5 | ="1" |
Logs first occurrence of each genuinely-unhandled inbound opcode (deduped by opcode) | print-only. Must stay the LAST else-if in the dispatch chain per comment (else it would intercept handled opcodes) — currently correct. | WorldSession static field DumpOpcodesEnabled (WorldSession.cs:788-789, consumed WorldSession.cs:2391-2398), issue #5 diagnostic. Also mirrored (display-only, non-functional) via DebugPanel.cs:241/DebugVM.cs:227. |
ACDREAM_DUMP_SCENERY_Z |
#48 | =1 |
Per-spawn Z-placement diagnostic for procedural scenery (trees/bushes/rocks), added for issue #48 (the "trees-in-sky" bug). | NOT print-only — this is a real behavior fork, not just added logging. LandblockBuildFactory.cs:167-178: when the flag is on, the streaming worker calls a separate, duplicate scenery-building method (BuildSceneryEntitiesForStreaming, a full parallel reimplementation of GfxObj/Setup mesh resolution + placement inline in this file) instead of production's LandblockPhysicsContentBuilder.HydrateProceduralScenery. Any visual/measurement run taken with this flag set is exercising a different scenery-placement code path than production, which can drift from it silently. |
RuntimeOptions.DumpSceneryZ → SessionPlayerComposition.cs:280 → LandblockBuildFactory.cs:23,42,168,335 |
ACDREAM_DUMP_SKY |
(unattributed) | =1 |
Print-only: dumps decoded SkyDesc raw values on region load (SkyDescLoader.cs) and per-GfxObj Surface.Type/translucency flags on first upload (SkyRenderer.cs), plus gates a TimeSync console diagnostic in GameWindow. Built to resolve specific open questions about retail sky units and GfxObjReplace timing (2026-04-23 research), now answered but the dumps remain wired. |
Three independent reads of the SAME env var, only one of which (RuntimeOptions.DumpSky) goes through the typed options object; the other two are raw scattered reads (see Notes). SkyRenderer.cs:582's raw read is in the App layer and has no architectural excuse for bypassing RuntimeOptions — _options.DumpSky was already available to that composition. print-only in all three sites. |
RuntimeOptions.DumpSky (typed) → GameWindow.cs:704 (TimeSyncDiagnostic); also two independent raw Environment.GetEnvironmentVariable reads at SkyDescLoader.cs:392 (Core) and SkyRenderer.cs:582 (App) |
ACDREAM_DUMP_STEEP_ROOF |
(unattributed) | =1 |
gates [steep-roof] KILL-VELOCITY-APPLIED in PhysicsEngine.ResolveWithTransition when retail's kill_velocity zeroes body velocity on steep-slope impact, plus per-frame plane-normal traces in TransitionTypes/PlayerMovementController |
print-only | PhysicsDiagnostics.DumpSteepRoofEnabled |
ACDREAM_DUMP_STEPUP |
(unattributed) | =1 |
prints stepup: enter normal=… verdict=WALKABLE/STEEP … on every step-up attempt |
print-only; raw per-call Environment.GetEnvironmentVariable read outside a diagnostics-owner class (rule-5 violation); content is mirrored (not replaced) into the buffered [transit-fail-stepup] trace gated separately by ACDREAM_DUMP_TRANSIT_FAIL |
raw read in Transition.DoStepUp (TransitionTypes.cs:5991, re-read every call — not cached) |
ACDREAM_DUMP_TRANSIT_FAIL |
#345 | =1 |
buffers per-tick [transit-fail-insert]/[transit-fail-stepup]/[transit-fail-walk]/[transit-fail-adjust] trace lines into a [ThreadStatic] list and flushes them to console ONLY when a tick requested nonzero XY movement but delivered zero (self-selecting "stuck tick" predicate) |
print-only, zero allocation when off (flag checked before touching any buffer per its own doc); buffer/list allocation only on ticks that are already stuck | PhysicsDiagnostics.DumpTransitFailEnabled |
ACDREAM_DUMP_VENDOR |
(unattributed) | ="1" |
[vendor-diag]-prefixed trace across ~25 call sites for two live-only vendor regressions: Chain A (far-click walk-to-use approach never opens the shop window) and Chain B (splittable vendor stack selection shows no quantity slider) |
print-only (Console.WriteLine), verified true no-op when unset |
VendorDiagnostics.DumpVendorEnabled (VendorDiagnostics.cs:25-26) — a proper diagnostics-owner class per Code Structure Rule 5, shared across App/Core.Net/Runtime |
ACDREAM_DUMP_VITALS |
(unattributed) | ="1" |
Logs every PrivateUpdateVital(Current) parse, every parsed PlayerDescription (vector flags/attr/spell counts), and PlayerDescriptionParser trailer/mid-walk FormatException failures with position |
print-only at every site. PlayerDescriptionParser.cs:458/473 re-read the env var raw inside catch blocks on every parse failure (rare, but scattered/uncached). |
Read independently (not shared) at 4 sites: WorldSession.cs:790-791 (DumpVitalsEnabled), GameEventWiring.cs:1041 (local dumpPd at PlayerDescription registration), PlayerDescriptionParser.cs:458 and :473 (per-catch-block raw reads). Also mirrored (display-only, non-functional) via DebugPanel.cs:240/DebugVM.cs:225. |
ACDREAM_HIDE_PART |
(unattributed) | =<int> |
Hides one mesh part by index on entities with ≥10 parts (humanoids) — a debugging aid for equipment/clothing part-visibility issues. | Real (visible) behavior change, not print-only, but scoped to a single diagnostic index and off by default. | RuntimeOptions.HidePartIndex → LivePresentationComposition.cs:608 → LiveEntityAnimationPresenter.cs:21,38,243 |
ACDREAM_LIGHT_DEBUG |
#176 | =<int> (int.TryParse; unset/invalid → 0) |
shader isolation mode uploaded as uLightDebug by EnvCellRenderer + WbDrawDispatcher: 0=off, 1=ambient-only vertex lighting, 2=kill dynamic point lights, 3=raw vLit visualization (texture ignored) |
ALTERS RENDERED OUTPUT directly every draw pass (changes fragment-shader lighting/texturing) — not a log probe; no DebugPanel mirror | RenderingDiagnostics.LightDebugMode |
ACDREAM_PROBE_AUTOWALK |
issue #63 | =1 |
gates [autowalk-out]/[autowalk-mt]/[autowalk-up] lines in LiveEntityNetworkUpdateController tracing local-player server-initiated auto-walk (SendUse/SendPickUp, inbound UpdateMotion, inbound UpdatePosition) |
print-only; filtered to local player only, low volume | PhysicsDiagnostics.ProbeAutoWalkEnabled |
ACDREAM_PROBE_BUILDING |
l.2d slice 1 | =1 |
gates the multi-line [resolve-bldg] BSP-shadow-hit trace in TransitionTypes.FindObjCollisions, one-time [entity-source] registration logs in GameWindow, [door-cycle] UM dispatch trail, and a one-shot [setstate-hex] wire dump of the first SetState (0xF74B) packet in WorldSession |
print-only; also un-gates the PhysicsDiagnostics.LastBspHitPoly diagnostic side-channel (a static field write in BSPQuery/FlatBspQuery, read back by the [resolve-bldg] line) — no gameplay effect, but an extra static-field write per BSP hit while on; heavy output (one multi-line entry per BSP hit per physics tick) |
PhysicsDiagnostics.ProbeBuildingEnabled |
ACDREAM_PROBE_CELL |
(unattributed) | =1 |
gates one [cell-transit] line per PlayerMovementController.CellId change (old→new cell, position, reason tag) |
print-only; low volume (only on actual cell crossings) | PhysicsDiagnostics.ProbeCellEnabled |
ACDREAM_PROBE_CELLSET |
a6.p5 | =1 |
gates PhysicsDiagnostics.LogCellSetBuild, one [cellset-build] line per BuildCellSetAndPickContaining call (seed cell, sphere XY, candidate list) from CellTransit.cs:1468 |
print-only; builds a StringBuilder of the candidate id list only when the flag is on |
PhysicsDiagnostics.ProbeCellSetEnabled |
ACDREAM_PROBE_CELL_CACHE |
indoor walking phase d | =1 |
gates one [cell-cache] line per EnvCell first-cached in PhysicsDataCache.CacheCellStruct (poly counts, BSP root structure) |
print-only; fires at most once per EnvCell (cache is no-op after first population); no DebugPanel mirror | PhysicsDiagnostics.ProbeCellCacheEnabled |
ACDREAM_PROBE_CHILD_CELL |
c4 route 7 | =1 |
gates one [child-cell] line per Runtime committed-child canonical-cell write in RuntimeLiveEntitySessionController, RuntimeEntityObjectLifetime, RuntimeEntityDirectory (parent/child guid, old/new cell, cause tag) |
print-only | PhysicsDiagnostics.ProbeChildCellEnabled |
ACDREAM_PROBE_CLIPROUTE |
"throwaway apparatus — strip once §4 ships" | =1 |
print-on-change [clip-route] / [clip-route-disp] / [clip-route-scis] lines: outside-slice clip routing, region-SSBO bytes, terrain-UBO head, actual GL/RHI scissor state |
print-only | RenderingDiagnostics.ProbeClipRouteEnabled |
ACDREAM_PROBE_CONTACT_PLANE |
spike-only, 2026-05-20 | =1 |
gates one [cp-write] line per write to CollisionInfo.ContactPlane*/LastKnownContactPlane* fields (field, old→new, caller method via stack walk, source line); only logs on actual value changes |
print-only, but performs a stack walk to identify the caller method when firing — real CPU cost per write while on (not just a string format); suppresses no-op writes to bound volume | PhysicsDiagnostics.ProbeContactPlaneEnabled |
ACDREAM_PROBE_ENT |
#138 | ="1" |
Traces the persistent player entity across teleport streaming churn: presence in the render draw-set flat view vs. survival of the dynamics cull, to distinguish "missing from draw set" vs "present but culled" | print-only, "Observation-only — emits no behavior change" (doc comment). LogPlayerDynOnChange dedupes by transition to avoid per-frame spam. Marked STRIP-once-root-caused (like the dense-town FPS apparatus). |
EntityVanishProbe.Enabled (EntityVanishProbe.cs:23-24), issue #138-B |
ACDREAM_PROBE_FLAP |
"throwaway apparatus — strip once the flap mechanism is confirmed" | =1 |
EVERY FRAME (unthrottled, not change-gated) while the camera root is indoor: [flap] from PortalVisibilityBuilder.Build (portal side-test/traverse/cull/projection) + paired [flap-cam] from PhysicsCameraCollisionProbe/[flap-sweep] (FindCameraCell resolution, eye positions) |
print-only, but unthrottled per-frame StringBuilder allocation + Console.WriteLine on multiple call sites while indoor — heavy log volume/allocation under sustained indoor play; does not alter rendered output |
RenderingDiagnostics.ProbeFlapEnabled |
ACDREAM_PROBE_GLSTATE |
"throwaway apparatus — strip once §4 ships" | =1 |
print-on-change [gl-state] line: depth/blend/cull/scissor/viewport/draw-FBO/color-mask/glGetError snapshot |
print-only per its docstring; the actual state-snapshot/comparison call site lives outside RenderingDiagnostics.cs and was outside this pass's cited read sites |
RenderingDiagnostics.ProbeGlStateEnabled |
ACDREAM_PROBE_INDOOR_BSP |
indoor walking phase 1 / cellar-lip wedge | =1 |
gates [indoor-bsp] (per BSPQuery.FindCollisions indoor call), [neg-poly] (near-miss polygon detail in BSPQuery), and [stepdown-decide] (step-down accept/reject inputs in TransitionTypes) trace lines |
print-only; also un-gates the LastBspHitPoly diagnostic side-channel write (same as ACDREAM_PROBE_BUILDING) |
PhysicsDiagnostics.ProbeIndoorBspEnabled |
ACDREAM_PROBE_INDOOR_LIGHT |
#176/#177 discriminator, a7.l1 | =1 |
rate-limited (1 Hz) [indoor-light] line from LightManager.BuildPointLightSnapshot: point-light pool set composition (pool/cellLess/registered/capped/byCell histogram) |
print-only, explicitly "inert unless set" per the call-site comment (LightManager.cs:368-370); no DebugPanel mirror | RenderingDiagnostics.ProbeIndoorLightEnabled |
ACDREAM_PROBE_JUMP |
campaign ch round 2 | =1 |
gates the [jump] line in PlayerMovementController.ReportJumpRefusal, printed UNCONDITIONALLY (even when OnInterfaceText is null) to distinguish "branch never fired" from "branch fired, callback dropped it" |
print-only; Headless/Policies/HeadlessBotPolicy.cs's JumpProbeHeadlessBotPolicy doc comment references this flag as a companion but does not itself read it — it is a headless bot behavior meant to be run alongside ACDREAM_PROBE_JUMP=1, not a second consumer |
PhysicsDiagnostics.ProbeJumpEnabled |
ACDREAM_PROBE_LIGHT |
#133 a7 | =1 |
rate-limited (1 Hz) [light] line + up to 3 [light-detail] lines: scene ambient/sun/registered/active light counts and nearest active point/spot light detail |
print-only ("Output-only, inert when off" per doc) | RenderingDiagnostics.ProbeLightEnabled |
ACDREAM_PROBE_LOCAL_TELEPORT |
c4 route 3 d-t8 | =1 |
gates one [local-tp] line per local-player portal-arrival attempt (committed AND refused) from LocalPlayerTeleportController and RuntimeAcceptedPositionDriveController.LogPortalArrivalAttempt — the single Runtime chokepoint both graphical and headless hosts share |
print-only; dual-host parity evidence (same line shape from both hosts) | PhysicsDiagnostics.ProbeLocalTeleportEnabled |
ACDREAM_PROBE_OUTSTAGE |
#131 | =1 |
print-on-change [outstage] line (outside-stage routing + per-slice cone verdicts) from RetailPViewRenderer; plus, when ACDREAM_DUMP_ENTITY also names watched ids, [outstage-own] per-entity PASS/CULL lines |
print-only | RenderingDiagnostics.ProbeOutStageEnabled |
ACDREAM_PROBE_PARK |
issue #309 | =1 |
gates [park]/[park-restore] lines when a RuntimeSetPositionState placement parks or a cancelled park's withdrawal is rolled back |
print-only, low volume (parks are rare); in a MULTI-session headless host, HeadlessStaticStateAudit.ValidateProcessIsolation THROWS HeadlessConfigurationException at startup if this (or any other process-global Probe*/Dump* boolean, CollisionShadowSampleEvery, or PhysicsResolveCapture) is enabled — refusal is waived only when sessionCount==1 (logs loudly and proceeds instead) |
PhysicsDiagnostics.ProbeParkEnabled |
ACDREAM_PROBE_PHANTOM |
#113, "throwaway apparatus — strip when the phantom closes" | =1 |
print-on-change [phantom-shell] / [phantom-objs] lines identifying which draw mechanism (shell pass vs. entity list) draws geometry unclipped/un-viewcone'd per cell |
print-only | RenderingDiagnostics.ProbePhantomEnabled |
ACDREAM_PROBE_PLACEMENT_FAIL |
issue #98 | =1 |
gates one [place-fail] line per Path-1 (Placement/Ethereal) Collided return in BSPQuery.FindCollisions, plus one per Transition.DoStepDown placement-insert rejection |
print-only; low volume (fires only on actual rejection) | PhysicsDiagnostics.ProbePlacementFailEnabled |
ACDREAM_PROBE_POLY_DUMP |
a6.p3 slice 4, issue #98 | =1 |
gates one [poly-dump] line (full polygon geometry: cell, poly index, sides, plane, all vertices) per AdjustSphereToPlane push-back call |
print-only; HEAVY output (one full-geometry dump per push-back call) — doc explicitly says "use briefly, then turn off" | PhysicsDiagnostics.ProbePolyDumpEnabled |
ACDREAM_PROBE_PORTAL_CHURN |
"throwaway apparatus — strip once the bound ships" | =1 |
one [portal-churn] summary per PortalVisibilityBuilder.Build call: per-cell pop/re-pop counts, re-enqueue totals, reciprocal-clip pre→post region growth |
print-only | RenderingDiagnostics.ProbePortalChurnEnabled |
ACDREAM_PROBE_PUSH_BACK |
phase a6.p1 | =1 |
gates [push-back] (BSPQuery.AdjustSphereToPlane), [push-back-disp] (BSPQuery.FindCollisions 6-path dispatcher), [push-back-cell] (Transition.CheckOtherCells multi-cell BSP) lines |
print-only; the DebugVM.cs:380 "runtime mirror" is dead code — DebugVM/DebugPanel (AcDream.UI.Abstractions/Panels/Debug/) are never instantiated anywhere in src/ (the ImGui frontend they required was removed at Campaign V slice V11); only the startup env var takes effect |
PhysicsDiagnostics.ProbePushBackEnabled |
ACDREAM_PROBE_PVINPUT |
"throwaway apparatus — strip once the jitter source is pinned" | =1 |
one [pv-input] line/frame with 6-dp-precision PortalVisibilityBuilder.Build inputs (camera eye, player position, VP elements) + resulting flood-cell count; deliberately runs WITHOUT the heavier [flap] probe so the log stays diffable |
print-only | RenderingDiagnostics.ProbePvInputEnabled |
ACDREAM_PROBE_REACH |
#334, temporary — strip with the probe family | =1 |
gates [reach-q] (per-cell candidate-disposition query summary, emitted even on zero-entry cells) and [reach-obj] (per-candidate disposition: exempt/no-shape/bsp-only-skip/tested) lines in Transition.FindObjCollisionsInCell |
print-only; runs on a HOT path (per cell per transitional insert); de-duplicated via two Dictionary caches with a lock-protected gate (_reachGate) — a real per-call dictionary lookup + occasional lock contention while on, bounded emission (≤2/sec per cell, ≤1/sec per candidate) |
PhysicsDiagnostics.ProbeReachEnabled |
ACDREAM_PROBE_REMOTE_LANDING |
bug a / issue #32, temporary | =1 |
gates [remote-landing]/[remote-landing-gate]/[remote-landing-after] lines around remote ground-contact edges in LiveEntityNetworkUpdateController and RuntimeRemotePhysicsUpdater; MotionTableDispatchSink.ApplyMotion unconditionally forwards its result to PhysicsDiagnostics.RecordRemoteLandingDispatch (self-guarded internally, no behavior change) |
print-only; uses [ThreadStatic] capture latches (_remoteLandingApplyCalls etc.) so a headless host ticking several sessions in parallel doesn't cross-contaminate |
PhysicsDiagnostics.ProbeRemoteLandingEnabled |
ACDREAM_PROBE_REMOTE_SLIDE |
bug b, temporary — strip once two-client roof capture lands | =1 OR =<comma-separated hex GUID list> |
gates [remote-slide-up]/[remote-slide-vec]/[remote-slide-snap]/[remote-slide-enq] lines across LiveEntityNetworkUpdateController, InterpolationManager, RuntimeRemotePhysicsUpdater, RuntimeRemoteSteadyStatePosition tracing two candidate remote-slide "blip" producers |
print-only; BeginRemoteSlideAttribution/GUID-stamping calls are UNCONDITIONAL at several call sites (self-guard is internal), so a [ThreadStatic] field write happens on every remote tick regardless of the flag (cheap, non-allocating); a GUID allow-list narrows output to specific entities for a readable two-client capture |
PhysicsDiagnostics.ProbeRemoteSlideEnabled + ProbeRemoteSlideGuids (raw string parsed via ParseHexIdList unless it's the literal "1") |
ACDREAM_PROBE_REMOTE_TELEPORT |
c4 route 4b-3, temporary | =1 |
gates one [remote-teleport] line per routed remote teleport arm in LiveEntityNetworkUpdateController.ApplyRemoteContactRouting |
print-only; a 2026-08-04 fix moved the enabled-check to the CALL SITE because the probe's internal self-guard did not prevent teleportStatus.ToString() from being evaluated/allocated on every teleport regardless of flag state — now properly guarded |
PhysicsDiagnostics.ProbeRemoteTeleportEnabled |
ACDREAM_PROBE_SEAMDRAW |
#176, "throwaway apparatus" | "1"/"true"/blank → default #176 Facility Hub cell set (7 fixed hex ids); otherwise comma-separated hex cell-id list |
change-deduped + 2 s-heartbeat [seam-cell]/[seam-snap]/[seam-ent]/[seam-mask] lines from EnvCellRenderer.Render and WbDrawDispatcher describing per-instance transforms and resolved light-set identities at target cells |
print-only | RenderingDiagnostics.ProbeSeamDrawEnabled / SeamDrawTargetCells |
ACDREAM_PROBE_SHELL |
#78, "throwaway apparatus — strip once the indoor-enclosure render is fixed" | =1 |
one [shell] line per opaque-pass EnvCellRenderer.Render call: per filtered cell — snapshot presence, gfxObj/batch/index/translucent/zero-bindless-handle counts |
print-only; allocates a StringBuilder and loops every visible cell on every opaque pass while enabled |
RenderingDiagnostics.ProbeShellEnabled |
ACDREAM_PROBE_STEP_HEIGHTS |
issue #338 | =1 |
gates edge-triggered [step-h] lines at prepare/publish/resolve sites tracing step-up/step-down height provenance |
print-only; AnnounceStepHeightProbeOnce prints TWO self-report lines EXACTLY ONCE PER PROCESS regardless of the flag's value (reports the flag's own state + the raw env var text + the running assembly's file path) — this self-report line is NOT gated by the flag itself, only rate-limited to once |
PhysicsDiagnostics.ProbeStepHeightsEnabled |
ACDREAM_PROBE_STEP_WALK |
a6.p3 issue #98 | =1 |
gates [step-walk] lines at select points in the transition sub-step loop and step-down probe (requested vs adjusted offset, sphere positions, contact planes, walkable flags) |
print-only; no DebugPanel mirror | PhysicsDiagnostics.ProbeStepWalkEnabled |
ACDREAM_PROBE_STICKY |
r5-v3 issue #171 | =1 |
gates [sticky] lifecycle lines (STICK/UNSTICK/LEASE-EXPIRE/TARGET-status teardown) and per-armed-tick steer lines in AcDream.Core.Physics.Motion.StickyManager, plus [sticky-snap-skip] in LiveEntityNetworkUpdateController when a server hard-snap is suppressed for a stuck entity |
print-only; heavy while a pack is stuck (~60 Hz × stuck count) | PhysicsDiagnostics.ProbeStickyEnabled |
ACDREAM_PROBE_SUPPORT |
issue #337, temporary | =1 |
gates [support] (per resolve, per body INCLUDING corpses/NPCs — independent terrain sample at the body's out-XY compared against the contact plane's height/provenance) and [geom] (once per nearby GfxObj — physics-BSP vertex cloud vs visual mesh AABB coincidence verdict) lines in PhysicsEngine |
print-only; [support] performs an INDEPENDENT terrain height sample every time it fires (real extra computation beyond the resolve itself, throttled to 4 Hz per body plus every 10 cm of vertical movement); pure reads only, never mutates production collision state |
PhysicsDiagnostics.ProbeSupportEnabled |
ACDREAM_PROBE_SWEPT |
phase w stage 0 | =1 |
gates one [cell-swept] line per ResolveWithTransition call comparing the transition's swept cell vs the legacy static ResolveCellId path |
print-only | PhysicsDiagnostics.ProbeSweptEnabled |
ACDREAM_PROBE_TELEPORT |
2026-06-22, "removable diagnostic" | =1 |
gates [tp-probe] lines (LogTeleport) at AIM/ENQ/BUILD/APPLY/PLACED teleport-pipeline events across LocalPlayerTeleportController and RuntimeAcceptedPositionDriveController, with cross-thread monotonic timestamps |
print-only | PhysicsDiagnostics.ProbeTeleportEnabled |
ACDREAM_PROBE_TEXFLUSH |
#105 | =1 |
one [tex-flush] line whenever WbMeshAdapter.Tick's staged-texture-update picture changes (pending layer updates before/after the per-frame mipmap flush) |
print-only | RenderingDiagnostics.ProbeTexFlushEnabled |
ACDREAM_PROBE_VIEWER |
#119-residual | =1 |
one [viewer] line per CHANGE of (root cell, flood size, OutsideView poly count, player cell), with mm-precision projection eye — capture half of the tower-ascent capture→replay loop (TowerAscentReplayTests) |
print-only | RenderingDiagnostics.ProbeViewerEnabled |
ACDREAM_PROBE_WALK_MISS |
issues #83, spike-only | =1 |
gates [walk-miss] (per Transition.TryFindIndoorWalkablePlane MISS) and [floor-polys] (per indoor cell cached, enumerating walkable-eligible polygons) lines |
print-only; no DebugPanel mirror | PhysicsDiagnostics.ProbeWalkMissEnabled |
ACDREAM_WIRE_MESH |
#337, explicitly "temporary" | =1 |
when the separate F2 collision-wireframe overlay is already active, replaces its cheap broadphase-proxy-cylinder drawing with the object's REAL physics-BSP polygon edges (cyan) + visual mesh AABB (magenta) + terrain triangle under the player (yellow), resolved live every frame | ALTERS RENDERED OUTPUT (debug overlay geometry): adds real per-frame physics-BSP polygon extraction + line-drawing cost while F2 is on; only takes effect when the separate F2 toggle (_state.CollisionWireframesVisible) is also enabled; also emits a throttled print-on-change stats line |
RenderingDiagnostics.CollisionMeshWireframeEnabled |
ACDREAM_WIRE_RADIUS |
companion knob to #337/acdream_wire_mesh |
=<float metres> (float.TryParse, invariant culture; falls back to 30 if unparsable or ≤0) |
sets the radius around the player within which CollisionMeshWireframeEnabled resolves polygon geometry |
larger radius = more physics-BSP polygon extraction/line-drawing cost per frame; only matters while ACDREAM_WIRE_MESH=1 |
RenderingDiagnostics.CollisionMeshWireframeRadius |
Deprecated
| Flag | Value | What it does | Side effects | Default | Read by |
|---|---|---|---|---|---|
ACDREAM_DEVTOOLS |
=1 |
logs a one-time "ImGui dev UI removed" notice; the only remaining functional consumer is VulkanGraphicsContext.cs:184 (enableOptionalExtensions: _options.DevTools, selects optional Vulkan validation/debug-utils extensions) |
real effect: turns on Vulkan validation/debug-utils extensions (can change perf and can surface validation-layer errors that don't occur when off) — NOT measurement-neutral for a perf gate; GameWindow.DevToolsEnabled is a hardcoded false const (dead — no ImGui dev UI exists to gate); DevToolsInputCaptureSource(bool enabled) explicitly discards its enabled ctor arg (_ = enabled;) — dead parameter, always reports WantCaptureKeyboard=false |
off | RuntimeOptions.DevTools (typed, Program.cs/RuntimeOptions.Parse) |
ACDREAM_STREAM_RADIUS |
=<int> (non-negative) |
Legacy override for the streaming near/far radii, applied on top of the quality-preset's radii at session-start composition. | CLAUDE.md explicitly documents this as "legacy" and warns against using it for measurement. Confirmed in code (SessionPlayerComposition.cs:256-259): nearRadius = legacyRadius; farRadius = Math.Max(legacyRadius, farRadius) — it FORCES NearRadius and only ever RAISES (never lowers) FarRadius. It is set once at session-start composition and is silently discarded by any later Settings quality change: RuntimeSettingsController.ApplyQuality → RuntimeSettingsTargets.ApplyQuality → StreamingController.ReconfigureRadii recomputes radii straight from the quality preset with no knowledge of this override. A measurement/gate run taken with this set is measuring a different streaming window than production and than any run that later touches Settings. |
null → quality-preset radii unmodified (production default: High preset, Near 4 / Far 12) |
RuntimeOptions.LegacyStreamRadius → SessionPlayerComposition.cs:254-268 |
Retired
Flags that no longer exist, kept only so a stale script or an old research document does not send someone hunting. Rows below this marker are exempt from the "must still exist" check.
| Flag | Retired | Replacement |
|---|---|---|
ACDREAM_RUN_SKILL |
Client-side run-skill override for local motion prediction. Skills now arrive from the server (LiveMovementStatsApplier); the hardcoded fallback is 200. |
none — server-authoritative |
ACDREAM_JUMP_SKILL |
As above. The fallback is 300, not the 200 that CLAUDE.md advertised. | none — server-authoritative |
ACDREAM_RENDER_BACKEND |
Selected the GL-vs-Vulkan backend. Campaign V deleted the OpenGL backend; Vulkan is the only one. Two comments still named it as a live co-requisite until 2026-08-24. | none |
ACDREAM_ANIM_SPEED_SCALE |
Animation-speed multiplier from the pre-retail-sequencer era; died with the 1.248x factor. | none |
ACDREAM_A8_AUDIT |
Phase A8 EnvCell batch/cull audit dump. Its only caller never existed; EnvCellRenderer.CollectCellAuditLines was unreachable and was deleted 2026-08-24. |
ACDREAM_PROBE_ENVCELL |