fix(render): restore retail per-cell alpha order

Reconstruct one combined static/dynamic object-part stream for each ordinary outdoor or interior cell, compute authored SortCenter CYpt keys, and stable-sort far to near before projecting opaque and delayed subsets. Prepare real cell-particle records at the leaf, preserve every S4-c2 router outcome, and merge object and particle delayed records by retained key before either source appends to the unchanged CLIP/ALPHA FIFO lists. Cell turns remain cell-major; equal cross-source ties are deterministically object-first.

File AP-241 and AP-242 for the remaining separate opaque/row-5 channels and unrepresented equal-key common ordinal. File AP-243 for the paired-binary correction: retail shares the cell CYpt/heading beyond 50 m while this bounded port always uses the more exact authored per-part center. Pin 162 active AP rows and correct world-alpha and AlphaFlushCounts prose.

Lead-approved scope clarification: RetailPViewPassExecutor.WalkLeaf.cs and RetailPViewPassExecutor.cs are the minimum existing production leaf adapter and thin particle-prepare forwarder omitted by the literal Walk/Wb file list. They contain no router, queue, mask, state, depth, or flush behavior; relocating them would create an artificial seam.

Gates: Release solution build 0W/0E; shader/manifest 32/32; focused production 210/210; real allocation 3/3 at 0 B; one-shot hermetic 16743/0/0 across 14 assemblies; InstalledDat 385 pass/10 documented fail/1 skip with all six AlphaFlushSites passing; git diff --check PASS. Initial no-restore solution build failed NETSDK1004 for 42 missing scratch assets; one solution restore preceded the official build.

Mutation proof, each restored before final gates:

1. Reverse comparator: authored-center order expected [202,101], actual [101,202].

2. Move ties left: multipart/subset order expected [11,12,21,22], actual [22,21,12,11].

3. Restore static/dynamic blocks: expected [2,3,1], actual [3,1,2].

4. Use entity origin: authored-center order expected [202,101], actual [101,202].

5. Restore particle tail: expected [Wb,Particle,Wb,Particle], actual [Wb,Wb,Particle,Particle].

6. Scope-global sort: first cell model X expected 5, actual 50.

7. Restore dead camera parameter: SubmitWalkAlphaInstance parameter count expected 2, actual 3.

8. Restore stale global-queue prose: exact Assert.DoesNotContain failure on distance-sorts one shared queue.

9. Remove AP-241 identity: Assert.Single found no matching row.

10. Allocate in real merge: expected 0 B, actual 3072 B.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
Erik 2026-09-04 13:18:54 +02:00
parent 06b986622b
commit a86ec73ece
17 changed files with 1067 additions and 197 deletions

View file

@ -16,6 +16,27 @@ internal readonly record struct ParticleSubmission(
float DistanceSq,
int Sequence);
/// <summary>
/// One scene-particle alpha record prepared at its owning cell turn but not
/// yet appended. S4-c3a lets <c>WalkFrameDriver</c> merge this retained CYpt
/// key with ordinary object parts before either source enters retail's FIFO
/// list. The source payload is reserved during preparation; <see
/// cref="RetailAlphaQueue.TryAppend"/> remains the sole visibility edge and
/// still owns capacity-drop cleanup by registering the source before a drop.
/// </summary>
internal readonly record struct PreparedParticleAlphaSubmission(
RetailAlphaQueue Queue,
RetailAlphaList List,
IRetailAlphaDrawSource Source,
int Token,
bool OverrideClipmap,
float DistanceSq,
int Sequence)
{
internal void Append() =>
Queue.TryAppend(List, Source, Token, OverrideClipmap);
}
/// <summary>
/// Shared ordering for the two retail particle geometry paths. Transparent
/// particles are submitted back-to-front; creation/enumeration order is the