docs(render): audit Campaign AR completion evidence

This commit is contained in:
Erik 2026-08-22 14:18:21 +02:00
parent d84edf0ceb
commit 772526d0cd
4 changed files with 92 additions and 14 deletions

View file

@ -61,8 +61,6 @@ accepted-divergence entries (#96, #49, #50).
| IA-21 | When ACE sends player BoolProperty `68` (`SpellComponentsRequired`) false, acdream presents the retail scarab/prismatic-taper formula even without a directly carried school focus. With component enforcement enabled, retail's exact focus/infusion versus account-customized selection remains intact. | `src/AcDream.App/Spells/SpellComponentRequirementService.cs` | A component-disabled server has no actionable legacy recipe; explicit product direction is that this client/server mode uses the modern scarab/taper component presentation | A custom server could expect retail's legacy recipe to remain visible even though casting consumes no components | `ClientMagicSystem::AreSpellComponentsRequired @ 0x00567B90`; `ClientMagicSystem::GetAppropriateSpellFormula @ 0x00567D50`; `CSpellBase::InqScarabOnlyFormula @ 0x00597050` |
| IA-22 | **Filed 2026-08-13 (#391, user-directed: "we should only support modern resolutions. Not any old format").** The Config Resolution dropdown offers a CURATED list — the monitor's real mode enumeration filtered to modern widescreen families (16:9/16:10/21:9/32:9, ≥1280 wide, fitting the desktop; `DisplayModeCatalog.Curate`) — and its Defaults value is the desktop's own mode. Retail offered the adapter's complete enumeration including 4:3 legacy modes and authored `800x600` as the row default (`gmConfigUI::InitOptions SetDefaultValue(0x03200258)`; `gmClient::Init @0x004047af` `Device::ForceDisplayResolution(1, 0x320, 0x258)`). | `src/AcDream.App/Rendering/DisplayModeCatalog.cs`; `src/AcDream.App/UI/Layout/ConfigOptionsPageController.cs` (Resolution row); fixture fallback `src/AcDream.UI.Abstractions/Panels/Settings/DisplaySettings.cs` (`AvailableResolutions`, 800x600 removed) | Explicit product direction. **Amended 2026-08-16 (#407, Campaign CC gate round 1):** the dropdown now offers `DisplayModeCatalog.WindowedResolutions` — the curated hardware modes UNIONed with the static modern-ladder sizes that fit the desktop — because a WINDOWED pick is a plain Size write needing no video mode, and remote/RDP virtual displays advertise almost no modes (the live RDP display exposed only 1920x1080 + the 2056x1290 desktop, starving the dropdown). The original "an offered mode is supported by construction" invariant now holds for the FULLSCREEN half only: the fullscreen apply still validates against the hardware `Resolutions` list plus `GlfwDisplayModeSwitcher`'s monitor-mode-list hard guard, so a fullscreen pick of a windowed-only entry refuses safely (log-and-stay, #388; the #392 apply-result seam is that family's open follow-up) — "Graphics mode not supported" crashes remain unreachable from the dropdown. | A user wanting a genuine legacy 4:3 mode cannot pick it; retail-parity comparisons of the Config tab's list/default will show the deviation. | decomp sites in the Divergence column; ISSUES #391 |
| IA-23 | **Filed 2026-08-17 at the night-round review fix round (F8).** `gmHouseUI::DisplayPurchaseTimeText @0x004a3110`'s not-yet-expired branch renders `"You may buy another landscape house at " + strftime("%c", localtime(timestamp + 0x278d00)) + ". This restriction does not apply to apartments."` — byte-decoded from raw pushed literals at `@0x004a3265`/`@0x004a321d`/`@0x004a3235` (all three text pieces confirmed; a prior filing had wrongly called this "unrecoverable"). This port renders the SAME three pieces, in the same order, with the same expiry-timestamp math, but formats the middle date/time piece with .NET's culture-default `DateTime.ToString()` (no explicit format string) rather than the C runtime's `strftime("%c", ...)` — the two engines do not share a format table, so the RENDERED SHAPE of the date/time differs (e.g. .NET's short numeric date+time vs the CRT's `Ddd Mon DD HH:MM:SS YYYY`-style locale string) even though both express "the process's own locale's full date+time" and use the SAME underlying instant (local time, matching retail's `localtime()`). | `src/AcDream.Runtime/Gameplay/RuntimeHouseState.cs` (`Recompute`'s not-expired branch) | Both are "whatever the process locale says" full date+time strings; no game-logic reads or parses this text back, it is pure chat-scroll presentation, so a differently-shaped (but equally legible) date string carries no functional risk | A retail-side-by-side visual comparison will show a differently formatted date/time (not a byte-identical `strftime("%c")` reproduction) — cosmetic only | `gmHouseUI::DisplayPurchaseTimeText @0x004a3110`; `strftime`/`localtime` CRT calls at `@0x004a322c`/`@0x004a3216` |
| IA-24 | **Filed 2026-08-22, Campaign AR.** An explicitly selected atmospheric render pack adds cascaded real-time directional shadows from terrain, trees, buildings, players, monsters, and other retained outdoor casters. The one shadow direction follows the visible authored sun, then the dominant haloed moon (`0x01001F6A`), then the secondary moon (`0x01001F67`); a moon supplies direction only while colour/energy remains retail's single interpolated `SkyTimeOfDay.DirColor × DirBright` channel. Retail renders none of these real-time object-shadow maps and does not expose a second moon light. | `src/AcDream.App/Rendering/Packs/AuthoredCelestialShadowSource.cs`; `src/AcDream.App/Rendering/DirectionalSunShadowRenderer.cs`; pack-only receiver shaders; evidence `docs/research/2026-08-22-dereth-celestial-shadow-sources.md` | This is the user-requested headline graphics enhancement and is strictly opt-in. The retail path remains the default and authoritative fallback; pack-off does not build/select shadow work or change `SceneLighting`. One selected source reuses one cascade array, so moon support does not multiply shadow resources. | Pack-on output intentionally differs from retail. A wrong celestial identity/transform or stale source transition would visibly misalign shadows from the sky; pack-off output changing would violate the campaign's primary safety contract. | `SkyDesc::GetLighting @0x00500A80`; `GameSky::UseTime @0x005075B0`; installed Region `0x13000000`; cited research note |
---

View file

@ -412,11 +412,10 @@ claim):
evidence; its ACE-backed execution and artifacts remain open below.
- The complete Release solution, including all three SDK samples, the
validator, shader compiler/generated manifest, and repository tools, builds
with **0 warnings and 0 errors**. The current managed workspace could not
repeat the gate's locked-restore stage because it denies NuGet access to the
user-profile `NuGet.Config`; the explicit no-restore build and complete test
stage above are current, while locked-restore verification remains a
closeout-environment requirement rather than being reported as green here.
with **0 warnings and 0 errors**. This historical checkpoint could not repeat
locked restore because that managed workspace denied NuGet access to the
user-profile `NuGet.Config`; the later Stage 1 moon gate and final Stage 2
gate supersede that limitation and both report forced locked restore green.
The corresponding durable source/test entry points are:
@ -537,8 +536,8 @@ strict SDK-equivalent entry admission, asynchronous candidate preparation,
frame-boundary activation/withdrawal/fallback, registration-scoped no-retry,
stable diagnostics, no-op sample, and headless exclusion are present and
automated. The checked-in default-path oracle and RX 9070 XT physical pack-off
rows pass; connected lifetime evidence and the remaining supported physical GPU
classes stay open.
rows pass; connected lifetime and graphical package evidence now pass. The
remaining supported physical GPU classes stay open.
Define the versioned BCL-only descriptor/registry, manifest fields, semantic
bindings, pack discovery, Display selection, diagnostics, and atomic
@ -575,8 +574,9 @@ slice meets its preset GPU/VRAM budget.
**Implementation:** complete. Authored sun projection, the screen-space
occlusion mask, declared sun/day-group/weather policy, pre-tonemap ray
composition, and deterministic disabled gates are implemented and automated.
The connected dawn/noon/dusk, weather, behind-camera, occlusion, and edge-
flicker visual matrix remains open.
Connected time/weather transitions pass; physical-display acceptance for
dawn/noon/dusk, behind-camera, occlusion, and edge-flicker behavior remains in
the final owner visual matrix.
Project the existing authored sun position, build a screen-space occlusion
mask, and composite weather-driven crepuscular rays before tonemapping. This
@ -667,9 +667,10 @@ volumetric pass reuses directional-shadow depth only when the selected source
is the authored sun, consumes authored sun/weather/indoor inputs, composites
before tonemapping, and has independent quality/step settings and automated
failure gates. The reference-GPU low-sun 2,048-sample enabled/neutral A/B passes
its incremental cost target. Moon selection does not enable moon shafts. The
connected occluder/weather visual matrix and additional physical GPU classes
remain open.
its incremental cost target. Moon selection does not enable moon shafts.
Connected weather/lifecycle transitions pass; physical-display
occluder/weather acceptance in the final owner matrix and additional physical
GPU classes remain open.
Reuse the directional shadow map for world-space light shafts only while its
source is the authored sun. Drive density, strength, and colour from authored
@ -927,6 +928,9 @@ and adds the current renderer's ownership and lifecycle boundaries.
## Completion gate
The requirement ledger and the exact remaining external rows are consolidated
in the [Campaign AR completion audit](../research/2026-08-22-atmospheric-campaign-completion-audit.md).
The design, implementation, Stage 1 owner gate, and every available
machine-local Stage 2 connected, performance, lifetime, package, shader, build,
and complete-test gate are complete. The campaign becomes **shipped** only

View file

@ -0,0 +1,73 @@
# Campaign AR completion audit
**Date:** 2026-08-22
**Branch:** `codex/atmospheric-rendering-campaign`
**Status:** all implementation and machine-local gates complete; not shipped
## Audit boundary
This is the requirement-by-requirement closeout audit for
[Campaign AR](../plans/2026-08-21-atmospheric-rendering.md). It uses the
measured evidence and constraints in the
[terrain and atmospheric findings](2026-08-21-terrain-and-atmospheric-rendering-findings.md)
without re-deriving them or revisiting that report's three refuted claims. The
detailed connected results remain in the
[Stage 2 report](2026-08-22-atmospheric-stage2-connected-gate.md).
The last remote fetch reported `origin/main` at `6c79d35c`; merge `99cf26e0`
is in this branch and `git rev-list --left-right --count HEAD...origin/main`
reported 11 branch commits and zero missing main commits before this audit's
documentation-only closeout commit.
## Requirement ledger
| Requirement | Verdict | Authoritative evidence |
|---|---|---|
| Stage 1 project-owner stop | Pass | The owner's 2026-08-22 “Looks good!” acceptance, after exposure 1.0 → 0.80, is recorded in the [live-gate report](2026-08-22-atmospheric-stage1-live-gate.md). |
| Retail-faithful path stays default and authoritative | Pass | The checked-in production no-op oracle, six physical pack-off rows, connected disable/restore transitions, and package-failure rows all pass. A branch diff contains only newly named atmospheric/detail shader sources plus the generated shader manifest; no pre-campaign retail shader source is modified. |
| Physics and collision unchanged | Pass | `git diff origin/main...HEAD -- src/AcDream.Runtime src/AcDream.App/Physics src/AcDream.Core/Physics` is empty. The connected routes use the existing gameplay simulation without changing it. |
| Tier 1 bloom, filmic tone mapping, colour grade, vignette, neutral settings, resize, and retained-UI/private-view isolation | Pass for implementation and available automation/physical rows | Slice 1 tests and the RX 9070 XT 30-row matrix pass; final project-owner image judgment remains below. |
| Tier 1 authored-sun rays | Pass for implementation and connected state transitions | Authored sun/day-group/weather, occlusion-mask, behind-camera/off gates, and pre-tonemap composition are automated; connected time/weather transitions pass. Final physical-display dawn/noon/dusk, occlusion, and edge-flicker judgment remains below. |
| Tier 2 moving authored sun/moon shadows are the headline | Pass for implementation, Stage 1 owner gate, and available connected rows | The selected-source contract, stabilized cascades, opaque/cutout casters, animated transforms, receivers, outdoor/indoor gating, and weather energy pass. Connected metadata proves terrain, outdoor statics, buildings, animated statics, local player, non-player creatures, other dynamics, and equipped children. The distinct-account remote-player row remains below. |
| Headline caster membership without fabricated identity | Pass | Diagnostics report source-owned `OutdoorStatics` and `NonPlayerCreatures` rather than guessing tree or hostile-monster identity. The transition capture published 6,624 casters and the capped route reached 9,533. |
| Low/Medium/High/Auto scaling and weak-hardware fail-safe | Pass on available hardware | The exact RX 9070 XT 30-row matrix passes. The integrated AMD Auto run retires atomically to retail with a visible reason and a 0.00365% paired sky-masked difference. Other physical adapters remain below. |
| Tier 2+ sun-only volumetric shafts | Pass for implementation and available performance/lifecycle rows | Sun-only selection, weather/indoor gates, independent quality, depth reuse, neutral A/B, and the 2,048-sample reference-GPU cost row pass. Final owner occluder/weather judgment remains below. |
| Connected select/disable/re-enable, resize, weather, interior/dungeon, portal, reconnect, and fresh renderer/device recreation | Pass | [`logs/connected-world-gate-20260822-132443/report.json`](../../logs/connected-world-gate-20260822-132443/report.json): three clean graphical processes, graceful exits, 77/77 terminal render-scene shadow parity, zero mismatch, and zero pending deltas. |
| Dense turning/frame-pacing and desktop-performance investigation | Pass | Matched Medium/retail dense-Arwic reports show the reported turning hitch on both paths. Medium does not worsen CPU p95 (32.2 vs 32.9 ms) and adds about 0.70.9 ms GPU work. Pack-owned CPU/GPU/memory measurements stay within Medium budgets. |
| Long-run resource convergence | Pass | [`logs/connected-r6-soak-20260822-134004.report.json`](../../logs/connected-r6-soak-20260822-134004.report.json) completes the 516.064-second nine-stop route with movement/jump/combat, revisits, convergence, and graceful shutdown. Deterministic 12-cycle and fresh-device fixtures also pass. |
| External pack install/select/update/remove/fail/recover | Pass | [`artifacts/atmospheric-rendering/connected-package-lifecycle-20260822-135333/report.json`](../../artifacts/atmospheric-rendering/connected-package-lifecycle-20260822-135333/report.json): all six fresh connected graphical processes pass; failures create no half-active pack and corrected recovery is explicit. |
| Public pack API and SDK | Pass | BCL-only v1 contracts, manifest schema, semantic bindings, compatibility guide, validator, built-in pack, no-op sample, and two Tier-2 samples are present. External projects reference only `AcDream.Plugin.Abstractions`, not App or Vulkan. |
| Shaders and generated artifacts | Pass | Managed regeneration compiles 24/24 Vulkan pairs. The final release gate reports no tracked SPIR-V difference after regeneration. |
| Locked restore, Release build, and complete hermetic tests | Pass | [`artifacts/atmospheric-rendering/stage2-closeout-release-gate-d78ce100/release-gate-summary.json`](../../artifacts/atmospheric-rendering/stage2-closeout-release-gate-d78ce100/release-gate-summary.json): clean exact code commit `d78ce100`, locked restore pass, zero-warning/error Release build, and 15,179/15,179 tests passing with zero skips/failures across 14 assemblies. |
| Campaign documentation and divergence registration | Pass | Campaign plan, SDK docs, Stage 1/2 reports, roadmap pointer, release-gate graph update, IA-24, and this audit are present. Phase identifier remains **Campaign AR**. |
| M4 priority is not displaced | Pass | The roadmap and campaign plan retain M4 as the active gameplay milestone and describe Campaign AR as owner-authorized parallel work. No roadmap milestone is reassigned. |
## Exact remaining external gates
No further renderer, SDK, tool, test, or machine-local documentation work is
known from this audit. Campaign AR remains deliberately **not shipped** until
all three evidence classes below pass:
1. **Distinct-account remote player.** Run
`tools/run-connected-render-pack-remote-player-gate.ps1` with separate
primary and observer ACE credentials. Require a nonzero authoritative
`RemotePlayers` caster count plus a visible moving remote-player shadow.
The same-account attempt is recorded in
[`artifacts/atmospheric-rendering/connected-remote-player-20260822-140355/report.json`](../../artifacts/atmospheric-rendering/connected-remote-player-20260822-140355/report.json): the observer entered and moved, then ACE rejected the concurrent primary session. The corrected gate does not serialize credentials.
2. **Unavailable physical adapters.** On every other supported physical Vulkan
adapter, run the source-identical matrix for pack-off, Low, Medium, High,
and Auto at 1920×1080, 2560×1440, and 3840×2160, each capped and uncapped.
That is 30 rows per adapter. The installed RX 9070 XT already passes all 30;
the installed integrated AMD row proves Auto-to-retail fallback only, so
active Low and the other 29 rows on that adapter also remain external.
3. **Final project-owner visual acceptance.** Compare pack off and pack on for
Tier-1 neutral output and private views/UI; sun rays at dawn/noon/dusk,
behind-camera and occluded states; foliage cutouts; moving local, remote,
creature, tree, and building shadows under sun and moon; indoor gating;
source transitions; temporal shimmer/pixelation and cascade/bias artifacts;
sun-only volumetric weather/occluder behavior; and exact pack-off
restoration. The owner must explicitly accept both sides before the plan or
roadmap says shipped.
These are evidence gates, not open implementation slices. Any failure reopens
only the behavior it contradicts; passing them closes the campaign.

View file

@ -172,3 +172,6 @@ not available to this machine-local run:
These are evidence gates, not authorization for more renderer features. The
current code, SDK, connected lifecycle, package lifecycle, long lifetime, and
machine-local automation are complete.
The campaign-wide requirement ledger and exact external-row definition are in
the [Campaign AR completion audit](2026-08-22-atmospheric-campaign-completion-audit.md).