285 lines
13 KiB
Markdown
285 lines
13 KiB
Markdown
# 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:
|
||
|
||
```text
|
||
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:
|
||
|
||
```text
|
||
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. `01f4791e` — **retirement-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. `670f307c` — **remote 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. `1fc529cd` — **distant 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. `f24532ad` — **spell, 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. `175ad6b0` — **login 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:
|
||
|
||
```powershell
|
||
$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 2–7 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 1–3:
|
||
|
||
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.
|