docs(overhaul): bound S4 c3a retail fix round
This commit is contained in:
parent
a86ec73ece
commit
8e0c6fb145
1 changed files with 114 additions and 0 deletions
|
|
@ -1432,3 +1432,117 @@ before the return matrix):
|
||||||
10. Allocate one object in the real cell-merge path:
|
10. Allocate one object in the real cell-merge path:
|
||||||
`ProductionCellObjectParticleMerge_WarmedPathAllocatesZeroBytes` first
|
`ProductionCellObjectParticleMerge_WarmedPathAllocatesZeroBytes` first
|
||||||
expected 0, actual 3,072 managed bytes.
|
expected 0, actual 3,072 managed bytes.
|
||||||
|
|
||||||
|
## 19. S4-c3a fix round 1 — authored particle CYpt and bounded preparation (lead, 2026-09-04)
|
||||||
|
|
||||||
|
The first retail-faithfulness lens returned **FAIL** on candidate
|
||||||
|
`44e2bc227ba74d10074cfe985eee094e10b7f438`. Ordinary object parts are
|
||||||
|
correct, but the billboard/mode-2–5 particle path orders by its rendered quad
|
||||||
|
center. That center is the vertex-AABB-derived `ParticleGfxInfo.CenterOffset`
|
||||||
|
after viewer-facing adjustment, not the GfxObj's authored `sort_center`.
|
||||||
|
Retail does not use the rendered center for CYpt:
|
||||||
|
`CPhysicsPart::UpdateViewerDistance @ 0x0050E030` reads the current GfxObj's
|
||||||
|
`sort_center` at offsets `+0x7C/+0x80/+0x84`, scales it, passes it with the
|
||||||
|
part `Position` to `Position::get_offset`, computes the length, and writes
|
||||||
|
CYpt. The paired bytes at `0x0050E036..0x0050E0AE` confirm that named-decomp
|
||||||
|
sequence. The same lens also found the stale statement that static records
|
||||||
|
are never re-sorted downstream.
|
||||||
|
|
||||||
|
The lead's pre-production audit found two coupled safety holes in the new
|
||||||
|
prepared-particle seam. `_preparedCellAlphaScratch` is a new retained list but
|
||||||
|
is absent from the alpha scratch accounting/retention bound. More importantly,
|
||||||
|
`PrepareForCellAlpha` reserves `_deferredAlpha` payload tokens before the
|
||||||
|
driver reaches the queue visibility edge. An exception from a later immediate
|
||||||
|
duplicate can strand unregistered source payload; ordinary capacity rejection
|
||||||
|
retains payload for entries that can never draw. These contradict §18.3's
|
||||||
|
source-owned rollback requirement. They are included in this same bounded
|
||||||
|
round rather than deferred to a predictable production-lens failure.
|
||||||
|
|
||||||
|
### 19.1 F1 — one authored particle sort point, separate from its draw center
|
||||||
|
|
||||||
|
Retain `GfxObj.SortCenter` explicitly in `ParticleGfxInfo`. Populate it
|
||||||
|
directly in `AuthoredParticleGfxInfo`; synthetic texture-only/default
|
||||||
|
billboards, which have no GfxObj, use zero. Do not derive it from vertex bounds
|
||||||
|
and do not replace or alter the visual `CenterOffset`.
|
||||||
|
|
||||||
|
For every billboard/mode-2–5 particle, compute the CYpt point before any
|
||||||
|
viewer-facing draw-frame adjustment:
|
||||||
|
|
||||||
|
`particle.Position + Transform(authoredSortCenter * particle.Size, ParticleOrientation)`.
|
||||||
|
|
||||||
|
Use the squared viewer distance from that point for `ParticleInstance` and
|
||||||
|
`ParticleSubmission`. The rendered quad position/axes remain byte-for-byte
|
||||||
|
the existing `CenterOffset`/facing result. The full-mesh path already applies
|
||||||
|
the equivalent `ObjectRenderData.SortCenter` through its model; keep the two
|
||||||
|
paths semantically identical and do not add a second sort.
|
||||||
|
|
||||||
|
Add a real GfxObj-backed billboard test whose authored SortCenter is distinct
|
||||||
|
from both its particle origin and vertex AABB center, with non-unit size and a
|
||||||
|
non-identity orientation. Drive the actual cell particle preparation and
|
||||||
|
driver merge against ordinary object alpha. It must prove that the authored
|
||||||
|
point determines the cross-source order while the captured billboard draw
|
||||||
|
center remains the existing visual center. Required mutations: using rendered
|
||||||
|
`pos`, using the AABB center, dropping size, or dropping orientation must each
|
||||||
|
fail a named first assertion.
|
||||||
|
|
||||||
|
### 19.2 F2 — reserve only at the queue visibility edge and roll back rejection
|
||||||
|
|
||||||
|
A prepared particle record retains only the information needed to reconstruct
|
||||||
|
its source payload when `Append` is called; preparation must not mutate
|
||||||
|
`_deferredAlpha`. At `Append`, reserve one tail token, call
|
||||||
|
`RetailAlphaQueue.TryAppend`, and roll back that exact tail token when the
|
||||||
|
append returns false or throws. A rejected first-use source must remain
|
||||||
|
registered by the queue and receive one flush/end/abort reset, but it owns no
|
||||||
|
rejected payload and never prepares or draws it. Accepted token indices remain
|
||||||
|
stable. An exception from a later row-5 or clip-immediate draw during
|
||||||
|
preparation must leave the source payload count unchanged.
|
||||||
|
|
||||||
|
Bound `_preparedCellAlphaScratch` by the physical two-list limit: retain no
|
||||||
|
more than the first 3,000 delayed candidates for CLIP and the first 3,000 for
|
||||||
|
ALPHA. Later candidates for a list cannot be admitted even in an otherwise
|
||||||
|
empty frame, so dropping only their prepared records is behavior-equivalent;
|
||||||
|
their immediate duplicate, if any, still executes. Include this list in an
|
||||||
|
explicit retained-byte/capacity diagnostic or an equivalent dedicated bound.
|
||||||
|
After a rejection storm its count is zero at reset/next preparation and its
|
||||||
|
retained capacity is no greater than the bounded geometric backing required
|
||||||
|
for 6,000 records (8,192 with `List<T>` growth). Do not change either queue's
|
||||||
|
3,000-entry capacity, FIFO append order, source registration, CLIP-then-ALPHA
|
||||||
|
drain, router decisions, or row-5 immediate state.
|
||||||
|
|
||||||
|
Pins cover: more than 3,000 candidates for each list; accepted/rejected token
|
||||||
|
counts; no rejected prepare/draw; flush, end, and abort cleanup; an injected
|
||||||
|
immediate-draw exception after at least one delayed candidate; bounded count,
|
||||||
|
capacity, and retained bytes; and the real warmed driver/particle/dispatcher
|
||||||
|
merge at 0 managed bytes. Mutations restoring eager reservation, omitting
|
||||||
|
false/exception rollback, or removing the per-list preparation cap must fail
|
||||||
|
at their first named count/capacity assertion.
|
||||||
|
|
||||||
|
### 19.3 F3 — prose and register truth
|
||||||
|
|
||||||
|
Correct `WalkFrameDriver.cs`'s `WalkFrameStaticRecords` comment: records retain
|
||||||
|
authored traversal/registration order until the ordinary-cell populator builds
|
||||||
|
the combined static/dynamic part list and performs the retail per-cell CYpt
|
||||||
|
sort. They are not final stream order. After F1, AP-241's positive authored-
|
||||||
|
part-order claim becomes true; AP-241/AP-242/AP-243 otherwise remain unchanged,
|
||||||
|
unique, inside the AP table, and the active physical count remains 162. No new
|
||||||
|
deviation is introduced by this exact repair.
|
||||||
|
|
||||||
|
### 19.4 Scope, return, and review order
|
||||||
|
|
||||||
|
Production edits are limited to `ParticleRenderer.cs`,
|
||||||
|
`ParticleSubmissionOrdering.cs`, and the comment-only correction in
|
||||||
|
`Walk/WalkFrameDriver.cs`. Tests may change only
|
||||||
|
`ParticleRendererRouteTests.cs` and `Walk/WalkFrameDriverTests.cs`; this packet
|
||||||
|
records the result. If the implementer proves one additional existing test
|
||||||
|
helper is the minimum real-path fixture seam, the lead must approve and record
|
||||||
|
it before commit. No router, queue, pipeline, shader, manifest, Content model,
|
||||||
|
serializer, package format, building-shell, EnvCell, or PView behavior changes.
|
||||||
|
|
||||||
|
Return one fix commit on top of `44e2bc227b`: `git diff --check`; Release 0W/0E;
|
||||||
|
the focused particle/driver/queue/order/bounds suite; the real 0-B pin; shader
|
||||||
|
contract lane; and a mutation ledger naming each actual first failure. No
|
||||||
|
graphical launch. The retail lens re-reviews F1, the paired bytes, F3, and the
|
||||||
|
unchanged S4-c2 behavior first. Only a retail PASS unlocks the sequential
|
||||||
|
production/gate-honesty lens over the entire c3a stack, with special attention
|
||||||
|
to F2. A failed re-review gets the one remaining bounded fix round; a further
|
||||||
|
finding after that would require a third round and stops the chunk.
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue