captures: readable player-view captures with a coverage gate (L69); R36 native-generator survey
- Capture exports now cover a 90-degree player frustum (radius 3, LOD 0-8, overlap patches); a 17x9 ray coverage probe aborts before rendering if tiles are missing (truncated-mesh control: 480 uncovered samples, rejected). Clear colour is sky blue, so un-meshed space can't pass as dark rock. 16 views of the owner's four-strate plan. - Explore commandlet: finite XYZ spawn override for traces (Source/, Linux-compiled). - In-engine four-strate trace NOT obtained: the engine-generated plan fails passage validation at a solid centerline voxel (~(-43,-34.5,-448.5) m) while the headless owner_world.json plan passes. Engine and headless plans diverge. - R36 (read-only): order TN -> VS -> FI for native migration; native FI is reachable from the adapter but not selected in the owner run, cause unknown. 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
bd7bba994c
commit
81e2452a3d
24 files changed
+1011
-5
No files matched your search
@@ -0,0 +1,96 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Run three interleaved UE startup traces at each owner-plan arrival."""
|
||||
import subprocess
|
||||
import time
|
||||
import json
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
ROOT = Path(__file__).resolve().parents[4]
|
||||
HOST = Path("/home/jahni/VFHost")
|
||||
PLUGIN_SAVED = ROOT / "Saved/Linux/l69"
|
||||
HOST_PLUGIN_SAVED = HOST / "Plugins/VoxelForge/Saved/Linux/l69"
|
||||
OWNER_WORLD = ROOT / "Standalone/data/owner_world.json"
|
||||
OWNER_MANIFEST = HOST_PLUGIN_SAVED / "owner_world_manifest.json"
|
||||
EDITOR = Path("/home/jahni/UnrealEngine/Engine/Binaries/Linux/UnrealEditor-Cmd")
|
||||
TRACES = PLUGIN_SAVED / "traces"
|
||||
HOST_SAVED = HOST / "Saved/Linux/l69"
|
||||
SPAWNS_M = {
|
||||
0: (0.0, 0.0, -374.939453),
|
||||
1: (25.836914, 3.199219, -737.0),
|
||||
2: (19.166016, -14.200195, -753.374023),
|
||||
3: (-20.0625, -5.068359, -900.353516),
|
||||
}
|
||||
ORDER = ((0, 1), (1, 1), (2, 1), (3, 1),
|
||||
(1, 2), (2, 2), (3, 2), (0, 2),
|
||||
(2, 3), (3, 3), (0, 3), (1, 3))
|
||||
|
||||
|
||||
def run(strate, trial):
|
||||
label = f"strate{strate}-trial{trial}"
|
||||
trace = TRACES / f"{label}.trace.jsonl"
|
||||
abslog = TRACES / f"{label}.log"
|
||||
stdout = TRACES / f"{label}.stdout.log"
|
||||
output = HOST_PLUGIN_SAVED / "output" / label
|
||||
userdir = HOST_SAVED / label / "User"
|
||||
zendata = HOST_SAVED / label / "Zen"
|
||||
ddc = HOST_SAVED / "DDC"
|
||||
for directory in (output, userdir, zendata, ddc, TRACES):
|
||||
directory.mkdir(parents=True, exist_ok=True)
|
||||
spawn_cm = ",".join(f"{value * 100.0:.3f}" for value in SPAWNS_M[strate])
|
||||
command = [
|
||||
str(EDITOR), str(HOST / "VFHost.uproject"), "-nullrhi", "-unattended",
|
||||
"-nop4", "-nosplash", "-NoSound", "-corelimit=12", "-NoZenAutoLaunch",
|
||||
"-notraceserver", "-nocrashreports", "-ddc=NoZenLocalFallback",
|
||||
f"-userdir={userdir}", f"-ZenDataPath={zendata}", f"-LocalDataCachePath={ddc}",
|
||||
"-run=VoxelForgeExplore", "-seed=0", "-archetype=TunnelNetwork", "-slot=0",
|
||||
"-modes=export", "-gameconfig=1", "-coreworldtest=1", "-ownerfourstrateplan=1",
|
||||
"-corevoxelsizecm=25", "-coreislandtest=0", "-corefallbacktest=0",
|
||||
"-coreofftest=0", "-coreplantest=0",
|
||||
"-settingsref=/Game/VoxelForge/DA_Settings.DA_Settings", "-corehybridmesher=0",
|
||||
f"-coreworldassembly={OWNER_MANIFEST}",
|
||||
f"-out={output}",
|
||||
"-voxel.StreamingCoarseFirst=0", "-voxel.StreamingDynamicNearReserve=1",
|
||||
"-voxel.StreamingLegacyPendingResultCap=0", "-voxel.CoreRegionConcurrentAdmission=1",
|
||||
"-voxel.StreamingResultBacklogCap=256", "-voxel.StreamingReadyQueueDepth=8",
|
||||
"-voxel.StreamingBackgroundWorkerCap=1", "-voxel.CoreColumnCacheDirectMapped=0",
|
||||
"-voxel.CoreMCGradientMemoization=1", "-voxel.StreamingCollisionLookahead=1",
|
||||
"-coreworldstreamtrace=1", "-voxel.TestMove=0",
|
||||
"-voxel.TestMoveSpeedCmPerSecond=0", f"-voxel.StartupTraceSpawnCm={spawn_cm}",
|
||||
f"-voxel.StartupTraceFile={trace}", "-voxel.StartupTraceUntilEndPlay=1",
|
||||
"-voxel.StartupTraceMaxTiles=16384", "-voxel.CollisionGate=0",
|
||||
f"-abslog={abslog}",
|
||||
]
|
||||
wrapped = ["taskset", "-c", "0-11", "prlimit", "--rss=6442450944", "--",
|
||||
"timeout", "1740s", *command]
|
||||
started = time.monotonic()
|
||||
with stdout.open("w", encoding="utf-8") as stream:
|
||||
result = subprocess.run(wrapped, cwd=ROOT, stdout=stream,
|
||||
stderr=subprocess.STDOUT, timeout=1740, check=False)
|
||||
elapsed = time.monotonic() - started
|
||||
print(f"[L69EngineTrace] label={label} spawn_cm={spawn_cm} elapsed_s={elapsed:.2f} "
|
||||
f"exit={result.returncode} trace={trace} stdout={stdout}", flush=True)
|
||||
if result.returncode != 0:
|
||||
raise SystemExit(f"{label} failed; inspect {stdout} and {abslog}")
|
||||
if not trace.is_file() or trace.stat().st_size == 0:
|
||||
raise SystemExit(f"{label} exited successfully but produced no startup trace")
|
||||
|
||||
|
||||
def main():
|
||||
if not EDITOR.is_file():
|
||||
raise SystemExit(f"missing UE commandlet executable: {EDITOR}")
|
||||
HOST_PLUGIN_SAVED.mkdir(parents=True, exist_ok=True)
|
||||
owner = json.loads(OWNER_WORLD.read_text(encoding="utf-8"))
|
||||
assembly = owner.get("settings_asset", {}).get("WorldAssemblyManifestJson")
|
||||
if not isinstance(assembly, str) or not assembly:
|
||||
raise SystemExit(f"{OWNER_WORLD} has no serialized world-assembly manifest")
|
||||
OWNER_MANIFEST.write_text(assembly + "\n", encoding="utf-8")
|
||||
print(f"[L69EngineTracePlan] source={OWNER_WORLD} manifest={OWNER_MANIFEST} "
|
||||
f"bytes={OWNER_MANIFEST.stat().st_size}", flush=True)
|
||||
for strate, trial in ORDER:
|
||||
run(strate, trial)
|
||||
print("[L69EngineTraceSet] strata=4 trials_each=3 total=12 status=PASS", flush=True)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in new issue
Block a user