feat(editor): walk a composed candidate in PIE + why rooms read angular

PART B -- the thing Jahni asked for: "any way to test those in game?"
A candidate existed only as measurements and PNGs. Now he can stand in one.

  Select the VoxelWorld actor in PIE -> Live Edit|Composer ->
  ComposerSeed / ComposerCandidateIndex / ComposerTargetStrateIndex /
  bComposerRollStructure -> click Apply Composer Candidate.

The button and the automation tests call the SAME roll wrapper, which was
the load-bearing requirement: a second roll path could drift, and then he
would be judging a different world than the contact sheet describes. A
determinism sample is logged on apply (seed, index, recipe, archetype,
metrics, epoch, eight-point density verdict) so drift is caught the day it
happens rather than in a month.

Hazards handled, since this is the first composer code to touch the live
runtime path: preflight materialisation before any live mutation, generation
and decoration tasks drained, PassagesVersion bumped to invalidate
thread_local caches, reuse of the existing RegenerateAllChunks / Epoch
invalidation rather than a new path, no Initialize() or GeneratePassages()
during apply (the re-entrancy trap), DiffLayer locks untouched, and custom
recipes conservatively force ClassifyTile to Mixed.

Scope is deliberate: a DENSITY-ONLY overlay. Layout height, authored
passages, content, water and biome metadata stay from the existing slot;
RebuildStrates() clears it. A full composed layout replacement needs a safe
rebuild path that does not exist yet.

Editor-only, verified: a Shipping build succeeds with the bridge excluded
(96/96 actions), so §3.1's "offline only, never on a player's machine"
still holds.

⚠️ UNVERIFIED BY DESIGN: a button cannot be tested headlessly and Codex was
told not to claim it works. Jahni presses it and confirms the visual plus
the "determinism=PASS" log line.

PART A -- why rooms read angular, measured not guessed. One of three room
shapes is VoxelSDF::RoundedBox:
  ShapeA = (.8 Rxy, .8 Rxy, .8 Rz)   ShapeR = .25 Rxy
so rounding is 31% of the horizontal half-extent but 78% of the vertical.
Corners are rounded; the broad planar FACES survive. SmoothMin (blend 4)
softens room/tunnel junctions not isolated corners; the cave warp bends
geometry but preserves flat regions; roughness is surface-scale only.
The name is accurate -- "rounded box" is not "blob".

NOT ACTED ON. Jahni corrected his own read: the angular archetype is Maze
(lattice source, rectilinear BY DESIGN and correct), and TunnelNetwork is
"alright-ish". Codex's recommendation is recorded for if he ever wants it:
~5-10% boxes, 10-20% capsules, rest ellipsoids, or a larger ShapeR.

Also closed REVIEW_FINDINGS EVoxelPassageType/Style as WONTFIX, enacting a
2026-08-16 judgement that recommended closure and was left open.

Build clean (Editor + Shipping), 25 succeeded / 0 failed, run by me.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VJiTcTSDNkKBtnNdiBtdaU
This commit is contained in:
Fr0zkaandClaude Opus 5 committed 2026-09-04 22:03:01 +02:00
1 parent 90c40c8d5a
commit d717bc74ff
13 files changed
+1182 -32

No files matched your search

+24 -1
View File
@@ -84,7 +84,10 @@ a model over the candidates at zero runtime cost. **And Jahni reviews and vetoes
publishes** — the system does the work, he keeps the veto.
**What ships is small:** the season's seed plus the chosen strates' parameter vectors. Clients generate
terrain from those, deterministically, exactly as today. **No runtime composition anywhere.**
terrain from those, deterministically, exactly as today. **No composition is shipped or run in the
normal game path.** The editor-only PIE inspection button described below is a deliberate debugging
exception: it overlays one already-built slot so the owner can walk a measured candidate; it is not
cooked, does not compose a season, and is cleared by RebuildStrates.
### 3.2 Structure: how a stack gets assembled
@@ -194,6 +197,26 @@ through the offline Tier 2 sampler; no runtime generation path calls this API. T
test took **76.466 s**. The complete `VoxelForge` namespace then passed **24/24 tests (0 failed,
0 not run)** in **339.797 s**.
### 3.2a Editor walk-through hand-off (not a runtime composer)
AVoxelWorld::ApplyComposerCandidate is the one editor-only bridge from this offline API to a live
PIE world. It calls VF_RollStrateCandidate(Corpus, ComposerSeed, ComposerCandidateIndex,
bComposerRollStructure). That wrapper delegates to the exact parameter/recipe calls exercised by
the offline composer tests, then installs the result
as a temporary density override on ComposerTargetStrateIndex. The layout slot's authored definition,
height, content, and generated passages are intentionally unchanged; this avoids calling
GeneratePassages while Initialize is half-built. The action pauses/drains generation, bumps the
manager layout version, and reuses RegenerateAllChunks so GenerationEpoch invalidates stale mesh
results and the normal streamer rebuilds the world.
The Details-panel properties are ComposerSeed, ComposerCandidateIndex, ComposerTargetStrateIndex,
and bComposerRollStructure, under Live Edit|Composer. The button is Apply Composer Candidate; it
is usable only during PIE. RebuildStrates clears the temporary override. A post-apply eight-point
density check compares the live generator with the same prepared candidate stack bit-for-bit when
no diff edits, disturbance post, or surface-biome context makes the standalone oracle incomplete.
The log line carries the recipe/archetype and the coarse metrics so it can be matched to a
contact-sheet row. This hand-off is editor-only and is not part of the shipped composer contract.
### 3.3 Parameters: the range problem
**Verified facts, not remembered:** `FStrateGenerationParams` has **73 scalar fields** (+1 bool) — not