extends RefCounted ## Sparse whole typed captures. No acceptance flags and no truncation. const Codec := preload("res://tests/fixtures/p08-02/mixed_world.gd") var directory: String var manifest: FileAccess var observer: MotionObserver class MotionObserver extends Node: var view: WorldPreview var frames: Array = [] var elapsed := 0.0 var scaled_elapsed := 0.0 func _ready() -> void: RenderingServer.frame_post_draw.connect(after_draw) func _process(delta: float) -> void: elapsed += delta var clock := get_node_or_null("/root/GameClock") if clock == null or not bool(clock.get("paused")): scaled_elapsed += delta * maxf(float(clock.get("speed")) if clock != null else 1.0, 0.0) func after_draw() -> void: if not is_instance_valid(view): return var report := view.get_life_observation_report() if report.is_empty(): return var sample := {} for key: String in ["animation_time", "paused", "layer", "zoom", "pan", "viewport", "actor_tracks", "elevator_tracks", "actor_drawings", "cabins"]: sample[key] = report[key] if not frames.is_empty() and sample == frames[-1]["display"] and not sample["paused"]: return # Keep only two draw frames, never whole Runtime copies per frame. frames.append({"frame": Engine.get_process_frames(), "delta": elapsed, "scaled_delta": scaled_elapsed, "display": sample}) if frames.size() > 2: frames.pop_front() elapsed = 0.0 scaled_elapsed = 0.0 func _exit_tree() -> void: if RenderingServer.frame_post_draw.is_connected(after_draw): RenderingServer.frame_post_draw.disconnect(after_draw) func watch(view: WorldPreview) -> void: observer = MotionObserver.new() observer.view = view view.add_child(observer) func open(path: String) -> bool: directory = path if DirAccess.dir_exists_absolute(path): return false if DirAccess.make_dir_recursive_absolute(path.path_join("objects")) != OK: return false manifest = FileAccess.open(path.path_join("manifest.jsonl"), FileAccess.WRITE) return manifest != null func object(value: Variant) -> String: var text := JSON.stringify(Codec.new().typed(value)) + "\n" var digest := text.sha256_text() var path := directory.path_join("objects").path_join(digest + ".json") if FileAccess.file_exists(path): return digest if FileAccess.get_sha256(path) == digest else "" var file := FileAccess.open(path, FileAccess.WRITE) if file == null: return "" file.store_string(text) file.close() return digest if FileAccess.get_sha256(path) == digest else "" func capture(label: String, runtime: Variant, view: WorldPreview) -> bool: if manifest == null: return false var state: Dictionary = runtime.create_snapshot() var report := view.get_life_observation_report() var state_hash := object(state) var report_hash := object(report) var audit_hash := object(rest_audit(runtime)) var motion_hash := object({"frames": observer.frames.duplicate(true) if is_instance_valid(observer) else []}) var after: Dictionary = runtime.create_snapshot() var after_hash := object(after) if state_hash.is_empty() or report_hash.is_empty() or audit_hash.is_empty(): return false manifest.store_line(JSON.stringify({"label": label, "pid": OS.get_process_id(), "ticks_usec": Time.get_ticks_usec(), "state": state_hash, "report": report_hash, "rest_audit": audit_hash, "motion": motion_hash, "state_after": after_hash, "input_method": "diagnostic", "acceptance": "pending"})) manifest.flush() return var_to_bytes(state) == var_to_bytes(after) func close() -> void: if manifest != null: manifest.close() manifest = null # Public selection inputs; Runtime output is only a comparison operand. func rest_audit(runtime: Variant) -> Dictionary: var rows: Array = [] for member: StaffRuntime in runtime.staff_service.get_staff_members(): var memberships: Array = [] for raid_id: StringName in runtime.defense_service.get_raid_ids(): var raid: Dictionary = runtime.defense_service.get_raid(raid_id) if raid.get(&"combatants", {}).has(member.staff_id): memberships.append({"raid_id": raid_id, "state": DefenseService.RaidState.keys()[raid[&"state"]], "side": raid[&"combatants"][member.staff_id].get(&"side", &"")}) var facilities: Array = [] for room: FacilityInstance in runtime.facility_service.get_instances(): var probes: Array = [] var candidates: Dictionary = {} var occupied := room.occupied_cells.duplicate() if occupied.is_empty(): occupied.append(room.origin) for cell: Vector3i in occupied: for delta: Vector3i in [Vector3i.ZERO, Vector3i.LEFT, Vector3i.RIGHT]: var present: bool = runtime.path_service.has_cell(cell + delta) probes.append({"cell": cell + delta, "has_cell": present}) if present: candidates[cell + delta] = true var ordered: Array = candidates.keys() ordered.sort_custom(func(a: Vector3i, b: Vector3i) -> bool: if a.z != b.z: return a.z < b.z if a.y != b.y: return a.y < b.y return a.x < b.x) var routes: Array = [] for cell: Vector3i in ordered: var path: Array = runtime.path_service.find_path(member.current_cell, cell, [WorldService.LAYER_FRONT, WorldService.LAYER_BACK], [&"staff"]) var edges: Array = [] for index: int in range(1, path.size()): # Empty reports remain explicit mismatch evidence. edges.append(runtime.path_service.get_edge_report(path[index - 1], path[index], [&"staff"])) routes.append({"cell": cell, "path": path, "edges": edges, "calculate_path_cost": runtime.path_service.calculate_path_cost(path, [&"staff"]) if not path.is_empty() else -1}) facilities.append({"instance_id": room.instance_id, "definition_id": room.definition_id, "operation_state": FacilityInstance.OperationState.keys()[room.operation_state], "origin": room.origin, "occupied_cells": room.occupied_cells.duplicate(), "probes": probes, "ordered": ordered, "routes": routes}) rows.append({"staff_id": member.staff_id, "state": StaffRuntime.State.keys()[member.state], "health": member.health, "current_task_id": member.current_task_id, "current_cell": member.current_cell, "defense_memberships": memberships, "actor_lock": runtime.event_service.get_actor_locks().has(member.staff_id), "in_transit": runtime.is_staff_in_transit(member.staff_id), "facilities": facilities, "comparison_only": runtime.get_staff_rest_report(member.staff_id)}) return {"staff": rows, "path_service_sha256": FileAccess.get_sha256("res://scripts/world/path_service.gd")} func record(label: String, value: Dictionary) -> bool: if manifest == null: return false var digest := object(value) if digest.is_empty(): return false manifest.store_line(JSON.stringify({"label": label, "pid": OS.get_process_id(), "ticks_usec": Time.get_ticks_usec(), "object": digest})) manifest.flush() return true