wip(assembler): round S14 -- 4-way column cache + memoized MC gradients (output unchanged)

Worker-local XY column cache uses deterministic 4-way sets at LOD3-8: LOD4
misses 8,224 -> 1,437, conflicts 7,407 -> 0 (direct-map control: 6.62 s /
43.5 worker-s vs 4.24 s / 21.7). Exact LOD0 lattice gradients memoized per
tile: MC-exclusive 242 -> 201 ns/sample, two-pass loop unchanged. Hashes
identical, no recipe bump. Primary cold trace 4.24 s full set, ring 0.45 s,
75/75 at 40 m/s; a repeat ran uniformly ~40% slower on every LOD (machine
contention suspected); tick p95 to re-check on an idle machine. CVars
voxel.CoreColumnCacheDirectMapped / voxel.CoreMCGradientMemoization.
Report: Standalone/Research/WorldAssemblerM3/Round18.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MmSoF64BbRFmk9C3p1VsBJ
This commit is contained in:
Fr0zkaandClaude Opus 5.5 committed 2026-10-19 17:58:54 +02:00
1 parent bd5e38594f
commit ec2afe9c93
11 files changed
+769 -50

No files matched your search

@@ -0,0 +1,340 @@
# World Assembler S14 — Round 18
## Decision
Shipped two output-preserving changes justified by the measurements:
1. Keep the 65,536-entry XY column cache worker-local. Use the old direct-map route at LOD0–2,
where conflict counts are low, and deterministic four-way sets at LOD3–8. The LOD4 miss spike
falls from 8,224 to 1,437, with conflict misses falling from 7,407 to zero.
2. Memoize exact step-1 ShapeWorld MC grid gradients per worker and tile. The MC two-pass loop,
density grid, halo, central differences, and output values stay intact. LOD0 MC-exclusive cost
falls from 241.87 to 201.48 ns/sample in the corrected-source audit; the original S13 figure was
243.40 ns/sample.
No shared XY page was built: cross-worker repeats show opportunity, but no measured page-cache A/B
shows a net cold-path win after the cache fix. The primary cold trace used 21.722 worker-seconds against
the 28.8 s target. Output hashes remain unchanged, so the recipe stays `MarchingCubesV1`; no recipe
bump or matched captures were required.
## 1. What the 243 ns/sample contains
The S13 “MC-exclusive” timer excludes MC column evaluation; it does **not** mean “triangle loop
only.” For LOD0, the corrected-source eight-tile audit measured 8.638 ms MC-exclusive plus 3.852 ms
MC column evaluation at the tuned setting. Each LOD0 tile has 35³ = 42,875 density samples. The
exclusive result is 201.48 ns/sample. The cell loop itself is only one part of it.
In the sampled stage audit, tuned LOD0 p95 was: density grid 8.971 ms (7.071 ms excluding column
evaluation), cell classification 0.143 ms, grid-gradient normals 1.036 ms, edge interpolation
0.080 ms, vertex dedup/stream 0.545 ms, and about 2.168 ms of unassigned remainder. The stage
profiler samples one in eight cells; these are independently calculated p95 values and do not add
to a measured total. Its `Other`/setup-finalization and unassigned-residual fields are computed
remainder buckets from different inclusive/exclusive timers, not separately isolated setup or
allocator timers.
The 164.93 ns/sample grid remainder is not a standalone `height - z` timer. Every lattice sample
still enters the exact `Heightfield2D::point` path: fixed-coordinate conversion, recipe/plan lookup,
the worker-local XY cache probe, the Z-dependent ground/cap composition, and any applicable exact
feature/edit checks. Column generation itself is counted separately: LOD0 records 44,100 field
calls, 2,244 cache misses (about 94.9% hits), and 89.89 ns/sample of column computation. The audit
does not split cache-hit lookup from Z composition and call overhead. Those Z/feature checks cannot
all move to one XY-column operation. The MC gradient work can be shared per lattice point and is
now memoized exactly; edge interpolation is already limited to crossed edges and the vertex map
deduplicates shared edge vertices. Material and allocation have no separate timers; the mesher's
thread-local grids and dedup map retain capacity between tiles.
The MC route still uses the protected two-pass loop: pass one rejects empty cells from the eight
cached corners; pass two computes positions, gradients, and emitted triangles only for surface
cells. Classification is per cell; exact gradients are reused per lattice point; interpolation and
deduplication are limited to crossed edges and their shared vertex keys. The stage measurements
place classification in the first pass and interpolation plus dedup/stream in the second.
Material/ground-cap grouping and vertex attributes are folded into
vertex creation and streaming; material work has no separate timer. The 35 edge-midpoint density
probes are negligible beside the gradient fallback calls.
| LOD | Density grid incl. | Grid excl. columns | Cell classification | Gradient normals | Edge interpolation | Dedup/stream | Unassigned residual |
|---:|---:|---:|---:|---:|---:|---:|---:|
| 0 | 210.11→209.22 | 168.04→164.93 | 3.28→3.32 | 65.10→24.16 | 1.91→1.86 | 12.96→12.72 | 50.40→50.56 |
| 1 | 163.74→164.91 | 163.74→164.91 | 3.82→3.55 | 4.20→4.01 | 2.14→2.10 | 13.47→13.56 | 54.77→55.06 |
| 2 | 390.55→395.47 | 0.00→0.00 | 2.84→2.89 | 11.62→11.51 | 6.14→5.47 | 68.70→69.15 | 277.12→306.20 |
| 3 | 777.21→437.15 | 120.00→131.99 | 3.15→2.97 | 15.37→15.37 | 6.77→6.25 | 604.40→407.99 | 46.97→110.89 |
| 4 | 4,603.98→425.25 | 210.50→178.79 | 2.92→3.32 | 10.15→10.96 | 5.60→5.48 | 565.21→309.90 | 95.44→109.50 |
| 5 | 385.90→434.09 | 135.75→155.07 | 3.02→3.48 | 5.13→7.00 | 1.78→3.50 | 155.02→38.26 | 96.38→137.65 |
| 6 | 366.38→371.92 | 88.76→101.46 | 2.97→3.09 | 18.66→18.11 | 9.72→8.39 | 431.20→185.07 | 124.84→171.70 |
| 7 | 361.29→447.14 | 115.03→102.64 | 3.13→2.99 | 20.47→17.75 | 9.69→8.84 | 443.10→239.22 | 99.92→254.21 |
| 8 | 367.98→377.58 | 95.55→96.05 | 4.05→3.05 | 14.90→19.08 | 7.48→7.92 | 513.15→213.89 | 159.02→234.19 |
All stage values are p95 **ns/sample**, before→after. “Before” is this build with the direct-map
cache and gradient memo off (`1/0`); “after” is this build's tuned default (`0/1`). Each side measured eight
tiles per LOD, with `hashes_identical=1`. LOD0/1 use 42,875 samples; LOD2–8 use 6,859. Large
variation in dedup/stream and residual is content/triangle-count and sampling noise, not a new
approximation. The last column is the commandlet's unassigned-residual bucket; the separately
reported setup-finalization field is also computed as a remainder and is not an allocator timer.
These warmed-route stage probes explain the hot path; the cold production timings are the
fresh-process trace in section 4.
| LOD | Candidate tile p95 ms | MC column p95 ms | MC-exclusive p95 ms / ns per sample | Column misses / conflicts |
|---:|---:|---:|---:|---:|
| 0 | 14.079→12.492 | 3.777→3.852 | 10.370→8.638 / 241.87→201.48 | 2,244/33→2,244/33 |
| 1 | 9.824→9.842 | 4.187→4.197 | 7.183→7.307 / 167.53→170.43 | 2,289/28→2,289/28 |
| 2 | 4.715→4.709 | 3.080→3.066 | 1.606→1.616 / 281.61→282.71 | 681/4→681/4 |
| 3 | 6.945→5.393 | 4.016→2.477 | 2.917→2.903 / 425.28→423.27 | 1,634/1,119→574/0 |
| 4 | 36.854→9.227 | 30.216→2.257 | 2.970→2.946 / 432.93→429.54 | 8,224/7,407→1,437/0 |
| 5 | 11.055→9.129 | 3.029→2.278 | 1.279→1.269 / 186.43→184.98 | 1,916/1,476→1,351/0 |
| 6 | 30.703→26.872 | 5.148→3.841 | 2.142→2.000 / 312.23→291.57 | 6,403/2,094→5,570/1 |
| 7 | 20.831→15.390 | 4.725→3.460 | 2.411→2.689 / 351.52→391.97 | 3,472/2,926→1,822/0 |
| 8 | 14.948→9.829 | 5.715→3.358 | 2.534→2.770 / 369.38→403.82 | 2,708/2,215→1,162/0 |
For LOD0 specifically, the S13 audit row was 14.160 ms candidate, 3.708 ms column evaluation,
10.436 ms MC-exclusive, and 243.40 ns/sample. The tuned corrected-source 35³ route is 12.492 ms
candidate and 8.638 ms MC-exclusive. Subtracting the measured density-grid p95 from candidate p95
leaves about 3.52 ms for the remaining work (about 82 ns/sample); the independently sampled stage
subtotal is about 3.97 ms (about 93 ns/sample). This is the measured in-world estimate for the
MC/classification/normal/interpolation/streaming work after density-grid evaluation, not a direct
pre-filled-grid benchmark. Treat the p95 subtraction as an estimate, not an additive percentile.
Gradient memoization reduces LOD0 fallback density probes from 11,474 to 3,018 per sampled p95
(−73.7%) and normal cost from 65.10 to 24.16 ns/sample. It records 5,610 memo hits. The memo stores
the exact central-difference vector at each grid lattice point, is worker-local, and resets its
validity bytes per tile. The existing grid and per-worker capacities are reused. No material
approximation or altered gradient arithmetic is involved.
## 2. Why LOD4 had the cache spike
The old cache already holds 65,536 `HeightfieldPointSample`s per worker, but its direct-map index
uses pointer identity and coordinate bits. Coarse LOD coordinates share sparse low-bit patterns;
the LOD4 16-voxel cap grid interleaves different XY probes with the MC grid and its halo/normal
lookups. The measured direct-map conflict count (7,407 of 8,224 misses) shows this is mostly
eviction, rather than 8,224 necessary unique columns. The audit did not tag every miss by probe
source, so the individual halo-versus-cap contribution is not claimed.
The new default keeps the same total entries and exact key verification. Its avalanched coordinate
hash selects one of 16,384 four-way sets; deterministic round-robin replacement only changes
residency, never values. Exact recipe/plan identities, content hashes, and XY coordinates are
checked on every hit, so fill order cannot affect output. LOD0–2 keep the fast original path because
they have only 33, 28, and 4 direct-map conflict misses in the audit. LOD6 remains at 5,570 misses
but only one conflict, showing that its remaining cost comes largely from its larger real XY
footprint and connector-shell work, not direct-map collision.
`voxel.CoreColumnCacheDirectMapped=1` is the direct-map negative control and was read back as `1`
in the trace. With gradient memo still on, the initial set took 6.624 s and 43.493 worker-seconds;
LOD4 used 11.071 worker-seconds. The tuned default took 4.238 s and 21.722 worker-seconds, with
LOD4 at 1.862 worker-seconds. The isolated audit also reports the per-LOD miss deltas above.
The separate memo negative control was `voxel.CoreMCGradientMemoization=0` with the four-way
column cache still enabled; both values were read back as `0/0`. It took 4.908 s and 27.609
worker-seconds, versus 4.238 s and 21.722 s at the `0/1` default. Its 3×3 support ring was 0.602 s
versus 0.447 s, and LOD0 last apply was 1.453 s versus 1.171 s. This cold-path A/B supports keeping
the exact gradient memo. The direct-map control is `1/1` and isolates the cache behavior; the memo
control is `0/0` and isolates the gradient behavior.
## 3. Shared XY pages
The corrected-source Standalone W8 overlap capture counted 281,910 cross-worker neighboring
duplicate columns at LOD0 and 123,803 at LOD4. Against Round17 (276,658 and 202,684), LOD0 is up
about 2%, while LOD4 is down about 39% after fixing intra-worker cache conflicts. The counters are
schedule-dependent work counts, not world output. Multiplying those counts by the current stage
audit's p95 column-time-per-miss ratios gives a rough estimate of 0.68 worker-seconds across the
LOD0/LOD4 repeats if each repeat avoided a recomputation and the shared lookup had zero cost. That
is about 3.1% of the measured 21.722 worker-seconds, before synchronization and memory costs. This
is an estimate, not a cold-path A/B win measurement.
After the four-way change, the remaining upper bound is too small to justify adding an unmeasured
synchronized page in this round. It would also add ownership/lifetime and bounded-memory work under
the S8 rules. The page was therefore not built. Existing immutable region pages and their S8
lifetime are unchanged; no new page lifetime needs proving.
## 4. Cold 40 m/s trace
Fresh BuildHost process, 25 cm SurfaceWorld, 40 m/s along +Y, background worker cap 1, ready queue
8, dynamic reserve, collision lookahead 1, `CoreColumnCacheDirectMapped=0`, and
`CoreMCGradientMemoization=1`. The `worker_backend_config` JSONL row reads back all these controls.
Round17 and Round18 use the same trace command and post-`BeginPlay` `elapsed_s` origin. In this run
`elapsed_s=4.238189`; raw trace `t_s` is 4.320372. Trace `t_s` begins 0.082022 s before the
end-of-BeginPlay origin. The 3×3 walkable support ring is measured at its first ready gate using
that same origin. S12's actor report uses a different clock origin; its comparisons are stated as
references, not clock-normalized samples.
| Metric | Round17 S13 | S14 primary | S14 fresh repeat |
|---|---:|---:|---:|
| Initial set | 2,578 tiles / 4.825 s | 2,578 / 4.238 s | 2,578 / 5.151 s |
| Initial-set worker seconds | 28.760 | 21.722 | 29.969 |
| 3×3 walkable support ring | 0.510 s | 0.447 s | 0.971 s |
| LOD0 last worker end | 1.131 s | 1.156 s | 1.524 s |
| LOD0 last apply | 1.146 s | 1.171 s | 1.532 s |
| 40 m/s moving readiness | 75/75 ready | 75/75 ready | 57/57 logged samples ready |
| Spawn `UWorld::Tick` p95/max | 3.133 / 5.426 ms | 4.200 / 5.571 ms | 4.601 / 6.682 ms |
| Walk `UWorld::Tick` p95/max | 30.314 / 43.142 ms | 32.218 / 45.720 ms | 33.986 / 41.654 ms |
| Initial-set LOD | Tiles | S14 primary worker s | S14 repeat worker s |
|---:|---:|---:|---:|
| 0 | 512 | 4.520 | 6.319 |
| 1 | 448 | 4.696 | 6.304 |
| 2 | 320 | 0.870 | 1.241 |
| 3 | 272 | 0.829 | 1.193 |
| 4 | 272 | 1.862 | 2.634 |
| 5 | 208 | 1.478 | 2.121 |
| 6 | 144 | 2.179 | 3.168 |
| 7 | 96 | 1.723 | 2.206 |
| 8 | 306 | 3.565 | 4.782 |
| **Total** | **2,578** | **21.722** | **29.969** |
The same-build LOD0 candidate-tile p95 fell 11.3% (14.079 to 12.492 ms). In the cold trace, LOD0
worker time fell 3.3% (4.672 to 4.520 s across 512 tiles, or 9.13 to 8.83 ms per tile).
The primary cold trace meets the 4.8 s full-set, 28.8 worker-second, and 0.51 s support-ring
targets, with all 75 moving samples ready. LOD0 is materially cheaper per tile. LOD0 last apply is
81 ms over the ~1.09 s target. I made one more fresh default trace to check the tick regression;
the same binary and `0/1` CVar readback passed the commandlet but took 5.151 s and 29.969
worker-seconds for all 2,578 tiles, 0.971 s for the support ring, and 1.532 s for the last LOD0
apply. Peak private memory was 3.29 GiB. Its spawn tick was 4.601/6.682 ms and walking tick was
33.986/41.654 ms p95/max; all 57 logged 40 m/s streaming samples stayed walkable-ready. Thus the
full-set, worker-second, support-ring, and LOD0 apply targets pass in the primary run but fail on
this repeat. Spawn tick p95/max is worse than S13 and matched S12 in both runs; walking p95 is
worse than both in both runs. The first-run walking max is worse than both references; the repeat
is worse than S12 but below S13. The strict no-worse tick goal therefore fails. I kept the S13
worker cap at 1; the measurements do not justify raising it.
## 5. Quality and determinism
- BuildHost W1/W8/W16 stable: density/mesh/payload/topology
`0cd2a1a4152ee4aa / a06243aee16b65d5 / c700162935c262d7 / 0af901aa42b452bc`.
- Standalone W1/W8/W12, fresh `--force-generate`: whole-view 2,553-tile hashes all match:
`c10697a8f48380c7 / e75c9119a1498cd5 / 49a9a8d1835a6c8c / edcb23288b5e8724`.
Full-detail 960-tile hashes also match:
`0ee0579bd15cbbe4 / 32e5d4964d610fee / 1932b96ee4b1d910 / 69743c6bad3447dc`.
- Core-off at 12.5 cm: `VOXELFORGE_CORE_OFF_LEGACY_PASS`.
- M2 Hybrid V1 and V2 at 25 cm: five analytic fixtures and borders passed.
- SurfaceWorld at 25 cm: BuildHost W1/W8/W16, geometry scale and height agreement, carve/fill,
native/bridge, and collision checks passed.
- S3 far-horizon agreement: max 0.0427 cm against 2 cm.
- S4 far-cap agreement: 128 shared points, max 0.0504 cm against 2 cm; negative control detected.
Cap rays: 1,584/1,584 (100%), no misses.
- FloatingIslands at 25 cm: W1/W8/W16 stable:
`4dcfb37585d7d986 / f14f76fbf065c6ed / 53035c45fd1a082e / 23550100654a4ec3`;
island and span contacts, anchors, carve/fill passed; water remained fixed.
No density, mesh, topology, payload, or collision output changed. No recipe bump or paired near/far
captures are needed.
## 6. Build, commands, and evidence
Builds (Normal priority, maximum 12 parallel workers):
```powershell
.\Tools\BuildVoxelForgeCoreHost.ps1 -MaxParallelActions 12 -TimeoutSeconds 900
.\Standalone\Build.ps1 -Target All -CompileWorkers 12 -BuildPriority Normal
```
BuildHost feature-stage controls:
```powershell
.\Tools\TestVoxelForgeCoreWorldHost.ps1 -SharedFeatureAuditOnly -CoreMCStageAudit -CoreColumnCacheDirectMapped 1 -CoreMCGradientMemoization 0 -CoreVoxelSizeCm 25 -TimeoutSeconds 900
.\Tools\TestVoxelForgeCoreWorldHost.ps1 -SharedFeatureAuditOnly -CoreMCStageAudit -CoreColumnCacheDirectMapped 0 -CoreMCGradientMemoization 1 -CoreVoxelSizeCm 25 -TimeoutSeconds 900
```
Cold stream command:
```powershell
.\Tools\TestVoxelForgeCoreWorldHost.ps1 -StreamingTraceOnly -StreamingOrder Legacy -NearReserveMode Dynamic -CoreVoxelSizeCm 25 -StreamingCollisionLookahead 1 -TestMoveDirection '0,1,0' -CoreRegionConcurrentAdmission 1 -StreamingResultBacklogCap 256 -TestMoveSpeedCmPerSecond 4000 -StreamingReadyQueueDepth 8 -StreamingBackgroundWorkerCap 1 -CoreColumnCacheDirectMapped 0 -CoreMCGradientMemoization 1 -TimeoutSeconds 900
```
The cold-path negative controls held every other argument fixed; the trace JSONL recorded the CVar
readbacks (`0/0` for memo-off, `1/1` for direct-map):
```powershell
.\Tools\TestVoxelForgeCoreWorldHost.ps1 -StreamingTraceOnly -StreamingOrder Legacy -NearReserveMode Dynamic -CoreVoxelSizeCm 25 -StreamingCollisionLookahead 1 -TestMoveDirection '0,1,0' -CoreRegionConcurrentAdmission 1 -StreamingResultBacklogCap 256 -TestMoveSpeedCmPerSecond 4000 -StreamingReadyQueueDepth 8 -StreamingBackgroundWorkerCap 1 -CoreColumnCacheDirectMapped 0 -CoreMCGradientMemoization 0 -TimeoutSeconds 900
.\Tools\TestVoxelForgeCoreWorldHost.ps1 -StreamingTraceOnly -StreamingOrder Legacy -NearReserveMode Dynamic -CoreVoxelSizeCm 25 -StreamingCollisionLookahead 1 -TestMoveDirection '0,1,0' -CoreRegionConcurrentAdmission 1 -StreamingResultBacklogCap 256 -TestMoveSpeedCmPerSecond 4000 -StreamingReadyQueueDepth 8 -StreamingBackgroundWorkerCap 1 -CoreColumnCacheDirectMapped 1 -CoreMCGradientMemoization 1 -TimeoutSeconds 900
```
Standalone processes were sequential, Normal priority, 12-CPU affinity, and used `--force-generate`:
```powershell
.\Standalone\bin\VoxelForgeCoreStandalone.exe --workers=1 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=3 --max-clip-level=8 --camera=0,-35,-487.94,0,-22 --far-horizon-lod8-step=0 --process-priority=Normal --process-affinity=4095 --frame-limit=60
.\Standalone\bin\VoxelForgeCoreStandalone.exe --workers=8 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --profile-column-overlap --force-generate --clip-radius=3 --max-clip-level=8 --camera=0,-35,-487.94,0,-22 --far-horizon-lod8-step=0 --process-priority=Normal --process-affinity=4095 --frame-limit=60
.\Standalone\bin\VoxelForgeCoreStandalone.exe --workers=12 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=3 --max-clip-level=8 --camera=0,-35,-487.94,0,-22 --far-horizon-lod8-step=0 --process-priority=Normal --process-affinity=4095 --frame-limit=60
```
Other BuildHost gate commands:
```powershell
.\Tools\TestVoxelForgeCoreWorldHost.ps1 -CoreOffTest -CoreVoxelSizeCm 12.5 -TimeoutSeconds 900
.\Tools\TestVoxelForgeCoreWorldHost.ps1 -HybridFixturesOnly -CoreMesherRecipe WorldAssemblerHybridV1 -CoreVoxelSizeCm 25 -TimeoutSeconds 900
.\Tools\TestVoxelForgeCoreWorldHost.ps1 -HybridFixturesOnly -CoreMesherRecipe WorldAssemblerHybridV2 -CoreVoxelSizeCm 25 -TimeoutSeconds 900
.\Tools\TestVoxelForgeCoreWorldHost.ps1 -CoreVoxelSizeCm 25 -TimeoutSeconds 900
.\Tools\TestVoxelForgeCoreWorldHost.ps1 -FloatingIslandsOnly -CoreVoxelSizeCm 25 -TimeoutSeconds 900
```
Measured binaries and SHA-256:
| Binary | SHA-256 |
|---|---|
| UE `UnrealEditor-Cmd.exe` | `ECCE9996191F7F7E69B3D104EECDD0E678AE69176FDCCD79828C3E75A0654D6D` |
| BuildHost `UnrealEditor-VoxelForge.dll` | `4E55A38547B96221562AEC84D61B0FFC7E455E21420C51E14D2BEACA88217A07` |
| BuildHost `UnrealEditor-VoxelForgeCore.dll` | `1F34F96208FC0E0A72CE2CE80014EBFB110C29C8333053A90735DF9C7BEE7949` |
| BuildHost `UnrealEditor-VoxelForgeEditor.dll` | `9B35350BBA3E7CE4F8D8DA617C216B21CB4CF9869FE5903FD84AAC6906B8187B` |
| Standalone `VoxelForgeCoreStandalone.exe` | `91D29D8BA421304F085BFAB4CCE5EC9DDD32C40BE13F15E118E0DC9606D21B84` |
Full logs, traces, and Standalone stdout/stderr are under `Saved/BuildHost/`; the current 40 m/s
trace files are in `Saved/BuildHost/HostProject/Plugins/VoxelForge/Saved/CoreWorldValidation/Logs/`.
The fresh repeat uses the same CVar-derived JSONL path as the primary trace, so its JSONL is the
current trace; the faster primary run's engine log summary is retained in that Logs directory as
`CoreWorldValidation-owner_surface_stream_trace_only_applyboost_default_bgcap_1_readyq_8_legacy_order_colcache_4way_gradientmemo_on_nearreserve_dynamic_trace_move_4000_lookahead_1_dir_0_1_0_region_1_backlog_256-backup-2026.10.19-15.44.14.log`.
Per-run Standalone command records and logs are in `Saved/BuildHost/WorldAssemblerM3/Round18/Standalone/`.
## 7. Failed probes, retries, and safety review
- `-coremcstageaudit=1` was ignored by Unreal’s boolean argument parser; the audit was repeated
with the bare `-coremcstageaudit` flag.
- An early direct-map control did not read back `1`, and an early audit binary did not log either
new CVar. Those measurements were rejected. I added the S11-style explicit BeginPlay parse and
trace readback, rebuilt BuildHost, then reran the direct/off baseline and tuned audit; the JSONL
readbacks are `1/0` and `0/1` respectively.
- The first corrected shared-audit command was rejected by a harness guard before launch because
it treated audit CVars as trace-only controls. The guard now allows them in shared-feature
audits; the rerun passed.
- The first W8 Standalone wrapper could not resolve its process-local memory helper type. That
run exited 0 and its process peak was 0.70 GiB, but its free-memory preflight was invalid. I
repeated W8 with the helper defined in that process: free-before 17.12 GiB, peak 0.71 GiB,
exit 0, and the whole-view hashes matched W1/W12.
- `Get-CimInstance` was denied and `Get-Counter` lacked the requested counter. I used
`GlobalMemoryStatusEx` instead; the initial available-memory reading was 15.85 GiB. BuildHost
scripts also enforce the 4 GiB preflight, Normal priority, 12-CPU affinity, 8 GiB process cap,
and 900 s timeout.
- Standalone build printed that `vswhere.exe` was not recognized and emitted existing
`VoxelStrateManager.cpp` C4838 narrowing warnings, but built both targets and exited successfully.
- BuildHost UBT passed on its first attempt; the 18 Core link shims passed link-safety inspection.
No `0xC0000142` occurred. No new `UECC-*` folder appeared (the only matching folder predates
this round, from 2026-09-17).
- Final diff review made the gradient memo's per-tile validity reset explicit by clearing every
validity byte after resizing the scratch array. Both targets were rebuilt and the corrected-source
stage, determinism, quality, and cold-trace gates were rerun; hashes stayed identical.
Diff review: no edits to `Epoch`, either MPSC queue, `EndPlay` draining, worker shutdown checks,
`ModsLock`, immutable region-page lifetime, or game-thread UObject/RMC mutation. The new cache and
gradient scratch remain thread-local. The readable RealtimeMeshComponent source was not modified.
No owner project, editor, asset, generated header, `Binaries/`, or `Intermediate/` source was edited.
No commit, push, or stash.
## 8. Files and compile spots
No new source file was added.
| Changed file | Likely compile/build spot |
|---|---|
| `Standalone/Core/include/VoxelForgeCore/VoxelForgeCore.h`, `Standalone/Core/src/VoxelForgeCore.cpp`, `Standalone/Core/src/WorldAssemblerInternal.h` | Standalone Core and BuildHost `VoxelForgeCore` |
| `Standalone/Source/VoxelForge/Public/VoxelMarchingCubesMesher.h`, `Standalone/Source/VoxelForge/Private/VoxelMarchingCubesMesher.cpp` | Standalone executable and BuildHost `VoxelForge` runtime |
| `Source/VoxelForge/Private/VoxelWorld.cpp` | BuildHost `VoxelForge` runtime |
| `Source/VoxelForgeEditor/Private/VoxelForgeExploreCommandlet.cpp` | BuildHost `VoxelForgeEditor` |
| `Tools/TestVoxelForgeCoreWorldHost.ps1` | BuildHost validation harness; no compile |
| `ARCHITECTURE.md`, `CODEMAP.md` | Documentation; no compile |
### Dialogue
**Owner:** What is inside the LOD0 MC-exclusive cost, why does LOD4 miss, and is a shared page worth it?
**Codex:** LOD0’s dominant measured MC-exclusive stage is density-grid evaluation excluding XY
column work (about 165 ns/sample), followed by grid-gradient normals (24 ns/sample after exact
memoization). The cache counters show LOD4’s direct-map spike was chiefly conflicts; four-way sets
remove those while keeping exact samples. Cross-worker repeats remain, but no shared-page A/B
measured a net cold-path win, so I left the S8 page lifetime unchanged.