docs(render): Phase U.2a review fixups — LIFO-on-ties comment + ISSUES #102
Code-review minor follow-ups: correct the CellTodoList comments (ties are LIFO, not FIFO — an equal-distance newcomer lands at the tail and pops first, matching retail's break-on-first-not-greater + pop-from-tail). Update ISSUES #102 to record that U.2a closes I-1/I-2 (under-count + duplicate accumulation) via the enqueue-once gate, narrowing the residual to diamond-topology clip-completeness (AddToCell onward re-propagation, tracked under U.6). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
d8807755ce
commit
306cdb069c
2 changed files with 27 additions and 4 deletions
|
|
@ -84,11 +84,32 @@ Related: #102 (builder dungeon-scaling fixpoint).
|
||||||
|
|
||||||
## #102 — A8.F PortalVisibilityBuilder — port retail update_count fixpoint (replace MaxReprocessPerCell cap)
|
## #102 — A8.F PortalVisibilityBuilder — port retail update_count fixpoint (replace MaxReprocessPerCell cap)
|
||||||
|
|
||||||
**Status:** OPEN
|
**Status:** PARTIALLY RESOLVED (Phase U.2a, 2026-05-30, commit `d880775`)
|
||||||
**Severity:** MEDIUM
|
**Severity:** MEDIUM → LOW (residual is diamond-topology clip-completeness only)
|
||||||
**Filed:** 2026-05-29
|
**Filed:** 2026-05-29
|
||||||
**Component:** rendering, visibility, EnvCell portal traversal
|
**Component:** rendering, visibility, EnvCell portal traversal
|
||||||
|
|
||||||
|
**U.2a resolution (2026-05-30):** Reading the decomp showed retail does NOT
|
||||||
|
re-enqueue on view-growth: `AddViewToPortals` (433446) enqueues a cell via
|
||||||
|
`InsCellTodoList` ONLY in the first-discovery branch (`ecx_5 == 0`); later
|
||||||
|
growth goes through `AddToCell` (433050) in place and never re-enqueues. U.2a
|
||||||
|
replaced the `MaxReprocessPerCell` cap with an **enqueue-once gate** (a `seen`
|
||||||
|
set = retail `cell_view_done`, 433784) + a distance-priority work list (retail
|
||||||
|
`InsCellTodoList`). This **closes I-1 and I-2**: the clip-region union into a
|
||||||
|
neighbour now runs UNCONDITIONALLY before the enqueue gate, so >4-portal cells
|
||||||
|
no longer under-count (I-1 gone), and each cell processes its exit portals
|
||||||
|
exactly once, so cyclic graphs no longer accumulate duplicate polygons (I-2
|
||||||
|
gone). The new `Build_CyclicHub_TerminatesAndBounds` test enforces the
|
||||||
|
acceptance (4-room ring ⇒ ≤5 cells, no dups). **Residual scope:** retail's
|
||||||
|
`AddToCell` ONWARD re-propagation of late growth (a cell reached via a longer
|
||||||
|
path AFTER it was drawn gets its own `CellView` unioned but does not
|
||||||
|
re-propagate that growth to ITS children) is NOT ported — this affects only
|
||||||
|
clip-region completeness on **diamond** topologies, never the visible cell set
|
||||||
|
or draw order. It overlaps the M-4 `OtherPortalClip` stub below; track both
|
||||||
|
under U.6 (dungeon-scale validation). A naive count-watermark re-enqueue is NOT
|
||||||
|
a valid fix (it never terminates, because `CellView.Add` appends without
|
||||||
|
merging) — the faithful fix is the in-place slice re-propagation.
|
||||||
|
|
||||||
**Description:** A8.F Task 4 shipped a bounded-BFS port of retail's
|
**Description:** A8.F Task 4 shipped a bounded-BFS port of retail's
|
||||||
`PView::ConstructView` → `ClipPortals` → `AddViewToPortals` in
|
`PView::ConstructView` → `ClipPortals` → `AddViewToPortals` in
|
||||||
[`src/AcDream.App/Rendering/PortalVisibilityBuilder.cs`](../src/AcDream.App/Rendering/PortalVisibilityBuilder.cs).
|
[`src/AcDream.App/Rendering/PortalVisibilityBuilder.cs`](../src/AcDream.App/Rendering/PortalVisibilityBuilder.cs).
|
||||||
|
|
|
||||||
|
|
@ -268,7 +268,8 @@ public static class PortalVisibilityBuilder
|
||||||
/// the tail; <see cref="PopNearest"/> removes the tail — giving closest-first traversal exactly
|
/// the tail; <see cref="PopNearest"/> removes the tail — giving closest-first traversal exactly
|
||||||
/// as ConstructView's pop-from-(cell_todo_num-1) does (433767-433769). The insertion only shifts
|
/// as ConstructView's pop-from-(cell_todo_num-1) does (433767-433769). The insertion only shifts
|
||||||
/// entries strictly farther than the newcomer (retail's flag test breaks on the first
|
/// entries strictly farther than the newcomer (retail's flag test breaks on the first
|
||||||
/// not-greater entry), so ties preserve insertion order (stable, FIFO among equal distances).
|
/// not-greater entry), so an equal-distance newcomer lands at the tail and pops FIRST —
|
||||||
|
/// LIFO on ties, matching retail's break-on-first-not-greater + pop-from-tail.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private sealed class CellTodoList
|
private sealed class CellTodoList
|
||||||
{
|
{
|
||||||
|
|
@ -280,7 +281,8 @@ public static class PortalVisibilityBuilder
|
||||||
{
|
{
|
||||||
// Find the slot: scan from the tail (nearest) toward the head while existing entries are
|
// Find the slot: scan from the tail (nearest) toward the head while existing entries are
|
||||||
// strictly nearer than `distance`, so the newcomer lands just ABOVE every entry that is
|
// strictly nearer than `distance`, so the newcomer lands just ABOVE every entry that is
|
||||||
// farther-or-equal — i.e. nearest-at-tail order, FIFO on ties.
|
// farther-or-equal — i.e. nearest-at-tail order, LIFO on ties (an equal-distance
|
||||||
|
// newcomer inserts at the tail and pops first).
|
||||||
int idx = _items.Count;
|
int idx = _items.Count;
|
||||||
while (idx > 0 && _items[idx - 1].Distance < distance)
|
while (idx > 0 && _items[idx - 1].Distance < distance)
|
||||||
idx--;
|
idx--;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue