extends SceneTree const CommuteType = preload("res://scripts/staff/staff_commute_service.gd") var _checks := 0 var _failures := 0 var _fixtures: Array = [] ## Movement is injected at Runtime's narrow boundary. Real Staff, Shift, Task, ## Facility and staff-only Path rights run unchanged in this focused suite. class CommuteRuntime extends RefCounted: var staff_service := StaffService.new() var facility_service := FacilityService.new() var path_service := PathService.new() var commute = CommuteType.new() var movements: Array[Dictionary] = [] var last_moved: Dictionary = {} var fail_movement := false var in_transit := false func configure() -> void: var cells: Array[Vector3i] = [] for layer: int in [0, 1]: for x in range(13): cells.append(Vector3i(x, 0, layer)) path_service.rebuild_graph(cells) path_service.configure_connector(&"staff_door", Vector3i.ZERO, Vector3i(0, 0, 1), 100, true, &"staff") for row: Array in [[&"west", Vector3i(5, 0, 0)], [&"east", Vector3i(10, 0, 0)], [&"back", Vector3i(5, 0, 1)]]: facility_service.create_instance({&"instance_id": row[0], &"definition_id": &"office", &"origin": row[1], &"occupied_cells": [row[1]], &"staff_min": 1, &"staff_max": 2}) commute.configure(self) func advance_staff_commute(staff_id: StringName, target: Vector3i, minute: int, reason: StringName = &"") -> Dictionary: var worker := staff_service.get_staff(staff_id) if not reason.is_empty() or int(last_moved.get(staff_id, -1)) >= minute or fail_movement: return {&"moved": false} var path := path_service.find_path(worker.current_cell, target, [0, 1], [&"staff"]) if path.size() <= 1: return {&"moved": false} var previous := worker.current_cell worker.current_cell = path[1] last_moved[staff_id] = minute movements.append({&"minute": minute, &"staff_id": staff_id, &"from": previous, &"to": worker.current_cell}) return {&"moved": true} func is_staff_in_transit(_staff_id: StringName) -> bool: return in_transit func advance(minute: int) -> void: staff_service.advance_one_minute(minute) commute.tick(minute) for facility: FacilityInstance in facility_service.get_instances(): var active: Array[StringName] = [] for worker: StaffRuntime in staff_service.get_staff_members(): if commute.is_present(worker, facility): active.append(worker.staff_id) facility_service.set_operational_status(facility.instance_id, {&"active_staff_ids": active}, minute) func dispose() -> void: staff_service.configure_attendance_driver() commute._runtime = null func _initialize() -> void: call_deferred("_run") func _run() -> void: print("P2: physical attendance, recurring commutes and saved position replay") _test_legacy_contract() _test_walk_and_arrival_staffing() _test_early_arrival_and_shift_end() _test_late_route_repair_and_replay() _test_reassignment_and_return_to_post() _test_reassignment_after_late_arrival_counts_boundary_once() _test_porter_dispatch_after_check_in() _test_back_layer_permissions_and_unavailable() _test_night_shift_and_missing_workplace() _test_boarded_reassignment_does_not_staff_origin() for fixture: CommuteRuntime in _fixtures: fixture.dispose() print("Staff commute: %d checks, %d failures" % [_checks, _failures]) quit(_failures) func _fixture(role: StringName = &"receptionist", minute := 360) -> CommuteRuntime: var fixture := CommuteRuntime.new() fixture.configure() fixture.staff_service.create_staff(&"worker", role) fixture.staff_service.advance_one_minute(minute) _fixtures.append(fixture) return fixture func _plan(fixture: CommuteRuntime, facility: StringName = &"west", template: StringName = &"DAY") -> StaffRuntime: _expect(fixture.staff_service.set_work_assignment(&"worker", facility, template).is_success(), "repeating work plan is accepted") return fixture.staff_service.get_staff(&"worker") func _test_legacy_contract() -> void: var legacy := StaffService.new() legacy.create_staff(&"legacy", &"receptionist") legacy.advance_one_minute(360) legacy.set_work_assignment(&"legacy", &"west", &"DAY") _expect(legacy.get_staff(&"legacy").state == StaffRuntime.State.AVAILABLE, "component-only recurring plans keep their original shift contract") var fixture := _fixture() fixture.staff_service.create_standard_shift(&"worker", &"DAY", 0, &"west", &"manual") var worker := fixture.staff_service.get_staff(&"worker") _expect(worker.state == StaffRuntime.State.AVAILABLE and not fixture.staff_service.requires_attendance(&"worker"), "manual legacy shifts remain available without a persistent plan") _expect(fixture.commute.is_present(worker, fixture.facility_service.get_instance(&"west")), "legacy manual-shift staffing keeps compatibility") func _test_walk_and_arrival_staffing() -> void: var fixture := _fixture() var worker := _plan(fixture) var shift := fixture.staff_service.get_shift(worker.shift_id) var west := fixture.facility_service.get_instance(&"west") _expect(worker.state == StaffRuntime.State.COMMUTING and worker.current_cell == Vector3i.ZERO, "paused assignment starts a real commute without teleporting") _expect(shift.worked_minutes == 0 and shift.actual_started_at == -1, "assignment time is not falsely counted as work") _expect(not fixture.commute.is_present(worker, west), "a remote assignment cannot staff a facility") for minute in range(361, 365): var previous := worker.current_cell fixture.advance(minute) _expect(worker.current_cell.distance_to(previous) <= 1.0, "commute advances at most one route edge per minute") _expect(worker.current_cell == Vector3i(4, 0, 0), "worker reaches the actual facility access cell") _expect(worker.state == StaffRuntime.State.COMMUTING and west.active_staff_ids.is_empty(), "movement arrival activates at the next Staff AI boundary") fixture.advance(365) _expect(worker.state == StaffRuntime.State.AVAILABLE and west.active_staff_ids == [&"worker"], "only physical arrival contributes the facility staff capacity") _expect(shift.actual_started_at == 365 and shift.worked_minutes == 1, "first recorded work minute is the arrival activation minute") var snapshot := fixture.staff_service.create_snapshot() fixture.commute.get_report() _expect(fixture.staff_service.create_snapshot() == snapshot, "attendance report reads do not mutate saved Staff state") _expect(fixture.staff_service.validate_invariants()[&"ok"], "physical commute preserves Staff invariants") func _test_early_arrival_and_shift_end() -> void: var fixture := _fixture(&"receptionist", 330) var worker := _plan(fixture) var shift := fixture.staff_service.get_shift(worker.shift_id) for minute in range(331, 360): fixture.advance(minute) _expect(worker.current_cell == Vector3i(4, 0, 0) and worker.state == StaffRuntime.State.COMMUTING, "early arrival waits at the workplace through the commute lead window") _expect(shift.actual_started_at == -1 and shift.worked_minutes == 0, "early arrival does not start paid duty before 06:00") fixture.advance(360) _expect(worker.state == StaffRuntime.State.AVAILABLE and shift.actual_started_at == 360, "an employee already at the workplace starts at exactly 06:00") fixture.advance(1080) _expect(worker.state == StaffRuntime.State.OFF_DUTY and worker.shift_id.is_empty() and shift.actual_ended_at == 1080, "18:00 closes the work shift and removes attendance") _expect(worker.current_cell == Vector3i(4, 0, 0), "shift end keeps the real position rather than teleporting home") fixture.advance(1770) _expect(worker.state == StaffRuntime.State.COMMUTING, "next day's recurring commute begins automatically at 05:30") fixture.advance(1800) _expect(worker.state == StaffRuntime.State.AVAILABLE, "next day's saved plan activates only at its new shift boundary") func _test_late_route_repair_and_replay() -> void: var fixture := _fixture() fixture.path_service.set_cell_temporary_block(Vector3i(2, 0, 0), true) var worker := _plan(fixture) for minute in range(361, 379): fixture.advance(minute) var shift := fixture.staff_service.get_shift(worker.shift_id) _expect(worker.current_cell == Vector3i.ZERO and worker.state == StaffRuntime.State.COMMUTING, "a blocked route never teleports or invents attendance") _expect(shift.late_minutes == 18 and shift.late_reason == CommuteType.ROUTE_BLOCKED, "lateness records the real route blockage after the grace threshold") _expect(shift.worked_minutes == 0 and shift.actual_started_at == -1, "unreachable staff do not accumulate fictional worked minutes") var checkpoint := fixture.staff_service.create_snapshot() var restored := _fixture() _expect(restored.staff_service.restore_snapshot(checkpoint), "a blocked commute snapshot restores using existing Staff and Shift data") restored.path_service.set_cell_temporary_block(Vector3i(2, 0, 0), true) _expect(restored.staff_service.create_snapshot() == checkpoint, "restored blocked attendance is exact without new service state") fixture.path_service.set_cell_temporary_block(Vector3i(2, 0, 0), false) restored.path_service.set_cell_temporary_block(Vector3i(2, 0, 0), false) for minute in range(379, 390): fixture.advance(minute) restored.advance(minute) _expect(fixture.staff_service.create_snapshot() == restored.staff_service.create_snapshot(), "route repair replays to identical work, lateness and positions after restore") _expect(worker.state == StaffRuntime.State.AVAILABLE and worker.absence_reason.is_empty(), "repairing the route allows physical arrival and clears the active absence") _expect(shift.actual_started_at == 383 and shift.late_minutes == 22, "arrival keeps historical late minutes while beginning real duty") var midwalk := _fixture() var walker := _plan(midwalk) midwalk.advance(361) midwalk.advance(362) var moving := midwalk.staff_service.create_snapshot() var replay := _fixture() _expect(replay.staff_service.restore_snapshot(moving), "mid-walk save restores the exact current cell") for minute in range(363, 368): midwalk.advance(minute) replay.advance(minute) _expect(midwalk.staff_service.create_snapshot() == replay.staff_service.create_snapshot() and walker.current_cell == Vector3i(4, 0, 0), "mid-walk replay neither skips nor repeats route cells") func _test_reassignment_and_return_to_post() -> void: var fixture := _fixture() var worker := _plan(fixture) for minute in range(361, 367): fixture.advance(minute) var first := fixture.staff_service.get_shift(worker.shift_id) _expect(fixture.staff_service.set_work_assignment(&"worker", &"east", &"DAY").is_success(), "fixed staff can be reassigned after arriving") first = fixture.staff_service.get_shift(first.shift_instance_id) _expect(worker.state == StaffRuntime.State.COMMUTING and worker.current_cell == Vector3i(4, 0, 0), "reassignment walks from the current location") _expect(first.assigned_facility_id == &"west" and first.actual_ended_at == 366, "historical duty remains attached to the old workplace") for minute in range(367, 374): fixture.advance(minute) var shift := fixture.staff_service.get_shift(worker.shift_id) _expect(worker.current_cell == Vector3i(9, 0, 0) and worker.state == StaffRuntime.State.AVAILABLE, "reassignment opens the new workplace after arrival") # Completion of a portable task leaves its employee at the work target. worker.current_cell = Vector3i(6, 0, 0) worker.transition_to(StaffRuntime.State.AVAILABLE, &"TASK_COMPLETED", 374) fixture.advance(374) _expect(worker.state == StaffRuntime.State.COMMUTING and worker.current_cell == Vector3i(7, 0, 0), "fixed roles return to their post after work elsewhere") fixture.advance(375) fixture.advance(376) fixture.advance(377) _expect(worker.state == StaffRuntime.State.AVAILABLE and worker.current_cell == Vector3i(9, 0, 0), "desk service resumes after returning physically") _expect(shift.late_minutes == 0, "returning from a completed task does not rewrite arrival lateness") _expect(fixture.staff_service.set_work_assignment(&"worker", &"", &"DAY").is_success(), "unassignment cancels the repeating commute") var cell := worker.current_cell fixture.advance(378) _expect(worker.state == StaffRuntime.State.OFF_DUTY and worker.current_cell == cell, "unassigned staff keep position and stop commuting") func _test_reassignment_after_late_arrival_counts_boundary_once() -> void: var fixture := _fixture() var worker := _plan(fixture) for minute in range(361, 366): fixture.advance(minute) var old_id := worker.shift_id fixture.facility_service.create_instance({&"instance_id": &"nearby", &"definition_id": &"office", &"origin": Vector3i(3, 0, 0), &"occupied_cells": [Vector3i(3, 0, 0)]}) _expect(fixture.staff_service.get_shift(old_id).worked_minutes == 1, "late arrival has only one actual duty minute before reassignment") _expect(fixture.staff_service.set_work_assignment(&"worker", &"nearby", &"DAY").is_success(), "paused reassignment may choose another workplace sharing this access cell") var old := fixture.staff_service.get_shift(old_id) var replacement := fixture.staff_service.get_shift(worker.shift_id) _expect(old.worked_minutes == 0 and old.actual_started_at == -1 and replacement.worked_minutes == 1, "reassignment transfers the current duty minute exactly once despite earlier commute gaps") _expect(fixture.staff_service.restore_snapshot(fixture.staff_service.create_snapshot()), "gap-aware historical shift split restores without extra saved attendance state") func _test_porter_dispatch_after_check_in() -> void: var fixture := _fixture(&"porter") var worker := _plan(fixture) _expect(not worker.is_available_for_dispatch(), "new porter cannot take a delivery before checking in") for minute in range(361, 367): fixture.advance(minute) worker.current_cell = Vector3i(10, 0, 0) worker.transition_to(StaffRuntime.State.AVAILABLE, &"TASK_COMPLETED", 367) fixture.advance(367) _expect(worker.state == StaffRuntime.State.AVAILABLE and worker.current_cell == Vector3i(10, 0, 0), "checked-in porter can accept another job from a delivery destination") _expect(not fixture.commute.is_present(worker, fixture.facility_service.get_instance(&"west")), "porter away from the warehouse does not falsely staff the warehouse") var restored := _fixture(&"porter") _expect(restored.staff_service.restore_snapshot(fixture.staff_service.create_snapshot()), "the porter's once-per-shift check-in survives save restoration") restored.advance(368) _expect(restored.staff_service.get_staff(&"worker").state == StaffRuntime.State.AVAILABLE, "loaded porter duty does not force an unnecessary return commute") fixture.advance(1080) fixture.advance(1770) _expect(worker.state == StaffRuntime.State.COMMUTING and worker.current_cell == Vector3i(9, 0, 0), "the following shift requires a fresh real warehouse check-in") func _test_back_layer_permissions_and_unavailable() -> void: var fixture := _fixture() var worker := _plan(fixture, &"back") var access: Dictionary = fixture.commute.find_facility_access_path(Vector3i.ZERO, fixture.facility_service.get_instance(&"back")) _expect(access[&"reachable"] and access[&"cell"].z == 1, "commute can reach BACK facilities through an authorized staff door") _expect(fixture.path_service.find_path(Vector3i.ZERO, Vector3i(4, 0, 1), [0, 1], []).is_empty(), "the same staff door remains inaccessible without staff rights") fixture.advance(361) _expect(worker.current_cell == Vector3i(0, 0, 1), "cross-layer commute uses the actual connector endpoint") worker.health = 0 worker.transition_to(StaffRuntime.State.INCAPACITATED, &"TEST", 362) fixture.advance(362) _expect(worker.current_cell == Vector3i(0, 0, 1) and worker.state == StaffRuntime.State.INCAPACITATED, "unavailable workers do not walk or get promoted to available") worker.health = 100 worker.transition_to(StaffRuntime.State.COMMUTING, &"RECOVERED", 363) fixture.fail_movement = true fixture.advance(363) _expect(worker.current_cell == Vector3i(0, 0, 1), "a refused Runtime movement leaves the commute position unchanged") fixture.fail_movement = false for minute in range(364, 371): fixture.advance(minute) _expect(fixture.commute.is_present(worker, fixture.facility_service.get_instance(&"back")), "recovered staff finish the real BACK commute") _expect(not CommuteType.is_at_facility(worker, fixture.facility_service.get_instance(&"west")), "identical screen coordinates on different layers never count as attendance") var upper := FacilityInstance.new().configure(&"upper", &"office", {&"origin": Vector3i(4, 1, 1), &"occupied_cells": [Vector3i(4, 1, 1)]}) _expect(not CommuteType.is_at_facility(worker, upper), "standing below an upper room cannot bypass the route to its floor") _expect(not fixture.commute.find_facility_access_path(worker.current_cell, upper)[&"reachable"], "a corridor underneath a room is not a valid workplace entrance") func _test_night_shift_and_missing_workplace() -> void: var fixture := _fixture(&"receptionist", 1410) var worker := _plan(fixture, &"west", &"NIGHT") for minute in range(1411, 1417): fixture.advance(minute) var shift := fixture.staff_service.get_shift(worker.shift_id) fixture.advance(1440) _expect(worker.state == StaffRuntime.State.AVAILABLE and worker.shift_id == shift.shift_instance_id, "midnight retains the same physically attended NIGHT shift") fixture.advance(1800) _expect(worker.state == StaffRuntime.State.OFF_DUTY and shift.actual_ended_at == 1800, "NIGHT attendance ends at next-day 06:00") var missing := _fixture() var absent := _plan(missing, &"missing") missing.advance(361) _expect(absent.state == StaffRuntime.State.COMMUTING and absent.absence_reason == CommuteType.WORKPLACE_MISSING, "missing workplace remains a visible waiting condition") _expect(missing.staff_service.get_shift(absent.shift_id).worked_minutes == 0, "a missing workplace creates no phantom duty") func _test_boarded_reassignment_does_not_staff_origin() -> void: var fixture := _fixture() var worker := _plan(fixture) fixture.facility_service.create_instance({&"instance_id": &"boarding_post", &"definition_id": &"office", &"origin": Vector3i.ZERO, &"occupied_cells": [Vector3i.ZERO]}) fixture.in_transit = true _expect(fixture.staff_service.set_work_assignment(&"worker", &"boarding_post", &"DAY").is_success(), "a boarded commute can accept a new destination plan") var shift := fixture.staff_service.get_shift(worker.shift_id) fixture.advance(361) _expect(worker.state == StaffRuntime.State.COMMUTING and shift.worked_minutes == 0, "the cabin's projected boarding cell cannot turn into attendance at the origin") _expect(not fixture.commute.is_present(worker, fixture.facility_service.get_instance(&"boarding_post")), "a passenger never supplies staff capacity while still in transit") _expect(fixture.commute.get_report()[&"staff"][0][&"reason"] == &"ELEVATOR_WAIT", "commute report distinguishes the owned ride from arrival at its projected origin") _expect(worker.current_cell == Vector3i.ZERO and fixture.movements.is_empty(), "the commute driver waits for the owned ride rather than moving its projected anchor") fixture.in_transit = false worker.current_cell = Vector3i(3, 0, 0) fixture.advance(362) _expect(worker.state == StaffRuntime.State.COMMUTING and worker.current_cell == Vector3i(2, 0, 0), "after safe disembarkation the employee walks toward the latest assignment") fixture.advance(363) fixture.advance(364) _expect(worker.state == StaffRuntime.State.AVAILABLE and shift.actual_started_at == 364, "new-post duty begins only after the completed ride and actual return") fixture.in_transit = true worker.current_task_id = &"owned_work" _expect(fixture.commute.can_attend_shift(worker, shift, 365), "an already checked-in employee's owned portable work remains duty while riding") worker.current_task_id = &"" _expect(not fixture.commute.can_attend_shift(worker, shift, 365), "an idle passenger cannot become dispatchable based on its old checked-in position") func _expect(condition: bool, message: String) -> void: _checks += 1 if not condition: _failures += 1 push_error("FAIL: %s" % message)