The round-3 'field contact error' measured hit-to-anchor distance; V2 contacts are 0 cm and on the zero isosurface. Tagged-tile cost 5.7-6.7x -> 1.175-1.270x MC; organic 0.998x. Bound, shelf-thickness and route audits rerun with negative controls; W1/W8/W16 stable; V1 and MarchingCubesV1 unchanged. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01MmSoF64BbRFmk9C3p1VsBJ
347 lines
32 KiB
Markdown
347 lines
32 KiB
Markdown
# World assembler M2 round 2 — standalone border closure
|
||
|
||
Date: 2026-10-10
|
||
Status: **same-LOD gate passed; full LOD0/LOD1 gate failed; no production mesher selected.**
|
||
|
||
## Decision
|
||
|
||
The hybrid now closes the same-LOD tile-border suite: 625/625 cases, with zero unmatched contour probes, open edges, or nonmanifold edges. MC retains its 625/625 pass, and DC also passes as a reference after the same assembly repair.
|
||
|
||
The 2:1 LOD transition is still not ready. The sharp cliff crossing fixture passes for MC, hybrid, and DC, but the complete 625-case suite has failures on corners, overhangs, a doorway, and two DC cave cases. The contact sheet makes the sharp-feature improvement visible, but the failed full transition gate blocks a production choice and an Unreal implementation this round.
|
||
|
||
Keep MC as the baseline and hybrid as the sharp-feature candidate. Keep DC-everywhere as a reference; it remains rougher on the sampled native patch. Continue standalone work on a topology-aware 2:1 transition before taking a candidate into Unreal.
|
||
|
||
## Harness and gates
|
||
|
||
The standalone C++20 spike uses 25 cm cells and five fixtures: a 90-degree corner, doorway, one-metre riser, cliff ledge/overhang, and analytic cave chamber. Each fixture is translated through 125 lattice phases (0, 5, 10, 15, and 20 cm per axis). The retained outputs are [phase_sweep.csv](results/phase_sweep.csv), [cost.csv](results/cost.csv), [determinism.csv](results/determinism.csv), and [seams.csv](results/seams.csv).
|
||
|
||
Same-LOD neighbors are sampled independently with a shared field halo and deterministic ownership of border quads. The assembled pair is checked after open-edge T-junction subdivision; the subdivision preserves the source triangle footprint. Hybrid/DC independent contours are also compared from temporary witness meshes. No shared surface mesh is clipped and reused for the neighbor comparison.
|
||
|
||
LOD0/LOD1 uses independent 25 cm and 50 cm half-grids at a 2:1 ratio. The spike clips their surfaces at the border and tries a collar/chain zipper; a residual closed seam loop is capped only when its own sampled field residual is within budget. This is a tested transition prototype, not a complete Transvoxel table.
|
||
|
||
The physical error budget is **0.50 m**, one LOD1 sample interval. This is a conservative, camera-independent limit that is easy to audit in the field. It does not establish a screen-space guarantee; round 3 must also check projected error at the target cameras.
|
||
|
||
## Same-LOD border results
|
||
|
||
Each method has 625 independently generated neighbor cases. “Bad” includes unmatched probes, boundary edges, and nonmanifold edges after assembly.
|
||
|
||
| Method | Bad cases | Unmatched probes | Open edges | Nonmanifold edges | Maximum contour mismatch |
|
||
|---|---:|---:|---:|---:|---:|
|
||
| MC | 0 / 625 | 0 | 0 | 0 | 0 m |
|
||
| Hybrid | 0 / 625 | 0 | 0 | 0 | 0 m |
|
||
| DC | 0 / 625 | 0 | 0 | 0 | 0 m |
|
||
|
||
The merge-time T-junction conformance added 52 triangles across Hybrid’s suite and 40 across DC’s; MC needed none. Its measured added-triangle field residual is 0 m at the CSV precision. The full per-case data is in [seams.csv](results/seams.csv).
|
||
|
||
## 2:1 LOD transition results
|
||
|
||
The full gate still fails. Raw fine/coarse contour comparisons stay below the 0.50 m budget, but the transition surface/topology does not close all cases.
|
||
|
||
| Method | Bad cases | Seam-band open edges | Seam-band nonmanifold edges | Worst raw contour mismatch | Worst transition field residual |
|
||
|---|---:|---:|---:|---:|---:|
|
||
| MC | 5 / 625 | 15 | 5 | 0.318199 m | 0.250008 m |
|
||
| Hybrid | 38 / 625 | 4,213 | 47 | 0.158352 m | 1.24975 m |
|
||
| DC | 40 / 625 | 4,465 | 49 | 0.158352 m | 1.96263 m |
|
||
|
||
Failures by fixture: MC has five doorway cases; Hybrid has 25 corner and 13 overhang cases; DC has those same 38 plus two organic-cave cases. Hybrid/DC transition residuals exceed the 0.50 m budget on the corner cases. Some remaining rows have open or nonmanifold seam edges even when the raw contour mismatch is small. The full CSV keeps pre-transition and internal topology counts separate. The unrestricted-cap diagnostic is preserved in [seams_cap_unbounded_diagnostic.csv](results/seams_cap_unbounded_diagnostic.csv).
|
||
|
||
The dedicated sharp cliff crossing case passes all three methods: zero unmatched probes, open edges, and nonmanifold edges. Its maximum raw contour mismatch is 0.249977 m for MC and 0.419411 m for Hybrid/DC; the transition field residual maxima are 0.233333 m and 0.238888 m respectively. See [lod_cliff_crossing.csv](results/lod_cliff_crossing.csv).
|
||
|
||
The remaining Unreal-only checks are actual `UBodySetup` collision cooking/contact, projected pixel error at the game cameras, and runtime task scheduling/upload against the plugin mesher. None of those can repair the standalone topology failures; the topology gate is still the reason to defer Unreal integration.
|
||
|
||
### Production skirt baseline
|
||
|
||
The current plugin skirt depth is `max(1, SkirtCells) × Step × GeometryVoxelSize`; skirts are normal-extruded, double-sided visual strips. With Core’s 25 cm geometry voxel size and the default `SkirtCells = 4`, nominal depth is 1 m at LOD0 and 2 m at LOD1. Project settings can override these defaults. Skirts hide many visual gaps but do not make the neighboring surface topologically watertight. The new transition has not yet replaced that production behavior.
|
||
|
||
## Surface residual and crease splits
|
||
|
||
Residual is the absolute field value sampled at triangle vertices, edge midpoints, and centroids; it is not a symmetric Hausdorff distance. Values below average the 625 phase rows per method; maxima are the worst sampled value.
|
||
|
||
| Method | Mean residual | Worst residual | Tagged crease pairs | Normal split pairs | Split rate on tagged creases | Mean triangles / vertices |
|
||
|---|---:|---:|---:|---:|---:|---:|
|
||
| MC | 0.5664 cm | 16.6670 cm | 10,926 | 1,847 | 16.90% | 3,363.1 / 1,728.8 |
|
||
| Hybrid | 0.2552 cm | 12.5027 cm | 140,876 | 140,806 | 99.95% | 3,365.3 / 3,469.2 |
|
||
| DC | 0.2786 cm | 12.5027 cm | 140,876 | 140,806 | 99.95% | 3,365.8 / 1,985.6 |
|
||
|
||
The hybrid keeps untagged/organic components on MC and uses DC for tagged sharp features. It preserves the sharp corner/riser/ledge better than MC in the analytic fixtures, while its feature splits roughly double the vertex count.
|
||
|
||
## Sampled native SurfaceWorld cliff
|
||
|
||
The native comparison samples the 8 m patch at 25 cm from the M1 SurfaceWorld manifest (feature type 4, feature `0x9812c26310b90c9`, manifest hash `0x8933693d9560ba9f`). MC and Hybrid emit bit-identical vertex and triangle arrays, with identical mesh hash `0x9d58e0603f1bf9c7`: 2,345 vertices and 4,496 triangles each. This confirms that the hybrid leaves this untagged native patch unchanged.
|
||
|
||
The sampled scalar-field residual is 0.212167 m mean and 16.0068 m max for both MC and Hybrid. This patch is cropped at the 8 m volume boundary and has 192 boundary edges; these values are not a seam result, and the scalar field is not a signed-distance guarantee. DC-everywhere differs (2,247 vertices, 3,961 triangles, 4.57272 m mean / 16.5898 m max, 504 boundary edges and 74 nonmanifold edges). The native CSV is [native_surface.csv](results/native_surface.csv).
|
||
|
||
## Cost and determinism
|
||
|
||
The timer starts after the 32³ field grid is sampled, measures meshing only, and excludes Unreal scheduling, upload, collision cooking, and rendering. Values below are the median of five fixture medians; W1/W8 use three builds, while W16 uses one timed build because repeated W16 thread creation had caused a host access violation. Hash determinism is still checked at all three worker counts.
|
||
|
||
| Workers | MC ms/tile | Hybrid ms/tile | DC ms/tile |
|
||
|---:|---:|---:|---:|
|
||
| 1 | 16.316 | 17.534 | 16.417 |
|
||
| 8 | 53.914 | 54.840 | 52.606 |
|
||
| 16 | 86.961 | 90.490 | 89.476 |
|
||
|
||
All 45 W1/W8/W16 rows match the W1 hash for that method and fixture. The standalone collision proxy copies the render mesh: all hashes match and measured geometry delta is 0 m. This does not test Unreal collision cooking.
|
||
|
||
These timings are **not comparable to the optimized production MC mesher**. The harness is a separate STL/map-based implementation with its own worker dispatch and already-sampled grid; the strong slowdown at W8/W16 is further evidence not to use these numbers as a production estimate. They are useful only for comparisons within this harness.
|
||
|
||
## Contact sheet
|
||
|
||
The [updated offline contact sheet](results/captures/contact_sheet.jpg) is 864 × 1,968 pixels. It contains the five analytic fixtures, the sampled SurfaceWorld cliff, and both LOD seam views, with MC/Hybrid/DC columns. The 24 individual JPEGs are 288 × 246 pixels; all 25 files including the sheet are below 300 KB. No viewer or GPU path was used.
|
||
|
||
## Round-2 recommendation and proposed round-3 work (historical)
|
||
|
||
At the end of round 2, the recommendation was not to select or enable the hybrid in the owner
|
||
project: same-LOD passed, but the full LOD gate did not. Round 3 later narrowed the policy to LOD0
|
||
interior feature cells with MC at borders and coarser LODs; the implementation and its remaining
|
||
transition limitation are recorded below. The following list preserves the original round-2 plan.
|
||
|
||
When the standalone LOD gate passes, round 3 should:
|
||
|
||
1. Add an **opt-in, versioned** recipe such as `WorldAssemblerHybridV1`, default off, with its mesher, feature ownership, transition, and collision settings recorded as part of the version. Keep the existing Core recipe and default hashes unchanged.
|
||
2. Add an Unreal test map with the five analytic fixtures, the sampled SurfaceWorld cliff, and a native Core cave tile. Include independent same-LOD neighbors and a sharp cliff crossing from LOD0 to LOD1. Compare skirts on/off and use matched cameras plus wireframe views.
|
||
3. Cook collision through the real Unreal path. Wait for cooking completion, then run capsule sweeps/walk tests over the doorway, riser, cliff underside, cave wall, and both borders. Check collision/render agreement and recooking after a local edit.
|
||
4. Record mesh and collision cook latency, CPU/memory, triangle/vertex counts, LOD error in pixels at the fixture cameras, and player contact results. Keep MC as the direct baseline and preserve a one-switch rollback to the existing recipe.
|
||
|
||
## Run ledger and scope
|
||
|
||
| Run/check | Result |
|
||
|---|---|
|
||
| Final MSVC C++20 build | Passed in 5.44 s, BelowNormal, affinity `0xFF00`. |
|
||
| Full seam run with unrestricted residual-loop caps | Completed in 602.78 s; 83 LOD cases failed. Preserved as `results/seams_cap_unbounded_diagnostic.csv`. |
|
||
| Final full seam run with 0.50 m cap-residual guard | Completed in 601.31 s; same-LOD passed 625/625 for all methods, LOD failures were MC 5, Hybrid 38, DC 40. No crash or guard trip. |
|
||
| Cost/phase/native analysis | Completed in 120.95 s; 1,875 phase rows, 45 determinism rows, native patch comparison. |
|
||
| Final offline renderer | Passed in 3.14 s; 25 JPEGs under the 300 KB cap. |
|
||
| Earlier full seam variants | Completed in 559.32 s and 566.44 s. Both failed earlier same-LOD Hybrid/DC cases (36/625 each); superseded by the final T-junction conformance pass. |
|
||
| Focused transition prototypes | Completed within seconds. Earlier MC doorway variants left 64, then 3–4 open edges; whole-mesh endpoint snapping introduced nonmanifold edges. Those variants were rejected. The bounded residual-loop cap closes this focused doorway case, but the full LOD matrix still fails. |
|
||
| Earlier native halo diagnostic | An initial process exited `0xC0000005`; an AddressSanitizer launch first failed `0xC0000135` because its runtime DLL was unavailable. After using the Visual Studio runtime path, ASan found the halo index overflow; the indexing was fixed, and subsequent harness runs completed. |
|
||
| W16 timing diagnostic | Repeated creation/timing of 16 OS workers caused a host access violation. W16 now uses one timed build; hash determinism remains checked. |
|
||
| Aggregation tools | Two PowerShell summary attempts had query errors, including a missing `vertices` field in `phase_sweep.csv`; corrected queries ran without launching a mesher. No `0xC0000142` retry was needed. |
|
||
|
||
Every final build, mesher, analysis, and renderer process ran BelowNormal with affinity `0xFF00`; the scripts enforce an 8 GB private-memory limit and 15-minute timeout. Peak observed mesher private memory was under 0.2 GB. No final process crashed, exceeded a limit, or needed a retry.
|
||
|
||
For round 2, all edits and outputs were under `Plugins/VoxelForge/Standalone/Research/WorldAssemblerM2`, plus its dialogue log. No `Source/` file, Core source, owner project file, `.uasset`, or editor was touched in that round. No commit, push, or stash was made.
|
||
|
||
## Round-2 files changed and new source files
|
||
|
||
Updated existing standalone files: [SharpMesherSpike.cpp](SharpMesherSpike.cpp), [BuildSharpMesherSpike.ps1](BuildSharpMesherSpike.ps1), [RunSharpMesherSpike.ps1](RunSharpMesherSpike.ps1), and [RenderSharpMesherCaptures.py](RenderSharpMesherCaptures.py). Updated this report and appended the M2 round-2 dialogue entry.
|
||
|
||
**New source files this round: none.** CSVs, OBJ meshes, JPEG captures, logs, and local build outputs are generated research artifacts; none were committed.
|
||
|
||
## Round-3 Unreal integration (2026-10-10)
|
||
|
||
The round-3 proposal is now in the plugin Core route as the versioned, opt-in
|
||
`WorldAssemblerHybridV1` recipe. `bUseVoxelForgeCore` remains off by default, and the Core recipe
|
||
defaults to `MarchingCubesV1`. The hybrid only consumes tagged type-2 world-plan feature boxes at
|
||
LOD0. Cells touching a tile border and every LOD1+ cell use MC; existing border skirts remain. The
|
||
selected recipe participates in Core content identity only when selected, so the disabled path and
|
||
the default MC path retain their existing identities.
|
||
|
||
### BuildHost evidence
|
||
|
||
The latest BuildHost UBT build and link-safety audit passed after the collision diagnostic was
|
||
changed to compare the runtime component trace and cooked-body bounds. The full null-RHI actor
|
||
commandlet ran for 11m00s and logged `pass complete=1`, `Success - 0 error(s)`. The PowerShell
|
||
wrapper then returned 1 while formatting its final status because it cast a `SwitchParameter` to
|
||
`Int32`; that print now uses the numeric fixture flag already computed by the script. A focused run
|
||
after this correction returned 0. The corrected full actor wrapper was then rerun and returned 0:
|
||
11m06s, peak sampled private memory 4,007,432,192 bytes (3.73 GiB), `pass complete=1`, and zero
|
||
engine errors. The final log is
|
||
[`CoreWorldValidation.log`](../../../Saved/BuildHost/HostProject/Plugins/VoxelForge/Saved/CoreWorldValidation/Logs/CoreWorldValidation.log).
|
||
|
||
W1/W8/W16 remained bit-stable at the round-6 Core hashes: density `0x8cc18e2981c50c4e`, mesh
|
||
`0x78e9c8ea42ff2965`, payload `0x380e8e11e76b47ca`, topology `0x24e40452e99fe482`. The actor passed
|
||
initial streaming, anchor movement, edit, height agreement, switch-off content gating, Blueprint
|
||
carve/fill, surface travel, and native SurfaceWorld travel. On the surface route, all 2,553 desired
|
||
visual tiles matched; 573 local tiles, 3,438 neighbor faces, and 432 LOD transitions were checked.
|
||
The actor run used about 2.8 GiB private memory. The only UECC directory is the older
|
||
2026-09-17 folder; no round-3 process crashed or retried on `0xC0000142`.
|
||
|
||
The hybrid selects triangles from the existing field and does not change field density, route
|
||
constraints, or signed-density bounds. This actor rerun passed height agreement, plan import,
|
||
anchor/edit/travel, switch-off gating, and Blueprint carve/fill. The last recorded full standalone
|
||
field audits remain the M1 round-4 results: 298 bounds / 8,046 samples with zero misses or unknown
|
||
ranges; 29,929 half-voxel shelf columns with zero sub-voxel runs; and a 530-center, 143,630-point
|
||
route sweep with zero blocked, unsupported, or grade-failing samples. Their negative controls were
|
||
detected. Those standalone audits were not rerun in round 3; the fresh route-related evidence is the
|
||
BuildHost actor travel/height pass above.
|
||
|
||
The focused production-mesher check passed all five fixture repeats. The separately staged native
|
||
SurfaceWorld type-4 cliff tile at `(-22,13,-58)` also passed a BuildHost MC/hybrid bit-identity
|
||
check: 10,231 vertices, 10,360 triangles, mesh hash `0xfc7bd7a3cf997992`. The full Core actor
|
||
session ran the TunnelNetwork cave path; its organic cave chamber fixture stayed on MC and produced
|
||
the same 2,408 triangles as MC.
|
||
|
||
Same-LOD borders are generated independently and pass with 63 MC segments and 63 hybrid/fallback
|
||
segments. The 125-phase LOD0/LOD1 doorway probe had zero cases and zero probes above 50 cm; its
|
||
worst measured contour mismatch was 22.844 cm. This does not close the known MC topology failures:
|
||
the standalone full transition matrix still has five failed doorway cases out of 625. This policy
|
||
keeps the existing skirts as the repair and leaves a true transition template for later work.
|
||
At LOD0, the measured 17.68 cm corner bevel is 0.35 of the 50 cm LOD1 sample. It may round off and
|
||
pop at the LOD threshold. Null RHI provided no projected-error or live visual measurement; the
|
||
owner must judge it at the target camera and movement speed.
|
||
|
||
### Cooked collision contacts
|
||
|
||
All five fixture contacts hit the actor's Pawn channel and the target RMC component. The actor's
|
||
Core render hash matched the standalone tile, render and cooked Chaos body bounds matched, and the
|
||
direct component trace differed from the world trace by 0.000 cm. Density-field contact error was
|
||
within one 25 cm Core voxel:
|
||
|
||
| Contact | World position (cm) | Field contact error |
|
||
|---|---:|---:|
|
||
| Corner top | (1025, 4150, −50127.64) | 20.332 cm |
|
||
| Doorway lintel | (1350, 4150, −50068.55) | 5.951 cm |
|
||
| Riser face | (1350, 4600, −50257.71) | 0.000 cm |
|
||
| Ledge top | (1450, 4600, −50140.14) | 8.956 cm |
|
||
| Ledge underside | (1450, 4600, −50190.14) | 13.262 cm |
|
||
|
||
### Production mesher cost
|
||
|
||
These BuildHost timings compare the plugin's production MC and hybrid routes after field sampling.
|
||
They measure meshing, not render upload or collision cooking.
|
||
|
||
| Fixture, 32³ cells | MC | Hybrid | Hybrid / MC | Triangles (MC / hybrid) |
|
||
|---|---:|---:|---:|---:|
|
||
| 90° corner | 2.246 ms | 15.048 ms | 6.70× | 3,196 / 3,200 |
|
||
| Doorway | 1.819 ms | 11.538 ms | 6.34× | 1,724 / 1,712 |
|
||
| 1 m riser | 1.979 ms | 11.974 ms | 6.05× | 2,108 / 2,112 |
|
||
| Cliff ledge | 2.270 ms | 12.839 ms | 5.66× | 3,132 / 3,128 |
|
||
| Organic cave | 2.106 ms | 2.089 ms | 0.992× | 2,408 / 2,408 |
|
||
|
||
Sharp-tagged fixtures cost roughly 5.66–6.70× MC in this plugin harness. The untagged cave is
|
||
effectively unchanged. This is a substantial local CPU cost where the tagged feature path runs.
|
||
|
||
### Owner hand-off and source inventory
|
||
|
||
In the owner project, enable `Use VoxelForge Core` on the `AVoxelWorld` and set `Core Mesher Recipe`
|
||
to `World Assembler Hybrid V1`. Both switches remain opt-in; the default recipe is MC. To preview
|
||
the surface-strate placements, duplicate the settings asset, import
|
||
[`surface_hybrid_fixture_plan.json`](round3/surface_hybrid_fixture_plan.json) through
|
||
`SourceWorldAssemblyManifestJson` / `ImportWorldAssemblyManifestJson`, then visit the corner,
|
||
doorway, riser, and ledge around the coordinates in the contact table. The plan carries nine stable
|
||
type-2 feature boxes and retains the sampled type-4 cliff. The owner should review the corner and
|
||
doorway as distance increases and cross the LOD threshold with skirts visible. No owner asset was
|
||
edited; all checks here used BuildHost with null RHI, so no visual capture was produced.
|
||
|
||
New source files this round are the mirrored private mesher headers
|
||
[`VoxelHybridSharpMesher.h`](../../../Source/VoxelForge/Private/VoxelHybridSharpMesher.h) and
|
||
[`VoxelHybridSharpMesher.h`](../../Source/VoxelForge/Private/VoxelHybridSharpMesher.h). No new
|
||
`.cpp` or generated header was added. Likely compile touchpoints are `VoxelWorld.h/.cpp`,
|
||
`VoxelTypes.h`, `VoxelMarchingCubesMesher.h/.cpp`, both hybrid mesher headers,
|
||
`Standalone/Core/include/VoxelForgeCore/VoxelForgeCore.h`,
|
||
`Standalone/Core/src/VoxelForgeCore.cpp`, `VoxelForgeExploreCommandlet.cpp`, and
|
||
`VoxelForgeEditor.Build.cs`.
|
||
|
||
### Round-3 failed-run ledger
|
||
|
||
Times below are BuildHost log stamps. Repeated attempts are listed individually; each was null-RHI
|
||
BuildHost work. The final passing commandlet and focused checks are described above.
|
||
|
||
| Run(s) | Result and correction |
|
||
|---|---|
|
||
| 02:32:40, 02:45:03 | The exact-output check failed for the tagged corner (`stable=1`, `expected_mc_identity=0`). Corrected the fixture assertion; the final five-fixture repeat check passes. |
|
||
| 03:00:55, 03:04:08 | The doorway probe compared the full coarse span with the fine span and reported 125/125 over-budget cases, worst 800.047 cm. Restricted comparison to their shared overlap; the final 125-phase probe is below budget. |
|
||
| 03:06:12, 03:24:05, 04:23:42 | Focused five-fixture checks passed. |
|
||
| 03:19:40 | Actor collision contact fixture failed before it recorded a corner contact. |
|
||
| 03:35:38, 03:52:53, 04:08:52, 04:21:48, 04:35:15, 04:51:17, 05:09:02, 05:22:12, 05:35:24, 05:52:51 | Actor checks exposed misses in the old pawn/visibility/closest-triangle diagnostic. Replaced that test with a direct RMC component trace plus cooked-body/render-bounds comparison. |
|
||
| 06:13:08 | Actor process hit the 900-second timeout at about 3.95 GiB and was stopped. No crash folder appeared. |
|
||
| 06:19:47 | Geometry audit included an injected synthetic fixture tile and rejected its 51.570 cm edge. Excluded injected fixture tiles from the natural-terrain scale audit. |
|
||
| 06:32:52 | Pawn/capsule hits worked, but the riser expected point was 100 cm from the actual contact (corner error 20.332 cm). Corrected the fixture anchor. |
|
||
| 06:48:33 | Pawn contacts worked, but the standalone closest-ray helper reported no visual hits; riser anchor was still offset. Replaced the unreliable helper and corrected the anchor again. |
|
||
| 07:03:11 | Double-precision triangle-ray helper still reported no visual hits; the riser target at x=1,250 cm missed the actual x=1,350 cm contact. Replaced this check with component tracing and render/cooked bounds. |
|
||
| 07:05–07:17 | A duplicate wrapper launch was refused because BuildHost PID 5616 was already active; its command line was verified as the requested null-RHI test and monitored. That actor run failed on the stale visual-ray helper and riser anchor. |
|
||
| Before final UBT pass | One compile failed because commandlet checks referenced `ReferenceWorld`, `TravelOptions`, and `CoreError` after their scope. Moved the check into scope; the next BuildHost UBT and link audit passed. |
|
||
| 07:22–07:33 | Full actor commandlet completed all assertions with `pass complete=1` and zero engine errors, but the wrapper returned 1 on its final `[int]$EnableHybridFixturePlacement` formatting cast. Fixed the status print to use the existing numeric flag; focused fixture and cliff wrappers then exited 0. |
|
||
| 07:40–07:51 | Reran the full actor path after the wrapper fix. Commandlet and wrapper both passed in 11m06s; peak sampled private memory was 4,007,432,192 bytes (3.73 GiB), and the engine reported zero errors. |
|
||
|
||
No new UECC folder, process crash, or `0xC0000142` retry occurred in round 3. No owner project/editor was
|
||
opened or built; no `.uasset` was edited; no commit, push, or stash was made.
|
||
|
||
## Round-4 exact, low-cost hybrid (2026-10-10)
|
||
|
||
### Decision and contact diagnosis
|
||
|
||
Added `WorldAssemblerHybridV2` as a separately versioned, opt-in recipe. It keeps MC connectivity and snaps only interior LOD0 MC edge roots that cross a tagged type-2 box face to that face’s exact sub-voxel plane. Stable face keys and axis normals keep shared edge roots deterministic. Tile-border cells and LOD1+ remain MC. V1 code/output, Core-off behavior, and `MarchingCubesV1` remain unchanged; select V2 when previewing the hybrid.
|
||
|
||
The previous table’s “field-contact error” label was wrong: it measured Euclidean distance from the cooked Pawn trace hit to a hand-authored expected point, not the signed field residual. The fixture anchors were correct: the same five anchors now produce exact hits with V2. The old offset came from MC interpolating across a type-2 box face between lattice samples. `Heightfield2D::point` applies the box only inside it (`min(base,-depth)`); outside it returns the base field, so the sampled edge root need not lie on the analytic face. The riser’s face happened to align with the lattice. These probes were all interior LOD0 contacts in tile `(1,5,-63)`, which rules out the border/LOD1 fallback. V2 snaps the eligible MC roots directly; its correction does not use a QEF clamp or center penalty.
|
||
|
||
The commandlet now logs `expected_point_error_cm`, the hit-to-anchor delta, and `density_at_contact` separately.
|
||
|
||
| Cooked Pawn contact | Expected-point error | Core density at hit | Render/cooked bounds |
|
||
|---|---:|---:|---|
|
||
| Corner top | 0.000 cm | 0.000000 | match |
|
||
| Doorway lintel | 0.000 cm | 0.000000 | match |
|
||
| Riser face | 0.000 cm | 0.000000 | match |
|
||
| Ledge top | 0.000 cm | 0.000000 | match |
|
||
| Ledge underside | 0.000 cm | 0.000000 | match |
|
||
|
||
Each trace hit the actor and target RMC component on the Pawn channel; the actor Core hash matched the expected mesh. The full V2 actor run passed all five contacts, the Core-off content gate, and the existing initial, anchor, edit, carve/fill, surface-travel, and surface-strate-travel checks.
|
||
|
||
### Tagged-tile cost
|
||
|
||
Full actor-run production mesher timings for 32³ LOD0 tiles, measured after field sampling:
|
||
|
||
| Fixture | MC during V1 | V1 | V1 / MC | MC during V2 | V2 | V2 / MC |
|
||
|---|---:|---:|---:|---:|---:|---:|
|
||
| 90° corner | 2.263 ms | 16.082 ms | 7.106× | 2.204 ms | 2.799 ms | 1.270× |
|
||
| Doorway | 1.808 ms | 11.416 ms | 6.313× | 1.797 ms | 2.112 ms | 1.175× |
|
||
| 1 m riser | 1.936 ms | 11.416 ms | 5.898× | 1.922 ms | 2.264 ms | 1.178× |
|
||
| Cliff ledge | 2.225 ms | 12.418 ms | 5.580× | 2.209 ms | 2.748 ms | 1.244× |
|
||
| Organic cave | 1.992 ms | 1.990 ms | 0.999× | 2.031 ms | 2.026 ms | 0.998× |
|
||
|
||
All four tagged fixtures are under the 1.5× target. V1 remains available for versioned comparison and retains its 5.58–7.11× cost; use V2 for the owner preview. V2 triangle counts match MC on these fixtures, and every fixture repeat was deterministic. The same-LOD independent border check passed; the V2 border mesh matched MC exactly.
|
||
|
||
### Final-code audits and identity checks
|
||
|
||
The rebuilt standalone audit reran the requested audits with negative controls:
|
||
|
||
| Audit | Final result | Negative control |
|
||
|---|---|---|
|
||
| Bounds | 298 boxes, 8,046 samples; 0 missed and 0 unknown bounds | Deliberately wrong bound detected |
|
||
| Shelf thickness | 29,929 columns; minimum 2.000 voxels; 0 sub-voxel runs | Legacy control found 20,963 sub-voxel runs in 19,251 columns |
|
||
| Route sweep | 33 points, 32 segments, 530 centers and 143,630 field samples; 0 blocked, unsupported, or grade failures | Raised-route control found 530 unsupported centers |
|
||
|
||
All three audits passed. The evaluator stayed deterministic at W1/W8/W16 (`c5e0371612e927af` each). The BuildHost actor hash matrix also remained at the round-6 hashes for density `0x8cc18e2981c50c4e`, mesh `0x78e9c8ea42ff2965`, payload `0x380e8e11e76b47ca`, and topology `0x24e40452e99fe482`.
|
||
|
||
V2 also passed the native SurfaceWorld cliff check: type-4-only tile `(-22,13,-58)`, 10,231 vertices, 10,360 triangles, hash `0xfc7bd7a3cf997992`, bit-identical to MC. The full actor SurfaceWorld run checked 2,553 desired tiles, 3,438 neighbor faces, 432 LOD transitions, and 1,016 skirt tiles.
|
||
|
||
Evidence: [standalone audit log](round4/audit.stdout.log), [focused V2 fixture and 125-phase doorway log](../../../Saved/BuildHost/HostProject/Plugins/VoxelForge/Saved/CoreWorldValidation/Logs/CoreWorldValidation-backup-2026.10.10-08.06.37.log), [full BuildHost actor log](../../../Saved/BuildHost/HostProject/Plugins/VoxelForge/Saved/CoreWorldValidation/Logs/CoreWorldValidation-backup-2026.10.10-08.20.33.log), and [V2 cliff check log](../../../Saved/BuildHost/HostProject/Plugins/VoxelForge/Saved/CoreWorldValidation/Logs/CoreWorldValidation.log).
|
||
|
||
### Doorway LOD failures with skirts
|
||
|
||
The five MC doorway failures remain topological failures of the standalone stitched-transition candidate. Every row has 3 seam-band boundary edges, 1 nonmanifold edge, and 1 unmatched loop. The raw fine/coarse contour mismatch is 18.57–20.48 cm and the transition-surface residual is 15.00–20.00 cm, below the 50 cm contour budget.
|
||
|
||
| Phase `(x,y,z)` m | Raw contour mismatch | Transition residual | Boundary / nonmanifold / unmatched |
|
||
|---|---:|---:|---:|
|
||
| `(0,0.15,0.15)` | 20.480 cm | 20.000 cm | 3 / 1 / 1 |
|
||
| `(0,0.20,0.20)` | 18.570 cm | 15.000 cm | 3 / 1 / 1 |
|
||
| `(0.05,0.15,0.15)` | 20.480 cm | 20.000 cm | 3 / 1 / 1 |
|
||
| `(0.05,0.20,0.20)` | 18.570 cm | 15.000 cm | 3 / 1 / 1 |
|
||
| `(0.10,0.15,0.15)` | 20.480 cm | 20.000 cm | 3 / 1 / 1 |
|
||
|
||
I regenerated the five failing phase pairs from independently meshed MC LOD0/LOD1 doorway tiles, then added the plugin’s normal-extruded, double-sided seam skirts at the round-2 comparison depths (1 m fine, 2 m coarse). In the matched CPU orthographic captures the seam opening is covered, but the skirt strips themselves are visible around the doorway. So the topology failures do not appear as open daylight gaps in this view; skirts can still be seen and may pop with camera movement. This is a static software-rendered diagnostic, not a live Unreal camera test.
|
||
|
||
Cases and meshes are in [the 750-row doorway sweep](round4/skirt-audit/seams.csv); the downscaled [skirts off/on contact sheet](round4/skirt-audit/captures/doorway_skirts_on_off_contact_sheet.jpg) shows all five failing phases. The production V2 policy still relies on skirts at LOD borders and keeps LOD1+ on MC.
|
||
|
||
### Build, source inventory, and run ledger
|
||
|
||
BuildHost UBT and the Core link-safety audit passed. The standalone Core/viewer build passed and produced `VoxelForgeM2Round4Audit.exe`; `vcvars64` printed a non-fatal missing-`vswhere.exe` message, and MSVC reported existing narrowing warnings in `VoxelStrateManager.cpp:3974–3975`. No build or test exceeded 15 minutes.
|
||
|
||
No permanent new source files were added. Modified implementation files are `Source/VoxelForge/Public/VoxelWorld.h`, `Source/VoxelForge/Private/VoxelWorld.cpp`, `Source/VoxelForge/Public/VoxelMarchingCubesMesher.h`, `Source/VoxelForge/Private/VoxelMarchingCubesMesher.cpp`, `Source/VoxelForge/Private/VoxelHybridSharpMesher.h`, the mirrored three files under `Standalone/Source/VoxelForge`, `Standalone/Core/include/VoxelForgeCore/VoxelForgeCore.h`, `Standalone/Core/src/VoxelForgeCore.cpp`, `Source/VoxelForgeEditor/Private/VoxelForgeExploreCommandlet.cpp`, and `Tools/TestVoxelForgeCoreWorldHost.ps1`. `ARCHITECTURE.md` and `CODEMAP.md` were updated. A temporary standalone skirt-export helper was built under `Saved/BuildHost` and removed after capture generation.
|
||
|
||
Likely compile touchpoints are the reflected enum in `VoxelWorld.h` (UHT), the VoxelForge runtime module, VoxelForgeCore, the VoxelForgeEditor commandlet, and the standalone `Build.ps1 -Target All` target.
|
||
|
||
| Run | Result |
|
||
|---|---|
|
||
| UBT attempt 1 | Failed in 50.5 s: `bCanSnapCell` was undeclared; changed the check to the V2 snap flag. |
|
||
| UBT attempt 2 | Failed in 8.8 s: standalone compatibility vectors do not support `operator[]`; added axis access helpers. |
|
||
| Final UBT + Core link audit | Passed; 16 parallel actions and Core symbol safety passed. |
|
||
| V2 fixture-only BuildHost | Passed, including fixture repeats, same-LOD border, and 125 doorway phases; commandlet reported 0 errors. |
|
||
| Full V2 actor BuildHost | Passed in about 11.5 min; peak sampled private memory 3,966,750,720 bytes (3.69 GiB); 0 engine errors. |
|
||
| V2 native cliff BuildHost | Passed in about 17 s; peak sampled private memory 2,130,636,800 bytes. |
|
||
| Standalone all-target build and bound/shelf/route audit | Passed; audit 24.2 s and peak sampled private memory 53,837,824 bytes. |
|
||
| Doorway skirt audit | Passed in 241.4 s; peak sampled private memory 214,925,312 bytes; CPU-only. |
|
||
|
||
No process crashed, no `0xC0000142` retry occurred, and no new `UECC-*` folder appeared. The only crash folder remains the older 2026-09-17 one. No owner project file or `.uasset` was changed, the owner’s editor/project was not opened or built, and no commit, push, or stash was made.
|