wip(assembler): round S5 -- streaming gates + trace; coarse-first order kept opt-in (no win)

Walkable/enclosed/refined gates defined; JSONL trace joins request, worker start,
build/apply and discards. Coarse-first + dynamic near reserve behind
voxel.StreamingCoarseFirst / voxel.StreamingDynamicNearReserve (default 0 =
S4 order): matched runs showed no walkability or full-view win and slower
LOD0/1 refinement. Instruments settled: 3.1 s standalone reproduced (16.7 s was
another generation route); black early captures were clear-only frames.
Hashes equal S4; Core-off, M2, SurfaceWorld/FloatingIslands BuildHost pass.

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 04:42:41 +02:00
1 parent 9d3c50ca95
commit c0596c5f24
32 files changed
+1049 -65

No files matched your search

@@ -1237,3 +1237,31 @@ occurred. I did not open the owner's editor, build his project or edit assets, a
push or stash.
— Luna
## World assembler S5 / M3 Round 9 — 2026-10-19
I separated walkable collision, rendered enclosure, and per-LOD refinement rather than using the
moving full-clipmap resident count as a gate. The old standalone order queued and started LOD0 first;
the owner-camera trace shows LOD8 queue-wait p95 at 16.290 s and LOD8 build p95 at 365.8 ms. A
five-second 60 m/s capture crossed 37 centers and logged 5,006 new requests / 3,211 queued cancels.
This establishes queue churn, but not a visual-gap duration or proof that the Unreal actor starves.
The source candidate gives the shared actor scheduler a collision-ring → coarse-shell → LOD0/1
refinement order, retains the authored near reserve while moving, and adds request/start ordinals and
discard tracing. Standalone mirrors the order and has a legacy-order control. I did not add an LOD8
placeholder because initial overlapping parents do not have an all-descendants swap gate. The loaded
full-view capture still shows a large sky region; do not call enclosure passed from tile counts.
The S4-to-current standalone timing mismatch is unresolved: both report 2,553 tiles, but the current
cold CPU run is 16.685 s versus Round 8's 3.107 s. The default-camera first run built only 2,226
tiles and was rerun with the owner camera. Spawn samples through 2.0 s and the 60 m/s mid-flight
sample are black. No candidate BuildHost, after captures, negative-control run, or S5 hash matrix is
available yet.
I stopped before compiling because plugin-root `CLAUDE.md` §#1 explicitly says never build/compile
and to hand off at “ready to build.” The report lists the exact outstanding checks, compile spots,
and every failed or corrected run in [WorldAssemblerM3/Round9/REPORT.md](../../WorldAssemblerM3/Round9/REPORT.md).
No owner editor/project or asset was touched; no commit, push or stash was made.
— Luna
@@ -0,0 +1,175 @@
[CmdletBinding()]
param(
[Parameter(Mandatory = $true)][string]$Label,
[Parameter(Mandatory = $true)][string[]]$ViewerArguments,
[ValidateSet('Spawn', 'Flight')][string]$CaptureMode = 'Spawn',
[switch]$WaitForFlightDrain
)
# Capture through the viewer's D3D back buffer; no desktop or window capture is used.
# Capturer le tampon D3D du viewer; aucune capture du bureau ou de la fenetre n'est utilisee.
Set-StrictMode -Version Latest
$ErrorActionPreference = 'Stop'
Add-Type -AssemblyName System.Drawing
$PluginRoot = [IO.Path]::GetFullPath((Join-Path $PSScriptRoot '../../../..'))
$ViewerExe = Join-Path $PluginRoot 'Standalone/bin/VoxelForgeCoreStandalone.exe'
$CaptureRoot = Join-Path $PSScriptRoot 'captures'
$LogRoot = Join-Path $PSScriptRoot 'viewer_logs'
[IO.Directory]::CreateDirectory($CaptureRoot) | Out-Null
[IO.Directory]::CreateDirectory($LogRoot) | Out-Null
if (-not ('VoxelForgeR9MemoryProbe' -as [type])) {
Add-Type -TypeDefinition @'
using System;
using System.Runtime.InteropServices;
public static class VoxelForgeR9MemoryProbe {
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
private struct MEMORYSTATUSEX {
public uint dwLength, dwMemoryLoad;
public ulong ullTotalPhys, ullAvailPhys, ullTotalPageFile, ullAvailPageFile;
public ulong ullTotalVirtual, ullAvailVirtual, ullAvailExtendedVirtual;
}
[DllImport("kernel32.dll", SetLastError = true)]
private static extern bool GlobalMemoryStatusEx(ref MEMORYSTATUSEX status);
public static ulong AvailablePhysicalBytes() {
var status = new MEMORYSTATUSEX();
status.dwLength = (uint)Marshal.SizeOf(typeof(MEMORYSTATUSEX));
if (!GlobalMemoryStatusEx(ref status)) throw new InvalidOperationException("GlobalMemoryStatusEx failed.");
return status.ullAvailPhys;
}
}
'@
}
if ([VoxelForgeR9MemoryProbe]::AvailablePhysicalBytes() -lt 4GB) {
throw 'Viewer launch skipped: less than 4 GiB of free physical memory.'
}
if (Get-Process UnrealEditor* -ErrorAction SilentlyContinue) {
throw 'Viewer launch skipped: an UnrealEditor process is still running.'
}
if (-not (Test-Path -LiteralPath $ViewerExe -PathType Leaf)) {
throw "Standalone viewer is missing: $ViewerExe"
}
Add-Type -AssemblyName System.Drawing
$SafeLabel = $Label -replace '[^A-Za-z0-9_-]', '_'
$SequenceSuffix = if ($CaptureMode -eq 'Spawn') { 'spawn' } else { 'mid_sprint' }
$CapturePrefix = Join-Path $CaptureRoot "${SafeLabel}_${SequenceSuffix}"
$RunArguments = [Collections.Generic.List[string]]::new()
foreach ($Argument in $ViewerArguments) { $RunArguments.Add($Argument) }
if ($CaptureMode -eq 'Spawn') {
$RunArguments.Add("--capture-spawn-sequence-prefix=$CapturePrefix")
$RunArguments.Add('--quit-after-spawn-captures')
$ExpectedIndices = @(0, 1, 2)
$TimeLimitSeconds = 60
} else {
$RunArguments.Add("--capture-flight-sequence-prefix=$CapturePrefix")
if (-not $WaitForFlightDrain) { $RunArguments.Add('--flight-capture-close-index=1') }
$ExpectedIndices = @(1)
$TimeLimitSeconds = if ($WaitForFlightDrain) { 900 } else { 45 }
}
$StdoutPath = Join-Path $LogRoot "$SafeLabel`_$SequenceSuffix.stdout.log"
$StderrPath = Join-Path $LogRoot "$SafeLabel`_$SequenceSuffix.stderr.log"
$QuotedArguments = @($RunArguments | ForEach-Object { '"' + $_.Replace('"', '\"') + '"' })
$ArgumentLine = $QuotedArguments -join ' '
$Process = Start-Process -FilePath $ViewerExe -ArgumentList $ArgumentLine `
-WorkingDirectory (Split-Path -Parent $ViewerExe) -PassThru -WindowStyle Normal `
-RedirectStandardOutput $StdoutPath -RedirectStandardError $StderrPath
$Started = [Diagnostics.Stopwatch]::StartNew()
try {
$Process.PriorityClass = [Diagnostics.ProcessPriorityClass]::Normal
$Process.ProcessorAffinity = [IntPtr]0xFFF
while ($true) {
$Process.Refresh()
if ($Process.HasExited) { break }
if ($Process.PrivateMemorySize64 -gt 8GB) {
throw "Owned viewer PID $($Process.Id) exceeded the 8 GiB private-memory limit."
}
if ($Started.Elapsed.TotalSeconds -gt $TimeLimitSeconds) {
throw "Owned viewer PID $($Process.Id) exceeded the $TimeLimitSeconds-second capture limit."
}
Start-Sleep -Milliseconds 200
}
$Process.WaitForExit()
$Process.Refresh()
if ($Process.ExitCode -ne 0) {
throw "Owned viewer PID $($Process.Id) exited with code $($Process.ExitCode)."
}
} catch {
$Process.Refresh()
if (-not $Process.HasExited) {
[void]$Process.CloseMainWindow()
if (-not $Process.WaitForExit(3000)) {
Stop-Process -Id $Process.Id -Force -ErrorAction SilentlyContinue
$Process.WaitForExit()
}
}
throw
}
function Save-DownscaledJpeg([string]$Source, [string]$Destination, [long]$Quality) {
$Original = [Drawing.Image]::FromFile($Source)
try {
$Width = [Math]::Min(960, $Original.Width)
$Height = [int][Math]::Round($Original.Height * $Width / $Original.Width)
$Small = New-Object Drawing.Bitmap($Width, $Height)
$Graphics = [Drawing.Graphics]::FromImage($Small)
try {
$Graphics.InterpolationMode = [Drawing.Drawing2D.InterpolationMode]::HighQualityBicubic
$Graphics.PixelOffsetMode = [Drawing.Drawing2D.PixelOffsetMode]::HighQuality
$Graphics.DrawImage($Original, 0, 0, $Width, $Height)
$Codec = [Drawing.Imaging.ImageCodecInfo]::GetImageEncoders() |
Where-Object { $_.MimeType -eq 'image/jpeg' } | Select-Object -First 1
$Parameters = New-Object Drawing.Imaging.EncoderParameters(1)
try {
$Parameters.Param[0] = New-Object Drawing.Imaging.EncoderParameter(
[Drawing.Imaging.Encoder]::Quality, $Quality)
$Small.Save($Destination, $Codec, $Parameters)
} finally {
$Parameters.Dispose()
}
} finally {
$Graphics.Dispose()
$Small.Dispose()
}
} finally {
$Original.Dispose()
}
}
$ViewerLog = Get-Content -LiteralPath $StdoutPath -Raw
foreach ($Index in $ExpectedIndices) {
$PngPath = '{0}_{1:D2}.png' -f $CapturePrefix, $Index
if (-not (Test-Path -LiteralPath $PngPath -PathType Leaf)) {
throw "Viewer exited normally but did not write required back-buffer capture index $Index."
}
if ($CaptureMode -eq 'Spawn') {
$CaptureTime = @('0.5s', '1.0s', '2.0s')[$Index]
$JpegPath = Join-Path $CaptureRoot "${SafeLabel}_spawn_$CaptureTime.jpg"
} else {
$JpegPath = Join-Path $CaptureRoot "${SafeLabel}_mid_sprint.jpg"
}
Save-DownscaledJpeg $PngPath $JpegPath 72
if ((Get-Item -LiteralPath $JpegPath).Length -ge 300KB) {
Save-DownscaledJpeg $PngPath $JpegPath 48
}
$Jpeg = Get-Item -LiteralPath $JpegPath
if ($Jpeg.Length -ge 300KB) { throw "Downscaled capture exceeds 300 KB: $($Jpeg.Name)" }
Remove-Item -LiteralPath $PngPath -Force
$Timing = [regex]::Match($ViewerLog, "\[(Spawn|Flight)SequenceCapture\] index=$Index elapsed_s=([0-9.]+)")
$Elapsed = if ($Timing.Success) { $Timing.Groups[2].Value } else { 'missing' }
Write-Host ('capture={0} elapsed_s={1} size={2} bytes' -f $Jpeg.Name, $Elapsed, $Jpeg.Length)
}
if ($CaptureMode -eq 'Flight') {
# Keep only the reviewed mid-flight JPG; remove this run's unused raw D3D frames.
# Garder uniquement le JPG de vol examine ; supprimer les tampons D3D bruts inutilises de ce run.
foreach ($Index in 0..4) {
$PngPath = '{0}_{1:D2}.png' -f $CapturePrefix, $Index
if (Test-Path -LiteralPath $PngPath -PathType Leaf) {
Remove-Item -LiteralPath $PngPath -Force
}
}
}
Write-Host ('viewer_closed=1 pid={0} exit_code={1} elapsed_s={2:0.000} priority=Normal affinity=0xFFF' -f
$Process.Id, $Process.ExitCode, $Started.Elapsed.TotalSeconds)
@@ -0,0 +1,147 @@
# World Assembler S5 / M3 Round 9 — measured result
**Status:** Standalone and BuildHost compile. Regression checks pass. The S5 scheduler is retained as an opt-in experiment; legacy order is the default again. S5 did not demonstrate an enclosure or walkability win, and the viewer could not confirm what was presented to the screen. The 60 m/s result also had invalid center deltas.
## Count, binaries and timing protocol
The owner clipmap is 2,553 tiles: 960 LOD0/1 and 1,593 coarse tiles. The final Standalone executable is Standalone/bin/VoxelForgeCoreStandalone.exe.
The matched CPU protocol used a fresh process, the staged owner_world.json, 12 workers, normal priority, affinity 0xFFF, radius 3, max LOD 8, camera 0,-35,-487.94,0,-22, world-assembler-prototype, force-generate, stream-benchmark and stream-hash. Same mode and settings for before/after:
| Run | 2,553 tiles | Hashes |
|---|---:|---|
| Legacy order | 3.641 s | Same as candidate |
| Coarse-first | 3.620 s | Same as legacy |
| Final coarse-first repeat | 3.579 s | Same as legacy |
| Final rebuilt default (legacy) smoke | 3.592 s | Same as legacy |
This is a 0.6–1.7% difference, within run noise. The 27-tile CPU mesh-ready measurement was 55 ms legacy / 22 ms coarse-first; Standalone has no collision cooking, so this is not a walkability result.
Round 7/8 report 2.975/3.107 s. The saved reproduction log, s4_protocol_reproduce_ffff.stdout.log, reproduces the 3.1 s result at 3.146 s with the prototype route, 2,553 tiles, 12 workers, hash on, normal priority and affinity 0xFFFF. The Round 7/8 reports did not preserve the exact executable hash or full launch command, so the historical binary identity cannot be established. Their Round 8 p95 run also inherited 0xFFFF, while the main S5 before/after protocol pins 0xFFF.
The reported 16.685 s run has no raw command log. A later run without the prototype route took 18.668 s, produced a different density hash, and emitted no LOD8 cap triangles; the correct prototype route produces density hash c10697a8f48380c7 and the 385-tile cap. This makes a different generation route the likely cause of the 16.685 s result, but the missing original log prevents proving its exact flags. It was not a matched comparison based on tile count alone. CPU-idle state was not controlled.
## Capture and cap instruments
The old black sequence logged three Presents with zero tile geometry and zero draw batches before its screenshots. That points to clear-only startup frames, not a capture-before-first-present race. Its logger did not tie each image to a frame index, so the exact capture frame cannot be proven. The matched S5 captures record frame index, prior presents, resident meshes, draw batches and triangle counts at capture:
| Sample | Legacy frame / tiles / batches / triangles | Coarse-first frame / tiles / batches / triangles |
|---|---|---|
| Spawn 0.5 s | 4 / 451 / 6 / 151,020 | 5 / 76 / 4 / 834,954 |
| Spawn 1.0 s | 13 / 1,801 / 41 / 446,090 | 12 / 133 / 4 / 1,804,858 |
| Spawn 2.0 s | 25 / 2,308 / 70 / 904,353 | 27 / 559 / 44 / 3,240,081 |
The capture reads the D3D back buffer pre-present after earlier frames have presented. The candidate Presents returned DXGI_STATUS_OCCLUDED even though the window was visible, so the images prove rendered back-buffer geometry but cannot establish player-visible pixels. The coarse-first images are visibly much sparser at spawn; treat that as a possible early visual regression, not a confirmed screen result.
Matched JPEGs are 9.7–21.8 KB, all below 300 KB. The viewer was capped at 60 fps with VSync and closed after capture. Coarse-first is now opt-in with --coarse-first-stream-order; legacy is the default:
| Capture | Legacy | Coarse-first |
|---|---|---|
| Spawn 0.5 s | [JPG](captures/s5_before_legacy_spawn_0.5s.jpg) | [JPG](captures/s5_after_coarse_spawn_0.5s.jpg) |
| Spawn 1.0 s | [JPG](captures/s5_before_legacy_spawn_1.0s.jpg) | [JPG](captures/s5_after_coarse_spawn_1.0s.jpg) |
| Spawn 2.0 s | [JPG](captures/s5_before_legacy_spawn_2.0s.jpg) | [JPG](captures/s5_after_coarse_spawn_2.0s.jpg) |
| 10 m/s mid-sprint | [JPG](captures/s5_before_legacy_10ms_mid_sprint.jpg) | [JPG](captures/s5_after_coarse_10ms_mid_sprint.jpg) |
| 60 m/s mid-sprint | [JPG](captures/s5_before_legacy_mid_sprint.jpg) | [JPG](captures/s5_after_coarse_mid_sprint.jpg) |
The S4 low-angle ray audit used the same owner camera at voxel origin (0,-140,-1951.8): all 72 upward rays at that view hit the roof, and all 2,520/2,520 audit rays hit. The dark “sky” region is the cap underside, not uncovered sky. S4 reports 385 refined LOD8 cap tiles; the final band census requested 413 cap bands, emitted 411, and classified the remaining two as zero-area boundary touches, with no unexplained empty bands. Far/near agreement was 0.0504 cm against a 2 cm tolerance.
## Gates and sprint results
The BuildHost actor trace reports collision readiness for the support tile and required 3×3 ring. Both orderings reached 9/9 ready at cold spawn:
| Gate interval | Legacy | Coarse-first |
|---|---:|---:|
| Cold spawn | 0.583→0.624 s (41.2 ms) | 0.577→0.618 s (41.6 ms) |
| Teleport to center (-5,0,-26) | 6.427→6.642 s (215 ms) | 6.389→6.598 s (208 ms) |
| Teleport to center (-2,8,-47) | 15.066→15.349 s (283 ms) | 14.943→15.504 s (561 ms) |
The actor test teleported between centers and logged speed 0; it is not a 10/60 m/s actor walk. Two separate enforced-collision-gate runs, one per order, reached the 900 s limit while support requests kept recentering. Thus the readiness counter passed at cold spawn, but physical gate enforcement during movement remains unverified.
Standalone cannot measure collision readiness. Its logged full LOD0/1 set completed at 0.889 s in the legacy spawn run. Coarse-first had not completed that set by the 2.053 s capture; its 10 m/s run logged completion at 3.450 s. The 1.57 s refinement target therefore failed for coarse-first in this viewer workload.
BuildHost full-set residency samples were spaced about 250 ms apart. These are per-LOD total residency times from trace start, not per-tile time-in-range:
| LOD | Legacy seconds | Coarse-first seconds |
|---:|---:|---:|
| 8 | 3.352 | 3.338 |
| 7 | 3.603 | 3.589 |
| 6 | 3.854 | 3.841 |
| 5 | 4.105 | 4.092 |
| 4 | 4.858 | 4.847 |
| 3 | 5.108 | 5.099 |
| 2 | 5.360 | 5.351 |
| 0 | 5.865 | 5.853 |
| 1 | 6.367 | 6.354 |
The largest difference is 13 ms, below the sample interval. The full desired LOD sets arrive after the 1.57 s goal in both orders. Enclosure gap frames/time were not measured: DXGI reported occlusion, and no reliable screen-visible gap counter exists. The static S4 ray audit proves roof coverage after generation, not startup or moving enclosure.
The S5 full-view tile p95 probe used the same 12 workers, normal priority, inherited affinity 0xFFFF, 60 fps/VSync and no timeline trace for both orderings. Each viewer was closed immediately after InitialClipmapReady:
| LOD | Legacy p95 ms | Coarse-first p95 ms |
|---:|---:|---:|
| 0 | 16.398 | 17.456 |
| 1 | 15.665 | 15.804 |
| 2 | 4.393 | 4.292 |
| 3 | 17.263 | 18.055 |
| 4 | 59.038 | 58.867 |
| 5 | 17.649 | 17.915 |
| 6 | 51.086 | 57.610 |
| 7 | 29.419 | 32.116 |
| 8 | 82.782 | 85.041 |
The coarse-first full view took 3.309 s versus 3.187 s legacy. LOD6/7 p95 rose 12.8%/9.2% in this one pair; the result cannot establish “within noise.” S4’s p95 check was a separate eight-key staged test (LOD7 19.801/19.807 ms, LOD8 58.346/58.411 ms for S3/S4) and was not replayed on those exact keys in S5. Do not claim an apples-to-apples S3/S4 p95 pass.
Standalone sprint benchmark results:
| Speed | Order | Requests incl. 2,553 spawn | Queued cancellations | Discarded stale results | Nearest-ready p95 / max | Max lag p95 / max | Status |
|---:|---|---:|---:|---:|---|---|---|
| 10 m/s | Legacy | 33,730 | 3 | 10 | 126.628 / 171.452 ms | 1.27 / 1.71 m | FAIL |
| 10 m/s | Coarse-first | 33,730 | 0 | 0 | 129.812 / 148.705 ms | 1.30 / 1.49 m | FAIL |
| 60 m/s | Legacy | 39,632 | 29,809 | 138 | 93.101 / 114.475 ms | 5.59 / 6.87 m | FAIL, invalid deltas |
| 60 m/s | Coarse-first | 38,679 | 22,662 | 120 | 68.748 / 182.143 ms | 4.12 / 10.93 m | FAIL, invalid deltas |
The 10 m/s route had valid unit-+Y center deltas: coarse-first slightly worsened p95 lag but improved worst lag. At 60 m/s the center deltas were invalid, so the apparent p95/crossing-wall improvement is not a valid matched gate win; its worst nearest-ready lag was worse by 67.7 ms. Request/cancellation counts cover the initial cold request set and crossings 1–250; stale discards include initial work and crossings 1–250.
The actor trace’s UpdateChunks sample is not an isolated scheduler timer. Legacy mean/p95/max was 0.549/0.683/5.480 ms; optimized coarse-first was 0.116/0.269/4.860 ms. The pre-optimization candidate had 79.073 and 35.510 ms spikes from sorting each level repeatedly while at capacity. The final candidate skips full queues and only sorts missing, nonpending tiles. No blocking wait was added to Tick.
## Determinism, regression checks and async safety
Standalone final 2,553-tile hashes match S4: density c10697a8f48380c7, mesh 430d2be2bdd8b988, payload b7b33e14092225c9, topology c5c46d66606a819e. LOD0–3 hashes also match S4 exactly:
| LOD | Density | Mesh | Payload | Topology |
|---:|---|---|---|---|
| 0 | 769f2a706d585a72 | 33eeeb39fa443816 | 645621a1d968983f | c2457ed905036c9d |
| 1 | 69cc5a5c0a2c60af | b48335f5410c57d5 | d15c5480162ab8ba | feca1bd025823604 |
| 2 | 85deed5683a77202 | 53469895987aeea2 | e55f8ae7e1532033 | d5feb12a0e85c09b |
| 3 | 6518caefb3be7e7f | ec513c90b853a614 | f62fa1137ff17f82 | ccf1dcf681965816 |
BuildHost SurfaceWorld at 25 cm passed W1/W8/W16 with density 0cd2a1a4152ee4aa, mesh 80a5b054b904b1a2, payload bf2f1b40dff38acc, topology 56074198682d5e18. FloatingIslands at 25 cm passed W1/W8/W16, collision, edits and switch-off. Core-off legacy passed at 12.5 cm; M2 V1 and V2 each passed five focused fixtures plus border. S4 roof coverage/agreement and S3 ground agreement passed; final ground delta was 0.000 cm and final far-horizon agreement max was 0.0427 cm.
Async safety audit: all four result queues remain EQueueMode::Mpsc; EndPlay sets bShuttingDown, waits ActiveTaskCount to zero, then drains queues. Generation workers check shutdown state. Both LoadTile and LoadCoreTile carry GenerationEpoch in the result and reject stale results; ModsLock behavior is unchanged. No async path or generated header was removed or rewritten.
## Builds, run ledger and changed files
Final Standalone Build.ps1 -Target All and BuildVoxelForgeCoreHost.ps1 builds passed. BuildHost link safety checked 96,244 dumpbin lines against 421 copied type names, verified five staged asset hashes, and linked/audited 18 Core shims. Recent launches had over 17 GiB free RAM; recorded runtime peaks stayed below 4 GiB. No run returned 0xC0000142. No new UECC-* folder appeared; the only crash folder is dated 2026-09-17.
Failed, retried or capped attempts:
- The first baseline used the default camera and generated 2,226 tiles in 6.521 s; the owner-camera run restored 2,553.
- One standalone hash launch omitted stream-benchmark and entered the viewer; it was stopped after 146 s and rerun correctly. A later clip-radius 6 request hit the standalone safety bound.
- A generic horizon test targeted invalid /Game/Untitled and failed; it was not an owner-world result. Initial headless/GDI captures did not read the D3D frame; the viewer back-buffer path replaced them.
- Get-CimInstance memory preflight was denied; subsequent checks used GlobalMemoryStatusEx. A fresh-shell helper/preflight attempt failed before process launch and was corrected. Two tile-profile command strings also had PowerShell parse errors before launch; the corrected pairs produced complete metrics.
- Both enforced-collision-gate actor runs timed out at 900 s while support requests recentered. All four tile-profile viewers reached InitialClipmapReady, were closed deliberately, and returned exit -1 on WM_CLOSE; their timing output was complete.
**Habits:** Counted 2,553 tiles and checked the executable/mode; evaluated the staged owner plan and walk; used fresh matched before/after settings; explained the Round 7/8 timing discrepancy and affinity difference; kept the result report bounded to measured outcomes.
## Source files and compile spots
No new C++ source file was added. Modified C++:
- Source/VoxelForge/Private/VoxelWorld.cpp and Source/VoxelForge/Public/VoxelWorld.h — VoxelForge runtime module; BuildHost UBT.
- Source/VoxelForge/Private/VoxelStartupTrace.cpp and Source/VoxelForge/Public/VoxelStartupTrace.h — VoxelForge runtime module; BuildHost UBT.
- Standalone/Source/StandaloneViewer.cpp and Standalone/Source/StreamingWorld.h — Standalone/Build.ps1 -Target All.
Modified supporting scripts/docs: Standalone/Build.ps1, Tools/VoxelForgeTest.ps1, Tools/TestVoxelForgeCoreWorldHost.ps1, Standalone/Research/WorldAssemblerM3/Round9/CaptureViewerSequence.ps1, CODEMAP.md §3, ARCHITECTURE.md §8.26. The capture helper is the only new helper source.
### Dialogue
**User:** Check the instrument before judging the scheduler.
**Luna:** The 3.1 s prototype result reproduced; the matched gates did not justify a default-on order, so coarse-first remains opt-in.
Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB