acdream/docs/plans/2026-07-20-automated-world-lifecycle-gate.md

6.6 KiB

Automated world-lifecycle gate

Status: In progress (2026-07-20) Owner: M3 stabilization / R6 rendering-lifecycle rebaseline Depends on: WorldRevealReadinessBarrier, retained-UI automation, FrameProfiler, connected local ACE

Outcome

Create a deterministic connected Release gate that catches the structural failures which previously required someone to stare at the client for several minutes:

  • the first login frame cannot expose world geometry before the destination's render meshes, composite textures, and collision data are all ready;
  • every portal/recall lifetime crosses the same readiness edge, materializes once, and returns to the normal viewport once;
  • dungeon entry and exit use the same lifecycle without grey frames, stale-source geometry, or an uncollidable destination;
  • graceful logout followed by a fresh reconnect starts a new reveal lifetime and cannot inherit readiness or resources from the previous process;
  • repeated destinations do not cause cumulative memory, owner-count, allocation, update-time, or GPU-time growth;
  • each stable checkpoint produces machine-readable state plus a screenshot for later human comparison.

This is a correctness and resource-lifetime gate. Screenshots preserve visual evidence, but automation does not claim retail visual equivalence. Color, composition, animation feel, and subtle geometry artifacts remain user gates.

Canonical runtime contract

WorldRevealReadinessBarrier remains the only definition of destination readiness. It will expose a structured snapshot rather than forcing telemetry to repeat the readiness formula. A snapshot records the destination cell, indoor/outdoor classification, required radius, render publication, composite texture readiness, collision readiness, an impossible/unhydratable claim, and the final Ready result.

A focused App-layer WorldRevealLifecycleTelemetry owns diagnostic reveal generations. It has no GL calls and no knowledge of GameWindow. For each login or portal generation it records:

  1. begin;
  2. destination acquisition;
  3. each distinct readiness transition;
  4. the first frame where the normal world viewport is actually eligible to draw;
  5. completion or cancellation.

Making the normal viewport visible before Ready is a hard invariant failure, not a warning. A newer generation retires the older one, so stale asynchronous completion cannot satisfy the new destination.

GameWindow only supplies facts and invokes the controller at existing lifecycle seams. It does not gain a new feature body.

Production automation seam

The retained-UI automation runner gains runtime commands through an injected interface:

  • wait world-ready [timeout-ms] waits on canonical lifecycle state instead of a guessed sleep;
  • wait materialized <occurrence> [timeout-ms] waits for the authoritative portal completion count;
  • checkpoint <name> emits one JSON record containing reveal state, landblock/entity/animation and resource-owner counts, managed memory, and the latest frame-profiler summary;
  • screenshot <name> [timeout-ms] queues a default-framebuffer capture after the complete world and retained UI have drawn, then waits for the render thread to finish the PNG;
  • existing input commands perform deterministic turns and movement through InputDispatcher.

All state mutation and GL readback stay on the update/render thread. The external gate only launches the process, observes files/logs and OS process metrics, and requests normal WM_CLOSE shutdown.

Connected route

The gate runs two capped/uncapped-aware sessions against local ACE:

  1. fresh login → wait for canonical readiness → checkpoint + screenshot;
  2. outdoor dense scene → turn → stable checkpoint + screenshot;
  3. world-edge scene → turn → stable checkpoint;
  4. known dungeon destination → checkpoint + screenshot → local movement;
  5. return outdoors → checkpoint + screenshot;
  6. revisit the first dense scene → stable resource comparison;
  7. graceful close;
  8. reconnect the same account → repeat the fresh-login readiness and screenshot gate → graceful close.

The existing seven-destination R6 soak remains the longer performance route. The lifecycle gate is shorter and more diagnostic; it composes with that soak rather than replacing it.

Hard failures

  • world viewport observed before the active reveal snapshot is ready;
  • destination never reaches readiness or materialization within the bounded connected test timeout;
  • missing or duplicate reveal/materialization/completion edges;
  • missing checkpoint JSON or screenshot, zero-sized/corrupt screenshot;
  • absent required destination landblock/EnvCell/collision readiness;
  • retained per-owner resources after delete/session teardown in deterministic tests;
  • same-location resource counts or memory/per-frame allocation grow beyond the route's documented relative tolerance;
  • unhandled exception, access violation, OOM, GL/device loss, disconnect, unexpected WeenieError, nonzero exit, or failure of graceful shutdown.

Absolute FPS is recorded, never compared across local and RDP sessions. The gate compares like-for-like samples within one process and reports CPU and GPU frame time separately.

Implementation sequence

  1. Add a structured readiness snapshot and exhaustive barrier tests.
  2. Add lifecycle telemetry as a pure App owner with stale-generation, cancellation, duplicate, and early-visible tests.
  3. Add the automation runtime interface, deterministic waits, checkpoints, and screenshot request/completion protocol.
  4. Add the render-thread screenshot owner and structured resource snapshots.
  5. Wire the owners at login, F751 portal start, TAS placement/completion, world draw eligibility, and session teardown.
  6. Add the connected route and PowerShell report/gate orchestration.
  7. Run capped and uncapped Release gates, fix root causes, and retain artifacts.
  8. Extract the now-protected streaming/portal/reveal frame orchestration from GameWindow without changing the accepted lifecycle trace.
  9. Run focused tests, full Release build/test, connected gates, graceful-close verification, and documentation reconciliation.

Completion evidence

  • focused App tests for every lifecycle invariant;
  • full Release solution build and test suite;
  • two-process connected lifecycle report with screenshots and JSONL timeline;
  • accepted capped and uncapped same-session metrics;
  • GameWindow extraction retains the exact accepted lifecycle trace;
  • roadmap, issues, architecture, divergence register, memory, AGENTS.md, and CLAUDE.md agree on the resulting ownership and remaining visual gates.