proto: liminal looks - pool rooms, backrooms grid, staircase to nowhere, terraced hills (L161)

Stamp vocabulary v7 (opt-in fillBox, carveBox, fillSteps; carveArch reused); flat-field liminal stamp fixtures; capsule
walk audit with doorway-width gate (1.2 m control fails as expected). Clang/GCC W1/W8/W12 identical; owner canonical
hashes unchanged; fast tier 273/273. Terraced wide view not yet legible.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016dhxM43dnWvUu2B5Ph1iG1
This commit is contained in:
Fr0zkaandClaude Opus 5.5 committed 2026-11-02 10:11:37 +01:00
1 parent 4290672d1c
commit ff52c9b576
17 files changed
+861 -12

No files matched your search

@@ -968,6 +968,7 @@ namespace VoxelForgeCore
inline constexpr std::uint32_t ResolvedLayoutStampVocabularyVersionV4 = 4;
inline constexpr std::uint32_t ResolvedLayoutStampVocabularyVersionV5 = 5;
inline constexpr std::uint32_t ResolvedLayoutStampVocabularyVersionV6 = 6;
inline constexpr std::uint32_t ResolvedLayoutStampVocabularyVersionV7 = 7;
inline constexpr std::uint32_t ResolvedLayoutCavernGraphVocabularyVersionV1 = 1;
inline constexpr std::uint32_t ResolvedLayoutOreVeinVocabularyVersionV1 = 1;
enum class ResolvedLayoutValidationModeV3 : std::uint8_t { compatibility, strict };
@@ -982,7 +983,10 @@ namespace VoxelForgeCore
fillDais = 4,
fillMonolith = 5,
fillPlatform = 6,
fillSweptDeckSegment = 7
fillSweptDeckSegment = 7,
fillBox = 8,
carveBox = 9,
fillSteps = 10
};
struct ResolvedLayoutStampRequestV1
@@ -1005,6 +1009,9 @@ namespace VoxelForgeCore
std::int64_t irregularityWavelengthMicrometres = 0;
std::int64_t roundingRadiusMicrometres = 0;
std::int64_t minimumSpacingMicrometres = 0;
// Vocabulary 7: fillSteps divides the X and Z extents into this many
// identical treads and risers. Other stamp kinds keep this at zero.
std::uint16_t stepCount = 0;
// 0 = free placement, 1 = seated on the authored flat profile floor.
std::uint8_t attachmentPolicy = 0;
std::int64_t floorMicrometres = 0;
@@ -1027,6 +1034,7 @@ namespace VoxelForgeCore
std::int64_t irregularityWavelengthMicrometres = 0;
std::int64_t roundingRadiusMicrometres = 0;
std::int64_t minimumSpacingMicrometres = 0;
std::uint16_t stepCount = 0;
std::uint8_t attachmentPolicy = 0;
std::int64_t floorMicrometres = 0;
std::uint64_t irregularitySeed = 0;
+29 -4
View File
@@ -176,7 +176,7 @@ namespace
{
const auto value=static_cast<std::uint8_t>(kind);
return value>=static_cast<std::uint8_t>(ResolvedSdfStampKindV1::carveEllipsoid)
&&value<=static_cast<std::uint8_t>(ResolvedSdfStampKindV1::fillSweptDeckSegment);
&&value<=static_cast<std::uint8_t>(ResolvedSdfStampKindV1::fillSteps);
}
bool LayoutStampIsMotif(ResolvedSdfStampKindV1 kind)
{return kind==ResolvedSdfStampKindV1::fillMonolith
@@ -711,6 +711,8 @@ namespace
<<",\"minimum_spacing_um\":"<<stamp.minimumSpacingMicrometres
<<",\"attachment_policy\":"<<static_cast<unsigned>(stamp.attachmentPolicy)
<<",\"floor_um\":"<<stamp.floorMicrometres;
if(stamp.kind==ResolvedSdfStampKindV1::fillSteps)
out<<",\"step_count\":"<<stamp.stepCount;
out<<'}';
}
out<<']';
@@ -1279,8 +1281,9 @@ bool ResolvedLayoutSnapshotV3::validate(ResolvedLayoutValidationModeV3 mode,
&&stampVocabularyVersion!=ResolvedLayoutStampVocabularyVersionV3
&&stampVocabularyVersion!=ResolvedLayoutStampVocabularyVersionV4
&&stampVocabularyVersion!=ResolvedLayoutStampVocabularyVersionV5
&&stampVocabularyVersion!=ResolvedLayoutStampVocabularyVersionV6)
add("stamp_vocabulary_version","resolved stamps require supported vocabulary version 1 through 6");
&&stampVocabularyVersion!=ResolvedLayoutStampVocabularyVersionV6
&&stampVocabularyVersion!=ResolvedLayoutStampVocabularyVersionV7)
add("stamp_vocabulary_version","resolved stamps require supported vocabulary version 1 through 7");
std::vector<std::string> stampIds;
for(const auto& stamp:stamps)
{
@@ -1292,8 +1295,18 @@ bool ResolvedLayoutSnapshotV3::validate(ResolvedLayoutValidationModeV3 mode,
if(!LayoutStampKindValid(stamp.kind)||stamp.yawQuarterTurns>3
||(stamp.kind==ResolvedSdfStampKindV1::fillSweptDeckSegment
&&stampVocabularyVersion<ResolvedLayoutStampVocabularyVersionV4)
||((stamp.kind==ResolvedSdfStampKindV1::fillBox
||stamp.kind==ResolvedSdfStampKindV1::carveBox
||stamp.kind==ResolvedSdfStampKindV1::fillSteps)
&&stampVocabularyVersion<ResolvedLayoutStampVocabularyVersionV7)
||(motif&&stampVocabularyVersion<ResolvedLayoutStampVocabularyVersionV3))
add("stamp_kind","stamp has an unsupported kind or orientation");
if((stamp.kind==ResolvedSdfStampKindV1::fillSteps
&&(stampVocabularyVersion<ResolvedLayoutStampVocabularyVersionV7
||stamp.stepCount<2||stamp.stepCount>128
||stamp.roundingRadiusMicrometres!=0))
||(stamp.kind!=ResolvedSdfStampKindV1::fillSteps&&stamp.stepCount!=0))
add("stamp_steps",stamp.stableId+" has an invalid step count or rounding mode");
bool validExtents=true;
for(const auto extent:stamp.halfExtentsMicrometres)
validExtents=validExtents&&extent>=500000&&extent<=100000000;
@@ -1777,6 +1790,7 @@ std::optional<ResolvedLayoutSnapshotV3> ResolvedLayoutSnapshotV3::FromJson(
stamp.floorMicrometres=LayoutInt(v,"floor_um");
stamp.irregularitySeed=static_cast<std::uint64_t>(LayoutInt(v,"irregularity_seed"));
stamp.yawQuarterTurns=static_cast<std::uint8_t>(LayoutInt(v,"yaw_quarter_turns"));
stamp.stepCount=static_cast<std::uint16_t>(LayoutInt(v,"step_count"));
s.stamps.push_back(std::move(stamp));
}
for(const auto& v:root.Get("cavern_rooms").AsArray())
@@ -1901,7 +1915,13 @@ bool ResolveResolvedLayoutStampsV1(ResolvedLayoutSnapshotV3& layout,std::int32_t
});
const bool hasSweptDeck=std::any_of(ordered.begin(),ordered.end(),[](const auto& request)
{return request.kind==ResolvedSdfStampKindV1::fillSweptDeckSegment;});
candidate.stampVocabularyVersion=hasContinuousSweptDeck
const bool hasVocabulary7Stamp=std::any_of(ordered.begin(),ordered.end(),[](const auto& request)
{return request.kind==ResolvedSdfStampKindV1::fillBox
||request.kind==ResolvedSdfStampKindV1::carveBox
||request.kind==ResolvedSdfStampKindV1::fillSteps;});
candidate.stampVocabularyVersion=hasVocabulary7Stamp
?ResolvedLayoutStampVocabularyVersionV7
:hasContinuousSweptDeck
?(hasNonMonotoneSweptDeck?ResolvedLayoutStampVocabularyVersionV6
:ResolvedLayoutStampVocabularyVersionV5)
:hasSweptDeck?ResolvedLayoutStampVocabularyVersionV4
@@ -1914,6 +1934,10 @@ bool ResolveResolvedLayoutStampsV1(ResolvedLayoutSnapshotV3& layout,std::int32_t
&&ordered[requestIndex-1].stableId==request.stableId))
{error="stamp requests require non-empty unique stable IDs";return false;}
if(!LayoutStampKindValid(request.kind)||request.yawQuarterTurns>3
||(request.kind==ResolvedSdfStampKindV1::fillSteps
?(request.stepCount<2||request.stepCount>128
||request.roundingRadiusMicrometres!=0)
:request.stepCount!=0)
||request.placementRadiusMicrometres<0
||request.placementRadiusMicrometres>100000000
||(request.kind==ResolvedSdfStampKindV1::fillSweptDeckSegment
@@ -1998,6 +2022,7 @@ bool ResolveResolvedLayoutStampsV1(ResolvedLayoutSnapshotV3& layout,std::int32_t
stamp.smoothWidthMicrometres=request.smoothWidthMicrometres;
stamp.irregularityAmplitudeMicrometres=request.irregularityAmplitudeMicrometres;
stamp.irregularityWavelengthMicrometres=request.irregularityWavelengthMicrometres;
stamp.stepCount=request.stepCount;
stamp.irregularitySeed=baseSeed;stamp.yawQuarterTurns=request.yawQuarterTurns;
std::array<std::int64_t,3> offset{};
if(request.placementRadiusMicrometres>0)
+26 -1
View File
@@ -7157,6 +7157,23 @@ private:
const float top=std::max(StampEllipsoidSdf(x,y,z,halfSize),-z);
return SmoothMinDistance(lower,top,round*2.0f);
}
static float StampStepsSdf(float x,float y,float z,
const std::array<float,3>& halfSize,std::uint16_t stepCount)
{
if(stepCount<2||stepCount>128)return std::numeric_limits<float>::infinity();
const float treadWidth=(2.0f*halfSize[0])/stepCount;
const float riserHeight=(2.0f*halfSize[2])/stepCount;
float distance=std::numeric_limits<float>::infinity();
for(std::uint16_t step=0;step<stepCount;++step)
{
const float stepHeight=(step+1)*riserHeight;
const float centerX=-halfSize[0]+(step+0.5f)*treadWidth;
const float centerZ=-halfSize[2]+stepHeight*0.5f;
const std::array<float,3> extent={treadWidth*0.5f,halfSize[1],stepHeight*0.5f};
distance=std::min(distance,StampRoundedBoxSdf(x-centerX,y,z-centerZ,extent,0.0f));
}
return distance;
}
static float StampContinuousSweptDeckSdf(const FStampRuntime& stamp,
float x,float y,float z)
{
@@ -7295,6 +7312,13 @@ private:
case VoxelForgeCore::ResolvedSdfStampKindV1::fillPlatform:
distance=StampRoundedBoxSdf(localX,localY,localZ,
stamp.halfExtentsVoxels,stamp.roundingRadiusVoxels);break;
case VoxelForgeCore::ResolvedSdfStampKindV1::fillBox:
case VoxelForgeCore::ResolvedSdfStampKindV1::carveBox:
distance=StampRoundedBoxSdf(localX,localY,localZ,
stamp.halfExtentsVoxels,stamp.roundingRadiusVoxels);break;
case VoxelForgeCore::ResolvedSdfStampKindV1::fillSteps:
distance=StampStepsSdf(localX,localY,localZ,stamp.halfExtentsVoxels,
stamp.record->stepCount);break;
case VoxelForgeCore::ResolvedSdfStampKindV1::fillDais:
if(ResolvedLayout&&ResolvedLayout->stampVocabularyVersion
>=VoxelForgeCore::ResolvedLayoutStampVocabularyVersionV2)
@@ -7471,7 +7495,8 @@ private:
||worldMicrometres[axis]>record.boundsMaximumMicrometres[axis])return;
const float distance=StampSdf(runtime,X,Y,Z);
if(record.kind==VoxelForgeCore::ResolvedSdfStampKindV1::carveEllipsoid
||record.kind==VoxelForgeCore::ResolvedSdfStampKindV1::carveArch)
||record.kind==VoxelForgeCore::ResolvedSdfStampKindV1::carveArch
||record.kind==VoxelForgeCore::ResolvedSdfStampKindV1::carveBox)
composed=SmoothMaxDistance(composed,-distance,runtime.smoothWidthVoxels);
else
composed=SmoothMinDistance(composed,distance,runtime.smoothWidthVoxels);
@@ -0,0 +1,226 @@
#!/usr/bin/env python3
"""Build four standalone liminal geometry fixtures and their capsule-walk specs."""
from __future__ import annotations
import argparse
import json
import os
from pathlib import Path
ROOT = Path(__file__).resolve().parents[4]
OWNER = Path(os.environ.get("VOXELFORGE_OWNER_DATA",
ROOT / "Standalone/data/owner_world.json"))
OUT_DEFAULT = Path(os.environ.get("VOXELFORGE_VERIFY_OUT", ROOT / "Saved/Linux/l161"))
FLAT_FIELD = {"version": 1, "kind": "flatField", "minimum_arena_clearance_m": 0.0}
def stamp(stamps: list[dict], stable_id: str, kind: str, x: float, y: float,
z: float, half: tuple[float, float, float], *, yaw: int = 0,
steps: int | None = None) -> None:
row = {
"stable_id": stable_id,
"kind": kind,
"anchor_xy_m": [x, y],
"z_offset_m": z,
"half_extents_m": list(half),
"yaw_quarter_turns": yaw,
}
if steps is not None:
row["step_count"] = steps
stamps.append(row)
def fixture(name: str, stamps: list[dict], walk_points: list[tuple[float, float, float]],
doors: list[dict], *, center: tuple[float, float], wide_camera: tuple[float, float, float],
eye_camera: tuple[float, float, float], eye_target_offset: tuple[float, float, float],
wide_target_offset: tuple[float, float, float],
eye_clip: int, wide_clip: int) -> tuple[str, dict, dict]:
root = json.loads(OWNER.read_text(encoding="utf-8"))
root["surface_profile_override"] = dict(FLAT_FIELD)
root["liminal_stamp_fixture_override"] = {
"version": 1,
"strate_index": 0,
"stamps": stamps,
}
walk = {
"version": 1,
"path_points_offset_m": [list(point) for point in walk_points],
"door_prefixes": doors,
}
views = {
"center_xy_m": list(center),
"eye_camera_offset_m": list(eye_camera),
"wide_camera_offset_m": list(wide_camera),
"eye_target_offset_m": list(eye_target_offset),
"wide_target_offset_m": list(wide_target_offset),
"eye_clip_radius": eye_clip,
"wide_clip_radius": wide_clip,
}
return name, root, {"walk": walk, "views": views}
def pool_rooms() -> tuple[str, dict, dict]:
stamps: list[dict] = []
cx, cy, cell, cells = 520.0, 440.0, 20.0, 7
half = cell * cells * 0.5
wall_height, wall_half_thickness = 9.0, 1.2
for line in range(cells + 1):
offset = (line - cells * 0.5) * cell
stamp(stamps, f"liminal/pool-rooms-v1/00-wall-x/{line:02d}", "fillBox",
cx + offset, cy, wall_height * 0.5,
(wall_half_thickness, half, wall_height * 0.5))
stamp(stamps, f"liminal/pool-rooms-v1/00-wall-y/{line:02d}", "fillBox",
cx, cy + offset, wall_height * 0.5,
(half, wall_half_thickness, wall_height * 0.5))
for row in range(cells):
y = cy + (row - (cells - 1) * 0.5) * cell
for line in range(cells + 1):
x = cx + (line - cells * 0.5) * cell
stamp(stamps, f"liminal/pool-rooms-v1/01-doorway-x/{row:02d}-{line:02d}",
"carveArch", x, y + 7.0, 4.0, (3.6, 1.55, 4.0), yaw=1)
stamp(stamps, f"liminal/pool-rooms-v1/01-doorway-y/{line:02d}-{row:02d}",
"carveArch", cx + (row - (cells - 1) * 0.5) * cell,
cy + (line - cells * 0.5) * cell, 4.0,
(3.6, 1.55, 4.0))
for row in range(cells):
y = cy + (row - (cells - 1) * 0.5) * cell
for column in range(cells):
x = cx + (column - (cells - 1) * 0.5) * cell
stamp(stamps, f"liminal/pool-rooms-v1/02-roof/{row:02d}-{column:02d}",
"fillBox", x, y, 9.4, (10.0, 10.0, 0.5))
stamp(stamps, f"liminal/pool-rooms-v1/03-skylight/{row:02d}-{column:02d}",
"carveBox", x, y, 9.4, (5.5, 5.5, 1.0))
stamp(stamps, f"liminal/pool-rooms-v1/04-basin/{row:02d}-{column:02d}",
"carveBox", x, y, -1.0, (5.5, 5.5, 1.5))
path_y = cy + 7.0
walk = [(-half - 2.0 + cx, path_y, 0.88), (half + 2.0 + cx, path_y, 0.88)]
doors = [
{"prefix": "liminal/pool-rooms-v1/01-doorway-x/", "width_axis": 0,
"minimum_width_m": 1.5},
{"prefix": "liminal/pool-rooms-v1/01-doorway-y/", "width_axis": 0,
"minimum_width_m": 1.5},
]
return fixture("pool-rooms", stamps, walk, doors, center=(cx, cy),
wide_camera=(-60.0, 7.0, 3.0), eye_camera=(-40.0, 7.0, 1.6),
eye_target_offset=(60.0, 7.0, 0.8),
wide_target_offset=(65.0, 7.0, 1.2), eye_clip=4, wide_clip=7)
def backrooms(width: float = 4.0, name: str = "backrooms-grid") -> tuple[str, dict, dict]:
stamps: list[dict] = []
cx, cy, cell, cells = 820.0, 420.0, 18.0, 7
half, wall_half = cell * cells * 0.5, 1.2
wall_height = 5.5
for line in range(cells + 1):
offset = (line - cells * 0.5) * cell
stamp(stamps, f"liminal/backrooms-grid-v1/00-wall-x/{line:02d}", "fillBox",
cx + offset, cy, wall_height * 0.5,
(wall_half, half, wall_height * 0.5))
stamp(stamps, f"liminal/backrooms-grid-v1/00-wall-y/{line:02d}", "fillBox",
cx, cy + offset, wall_height * 0.5,
(half, wall_half, wall_height * 0.5))
door_half = width * 0.5
for row in range(cells):
y = cy + (row - (cells - 1) * 0.5) * cell
for line in range(cells + 1):
x = cx + (line - cells * 0.5) * cell
stamp(stamps, f"liminal/backrooms-grid-v1/01-door-x/{row:02d}-{line:02d}",
"carveBox", x, y, 1.25, (1.6, door_half, 1.25))
stamp(stamps, f"liminal/backrooms-grid-v1/01-door-y/{line:02d}-{row:02d}",
"carveBox", cx + (row - (cells - 1) * 0.5) * cell,
cy + (line - cells * 0.5) * cell, 1.25,
(door_half, 1.6, 1.25))
stamp(stamps, "liminal/backrooms-grid-v1/02-ceiling", "fillBox",
cx, cy, 5.9, (half, half, 0.5))
walk = [(cx - half - 2.0, cy, 0.88), (cx + half + 2.0, cy, 0.88)]
doors = [
{"prefix": "liminal/backrooms-grid-v1/01-door-x/", "width_axis": 1,
"minimum_width_m": 1.5},
{"prefix": "liminal/backrooms-grid-v1/01-door-y/", "width_axis": 0,
"minimum_width_m": 1.5},
]
return fixture(name, stamps, walk, doors, center=(cx, cy),
wide_camera=(-42.0, -6.0, 1.6), eye_camera=(-54.0, 0.0, 1.6),
eye_target_offset=(102.0, 0.0, 1.6),
wide_target_offset=(80.0, 20.0, 0.0), eye_clip=6, wide_clip=6)
def nowhere_stairs() -> tuple[str, dict, dict]:
stamps: list[dict] = []
cx, cy = 300.0, -760.0
stamp(stamps, "liminal/staircase-nowhere-v1/00-stair", "fillSteps",
cx, cy, 6.0, (32.0, 4.0, 6.0), steps=64)
stamp(stamps, "liminal/staircase-nowhere-v1/04-landing", "fillBox",
cx + 40.5, cy, 11.5, (9.0, 4.5, 0.5))
stamp(stamps, "liminal/staircase-nowhere-v1/02-arch-wall", "fillBox",
cx + 38.0, cy, 7.5, (1.2, 6.5, 7.5))
stamp(stamps, "liminal/staircase-nowhere-v1/03-doorway-arch", "carveArch",
cx + 38.0, cy, 7.0, (5.0, 5.0, 7.0), yaw=1)
# Begin high enough to clear the first riser with the audit capsule, then
# walk the same ascending staircase through the arch and onto the landing.
points = [(cx - 32.5, cy, 0.88 + 12.0 / 64.0 + 0.05)]
tread, rise = 64.0 / 64, 12.0 / 64
for index in range(64):
points.append((cx - 32.0 + (index + 0.5) * tread,
cy, 0.88 + (index + 1) * rise + 0.05))
points.extend([(cx + 34.0, cy, 12.93), (cx + 38.0, cy, 12.93),
(cx + 44.0, cy, 12.93)])
doors = [{"prefix": "liminal/staircase-nowhere-v1/03-doorway-arch", "width_axis": 0,
"minimum_width_m": 1.5}]
return fixture("staircase-to-nowhere", stamps, points, doors, center=(cx, cy),
wide_camera=(-8.0, -32.0, 36.0), eye_camera=(10.0, 0.0, 9.7),
eye_target_offset=(38.0, 0.0, 13.6),
wide_target_offset=(42.0, 0.0, 11.0), eye_clip=4, wide_clip=6)
def terraced_hills() -> tuple[str, dict, dict]:
stamps: list[dict] = []
cx, cy, rows, spacing = -520.0, -500.0, 9, 96.0
half_run, half_width, half_rise, steps = 48.0, 40.0, 8.0, 80
for row in range(rows):
y = cy + (row - (rows - 1) * 0.5) * spacing
stamp(stamps, f"liminal/terraced-hills-v1/ridge/{row:02d}/rise-west",
"fillSteps", cx - half_run, y, half_rise,
(half_run, half_width, half_rise), steps=steps)
stamp(stamps, f"liminal/terraced-hills-v1/ridge/{row:02d}/rise-east",
"fillSteps", cx + half_run, y, half_rise,
(half_run, half_width, half_rise), yaw=2, steps=steps)
points = [(cx - 100.0, cy, 0.93)]
tread, rise = (2.0 * half_run) / steps, (2.0 * half_rise) / steps
for index in range(steps):
points.append((cx - 2.0 * half_run + (index + 0.5) * tread,
cy, 0.93 + (index + 1) * rise))
for index in reversed(range(steps)):
points.append((cx + 2.0 * half_run - (index + 0.5) * tread,
cy, 0.93 + (index + 1) * rise))
points.append((cx + 100.0, cy, 0.93))
return fixture("terraced-hills", stamps, points, [], center=(cx, cy),
wide_camera=(-40.0, 0.0, 20.0), eye_camera=(-60.0, 0.0, 7.8),
eye_target_offset=(0.0, 0.0, 14.5),
wide_target_offset=(100.0, 0.0, -10.0), eye_clip=4, wide_clip=3)
def write(path: Path, value: dict) -> None:
path.parent.mkdir(parents=True, exist_ok=True)
path.write_text(json.dumps(value, indent=2) + "\n", encoding="utf-8")
def main() -> None:
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument("--out", type=Path, default=OUT_DEFAULT / "fixtures")
args = parser.parse_args()
args.out.mkdir(parents=True, exist_ok=True)
specs = args.out / "walk-specs"
fixtures = [pool_rooms(), backrooms(), nowhere_stairs(), terraced_hills()]
fixtures.append(backrooms(width=1.2, name="backrooms-narrow-control"))
for name, world, metadata in fixtures:
write(args.out / f"liminal-{name}.json", world)
write(specs / f"{name}.json", metadata["walk"])
write(args.out / "views" / f"{name}.json", metadata["views"])
print(f"[L161Fixture] name={name} stamps="
f"{len(world['liminal_stamp_fixture_override']['stamps'])} status=PASS")
if __name__ == "__main__":
main()
@@ -0,0 +1,320 @@
#!/usr/bin/env python3
"""Run L161 stamp-fixture determinism, walk audits and two-view captures."""
from __future__ import annotations
import argparse
import hashlib
import json
import math
import os
from pathlib import Path
import re
import subprocess
import sys
import time
ROOT = Path(__file__).resolve().parents[4]
OUT_DEFAULT = Path(os.environ.get("VOXELFORGE_VERIFY_OUT", ROOT / "Saved/Linux/l161"))
CAPTURE_DEFAULT = Path(__file__).resolve().parent / "captures"
LIMIT = ["taskset", "-c", "0-11", "prlimit", "--as=6442450944", "--"]
Q_PER_METRE = 1024.0
FOG_COLOR = "0.78,0.84,0.87"
sys.path.insert(0, str(ROOT / "Standalone/Tools/verify"))
from runner import current_stamp, first_stamp
def fmt(values) -> str:
return ",".join(f"{value:.6f}" for value in values)
def sha256(path: Path) -> str:
digest = hashlib.sha256()
with path.open("rb") as stream:
for block in iter(lambda: stream.read(1024 * 1024), b""):
digest.update(block)
return digest.hexdigest()
def run_step(name: str, command: list[object], log: Path, *, env: dict[str, str],
stamped: bool = False, expected_exit: int = 0,
timeout_seconds: int = 1740) -> str:
expected_stamp = current_stamp() if stamped else None
if stamped:
probe = subprocess.run([str(command[0]), "--print-source-stamp"], cwd=ROOT,
capture_output=True, text=True, timeout=15, check=False)
if probe.returncode != 0 or first_stamp(probe.stdout) != expected_stamp:
raise RuntimeError(f"{name} refused a stale executable: {command[0]}")
log.parent.mkdir(parents=True, exist_ok=True)
started = time.monotonic()
with log.open("w", encoding="utf-8") as stream:
result = subprocess.run([*LIMIT, "timeout", f"{timeout_seconds}s",
*map(str, command)], cwd=ROOT, env=env, stdout=stream,
stderr=subprocess.STDOUT, timeout=timeout_seconds + 5, check=False)
elapsed = time.monotonic() - started
output = log.read_text(encoding="utf-8", errors="replace")
print(f"[L161Run] step={name} elapsed_s={elapsed:.3f} exit={result.returncode} log={log}",
flush=True)
if stamped and (first_stamp(output) != expected_stamp or current_stamp() != expected_stamp):
raise RuntimeError(f"{name} source stamp mismatch; see {log}")
if result.returncode != expected_exit:
raise RuntimeError(f"{name} exit={result.returncode}, expected={expected_exit}; see {log}")
return output
def camera_for(view: dict, floor: float, name: str, kind: str) -> tuple[float, float, float]:
center_x, center_y = view["center_xy_m"]
offset = view[f"{kind}_camera_offset_m"]
z = floor + offset[2]
if name == "backrooms-grid" or name == "backrooms-narrow-control":
z = floor + offset[2]
return center_x + offset[0], center_y + offset[1], z
def target_for(view: dict, floor: float, name: str, kind: str) -> tuple[float, float, float]:
center_x, center_y = view["center_xy_m"]
offset = view[f"{kind}_target_offset_m"]
return center_x + offset[0], center_y + offset[1], floor + offset[2]
def headless_command(binary: Path, fixture: Path, camera, mesh: Path,
manifest: Path, layout: Path, workers: int, clip_radius: int,
*, max_level: int = 0, hash_tiles: bool = False,
audit_path: Path | None = None) -> list[object]:
command: list[object] = [binary, fixture, f"--workers={workers}", "--seed=0",
"--world-assembler-prototype", "--stream-benchmark", "--stream-pipeline",
"--force-generate", f"--clip-radius={clip_radius}",
f"--max-clip-level={max_level}", f"--max-level={max_level}",
"--render-distance-chunks=0",
f"--camera={fmt((*camera, 0.0, 0.0))}", f"--mesh-export={mesh}",
f"--world-assembler-manifest-output={manifest}",
f"--resolved-layout-output={layout}"]
if hash_tiles:
command.append("--stream-hash-tiles")
if audit_path is not None:
command.append(f"--audit-liminal-stamp-walk={audit_path}")
return command
def digest(output: str, manifest_path: Path, layout_path: Path) -> tuple[str, str, str]:
tile_hashes = sorted(line for line in output.splitlines()
if line.startswith("[PipelineTileHash] "))
if not manifest_path.is_file() or not layout_path.is_file() or not tile_hashes:
raise RuntimeError("determinism run omitted manifest, resolved layout or tile hashes")
manifest = json.loads(manifest_path.read_text(encoding="utf-8"))
layout = json.loads(layout_path.read_text(encoding="utf-8"))
manifest_digest = "|".join((manifest["content_hash"],
manifest["recipe"]["content_hash"], manifest["plan"]["content_hash"]))
return manifest_digest, layout["stable_identity"], "\n".join(tile_hashes)
def write_walk_audit(spec_path: Path, manifest_path: Path, audit_path: Path) -> None:
spec = json.loads(spec_path.read_text(encoding="utf-8"))
manifest = json.loads(manifest_path.read_text(encoding="utf-8"))
surface = manifest["recipe"]["surface_profile"]
floor = surface["h0_q"] / Q_PER_METRE
lines = ["# P records are world metres; doorway width axes use the resolved stamp's local extents."]
for gate in spec["door_prefixes"]:
lines.append(f"D {gate['prefix']} {gate['width_axis']} {gate['minimum_width_m']:.6f}")
for x, y, z_offset in spec["path_points_offset_m"]:
lines.append(f"P {x:.6f} {y:.6f} {floor + z_offset:.6f}")
audit_path.parent.mkdir(parents=True, exist_ok=True)
audit_path.write_text("\n".join(lines) + "\n", encoding="utf-8")
def camera_angles(camera, target) -> tuple[float, float]:
dx, dy, dz = (target[index] - camera[index] for index in range(3))
return math.degrees(math.atan2(dx, dy)), math.degrees(math.atan2(dz, math.hypot(dx, dy)))
def build_plan(binary: Path, name: str, fixture: Path, view: dict,
out: Path, env: dict[str, str]) -> tuple[Path, Path, dict, dict]:
run_dir = out / "plan-probes" / name
run_dir.mkdir(parents=True, exist_ok=True)
manifest, layout = run_dir / "manifest.json", run_dir / "layout.json"
mesh = run_dir / "probe.vfmesh"
camera = (view["center_xy_m"][0], view["center_xy_m"][1], -500.0)
output = run_step(f"plan-{name}", headless_command(binary, fixture, camera,
mesh, manifest, layout, 12, 1), out / "logs" / f"plan-{name}.log",
env=env, stamped=True)
if "[LiminalStampFixtureResolved] vocabulary=7" not in output:
raise RuntimeError(f"{name} did not resolve with stamp vocabulary 7")
if not manifest.is_file() or not layout.is_file():
raise RuntimeError(f"{name} plan probe omitted its outputs")
manifest_value = json.loads(manifest.read_text(encoding="utf-8"))
layout_value = json.loads(layout.read_text(encoding="utf-8"))
return manifest, layout, manifest_value, layout_value
def run_determinism(name: str, fixture: Path, view: dict, floor: float,
binaries: dict[str, Path], out: Path, env: dict[str, str]) -> None:
camera = camera_for(view, floor, name, "eye")
baseline = None
for compiler in ("clang", "gcc"):
for workers in (1, 8, 12):
tag = f"{name}-{compiler}-w{workers}"
run_dir = out / "determinism" / tag
run_dir.mkdir(parents=True, exist_ok=True)
mesh, manifest, layout = (run_dir / "fixture.vfmesh",
run_dir / "manifest.json", run_dir / "layout.json")
output = run_step(tag, headless_command(binaries[compiler], fixture,
camera, mesh, manifest, layout, workers, 1,
hash_tiles=True), out / "logs" / f"determinism-{tag}.log",
env=env, stamped=True)
result = digest(output, manifest, layout)
if baseline is None:
baseline = result
elif result != baseline:
raise RuntimeError(f"{name} diverged at {compiler} W{workers}; see determinism logs")
print(f"[L161Determinism] fixture={name} compiler_worker_cells=6 identical=yes status=PASS",
flush=True)
def run_walk_audit(name: str, fixture: Path, view: dict, floor: float,
spec: Path, binary: Path, out: Path, env: dict[str, str],
*, expected_exit: int = 0) -> str:
camera = camera_for(view, floor, name, "eye")
run_dir = out / "walk-audits" / name
run_dir.mkdir(parents=True, exist_ok=True)
manifest = run_dir / "manifest.json"
layout = run_dir / "layout.json"
mesh = run_dir / "audit.vfmesh"
audit_path = run_dir / "walk.path"
# Use a fixture-specific manifest, so the path uses the exact authored floor height.
plan = out / "plan-probes" / name / "manifest.json"
if not plan.is_file():
raise RuntimeError(f"{name} has no resolved manifest for its walk audit")
write_walk_audit(spec, plan, audit_path)
output = run_step(f"walk-{name}", headless_command(binary, fixture, camera,
mesh, manifest, layout, 12, 1, audit_path=audit_path),
out / "logs" / f"walk-{name}.log", env=env, stamped=True,
expected_exit=expected_exit)
expected_status = "FAIL" if expected_exit else "PASS"
if not re.search(rf"\[LiminalStampWalkAudit\].*status={expected_status}\b", output):
raise RuntimeError(f"{name} walk audit did not report expected {expected_status}")
return output
def capture(name: str, fixture: Path, view: dict, floor: float, *, kind: str,
binary: Path, renderer: Path, out: Path, artifact_dir: Path,
env: dict[str, str]) -> None:
camera = camera_for(view, floor, name, kind)
target = target_for(view, floor, name, kind)
clip_radius = int(view[f"{kind}_clip_radius"])
max_level = 1 if name == "terraced-hills" and kind == "wide" else 0
stem = f"{name}-{kind}"
run_dir = out / "captures" / stem
run_dir.mkdir(parents=True, exist_ok=True)
mesh, manifest, layout = (run_dir / "capture.vfmesh",
run_dir / "manifest.json", run_dir / "layout.json")
png = run_dir / "capture.png"
image = artifact_dir / f"{stem}.jpg"
output = run_step(f"capture-export-{stem}", headless_command(binary,
fixture, camera, mesh, manifest, layout, 12, clip_radius,
max_level=max_level), out / "logs" / f"capture-export-{stem}.log",
env=env, stamped=True)
if not mesh.is_file() or mesh.stat().st_size == 0:
raise RuntimeError(f"{stem} produced an empty mesh")
yaw, pitch = camera_angles(camera, target)
if name == "backrooms-grid":
fog_start, fog_end, fog_color = 90, 500, "0.82,0.83,0.76"
elif name == "pool-rooms":
fog_start, fog_end, fog_color = 90, 480, "0.76,0.84,0.87"
elif name == "staircase-to-nowhere":
fog_start, fog_end, fog_color = 110, 700, "0.78,0.84,0.87"
else:
fog_start, fog_end, fog_color = 160, 1050, "0.78,0.84,0.89"
renderer_command = [renderer, mesh, png, "--size=1600x900", "--fov-deg=72",
f"--camera-m={fmt(camera)}", f"--yaw-deg={yaw:.6f}",
f"--pitch-deg={pitch:.6f}", "--tile-skirts=on", "--shade=readable",
"--headlamp=off", "--height-tint=on",
f"--height-center-m={floor + 3.0:.6f}", "--height-range-m=30.0",
"--light-direction=-0.42,-0.58,0.70", "--fog=on",
f"--fog-start-m={fog_start}", f"--fog-end-m={fog_end}",
f"--fog-color={fog_color}"]
run_step(f"capture-render-{stem}", renderer_command,
out / "logs" / f"capture-render-{stem}.log", env=env, stamped=True)
run_step(f"capture-jpeg-{stem}", ["ffmpeg", "-nostdin", "-hide_banner",
"-loglevel", "error", "-y", "-i", png, "-frames:v", "1", "-q:v", "4", image],
out / "logs" / f"capture-jpeg-{stem}.log", env=env)
quality = run_step(f"capture-quality-{stem}", [sys.executable,
ROOT / "Standalone/Tools/verify/capture_quality.py", image],
out / "logs" / f"capture-quality-{stem}.log", env=env)
if "[CaptureQuality]" not in quality or not image.is_file() or image.stat().st_size > 300_000:
raise RuntimeError(f"{stem} failed image quality or size checks")
print(f"[L161Capture] fixture={name} view={kind} camera_m=({fmt(camera)}) "
f"target_m=({fmt(target)}) bytes={image.stat().st_size} "
f"sha256={sha256(image)} status=PASS", flush=True)
def main() -> int:
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument("--out", type=Path, default=OUT_DEFAULT)
parser.add_argument("--artifact-dir", type=Path, default=CAPTURE_DEFAULT)
parser.add_argument("--headless-clang", type=Path, required=True)
parser.add_argument("--headless-gcc", type=Path, required=True)
parser.add_argument("--renderer", type=Path, required=True)
args = parser.parse_args()
out, artifact_dir = args.out.resolve(), args.artifact_dir.resolve()
fixture_dir = out / "fixtures"
for directory in (out, fixture_dir, artifact_dir):
directory.mkdir(parents=True, exist_ok=True)
env = os.environ.copy()
env["VOXELFORGE_VERIFY_OUT"] = str(out)
env["VOXELFORGE_OWNER_DATA"] = str(ROOT / "Standalone/data/owner_world.json")
env["LP_NUM_THREADS"] = "12"
env["XDG_CACHE_HOME"] = str(out / "xdg-cache")
run_step("build-fixtures", [sys.executable,
Path(__file__).resolve().parent / "BuildL161Fixtures.py",
f"--out={fixture_dir}"], out / "logs" / "build-fixtures.log", env=env)
binaries = {"clang": args.headless_clang.resolve(), "gcc": args.headless_gcc.resolve()}
fixtures = {name: fixture_dir / f"liminal-{name}.json" for name in
("pool-rooms", "backrooms-grid", "staircase-to-nowhere", "terraced-hills")}
views = {}
floors = {}
for name, fixture_path in fixtures.items():
view = json.loads((fixture_dir / "views" / f"{name}.json").read_text(encoding="utf-8"))
manifest_path, _, manifest, layout = build_plan(binaries["clang"], name,
fixture_path, view, out, env)
view["center_xy_m"] = view["center_xy_m"]
floors[name] = manifest["recipe"]["surface_profile"]["h0_q"] / Q_PER_METRE
if layout["stamp_vocabulary_version"] != 7 or not layout["stamps"]:
raise RuntimeError(f"{name} plan lacks resolved vocabulary-7 stamps")
write_walk_audit(fixture_dir / "walk-specs" / f"{name}.json",
manifest_path, out / "walk-audits" / name / "walk.path")
views[name] = view
print(f"[L161Plan] fixture={name} stamps={len(layout['stamps'])} "
f"floor_m={floors[name]:.3f} layout={layout['stable_identity']} status=PASS")
for name, fixture_path in fixtures.items():
run_walk_audit(name, fixture_path, views[name], floors[name],
fixture_dir / "walk-specs" / f"{name}.json", binaries["clang"], out, env)
run_determinism(name, fixture_path, views[name], floors[name], binaries, out, env)
narrow_name = "backrooms-narrow-control"
narrow_fixture = fixture_dir / f"liminal-{narrow_name}.json"
narrow_view = json.loads((fixture_dir / "views" / f"{narrow_name}.json").read_text(encoding="utf-8"))
narrow_manifest, _, narrow_manifest_value, _ = build_plan(binaries["clang"],
narrow_name, narrow_fixture, narrow_view, out, env)
narrow_floor = narrow_manifest_value["recipe"]["surface_profile"]["h0_q"] / Q_PER_METRE
run_walk_audit(narrow_name, narrow_fixture, narrow_view, narrow_floor,
fixture_dir / "walk-specs" / f"{narrow_name}.json", binaries["clang"],
out, env, expected_exit=14)
print("[L161DoorwayNegativeControl] width_m=1.200 minimum_m=1.500 expected=FAIL status=PASS")
for name, fixture_path in fixtures.items():
for kind in ("eye", "wide"):
capture(name, fixture_path, views[name], floors[name], kind=kind,
binary=binaries["clang"], renderer=args.renderer.resolve(), out=out,
artifact_dir=artifact_dir, env=env)
return 0
if __name__ == "__main__":
try:
raise SystemExit(main())
except Exception as error:
print(f"[L161Capture] status=FAIL error={error}", file=sys.stderr, flush=True)
raise SystemExit(1)
@@ -0,0 +1,31 @@
# L161 — More liminal looks
| Look | Eye height | Wide |
|---|---|---|
| Pool rooms | ![Pool rooms at eye height](captures/pool-rooms-eye.jpg) | ![Pool rooms wide](captures/pool-rooms-wide.jpg) |
| Backrooms grid | ![Backrooms corridor at eye height](captures/backrooms-grid-eye.jpg) | ![Backrooms grid wide](captures/backrooms-grid-wide.jpg) |
| Staircase to nowhere | ![Staircase at eye height](captures/staircase-to-nowhere-eye.jpg) | ![Staircase wide](captures/staircase-to-nowhere-wide.jpg) |
| Terraced hills | ![Terraced hills at eye height](captures/terraced-hills-eye.jpg) | ![Terraced hills wide](captures/terraced-hills-wide.jpg) |
## Result
Four standalone SurfaceWorld fixtures resolve from the shared stamp vocabulary. They use repeated rooms and basins, a doorway grid, a freestanding stair and arch, and nine stepped ridges. This round authored no inter-strate passages or owner content.
## Changes
- Stamp vocabulary v7 adds `fillBox`, `carveBox`, and `fillSteps`; the existing `carveArch` is reused. The new kinds are opt-in.
- Added a flat-field liminal stamp-fixture override and a capsule walk audit with doorway-width gates. The audit checks support, collision, grade, and authored opening widths.
- Fixtures contain 275 pool-room stamps, 129 backrooms stamps, 4 staircase/arch stamps, and 18 terrace stamps.
## Verification
- Clang 19 and GCC 14 builds passed with FP contraction off. Both binaries carry source stamp `8e9e114c1357`.
- Each fixture matched across Clang/GCC at W1, W8, and W12: manifest, resolved-layout identity, and tile hashes were identical in all six cells.
- Positive capsule audits passed. Pool doorways measured 7.2 m, backrooms doorways 4.0 m, and the arch opening 10.0 m. The narrow 1.2 m backrooms control failed the 1.5 m minimum as expected. The terrace walk had zero blocked samples, unsupported samples, or grade failures.
- All eight 1600×900 captures passed image quality checks; files are 25.3–58.4 KB. Capture and audit logs are under `Saved/Linux/l161/logs/`.
- Fast tier passed: 273 checks in 346.6 s. Both owner generators matched their pinned L130/v227 canonical baselines exactly (12/12 rows), and W1/W12 signatures matched. Summary: `Saved/Linux/l161/fast-tier/fast-summary.json`.
- `git diff --check` passed. No Unreal `Source/` files changed; no Unreal build or medium/full verification tier was run.
## Remaining risk
The captures show untextured geometry with simple fog. The terraced wide capture uses clip radius 3 and max LOD 1 to stay within the standalone shape-build bound, so the long-range horizon read still needs an art review.
Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 37 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 48 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 49 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 57 KiB

+34 -3
View File
@@ -105,6 +105,7 @@ namespace
std::filesystem::path WorldAssemblyManifestOutputPath;
std::filesystem::path ResolvedLayoutOutputPath;
std::filesystem::path CoreSnapshotInputPath;
std::filesystem::path LiminalStampWalkAuditPath;
bool ResolvedLayoutOnly=false;
bool AuditResolvedLayoutBoundaries=false;
bool AuditResolvedLayoutPassages=false;
@@ -1449,6 +1450,7 @@ namespace
" --transition-mode=hard|gradient|interleaved --transition-width-chunks=N (fixture override)\n"
" --audit-resolved-layout-passages (capsule, support, route-binding and blocked-control audit)\n"
" --audit-liminal-road-walk (capsule, support, width and grade audit for the liminal road)\n"
" --audit-liminal-stamp-walk=FILE (capsule, support and doorway-width audit for a stamp fixture)\n"
" --audit-heightfield-profile (brute-force the profiled field intervals and route)\n"
" --audit-motif-intervals (brute-force motif bounds, BVH and shape-free guards)\n"
" --audit-landmark-reachability (capsule, support, grade and buried-L43 control)\n"
@@ -1497,6 +1499,9 @@ namespace
else if(arg=="--audit-resolved-layout-boundaries")options.AuditResolvedLayoutBoundaries=true;
else if(arg=="--audit-resolved-layout-passages")options.AuditResolvedLayoutPassages=true;
else if(arg=="--audit-liminal-road-walk")options.AuditLiminalRoadWalk=true;
else if(arg.starts_with("--audit-liminal-stamp-walk="))
options.LiminalStampWalkAuditPath=std::filesystem::path(std::string(
arg.substr(std::string_view("--audit-liminal-stamp-walk=").size())));
else if(arg=="--native-owner-fi")options.NativeOwnerFloatingIslandsRecipe=true;
else if(arg=="--density-dispatch-report")
{options.DensityDispatchReport=true;options.StreamHash=true;options.StreamHashTiles=true;}
@@ -2035,10 +2040,14 @@ int main(int argc,char** argv)
ownerJsonRoot.Get("liminal_road_override").Data);
const bool hasLiminalPillarGrid=!std::holds_alternative<std::nullptr_t>(
ownerJsonRoot.Get("liminal_pillar_grid_override").Data);
const bool hasLiminalStampFixture=!std::holds_alternative<std::nullptr_t>(
ownerJsonRoot.Get("liminal_stamp_fixture_override").Data);
if((hasMotifFamily&&hasLiminalRoad)||(hasMotifFamily&&hasLiminalPillarGrid)
||(hasLiminalRoad&&hasLiminalPillarGrid))
||(hasLiminalRoad&&hasLiminalPillarGrid)
||(hasLiminalStampFixture&&(hasMotifFamily||hasLiminalRoad||hasLiminalPillarGrid)))
{std::fprintf(stderr,"liminal content overrides must be used in separate fixtures\n");return 2;}
if(hasCoreLiminalField&&(hasMotifFamily||hasLiminalRoad||hasLiminalPillarGrid))
if(hasCoreLiminalField&&(hasMotifFamily||hasLiminalRoad||hasLiminalPillarGrid
||hasLiminalStampFixture))
{std::fprintf(stderr,"Core.Liminal.Field owns its variant geometry and cannot be combined with prototype content overrides\n");return 2;}
if(hasMotifFamily)
{
@@ -2138,6 +2147,27 @@ int main(int argc,char** argv)
"placement=regular_grid route_keepout=PASS band_clearance=PASS status=PASS\n",
resolvedLayout.stampVocabularyVersion,resolvedLayout.stamps.size());
}
if(hasLiminalStampFixture)
{
std::vector<VoxelForgeCore::ResolvedLayoutStampRequestV1> requests;
if(!StandaloneWorldAssemblyPrototype::BuildLiminalStampFixtureRequests(ownerJsonRoot,
*ownerWorld,worldAssembly,resolvedLayout,requests,error)
||!VoxelForgeCore::ResolveResolvedLayoutStampsV1(
resolvedLayout,seed,requests,error))
{std::fprintf(stderr,"Liminal stamp fixture resolution failed: %s\n",error.c_str());return 2;}
const std::size_t boxFills=static_cast<std::size_t>(std::count_if(
resolvedLayout.stamps.begin(),resolvedLayout.stamps.end(),[](const auto& stamp)
{return stamp.kind==VoxelForgeCore::ResolvedSdfStampKindV1::fillBox;}));
const std::size_t boxCarves=static_cast<std::size_t>(std::count_if(
resolvedLayout.stamps.begin(),resolvedLayout.stamps.end(),[](const auto& stamp)
{return stamp.kind==VoxelForgeCore::ResolvedSdfStampKindV1::carveBox;}));
const std::size_t stairs=static_cast<std::size_t>(std::count_if(
resolvedLayout.stamps.begin(),resolvedLayout.stamps.end(),[](const auto& stamp)
{return stamp.kind==VoxelForgeCore::ResolvedSdfStampKindV1::fillSteps;}));
std::printf("[LiminalStampFixtureResolved] vocabulary=%u records=%zu box_fills=%zu box_carves=%zu steps=%zu placement=bounded_flat_field status=PASS\n",
resolvedLayout.stampVocabularyVersion,resolvedLayout.stamps.size(),
boxFills,boxCarves,stairs);
}
if(options.LandmarkChamberDemo)
{
std::vector<VoxelForgeCore::ResolvedLayoutStampRequestV1> requests;
@@ -2639,5 +2669,6 @@ int main(int argc,char** argv)
options.MovingCameraSpeedMetersPerSecond,options.MovingCameraDurationSeconds,
options.MovingCameraDwellSeconds,options.ColdWorkerTimeline,
options.AuditPassageSourceClamp,options.AuditPassageCarveReach,
options.AuditPassageTileSeams,options.AuditLiminalRoadWalk);
options.AuditPassageTileSeams,options.AuditLiminalRoadWalk,
options.LiminalStampWalkAuditPath);
}
+83 -3
View File
@@ -22,6 +22,7 @@
#include <limits>
#include <numeric>
#include <queue>
#include <sstream>
#include <string_view>
#include <thread>
#include <tuple>
@@ -2385,7 +2386,8 @@ namespace StandaloneStreamBenchmark
double MovingCameraDurationSeconds=12.0,double MovingCameraDwellSeconds=5.0,
bool bColdWorkerTimeline=false,bool bAuditPassageSourceClamp=false,
bool bAuditPassageCarveReach=false,bool bAuditPassageTileSeams=false,
bool bAuditLiminalRoadWalk=false)
bool bAuditLiminalRoadWalk=false,
const std::filesystem::path& LiminalStampWalkAuditPath={})
{
using Clock=std::chrono::steady_clock;
const std::clock_t ColdCpuOrigin=std::clock();
@@ -2555,7 +2557,8 @@ namespace StandaloneStreamBenchmark
||bAuditOreVeinYield||bAuditLandmarkReachability||bAuditStrateTransitions
||bAuditResolvedLayoutPassages||bAuditResolvedLayoutBoundaries
||bAuditTileShapeReadiness||bAuditBasePageEquivalence||bAuditRouteParity
||bAuditPassageSourceClamp||bAuditPassageCarveReach||bAuditLiminalRoadWalk;
||bAuditPassageSourceClamp||bAuditPassageCarveReach||bAuditLiminalRoadWalk
||!LiminalStampWalkAuditPath.empty();
const bool bDeferFarWorld=bIncludeFarWorld&&!bMovingCameraTrace&&!bFarWorldAudit;
VoxelForgeCore::ShapeBuildRequest ShapeRequest;
ShapeRequest.minVoxel={FineMin.X,FineMin.Y,FineMin.Z};
@@ -2821,7 +2824,8 @@ namespace StandaloneStreamBenchmark
Streamer.Stop();
return passed?0:11;
}
if(bAuditResolvedLayoutPassages||bAuditLiminalRoadWalk)
if(bAuditResolvedLayoutPassages||bAuditLiminalRoadWalk
||!LiminalStampWalkAuditPath.empty())
{
if(ResolvedLayout==nullptr||!CoreSnapshot.resolvedLayout())
{Streamer.Stop();std::fprintf(stderr,"[ResolvedWalkAudit] missing resolved-layout snapshot\n");return 2;}
@@ -3230,6 +3234,82 @@ namespace StandaloneStreamBenchmark
}
return passed;
};
if(!LiminalStampWalkAuditPath.empty())
{
struct FDoorwayWidthGate
{
std::string prefix;
std::uint32_t widthAxis=0;
double minimumWidthMetres=0.0;
};
std::ifstream auditFile(LiminalStampWalkAuditPath);
std::vector<std::array<double,3>> walkPath;
std::vector<FDoorwayWidthGate> doorwayGates;
bool inputValid=static_cast<bool>(auditFile);
std::string line;
while(inputValid&&std::getline(auditFile,line))
{
if(line.empty()||line[0]=='#')continue;
std::istringstream fields(line);
char record=0;fields>>record;
if(record=='P')
{
std::array<double,3> point{};
fields>>point[0]>>point[1]>>point[2];
inputValid=inputValid&&static_cast<bool>(fields)
&&std::isfinite(point[0])&&std::isfinite(point[1])
&&std::isfinite(point[2]);
if(inputValid)
walkPath.push_back({point[0]/coreMetres,
point[1]/coreMetres,point[2]/coreMetres});
}
else if(record=='D')
{
FDoorwayWidthGate gate;
fields>>gate.prefix>>gate.widthAxis>>gate.minimumWidthMetres;
inputValid=inputValid&&static_cast<bool>(fields)
&&!gate.prefix.empty()&&gate.widthAxis<2
&&std::isfinite(gate.minimumWidthMetres)
&&gate.minimumWidthMetres>=1.5;
if(inputValid)doorwayGates.push_back(std::move(gate));
}
else inputValid=false;
}
std::uint64_t doorwayCount=0;
double narrowestDoorway=std::numeric_limits<double>::infinity();
bool doorwayWidthsPass=inputValid;
for(const auto& gate:doorwayGates)
{
std::uint64_t found=0;
for(const auto& stamp:ResolvedLayout->stamps)
{
if(!stamp.stableId.starts_with(gate.prefix))continue;
++found;++doorwayCount;
const double width=2.0*stamp.halfExtentsMicrometres[gate.widthAxis]/1.0e6;
narrowestDoorway=std::min(narrowestDoorway,width);
if(width+1.0e-9<gate.minimumWidthMetres)doorwayWidthsPass=false;
}
doorwayWidthsPass=doorwayWidthsPass&&found>0;
}
if(doorwayCount==0)narrowestDoorway=0.0;
const FWalkAudit walkAudit=inputValid&&walkPath.size()>=2
?auditPlayerPath(Shape,walkPath,0.125,0.125,1.125,3,0.45):FWalkAudit{};
const bool passed=inputValid&&doorwayWidthsPass&&walkAudit.passed;
std::printf("[LiminalStampWalkAudit] path_points=%zu stations=%llu capsule_samples=%llu "
"blocked=%llu support_samples=%llu unsupported=%llu grade_failures=%llu "
"doorways=%llu narrowest_doorway_m=%.3f minimum_doorway_m=1.500 "
"status=%s\n",walkPath.size(),
static_cast<unsigned long long>(walkAudit.centers),
static_cast<unsigned long long>(walkAudit.capsuleSamples),
static_cast<unsigned long long>(walkAudit.blocked),
static_cast<unsigned long long>(walkAudit.supportSamples),
static_cast<unsigned long long>(walkAudit.unsupported),
static_cast<unsigned long long>(walkAudit.gradeFailures),
static_cast<unsigned long long>(doorwayCount),narrowestDoorway,
passed?"PASS":"FAIL");
Streamer.Stop();
return passed?0:14;
}
if(bAuditLiminalRoadWalk&&!bAuditResolvedLayoutPassages)
{
const bool passed=auditLiminalRoadWalk(true);
+103
View File
@@ -822,6 +822,109 @@ namespace StandaloneWorldAssemblyPrototype
return true;
}
inline bool BuildLiminalStampFixtureRequests(const VFJson::Value& root,
const FStandaloneOwnerWorld& owner,
const VoxelForgeCore::WorldAssemblyManifest& assembly,
const VoxelForgeCore::ResolvedLayoutSnapshotV3& layout,
std::vector<VoxelForgeCore::ResolvedLayoutStampRequestV1>& requests,
std::string& error)
{
using namespace VoxelForgeCore;
requests.clear();
const VFJson::Value& fixture=root.Get("liminal_stamp_fixture_override");
if(!fixture.IsObject()||!fixture.Get("version").IsNumber()
||fixture.Get("version").Integer()!=1||!fixture.Get("stamps").IsArray())
{error="liminal_stamp_fixture_override must be a version-1 object with a stamps array";return false;}
if(assembly.recipe.surfaceProfile.version!=1
||assembly.recipe.surfaceProfile.kind!=WorldAssemblySurfaceProfileKindV1::flatField
||owner.CoreVoxelSizeMicrons==0)
{error="liminal stamp fixtures require a valid flatField SurfaceWorld recipe";return false;}
const VFJson::Value& strateValue=fixture.Get("strate_index");
if(!strateValue.IsNumber())
{error="liminal stamp fixture must select a resolved SurfaceWorld strate";return false;}
const auto strateIndex=static_cast<std::int32_t>(strateValue.Integer());
const auto strate=std::find_if(layout.strates.begin(),layout.strates.end(),
[strateIndex](const auto& value){return value.strateIndex==strateIndex
&&value.generatorKind=="SurfaceWorld";});
if(strate==layout.strates.end())
{error="liminal stamp fixture strate is not a resolved SurfaceWorld strate";return false;}
const auto toMicrometres=[](double value)
{return static_cast<std::int64_t>(std::llround(value*1000000.0));};
const std::int64_t floorMicrometres=static_cast<std::int64_t>(std::llround(
static_cast<double>(assembly.recipe.surfaceProfile.h0Subvoxels)
*owner.CoreVoxelSizeMicrons/WorldAssemblySubvoxelsPerVoxel));
const auto readOptionalMetres=[&](const VFJson::Value& object,const char* key,
double fallback,double& result)
{
const VFJson::Value& value=object.Get(key);
if(std::holds_alternative<std::nullptr_t>(value.Data))
{result=fallback;return true;}
if(!value.IsNumber()||!std::isfinite(value.Number()))return false;
result=value.Number();return true;
};
for(const auto& entry:fixture.Get("stamps").AsArray())
{
if(!entry.IsObject())
{error="liminal stamp fixture contains a malformed stamp record";return false;}
const auto* id=std::get_if<std::string>(&entry.Get("stable_id").Data);
const auto* kind=std::get_if<std::string>(&entry.Get("kind").Data);
const VFJson::Value& anchor=entry.Get("anchor_xy_m");
const VFJson::Value& extents=entry.Get("half_extents_m");
double zOffset=0.0,rounding=0.0,smooth=0.0;
if(!id||id->empty()||!kind||anchor.AsArray().size()!=2
||extents.AsArray().size()!=3
||!readOptionalMetres(entry,"z_offset_m",0.0,zOffset)
||!readOptionalMetres(entry,"rounding_radius_m",0.0,rounding)
||!readOptionalMetres(entry,"smooth_width_m",0.0,smooth))
{error="liminal stamp fixture record requires an identity, kind, anchor, extents and finite metre values";return false;}
for(const auto& value:anchor.AsArray())
if(!value.IsNumber()||!std::isfinite(value.Number()))
{error="liminal stamp anchor_xy_m must contain finite metre values";return false;}
for(const auto& value:extents.AsArray())
if(!value.IsNumber()||!std::isfinite(value.Number())||value.Number()<=0.0)
{error="liminal stamp half_extents_m must contain positive finite metre values";return false;}
if(std::abs(anchor.AsArray()[0].Number())>5000.0
||std::abs(anchor.AsArray()[1].Number())>5000.0
||std::abs(zOffset)>1000.0||rounding<0.0||smooth<0.0)
{error="liminal stamp fixture values exceed their bounded ranges";return false;}
ResolvedLayoutStampRequestV1 request;
request.stableId=*id;request.strateIndex=strateIndex;
request.anchorPositionMicrometres={
toMicrometres(anchor.AsArray()[0].Number()),
toMicrometres(anchor.AsArray()[1].Number()),
floorMicrometres+toMicrometres(zOffset)};
request.halfExtentsMicrometres={toMicrometres(extents.AsArray()[0].Number()),
toMicrometres(extents.AsArray()[1].Number()),
toMicrometres(extents.AsArray()[2].Number())};
request.roundingRadiusMicrometres=toMicrometres(rounding);
request.smoothWidthMicrometres=toMicrometres(smooth);
const VFJson::Value& yaw=entry.Get("yaw_quarter_turns");
if(!std::holds_alternative<std::nullptr_t>(yaw.Data))
{
if(!yaw.IsNumber()||yaw.Integer()<0||yaw.Integer()>3)
{error="liminal stamp yaw_quarter_turns must be an integer from zero through three";return false;}
request.yawQuarterTurns=static_cast<std::uint8_t>(yaw.Integer());
}
if(*kind=="fillBox")request.kind=ResolvedSdfStampKindV1::fillBox;
else if(*kind=="carveBox")request.kind=ResolvedSdfStampKindV1::carveBox;
else if(*kind=="carveArch")request.kind=ResolvedSdfStampKindV1::carveArch;
else if(*kind=="fillSteps")
{
request.kind=ResolvedSdfStampKindV1::fillSteps;
const VFJson::Value& count=entry.Get("step_count");
if(!count.IsNumber()||count.Integer()<2||count.Integer()>128)
{error="fillSteps requires step_count from two through 128";return false;}
request.stepCount=static_cast<std::uint16_t>(count.Integer());
}
else
{error="liminal stamp kind must be fillBox, carveBox, carveArch or fillSteps";return false;}
requests.push_back(std::move(request));
}
if(requests.empty())
{error="liminal stamp fixture must resolve at least one stamp";return false;}
return true;
}
inline bool BuildCoreLiminalFieldRequests(
const VoxelForgeCore::WorldAssemblyManifest& assembly,
const FStandaloneOwnerWorld& owner,