extends SceneTree const Demo := preload("res://scripts/ui/pixel_tower_demo.gd") var checks := 0 var failures := 0 func _initialize() -> void: call_deferred("run") func expect(ok: bool, label: String) -> void: checks += 1 if not ok: failures += 1; push_error(label) func run() -> void: var runtime: Variant = root.get_node("SimulationRuntime") var clock: Variant = root.get_node("GameClock") var state: Variant = root.get_node("GameState") # Disposable Demo fixture funds exact Doran signing_cost 300; DEFAULT5000 and paid hire stay unchanged. clock.reset(1,6,0); state.reset();state.resources[&"gold"] += 300; runtime.initialize(clock,state,424242); clock.set_paused(true) runtime.configure_save_policy({&"enabled":false,&"daily_checkpoint_enabled":false}) verify_detached(runtime, "funded disposable initial fixture") var demo := Demo.new() expect(await demo.prepare(runtime,clock,self), "populated production fixture prepares") verify_detached(runtime, "populated game") var retained: Dictionary = runtime.create_snapshot() var original := retained.duplicate(true) clock.advance_minutes(15) expect(retained == original, "advancing live actors never changes a retained snapshot") var after: Dictionary = runtime.create_snapshot() expect(runtime.restore_snapshot(retained), "owned snapshot restores before deterministic replay") clock.advance_minutes(15) expect(runtime.create_snapshot() == after, "owned snapshot replays all subsystems identically") # Keep the general-purpose capture API's protective copy contract. var extra := {&"caller": {&"rows": [{&"value":1}]}} var generic: Dictionary = SimulationSnapshot.capture(clock,state,extra) extra[&"caller"][&"rows"][0][&"value"] = 2 expect(generic[&"systems"][&"caller"][&"rows"][0][&"value"] == 1, "general capture still detaches caller-owned extras") print("Snapshot ownership: %d checks, %d failures" % [checks,failures]);quit(failures) func verify_detached(runtime: Variant, stage: String) -> void: var expected: Dictionary = runtime.create_snapshot().duplicate(true) for section: Variant in expected[&"systems"][&"runtime"]: var candidate: Dictionary = runtime.create_snapshot() poison(candidate[&"systems"][&"runtime"][section]) expect(runtime.create_snapshot() == expected, "%s detached section: %s" % [stage,section]) if failures: return var candidate: Dictionary = runtime.create_snapshot() poison(candidate[&"clock"]);poison(candidate[&"game_state"]) expect(runtime.create_snapshot() == expected, "%s clock and resource snapshots remain detached" % stage) func poison(value: Variant) -> void: if value is Dictionary: for child: Variant in value.values(): poison(child) value.clear() value[&"ownership_probe"] = true elif value is Array: for child: Variant in value: poison(child) value.clear() match value.get_typed_builtin(): TYPE_NIL: value.append(null) TYPE_DICTIONARY: value.append({}) TYPE_ARRAY: value.append([]) TYPE_STRING: value.append("ownership_probe") TYPE_STRING_NAME: value.append(&"ownership_probe") TYPE_INT: value.append(99) TYPE_FLOAT: value.append(99.0) TYPE_BOOL: value.append(true) TYPE_VECTOR2I: value.append(Vector2i(99,99)) TYPE_VECTOR3I: value.append(Vector3i(99,99,99)) _: expect(false, "ownership probe covers typed snapshot array %s" % value.get_typed_builtin())