Two WORK-NEXT items, one null result and one confirmed removal. Item 4 untouched.
ITEM 3 -- CANCEL OBSOLETE WORK AND PRIORITISE THE FLOOR: NULL RESULT
Clean -nullrhi, diagnostics off, 800 cm/s, 200 m of travel:
before after
request->ready p95 0.369117 s 0.367612 s
queue wait p95 0.066949 s 0.064483 s
generation p95 0.287926 s 0.283642 s
p95 travel distance 2.952938 m 2.940894 m
obsolete aborts 0 12
Flat. Aborting obsolete tiles, sorting from the true pawn position and prioritising the
occupied/next tile changed request-to-ready by 0.4%.
⭐ AND THE NULL RESULT IS ITSELF THE FINDING. Look at the split: queue wait is 65 ms of a
368 ms p95; generation is 284 ms. **The queue was never the problem, so reordering it
cannot help.** Only 12 tiles in a 200 m run were obsolete enough to abort. The floor is
late because generation is slow, not because work is badly ordered -- item 3 establishes
that by exclusion, which is worth more than the 0.4%.
The machinery is kept: it is correct, it costs nothing, and it will matter once
generation is fast enough for ordering to be the binding constraint.
ITEM 5 -- VERDICT CACHE REMOVED. It was pure overhead.
Clean moving-session audit:
outer calls/probes/hits 2,109 / 2,109 / 0
nested calls/probes/hits 19,904 / 19,904 / 0
enclosing hits 0
stores 15,877, evictions 15,365
⇒ It stored 15,877 proofs, evicted 15,365 of them, and hit ZERO times. A moving player
visits unique regions; the cache was filling and thrashing a 512-entry table under a
global lock for no benefit. Same-binary A/B: request p95 0.367645 vs 0.365978,
generation p95 0.285559 vs 0.285992 -- neutral within noise, so its cost was the lock and
the linear scans rather than time we can see.
Removed: the global cache, its lock, the entry table, the invalidation path, the
cache-only profiler fields and the synthetic probe. The proof classifier stays.
⚠️ I asked for this cache two days ago on the strength of a commandlet measurement that
re-visited the same region repeatedly. That access pattern is nothing like a moving
player, and I should have said so when specifying it.
VERIFIED BY ME: build 0 errors; export 0.563 / 0.565 / 0.566 s (35de59b was 0.545-0.563,
flat as expected); geometry SHA-256 b3e5f4c3..9b377 UNCHANGED; capability 20,830 /
10,909, connected.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012aheo2crrZmHuYtPpdY2Cb
107 lines
6.0 KiB
Markdown
107 lines
6.0 KiB
Markdown
# WORK-NEXT — the queue after the read-only audit (2026-09-11)
|
||
|
||
Ordered by importance, then by size. Everything here comes from Sol's read-only audit of
|
||
`experimental` @ `aa62971`, checked against `main`.
|
||
|
||
The audit's two-sentence verdict:
|
||
> *The operator abstraction leaked into the innermost loop, and streaming treats
|
||
> "work submitted/applied" as "safe to stand on."*
|
||
|
||
**Standing rules for every item**: determinism is absolute (same build + same seed = same world on
|
||
every machine); output may change between builds; nothing is deleted to go fast; capability before
|
||
speed (player-fit 20,830 / walk-reachable 10,909 — do not drop below); scope is
|
||
`Plugins\VoxelForge` only, no links, absolute `-out=` paths under the plugin's own `Saved\`.
|
||
|
||
---
|
||
|
||
## 1. Collision-ready before player-ready · CORRECTNESS · medium
|
||
|
||
The player falls through the world. There is **no invariant** that a tile you occupy has collision.
|
||
`main` has no such barrier either — it was simply fast enough to hide the race.
|
||
|
||
- `apply_s` ends at mesh **submission**. RMC cooks collision **asynchronously** and we never record
|
||
cook-complete. We have never measured when physics can actually collide.
|
||
- A tile enters `LoadedTiles` before its apply path completes (`VoxelWorld.cpp:1532`).
|
||
- Only LOD0 carries collision (`VoxelWorld.cpp:3109`), so visible coarse terrain can exist while the
|
||
collidable tile is still queued.
|
||
|
||
**Do**: record cook-complete; gate the pawn (spawn and movement) on the supporting tile being
|
||
collidable, not merely applied.
|
||
|
||
📖 **Reading `Plugins/RealtimeMeshComponent` is permitted for this item — READ ONLY.** Find whether a
|
||
cook-complete delegate/flag exists. ⛔ No edits, no builds against it: the owner's copy carries custom
|
||
modifications and was destroyed once by an over-broad delete.
|
||
|
||
## 2. Lower the operator graph into a fused evaluator · PERFORMANCE · large
|
||
|
||
This is where the ~8× lives (pre-op-stack `34f06df` did 128³ in 0.130 s; we are at ~1.04 s).
|
||
|
||
A LOD0 tile samples 42,875 positions. The old path short-circuited the whole cave suite per sample
|
||
when `bNearCaveSurface` was false — roughly **70% of deep-solid samples**. We now allocate a rich
|
||
`FVoxelOpSample` per position, run each active operator across the entire block, use scalar fallbacks
|
||
for most operators, copy scratch in and out, and still call scalar `GetDensityAt` per grid point.
|
||
|
||
> *An operator whose interval intersects the surface anywhere in the block runs across the whole
|
||
> block; the old path could decide per sample that expensive detail work was irrelevant.*
|
||
|
||
**Do**: keep the authored operator graph, but **compile/lower it** into a fused evaluator that restores
|
||
per-sample short-circuiting and stops spilling `FVoxelOpSample` through memory per operator.
|
||
⚠️ Byte-identical geometry is the acceptance test. Stage it so the tree never breaks.
|
||
|
||
Note: the D-floors/terracing features are only ~17% of the penalty — not the 8×.
|
||
|
||
## 3. Cancel obsolete work, and prioritise the floor · BOTH · medium
|
||
|
||
Nothing aborts a tile when the player moves and it stops being desired. Work is distance-sorted from
|
||
an artificial chunk centre, not the pawn, with no collision-critical priority
|
||
(`VoxelWorld.cpp:1864`). Up to 14 workers can be busy with stale coarse tiles while the player's LOD0
|
||
floor waits.
|
||
|
||
**Do**: abort no-longer-desired tiles; sort from the true pawn position; give the occupied tile and the
|
||
next tile along the heading absolute priority.
|
||
|
||
## 4. Collapse the duplicated field semantics · MAINTENANCE · medium-large
|
||
|
||
The effective field now lives in three places: the operator stack, the classifier's parallel interval
|
||
logic, and a post-stack repair tail in `GetDensityAt` (origin floors, passage structure, passage
|
||
floors, room floors). `FRoomGraphSource` evaluates the room graph then traverses tunnels *again* for
|
||
metadata (`VoxelDensityOpStack.cpp:4234`).
|
||
|
||
The audit calls this *"the clearest sign of overengineering"*: later fixes compensating for where an
|
||
operation sits in the pipeline. It also makes interval proofs harder to trust.
|
||
|
||
**Do**: make the stack the single semantic source of truth. Likely overlaps heavily with item 2.
|
||
|
||
## 5. Verdict cache removed after moving-session audit · complete
|
||
|
||
The clean moving-session audit found zero outer or nested hits: 2,109 outer probes and 19,904 nested
|
||
probes produced 15,877 stores and 15,365 replacements in the full 512-entry table. Same-binary
|
||
cache-on/cache-off request-to-ready was 0.367645/0.365978 s p95 and generation was 0.285559/0.285992
|
||
s p95, so the cache was neutral within run noise while paying the global lock and linear scans.
|
||
|
||
The global verdict cache, lock, entry table, invalidation path, cache-only profiler fields, and
|
||
deliberate cache probe are removed. The proof classifier remains; item 4 is still deliberately untouched.
|
||
|
||
## 6. Three small, sharp ones · tiny
|
||
|
||
- **The zero-position guard.** Streaming only starts when `GetPlayerPosition()` is not exactly
|
||
`FVector::ZeroVector` (`VoxelWorld.cpp:1167`, `:1359`) — a pawn at the world origin is
|
||
indistinguishable from "no pawn", and **the owner spawns at (0,0)**.
|
||
- **`ApplyMeshToTile` has no success return** (`VoxelWorld.cpp:3064`). If runtime-mesh init fails the
|
||
tile stays recorded as loaded and never retries — a permanent hole.
|
||
- **Whole-tile uniform verdicts are trusted without exact validation.** Block verdicts get checked
|
||
against the full grid when meshing; an outer AllAir/AllSolid verdict has no equivalent safety net.
|
||
|
||
## 7. Deferred, with reasons
|
||
- **Coarse-first LOD refinement** — blocked until coarse tiles can carry collision, or item 1 lands.
|
||
- **GPU evaluation** — right hardware, but bit-exactness across vendors/drivers is unproven and
|
||
determinism is absolute. Item 2 is the honest prerequisite either way.
|
||
- **The origin spawn room** — the owner considers it a design mistake that should not exist. Design
|
||
conversation, not a fix.
|
||
|
||
---
|
||
|
||
### Open design questions for the owner
|
||
- All five strate slots resolve to `DA_Strate3`. Intended?
|
||
- Should a composer roll be allowed to overwrite an explicitly authored value?
|