saumwacht-godot/tools/verify_phase4_standalone.py
Martin Stickelbroeck c2b447610c Baseline: Saumwacht 0.15.0 (Phase 20A) vor dem Umbau zu Champions of Luneraria
Unveränderter Ausgangsstand inklusive Masterprompt und Konzeptbildern
unter assets/. .godot/ und docs/screenshots/ bleiben laut .gitignore
unversioniert; letztere sind unter ../backups gesichert.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-27 20:00:36 +02:00

82 lines
3.5 KiB
Python

"""Blender integration audit of copied standalone scripts and scene preservation.
Run in a separate process with --background --factory-startup --python-exit-code 1.
All generated test assets stay in a temporary directory, outside the project.
"""
from pathlib import Path
import json
import runpy
import shutil
import sys
import tempfile
import bpy
PROJECT = Path(__file__).resolve().parents[1]
CASES = [('melee', 'm04'), ('tank', 'g04'), ('ranged', 'w06'),
('artillery', 'n08'), ('support', 'w10'), ('mercenary', 's04'),
('worker', 'worker'), ('lane', 'map_lane_segment'), ('core', 'core_team1')]
def main():
previous_scene = bpy.context.scene
cube = bpy.data.objects['Cube']
cube.name = 'Body'
cube.location = (7, 8, 9)
material = bpy.data.materials.new('SW_glutpakt_primary_292B35')
material.diffuse_color = (.13, .27, .41, 1)
cube.data.materials.append(material)
old_color = tuple(material.diffuse_color)
old_slots = list(cube.data.materials)
old_objects = set(bpy.data.objects)
with tempfile.TemporaryDirectory(prefix='saumwacht-standalone-') as directory:
base = Path(directory)
scripts = base / 'scripts'
scripts.mkdir()
for source in (PROJECT / 'assets-source/phase4/standalone').glob('*.py'):
shutil.copy2(source, scripts / source.name)
def run(role, asset_id, keep=False):
script = scripts / ('create_' + role + '.py')
sys.argv = [str(script), '--', '--id', asset_id,
'--export-dir', str(base / 'exports'),
'--blend-dir', str(base / 'blend')]
if not keep:
sys.argv.append('--no-keep-scene')
runpy.run_path(str(script), run_name='__main__')
for role, asset_id in CASES:
run(role, asset_id)
assert bpy.context.scene == previous_scene, asset_id
assert set(bpy.data.objects) == old_objects, asset_id
assert tuple(cube.location) == (7, 8, 9), asset_id
assert tuple(material.diffuse_color) == old_color, asset_id
assert list(cube.data.materials) == old_slots, asset_id
assert (base / 'blend' / (asset_id + '.blend')).is_file(), asset_id
records = list(base.rglob(asset_id + '.json'))
assert len(records) == 1, (asset_id, records)
record = json.loads(records[0].read_text())
assert record['resource_path'] is None, asset_id
assert Path(record['export_path']).is_file(), asset_id
print('STANDALONE_ISOLATION_PASS: 9/9; original scene, objects and material preserved')
for _ in range(2):
run('melee', 'g01', keep=True)
assert len(bpy.data.scenes) == 3
assert set(previous_scene.objects) == old_objects
assert tuple(material.diffuse_color) == old_color
assert len([o for o in bpy.data.objects if o.name.startswith('Model_g01')]) == 2
print('KEEP_SCENE_PASS: two generated scenes and original scene retained')
bpy.ops.wm.open_mainfile(filepath=str(base / 'blend/n08.blend'))
assert len(bpy.data.scenes) == 1
objects = list(bpy.context.scene.objects)
assert all(o.type not in ('LIGHT', 'CAMERA') for o in objects)
assert any(o.name == 'Model_n08' for o in objects)
assert any(o.name == 'Forward' for o in objects)
assert not any(tuple(o.location) == (7, 8, 9) for o in objects)
print('NATIVE_BLEND_PASS: isolated N08 scene reopened;', len(objects), 'objects')
if __name__ == '__main__':
main()