Files
TheTree_mock/tests/transport/test_runtime_stairs.gd
Takeshi 5dde0c5ec2 Record original-alignment implementation and traceability checkpoint
Capture current source, content data, tests, asset licenses, and original-specification traceability. Original implementation remains incomplete. The accepted matching UI generation passed 154 suites and 12,253 checks, with eight rendered staff-contract screens reviewed. Latest native Windows and full-original acceptance remain outstanding.
2026-09-30 23:52:24 +09:00

178 lines
11 KiB
GDScript

extends SceneTree
var _checks := 0
var _failures := 0
var _runtime: Variant
var _clock: Variant
var _state: Variant
var _serial := 0
func _initialize() -> void:
call_deferred("_run")
func _run() -> void:
_runtime = load("res://autoload/simulation_runtime.gd").new()
_clock = load("res://autoload/game_clock.gd").new()
_state = load("res://autoload/game_state.gd").new()
_reset()
_expect(_runtime.path_service.get_vertical_walk_requires_connector(), "new Runtime requires explicit vertical transport")
_expect(_runtime.definition_registry.facility_count() == 23, "Runtime registers baseline16, stairs, infirmary and premium room/dormitory and chapel")
var before: Dictionary = _runtime.create_snapshot()
var invalid := _command(&"build_facility", {&"definition_id": &"guest_stairs", &"origin": Vector3i(4, 3, 0)})
_expect(not invalid.is_success() and invalid.details.get(&"reason") == &"STAIR_LANDING_MISSING", "stairs without a lower landing reject before any construction")
_expect(_runtime.construction_service.get_jobs().is_empty() and _state.get_resource(&"gold") == 5000, "missing landing spends no money and starts no job")
_build(&"guest_stairs", Vector3i(4, 1, 0))
_build(&"guest_stairs", Vector3i(4, 2, 0))
var route: Array = _runtime.path_service.find_path(Vector3i(4, 0, 0), Vector3i(4, 2, 0))
_expect(route.size() == 3 and _runtime.path_service.calculate_path_cost(route) == 300, "two staircase floors cost three walking minutes")
_expect(_runtime._estimated_actor_path_minutes(route, Array([], TYPE_STRING_NAME, &"", null)) == 3, "actor arrival estimate includes stair time")
var spawn := _command(&"spawn_guest", {&"guest_id": &"stair.guest", &"guest_type_id": &"traveler", &"gold": 100,
&"options": {&"current_cell": Vector3i(4, 0, 0), &"state": GuestRuntime.State.MOVING,
&"state_entered_at": _clock.absolute_minute - 1, &"planned_exit_at": _clock.absolute_minute + 2000,
&"path_handle": {&"target_cell": Vector3i(4, 2, 0)}}})
_expect(spawn.is_success(), "public guest spawn creates a real stair traveller")
_clock.advance_minutes(1)
var guest: GuestRuntime = _runtime.guest_service.get_guest(&"stair.guest")
_expect(guest.current_cell == Vector3i(4, 0, 0), "after one minute guest is still completing the first staircase")
var mid: Dictionary = _runtime.create_snapshot()
_expect(mid[&"systems"][&"runtime"][&"movement_credits"][0][&"credit"] == 1000, "partial staircase persists one minute of movement credit")
_expect(_runtime.restore_snapshot(mid) and _runtime.create_snapshot() == mid, "half-finished staircase restores exactly")
_clock.advance_minutes(2)
var arrived: Dictionary = _runtime.create_snapshot()
_expect(_runtime.guest_service.get_guest(&"stair.guest").current_cell == Vector3i(4, 2, 0), "two floors complete in three actual simulation minutes")
_expect(_runtime.restore_snapshot(mid), "restore partial staircase for deterministic replay")
_clock.advance_minutes(2)
_expect(_runtime.create_snapshot() == arrived, "fractional stair travel replays every aggregate exactly")
var bad := mid.duplicate(true)
bad[&"systems"][&"runtime"][&"movement_credits"][0][&"credit"] = 1500
_expect(not _runtime.restore_snapshot(bad) and _runtime.create_snapshot() == arrived, "unspent complete stair step is rejected atomically")
bad = mid.duplicate(true)
bad[&"systems"][&"runtime"][&"path"][&"vertical_walk_requires_connector"] = false
_expect(not _runtime.restore_snapshot(bad), "current Runtime cannot save unrestricted vertical walking")
bad = mid.duplicate(true)
bad[&"systems"][&"runtime"].erase(&"legacy_stairs")
_expect(not _runtime.restore_snapshot(bad), "current Runtime requires stair ownership metadata")
bad = mid.duplicate(true)
bad[&"systems"][&"runtime"][&"runtime_schema_version"] = 8
bad[&"systems"][&"runtime"].erase(&"legacy_stairs")
bad[&"systems"][&"runtime"][&"path"][&"vertical_walk_requires_connector"] = false
_expect(not _runtime.restore_snapshot(bad), "older Runtime label cannot smuggle current Path policy fields")
var blockade := mid.duplicate(true)
for traffic: Dictionary in blockade[&"systems"][&"runtime"][&"path"][&"cell_traffic"]:
if traffic[&"cell"] == Vector3i(4, 1, 0):
traffic[&"temporary_block"] = true
_expect(_runtime.restore_snapshot(blockade), "temporary blockade preserves valid fractional staircase credit")
_expect(_runtime.restore_snapshot(_runtime.create_snapshot()), "blocked partial staircase re-saves canonically")
_reset()
_build(&"guest_corridor", Vector3i(4, 1, 0))
_build(&"guest_stairs", Vector3i(4, 2, 0))
var lower_id := _facility_at(Vector3i(4, 1, 0))
var upper_id := _facility_at(Vector3i(4, 2, 0))
var blocked := _command(&"demolish_facility", {&"instance_id": lower_id})
_expect(not blocked.is_success() and blocked.details.get(&"reason") == &"STAIR_LANDING_IN_USE", "occupied lower landing rejects demolition before a broken stair is created")
_expect(_runtime.restore_snapshot(_runtime.create_snapshot()), "rejected stair demolition remains saveable")
_expect(_command(&"demolish_facility", {&"instance_id": upper_id}).is_success(), "upper staircase can be removed first")
_expect(_command(&"demolish_facility", {&"instance_id": lower_id}).is_success(), "unused lower corridor can then be removed")
_reset()
_build(&"service_stairs", Vector3i(4, 1, 1))
_expect(_runtime.path_service.find_path(Vector3i(4, 0, 1), Vector3i(4, 1, 1)).is_empty(), "guests cannot use service stairs")
_expect(_runtime.path_service.find_path(Vector3i(4, 0, 1), Vector3i(4, 1, 1), [0, 1], [&"staff"]).size() == 2, "staff can use service stairs")
_test_legacy()
_test_occupied_stair_demolition()
print("Runtime stairs: %d checks, %d failures" % [_checks, _failures])
_runtime.free()
_clock.free()
_state.free()
quit(1 if _failures else 0)
func _test_legacy() -> void:
_reset()
_build(&"guest_corridor", Vector3i(4, 1, 0))
_build(&"guest_corridor", Vector3i(4, 2, 0))
_expect(_runtime.path_service.find_path(Vector3i(4, 0, 0), Vector3i(4, 2, 0)).is_empty(), "new corridors do not act as invisible stairs")
var legacy: Dictionary = _runtime.create_snapshot()
var data: Dictionary = legacy[&"systems"][&"runtime"]
data[&"runtime_schema_version"] = 8
data.erase(&"legacy_stairs")
preload("res://tests/fixtures/pre_upkeep_runtime.gd").strip_empty_upkeep(data)
data[&"path"][&"schema_version"] = 4
data[&"path"].erase(&"vertical_walk_requires_connector")
data[&"path"].erase(&"transit_actor_ids")
_expect(_runtime.restore_snapshot(legacy), "actual v8 structure migrates existing vertical corridors")
var records: Array = _runtime.legacy_stairs.create_snapshot()[&"stairs"]
_expect(records.size() == 2 and _runtime.path_service.get_vertical_walk_requires_connector(), "migration materializes only the two original vertical links")
var route: Array = _runtime.path_service.find_path(Vector3i(4, 0, 0), Vector3i(4, 2, 0))
_expect(route.size() == 3 and _runtime.path_service.calculate_path_cost(route) == 200, "old corridor stairs retain their original speed and reachability")
var canonical: Dictionary = _runtime.create_snapshot()
var preview := WorldPreview.new()
preview.size=Vector2(1280,720)
preview.set_runtime(_runtime)
preview.layer_mode=WorldPreview.LayerMode.BACK
preview.reset_view()
var ghost_ids: Array = []
for item: Dictionary in preview._other_layer_rooms():
if item.get(&"legacy_stair",false): ghost_ids.append(item[&"id"])
_expect(ghost_ids.size()==2 and ghost_ids.has(records[0][&"id"]) and ghost_ids.has(records[1][&"id"]), "opposite-layer view renders each actually migrated legacy connector once")
preview.free()
_expect(_runtime.create_snapshot()==canonical,"migrated legacy visualization does not alter canonical save or routes")
_expect(_runtime.restore_snapshot(canonical) and _runtime.create_snapshot() == canonical, "migrated save is canonical and migration does not repeat")
var malformed := canonical.duplicate(true)
malformed[&"systems"][&"runtime"][&"legacy_stairs"][&"stairs"].pop_back()
_expect(not _runtime.restore_snapshot(malformed) and _runtime.create_snapshot() == canonical, "orphan legacy connector is rejected atomically")
var upper_id := _facility_at(Vector3i(4, 2, 0))
_expect(_command(&"demolish_facility", {&"instance_id": upper_id}).is_success(), "legacy upper landing can be demolished normally")
_expect(_runtime.legacy_stairs.create_snapshot()[&"stairs"].size() == 1, "demolition retires that stair's ownership record")
_build(&"guest_corridor", Vector3i(4, 2, 0))
_expect(_runtime.path_service.find_path(Vector3i(4, 1, 0), Vector3i(4, 2, 0)).is_empty(), "rebuilding a plain corridor never regenerates a legacy staircase")
_expect(_runtime.restore_snapshot(_runtime.create_snapshot()), "pruned and rebuilt topology remains saveable")
func _reset() -> void:
_clock.reset(1, 6, 0)
_state.reset()
_expect(_runtime.initialize(_clock, _state, 90416)[&"valid"], "stairs fixture initializes")
_runtime.configure_save_policy({&"enabled": false, &"daily_checkpoint_enabled": false})
_clock.set_paused(true)
func _build(id: StringName, origin: Vector3i) -> void:
var built := _command(&"build_facility", {&"definition_id": id, &"origin": origin})
_expect(built.is_success(), "normal construction accepts %s %s: %s" % [id, origin, built.message])
_clock.advance_minutes(10)
_expect(not _facility_at(origin).is_empty(), "construction completes %s %s" % [id, origin])
func _facility_at(origin: Vector3i) -> StringName:
for facility: Dictionary in _runtime.construction_service.get_facilities():
if facility[&"origin"] == origin:
return facility[&"instance_id"]
return &""
func _command(type: StringName, payload: Dictionary) -> CommandResult:
_serial += 1
return _runtime.submit_command(type, payload, &"manager", &"", 0, -1, StringName("runtime.stairs.%d" % _serial))
func _expect(ok: bool, label: String) -> void:
_checks += 1
if not ok:
_failures += 1
push_error(label)
else:
print("PASS: ", label)
func _test_occupied_stair_demolition() -> void:
_reset()
_build(&"guest_stairs", Vector3i(4, 1, 0))
var stair_id := _facility_at(Vector3i(4, 1, 0))
_expect(_command(&"spawn_guest", {&"guest_id": &"occupied.stair", &"guest_type_id": &"traveler", &"gold": 100,
&"options": {&"current_cell": Vector3i(4, 1, 0), &"state": GuestRuntime.State.MOVING,
&"state_entered_at": _clock.absolute_minute - 1, &"planned_exit_at": _clock.absolute_minute + 100,
&"path_handle": {&"target_cell": Vector3i(4, 0, 0)}}}).is_success(), "real guest is standing on upper staircase landing")
var paths: Dictionary = _runtime.path_service.create_snapshot()
var rejected := _command(&"demolish_facility", {&"instance_id": stair_id})
_expect(not rejected.is_success() and rejected.details.get(&"reason") == &"FACILITY_OCCUPIED", "occupied staircase cannot delete a real guest's landing")
_expect(_runtime.path_service.create_snapshot() == paths and _runtime.guest_service.get_guest(&"occupied.stair").current_cell == Vector3i(4, 1, 0), "demolition rejection preserves actor projection and position")
_expect(_runtime.restore_snapshot(_runtime.create_snapshot()), "occupied staircase rejection leaves a valid canonical save")
_clock.advance_minutes(2)
_expect(_runtime.guest_service.get_guest(&"occupied.stair").current_cell == Vector3i(4, 0, 0), "guest physically finishes descending before demolition")
_expect(_command(&"demolish_facility", {&"instance_id": stair_id}).is_success(), "empty staircase can be removed after the guest leaves")
_expect(_runtime.restore_snapshot(_runtime.create_snapshot()), "post-descent demolition remains saveable")