extends SceneTree const PathType = preload("res://scripts/world/path_service.gd") const LegacyType = preload("res://scripts/world/legacy_stair_service.gd") class ControlledPath: extends PathService var fail_restore_once := false var fail_restore_always := false var reenter: LegacyStairService var nested_rejected := false func restore_snapshot(snapshot: Dictionary) -> bool: var result := super.restore_snapshot(snapshot) if reenter != null: var target := reenter reenter = null nested_rejected = not target.migrate_existing_vertical_walks() if fail_restore_always: set_vertical_walk_requires_connector(not get_vertical_walk_requires_connector()) return false if fail_restore_once: fail_restore_once = false return false return result var _checks := 0 var _failures := 0 func _initialize() -> void: call_deferred("_run") func _run() -> void: _test_one_time_migration_and_access() _test_prune_and_no_regeneration() _test_snapshot_ownership() _test_atomic_failure_and_reentry() print("Legacy stairs: %d checks, %d failures" % [_checks, _failures]) quit(_failures) func _test_one_time_migration_and_access() -> void: var path := PathType.new() var cells: Array[Vector3i] = [Vector3i(0, 0, 0), Vector3i(0, 1, 0), Vector3i(0, 2, 0), Vector3i(1, 0, 0), Vector3i(1, 1, 0), Vector3i(2, 0, 0), Vector3i(2, 1, 0), Vector3i(0, 0, 1), Vector3i(0, 1, 1)] _expect(path.rebuild_graph(cells), "materialize legacy floors") _expect(path.configure_connector(&"staff.door", Vector3i(0, 0, 0), Vector3i(0, 0, 1), 120, true, &"staff"), "existing staff door remains separately owned") _expect(path.configure_connector(&"external.express", Vector3i(0, 0, 0), Vector3i(0, 1, 0), 50, false, &"permit"), "existing cheaper one-way connector coexists with WALK") var shaft_cells: Array[Vector3i] = [Vector3i(2, 0, 0), Vector3i(2, 1, 0)] _expect(path.set_vertical_walk_blockers(&"infra.shaft:lift", shaft_cells), "existing elevator shaft suppresses ordinary climbing") _expect(path.set_cell_temporary_block(Vector3i(1, 1, 0), true), "temporary traffic block does not remove structural connection") _expect(path.project_occupancy([{&"actor_id": &"staff:porter", &"cell": Vector3i(0, 0, 1)}]), "preserve existing occupancy during migration") var before := path.create_snapshot() var legacy := LegacyType.new() _expect(legacy.configure(path), "bind legacy owner") _expect(legacy.migrate_existing_vertical_walks(), "one migration materializes ordinary vertical WALK edges") var snapshot := legacy.create_snapshot() _expect(snapshot[&"stairs"].size() == 4, "both FRONT and BACK WALK edges convert once, without shaft bypass") _expect(path.get_vertical_walk_requires_connector() and legacy.validate_invariants()[&"ok"], "migration enables strict floor policy") _expect(path.has_connector(&"legacy.stairs:0:0:0") and path.has_connector(&"legacy.stairs:0:0:1"), "stable IDs encode layer, x and lower floor") _expect(not path.has_connector(&"legacy.stairs:0:2:0"), "shaft has no free compatibility stairs") _expect(path.get_connector(&"legacy.stairs:0:1:0")[&"cost"] == 100, "temporary blocked route still migrates at original WALK score") _expect(path.get_connector(&"legacy.stairs:1:0:0")[&"access_id"] == &"", "legacy BACK route keeps its previous access semantics") _expect(path.get_connector(&"staff.door") == _connector(before, &"staff.door"), "staff door cost and permission are unchanged") _expect(path.get_connector(&"external.express") == _connector(before, &"external.express"), "one-way custom connector retains exact configuration") var after := path.create_snapshot() for key: StringName in [&"cell_traffic", &"actor_cells", &"actor_progress", &"vertical_walk_blockers", &"active_elevator_units", &"known_elevator_request_ids", &"transit_actor_ids", &"traffic_revision"]: _expect(after[key] == before[key], "migration preserves unrelated Path field %s" % key) _expect(path.find_path(Vector3i(0, 0, 0), Vector3i(0, 2, 0), [0], []).size() == 3, "ordinary guests retain their old multi-floor route") _expect(path.find_path(Vector3i(0, 0, 0), Vector3i(0, 1, 1), [0, 1], []).is_empty(), "migration does not bypass staff-door access") _expect(not path.find_path(Vector3i(0, 0, 0), Vector3i(0, 1, 1), [0, 1], [&"staff"]).is_empty(), "staff keep cross-layer commute via original door") _expect(legacy.migrate_existing_vertical_walks() and legacy.create_snapshot() == snapshot and path.create_snapshot() == after, "repeat migration is an exact no-op") cells.append(Vector3i(0, 3, 0)) _expect(path.rebuild_graph(cells), "append newly built upper corridor after migration") _expect(legacy.migrate_existing_vertical_walks() and legacy.create_snapshot() == snapshot, "new vertical adjacency never receives compatibility stairs") _expect(path.find_path(Vector3i(0, 2, 0), Vector3i(0, 3, 0)).is_empty(), "new floors require a real stair or elevator") snapshot[&"stairs"].clear() _expect(legacy.create_snapshot()[&"stairs"].size() == 4, "snapshot returns defensive metadata") func _test_prune_and_no_regeneration() -> void: var path := PathType.new() var cells: Array[Vector3i] = [Vector3i(0, 0, 0), Vector3i(0, 1, 0), Vector3i(0, 2, 0), Vector3i(1, 0, 0), Vector3i(1, 1, 0)] path.rebuild_graph(cells) var legacy := LegacyType.new() legacy.configure(path) _expect(legacy.migrate_existing_vertical_walks(), "migrate prune fixture") cells.erase(Vector3i(0, 1, 0)) _expect(path.rebuild_graph(cells), "demolish middle landing") _expect(not legacy.validate_invariants()[&"ok"], "missing landing marks legacy ownership stale until prune") _expect(legacy.prune_invalid(), "prune both incident stair edges atomically") _expect(legacy.create_snapshot()[&"stairs"].size() == 1 and not path.has_connector(&"legacy.stairs:0:0:0") and not path.has_connector(&"legacy.stairs:0:0:1"), "removed landing retires both owned connector records") cells.append(Vector3i(0, 1, 0)) _expect(path.rebuild_graph(cells) and legacy.prune_invalid(), "rebuild same coordinates after demolition") _expect(path.find_path(Vector3i(0, 0, 0), Vector3i(0, 2, 0)).is_empty(), "retired links never resurrect at reused coordinates") var blocked: Array[Vector3i] = [Vector3i(1, 1, 0)] _expect(path.set_vertical_walk_blockers(&"new.shaft", blocked), "new elevator shaft covers remaining landing") _expect(legacy.prune_invalid() and legacy.create_snapshot()[&"stairs"].is_empty(), "new shaft removes touching compatibility connector") _expect(path.remove_vertical_walk_blockers(&"new.shaft") and legacy.prune_invalid(), "remove elevator shaft later") _expect(not path.has_connector(&"legacy.stairs:0:1:0"), "removing a shaft does not restore compatibility stairs") var before := path.create_snapshot() _expect(legacy.prune_invalid() and path.create_snapshot() == before, "unchanged prune does not advance graph revision") path.set_vertical_walk_requires_connector(false) before = path.create_snapshot() _expect(not legacy.migrate_existing_vertical_walks() and not legacy.prune_invalid(), "policy tampering cannot restart closed migration") _expect(path.create_snapshot() == before, "rejected repeated migration does not mutate tampered Path") func _test_snapshot_ownership() -> void: var path := PathType.new() var cells: Array[Vector3i] = [Vector3i(-1, -1, 0), Vector3i(-1, 0, 0), Vector3i(2, 0, 1), Vector3i(2, 1, 1)] path.rebuild_graph(cells) var legacy := LegacyType.new() legacy.configure(path) _expect(legacy.migrate_existing_vertical_walks(), "migrate negative floor and BACK snapshot fixture") var saved_path := path.create_snapshot() var saved := legacy.create_snapshot() var restored_path := PathType.new() var restored := LegacyType.new() _expect(restored.configure(restored_path), "bind destination before restoring Path") _expect(restored_path.restore_snapshot(saved_path) and restored_path.rebuild_graph(cells), "restore and materialize saved Path") _expect(restored.restore_snapshot(saved) and restored.create_snapshot() == saved, "strict current legacy snapshot roundtrip") var malformed: Array[Dictionary] = [] var row := saved.duplicate(true) row[&"extra"] = true malformed.append(row) row = saved.duplicate(true) row[&"schema_version"] = 2 malformed.append(row) row = saved.duplicate(true) row[&"schema_version"] = "1" malformed.append(row) row = saved.duplicate(true) row[&"stairs"].reverse() malformed.append(row) row = saved.duplicate(true) row[&"stairs"].append(row[&"stairs"][0].duplicate(true)) malformed.append(row) row = saved.duplicate(true) row[&"stairs"][0][&"id"] = "legacy.stairs:forged" malformed.append(row) row = saved.duplicate(true) row[&"stairs"][0][&"to"] = Vector3i(-1, 1, 0) malformed.append(row) row = saved.duplicate(true) row[&"stairs"][0][&"to"] = Vector3i(-1, 0, 1) malformed.append(row) row = saved.duplicate(true) row[&"stairs"][0][&"cost"] = 100 malformed.append(row) row = saved.duplicate(true) row[&"stairs"].clear() malformed.append(row) for bad: Dictionary in malformed: _expect(not restored.restore_snapshot(bad), "reject malformed or incomplete compatibility ownership") _expect(restored.create_snapshot() == saved and restored_path.create_snapshot() == saved_path, "legacy snapshot rejection preserves metadata and Path exactly") restored_path.configure_connector(&"legacy.stairs:orphan", cells[0], cells[1]) _expect(not restored.restore_snapshot(saved) and not restored.prune_invalid(), "untracked managed connector blocks restore and prune") restored_path.remove_connector(&"legacy.stairs:orphan") restored_path.configure_connector(&"legacy.stairs:0:-1:-1", cells[0], cells[1], 100, true, &"staff") _expect(not restored.restore_snapshot(saved) and not restored.prune_invalid(), "owned connector permission tampering is rejected") _expect(restored_path.restore_snapshot(saved_path), "repair exact connector configuration") restored_path.set_vertical_walk_requires_connector(false) _expect(not restored.restore_snapshot(saved), "current legacy snapshot cannot restore with free vertical walking") var fresh_path := PathType.new() fresh_path.rebuild_graph(cells) fresh_path.set_vertical_walk_requires_connector(true) var fresh := LegacyType.new() fresh.configure(fresh_path) _expect(fresh.migrate_existing_vertical_walks() and fresh.create_snapshot()[&"stairs"].is_empty(), "new strict game never gains migration stairs") _expect(fresh.restore_snapshot({&"schema_version": 1, &"stairs": []}), "new game empty legacy snapshot is valid") var out_of_bounds_path := PathType.new() out_of_bounds_path.rebuild_graph([Vector3i(100_001, 0, 0), Vector3i(100_001, 1, 0)]) var out_of_bounds := LegacyType.new() out_of_bounds.configure(out_of_bounds_path) var out_of_bounds_before := out_of_bounds_path.create_snapshot() _expect(not out_of_bounds.migrate_existing_vertical_walks() and out_of_bounds_path.create_snapshot() == out_of_bounds_before, "unsupported migration coordinates cannot create unrestorable records") func _test_atomic_failure_and_reentry() -> void: var path := ControlledPath.new() var cells: Array[Vector3i] = [Vector3i(0, 0, 0), Vector3i(0, 1, 0), Vector3i(0, 2, 0)] path.rebuild_graph(cells) var legacy := LegacyType.new() legacy.configure(path) var before := path.create_snapshot() var metadata := legacy.create_snapshot() path.fail_restore_once = true _expect(not legacy.migrate_existing_vertical_walks(), "injected partial Path apply failure rejects migration") _expect(path.create_snapshot() == before and legacy.create_snapshot() == metadata, "failed migration restores Path and owned metadata exactly") path.reenter = legacy _expect(legacy.migrate_existing_vertical_walks() and path.nested_rejected, "outer migration succeeds while nested migration is rejected") cells.erase(Vector3i(0, 1, 0)) path.rebuild_graph(cells) before = path.create_snapshot() metadata = legacy.create_snapshot() path.fail_restore_once = true _expect(not legacy.prune_invalid(), "injected partial prune failure rejects ownership removal") _expect(path.create_snapshot() == before and legacy.create_snapshot() == metadata, "failed prune restores both dangling records and original Path for caller rollback") _expect(legacy.prune_invalid(), "prune can retry after exact rollback") var broken_path := ControlledPath.new() broken_path.rebuild_graph([Vector3i(0, 0, 0), Vector3i(0, 1, 0)]) var broken := LegacyType.new() broken.configure(broken_path) broken_path.fail_restore_always = true _expect(not broken.migrate_existing_vertical_walks(), "repeated rollback failure rejects migration") _expect(broken.validate_invariants()[&"quarantined"] and not broken.migrate_existing_vertical_walks(), "uncertain rollback quarantines future mutation") func _connector(snapshot: Dictionary, connector_id: StringName) -> Dictionary: for connector: Dictionary in snapshot[&"connectors"]: if StringName(connector[&"id"]) == connector_id: return connector return {} func _expect(ok: bool, label: String) -> void: _checks += 1 if not ok: _failures += 1 push_error(label)