Save The Tree implementation and acceptance work in progress

Preserve production code, regression fixtures, audio assets and provenance, test infrastructure, and the original-completion plan and progress ledger. Final game and Windows acceptance remain pending; excluded local artifacts and native experiments are not part of this snapshot.
This commit is contained in:
Takeshi
2026-10-11 15:58:00 +09:00
parent 39f6068461
commit b84bade045
235 changed files with 495831 additions and 312 deletions
+122
View File
@@ -53,6 +53,7 @@ func _run() -> void:
_test_expanded_world_round_trips()
_test_grid_preserves_hit_testing()
_test_animation_pause_and_simulation_isolation()
await _test_vertical_scroll_and_connection()
_preview.queue_free()
await process_frame
@@ -302,3 +303,124 @@ func _expect(condition: bool, message: String) -> void:
if not condition:
_failures += 1
push_error(message)
func _test_vertical_scroll_and_connection() -> void:
var previous_mouse_filter := _preview.mouse_filter
_preview.mouse_filter = Control.MOUSE_FILTER_IGNORE
var evidence := OS.get_environment("THE_TREE_P05_FIXTURE_OUTPUT")
var before := var_to_bytes(_runtime.create_snapshot())
_preview.reset_view()
_preview.set_pan_mode(true)
var anchor_cell := Vector3i(-5,0,0)
var wheel := InputEventMouseButton.new()
wheel.button_index = MOUSE_BUTTON_WHEEL_UP
wheel.pressed = true
wheel.position = _preview.cell_to_canvas(anchor_cell)
wheel.factor = 1.0
var zoom_before := _preview.zoom_level
var point_before := _preview.cell_to_canvas(anchor_cell)
_preview._gui_input(wheel)
_expect(_preview.zoom_level == zoom_before and _preview.cell_to_canvas(anchor_cell).y > point_before.y,
"pan-mode wheel moves vertically without zooming")
wheel.button_index = MOUSE_BUTTON_WHEEL_DOWN
_preview._gui_input(wheel)
_expect(_preview.cell_to_canvas(anchor_cell) == point_before, "opposite wheel returns the same cell to the same point")
wheel.ctrl_pressed = true
wheel.button_index = MOUSE_BUTTON_WHEEL_UP
_preview._gui_input(wheel)
_expect(_preview.zoom_level > zoom_before, "Ctrl-wheel retains zoom while pan mode is active")
_preview.set_pan_mode(false)
wheel.ctrl_pressed = false
wheel.button_index = MOUSE_BUTTON_WHEEL_DOWN
_preview._gui_input(wheel)
_expect(_preview.zoom_level == zoom_before, "ordinary wheel retains established zoom outside pan mode")
_preview.set_pan_mode(true)
wheel.button_index = MOUSE_BUTTON_WHEEL_UP
for i in 200: _preview._gui_input(wheel)
var clamped := _preview.pan_offset
_preview._gui_input(wheel)
_expect(_preview.pan_offset == clamped, "repeated vertical scroll stays at the existing camera boundary")
_preview.reset_view()
_preview.set_pan_mode(false)
_expect(before == var_to_bytes(_runtime.create_snapshot()), "new camera input leaves whole authoritative Runtime bytes unchanged")
var camera_after := var_to_bytes(_runtime.create_snapshot())
if not evidence.is_empty():
var f := FileAccess.open(evidence.path_join("before-camera.var"),FileAccess.WRITE);f.store_buffer(before)
f = FileAccess.open(evidence.path_join("after-camera.var"),FileAccess.WRITE);f.store_buffer(var_to_bytes(_runtime.create_snapshot()))
var definition: FacilityDefinition = _runtime.definition_registry.get_facility(&"standard_room")
_preview.layer_mode = 0
_preview.set_build_definition(definition)
_preview.set("_hovered_cell",Vector3i(-6,2,0))
_preview.call("_update_build_preview")
var before_query := var_to_bytes(_runtime.create_snapshot())
var disconnected: Dictionary = _preview.get_build_preview_report(Vector3i(-6,2,0))[&"connection"]
_expect(disconnected[&"status"] == &"DISCONNECTED", "upper room warns before real stairs reach its access cells")
_expect(before_query == var_to_bytes(_runtime.create_snapshot()), "connection warning query preserves every Runtime byte")
var control := FacilityInstance.new()
control.origin = Vector3i(-6,2,0)
control.occupied_cells.assign(_runtime.world_service.cells_for_footprint(control.origin,definition.footprint))
_expect(not _runtime.call("_find_facility_access_path",_runtime.call("_operations_entrance_cell"),control)[&"reachable"],
"warning agrees with ordinary facility routing before stairs")
await _capture_connection("disconnected",evidence)
for cell: Vector3i in [Vector3i(-7,1,0),Vector3i(-7,2,0)]:
var result: CommandResult = _runtime.submit_command(&"build_facility",{&"definition_id":&"guest_stairs",&"origin":cell})
_expect(result.is_success(), "connect preview through real paid stair construction")
_clock.advance_minutes(_runtime.definition_registry.get_facility(&"guest_stairs").build_minutes)
_preview.set("_hovered_cell",Vector3i(-6,2,0))
_preview._process(0)
before_query = var_to_bytes(_runtime.create_snapshot())
var connected: Dictionary = _preview.get_build_preview_report(Vector3i(-6,2,0))[&"connection"]
_expect(connected[&"status"] == &"CONNECTED" and not connected[&"path"].is_empty(), "real stair completion changes warning into a connected path")
_expect(before_query == var_to_bytes(_runtime.create_snapshot()), "connected preview preserves the full authoritative state")
_expect(_runtime.call("_find_facility_access_path",_runtime.call("_operations_entrance_cell"),control)[&"reachable"],
"connected preview agrees with ordinary facility routing")
_expect(_preview.get("_last_preview_report")[&"connection"][&"status"] == &"CONNECTED", "topology changes refresh the visible report even while paused")
await _capture_connection("connected",evidence)
var route: Array = connected[&"path"]
for i in range(1,route.size()):
_expect(not _runtime.path_service.get_edge_report(route[i-1],route[i]).is_empty(), "drawn connection consists only of actually accessible edges")
var blocked: Array = connected[&"access_points"]
for cell: Vector3i in blocked: _runtime.path_service.set_cell_temporary_block(cell,true)
_preview._process(0)
var blocked_report: Dictionary = _preview.get_build_preview_report(Vector3i(-6,2,0))[&"connection"]
_expect(blocked_report[&"status"] == &"DISCONNECTED", "temporary access block invalidates the cached connected report")
for cell: Vector3i in blocked: _runtime.path_service.set_cell_temporary_block(cell,false)
_preview._process(0)
_expect(_preview.get_build_preview_report(Vector3i(-6,2,0))[&"connection"][&"status"] == &"CONNECTED", "removing the block restores the same connection without stale UI")
var connected_snapshot: Dictionary = _runtime.create_snapshot()
_runtime.path_service.set_cell_temporary_block(Vector3i(-6,0,0),true)
var branch_a: Dictionary = _runtime.create_snapshot()
var revisions_a: Array = _preview.call("_current_preview_topology")
_expect(_runtime.restore_snapshot(connected_snapshot), "restore real connected Runtime before second save branch")
_runtime.path_service.set_cell_temporary_block(Vector3i(-7,2,0),true)
var branch_b: Dictionary = _runtime.create_snapshot()
var revisions_b: Array = _preview.call("_current_preview_topology")
_expect(revisions_a == revisions_b, "different saved block topology deliberately has identical revision tuple")
_expect(_runtime.restore_snapshot(branch_a), "restore first equal-revision snapshot through actual Runtime")
var branch_a_report: Dictionary = _preview.get_build_preview_report(Vector3i(-6,2,0))[&"connection"]
_expect(_runtime.restore_snapshot(branch_b), "restore second equal-revision snapshot through actual Runtime")
var branch_b_report: Dictionary = _preview.get_build_preview_report(Vector3i(-6,2,0))[&"connection"]
_expect(branch_a_report[&"status"] == &"CONNECTED" and branch_b_report[&"status"] == &"DISCONNECTED", "snapshot restore replaces stale connection despite identical revision numbers")
_expect(branch_b_report[&"status"] == &"DISCONNECTED", "blocked access remains disconnected after equal-revision save restore")
_expect(_runtime.restore_snapshot(connected_snapshot), "restore connected branch after collision test")
_preview.set_runtime(_runtime)
_expect(_preview.get_build_preview_report(Vector3i(-6,2,0))[&"connection"][&"status"] == &"CONNECTED", "Runtime rebind clears prior connection cache")
if not evidence.is_empty():
var report := {"checks":_checks,"failures":_failures,"pid":OS.get_process_id(),"camera_before_after_equal":before==camera_after,"disconnected":disconnected,"connected":connected,"blocked":blocked_report,"equal_revision_a":revisions_a,"equal_revision_b":revisions_b,"branch_a":branch_a_report,"branch_b":branch_b_report,"fixture_only":true,"normal_OS_input":false,"unit_accepted":false}
var f := FileAccess.open(evidence.path_join("report.json"),FileAccess.WRITE);f.store_string(JSON.stringify(report,"\t"))
_preview.set_build_definition(null)
_preview.mouse_filter = previous_mouse_filter
func _capture_connection(label: String, evidence: String) -> void:
if evidence.is_empty() or DisplayServer.get_name() == "headless": return
_preview.set_zoom(2)
_center_on(Vector3i(-5,1,0))
_preview.set("_hovered_cell",Vector3i(-6,2,0))
_preview.call("_update_build_preview")
_preview.queue_redraw()
await process_frame
await RenderingServer.frame_post_draw
_expect(root.get_texture().get_image().save_png(evidence.path_join("connection-"+label+".png"))==OK,
"capture actual native connection line "+label)