Startup apply mode on by default (12 meshes / 14 ms per frame, ends when the initial set and walkable ring are ready, 30 s cap); normal play keeps the authored budget. Backlog peak 252 -> 10, LOD8 apply wait 1.1 s -> 4 ms. Ring 0.49 s, LOD0 1.40 s, 40 m/s ring 75/75. Remaining floor: frame-paced admission (~8.3 submits/frame, 8 running workers max). No geometry change. Report: Standalone/Research/WorldAssemblerM3/Round15. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01MmSoF64BbRFmk9C3p1VsBJ
15 KiB
World Assembler M3 — Round 15 (S11)
Date: 2026-10-19
Starting revision: b90d63d (S10)
Result: shared spawn-phase apply budget enabled by default; geometry and recipe unchanged.
Finding
The old 7.1 s result was an apply backlog layered on top of generation. In the matched authored-budget control, 2,578 initial tiles were generated. The four-visible-mesh cap was reached on 305 of 399 apply frames; the result backlog peaked at 252/256 and eight result-backlog-cap declines were recorded (decline rule 6). Dynamic near-reserve holds (rule 2) appeared on three frames in both runs; full task-cap holds (rule 1) appeared on 312 control frames and 309 default frames while the ten-task guard was occupied. Rule 6 (result backlog cap) appeared on two control frames, with eight declined tile attempts, and on zero default frames. Result-wait p95/max was 847.5/1,119.2 ms. LOD8's last worker finished at 6.068 s, but its result was not applied until 7.182 s.
I enabled the existing bounded startup apply mode in the shared AVoxelWorld::ProcessPendingChunks path: up to 12 visible applies or 14 ms per frame, capped at 30 seconds. It ends when the initial desired set and stationary walkable ring are ready, the desired epoch changes, a per-step override is active, or the duration expires. The regular authored budget (4 meshes/2 ms in this test) resumes for normal play. A trace record now reads back the CVar and resolved budgets. With the mode enabled, the peak backlog was 10/256, there were no backlog-cap declines, and result-wait p95/max fell to 16.6/19.3 ms. LOD8's last worker/apply were 6.015/6.019 s. The full set fell from 7.118 to 5.960 s, a 1.158 s (16.3%) improvement.
The remaining floor is generation/admission, not result application, collision cooking, or LOD4. The set's worker span was 5.581 s after the first request, with 26.786 worker-seconds total. Ten perfectly occupied slots would need 2.679 s, but the actor issued 2,578 requests over 310 submission passes (8.32 submissions/pass); sampled active-task guards averaged 9.90/10 while sampled running workers averaged 7.95 and peaked at 8. Across the request-to-ready interval, the trace integrates 4.78 busy-worker equivalents and 29.24 idle slot-seconds. The initial-set trace records one scheduler_admission on every actor frame from the first desired pass through ready, with no frame gaps. The control took 379 frames (6.758 s from first request), including 314 frames that submitted work and 65 drain-only frames; the default took 312 frames (5.602 s), 310 with submissions and two drain-only. That is about 56 admission frames/s, with 8.3 submissions per non-empty pass. The remaining floor is frame-paced admission/refill, with effective worker supply also below the ten task slots (running workers peaked at eight). The trace shows this occupancy limit but does not establish why the task backend tops out at eight.
Collision was not the startup floor: the 60 initial non-empty body updates had an 18.4 ms p95 submit-to-body-update interval, while the walkable ring was ready in 0.486 s. RMC section updates were not changed. LOD4 used the most aggregate worker time (6.590 s), but completed by 4.276 s; LOD8 remained the final LOD at 6.019 s. LOD4 averaged about 24.2 ms over the 272 tiles in the owner's count, but it did not set the tail, so I left its generation path alone.
Matched spawn results
Fresh BuildHost processes, same binary, same 25 cm SurfaceWorld plan and streaming options; only the startup apply CVar differed. Both generated/drained 2,578 initial tiles and applied 1,333 visible meshes.
| Metric | Authored budget: CVar 0 | Startup budget: default 1 |
|---|---|---|
| Full set ready | 7.118 s | 5.960 s |
| Walkable ring, 9/9 | 0.495 s | 0.486 s |
| Full LOD0 | 1.444 s | 1.403 s |
| Worker-seconds | 27.077 s | 26.786 s |
| Worker span from first request | 5.626 s | 5.581 s |
| First request to full ready | 6.758 s | 5.603 s |
| Ideal worker time, total / 10 slots | 2.708 s | 2.679 s |
| Integrated busy equivalents over worker span | 4.01/10 | 4.78/10 |
| Idle slot-seconds to full ready | 40.50 | 29.24 |
| Scheduler admission frames through ready | 379 | 312 |
| Non-empty submit passes / submissions per pass | 314 / 8.21 | 310 / 8.32 |
| Sampled active task guards, average / 10 | 8.24 | 9.90 |
| Sampled running workers, average / max | 6.62 / 8 | 7.95 / 8 |
| Worker queue p95 / max | 6.15 / 26.57 ms | 6.17 / 20.33 ms |
| Result queue p50 / p95 / max | 34.66 / 847.53 / 1,119.15 ms | 10.69 / 16.62 / 19.26 ms |
| Peak result backlog / cap | 252 / 256 | 10 / 256 |
| Backlog-cap declined tile attempts | 8 | 0 |
| Near-reserve decline frames | 3 | 3 |
| Apply frames through initial-ready | 399 | 332 |
| Apply-count cap frames | 305 | 0 |
| Max visible applies in one frame | 4 | 10 (12 allowed) |
| Total measured Apply time | 235.80 ms | 236.14 ms |
| Maximum Apply time in one frame | 1.576 ms | 2.357 ms |
| Initial non-empty body updates | 60 | 60 |
| Submit-to-body-update p95 / max | 17.69 / 17.81 ms | 18.37 / 18.45 ms |
The control spent 65 scheduler frames draining after its final non-empty submit pass; the default spent two. The startup CVar negative control is effective: startup_apply_config read back 0 for the control and 1 when omitted for the default run. Both records reported the authored budget as 4 meshes/2 ms and the startup budget as 12 meshes/14 ms. startup_apply_budget showed the default run entering and leaving the bounded phase. The cap, collision, reserve, order, speed and backlog settings were matched.
Worker timeline
Busy worker slot-seconds are integrated from the first request, in elapsed one-second bins (the last bin is approximately 0.6 s). Each value is CVar 0 / default 1.
| Time from first request | Busy worker slot-seconds, CVar 0 / default 1 |
|---|---|
| 0–1 s | 3.93 / 3.97 |
| 1–2 s | 3.92 / 3.92 |
| 2–3 s | 3.35 / 3.39 |
| 3–4 s | 6.63 / 6.48 |
| 4–5 s | 5.47 / 5.52 |
| 5–~5.6 s | 3.78 / 3.51 |
The apply change does not materially change generation occupancy. It removes the long post-generation queue wait, especially for the far LODs. Last visible apply per LOD, measured from the same spawn origin:
| LOD | Worker-seconds CVar 0 / default 1 | Last apply CVar 0 / default 1 |
|---|---|---|
| 0 | 3.827 / 3.725 | 1.444 / 1.403 s |
| 1 | 3.792 / 3.895 | 2.292 / 2.283 s |
| 2 | 0.813 / 0.806 | 2.857 / 2.849 s |
| 3 | 2.139 / 2.064 | 3.355 / 3.330 s |
| 4 | 6.685 / 6.590 | 4.352 / 4.276 s |
| 5 | 1.599 / 1.528 | 4.930 / 4.660 s |
| 6 | 2.076 / 2.077 | 5.383 / 5.060 s |
| 7 | 1.865 / 1.928 | 5.802 / 5.338 s |
| 8 | 4.280 / 4.171 | 7.182 / 6.019 s |
LOD8 last worker/apply were 6.068/7.182 s in the control and 6.015/6.019 s with the startup budget. That 1.114 s control-side wait nearly vanishes under the higher budget. LOD4 remains the highest total worker cost but not the completion tail.
Tick and 40 m/s ring
UWorld::Tick p95/max from the matched 6 m/s spawn and subsequent normal-walk windows:
| Window | CVar 0 spawn | Default 1 spawn | CVar 0 walk | Default 1 walk |
|---|---|---|---|---|
| Tick p95 / max | 1.805 / 5.374 ms | 2.740 / 5.175 ms | 2.364 / 28.993 ms | 2.483 / 28.876 ms |
The normal-walk p95 changed by 0.119 ms and max by -0.117 ms; the normal authored budget is restored after startup. In a separate fresh 40 m/s default run, 75/75 moving support-center samples had the full 9/9 ring (100%); first/last sample were 30.207/45.015 s. That high-speed stress run measured spawn tick p95/max 2.426/14.061 ms and walk tick p95/max 31.428/56.628 ms. It is a 40 m/s stress measure, not the normal-walk comparison.
Quality and determinism
No density, mesh generation, collision arithmetic or recipe output changed, so no recipe version bump is needed. The apply pacing change is shared by all world families. All requested gates passed:
- Core off at 12.5 cm: legacy path passed.
- M2 Hybrid V1 and V2 fixtures: all analytic fixtures and border checks passed.
- SurfaceWorld BuildHost at 25 cm: passed; actor collision, anchors and carve/fill checks passed; water remains fixed for the season.
- FloatingIslands BuildHost at 25 cm: passed; capsule contact, island/span height, carve/fill and switch-off legacy checks passed.
- S3/S4 standalone audit: S3 72 samples, max 0.0427 cm; S4 128 samples, max 0.0504 cm; both within 2 cm. The 100 cm negative control was detected for both. Cap census 385/385, coverage 2,520/2,520 (100%), no misses.
- 40 m/s walkable ring: 75/75 samples at 9/9 (100%).
Current-build worker hash matrices were stable:
| Run family / workers | Density | Mesh | Payload | Topology |
|---|---|---|---|---|
| Standalone W1/W8/W12 | c10697a8f48380c7 |
e75c9119a1498cd5 |
49a9a8d1835a6c8c |
edcb23288b5e8724 |
| SurfaceWorld BuildHost W1/W8/W16 | 0cd2a1a4152ee4aa |
a06243aee16b65d5 |
c700162935c262d7 |
0af901aa42b452bc |
| FloatingIslands BuildHost W1/W8/W16 | 4dcfb37585d7d986 |
f14f76fbf065c6ed |
53035c45fd1a082e |
23550100654a4ec3 |
Commands and artifacts
Fresh matched 6 m/s pair (the first command is the CVar negative control; the second omits the override to exercise the code default):
.\Tools\TestVoxelForgeCoreWorldHost.ps1 -StreamingTraceOnly -StartupApplyBoost 0 -StreamingOrder Legacy -NearReserveMode Dynamic -CoreVoxelSizeCm 25 -StreamingCollisionLookahead 1 -TestMoveDirection '0,1,0' -CoreRegionConcurrentAdmission 1 -StreamingResultBacklogCap 256 -TestMoveSpeedCmPerSecond 600 -TimeoutSeconds 900
.\Tools\TestVoxelForgeCoreWorldHost.ps1 -StreamingTraceOnly -StreamingOrder Legacy -NearReserveMode Dynamic -CoreVoxelSizeCm 25 -StreamingCollisionLookahead 1 -TestMoveDirection '0,1,0' -CoreRegionConcurrentAdmission 1 -StreamingResultBacklogCap 256 -TestMoveSpeedCmPerSecond 600 -TimeoutSeconds 900
40 m/s ring confirmation:
.\Tools\TestVoxelForgeCoreWorldHost.ps1 -StreamingTraceOnly -StreamingOrder Legacy -NearReserveMode Dynamic -CoreVoxelSizeCm 25 -StreamingCollisionLookahead 1 -TestMoveDirection '0,1,0' -CoreRegionConcurrentAdmission 1 -StreamingResultBacklogCap 256 -TestMoveSpeedCmPerSecond 4000 -TimeoutSeconds 900
Quality commands:
.\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
.\Standalone\bin\VoxelForgeCoreStandalone.exe --world-assembler-audit --workers=12 --clip-radius=3 --max-clip-level=8 --camera=0,-35,-487.94,0,-22 --process-priority=Normal --process-affinity=4095 --frame-limit=60
Determinism commands were run serially at Normal priority and affinity 4095. Standalone used the same command for workers 1, 8 and 12:
.\Standalone\bin\VoxelForgeCoreStandalone.exe --workers=$workers --world-assembler-prototype --stream-benchmark --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
BuildHost W1/W8/W16 matrices were part of the SurfaceWorld and FloatingIslands 25 cm gates above. Build commands:
.\Tools\BuildVoxelForgeCoreHost.ps1 -MaxParallelActions 12 -TimeoutSeconds 900
.\Standalone\Build.ps1 -Target All -CompileWorkers 12 -BuildPriority Normal
The BuildHost trace JSONL files remain under Saved/BuildHost/HostProject/Plugins/VoxelForge/Saved/CoreWorldValidation/Logs/; paired names begin CoreWorldValidation-owner_surface_stream_trace_only_applyboost_0_...move_600... and ...applyboost_default_...move_600.... The 40 m/s trace uses ...applyboost_default_...move_4000.... They remain in Saved, including files over 300 KB. Standalone stdout logs are in Saved/BuildHost/Round15/.
Final binary SHA-256:
| Binary | SHA-256 |
|---|---|
BuildHost UnrealEditor-VoxelForge.dll |
E2744E97F3690A4B125E01E4AC89CD21D6771BFD70F72B71301411FDDAEFA56C |
BuildHost UnrealEditor-VoxelForgeCore.dll |
D87CC56BACCDE6559705EEAEA7DB73D1A6ABF79484D37A3887B94A9FD62BABD3 |
BuildHost UnrealEditor-VoxelForgeEditor.dll |
C7F00CD4BD150236C1BAD2BB2D54E6617A9F4313C1CFE64487928CD400442459 |
Standalone VoxelForgeCoreStandalone.exe |
68C81625911DF9764354C3D75A059B8A735423110D66EF3D50916199F066E9ED |
Build, run and async-safety notes
- BuildHost compiled successfully with 12 max parallel actions. Standalone
Allcompiled successfully with 12 workers at Normal priority. The existingvswhere.exelookup warnings andVoxelStrateManager.cppC4838 conversion warnings remain. - Fresh processes were run serially, at Normal priority, with a 12-thread maximum. Free memory was above 17 GiB before the final launches; measured BuildHost peak private memory stayed below 3.7 GiB. No Unreal/Standalone process is running now. Each step stayed under the 15-minute limit.
- A first Standalone determinism launcher invocation had a PowerShell parse error from
W$workers:interpolation before launching any process. The launcher was corrected to${workers}and all W1/W8/W12 runs passed. No binary run failed, no0xC0000142occurred and no retry was needed. Saved/BuildHost/HostProject/Saved/Crashes/contains only the pre-existingUECC-Windows-F1A3EFD5469F5DD62E68EBBACAC84376_0000(2026-09-17); no new UECC folder appeared.- Async safety was checked in the source diff: no worker or queue behavior changed. Epoch validation, MPSC queue modes, EndPlay drain, worker
bShuttingDownchecks,ModsLock, region-page lifetime, and game-thread UObject/RMC mutation are untouched. The only new actor field records whether the first trace config record has been emitted. - No new source file. Compile spots:
Source/VoxelForge/Private/VoxelWorld.cppandSource/VoxelForge/Public/VoxelWorld.hcompile in the BuildHost VoxelForge module; the harness edit is PowerShell only. No generated header, recipe core, or.uassetchanged. Owner.uprojectand editor were not opened or built. RealtimeMeshComponent was read-only. - No commit, push or stash.
Files changed
Source/VoxelForge/Private/VoxelWorld.cpp— default-on bounded startup budget and trace readback of the effective CVar/budgets.Source/VoxelForge/Public/VoxelWorld.h— per-world one-time trace guard, with French and English comment.Tools/TestVoxelForgeCoreWorldHost.ps1—-1means no override (exercise code default); explicit0remains the negative control.CODEMAP.mdsection 3 — shared drain and trace behavior.ARCHITECTURE.mdsection 8.32 — behavior and measured floor.
Dialogue
User: Count first, identify the new 7.1 s floor from the trace, move shared behavior only when the CVar control proves it, and retain every quality/determinism gate.
Codex: The 4-mesh cap was holding completed LOD8 results for up to 1.1 s. The bounded 12-mesh/14 ms startup budget removed that backlog and brought the set to 5.96 s while preserving the 0.486 s walkable ring and all quality gates. The remaining measured span is 5.58 s of generation/admission; the trace narrows it to frame-paced refill and worker supply but cannot isolate actor tick refill from task-backend dispatch variation.