Files
TheTree_mock/tests/transport/test_runtime_transport.gd
T

148 lines
8.2 KiB
GDScript

extends SceneTree
var _checks := 0
var _failures := 0
var _runtime: Variant
var _clock: Variant
var _state: Variant
var _serial := 0
var _main: Control
var _saw_trip := false
var _saw_boarded := false
var _saw_arrival := false
var _saved := false
var _preview_snapshot: Dictionary = {}
func _initialize() -> void:
call_deferred("_run")
func _run() -> void:
_runtime = root.get_node("SimulationRuntime")
_clock = root.get_node("GameClock")
_state = root.get_node("GameState")
_clock.reset(1, 6, 0)
_state.reset()
_runtime.initialize(_clock, _state, 424242)
_runtime.configure_save_policy({&"enabled": false, &"daily_checkpoint_enabled": false})
_clock.set_paused(true)
root.size = Vector2i(1440, 810)
_main = load("res://scenes/main/main.tscn").instantiate() as Control
_main.set("manual_save_path", "user://tests/transport_%d/manual" % OS.get_process_id())
root.add_child(_main)
await process_frame
_runtime.configure_save_policy({&"enabled": false, &"daily_checkpoint_enabled": false})
_expect(_state.get_resource(&"gold") == 5000 and _state.get_resource(&"materials") == 50, "ordinary starting budget")
if not _build(&"guest_elevator", Vector3i(0, 0, 0)) or not _build(&"reception", Vector3i(2, 0, 0)):
_finish(); return
_clock.advance_minutes(300)
_expect(_runtime.elevators.get_report()[&"shafts"].size() == 1, "completed construction registers physical cabin")
if _runtime.elevators.get_report()[&"shafts"].is_empty(): _finish(); return
if not _build(&"guest_elevator", Vector3i(0, 2, 0)) or not _build(&"standard_room", Vector3i(2, 2, 0)):
_finish(); return
_clock.advance_minutes(300)
if not _build(&"standard_room", Vector3i(2, 3, 0)):
_finish(); return
_clock.advance_minutes(60)
var report: Dictionary = _runtime.elevators.get_report()
_expect(report[&"shafts"].size() == 1 and report[&"shafts"][0][&"stops"].size() == 4, "stacked modules share one cabin across four floors")
_expect(_state.get_resource(&"materials") == 2, "buildings fit within 50 materials")
var reception: FacilityInstance
for facility: FacilityInstance in _runtime.facility_service.get_instances():
if facility.definition_id == &"reception": reception = facility
_expect(_cmd(&"hire_staff_candidate", {&"candidate_id": &"staff_akane"}).is_success(), "hire receptionist with earned starting funds")
_expect(_cmd(&"set_staff_work_assignment", {&"staff_id": &"staff_akane", &"facility_id": reception.instance_id, &"template_id": &"DAY"}).is_success(), "assign real commute")
_expect(reception.active_staff_ids.is_empty(), "assignment alone does not open reception")
for index: int in range(250):
_clock.advance_minutes(1)
var current: Dictionary = _runtime.elevators.get_report()
if not current[&"trips"].is_empty(): _saw_trip = true
for trip: Dictionary in current[&"trips"]:
if trip[&"state"] != PathService.ELEVATOR_REQUEST_BOARDED: continue
_saw_boarded = true
if not _saved:
_saved = _verify_mid_ride()
_preview_snapshot = _runtime.create_snapshot()
for guest: GuestRuntime in _runtime.guest_service.get_guests():
if guest.current_cell.y >= 2: _saw_arrival = true
if _saw_boarded and not _main.get_meta(&"captured", false) and OS.get_environment("THE_TREE_TRANSPORT_CAPTURE") == "1":
_main.set_meta(&"captured", true)
await _capture()
if index % 30 == 0: await process_frame
if not _saw_trip:
print("TRANSPORT_DIAGNOSTIC ", _runtime.elevators.get_report(), " STAFF ", _runtime.staff_commute.get_report())
for f: FacilityInstance in _runtime.facility_service.get_instances(): print("FAC ", f.definition_id, " ", f.state, " ", f.active_staff_ids)
for g: GuestRuntime in _runtime.guest_service.get_guests(): print("GUEST ", g.guest_id, " ", g.state, " ", g.current_cell, " ", _runtime._project_guest_candidates(g.guest_id))
_expect(_saw_trip, "natural guest requests an elevator")
_expect(_saw_boarded, "natural guest boards the shared cabin")
_expect(_saw_arrival, "natural guest physically reaches an upper floor")
_expect(_saved, "mid-ride replay tested")
_expect(_runtime.restore_snapshot(_runtime.create_snapshot()), "current completed runtime restores")
if OS.get_environment("THE_TREE_TRANSPORT_PREVIEW") == "1" and _failures == 0:
_expect(_runtime.restore_snapshot(_preview_snapshot), "preview returns to the verified first boarding")
if _failures > 0: _finish(); return
await _capture()
DisplayServer.window_set_title("The Tree · 昇降機と通勤の試遊(保存なし)")
_clock.set_paused(true)
print("Runtime transport: %d checks, %d failures" % [_checks, _failures])
print("TRANSPORT_PREVIEW_READY Space resumes; test saves disabled")
return
_finish()
func _verify_mid_ride() -> bool:
var save_path := "user://tests/transport_%d/ride" % OS.get_process_id()
_expect(bool(_runtime.save_to_path(save_path).get(&"ok", false)), "boarded save writes isolated disk slot")
_expect(bool(_runtime.load_from_path(save_path).get(&"ok", false)), "boarded disk slot reloads")
var snapshot: Dictionary = _runtime.create_snapshot()
_expect(snapshot[&"systems"][&"runtime"][&"runtime_schema_version"] == 8, "runtime schema8 records elevator state")
_expect(_runtime.restore_snapshot(snapshot), "mid-ride Runtime snapshot restores actor/cabin/Path ownership")
var shaft: Dictionary = _runtime.elevators.get_report()[&"shafts"][0]
var busy := _cmd(&"demolish_facility", {&"instance_id": shaft[&"module_ids"][1]})
_expect(not busy.is_success() and busy.details.get(&"reason") == &"ELEVATOR_BUSY", "occupied shaft demolition rejected before spending or topology changes")
_expect(_runtime.restore_snapshot(snapshot), "snapshot resets rejected command metadata")
_clock.advance_minutes(45)
var expected: Dictionary = _runtime.create_snapshot()
_expect(_runtime.restore_snapshot(snapshot), "rewind boarded save for deterministic replay")
_clock.advance_minutes(45)
_expect(_runtime._strict_variants_equal(expected, _runtime.create_snapshot()), "mid-ride save replays all Runtime state identically")
_expect(_runtime.restore_snapshot(snapshot), "restore original ride position after replay test")
var stopped := _cmd(&"set_elevator_operation", {&"shaft_id": shaft[&"shaft_id"], &"operator_open": false})
_expect(stopped.is_success(), "player stops elevator through public command")
_expect(_runtime.elevators.get_report()[&"trips"].is_empty(), "stop releases waiting and disembarks passengers at safe floor")
_expect(_runtime.restore_snapshot(_runtime.create_snapshot()), "stopped elevator save restores")
_expect(_runtime.restore_snapshot(snapshot), "resume original operating snapshot")
return true
func _capture() -> void:
var preview: Control = _main.get("world_preview")
_main.call("_on_facility_selected", _runtime.elevators.get_report()[&"shafts"][0][&"module_ids"][0])
preview.call("set_zoom", 2.0)
preview.set("pan_offset", preview.get("pan_offset") + preview.size * Vector2(0.5, 0.55) - preview.call("cell_to_canvas", Vector3i(2, 1, 0)))
preview.queue_redraw()
await process_frame
await RenderingServer.frame_post_draw
for trip: Dictionary in _runtime.elevators.get_report()[&"trips"]:
if trip[&"state"] != PathService.ELEVATOR_REQUEST_BOARDED: continue
var key := String(trip[&"actor_id"]).replace("guest:", "guest/").replace("staff:", "staff/")
_expect((preview.get("_boarded_actor_ids") as Dictionary).has(key), "live rider identified in cabin rendering")
_expect(not (preview.get("_actor_tracks") as Dictionary).has(key), "live rider is not duplicated on floor")
var path := ProjectSettings.globalize_path("res://artifacts/transport/elevator-cabin.png")
root.get_texture().get_image().save_png(path)
func _build(id: StringName, origin: Vector3i) -> bool:
var result := _cmd(&"build_facility", {&"definition_id": id, &"origin": origin})
_expect(result.is_success(), "build %s at %s %s" % [id, origin, result.message])
return result.is_success()
func _cmd(kind: StringName, payload: Dictionary) -> CommandResult:
_serial += 1
return _runtime.submit_command(kind, payload, &"player", &"", 0, _clock.absolute_minute, StringName("transport.test.%d" % _serial))
func _expect(condition: bool, message: String) -> void:
_checks += 1
if not condition: _failures += 1
print("%s %s" % ["PASS" if condition else "FAIL", message])
func _finish() -> void:
print("Runtime transport: %d checks, %d failures" % [_checks, _failures])
quit(1 if _failures else 0)