acdream/docs
Erik e6362da5c2 fix(diag): resolve the multisampled backbuffer before reading it
Every automated pixel gate and every blank-world verdict in Campaign V is
produced by FrameScreenshotController reading the default framebuffer with
glReadPixels. The window is created with the quality preset's MSAA sample
count, so that framebuffer is normally 4x multisampled -- and glReadPixels
against a multisampled read framebuffer is undefined per the GL spec. The
instrument the campaign has been using to decide "did the world render?"
rested on an operation with no specified result.

That is not a theoretical complaint. The blank-world investigation spent
several rounds unable to tell "the renderer drew nothing" apart from "the
readback did not return what the renderer drew", and it took an out-of-process
desktop grab to separate them. A gate cannot arbitrate a rendering defect
while its own read is unspecified.

So the capture resolves first: when the default framebuffer is multisampled
it blits the whole colour buffer into a single-sampled RGBA8 framebuffer with
identical rectangles and GL_NEAREST -- the defined resolve -- and reads that.
A single-sampled default framebuffer keeps the original direct read, so
non-MSAA captures stay byte-for-byte what they were. The blit disables and
restores the scissor test, because a blit is subject to it and a frame that
left a rectangle armed would otherwise resolve only part of the image; that
is the same self-contained-GL-state rule the render passes follow. The
resolve target is created and destroyed per capture -- captures are rare, and
a cache would have to track resize and context teardown for no gain.

GlGpuDevice.CaptureBackbuffer had the identical undefined read. It now routes
through the same path rather than being a second instrument to keep sound.

The IDefaultFramebufferSurface seam grows the draw binding, the sample count,
and the resolve operations, so the bind/query/blit/read/restore order stays
assertable without a GL context; two new tests pin the resolve order and the
resolve target's release on a failing read.

Gates: Release build green. App tests 3,866 passed / 3 skipped. Offline pixel
gate against fed636b9 passes at a differing fraction of 4.08e-05 against the
0.001 threshold -- which is exactly the same-commit control pair measured at
this commit, i.e. indistinguishable from ambient noise. Same-commit controls
re-measured at 17 px (fed636b9) and 23 px (here) out of 563,200; the recorded
band in plan section 5.1 widens to 15-23 px, fraction <= 4.1e-05.

Plan section 5.5.1 records what the connected investigation established: the
interleaved A/B attribution (4/5 vs 0/5, p ~ 0.024), the desktop witness
showing every depth-tested draw missing while the atmosphere clear and the
complete retained UI present, the probe evidence that the CPU dispatched
3,331 statics with no GL error, and the falsification list -- including the
ring glBufferSubData hazard, which condition 1 shipped against and did not
fix.

Section 5.5.2 records this session's second investigation, run against a
staged (never committed) V4c with log-only glGet* probes, and it closes the
shared-3-D-state hypothesis. The depth plane is bit-identical on blank and
rendered frames -- test on, write mask on, GL_LESS, clear value 1.0, range
[0,1], full viewport, full colour mask, no clip distances. The camera
constants are sane and advancing. Forcing gl_ClipDistance off left the blank
rate unchanged at 3/5. glGetGraphicsResetStatus returned NO_ERROR in all
1,814 samples across four blank runs, which also retires the "GPU-side fault"
reading in its context-reset form.

Two sharper facts replace it. Replacing only the frame clear colour with
magenta makes a blank frame come back uniformly magenta under the complete
retained UI, so no 3-D fragment is rasterized at all -- the world is not
drawn-then-hidden, fogged, or overdrawn. And on a blank run the client's own
capture of framebuffer 0 is RGBA(0,0,0,0) in every pixel, including pixels
where the UI is visibly on screen at that moment. That survives this commit's
resolve fix, so it is a second, independent instrument fault: the screenshot-
byte verdict used by the repeat and A/B gates measures the readback, not the
renderer, and those gates need to assert on the desktop witness instead.

V4c is NOT re-landed. No fix was attempted, because the mechanism is not
renderer state and does not sit in V4c's surface as this hypothesis predicted.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-28 00:54:59 +02:00
..
architecture docs: reconcile project state and refresh README 2026-07-27 12:53:31 +02:00
audit docs: update audit — Sprint 1 items verified (sequence counters + scenery LCG) 2026-04-13 13:51:39 +02:00
plans fix(diag): resolve the multisampled backbuffer before reading it 2026-07-28 00:54:59 +02:00
reference docs(reference): preserve local ACE command catalog 2026-07-27 00:03:58 +02:00
research docs(linux): park Slice L at L1 checkpoint 2026-07-27 12:35:47 +02:00
superpowers fix(world): remove non-retail portal exit fade 2026-07-15 23:20:52 +02:00
bugs.md docs: reconcile project status and navigation 2026-07-20 13:00:41 +02:00
ISSUES.md feat(render): add integer vertex attributes and the terrain tiling binding 2026-07-27 21:11:48 +02:00
README.md docs: reconcile project state and refresh README 2026-07-27 12:53:31 +02:00

acdream documentation map

This page is the entry point for project documentation. It distinguishes current sources of truth from implementation history so an old plan or issue banner cannot silently override the current program state.

Current snapshot — 2026-07-27

  • Milestone state: M3, “Cast a spell,” landed 2026-07-21. M4, “Live in the world,” is active.
  • M4 gameplay program: resume the pre-M4 world-interaction completion program. Favorite-spell overflow, status Use/Assess, and the complete assessment surface are user-accepted. Equipped-child picking and vendor browse/transactions remain Slices 46.
  • Structural/runtime state: all eight GameWindow decomposition slices, Modern Runtime Slices AJ, and the connected visual/lifecycle gates are complete. GameWindow is a 1,622-line composition/callback shell. AcDream.Runtime.GameRuntime owns canonical session, entity/object, gameplay, movement, physics, projectile, environment, and portal state; graphical and no-window hosts borrow the same owner graph.
  • Headless state: Slice K is complete. AcDream.Headless is a presentation-free Windows/Linux host with deterministic commands/events, shared immutable content, multi-session isolation, reconnect, resource telemetry, and 1/5/10/30-session gates. The final two-account native-Linux soak completed ten minutes, logged out through ACE, and converged every ownership ledger.
  • Linux graphical state: Slice L0 and the L1 implementation checkpoint are complete at 66f114b2 and 11501d52. Native Windows passes the active modern-GL/audio/window smoke. WSLg X11/Wayland correctly reject their missing GL_ARB_bindless_texture. Physical-Linux validation and L2L6 are explicitly deferred; resume at the supported AMD/NVIDIA L1 gate.
  • Completed gameplay gates: R6 locomotion/collision/projectile/teleport/ radar, two-client portal-out/materialization, indoor prepared collision, loot ordering, local/remote ground drops, and selection-marker lifetime.
  • Separate visual verification: issue #225, the shared-alpha lifestone/particle result; its connected resource-lifetime and performance routes pass.
  • Carried behaviour debt: issue #153 (far teleport onto an unstreamed edge), #116 (narrowed slide response), #235 (capped/RDP jump cadence), and the active temporary-stopgap rows in the divergence register.
  • Divergence audit: 189 active rows — IA 18, AD 38, AP 91, TS 38, and UN 4 — plus retained struck/retired historical rows such as TS-37.
  • Latest automated baseline: the Release build succeeds with the 17 test-project warnings tracked by issue #228; 8,826 tests pass and five are intentionally skipped. App passes 3,763 / 3 skips. The L1 Windows supported smoke and WSLg X11/Wayland negative-capability reports all end with zero window/GL/input/audio ownership.

Sources of truth

Read these in this order when deciding what to do next:

  1. plans/2026-05-12-milestones.md — the active playable outcome, freeze boundaries, and visual gates.
  2. plans/2026-04-11-roadmap.md — strategic phase ledger: shipped, active, deferred, and future work.
  3. ISSUES.md — tactical defects and small follow-ups. The status inside an issue is authoritative; physical order is not.
  4. architecture/retail-divergence-register.md — every known place runtime behavior can differ from retail.
  5. architecture/acdream-architecture.md and architecture/code-structure.md — ownership, dependency, update-thread, and extraction rules.
  6. architecture/worldbuilder-inventory.md — rendering/DAT code already owned in-tree versus mechanisms still ours to port.

If these disagree, milestones control the current outcome, the roadmap controls work ordering, the issue status controls the individual defect, and the architecture documents control implementation shape. Reconcile the stale document in the same change; do not leave both claims standing.

Research and implementation records

  • research/named-retail/ is the primary retail oracle: named pseudo-C, headers, symbols, and types from the Sept 2013 build.
  • research/decompiled/ is the older Ghidra fallback.
  • research/ contains focused pseudocode, traces, fixtures, and gate reports. A dated research note records evidence; it does not become a new roadmap.
  • superpowers/specs/ and superpowers/plans/ are per-slice design and execution records. Completed plans remain historical.
  • audit/ contains completion and conformance audits.
  • reference/ace-commands.md preserves the local ACE server's complete in-game command catalog and points to the authoritative per-command help surface.

Durable memory

  • ../claude-memory/MEMORY.md indexes the live subsystem memories and the render/physics digests. Read a domain digest before changing that subsystem, especially its DO-NOT-RETRY table.
  • ../memory/ contains stable engineering references such as the modern rendering pipeline, two-tier streaming, and toolchain notes.

Memory accelerates recall; it does not outrank the canonical documents above. When current truth changes, update the relevant canonical document and distill only the durable lesson into memory.

Historical and deprecated documents

  • bugs.md is the April 2026 bug snapshot. It is preserved for archaeology and is not an active ledger.
  • Dated plans and specs describe the decision at that time. Their completion wording is historical unless the current milestone/roadmap explicitly links the item as active.
  • Old R1→R8 architecture sequencing is superseded. Current execution comes from the milestones and strategic roadmap.

Documentation maintenance rules

  • Update milestone, roadmap, issue, divergence, architecture, and memory claims in the same commit when a shipped change affects them.
  • Keep one issue ID per defect. Narrow an issue in place; do not reuse another issue's number as a shorthand.
  • Mark automated, connected, and visual gates separately. An automated pass is not a visual acceptance, and an RDP throughput sample is not a local-display visual comparison.
  • Preserve research history, but remove stale “current/next” claims from living documents once the state advances.