acdream/docs/research/2026-08-02-collision-throughput-handoff/NEXT-AGENT-PROMPT.md

13 KiB
Raw Permalink Blame History

Next-agent prompt — finish the retail placement/collision campaign

Continue acdream from the 2026-08-03 stabilization checkpoint. The code is modern; behavior must remain retail-faithful. The campaign is playable again, but it is not closed.

Start here

Use the merged local main worktree:

C:\Users\erikn\source\repos\acdream

The completed fixes originated on codex/port-claude-agents and are merged into local main. Confirm the exact starting commit with git rev-parse HEAD and read the operator's handoff message for the merge SHA. Do not reset, clean, or overwrite the main worktree's untracked research/reference files. The original feature worktree remains at:

C:\Users\erikn\.codex\worktrees\af5e\acdream

That feature worktree contains protected user-local modifications and is not the preferred continuation workspace.

Read these files in order before editing:

  1. CLAUDE.md and AGENTS.md.
  2. docs/plans/2026-08-02-placement-cutover.md — canonical placement-cutover plan and the 2026-08-03 checkpoint.
  3. This prompt.
  4. docs/research/2026-08-02-collision-throughput-handoff/implementer-progress.md — especially ## P1 and the final stabilization checkpoint.
  5. docs/research/2026-08-02-collision-throughput-handoff/p1-retirement-receipt-loop.md.
  6. docs/research/2026-08-02-c3c-cutover-closeout.md.
  7. docs/ISSUES.md #269 and #276#280.
  8. docs/architecture/retail-divergence-register.md rows AP-1, AP-22, AP-131, AD-1, AD-10, AD-60, and TS-28.

docs-drafts.md is now explicitly historical. Do not apply it wholesale: it predates the final fixes and incorrectly tries to reuse issue number #280.

Binding rules

  • Grep docs/research/named-retail/acclient_2013_pseudo_c.txt by named class::method before fresh decompilation. Retail behavior is the oracle.
  • Preserve the modern Runtime-owned, presentation-independent architecture. Graphical and headless hosts must use the same canonical gameplay owners.
  • Root causes only. Do not add timeouts, grace periods, suppression flags, catch-and-swallow paths, duplicated placement writers, or compatibility bypasses to make a test green.
  • The user's connected observations are acceptance facts. A green automated test cannot overrule a live regression.
  • Never use git add -A, git add ., git reset --hard, or git checkout -- <path>. Stage exact paths only.
  • Do not delete or normalize unrelated/untracked worktree content.
  • Each independent fix must be a bisectable commit whose message records the root cause and evidence.
  • Update the divergence register and issues in the same commit that changes their truth. Retire a row only when its exact legacy mechanism is gone.
  • Do not push unless the user explicitly asks.
  • Connected tests require the user's ACE server at 127.0.0.1:9000. Close the client gracefully before reconnecting so ACE releases the session.

What has been completed

C3c and collision-publication checkpoint

  • 529e0e9d — C3c production first-entry cutover for graphical and headless hosts.
  • 71604331 — O(changed) per-landblock collision publication checkpoint. Its original commit was deliberately marked WIP after the first feel test; do not treat that old label as the current product status. The following fixes addressed the observed failures.

Stabilization fixes, all user-verified where visual behavior applies

  1. 01f4791eretirement-receipt replay loop fixed.

    • Root cause: a pending-only live-projection bucket was promoted to a second full landblock cleanup receipt after the first detach had already committed. The duplicate guard threw; a broad resumable path replayed the detach 243 times.
    • Fix: retain pending identities without manufacturing another receipt; post-commit receipt invariants are terminal, not resumable.
    • Evidence: focused recenter tests; complete Release suite 10,815 passed / 4 skipped; lifecycle report logs/connected-world-gate-20260802-203751/report.json; nine-stop report logs/connected-r6-soak-20260802-204309.report.json with Passed=true, nine checkpoints, zero failures, zero wait cues, zero pending retirements, and no recurrence of the 243x exception.
  2. 670f307cremote placement and targeting share one world frame.

    • Root cause: CreateObject positions are landblock-local, but Runtime submitted remote first-entry placement with zero world offset; the local physics host also published a landblock-local origin to targeting.
    • Fix: Runtime owns the accepted local-player world center, converts remote Create placement before SetPosition, and publishes the local body's world position.
    • User gate: monsters and statics place correctly; monsters chase and hit the visible player instead of attacking another coordinate.
  3. 1fc529cddistant Use/approach restored.

    • Root cause: Runtime object lookup is intentionally non-constructing, so a static door/corpse could enter MoveTo without a physics host and its target snapshot expired at the origin. Startup placement could also leave an impossible pre-PartArray motion suffix ahead of later actions.
    • Fix: ensure the canonical minimal static host before routing MoveTo and reconcile the startup suffix exactly at presentation attach.
    • User gate: near and distant object use works, including approach, turn, and use after arrival.
  4. f24532adspell, recall, projectile, and static VFX binding fixed.

    • Root cause: C3c could create effect/projectile/static-animation sidecars before first SetPosition had bound the entity's mesh, pose, cell, and visibility. One-shot F754/F755 packets were lost and projectiles could inherit a cell-less body.
    • Fix: exact-incarnation presentation barrier and FIFO replay; retry projectile/static binding on the committed visibility edge; synchronize effect cells on rebucket.
    • User gate: buffs/protections, recall effects, arrows, combat spell projectiles, portals, and static animation all work.
  5. 175ad6b0login materialization acknowledgement fixed.

    • Root cause: ACE creates the local player Hidden and releases that state on LoginComplete. Sending LoginComplete from raw F746 receipt raced first canonical placement and left the purple haze over the character.
    • Fix: one completion callback from Runtime's local first-entry terminal edge; content-less headless retains its only truthful accepted-Create edge.
    • User gate: ordinary login no longer leaves the purple haze; recall still has the intended materialization presentation.

Latest focused verification

After the final fix, these passed:

  • 90 focused App effect/projectile/static-animation scheduler tests.
  • Two focused Runtime login-completion tests.
  • The exact live-entity cell-tracking regression.
  • All 79 Headless tests.
  • dotnet build AcDream.slnx -c Release --no-restore with zero errors (existing warnings remain).

The long complete suite and connected nine-stop soak were not rerun after the final four stabilization commits. The P1 soak proves P1's binary, not the final campaign binary.

What remains — execute in this order

1. Reconcile the six selected-fixture failures

A broad selected run after cleanup exposed:

  • five failures in LiveEntityRuntimeTests, associated with the still-open placement/cell cutover;
  • one old RuntimeLiveEntitySessionControllerTests remote-first-entry fixture that provides an empty collision source while the production contract now requires truthful collision admission.

Re-run these two classes first and record the exact test names and assertions. Classify each as either a real product failure or a stale fixture. If stale, update the fixture to provide the same valid prepared collision neighborhood as production; never weaken the product contract or merely change expected values. If real, fix the owning production mechanism and add a smaller regression test.

Suggested first commands:

$env:ACDREAM_PAK_PATH='C:\Users\erikn\Documents\Asheron''s Call\acdream.pak'
dotnet test tests/AcDream.App.Tests/AcDream.App.Tests.csproj -c Release --no-restore --filter FullyQualifiedName~LiveEntityRuntimeTests -m:1
dotnet test tests/AcDream.Runtime.Tests/AcDream.Runtime.Tests.csproj -c Release --no-restore --filter FullyQualifiedName~RuntimeLiveEntitySessionControllerTests -m:1

2. Finish C4: remaining authoritative placement routes

The plan still marks routes 27 open:

  • route 2: ForcePosition;
  • route 3: portal placement through RuntimeWorldTransitState and RuntimePortalPlacementAuthority;
  • route 4: remote Create/Position, deleting the remaining RemoteTeleportController/inline MoveOrTeleport duplicate;
  • route 5: authoritative projectile correction;
  • route 6: drops and split-recovery marking;
  • route 7: pickup, parent-detach, and delete/recreate residue.

Inventory every current writer before editing. For each route, prove:

  • one Runtime SetPosition transaction owns accepted frame, exact cell, collision result, shadow/workset membership, and deferred-cell lifetime;
  • App only projects the committed result;
  • graphical and headless hosts use the same command and state path;
  • stale sequences, delete/GUID reuse, missing cells, portal generations, and replacement collision generations cannot commit old state;
  • no route reconstructs from a stale spawn or uses the legacy outdoor demote/ terrain-Z lift.

Resolve #276 when the spawn settler's resolved CellId becomes authoritative. Resolve #277 with a real service-window/celless lifecycle instead of relying on ACE's current broadcast radius.

3. Fix #280: destination prefetch before portal reveal

Current behavior waits only a hard-coded radius-one (3x3) outdoor neighborhood, while the visible configured world extends farther. The user can see distant terrain continue building after portal exit.

Port the retail mechanism, not a larger magic number:

  • CellManager::PreFetchCells @ 0x00455820;
  • LScape::PreFetchCells @ 0x00505660;
  • CLandBlock::PreFetchCells and CLandBlockInfo::PreFetchCells;
  • SmartBox::UseTime @ 0x00455410 while blocking_for_cells;
  • the TAS_TUNNEL_CONTINUE resume/reveal order.

Use the quality/view-distance configured destination window. Hold one generation-scoped reservation across terrain, buildings/statics, EnvCells, render publication, composite textures, and collision. Keep portal UI and wait cue responsive. Never reveal early because of a timeout, and do not wait for an impossible terminal marker for all dynamic ACE objects.

Acceptance: repeated login, /ls, spell recall, and portals at every quality setting reveal no constructing terrain, missing nearby statics/buildings, unready interiors, missing composites, or absent nearby collision. Dynamic monsters/items may still arrive later from ACE.

4. C5 closeout and live gates

After steps 13:

  1. Delete every superseded placement writer and compatibility projection.
  2. Run focused Runtime/Core/App tests for every route.
  3. Run the complete Release solution suite with the installed pak.
  4. Run the exact lifecycle/reconnect route.
  5. Run the canonical nine-stop soak on the final binary. Read report.json, not marker output. Required: Passed=true, zero failures, every canonical checkpoint, waitCueShown=false, zero pending publication/retirement/reveal debt, graceful exit, and no render-shadow mismatch. Diagnose any real failure; do not rerun past it.
  6. Perform two-client observation for remote creation, chase/attack, doors, drops/pickups, portal departure/arrival, arrows, and spells.
  7. Ask the user for the remaining #269/#278 slope-glide comparison at the known impassable slope.

Only then retire AP-1, AD-1, AP-131, and the legacy half of AD-60 and close the corresponding placement issues.

5. Finish the original physics-divergence campaign

After placement C5 is green:

  • AP-22: make ShadowShapeBuilder the sole authority for authored Setup collision shapes. Preserve cylinder order; use authored spheres when there are no cylinders; cylinder-first for mixed data; truly shapeless means no shadow. Remove invented Setup.Radius cylinders, Radius * 2 heights, and sphere-to-cylinder coercion across graphical, headless, static, and live paths.
  • AD-10: prove remote motion uses the full transition sweep, remove terrain-normal preprojection, and let CTransition::adjust_offset project against the actual retained contact plane. Preserve interpolation, correction replacement, Hidden state, and network cadence.
  • Run the final movement/collision matrix and update the divergence ledger, architecture, roadmap, milestones, memory, CLAUDE.md, and AGENTS.md. Resume vendor Slice 5 only after this campaign is genuinely closed.

Required deliverable

For every remaining item report:

  • observed failure and deterministic reproduction;
  • retail/reference evidence with named functions and addresses;
  • root cause in plain language plus file/line evidence;
  • exact fix and why it preserves Runtime ownership;
  • tests added or corrected;
  • commit SHA;
  • complete build/test/connected-gate numbers;
  • user visual result where required;
  • divergence/issue rows retired, narrowed, or left open.

Finish with an explicit list of anything still open. Do not describe the campaign as complete while any C4 route, #280, final-binary soak, AP-22, AD-10, or required user visual gate remains.