wip(assembler): round S2 (Sol) -- shared per-tile feature queries for every Core family; island placement 30x faster

Island-only worker context replaced by a shared worker-local candidate domain
(WorldAssemblyFeatureTileListV1 / ScopedWorldAssemblyFeatureQueriesV1) serving
SurfaceWorld, FloatingIslands and far-shell queries; a per-domain cost hint keeps the
full scan on small plans. Content placement prepares the same queries and skips proven
air: owner island cell p95 7.07 -> 0.24 ms; populated fixture 572 exact placements,
3.27 s -> 29 ms. Full/candidate hashes equal with dropped-feature controls on both
families; S1 default W1/W8/W16 hashes reproduced; Core-off and M2 fixtures pass.
Default contract for future families in ARCHITECTURE 8.23. Run on gpt-6.1-sol medium.

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-18 19:50:45 +02:00
1 parent d6e69420e8
commit 6ddb834b1c
19 files changed
+1849 -132

No files matched your search

@@ -1138,3 +1138,59 @@ link-safety passed. No 0xC0000142 retry or new UECC folder occurred. I did not o
editor or build his project, edit any .uasset, create a link, commit, push or stash.
— Luna
## World assembler S2 / M3 Round 6 — 2026-10-18
The shared engine now owns a family-neutral, worker-local feature-query scope. I removed the
island-only context from ShapeWorld; SurfaceWorld finite features, island groups, meshing, far-shell
field calls, decoration cells and landmark columns use the same domain/identity/halo contract.
S1's root-aware positive-density bounds and ordered connector composition are preserved.
The measurements matter here: the staged SurfaceWorld has one finite shelf, and the staged island
plan has four islands. Forced candidate bookkeeping gave no useful small-plan gain and regressed
the island tile timings by 7–13%. I added a shared cost hint, resolved once per domain, so these
small plans keep their full evaluator. Richer plans still use candidates. With the actual staged
owner template expanded to 256 islands, forced-list p95 was 110.570 -> 7.3619 ms (about 15x), with
identical hashes and a detected dropped-feature control. The composed surface stress (64 shelves,
one XY height writer and one cap writer) was 0.7084 -> 0.4078 ms, again exact with its control caught.
The S1 57x stress number used a different Round 3 template, so I do not compare those as a regression.
The placement cost came from marching almost the entire strate and using a full plan at every
step. Family-declared solid-support bounds now feed a shared column range query, alongside the
same feature scopes. We skip only certified air and keep the old march phase, bisection,
interpolation and transforms. Owner-palette p95 fell 7.0706 -> 0.2385 ms, with 58.84 density calls
per cell versus S1's 7,763.38. Its sampled authored palette still places zero objects; I keep that
limitation explicit rather than claiming those timings include spawning trees.
A separate populated fixture produced 572 placements across 14 cells. All 572 full/candidate
transforms match exactly, all canonical anchor checks pass, and the largest density residual is
0.035156 Core voxel units. The 64-cell active batch, including merge and real HISM application,
was 3271.147 -> 29.105 ms. All 572 instances were applied and then cleared. This is synchronous
CPU work under null RHI; it excludes rendering, GPU upload, async tree completion and owner tree
Blueprint logic. One run failed the new count assertion because normal region application clears
live landmark footprints. I isolated the validation fixture from those footprints; normal content
keeps them enabled. The corrected run passes.
BuildHost SurfaceWorld passed its full actor/streaming/collision/edit checks and W1/W8/W16 with
S1's default 25 cm hashes. The final island actor also keeps S1's entire W1/W8/W16 matrix. The final
focused surface replay checks LOD0/1/7/8 full-versus-default tile hashes after the cost hint. M2 V1/V2
fixture repeats, borders, MC identity and all 125 doorway phases pass. A separate Core-off run
proves unchanged legacy density and 12.5 cm scale. All builds/link audits passed. No timeout,
0xC0000142 or new UECC folder occurred. The failed HISM fixture run exited normally with test status 1.
My next structural suggestion is an immutable per-strate family-provider table, carrying declared
bounds, cost hints, value certificates and optional support/surface queries. It would avoid repeating
concrete family enumeration and rebuilding metadata in each consumer. I have not rebuilt that
boundary this round; the report lists the allocation, many-strate, hash and stale-provider evidence
needed first. Preserve the existing bounded biome lattice and cave interval machinery meanwhile.
New source files are `Round6/SharedFeatureListAudit.cpp` and `Round6/BuildSharedFeatureListAudit.ps1`
under WorldAssemblerM3. The report lists every modified source, likely compile spots, all failed and
replayed runs, timing limitations and the plain-words owner note. CODEMAP section 3 and ARCHITECTURE
section 8.23 are updated. No owner project/editor was opened, closed or built. No .uasset was edited,
and no link, commit, push or stash was created.
[Full S2 report](../../WorldAssemblerM3/Round6/REPORT.md).
— Sol
@@ -0,0 +1,61 @@
[CmdletBinding()]
param([string]$IslandAssemblyPath, [string]$SurfaceAssemblyPath)
$ErrorActionPreference = 'Stop'
$PluginRoot = [IO.Path]::GetFullPath((Join-Path $PSScriptRoot '..\..\..\..'))
$HostOutput = Join-Path $PluginRoot 'Saved\BuildHost\HostProject\Plugins\VoxelForge\Saved\CoreWorldValidation\User\Saved\CoreWorldValidation\Output'
if (!$IslandAssemblyPath) { $IslandAssemblyPath = Join-Path $HostOutput 's2_assembly_FloatingIslands.json' }
if (!$SurfaceAssemblyPath) { $SurfaceAssemblyPath = Join-Path $HostOutput 's2_assembly_SurfaceWorld.json' }
$Results = Join-Path $PSScriptRoot 'results'
$BuildRoot = Join-Path $PluginRoot 'Standalone\Build\VoxelForgeCore'
$Exe = Join-Path $BuildRoot 'SharedFeatureListAudit.exe'
$Rsp = Join-Path $BuildRoot 'shared-feature-list-audit.rsp'
$VcVars = 'E:\Program Files\Microsoft Visual Studio\2022\Community\VC\Auxiliary\Build\vcvars64.bat'
$Source = Join-Path $PSScriptRoot 'SharedFeatureListAudit.cpp'
$Library = Join-Path $BuildRoot 'VoxelForgeCore.lib'
foreach ($Required in @($IslandAssemblyPath,$SurfaceAssemblyPath,$VcVars,$Library,$Source)) {
if (!(Test-Path -LiteralPath $Required -PathType Leaf)) { throw "Missing audit input: $Required" }
}
[IO.Directory]::CreateDirectory($Results) | Out-Null
$Lines = @('/nologo','/std:c++20','/O2','/arch:AVX2','/fp:precise','/EHsc',
('/I"{0}"' -f (Join-Path $PluginRoot 'Standalone\Core\include')),
('/Fe"{0}"' -f $Exe),('"{0}"' -f $Source),('"{0}"' -f $Library))
[IO.File]::WriteAllLines($Rsp,$Lines,[Text.UTF8Encoding]::new($false))
Push-Location $BuildRoot
try {
$Command = 'call "{0}" >nul && cl.exe @"{1}"' -f $VcVars,$Rsp
& $env:ComSpec /d /s /c $Command
if ($LASTEXITCODE -eq -1073741502) { & $env:ComSpec /d /s /c $Command }
if ($LASTEXITCODE -ne 0) { throw "Audit compile failed: $LASTEXITCODE" }
} finally { Pop-Location }
for ($Attempt=1;$Attempt -le 2;++$Attempt) {
$Stdout = Join-Path $Results "shared_audit_attempt_$Attempt.stdout.log"
$Stderr = Join-Path $Results "shared_audit_attempt_$Attempt.stderr.log"
$Process = Start-Process -FilePath $Exe -WindowStyle Hidden -PassThru -WorkingDirectory $BuildRoot `
-ArgumentList @(('"{0}"' -f $IslandAssemblyPath),('"{0}"' -f $SurfaceAssemblyPath),('"{0}"' -f $Results)) `
-RedirectStandardOutput $Stdout -RedirectStandardError $Stderr
$Process.PriorityClass = [Diagnostics.ProcessPriorityClass]::Normal
$Process.ProcessorAffinity = [IntPtr]0xFFF
$Timer = [Diagnostics.Stopwatch]::StartNew()
$Peak = 0L
while (!$Process.WaitForExit(250)) {
$Process.Refresh()
$Peak = [Math]::Max($Peak,$Process.PrivateMemorySize64)
if ($Timer.Elapsed.TotalSeconds -gt 900 -or $Peak -gt 8GB) {
Stop-Process -Id $Process.Id -Force
throw 'Shared audit exceeded 15 minutes or 8 GiB.'
}
}
$Process.WaitForExit()
$Process.Refresh()
$ExitCode = $Process.ExitCode
if ($null -eq $ExitCode -and (Select-String -LiteralPath $Stdout -SimpleMatch 'SHARED_FEATURE_AUDIT_PASS' -Quiet)) { $ExitCode=0 }
"attempt=$Attempt exit=$ExitCode elapsed_s=$($Timer.Elapsed.TotalSeconds) peak_private_bytes=$Peak" |
Add-Content (Join-Path $Results 'shared_audit_ledger.txt')
Get-Content $Stdout
Get-Content $Stderr
if ($ExitCode -eq -1073741502 -and $Attempt -eq 1) { continue }
if ($ExitCode -ne 0 -or !(Select-String -LiteralPath $Stdout -SimpleMatch 'SHARED_FEATURE_AUDIT_PASS' -Quiet)) {
throw "Shared feature audit failed: $ExitCode"
}
break
}
@@ -0,0 +1,269 @@
# World assembler S2 / M3 Round 6
Date: 2026-10-18. Author: Sol. Base: `d6e6942`, branch `assembler/world`. No commit, push or stash.
## Shared engine change
The island-only worker context has been removed from `ShapeWorldInternal.h`.
`WorldAssemblyFeatureTileListV1` and `ScopedWorldAssemblyFeatureQueriesV1` now carry a shared,
worker-local candidate domain, keyed by immutable recipe/plan identity. Nested scopes restore their
predecessor; samples outside the prepared domain use the full evaluator. Tile preparation includes
the mesher's normal halo and prepares both existing native families. Derived far-shell field calls
stay in that scope too. The old island payload names remain aliases so S1 research tools still build.
Families retain their mathematics: SurfaceWorld declares XY influence for column writers and finite
no-op boxes for volumetric exceptions; islands retain S1's root-aware positive-density certificate
and ordered island/connector groups. The engine never assumes that density magnitude is Euclidean
distance. Unknown operations stay active. A shared `candidateEvaluationUseful` cost hint is resolved
once per domain. The measured one-feature SurfaceWorld and four-island plans prefer the full scan;
larger plans retain culling. Audits force candidates on small plans to prove their bounds too. No density arithmetic, recipe serialization/version,
voxel-size resolution, queue, Epoch, edit lock or streaming policy was changed.
The default contract for future caves, shafts, pits, passages and rivers is documented in
ARCHITECTURE §8.23. Declare conservative bounds and any value-side proof needed to preserve exact
positive values. Preserve operation order; unknown proofs evaluate normally. An air-base family can
also declare conservative solid support, allowing the shared column union to shorten a search.
Solid-base caves cannot use that air proof. Every new proof needs equal full/candidate hashes and a
dropped-needed-feature control.
Surface biome-site selection already searches a fixed local lattice and is cached by XY. It is not
a global feature scan. We preserve that machinery and target its finite feature loops. Existing
cave extraction keeps its existing line/spatial bins; this round makes no new cave performance claim.
FarShells remains derived repair geometry with existing connector/stratum candidate filtering, rather
than becoming another canonical generator. Its field queries inherit the shared scope.
## Placement cause and correction
Native island placement previously scanned the entire owner strate, calling a full-plan evaluator
at each step. The owner workload used about 7,763 density queries per cell in S1. Its sampling cell
was mostly air, so optimizing only the top-anchor helper did not remove the dominant work.
Snapshots now declare conservative support bounds once. Decoration cells and landmark columns
prepare the same shared feature queries as meshing. A shared support-union query skips proven air,
including entirely empty columns. The march retains its original lattice phase, crossing budget,
four bisections, interpolation, normals and placement hashes. No alternate approximate top surface
was introduced. Companion queries get their own nested domain when needed.
Validation preserves the owner's palette and reports it separately from a deliberately populated
fixture. That fixture uses dense deterministic floor placements, both water classifications, the
resolved biome tags, and a staged decoration mesh (engine cube fallback if none is available).
It checks exact full/candidate transforms and canonical island density residuals, then merges and
applies real HISM regions and clears them immediately. CPU totals include cell preparation, merge
and region application; the identical application/merge cost is shared by both comparison totals.
The isolated HISM fixture bypasses live landmark footprints, which otherwise suppress its instances.
Normal region application keeps those footprints enabled. Null RHI does not measure GPU upload,
rendering, a rendered frame, or asynchronous cluster-tree completion. Existing native content
snapshots still describe the planned base field; this round does not add edit-aware reanchoring.
## Measurements and proof
The field audit replays the plans exported from BuildHost's staged owner route. These are the
same transient owner-height fixtures described in Round 4: the saved settings point to `DA_Strate4`,
while the logged SurfaceWorld layout is reconstructed from `DA_Strate1` without saving an asset.
No Season is assigned in these copies. The island plan has 4 islands and 3 connectors; the surface
plan has one finite type-4 shelf. The stress cases extend those plans to 256 islands/240 connectors
and 64 surface shelves plus one XY height writer and one XY cap writer. They do not change any production recipe.
### Forced candidate proof and cost
Each island row samples 64 tiles / 64,000 points, including the normal halo. Each surface row
samples 64 tiles / 46,656 points and hashes density, ground, cap and biome ID (186,624 values).
Surface timings start both paths with cold column caches by changing only the local validation
cache epoch. Final timing replay ran without an overlapping build or Unreal process.
| Family / plan | Full-scan p95 ms | Forced-candidate p95 ms | List build p95 ms | Full and candidate hash | Negative control |
|---|---:|---:|---:|---|---|
| Islands, staged owner | 0.9803 | 1.0194 | 0.0012 | `cb94db3ca317d001` | detected |
| Islands, 256 stress | 110.570 | 7.3619 | 0.0803 | `d83bac7778f3d62a` | detected |
| Surface, staged owner | 0.4748 | 0.4559 | 0.0003 | `4207efd4ac869108` | detected |
| Surface, 64 shelves + height/cap writers | 0.7084 | 0.4078 | 0.0011 | `f1c6ea123284cc38` | detected |
Every row has zero mismatches. Each control removes a needed feature; the island control removes
its group certificate too. The shared-scope audit also checks identity/domain fallback, nested empty
scope restoration, scope teardown and the full-scan cost hint.
The owner island point audit offers no useful culling gain. Stress p95 improves about **15×**;
3,362 stress lists cost 216.615 ms in total (108 owner lists cost 0.0766 ms). The stress template comes
from the actual staged owner plan, whereas S1's standalone audit used Round 3's manifest; its 57×
figure is not an apples-to-apples regression comparison.
Surface's single feature has no material point-query gain. Its column computation alone is about
0.368 ms of the 0.475 ms p95, and the existing bounded biome/cap path stays intact. The stress case
reduces p95 by about 42% while column cost stays similar (0.3699/0.3552 ms). There is no reason to
force a global biome/cap feature list into this owner plan.
Warmed BuildHost tile timings initially exposed a 7–13% island regression from forcing group
bookkeeping on four islands. That led to the shared cost hint. The final default path keeps its small-plan timing:
| Staged plan | LOD | Full tile p95 ms | Default shared-engine p95 ms | Full / shared shell p95 ms |
|---|---:|---:|---:|---:|
| Islands | 0 | 94.984 | 95.094 | 0.0002 / 0.0003 |
| Islands | 1 | 87.280 | 87.577 | 0.0005 / 0.0003 |
| Islands | 7 | 20.442 | 20.409 | 16.918 / 16.882 |
| Islands | 8 | 73.038 | 72.923 | 69.930 / 69.844 |
| Surface | 0 | 11.238 | 11.178 | 0.0001 / 0.0001 |
| Surface | 1 | 7.346 | 7.354 | 0.0001 / 0.0001 |
| Surface | 7 | 32.739 | 32.381 | 26.378 / 26.021 |
| Surface | 8 | 168.545 | 168.063 | 135.960 / 136.310 |
Each row measures eight owner clipmap keys after warming both routes, including list preparation,
meshing and density hashes. All four output hashes match on every paired key. This is a small,
hash-capture workload, not a rendered-frame percentile. The far-shell stage excludes LOD8 cap
refinement. There is no measured reason to add another shell-specific feature index for these
small owner plans; larger canonical fields inherit their family culling through the shared scope.
### Island placement and active populated cost
| Workload | Full scan | Shared engine | Result |
|---|---:|---:|---|
| Owner palette, cell p95 | 7.0706 ms | 0.2385 ms | about 29.6× faster |
| Owner palette, 64-cell preparation | 412.960 ms | 3.840 ms | same zero authored placements |
| Populated fixture, populated-cell p95 | 53.9875 ms | 2.1501 ms | 14 populated cells / 572 placements |
| Populated fixture, all 64 cells | 3270.478 ms | 28.436 ms | exact transforms match |
| Merge / real HISM apply | 0.0623 / 0.6068 ms | same products/cost | 572 applied instances |
| Populated active batch CPU total | 3271.147 ms | 29.105 ms | about 112× faster |
Candidate density calls are 58.84 per authored cell, versus S1's 7,763.38 for the same owner plan.
Legacy remains 193.25 calls/cell and 0.2855 ms p95. Stationary manager update p95 is 0.0005 ms;
that idle number is separate from the active batch totals above.
All 572 populated transforms match their full-scan counterparts exactly. All 572 canonical island
anchor checks pass; maximum density residual is 0.035156 Core voxel density units. The existing
terrain/content tests pass on both island and connector: island height difference is 0.373 cm,
connector difference 0.096 cm. Capsule contacts, Blueprint carve/fill, water and atmosphere pass.
No approximate anchor shortcut is used.
The six-entry authored palette still produces zero placements in these 64 cells. The populated
fixture is explicit synthetic coverage; it does not claim the cost of the owner's tree Blueprint
logic or rendered foliage. Active totals sum worker preparation and synchronous merge/application
calls over the whole batch, not one frame. Footprint suppression is disabled only for the isolated
fixture, which is immediately cleared. Async HISM tree completion and rendering are not included.
The earlier SurfaceWorld populated diagnostic produced 8,192 synthetic transforms with exact
full/candidate agreement, but had no mesh application in that build and warm-cache ordering;
its speed figures are not used as a SurfaceWorld improvement claim.
### Default identity
No recipe version was bumped: all changes select exact evaluators or skip certified air.
The full SurfaceWorld actor run reproduced S1's W1/W8/W16 matrix:
`0cd2a1a4152ee4aa / 17775c835711e5a3 / a27224958fc27d7b / 3821fea90b134ce4`
(density / mesh / payload / topology). Island assembly/recipe/plan remain
`9c372e7bfb5b8310 / 5e0370d9f95f1c15 / dbbda4932378047a`.
The final-source island W1/W8/W16 matrix is also exactly S1:
`4dcfb37585d7d986 / 725a18374c5623de / fb345d8cb319d18b / 76f2846be8efb5f4`.
The full SurfaceWorld actor pass precedes the final cost hint; the final-source focused replay
checks its LOD0/1/7/8 full-versus-default hashes after that selection-only change. Core-off's separate
final run proves unchanged legacy density at three probes and 12.5 cm. M2 V1/V2 five-fixture repeats,
same-LOD borders, V2 MC identity and 125 doorway phases all pass. Existing doorway contour
mismatch remains 22.844 cm in that fixture audit; this round does not claim a new seam solution.
### Run ledger and limits
| Run | Result / limit |
|---|---|
| Standalone Core library builds (four iterations) | all first-attempt passes; final link-safety audit checks 220,200 symbol lines |
| BuildHost UBT/UHT builds (six iterations) | all first-attempt passes; latest 62.03 s; 18 Core shims, link-safety 95,738 symbol lines; five staged asset hashes verified |
| Preliminary island actor | pass, about 3m57s, 3.19 GiB peak; canonical hashes and 572 anchor checks |
| Full SurfaceWorld actor | pass, about 12m15s, 3.58 GiB peak; streaming, collisions, motion, edits, geometry/anchors, W1/W8/W16 |
| Island actor with new HISM fixture | exit 1, about 4m14s; landmark footprint suppression hit the fixture count assertion; field/worker/anchor gates passed |
| Final island actor, cost hint and isolated HISM fixture | pass, about 3m52s, 3.03 GiB peak; W1/W8/W16, 572 exact anchors and applied instances |
| Final focused SurfaceWorld tile replay | pass, about 21s, 2.70 GiB peak; 32 paired LOD0/1/7/8 keys, all hashes equal |
| Final M2 V1/V2 fixtures | pass, about 17s, 2.34 GiB peak; repeats, borders, MC identity, 125 doorway phases |
| Final Core-off | pass, about 14s, 2.14 GiB peak; legacy density and scale unchanged |
| Final composed standalone audit | pass, 7.87s, about 64 MiB peak; all four full/candidate rows exact and controls detected |
Build iterations cover initial integration, added diagnostics, active fixture application, warmed
measurements, duplicate-validation removal, and the cost-hint/fixture fix. Their logs are the six
`results/host_build*.log` files and four `results/core_build*.log` files. The standalone audit was
replayed as those diagnostics were refined; the final composed stress also exercises XY height/cap
writers at unrelated Z values. Every replay passed its field/control assertions.
One actor run failed its new populated-HISM count
assertion after passing field/worker/anchor gates: normal `ApplyRegion` also clears live landmark
footprints. The fixture now explicitly isolates those footprints; normal application defaults to
keeping them enabled. The failed log is `results/islands_hism_fixture_failed.log` (exit 1, no crash).
Preliminary surface tile timings used a cold full path followed by a warm candidate path. Those
numbers are discarded; the final focused replay warms both paths. The first standalone audit
also overlapped compilation; it passed functional controls, but its timings are discarded. Idle
replays and the final-source replay are all recorded in `results/shared_audit_ledger.txt`.
An audit iteration removed duplicate plan validation from scoped island samples. All standalone
field audits passed; `vswhere.exe` was not found by the installed VC setup script, but CL compiled
and the audit ran successfully. A documentation-edit attempt failed on Python's default Windows
encoding; it changed no files and was corrected with UTF-8/apply_patch.
The first preliminary island launch used the existing launcher; I applied 12-CPU affinity during
that run, then added `-corelimit=12` and 12-CPU affinity to the launcher for subsequent runs. Builds
used at most eight UBT actions, or eight UBT plus four standalone compiler actions. W16 remains a
logical determinism partition under the 12-CPU execution cap. Each Unreal launch checks 4 GiB free
RAM and refuses another Unreal process. Every process is guarded at 8 GiB and 900 seconds.
No viewer or GPU capture was launched. No run exceeded its memory/time guard, no timeout occurred,
and no run returned `0xC0000142` (so its one-retry rule was never needed).
Crash audit: `Saved/BuildHost/HostProject/Saved/Crashes/` still contains only
`UECC-Windows-F1A3EFD5469F5DD62E68EBBACAC84376_0000` (2026-09-17). The isolated User crash root
still contains only `UECC-Windows-7B23387E4235BCFEDE42BC9D637E41CB_0000` (2026-10-08).
No new UECC folder exists in the host, staged plugin or isolated User crash roots. The final
commandlets finished with zero errors; known missing staged `/Game/VoxelForge/Blocks/NewDataAsset`
and certificate-store warnings remain. The failed fixture run logged its explicit test error and
exited normally.
Evidence: `results/SUMMARY.json`, `results/shared_audit_attempt_1.stdout.log`,
`results/island_tile_lists.json`, `results/shared_audit_ledger.txt`, `results/surface_full_actor.log`,
`results/islands_full_actor_final.log`, `results/surface_warmed_final.log`,
`results/m2_fixtures_final.log` and `results/core_off_final.log`. Owner plans exported under
BuildHost's isolated User Saved directory are the standalone replay inputs.
No owner project/editor was opened, closed or built, no `.uasset` was edited, and no junction,
symlink, commit, push or stash was created. All authored writes and build outputs stayed inside
this plugin's workspace/BuildHost.
## My view of the boundary
The next structural improvement should be a prepared immutable family-provider table per strate.
Today the shared scope is generic, but the world and content snapshot adapters still enumerate the
two concrete field families, and preparation rebuilds metadata vectors for each query. A provider
could publish stable feature IDs, bounds, an optional value certificate and optional surface/support
queries once, while the engine handles consumer domains, ordering, cache lifetime and instrumentation.
That would also give future cave/rivers placement the same entry point without adding another
content snapshot class. I have not rebuilt the architecture for that proposal in this round.
Evidence required before doing it: a many-strate preparation profile showing the cost of rebuilding
bounds/group summaries; separate point-evaluation and list-build allocation counts; equal full versus
prepared hashes across owner plans, halos and edited epochs; a deliberately stale-provider control;
and no regression in time to collision-ready terrain or peak memory. Preserve the current bounded
lattice path for procedural biomes and the current cave interval engine until a measured replacement
wins. A universal list of shapes would not capture those processes or their proofs.
## Files and compile spots
New source files:
- `Standalone/Research/WorldAssemblerM3/Round6/SharedFeatureListAudit.cpp` — standalone owner/stress audit.
- `Standalone/Research/WorldAssemblerM3/Round6/BuildSharedFeatureListAudit.ps1` — guarded audit compile/run script.
Modified runtime/Core sources:
- `Standalone/Core/include/VoxelForgeCore/VoxelForgeCore.h`
- `Standalone/Core/src/WorldAssemblerInternal.h`
- `Standalone/Core/src/FloatingIslandsInternal.h`
- `Standalone/Core/src/ShapeWorldInternal.h`
- `Standalone/Core/src/VoxelForgeCore.cpp`
- `Source/VoxelForge/Private/VoxelContentManager.cpp`
- `Source/VoxelForge/Public/VoxelContentManager.h`
- `Source/VoxelForgeEditor/Private/VoxelForgeExploreCommandlet.cpp`
Also updated `Tools/TestVoxelForgeCoreWorldHost.ps1`, CODEMAP §3, ARCHITECTURE §8.23 and the dialogue.
Likely compile spots: the public Core API/export boundary and canonical Core shim; shared scope/TLS
linkage; `VoxelContentManager.h` parsing and its runtime translation unit; editor commandlet timing
and fixture code. No new runtime translation unit or manifest shim is required.
## Owner note
Keep Core enabled at the existing 25 cm setting. There is no new generator setting to configure.
The shared engine now narrows terrain searches for both native families and skips empty space when
placing island content. Terrain shapes and default hashes are preserved. The populated validation
fixture measures placement without changing your decoration assets. Ready to build your project
when you choose; I only build and launch the isolated plugin BuildHost.
@@ -0,0 +1,601 @@
#include "VoxelForgeCore/VoxelForgeCore.h"
#include <algorithm>
#include <array>
#include <chrono>
#include <cmath>
#include <cstdint>
#include <filesystem>
#include <fstream>
#include <iomanip>
#include <iostream>
#include <iterator>
#include <numeric>
#include <sstream>
#include <stdexcept>
#include <string>
#include <vector>
namespace
{
using namespace VoxelForgeCore;
using Clock = std::chrono::steady_clock;
constexpr std::int64_t Q = WorldAssemblySubvoxelsPerVoxel;
constexpr std::int64_t TileQ = 32 * Q;
constexpr std::int64_t TileStepQ = 4 * Q;
constexpr std::int64_t MesherHaloQ = Q;
struct Tile
{
std::array<std::int64_t, 3> minimum{};
std::array<std::int64_t, 3> maximum{};
FloatingIslandTileFeatureListV1 featureList;
double buildMilliseconds = 0.0;
};
struct Measurement
{
std::uint64_t tilesBuilt = 0;
std::uint64_t sampledTiles = 0;
std::uint64_t samples = 0;
std::uint64_t candidateEvaluations = 0;
std::uint64_t fullEvaluations = 0;
std::uint64_t exactMismatches = 0;
std::uint64_t droppedFeatureDetected = 0;
double listBuildTotalMilliseconds = 0.0;
double listBuildP95Milliseconds = 0.0;
double beforeP95Milliseconds = 0.0;
double afterP95Milliseconds = 0.0;
double beforeMedianMilliseconds = 0.0;
double afterMedianMilliseconds = 0.0;
double meanCandidateFeatures = 0.0;
double p95CandidateFeatures = 0.0;
std::string beforeHash;
std::string afterHash;
bool negativeControlPassed = false;
};
std::string Hex64(std::uint64_t value)
{
std::ostringstream output;
output << std::hex << std::setfill('0') << std::setw(16) << value;
return output.str();
}
std::uint64_t HashValues(const std::vector<std::int64_t>& values)
{
std::uint64_t hash = 14695981039346656037ull;
for (const auto value : values)
for (int byte = 0; byte < 8; ++byte)
{
hash ^= static_cast<std::uint8_t>(static_cast<std::uint64_t>(value) >> (byte * 8));
hash *= 1099511628211ull;
}
return hash;
}
double Percentile95(std::vector<double> values)
{
if (values.empty()) return 0.0;
std::sort(values.begin(), values.end());
const std::size_t index = (values.size() * 95 + 99) / 100 - 1;
return values[std::min(index, values.size() - 1)];
}
double Median(std::vector<double> values)
{
if (values.empty()) return 0.0;
std::sort(values.begin(), values.end());
const std::size_t middle = values.size() / 2;
if (values.size() & 1u) return values[middle];
return 0.5 * (values[middle - 1] + values[middle]);
}
std::int64_t FloorDiv(std::int64_t value, std::int64_t divisor)
{
std::int64_t quotient = value / divisor;
const std::int64_t remainder = value % divisor;
if (remainder != 0 && ((remainder < 0) != (divisor < 0))) --quotient;
return quotient;
}
void ShiftBounds(std::array<std::int64_t, 3>& minimum,
std::array<std::int64_t, 3>& maximum, const std::array<std::int64_t, 3>& delta)
{
for (std::size_t axis = 0; axis < 3; ++axis)
{ minimum[axis] += delta[axis]; maximum[axis] += delta[axis]; }
}
std::uint64_t SyntheticId(std::uint32_t index, std::uint64_t salt)
{
std::uint64_t value = (static_cast<std::uint64_t>(index) << 32) ^ salt;
value += 0x9e3779b97f4a7c15ull;
value = (value ^ (value >> 30)) * 0xbf58476d1ce4e5b9ull;
value = (value ^ (value >> 27)) * 0x94d049bb133111ebull;
value ^= value >> 31;
return value == 0 ? 1 : value;
}
FloatingIslandPlanV1 MakeStressPlan(const FloatingIslandRecipeV1& recipe,
const FloatingIslandPlanV1& source, std::size_t islandCount)
{
if (source.islands.empty()) throw std::runtime_error("source plan has no island template");
FloatingIslandPlanV1 result;
result.islands.reserve(islandCount);
const auto& prototype = source.islands.front();
constexpr std::size_t Columns = 16;
const std::int64_t spacing = 80 * Q;
for (std::size_t index = 0; index < islandCount; ++index)
{
FloatingIslandAnchorV1 island = prototype;
const std::int64_t dx = static_cast<std::int64_t>(index % Columns) * spacing;
const std::int64_t dy = static_cast<std::int64_t>(index / Columns) * spacing;
const std::int64_t dz = static_cast<std::int64_t>(index % 3) * 4 * Q;
const std::array<std::int64_t, 3> delta{dx, dy, dz};
island.centerSubvoxels = {prototype.centerSubvoxels[0] + dx,
prototype.centerSubvoxels[1] + dy, prototype.centerSubvoxels[2] + dz};
island.topZSubvoxels += dz;
island.bottomZSubvoxels += dz;
ShiftBounds(island.influenceMinimumSubvoxels, island.influenceMaximumSubvoxels, delta);
island.ordinal = static_cast<std::uint32_t>(index);
island.stableId = SyntheticId(static_cast<std::uint32_t>(index), 0x49534c414e44ull);
result.islands.push_back(island);
}
result.clusterEdges.reserve(islandCount - islandCount / Columns);
for (std::size_t index = 0; index < islandCount; ++index)
{
if (index % Columns + 1 >= Columns || index + 1 >= islandCount) continue;
const auto& from = result.islands[index];
const auto& to = result.islands[index + 1];
FloatingIslandConnectorV1 edge;
edge.stableId = SyntheticId(static_cast<std::uint32_t>(index), 0x425249444745ull);
edge.fromIslandId = from.stableId;
edge.toIslandId = to.stableId;
edge.startSubvoxels = {from.centerSubvoxels[0] + from.radiusSubvoxels,
from.centerSubvoxels[1], from.topZSubvoxels};
edge.endSubvoxels = {to.centerSubvoxels[0] - to.radiusSubvoxels,
to.centerSubvoxels[1], to.topZSubvoxels};
edge.halfWidthSubvoxels = recipe.bridgeHalfWidthSubvoxels;
edge.thicknessSubvoxels = recipe.bridgeThicknessSubvoxels;
const std::int64_t pad = recipe.blendRadiusSubvoxels + recipe.roughnessSubvoxels;
const std::int64_t archDepth = recipe.geometryVersion >= 2
? 2 * edge.thicknessSubvoxels : 0;
const std::int64_t xyPad = edge.halfWidthSubvoxels + pad;
edge.influenceMinimumSubvoxels = {
std::min(edge.startSubvoxels[0], edge.endSubvoxels[0]) - xyPad,
std::min(edge.startSubvoxels[1], edge.endSubvoxels[1]) - xyPad,
std::min(edge.startSubvoxels[2], edge.endSubvoxels[2])
- edge.thicknessSubvoxels - pad - archDepth};
edge.influenceMaximumSubvoxels = {
std::max(edge.startSubvoxels[0], edge.endSubvoxels[0]) + xyPad,
std::max(edge.startSubvoxels[1], edge.endSubvoxels[1]) + xyPad,
std::max(edge.startSubvoxels[2], edge.endSubvoxels[2]) + pad};
result.clusterEdges.push_back(edge);
}
return result;
}
std::vector<Tile> BuildMixedTiles(const FloatingIslandFieldV1& field,
const std::array<std::int64_t, 3>& tileLimitMinimum,
const std::array<std::int64_t, 3>& tileLimitMaximum,
Measurement& measurement)
{
std::vector<Tile> tiles;
for (std::int64_t z = tileLimitMinimum[2]; z <= tileLimitMaximum[2]; z += TileQ)
for (std::int64_t y = tileLimitMinimum[1]; y <= tileLimitMaximum[1]; y += TileQ)
for (std::int64_t x = tileLimitMinimum[0]; x <= tileLimitMaximum[0]; x += TileQ)
{
Tile tile;
tile.minimum = {x, y, z};
tile.maximum = {x + TileQ, y + TileQ, z + TileQ};
const std::array<std::int64_t, 3> sampleMinimum{
x - MesherHaloQ, y - MesherHaloQ, z - MesherHaloQ};
const std::array<std::int64_t, 3> sampleMaximum{
x + TileQ + MesherHaloQ, y + TileQ + MesherHaloQ, z + TileQ + MesherHaloQ};
const auto begin = Clock::now();
tile.featureList = field.buildFeatureTileList(sampleMinimum, sampleMaximum);
tile.buildMilliseconds = std::chrono::duration<double, std::milli>(Clock::now() - begin).count();
measurement.listBuildTotalMilliseconds += tile.buildMilliseconds;
++measurement.tilesBuilt;
if (!tile.featureList.featureIndices.empty()) tiles.push_back(std::move(tile));
}
return tiles;
}
Measurement MeasureField(const FloatingIslandFieldV1& field,
std::array<std::int64_t, 3> limitMinimum,
std::array<std::int64_t, 3> limitMaximum)
{
Measurement measurement;
for (std::size_t axis = 0; axis < 3; ++axis)
{
limitMinimum[axis] = FloorDiv(limitMinimum[axis], TileQ) * TileQ;
limitMaximum[axis] = FloorDiv(limitMaximum[axis], TileQ) * TileQ;
}
auto tiles = BuildMixedTiles(field, limitMinimum, limitMaximum, measurement);
if (tiles.empty()) throw std::runtime_error("tile bounds produced no candidate tiles");
std::vector<double> buildTimes, candidateCounts;
buildTimes.reserve(tiles.size()); candidateCounts.reserve(tiles.size());
for (const Tile& tile : tiles)
{ buildTimes.push_back(tile.buildMilliseconds); candidateCounts.push_back(static_cast<double>(tile.featureList.featureIndices.size())); }
measurement.listBuildP95Milliseconds = Percentile95(std::move(buildTimes));
measurement.meanCandidateFeatures = std::accumulate(candidateCounts.begin(), candidateCounts.end(), 0.0)
/ static_cast<double>(candidateCounts.size());
measurement.p95CandidateFeatures = Percentile95(std::move(candidateCounts));
constexpr std::size_t MaximumSampleTiles = 64;
if (tiles.size() > MaximumSampleTiles)
{
std::vector<Tile> selected;
selected.reserve(MaximumSampleTiles);
for (std::size_t slot = 0; slot < MaximumSampleTiles; ++slot)
{
const std::size_t index = slot * (tiles.size() - 1) / (MaximumSampleTiles - 1);
selected.push_back(std::move(tiles[index]));
}
tiles = std::move(selected);
}
std::vector<double> beforeTimes, afterTimes;
std::vector<std::int64_t> beforeValues, afterValues;
beforeTimes.reserve(tiles.size()); afterTimes.reserve(tiles.size());
for (const Tile& tile : tiles)
{
// Cover the mesher's one-sample LOD0 halo as well as the tile at four-voxel spacing.
// Couvrir la marge d'un echantillon du maillage LOD0 et la tuile a pas de quatre voxels.
const auto buildAxis = [](std::int64_t minimum, std::int64_t maximum)
{
std::vector<std::int64_t> values;
const std::int64_t start = minimum - MesherHaloQ;
const std::int64_t end = maximum + MesherHaloQ;
for (std::int64_t value = start; value <= end; value += TileStepQ)
values.push_back(value);
if (values.empty() || values.back() != end) values.push_back(end);
return values;
};
const auto xs = buildAxis(tile.minimum[0], tile.maximum[0]);
const auto ys = buildAxis(tile.minimum[1], tile.maximum[1]);
const auto zs = buildAxis(tile.minimum[2], tile.maximum[2]);
std::vector<std::array<std::int64_t, 3>> points;
points.reserve(xs.size() * ys.size() * zs.size());
for (const std::int64_t z : zs)
for (const std::int64_t y : ys)
for (const std::int64_t x : xs)
points.push_back({x, y, z});
measurement.samples += points.size();
measurement.fullEvaluations += points.size();
measurement.candidateEvaluations += points.size() * tile.featureList.featureIndices.size();
const auto beforeStart = Clock::now();
for (const auto& point : points)
beforeValues.push_back(field.densitySubvoxels(point[0], point[1], point[2]));
beforeTimes.push_back(std::chrono::duration<double, std::milli>(Clock::now() - beforeStart).count());
const auto afterStart = Clock::now();
const WorldAssemblyFeatureQueryV1 query{field.recipe(),field.plan(),tile.featureList};
{
const ScopedWorldAssemblyFeatureQueriesV1 scope(std::span(&query,1),true);
for (const auto& point : points)
afterValues.push_back(field.densitySubvoxels(point[0],point[1],point[2]));
}
afterTimes.push_back(std::chrono::duration<double, std::milli>(Clock::now() - afterStart).count());
++measurement.sampledTiles;
}
measurement.beforeP95Milliseconds = Percentile95(beforeTimes);
measurement.afterP95Milliseconds = Percentile95(afterTimes);
measurement.beforeMedianMilliseconds = Median(beforeTimes);
measurement.afterMedianMilliseconds = Median(afterTimes);
measurement.beforeHash = Hex64(HashValues(beforeValues));
measurement.afterHash = Hex64(HashValues(afterValues));
const std::size_t common = std::min(beforeValues.size(), afterValues.size());
for (std::size_t index = 0; index < common; ++index)
if (beforeValues[index] != afterValues[index]) ++measurement.exactMismatches;
if (field.plan() && !field.plan()->islands.empty())
{
constexpr std::uint32_t droppedFeature = 0;
const auto& island = field.plan()->islands.front();
const std::array<std::int64_t, 3> point{island.centerSubvoxels[0], island.centerSubvoxels[1],
island.bottomZSubvoxels + (island.topZSubvoxels - island.bottomZSubvoxels) / 2};
std::array<std::int64_t, 3> minimum{};
std::array<std::int64_t, 3> maximum{};
for (std::size_t axis = 0; axis < 3; ++axis)
{
minimum[axis] = FloorDiv(point[axis], TileQ) * TileQ;
maximum[axis] = minimum[axis] + TileQ;
}
auto sampleMinimum = minimum;
auto sampleMaximum = maximum;
for (std::size_t axis = 0; axis < 3; ++axis)
{
sampleMinimum[axis] -= MesherHaloQ;
sampleMaximum[axis] += MesherHaloQ;
}
FloatingIslandTileFeatureListV1 dropped = field.buildFeatureTileList(
sampleMinimum, sampleMaximum);
auto candidate = std::lower_bound(dropped.featureIndices.begin(), dropped.featureIndices.end(),
droppedFeature);
if (candidate != dropped.featureIndices.end() && *candidate == droppedFeature)
{
dropped.featureIndices.erase(candidate);
for (std::size_t axis = 0; axis < 3; ++axis)
{
dropped.groupBounds[droppedFeature].minimumSubvoxels[axis] += 100000000000ll;
dropped.groupBounds[droppedFeature].maximumSubvoxels[axis] += 100000000000ll;
}
const auto order = std::find(dropped.groupSearchOrder.begin(),
dropped.groupSearchOrder.end(), droppedFeature);
if (order != dropped.groupSearchOrder.end())
{
const std::size_t orderIndex = static_cast<std::size_t>(order - dropped.groupSearchOrder.begin());
dropped.groupSearchOrder.erase(order);
dropped.groupDistanceLowerBoundsSubvoxels.erase(
dropped.groupDistanceLowerBoundsSubvoxels.begin() + orderIndex);
dropped.groupSearchComplete = false;
const auto full = field.densitySubvoxels(point[0], point[1], point[2]);
const WorldAssemblyFeatureQueryV1 badQuery{field.recipe(),field.plan(),dropped};
const ScopedWorldAssemblyFeatureQueriesV1 badScope(std::span(&badQuery,1),true);
const auto bad = field.densitySubvoxels(point[0],point[1],point[2]);
if (full != bad) ++measurement.droppedFeatureDetected;
}
}
}
measurement.negativeControlPassed = measurement.droppedFeatureDetected > 0;
return measurement;
}
void Print(const char* label, const Measurement& measurement,
std::size_t islandCount, std::size_t connectorCount)
{
std::cout << label << " islands=" << islandCount << " connectors=" << connectorCount
<< " forced_candidates=1 list_tiles_built=" << measurement.tilesBuilt
<< " sampled_tiles=" << measurement.sampledTiles
<< " sample_count=" << measurement.samples
<< " mean_candidates=" << measurement.meanCandidateFeatures
<< " p95_candidates=" << measurement.p95CandidateFeatures
<< " list_build_total_ms=" << measurement.listBuildTotalMilliseconds
<< " list_build_p95_ms=" << measurement.listBuildP95Milliseconds
<< " full_tile_p95_ms=" << measurement.beforeP95Milliseconds
<< " candidate_tile_p95_ms=" << measurement.afterP95Milliseconds
<< " full_tile_median_ms=" << measurement.beforeMedianMilliseconds
<< " candidate_tile_median_ms=" << measurement.afterMedianMilliseconds
<< " exact_mismatches=" << measurement.exactMismatches
<< " full_hash=" << measurement.beforeHash
<< " candidate_hash=" << measurement.afterHash
<< " negative_control_detected=" << measurement.negativeControlPassed << '\n';
}
}
int IslandAuditMain(int argc, char** argv)
{
try
{
if (argc != 3)
{ std::cerr << "usage: FloatingIslandTileListAudit <manifest.json> <output.json>\n"; return 2; }
std::ifstream input(argv[1], std::ios::binary);
if (!input) throw std::runtime_error("could not open the recorded round-3 island manifest");
const std::string json{std::istreambuf_iterator<char>(input), std::istreambuf_iterator<char>()};
std::string error;
const auto manifest = FloatingIslandManifestV1::FromJson(json, error);
if (!manifest || !manifest->validate(error)) throw std::runtime_error("manifest invalid: " + error);
FloatingIslandFieldV1 field(manifest->recipe, manifest->plan);
if (!field.isValid()) throw std::runtime_error("round-3 production field did not validate");
const auto bounds = field.influenceBounds();
const auto& center=manifest->plan.islands.front().centerSubvoxels;
WorldAssemblyFeatureQueryV1 guardQuery{field.recipe(),field.plan(),field.buildFeatureTileList(center,center)};
if(!guardQuery.features.candidateEvaluationUseful)
{
const ScopedWorldAssemblyFeatureQueriesV1 preferredFull(std::span(&guardQuery,1));
if(ScopedWorldAssemblyFeatureQueriesV1::find(field.recipe(),field.plan(),center[0],center[1],center[2]))
throw std::runtime_error("shared scope ignored the full-scan cost hint");
}
const auto outsideX=center[0]+1000*Q;
const auto outsideFull=field.densitySubvoxels(outsideX,center[1],center[2]);
{
const ScopedWorldAssemblyFeatureQueriesV1 scope(std::span(&guardQuery,1),true);
if(field.densitySubvoxels(outsideX,center[1],center[2])!=outsideFull)
throw std::runtime_error("outside-domain fallback changed density");
{
const ScopedWorldAssemblyFeatureQueriesV1 emptyScope(std::span<const WorldAssemblyFeatureQueryV1>{});
if(ScopedWorldAssemblyFeatureQueriesV1::find(field.recipe(),field.plan(),center[0],center[1],center[2]))
throw std::runtime_error("nested empty scope inherited candidates");
}
if(!ScopedWorldAssemblyFeatureQueriesV1::find(field.recipe(),field.plan(),center[0],center[1],center[2]))
throw std::runtime_error("nested scope did not restore candidates");
}
if(ScopedWorldAssemblyFeatureQueriesV1::find(field.recipe(),field.plan(),center[0],center[1],center[2]))
throw std::runtime_error("scope leaked candidates");
const Measurement today = MeasureField(field, bounds.minimumSubvoxels, bounds.maximumSubvoxels);
const FloatingIslandPlanV1 stressPlan = MakeStressPlan(manifest->recipe, manifest->plan, 256);
FloatingIslandFieldV1 stressField(manifest->recipe, stressPlan);
if (!stressField.isValid()) throw std::runtime_error("synthetic stress field did not validate");
const auto stressBounds = stressField.influenceBounds();
const Measurement stress = MeasureField(stressField,
stressBounds.minimumSubvoxels, stressBounds.maximumSubvoxels);
Print("today", today, manifest->plan.islands.size(), manifest->plan.clusterEdges.size());
Print("stress", stress, stressPlan.islands.size(), stressPlan.clusterEdges.size());
std::ofstream output(argv[2], std::ios::trunc);
if (!output) throw std::runtime_error("could not create audit result JSON");
output << std::setprecision(12) << "{\n"
<< " \"baseline\":{\"islands\":" << manifest->plan.islands.size()
<< ",\"connectors\":" << manifest->plan.clusterEdges.size()
<< ",\"tiles_built\":" << today.tilesBuilt << ",\"sampled_tiles\":" << today.sampledTiles
<< ",\"samples\":" << today.samples << ",\"mean_candidates\":" << today.meanCandidateFeatures
<< ",\"p95_candidates\":" << today.p95CandidateFeatures
<< ",\"list_build_total_ms\":" << today.listBuildTotalMilliseconds
<< ",\"list_build_p95_ms\":" << today.listBuildP95Milliseconds
<< ",\"before_p95_ms\":" << today.beforeP95Milliseconds
<< ",\"after_p95_ms\":" << today.afterP95Milliseconds
<< ",\"before_median_ms\":" << today.beforeMedianMilliseconds
<< ",\"after_median_ms\":" << today.afterMedianMilliseconds
<< ",\"exact_mismatches\":" << today.exactMismatches
<< ",\"before_hash\":\"" << today.beforeHash << "\",\"after_hash\":\"" << today.afterHash
<< "\",\"negative_control\":" << (today.negativeControlPassed ? "true" : "false") << "},\n"
<< " \"stress\":{\"islands\":" << stressPlan.islands.size()
<< ",\"connectors\":" << stressPlan.clusterEdges.size()
<< ",\"tiles_built\":" << stress.tilesBuilt << ",\"sampled_tiles\":" << stress.sampledTiles
<< ",\"samples\":" << stress.samples << ",\"mean_candidates\":" << stress.meanCandidateFeatures
<< ",\"p95_candidates\":" << stress.p95CandidateFeatures
<< ",\"list_build_total_ms\":" << stress.listBuildTotalMilliseconds
<< ",\"list_build_p95_ms\":" << stress.listBuildP95Milliseconds
<< ",\"before_p95_ms\":" << stress.beforeP95Milliseconds
<< ",\"after_p95_ms\":" << stress.afterP95Milliseconds
<< ",\"before_median_ms\":" << stress.beforeMedianMilliseconds
<< ",\"after_median_ms\":" << stress.afterMedianMilliseconds
<< ",\"exact_mismatches\":" << stress.exactMismatches
<< ",\"before_hash\":\"" << stress.beforeHash << "\",\"after_hash\":\"" << stress.afterHash
<< "\",\"negative_control\":" << (stress.negativeControlPassed ? "true" : "false") << "}\n}\n";
if (!today.negativeControlPassed || !stress.negativeControlPassed)
throw std::runtime_error("dropped-feature negative control was not detected");
if (today.exactMismatches || stress.exactMismatches)
throw std::runtime_error("tile feature evaluation changed canonical field values");
std::cout << "TILE_LIST_AUDIT_PASS\n";
return 0;
}
catch (const std::exception& exception)
{
std::cerr << "FLOATING_ISLAND_TILE_LIST_AUDIT_FAIL: " << exception.what() << '\n';
return 1;
}
}
// Surface finite features use the same scope as islands. Biome sites stay in their fixed local window.
// Les features finies de surface partagent la portee; les sites biomes restent dans leur fenetre locale.
void MeasureSurface(WorldAssemblyRecipeV1 recipe, WorldAssemblyStratumPlanV1 plan,
const char* label, bool stress)
{
if(stress)
{
const auto originals=plan.features;
for(int copy=1;copy<64;++copy)
for(auto feature:originals)
{
feature.stableId=SyntheticId(static_cast<std::uint32_t>(plan.features.size()),0x53555246);
for(int axis=0;axis<2;++axis)
{
const auto delta=(axis==0 ? copy%8 : copy/8)*512*Q;
feature.minimumSubvoxels[axis]+=delta;
feature.maximumSubvoxels[axis]+=delta;
}
plan.features.push_back(feature);
}
}
if(stress)
{
// One composed stress case also exercises XY column writers at unrelated Z values.
// Une fixture composee couvre aussi les modificateurs XY a des altitudes independantes.
const auto& shelf=plan.features.front();
WorldAssemblyFeatureV1 cliff;
cliff.stableId=SyntheticId(10000,0x434c494646);
cliff.type=1;
cliff.minimumSubvoxels={(shelf.minimumSubvoxels[0]+shelf.maximumSubvoxels[0])/2-8*Q,
(shelf.minimumSubvoxels[1]+shelf.maximumSubvoxels[1])/2-8*Q,0};
cliff.maximumSubvoxels={cliff.minimumSubvoxels[0]+16*Q,cliff.minimumSubvoxels[1]+16*Q,0};
cliff.parametersSubvoxels={8*Q,8*Q,0,0};
auto cap=cliff;
cap.stableId=SyntheticId(10001,0x434150);
cap.type=3;
cap.parametersSubvoxels={4*Q,32*Q,8*Q,0};
plan.features.push_back(cliff);
plan.features.push_back(cap);
}
if(stress) plan.contentHash ^= 0x5354524553534341ull; // Separate validation cache epochs. / Epoques distinctes.
Heightfield2D field(recipe,plan);
std::vector<double> fullTimes,candidateTimes,buildTimes,counts,fullColumnTimes,candidateColumnTimes;
std::vector<std::int64_t> fullValues,candidateValues;
std::uint64_t mismatches=0;
bool negative=false;
if(plan.features.empty())throw std::runtime_error("surface has no finite features to audit");
// 64 bounded tile probes, spanning each feature and its faces, including normal halos.
for(int tile=0;tile<64;++tile)
{
const auto& feature=plan.features[static_cast<std::size_t>(tile)%plan.features.size()];
const std::int64_t x=(feature.minimumSubvoxels[0]+feature.maximumSubvoxels[0])/2;
const std::int64_t y=(feature.minimumSubvoxels[1]+feature.maximumSubvoxels[1])/2;
const auto column=field.point(x,y,0);
const std::int64_t z=(tile%3==0) ? column.groundHeightSubvoxels :
(tile%3==1 ? column.capHeightSubvoxels :
(feature.minimumSubvoxels[2]+feature.maximumSubvoxels[2])/2);
const std::array<std::int64_t,3> lo{x-17*Q,y-17*Q,z-17*Q};
const std::array<std::int64_t,3> hi{x+17*Q,y+17*Q,z+17*Q};
const auto buildStart=Clock::now();
WorldAssemblyFeatureQueryV1 query{field.recipe(),field.plan(),field.buildFeatureTileList(lo,hi)};
buildTimes.push_back(std::chrono::duration<double,std::milli>(Clock::now()-buildStart).count());
counts.push_back(static_cast<double>(query.features.featureIndices.size()));
auto sample=[&](std::vector<std::int64_t>& values)
{
for(int iz=0;iz<9;++iz)for(int iy=0;iy<9;++iy)for(int ix=0;ix<9;++ix)
{
const auto p=field.point(lo[0]+ix*4*Q,lo[1]+iy*4*Q,lo[2]+iz*4*Q);
values.push_back(p.densitySubvoxels);
values.push_back(p.groundHeightSubvoxels);
values.push_back(p.capHeightSubvoxels);
values.push_back(p.biomeId);
}
};
// Change only the local cache epoch: both timed paths start with cold columns.
// Epoch de cache local seulement : les deux parcours partent de colonnes froides.
++plan.contentHash;
Heightfield2D::resetThreadColumnCacheStats();
const auto start=Clock::now();sample(fullValues);
fullTimes.push_back(std::chrono::duration<double,std::milli>(Clock::now()-start).count());
fullColumnTimes.push_back(Heightfield2D::threadColumnCacheStats().columnComputeMilliseconds);
++plan.contentHash;
Heightfield2D::resetThreadColumnCacheStats();
const auto candidateStart=Clock::now();
{const ScopedWorldAssemblyFeatureQueriesV1 scope(std::span(&query,1),true);sample(candidateValues);}
candidateTimes.push_back(std::chrono::duration<double,std::milli>(Clock::now()-candidateStart).count());
candidateColumnTimes.push_back(Heightfield2D::threadColumnCacheStats().columnComputeMilliseconds);
if(!negative)
{
if (!query.features.featureIndices.empty())
query.features.featureIndices.erase(query.features.featureIndices.begin());
std::vector<std::int64_t> bad;
++plan.contentHash;
{const ScopedWorldAssemblyFeatureQueriesV1 scope(std::span(&query,1),true);sample(bad);}
const auto offset=fullValues.size()-bad.size();
for(std::size_t i=0;i<bad.size();++i)if(bad[i]!=fullValues[offset+i])negative=true;
++plan.contentHash; // Discard deliberately poisoned negative-control columns. / Purger le controle negatif.
}
}
for(std::size_t i=0;i<fullValues.size();++i)if(fullValues[i]!=candidateValues[i])++mismatches;
std::cout<<"surface label="<<label<<" forced_candidates=1 features="<<plan.features.size()
<<" values="<<fullValues.size()<<" full_hash="<<Hex64(HashValues(fullValues))
<<" candidate_hash="<<Hex64(HashValues(candidateValues))
<<" mismatches="<<mismatches<<" negative_control="<<negative
<<" full_p95_ms="<<Percentile95(fullTimes)<<" candidate_p95_ms="<<Percentile95(candidateTimes)
<<" build_p95_ms="<<Percentile95(buildTimes)<<" candidates_p95="<<Percentile95(counts)
<<" full_column_p95_ms="<<Percentile95(fullColumnTimes)
<<" candidate_column_p95_ms="<<Percentile95(candidateColumnTimes)<<'\n';
if(mismatches||!negative)throw std::runtime_error("surface candidate proof failed");
}
int main(int argc,char** argv)
{
try
{
if(argc!=4)throw std::runtime_error("usage: audit owner_island_assembly owner_surface_assembly results_dir");
const auto read=[](const char* path)
{std::ifstream input(path);return std::string(std::istreambuf_iterator<char>(input),{});};
std::string error;
auto islands=WorldAssemblyManifest::FromJson(read(argv[1]),error);
if(!islands||islands->floatingIslands.empty())throw std::runtime_error("island assembly: "+error);
const auto islandPath=std::filesystem::path(argv[3])/"owner_island_manifest.json";
{std::ofstream output(islandPath);output<<islands->floatingIslands.front().manifest.ToJson();}
std::string exe=argv[0],islandFile=islandPath.string();
std::string resultFile=(std::filesystem::path(argv[3])/"island_tile_lists.json").string();
char* islandArgs[]{exe.data(),islandFile.data(),resultFile.data()};
if(IslandAuditMain(3,islandArgs)!=0)return 1;
auto surface=WorldAssemblyManifest::FromJson(read(argv[2]),error);
if(!surface||surface->plan.strates.empty())throw std::runtime_error("surface assembly: "+error);
MeasureSurface(surface->recipe,surface->plan.strates.front(),"owner",false);
MeasureSurface(surface->recipe,surface->plan.strates.front(),"stress64",true);
std::cout<<"SHARED_FEATURE_AUDIT_PASS\n";
return 0;
}
catch(const std::exception& e){std::cerr<<"SHARED_FEATURE_AUDIT_FAIL: "<<e.what()<<'\n';return 1;}
}
@@ -0,0 +1,224 @@
{
"field_audit": [
{
"islands": 4,
"connectors": 3,
"forced_candidates": 1,
"list_tiles_built": 108,
"sampled_tiles": 64,
"sample_count": 64000,
"mean_candidates": 2.63158,
"p95_candidates": 6,
"list_build_total_ms": 0.0766,
"list_build_p95_ms": 0.0012,
"full_tile_p95_ms": 0.9803,
"candidate_tile_p95_ms": 1.0194,
"full_tile_median_ms": 0.85265,
"candidate_tile_median_ms": 0.88875,
"exact_mismatches": 0,
"full_hash": "cb94db3ca317d001",
"candidate_hash": "cb94db3ca317d001",
"negative_control_detected": 1
},
{
"islands": 256,
"connectors": 240,
"forced_candidates": 1,
"list_tiles_built": 3362,
"sampled_tiles": 64,
"sample_count": 64000,
"mean_candidates": 3.31231,
"p95_candidates": 4,
"list_build_total_ms": 216.615,
"list_build_p95_ms": 0.0803,
"full_tile_p95_ms": 110.57,
"candidate_tile_p95_ms": 7.3619,
"full_tile_median_ms": 109.41,
"candidate_tile_median_ms": 4.12255,
"exact_mismatches": 0,
"full_hash": "d83bac7778f3d62a",
"candidate_hash": "d83bac7778f3d62a",
"negative_control_detected": 1
},
{
"label": "owner",
"forced_candidates": 1,
"features": 1,
"values": 186624,
"full_hash": "4207efd4ac869108",
"candidate_hash": "4207efd4ac869108",
"mismatches": 0,
"negative_control": 1,
"full_p95_ms": 0.4748,
"candidate_p95_ms": 0.4559,
"build_p95_ms": 0.0003,
"candidates_p95": 1,
"full_column_p95_ms": 0.3679,
"candidate_column_p95_ms": 0.3693
},
{
"label": "stress64",
"forced_candidates": 1,
"features": 66,
"values": 186624,
"full_hash": "f1c6ea123284cc38",
"candidate_hash": "f1c6ea123284cc38",
"mismatches": 0,
"negative_control": 1,
"full_p95_ms": 0.7084,
"candidate_p95_ms": 0.4078,
"build_p95_ms": 0.0011,
"candidates_p95": 1,
"full_column_p95_ms": 0.3699,
"candidate_column_p95_ms": 0.3552
}
],
"default_tile_audit": [
{
"label": "islands",
"lod": 0,
"tiles": 8,
"hashes_identical": 1,
"full_p95_ms": 94.9835,
"candidate_p95_ms": 95.0935,
"list_p95_ms": 0.0021,
"full_shell_p95_ms": 0.0002,
"candidate_shell_p95_ms": 0.0003
},
{
"label": "islands",
"lod": 1,
"tiles": 8,
"hashes_identical": 1,
"full_p95_ms": 87.2796,
"candidate_p95_ms": 87.5774,
"list_p95_ms": 0.0035,
"full_shell_p95_ms": 0.0005,
"candidate_shell_p95_ms": 0.0003
},
{
"label": "islands",
"lod": 7,
"tiles": 8,
"hashes_identical": 1,
"full_p95_ms": 20.4421,
"candidate_p95_ms": 20.4088,
"list_p95_ms": 0.0017,
"full_shell_p95_ms": 16.9176,
"candidate_shell_p95_ms": 16.8824
},
{
"label": "islands",
"lod": 8,
"tiles": 8,
"hashes_identical": 1,
"full_p95_ms": 73.0376,
"candidate_p95_ms": 72.9233,
"list_p95_ms": 0.0016,
"full_shell_p95_ms": 69.9303,
"candidate_shell_p95_ms": 69.8442
},
{
"label": "surface",
"lod": 0,
"tiles": 8,
"hashes_identical": 1,
"full_p95_ms": 11.2377,
"candidate_p95_ms": 11.1781,
"list_p95_ms": 0.0006,
"full_shell_p95_ms": 0.0001,
"candidate_shell_p95_ms": 0.0001
},
{
"label": "surface",
"lod": 1,
"tiles": 8,
"hashes_identical": 1,
"full_p95_ms": 7.3458,
"candidate_p95_ms": 7.3544,
"list_p95_ms": 0.0007,
"full_shell_p95_ms": 0.0001,
"candidate_shell_p95_ms": 0.0001
},
{
"label": "surface",
"lod": 7,
"tiles": 8,
"hashes_identical": 1,
"full_p95_ms": 32.7389,
"candidate_p95_ms": 32.3814,
"list_p95_ms": 0.0006,
"full_shell_p95_ms": 26.3776,
"candidate_shell_p95_ms": 26.021
},
{
"label": "surface",
"lod": 8,
"tiles": 8,
"hashes_identical": 1,
"full_p95_ms": 168.5449,
"candidate_p95_ms": 168.0627,
"list_p95_ms": 0.0008,
"full_shell_p95_ms": 135.9596,
"candidate_shell_p95_ms": 136.31
}
],
"island_placement": [
{
"label": "FloatingIslands",
"authored_full_p95_ms": 7.0706,
"authored_candidate_p95_ms": 0.2385,
"authored_active_batch_full_ms": 412.95957,
"authored_active_batch_candidate_ms": 3.84022,
"populated_cells": 14,
"populated_placements": 572,
"populated_full_p95_ms": 53.9875,
"populated_candidate_p95_ms": 2.1501,
"exact_transform_comparisons": 572,
"anchor_checks": 572,
"max_density_residual": 0.035156
}
],
"island_active": [
{
"label": "FloatingIslands",
"cells": 64,
"placements": 572,
"full_batch_ms": 3270.4782,
"candidate_batch_ms": 28.43621,
"merge_ms": 0.06231,
"apply_ms": 0.6068,
"applied_instances": 572,
"full_total_cpu_ms": 3271.14731,
"candidate_total_cpu_ms": 29.10532,
"rhi": "null"
}
],
"hash_matrices": [
{
"worker_hash_matrix": "1/8/16",
"stable": 1,
"density": "0x4dcfb37585d7d986",
"mesh": "0x725a18374c5623de",
"payload": "0xfb345d8cb319d18b",
"topology": "0x76f2846be8efb5f4"
},
{
"worker_hash_matrix": "1/8/16",
"stable": 1,
"density": "0x0cd2a1a4152ee4aa",
"mesh": "0x17775c835711e5a3",
"payload": "0xa27224958fc27d7b",
"topology": "0x3821fea90b134ce4"
}
],
"limits": {
"unreal_core_limit": 12,
"max_ubt_actions": 8,
"max_standalone_compile_actions": 4,
"process_limit_gib": 8,
"launch_memory_gate_gib": 4,
"step_limit_seconds": 900
},
"known_failed_run": "islands_hism_fixture_failed.log: exit 1; fixture collided with live landmark suppression; isolated fixture passes."
}
@@ -0,0 +1,4 @@
{
"baseline":{"islands":4,"connectors":3,"tiles_built":108,"sampled_tiles":64,"samples":64000,"mean_candidates":2.63157894737,"p95_candidates":6,"list_build_total_ms":0.0766,"list_build_p95_ms":0.0012,"before_p95_ms":0.9803,"after_p95_ms":1.0194,"before_median_ms":0.85265,"after_median_ms":0.88875,"exact_mismatches":0,"before_hash":"cb94db3ca317d001","after_hash":"cb94db3ca317d001","negative_control":true},
"stress":{"islands":256,"connectors":240,"tiles_built":3362,"sampled_tiles":64,"samples":64000,"mean_candidates":3.31231409875,"p95_candidates":4,"list_build_total_ms":216.6153,"list_build_p95_ms":0.0803,"before_p95_ms":110.5695,"after_p95_ms":7.3619,"before_median_ms":109.40955,"after_median_ms":4.12255,"exact_mismatches":0,"before_hash":"d83bac7778f3d62a","after_hash":"d83bac7778f3d62a","negative_control":true}
}
@@ -0,0 +1 @@
{"schema_version":1,"content_hash":"87222553193002d8","recipe":{"schema_version":1,"units_per_voxel":256,"owner_voxel_size_microns":125000,"core_voxel_size_microns":250000,"owner_to_core_scale_numerator":1,"owner_to_core_scale_denominator":2,"seed":0,"origin_x_q":0,"origin_y_q":0,"center_top_z_q":-126976,"layout_min_z_q":-258048,"layout_max_z_q":4096,"primary_island_count":3,"island_density_q16":32768,"spacing_q":14336,"minimum_radius_q":3072,"maximum_radius_q":6144,"thickness_ratio_q16":39322,"vertical_jitter_q16":39322,"top_flatten_q16":39322,"taper_end_min_q16":29491,"taper_end_max_q16":45875,"geometry_version":2,"crust_depth_bonus_q16":9830,"root_depth_ratio_q16":49152,"blend_radius_q":768,"contour_warp_q":1613,"roughness_q":384,"boundary_seal_q":512,"bridge_half_width_q":768,"bridge_thickness_q":1024,"route_constraints":{"version":1,"capsule_radius_q":348,"capsule_height_q":1802,"maximum_grade_q16":17560,"sweep_spacing_q":128,"support_probe_radius_q":230,"support_search_depth_q":512,"minimum_clearance_q":128,"minimum_support_probes":3},"content_hash":"5e0370d9f95f1c15"},"plan":{"content_hash":"dbbda4932378047a","islands":[{"stable_id":"e6e461e18b3a9c87","ordinal":0,"center_q":[-10035,4422,-129150],"radius_q":3605,"top_half_q":721,"top_z_q":-128429,"bottom_z_q":-133837,"taper_end_q16":41663,"bounds_min_q":[-17941,-3484,-136525],"bounds_max_q":[-2129,12328,-125741]},{"stable_id":"2bc1820baba047f6","ordinal":1,"center_q":[0,-5178,-127714],"radius_q":3693,"top_half_q":738,"top_z_q":-126976,"bottom_z_q":-132516,"taper_end_q16":33506,"bounds_min_q":[-7994,-13172,-135204],"bounds_max_q":[7994,2816,-124288]},{"stable_id":"adc259cbe2a395e9","ordinal":2,"center_q":[10035,4681,-127887],"radius_q":5181,"top_half_q":1036,"top_z_q":-126851,"bottom_z_q":-134623,"taper_end_q16":39164,"bounds_min_q":[553,-4801,-137311],"bounds_max_q":[19517,14163,-124163]},{"stable_id":"7855fb022cc561c9","ordinal":3,"center_q":[-6451,-19514,-124414],"radius_q":5840,"top_half_q":1168,"top_z_q":-123246,"bottom_z_q":-132006,"taper_end_q16":33440,"bounds_min_q":[-16592,-29655,-134694],"bounds_max_q":[3690,-9373,-120558]}],"cluster_edges":[{"stable_id":"eaa5dd310e846520","from_island_id":"e6e461e18b3a9c87","to_island_id":"2bc1820baba047f6","start_q":[-8680,3126,-128554],"end_q":[-1388,-3851,-126819],"half_width_q":768,"thickness_q":1024,"bounds_min_q":[-10600,-5771,-132778],"bounds_max_q":[532,5046,-125667],"sharp_tag_ready":true},{"stable_id":"034023599b466c51","from_island_id":"2bc1820baba047f6","to_island_id":"adc259cbe2a395e9","start_q":[1370,-3832,-126951],"end_q":[8113,2793,-126831],"half_width_q":768,"thickness_q":1024,"bounds_min_q":[-550,-5752,-131175],"bounds_max_q":[10033,4713,-125679],"sharp_tag_ready":true},{"stable_id":"4962fa885545fb26","from_island_id":"2bc1820baba047f6","to_island_id":"7855fb022cc561c9","start_q":[-788,-6929,-126846],"end_q":[-5205,-16745,-123222],"half_width_q":768,"thickness_q":1024,"bounds_min_q":[-7125,-18665,-131070],"bounds_max_q":[1132,-5009,-122070],"sharp_tag_ready":true}],"route":[{"feature_id":"2e805a1f1f778cbb","position_q":[-10035,4422,-127367],"radius_q":1024},{"feature_id":"5be3b2b1e01722ea","position_q":[-9318,3736,-127414],"radius_q":1024},{"feature_id":"ab4eda612c1f03b5","position_q":[-8601,3051,-127336],"radius_q":1024},{"feature_id":"ba2fd2b050d0dd8c","position_q":[-7885,2365,-127288],"radius_q":1024},{"feature_id":"fc5829ee129fdc4f","position_q":[-7168,1679,-127113],"radius_q":1024},{"feature_id":"1393bb00329a9d5e","position_q":[-6451,993,-126951],"radius_q":1024},{"feature_id":"1dabc9715c93e2c9","position_q":[-5734,308,-126760],"radius_q":1024},{"feature_id":"0ea2008a85e73050","position_q":[-5018,-378,-126563],"radius_q":1024},{"feature_id":"754f55a5f1465cf3","position_q":[-4301,-1064,-126408],"radius_q":1024},{"feature_id":"1b6752776b4a7d22","position_q":[-3584,-1749,-126236],"radius_q":1024},{"feature_id":"0ab3b704db76084d","position_q":[-2867,-2435,-126017],"radius_q":1024},{"feature_id":"bd6980911e0879c4","position_q":[-2150,-3121,-125838],"radius_q":1024},{"feature_id":"ad164d7d0c049d87","position_q":[-1434,-3807,-125738],"radius_q":1024},{"feature_id":"9661463acbada2d6","position_q":[-717,-4492,-125928],"radius_q":1024},{"feature_id":"280a96547fadb0a1","position_q":[0,-5178,-125908],"radius_q":1024},{"feature_id":"531455b42fc13108","position_q":[717,-4474,-125939],"radius_q":1024},{"feature_id":"55d04c20849d7fcb","position_q":[1434,-3770,-125798],"radius_q":1024},{"feature_id":"ac4ebe80860dbdfa","position_q":[2150,-3065,-125893],"radius_q":1024},{"feature_id":"ff942855bf8e3fc5","position_q":[2867,-2361,-125886],"radius_q":1024},{"feature_id":"e6b8bba6c6acaf9c","position_q":[3584,-1657,-125861],"radius_q":1024},{"feature_id":"ae47379bbd4f7fdf","position_q":[4301,-953,-125839],"radius_q":1024},{"feature_id":"98779442384a30ee","position_q":[5018,-249,-125844],"radius_q":1024},{"feature_id":"f4c7757b2ee9fe19","position_q":[5734,456,-125814],"radius_q":1024},{"feature_id":"3ea33fae0fLine truncated
@@ -0,0 +1,9 @@
attempt=1 exit=0 elapsed_s=8.7570529 peak_private_bytes=68067328
Final timing replay: no overlapping BuildHost build or Unreal process.
attempt=1 exit=0 elapsed_s=8.0385819 peak_private_bytes=66658304
Final source timing replay: redundant scoped validation removed; idle build/Unreal.
attempt=1 exit=0 elapsed_s=7.9966612 peak_private_bytes=66658304
Final cost-hint source: force candidates for proof; no overlapping build/Unreal.
attempt=1 exit=0 elapsed_s=8.0365247 peak_private_bytes=65884160
Final composed stress: 64 shelves plus XY cliff/cap writers; no overlapping build/Unreal.
attempt=1 exit=0 elapsed_s=7.8703235 peak_private_bytes=66654208