# 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.