extends Node var failures := 0 func check(ok: bool, message: String) -> void: if not ok: failures += 1 push_error(message) func _ready() -> void: GameState.save_locked = true call_deferred("run") func deposit(restaurant: Node) -> void: var plate: Dish = load("res://scenes/restaurant/dish.tscn").instantiate() plate.state = Dish.State.DIRTY restaurant.add_child(plate) plate.pick_up(restaurant.player) restaurant.handle_interaction("dishwasher") func run() -> void: GameState._reset_progress_state() GameState.restaurant_washing = {} var restaurant = load("res://scenes/restaurant/restaurant.tscn").instantiate() add_child(restaurant) await get_tree().process_frame restaurant.set_process(false) for plate in get_tree().get_nodes_in_group("dish"): plate.free() restaurant.player.held_dish = null for station: Dictionary in restaurant.stations: station.remaining = 0.0 station.recipe = "" GameState.add_modifier("test:wash-capacity", "plates", "override", 1.0, 0.0, "set") GameState.add_modifier("test:wash-capacity", "wash_lines", "override", 1.0, 0.0, "set") var cycle: float = restaurant.wash_duration() deposit(restaurant) check(restaurant._plates_in_use() == 1, "washing plate remains occupied immediately") await get_tree().process_frame check(restaurant._plates_in_use() == 1, "washing plate remains occupied after node deletion") check(restaurant._plates_in_use() >= restaurant.get_plate_capacity(), "last washing plate blocks oven capacity") restaurant._advance_washing(cycle * 0.8) check(restaurant._plates_in_use() == 1, "plate unavailable before completion") restaurant._advance_washing(cycle * 0.2) check(restaurant._plates_in_use() == 0, "plate returned exactly at completion") for i in 4: deposit(restaurant) check(restaurant.wash_running.size() == 1 and restaurant.wash_queue == 3, "one line queues additional plates") check(restaurant._plates_in_use() == 4, "running and queued plates are occupied") GameState.remove_modifiers_by_source("test:wash-capacity") GameState.add_modifier("test:wash-capacity", "wash_lines", "flat", 2.0) restaurant._advance_washing(0.0) check(restaurant.wash_running.size() == 3 and restaurant.wash_queue == 1, "upgrade starts two queued plates immediately") check(restaurant.washing_progress_lines().size() == 3, "three independent progress bars") restaurant._advance_washing(cycle * 0.4) var payload := GameState._build_save_payload() check(payload.restaurant_washing.running.size() == 3 and payload.restaurant_washing.queue == 1, "save contains all occupied washing plates") var progress: float = restaurant.wash_running[0].remaining restaurant._persist_room() restaurant.queue_free() await get_tree().process_frame # Exercise the actual JSON load path, not just the in-memory scene return. GameState.restaurant_washing = {} GameState._apply_save_payload(JSON.parse_string(JSON.stringify(payload))) check(GameState.restaurant_washing.running.size() == 3, "save load restores washing state") var restored = load("res://scenes/restaurant/restaurant.tscn").instantiate() add_child(restored) restored.set_process(false) check(restored.wash_running.size() == 3 and restored.wash_queue == 1, "scene return restores parallel washing and queue") check(is_equal_approx(restored.wash_running[0].remaining, progress), "scene return preserves elapsed cycle") restored._advance_washing(cycle * 0.6) check(restored._plates_in_use() == 1 and restored.wash_running.size() == 1, "three completed plates free up while fourth starts") restored._advance_washing(cycle) check(restored._plates_in_use() == 0, "last queued plate eventually returns") GameState.add_modifier("test:wash-capacity", "wash_lines", "flat", 20.0) check(restored.wash_line_count() == 3, "maximum three lines") GameState.remove_modifiers_by_source("test:wash-capacity") restored.queue_free() await get_tree().process_frame print("WASHING CAPACITY: ", "PASSED" if failures == 0 else "FAILED") get_tree().quit(0 if failures == 0 else 1)