feat(core): ore vein records and a materialAt query, off by default (L50); research R18, R19
Versioned capsule vein records (stable ID, resource ID, endpoints, radius, seeded irregularity) resolved into the snapshot only when requested, placed beside the route and away from passages, landings and landmarks (forced-passage control rejected). The bound field table gains materialAt (host + two resource IDs + Q16 weights) behind a per-tile BVH; mesh export v2 carries per-vertex materials; a measurement-only yield computes removed resource volume (0 on already-air space). With veins on, every density, mesh, payload and topology hash is unchanged; demo off: owner hashes identical to L47. fast/medium/full PASS. Research R18 (cavern-graph planner) and R19 (why FloatingIslands costs ~10x SurfaceWorld). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016dhxM43dnWvUu2B5Ph1iG1
This commit is contained in:
1 parent
b9ccff4ad6
commit
ca85e876ad
15 files changed
+1573
-19
No files matched your search
@@ -56,6 +56,9 @@ TILE_HASH_RE = re.compile(
|
||||
r"^\[PipelineTileHash\] lod=(-?\d+) x=(-?\d+) y=(-?\d+) z=(-?\d+) "
|
||||
r"density=(0x[0-9a-f]+) mesh=(0x[0-9a-f]+) "
|
||||
r"payload=(0x[0-9a-f]+) topology=(0x[0-9a-f]+)$", re.M)
|
||||
TILE_MATERIAL_HASH_RE = re.compile(
|
||||
r"^\[PipelineTileMaterialHash\] lod=(-?\d+) x=(-?\d+) y=(-?\d+) z=(-?\d+) "
|
||||
r"material=(0x[0-9a-f]+)$", re.M)
|
||||
CAMERA_SWEEP_SEED = 0x4C3434
|
||||
RECIPE_RE = re.compile(
|
||||
r"^\[WorldAssemblerRecipeAudit\] requested=([^ ]+) actual=([^ ]+).*status=([^ ]+)$", re.M)
|
||||
@@ -428,6 +431,115 @@ def parse_tile_hashes(output: str) -> dict[tuple[int, int, int, int], tuple[str,
|
||||
return rows
|
||||
|
||||
|
||||
def parse_tile_material_hashes(output: str) -> dict[tuple[int, int, int, int], str]:
|
||||
rows: dict[tuple[int, int, int, int], str] = {}
|
||||
for match in TILE_MATERIAL_HASH_RE.finditer(output):
|
||||
key = tuple(int(match.group(i)) for i in range(1, 5))
|
||||
rows[key] = match.group(5)
|
||||
return rows
|
||||
|
||||
|
||||
def ore_vein_audit_camera(layout_path: Path) -> tuple[float, float, float, float, float]:
|
||||
layout = json.loads(layout_path.read_text(encoding="utf-8"))
|
||||
core_um = int(layout["core_voxel_size_um"])
|
||||
route = [anchor for strate in layout["strates"]
|
||||
if strate["generator_kind"] == "SurfaceWorld"
|
||||
for anchor in strate["anchors"] if anchor["kind"] == "route_point"]
|
||||
route.sort(key=lambda anchor: int(anchor["stable_id"].split("/")[-1]))
|
||||
records = layout.get("ore_veins", [])
|
||||
vein = next((row for row in records
|
||||
if row["stable_id"] == "ore/sw-arrival-route-copper-v1"), None)
|
||||
if len(route) < 2 or vein is None:
|
||||
raise VerificationFailure(f"cannot derive ore camera from {layout_path}")
|
||||
target = [sum(value) / 2_000_000.0 for value in zip(*vein["endpoints_um"])]
|
||||
points = [[value * core_um / 256_000_000.0 for value in anchor["values"][:3]]
|
||||
for anchor in route]
|
||||
best: tuple[float, int, float, tuple[float, float, float]] | None = None
|
||||
for index, (a, b) in enumerate(zip(points, points[1:])):
|
||||
dx, dy = b[0] - a[0], b[1] - a[1]
|
||||
length2 = dx * dx + dy * dy
|
||||
t = 0.0 if length2 <= 1.0e-12 else max(0.0, min(1.0,
|
||||
((target[0] - a[0]) * dx + (target[1] - a[1]) * dy) / length2))
|
||||
point = tuple(a[axis] + t * (b[axis] - a[axis]) for axis in range(3))
|
||||
distance2 = (point[0] - target[0]) ** 2 + (point[1] - target[1]) ** 2
|
||||
candidate = (distance2, index, t, point)
|
||||
if best is None or candidate[:3] < best[:3]:
|
||||
best = candidate
|
||||
assert best is not None
|
||||
_, _, _, floor = best
|
||||
camera = (floor[0], floor[1], floor[2] + 1.6)
|
||||
dx, dy = target[0] - camera[0], target[1] - camera[1]
|
||||
horizontal = max(math.hypot(dx, dy), 1.0e-6)
|
||||
target_z = target[2] + 1.0
|
||||
yaw = math.degrees(math.atan2(dx, dy))
|
||||
pitch = math.degrees(math.atan2(target_z - camera[2], horizontal))
|
||||
return (*camera, yaw, pitch)
|
||||
|
||||
|
||||
def run_ore_vein_hash_controls(runner: VerificationRunner) -> None:
|
||||
camera_layout = OUT / "layouts" / "ore-vein-camera-layout.json"
|
||||
row, output = runner.run_cpp("ore-vein-camera-layout", CLANG, OWNER,
|
||||
"surface-world", ["--landmark-chamber-demo", "--ore-veins-demo",
|
||||
"--resolved-layout-only"],
|
||||
expected_style=2, expected_strate_styles={"0": 2, "1": 1}, workers=1,
|
||||
max_level=0, layout_path=camera_layout)
|
||||
audit = re.search(r"^\[ResolvedOreVeinPlacementAudit\].*status=PASS$", output, re.M)
|
||||
runner.require("ore-vein-resolved-records", audit is not None,
|
||||
f"layout={row['layout_id']} resolved={len(json.loads(camera_layout.read_text()).get('ore_veins', []))}/3")
|
||||
x, y, z, yaw, pitch = ore_vein_audit_camera(camera_layout)
|
||||
camera_flag = f"--camera={x:.6f},{y:.6f},{z:.6f},{yaw:.3f},{pitch:.3f}"
|
||||
base_flags = ["--stream-hash-tiles", "--landmark-chamber-demo", camera_flag,
|
||||
"--clip-radius=2", "--max-clip-level=0", "--max-level=0",
|
||||
"--render-distance-chunks=0"]
|
||||
geometry: dict[str, dict[tuple[int, int, int, int], tuple[str, ...]]] = {}
|
||||
material: dict[str, dict[tuple[int, int, int, int], str]] = {}
|
||||
outputs: dict[str, str] = {}
|
||||
for label, enabled in (("off", False), ("on", True)):
|
||||
flags = [*base_flags]
|
||||
if enabled:
|
||||
flags.extend(("--ore-veins-demo", "--audit-ore-vein-yield"))
|
||||
_, captured = runner.run_cpp(f"ore-vein-geometry-{label}", CLANG, OWNER,
|
||||
"surface-world", flags, expected_style=2,
|
||||
expected_strate_styles={"0": 2, "1": 1}, workers=1,
|
||||
max_level=0, layout_path=OUT / "layouts" / f"ore-vein-geometry-{label}.json")
|
||||
outputs[label] = captured
|
||||
geometry[label] = parse_tile_hashes(captured)
|
||||
material[label] = parse_tile_material_hashes(captured)
|
||||
whole = re.search(r"^\[PipelineWholeViewHash\] tiles=(\d+)", captured, re.M)
|
||||
expected_rows = int(whole.group(1)) if whole else -1
|
||||
runner.require(f"ore-vein-geometry-{label}:hash-rows",
|
||||
bool(geometry[label]) and len(geometry[label]) == expected_rows
|
||||
and len(material[label]) == expected_rows,
|
||||
f"geometry_rows={len(geometry[label])} material_rows={len(material[label])} "
|
||||
f"expected={expected_rows}")
|
||||
cost = re.search(r"^\[MaterialQueryCost\] queries=(\d+) candidate_checks=(\d+) "
|
||||
r"outside_vein_tiles=(\d+) tiles=(\d+) elapsed_ms=([0-9.]+) "
|
||||
r"outside_query_ms=0 status=([^ ]+)$", captured, re.M)
|
||||
cost_ok = cost is not None and int(cost.group(1)) == 0 if not enabled else (
|
||||
cost is not None and int(cost.group(1)) > 0 and int(cost.group(3)) > 0
|
||||
and float(cost.group(5)) >= 0.0)
|
||||
runner.require(f"ore-vein-material-cost-{label}", cost_ok,
|
||||
f"cost_line={cost.group(0) if cost else 'MISSING'}")
|
||||
differing = [key for key in set(material["off"]) | set(material["on"])
|
||||
if material["off"].get(key) != material["on"].get(key)]
|
||||
runner.require("ore-vein-geometry-unchanged-with-veins",
|
||||
geometry["off"] == geometry["on"],
|
||||
f"camera_m=({x:.3f},{y:.3f},{z:.3f}) density/mesh/payload/topology "
|
||||
f"tile_hashes_match={geometry['off']==geometry['on']} "
|
||||
f"material_tiles_changed={len(differing)}")
|
||||
runner.require("ore-vein-material-hash-changes",
|
||||
bool(differing) and material["off"] != material["on"],
|
||||
f"changed_tiles={len(differing)} camera_m=({x:.3f},{y:.3f},{z:.3f})")
|
||||
mined = re.search(r"^\[OreMiningYield\].*resource_volume_m3=([0-9.]+) status=PASS$",
|
||||
outputs["on"], re.M)
|
||||
air = re.search(r"^\[OreMiningYieldControl\] case=already-air.*"
|
||||
r"resource_volume_m3=0\.000000 status=PASS$", outputs["on"], re.M)
|
||||
runner.require("ore-vein-yield-positive", mined is not None and float(mined.group(1)) > 0,
|
||||
"fixed 0.25 m sample spacing measured positive removed resource volume")
|
||||
runner.require("ore-vein-yield-already-air-zero", air is not None,
|
||||
"the same sphere measurement on the already-air chamber tunnel returned zero")
|
||||
|
||||
|
||||
def cavern_audit_cameras(layout_path: Path) -> list[tuple[float, float, float, float, float]]:
|
||||
layout = json.loads(layout_path.read_text(encoding="utf-8"))
|
||||
edges = layout.get("cavern_edges", [])
|
||||
@@ -473,6 +585,7 @@ def run_random_camera_sweep(runner: VerificationRunner, binaries: tuple[Path, ..
|
||||
label = (f"random-camera-{compiler}-{recipe}-s{CAMERA_SWEEP_SEED:06x}"
|
||||
f"-p{camera_index:02d}-r{clip_radius}-c{max_clip_level}-m{max_level}")
|
||||
signatures: dict[int, dict[tuple[int, int, int, int], tuple[str, ...]]] = {}
|
||||
material_signatures: dict[int, dict[tuple[int, int, int, int], str]] = {}
|
||||
for workers in (1, 8, 12):
|
||||
name = f"{label}-w{workers}"
|
||||
flags = ["--stream-hash-tiles", camera_flag,
|
||||
@@ -480,7 +593,7 @@ def run_random_camera_sweep(runner: VerificationRunner, binaries: tuple[Path, ..
|
||||
f"--max-clip-level={max_clip_level}",
|
||||
f"--max-level={max_level}", "--render-distance-chunks=0"]
|
||||
if recipe == "surface-world":
|
||||
flags.append("--landmark-chamber-demo")
|
||||
flags.extend(("--landmark-chamber-demo", "--ore-veins-demo"))
|
||||
row, output = runner.run_cpp(name, binary, OWNER, recipe, flags,
|
||||
expected_style=2,
|
||||
expected_strate_styles={"0": 2, "1": 1},
|
||||
@@ -496,11 +609,17 @@ def run_random_camera_sweep(runner: VerificationRunner, binaries: tuple[Path, ..
|
||||
}
|
||||
current = parse_tile_hashes(output)
|
||||
signatures[workers] = current
|
||||
material_signatures[workers] = parse_tile_material_hashes(output)
|
||||
whole = re.search(r"^\[PipelineWholeViewHash\] tiles=(\d+)", output, re.M)
|
||||
expected_rows = int(whole.group(1)) if whole else -1
|
||||
runner.require(f"{name}:tile-hash-rows",
|
||||
bool(current) and len(current) == expected_rows,
|
||||
f"rows={len(current)} expected={expected_rows} settings={settings}")
|
||||
if recipe == "surface-world":
|
||||
material_rows = material_signatures[workers]
|
||||
runner.require(f"{name}:material-hash-rows",
|
||||
bool(material_rows) and len(material_rows) == expected_rows,
|
||||
f"rows={len(material_rows)} expected={expected_rows} settings={settings}")
|
||||
camera_text = (f"seed=0x{CAMERA_SWEEP_SEED:06x} camera_m="
|
||||
f"({x:.3f},{y:.3f},{z:.3f}) recipe={recipe} settings={settings}")
|
||||
for left, right in ((1, 8), (1, 12), (8, 12)):
|
||||
@@ -517,12 +636,19 @@ def run_random_camera_sweep(runner: VerificationRunner, binaries: tuple[Path, ..
|
||||
topology_diff = [key for key in keys
|
||||
if left_rows.get(key, (None, None, None, None))[3]
|
||||
!= right_rows.get(key, (None, None, None, None))[3]]
|
||||
material_left=material_signatures[left]
|
||||
material_right=material_signatures[right]
|
||||
material_diff=([key for key in set(material_left)|set(material_right)
|
||||
if material_left.get(key)!=material_right.get(key)]
|
||||
if recipe=="surface-world" else [])
|
||||
detail = (f"{camera_text} W{left}=W{right} "
|
||||
f"density_tiles={len(density_diff)} mesh_tiles={len(mesh_diff)} "
|
||||
f"payload_tiles={len(payload_diff)} topology_tiles={len(topology_diff)} "
|
||||
f"material_tiles={len(material_diff)} "
|
||||
f"sample_coords={sorted(density_diff or mesh_diff)[:6]}")
|
||||
runner.require(f"{label}:W{left}-W{right}",
|
||||
left_rows == right_rows, detail)
|
||||
left_rows == right_rows and
|
||||
(recipe != "surface-world" or material_left == material_right), detail)
|
||||
|
||||
# Keep a pair of fixed cameras on the current owner graph: one in the bore and
|
||||
# one beside its curved wall. Their tile hashes join the seeded W1/W8/W12 sweep.
|
||||
@@ -536,10 +662,12 @@ def run_random_camera_sweep(runner: VerificationRunner, binaries: tuple[Path, ..
|
||||
camera_flag = f"--camera={x:.6f},{y:.6f},{z:.6f},{yaw:.3f},{pitch:.3f}"
|
||||
label = f"cavern-camera-{compiler}-s{CAMERA_SWEEP_SEED:06x}-p{camera_index:02d}"
|
||||
signatures: dict[int, dict[tuple[int, int, int, int], tuple[str, ...]]] = {}
|
||||
material_signatures: dict[int, dict[tuple[int, int, int, int], str]] = {}
|
||||
for workers in (1, 8, 12):
|
||||
name = f"{label}-w{workers}"
|
||||
row, output = runner.run_cpp(name, binary, OWNER, "surface-world",
|
||||
["--stream-hash-tiles", camera_flag, "--landmark-chamber-demo",
|
||||
"--ore-veins-demo",
|
||||
"--clip-radius=3", "--max-clip-level=0", "--max-level=0",
|
||||
"--render-distance-chunks=0"],
|
||||
expected_style=2,
|
||||
@@ -548,17 +676,24 @@ def run_random_camera_sweep(runner: VerificationRunner, binaries: tuple[Path, ..
|
||||
row["camera_position_m"] = [round(value, 6) for value in camera[:3]]
|
||||
row["camera_region"] = "inside-tunnel" if camera_index == 0 else "near-tunnel-wall"
|
||||
signatures[workers] = parse_tile_hashes(output)
|
||||
material_signatures[workers] = parse_tile_material_hashes(output)
|
||||
whole = re.search(r"^\[PipelineWholeViewHash\] tiles=(\d+)", output, re.M)
|
||||
expected_rows = int(whole.group(1)) if whole else -1
|
||||
runner.require(f"{name}:tile-hash-rows",
|
||||
bool(signatures[workers]) and len(signatures[workers]) == expected_rows,
|
||||
f"rows={len(signatures[workers])} expected={expected_rows} camera={camera[:3]}")
|
||||
runner.require(f"{name}:material-hash-rows",
|
||||
bool(material_signatures[workers])
|
||||
and len(material_signatures[workers]) == expected_rows,
|
||||
f"rows={len(material_signatures[workers])} expected={expected_rows} "
|
||||
f"camera={camera[:3]}")
|
||||
for left, right in ((1, 8), (1, 12), (8, 12)):
|
||||
runner.require(f"{label}:W{left}-W{right}",
|
||||
signatures[left] == signatures[right],
|
||||
signatures[left] == signatures[right]
|
||||
and material_signatures[left] == material_signatures[right],
|
||||
f"camera_m=({x:.3f},{y:.3f},{z:.3f}) "
|
||||
f"region={'inside' if camera_index == 0 else 'near'}-tunnel "
|
||||
f"W{left}=W{right} density/mesh/payload/topology tile hashes match")
|
||||
f"W{left}=W{right} density/mesh/payload/topology/material tile hashes match")
|
||||
|
||||
|
||||
def run_ring(runner: VerificationRunner, *, full: bool) -> None:
|
||||
@@ -904,6 +1039,7 @@ def run_medium_suite(runner: VerificationRunner, *, both_compilers: bool = False
|
||||
run_transitions_and_invariants(runner, binaries)
|
||||
run_ring(runner, full=True)
|
||||
run_captures_and_mesh_audits(runner)
|
||||
run_ore_vein_hash_controls(runner)
|
||||
run_random_camera_sweep(runner, (CLANG,), 5,
|
||||
((3, 0, 0), (2, 1, 1), (3, 2, 1)))
|
||||
|
||||
@@ -939,6 +1075,7 @@ def main() -> int:
|
||||
run_landmark_reachability(runner, (CLANG,))
|
||||
run_regression_controls(runner)
|
||||
run_hash_pairs(runner, owners)
|
||||
run_ore_vein_hash_controls(runner)
|
||||
run_random_camera_sweep(runner, (CLANG,), 3, ((3, 0, 0),))
|
||||
run_ring(runner, full=False)
|
||||
elif ARGS.tier == "medium":
|
||||
|
||||
Reference in new issue
Block a user