Separate map projects and add reusable island and operator camera tools

This commit is contained in:
Emil
2026-09-13 20:43:42 +03:00
parent 89c53d7058
commit 224b29f0e7
158 changed files with 633 additions and 34966 deletions
-60
View File
@@ -1,60 +0,0 @@
#!/usr/bin/env python3
"""Compare every live map column to the planned visible result and inspect hidden water."""
import argparse
from collections import defaultdict
import importlib.util
import json
from pathlib import Path
ROOT=Path(__file__).resolve().parents[1]
def main():
p=argparse.ArgumentParser(description=__doc__)
p.add_argument('--before',type=Path,required=True);p.add_argument('--after',type=Path,required=True)
p.add_argument('--layout',type=Path,action='append',required=True);p.add_argument('--report',type=Path,required=True)
args=p.parse_args();before=json.loads(args.before.read_text());after=json.loads(args.after.read_text())
for key in ('world_uuid','min_x','max_x','min_z','max_z','width','length'):
if before[key]!=after[key]:raise ValueError('Map scopes differ: '+key)
w=before['width'];expected_y=before['surface_y'].copy()
expected_m=[before['palette'][i] for i in before['material_index']]
original_m=expected_m.copy();targets=set();planned_blocks=0
for path in args.layout:
layout=json.loads(path.read_text())
if layout['scope']['world_id']!=before['world_uuid']:raise ValueError('Layout world differs')
for b in sorted(layout['blocks'],key=lambda b:b['y']):
i=(b['z']-before['min_z'])*w+b['x']-before['min_x'];targets.add((b['x'],b['y'],b['z']));planned_blocks+=1
if b['y']>=expected_y[i]:expected_y[i]=b['y'];expected_m[i]=b['block']
observed=[after['palette'][i] for i in after['material_index']]
mismatches=[i for i in range(len(expected_y)) if expected_y[i]!=after['surface_y'][i] or expected_m[i]!=observed[i]]
if mismatches:raise ValueError(f'{len(mismatches)} unexpected surface columns; first indices {mismatches[:8]}')
hidden_water=defaultdict(list)
for i,material in enumerate(original_m):
if material=='minecraft:water' and observed[i]!='minecraft:water':
x=i%w+before['min_x'];z=i//w+before['min_z'];y=before['surface_y'][i]
hidden_water[(x//16,z//16,y)].append((x,y,z))
spec=importlib.util.spec_from_file_location('terrain',ROOT/'scripts/terrain.py')
terrain=importlib.util.module_from_spec(spec);spec.loader.exec_module(terrain)
backend=terrain.Backend(ROOT/'.runtime/server/plugins/MinecraftBuilderMCP/config.yml')
context=backend.call('project_context')
if context['world_id']!=before['world_uuid']:raise ValueError('Live verification world differs')
verified_water=0
for points in hidden_water.values():
lo={axis:min(point[j] for point in points) for j,axis in enumerate(('x','y','z'))}
hi={axis:max(point[j] for point in points) for j,axis in enumerate(('x','y','z'))}
read=backend.call('region_inspect',min=lo,max=hi,detail='blocks')
states={tuple(b['pos'][axis] for axis in ('x','y','z')):b['state'] for b in read['blocks']}
for point in points:
if not states[point].startswith('minecraft:water['):raise ValueError('Water changed beneath a marker: '+str(point))
verified_water+=1
report={'world':before['world'],'source':'live Paper surface maps + bounded RPC water reads',
'verified_surface_columns':len(expected_y),'surface_mismatches':0,
'unique_marker_blocks':len(targets),'planned_writes':planned_blocks,
'original_water_columns':original_m.count('minecraft:water'),'water_columns_obscured_by_markers':verified_water,
'water_obscured_by_markers_verified_intact':True,
'height_unchanged_columns':sum(a==b for a,b in zip(before['surface_y'],after['surface_y'])),
'capture_started_at':after['capture_started_at'],'capture_finished_at':after['capture_finished_at'],
'atomic_snapshot':False,'note':'World edits were idle during each capture. Terrain follows its original heights; raised markers represent future structures, not finished traversable paths.'}
args.report.parent.mkdir(parents=True,exist_ok=True);args.report.write_text(json.dumps(report,indent=2)+'\n')
print(json.dumps(report))
if __name__=='__main__':main()