Files
Fr0zkaandClaude Opus 5.5 dd9bfd3217 wip(assembler): round S11 -- bounded spawn apply budget: in-game full set 7.1 s -> 6.0 s
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
2026-10-19 13:03:44 +02:00

15 KiB
Raw Permalink Blame History

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 All compiled successfully with 12 workers at Normal priority. The existing vswhere.exe lookup warnings and VoxelStrateManager.cpp C4838 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, no 0xC0000142 occurred and no retry was needed.
  • Saved/BuildHost/HostProject/Saved/Crashes/ contains only the pre-existing UECC-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 bShuttingDown checks, 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.cpp and Source/VoxelForge/Public/VoxelWorld.h compile in the BuildHost VoxelForge module; the harness edit is PowerShell only. No generated header, recipe core, or .uasset changed. Owner .uproject and 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 — -1 means no override (exercise code default); explicit 0 remains the negative control.
  • CODEMAP.md section 3 — shared drain and trace behavior.
  • ARCHITECTURE.md section 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.