docs: launch-options reference + the test that keeps it honest
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>
This commit is contained in:
parent
92999b0101
commit
e77dd7c413
9 changed files with 744 additions and 165 deletions
125
CLAUDE.md
125
CLAUDE.md
|
|
@ -1555,108 +1555,35 @@ governed by whether the previous shutdown was graceful or forced.
|
|||
### Test character
|
||||
|
||||
`+Acdream` at server guid `0x5000000A`. Starts at or near Holtburg. Has
|
||||
basic stats; `ACDREAM_RUN_SKILL` / `ACDREAM_JUMP_SKILL` env vars (default
|
||||
200) set the *client-side* skill value used by `PlayerWeenie.InqRunRate`
|
||||
for local motion prediction. **These are NOT synced to the server** —
|
||||
ACE's own character data is authoritative for broadcast motion. If you
|
||||
see a speed/anim mismatch between local and observer views, the fix is
|
||||
to sync the runSkill from ACE via `UpdateMotion.ForwardSpeed` echo (wired
|
||||
via `PlayerMovementController.ApplyServerRunRate`) or from
|
||||
`PlayerDescription (0x0013)`.
|
||||
basic stats. Run/jump skills arrive FROM the server and drive local motion
|
||||
prediction (`LiveMovementStatsApplier` → `PlayerMovementController`); the
|
||||
hardcoded fallbacks before the server speaks are 200 run / 300 jump. The
|
||||
former `ACDREAM_RUN_SKILL` / `ACDREAM_JUMP_SKILL` client-side overrides no
|
||||
longer exist — see the Retired section of
|
||||
[`docs/launch-options.md`](docs/launch-options.md). If you see a speed/anim
|
||||
mismatch between local and observer views, check the server sync path
|
||||
(`UpdateMotion.ForwardSpeed` echo via
|
||||
`PlayerMovementController.ApplyServerRunRate`, or
|
||||
`PlayerDescription (0x0013)`).
|
||||
|
||||
### Diagnostic env vars
|
||||
|
||||
- `ACDREAM_DUMP_MOTION=1` — dump every inbound `UpdateMotion` (guid,
|
||||
stance, cmd, speed) + resulting `SetCycle` call. Massive for remote-
|
||||
animation debugging.
|
||||
- `ACDREAM_STREAM_RADIUS=N` — **legacy** streaming-radius override
|
||||
(`RuntimeOptions.LegacyStreamRadius`). **Default is UNSET**, not 2: the
|
||||
shipped radii come from the quality preset
|
||||
(`QualityPreset.High` = NearRadius 4 / FarRadius 12, i.e. a 9×9 Near ring
|
||||
inside a 25×25 Far window). When set it FORCES `NearRadius = N` and only
|
||||
ever RAISES `FarRadius` (`SessionPlayerComposition.ComposeCore`), and it is
|
||||
silently discarded by any later Settings `ApplyQuality`
|
||||
(`RuntimeSettingsTargets.ApplyQuality` → `ReconfigureRadii`). **Leave it
|
||||
unset for any measurement or gate run** — with it set you are measuring a
|
||||
different window than production. Per-axis overrides
|
||||
`ACDREAM_NEAR_RADIUS` / `ACDREAM_FAR_RADIUS` (`QualitySettings.WithEnvOverrides`)
|
||||
are the modern spelling.
|
||||
- `ACDREAM_PROBE_REVEAL_RADIUS=N` — #280 A/B measurement probe
|
||||
(`StreamingDiagnostics.RevealRadiusOverride`). Forces the outdoor reveal
|
||||
gate to landblock radius N instead of the derived streaming window, so the
|
||||
same binary can run a route once with the pre-#280 behaviour (`=1`) and once
|
||||
without. Not a user setting; not surfaced in Settings; not persisted.
|
||||
Values below 1 are rejected by the parser: an outdoor acknowledgement with
|
||||
`RequiredRenderRadius == 0` fails Runtime's `invalid-readiness-shape`
|
||||
invariant, so `=0` would hang the route it is meant to measure.
|
||||
- `ACDREAM_NO_AUDIO=1` — suppress OpenAL init for headless / driver-
|
||||
broken setups.
|
||||
- `ACDREAM_REMOTE_VEL_DIAG=1` — dump per-tick / per-UM remote motion
|
||||
diagnostics (`[UM_RAW]`, `[SCFAST]`, `[SCFULL]`, `[SETCYCLE]`,
|
||||
`[FWD_WIRE]`, `[OMEGA_DIAG]`, `[SEQSTATE]`, `[PARTSDIAG]`,
|
||||
`[VEL_DIAG]`, `[UPCYCLE]`). Heavy.
|
||||
- `ACDREAM_PROBE_RESOLVE=1` — one `[resolve]` line per
|
||||
`PhysicsEngine.ResolveWithTransition` call: input + target + output
|
||||
position/cell, ok-vs-partial, grounded-in, contact-plane status,
|
||||
wall normal if hit, **responsible entity guid**, env flag, walkable
|
||||
polygon valid. Heavy (~30 Hz × every entity). Runtime-toggleable via
|
||||
the DebugPanel "Diagnostics" section if `ACDREAM_DEVTOOLS=1`.
|
||||
- `ACDREAM_PROBE_CELL=1` — one `[cell-transit]` line per
|
||||
`PlayerMovementController.CellId` change: old → new cell, world
|
||||
position, reason tag (`resolver` / `teleport`). Low volume — only
|
||||
fires on actual cell crossings. Runtime-toggleable via the same
|
||||
DebugPanel section.
|
||||
- `ACDREAM_PROBE_PUSH_BACK=1` — emits three line types per physics
|
||||
tick: `[push-back]` (per `BSPQuery.AdjustSphereToPlane` call),
|
||||
`[push-back-disp]` (per `BSPQuery.FindCollisions` dispatch),
|
||||
`[push-back-cell]` (per `Transition.CheckOtherCells` off-cell hit).
|
||||
Heavy under motion (~100–500 lines/sec). Pair with retail's cdb
|
||||
breakpoint set at `tools/cdb/a6-probe.cdb` for the A6.P1 capture
|
||||
protocol. Runtime-toggleable via the DebugPanel.
|
||||
- `ACDREAM_PROBE_FLAP=1` — capture probe for indoor visibility
|
||||
decisions at frame boundaries. Used to converge the U.4c flap fix
|
||||
(root indoor visibility at player's cell, not eye).
|
||||
- `ACDREAM_PROBE_STICKY=1` — per-guid sticky-melee timeline: `[sticky]`
|
||||
lifecycle lines (STICK/UNSTICK/LEASE-EXPIRE/TARGET-status teardown),
|
||||
per-armed-tick steer lines (signed gap dist, applied delta, heading
|
||||
delta), `[sticky-snap-skip]` at the suppressed NPC UP-snap site.
|
||||
Heavy while a pack is stuck (~60 Hz × stuck count). Converged the
|
||||
#171 residuals (the deep-overlap sign pin AP-82).
|
||||
- `ACDREAM_PROBE_SUPPORT=1` — **what is holding a body up, and is the
|
||||
collision geometry where the visual geometry is?** (#337, TEMPORARY).
|
||||
`[support]`: one line per resolve **for every body, not just the player**
|
||||
(a corpse falling through geometry is the cheapest control there is on
|
||||
"movement code vs geometry data"). It samples the outdoor terrain
|
||||
independently at the body's own out-XY and prints the contact plane's own
|
||||
height at that same XY, so `support=terrain` / `object` / `none` is a
|
||||
measurement rather than an inference; `cpSrc=` names the site that wrote
|
||||
the plane so provenance cross-checks the classification. Edge-eager,
|
||||
throttled to 4 Hz per body, and emits every 10 cm of vertical movement.
|
||||
`[geom]`: once per GfxObj near the mover — the object's physics-BSP vertex
|
||||
cloud against its visual mesh AABB in the same frame, with a verdict
|
||||
(`coincident` REFUTES "collision isn't where the visual is";
|
||||
`no-physics-bsp` / `empty-physics-bsp` / `displaced` / `extent-mismatch`
|
||||
each name a data defect). `ACDREAM_PROBE_RESOLVE` alone cannot separate
|
||||
those cases — it carries no plane normal, no plane height, no terrain
|
||||
sample and no provenance.
|
||||
- `ACDREAM_WIRE_MESH=1` — upgrades the existing **F2** collision overlay from
|
||||
a broadphase proxy cylinder to the real physics-BSP polygon edges (cyan)
|
||||
beside the same objects' visual mesh boxes (magenta) and the terrain
|
||||
surface (yellow). Settles "visual versus collision" by eye instead of by
|
||||
log. `ACDREAM_WIRE_RADIUS=<metres>` sets the window (default 30).
|
||||
TEMPORARY, with the #337 probe family.
|
||||
- `ACDREAM_CAPTURE_RESOLVE=<path>` — live capture of every player-side
|
||||
`PhysicsEngine.ResolveWithTransition` call. Each call appends one
|
||||
JSON Lines record with full inputs, PhysicsBody snapshot before AND
|
||||
after, plus the `ResolveResult`. Filtered to `IsPlayer` mover flag
|
||||
— NPC / remote DR calls don't pollute. Pairs with the trajectory
|
||||
replay harness comparison tests to diff captured vs harness state
|
||||
per field — the first divergence pinpoints missing apparatus state.
|
||||
Capture is OFF when the env var is unset (one null-check cost per
|
||||
call).
|
||||
- `ACDREAM_DUMP_CELLS=<path>` / `ACDREAM_DUMP_GFXOBJS=<path>` — dump
|
||||
resolved cell/GfxObj polygon tables as JSON when ids cache. Used
|
||||
for harness fixture extraction.
|
||||
Every environment variable and command-line argument the client reads —
|
||||
what it does, its exact value shape, and **what else it changes about the
|
||||
run** — is documented in
|
||||
[`docs/launch-options.md`](docs/launch-options.md). That file is the single
|
||||
source of truth and is enforced by `LaunchOptionsDocumentationTests`: a
|
||||
flag without a documented row fails the build, and so does a documented row
|
||||
whose read site was deleted.
|
||||
|
||||
Two habits that list exists to enforce:
|
||||
|
||||
- **Read the side-effects column before any measurement.** Flags that look
|
||||
inert are not: `ACDREAM_AUTOMATION_ARTIFACT_DIR` also builds a per-frame
|
||||
diagnostics referee (#432), and `ACDREAM_STREAM_RADIUS` measures a
|
||||
streaming window production never uses.
|
||||
- **A temporary probe dies with its investigation.** Add the row when you
|
||||
add the probe; delete both in the commit that fixes the issue.
|
||||
|
||||
### Outbound motion wire format (acdream → ACE)
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue