Files
VoxelForge/WORK-NEXT.md
T
Fr0zkaandClaude Opus 5 cf0319d480 perf(streaming): item 3 bought nothing, item 5 removed dead weight -- both worth knowing
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
2026-09-12 06:49:20 +02:00

107 lines
6.0 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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?