Prepare v0.6.6-alpha release

This commit is contained in:
Alexander Sellite 2026-08-11 20:02:54 -04:00
parent 96df168851
commit b044d35021
29 changed files with 568 additions and 134 deletions

View file

@ -109,6 +109,7 @@ func _run() -> void:
select_button.button_index = JOY_BUTTON_BACK
select_button.pressed = true
assert(bool(game_ui.call("_handle_controller_chat_controls", select_button)))
await process_frame
assert(chat_ui.is_open())
assert(chat_panel.mouse_filter == Control.MOUSE_FILTER_STOP)
var typed_chat_entry := chat_ui.find_child(
@ -121,6 +122,8 @@ func _run() -> void:
accept_button.pressed = true
assert(bool(game_ui.call("_handle_controller_chat_controls", accept_button)))
assert(typed_chat_entry.virtual_keyboard_enabled)
await process_frame
assert(typed_chat_entry.has_focus())
var left_bumper := InputEventJoypadButton.new()
left_bumper.button_index = JOY_BUTTON_LEFT_SHOULDER
left_bumper.pressed = true
@ -129,10 +132,8 @@ func _run() -> void:
assert(chat_panel.mouse_filter == Control.MOUSE_FILTER_IGNORE)
assert(not typed_chat_entry.virtual_keyboard_enabled)
assert(bool(game_ui.call("_handle_controller_chat_controls", left_bumper)))
assert(chat_ui.is_open())
assert(not typed_chat_entry.virtual_keyboard_enabled)
assert(bool(game_ui.call("_handle_controller_chat_controls", left_bumper)))
assert(not chat_ui.is_open())
assert(not typed_chat_entry.virtual_keyboard_enabled)
assert(bool(game_ui.call("_handle_controller_chat_controls", select_button)))
assert(not chat_ui.is_open())
assert(chat_ui.is_collapsed())
@ -315,5 +316,7 @@ func _run() -> void:
var session := main.get_node("%NetworkSession") as NetworkSession
session.disconnect_session("")
main.queue_free()
await process_frame
for _frame: int in 4:
await process_frame
await create_timer(0.1).timeout
quit()

View file

@ -39,6 +39,15 @@ func _run() -> void:
standard_button.material != null,
"ordinary controller focus receives inversion",
)
var pointer_motion := InputEventMouseMotion.new()
pointer_motion.position = Vector2(4.0, 4.0)
presentation._input(pointer_motion)
await process_frame
_expect(
standard_button.material == null,
"mouse motion clears controller focus presentation",
)
presentation._input(controller_event)
authored_selector.grab_focus()
await process_frame

View file

@ -23,14 +23,45 @@ func _run() -> void:
var original := _make_button("cute", "cute (show variants)")
option_list.add_child(original)
await process_frame
original.grab_focus()
await process_frame
await process_frame
_expect(
root.gui_get_focus_owner() == null,
"programmatic focus stays pending outside navigation mode",
)
var keyboard_navigation := InputEventKey.new()
keyboard_navigation.keycode = KEY_DOWN
keyboard_navigation.pressed = true
recovery._input(keyboard_navigation)
await process_frame
await process_frame
_expect(
root.gui_get_focus_owner() == original,
"keyboard navigation restores pending initial focus",
)
var menu_shortcut := InputEventKey.new()
menu_shortcut.physical_keycode = KEY_TAB
menu_shortcut.pressed = true
recovery._input(menu_shortcut)
await process_frame
await process_frame
_expect(
root.gui_get_focus_owner() == null,
"the menu shortcut does not leave a pseudo-focused option",
)
var controller_event := InputEventJoypadButton.new()
controller_event.button_index = JOY_BUTTON_A
controller_event.pressed = true
recovery._input(controller_event)
original.grab_focus()
await process_frame
_expect(root.gui_get_focus_owner() == original, "original option receives focus")
await process_frame
await process_frame
_expect(
root.gui_get_focus_owner() == original,
"controller navigation restores pending initial focus",
)
option_list.remove_child(original)
original.queue_free()
@ -53,6 +84,63 @@ func _run() -> void:
root.gui_get_focus_owner() == explicit_target,
"explicit focus changes take precedence over recovery",
)
var pointer_motion := InputEventMouseMotion.new()
pointer_motion.position = Vector2(4.0, 4.0)
recovery._input(pointer_motion)
await process_frame
await process_frame
_expect(
root.gui_get_focus_owner() == null,
"mouse motion releases controller focus",
)
await process_frame
_expect(
root.gui_get_focus_owner() == null,
"mouse motion prevents automatic focus recovery",
)
recovery._input(controller_event)
await process_frame
await process_frame
_expect(
root.gui_get_focus_owner() == explicit_target,
"controller navigation can resume from pointer mode",
)
var pointer_press := InputEventMouseButton.new()
pointer_press.button_index = MOUSE_BUTTON_LEFT
pointer_press.pressed = true
recovery._input(pointer_press)
await process_frame
_expect(
root.gui_get_focus_owner() == explicit_target,
"mouse-down preserves focus through button activation",
)
var pointer_release := InputEventMouseButton.new()
pointer_release.button_index = MOUSE_BUTTON_LEFT
pointer_release.pressed = false
recovery._input(pointer_release)
await process_frame
await process_frame
_expect(
root.gui_get_focus_owner() == null,
"mouse-up clears the completed button focus",
)
recovery._input(controller_event)
await process_frame
await process_frame
var outside_button := _make_button("outside", "outside")
stage.add_child(outside_button)
option_list.hide()
root.gui_release_focus()
await process_frame
await process_frame
_expect(
root.gui_get_focus_owner() == null,
"focus recovery never escapes a hidden menu scope",
)
option_list.show()
explicit_target.grab_focus()
await process_frame
var leave_world_ui_event := InputEventJoypadButton.new()
leave_world_ui_event.button_index = JOY_BUTTON_LEFT_SHOULDER
leave_world_ui_event.pressed = true
@ -64,6 +152,14 @@ func _run() -> void:
root.gui_get_focus_owner() == null,
"LB intentionally leaving world UI is never recovered",
)
var accessibility_only := Control.new()
accessibility_only.focus_mode = Control.FOCUS_ACCESSIBILITY
stage.add_child(accessibility_only)
await process_frame
_expect(
not bool(recovery.call("_is_focusable", accessibility_only)),
"accessibility-only controls are not recovery targets",
)
stage.queue_free()
if _failures.is_empty():

View file

@ -127,7 +127,9 @@ func _run_multiplayer_host() -> void:
print("Economy multiplayer host validation: PASS")
session.disconnect_session("Economy host validation complete.")
main.queue_free()
await process_frame
for _frame: int in 4:
await process_frame
await create_timer(0.1).timeout
quit()
@ -229,7 +231,9 @@ func _run_multiplayer_client() -> void:
print("Economy multiplayer client validation: PASS")
session.disconnect_session("Economy client validation complete.")
main.queue_free()
await process_frame
for _frame: int in 4:
await process_frame
await create_timer(0.1).timeout
quit()
@ -408,7 +412,7 @@ func _test_player_menu_sale(
assert(sell_action.mouse_filter == Control.MOUSE_FILTER_STOP)
assert(sell_action.focus_mode == Control.FOCUS_ALL)
assert(ui_viewport != null)
await _activate_focused_button(sell_action, ui_viewport)
await _activate_pointer_control(sell_action, ui_viewport)
await process_frame
assert(confirmation.visible)
assert(confirm_button.visible and not confirm_button.disabled)
@ -417,7 +421,7 @@ func _test_player_menu_sale(
> (player_menu.get_node("%CoolerOuterWall") as Control).z_index
)
_sale_result.clear()
await _activate_focused_button(confirm_button, ui_viewport)
await _activate_pointer_control(confirm_button, ui_viewport)
await process_frame
assert(not _sale_result.is_empty() and bool(_sale_result[1]))
assert(not player.inventory.contains_catch_id(fish_catch.catch_id))
@ -436,18 +440,29 @@ func _test_player_menu_sale(
await create_timer(2.2).timeout
func _activate_focused_button(
button: Button,
func _activate_pointer_control(
control: Control,
ui_viewport: SubViewport,
) -> void:
button.grab_focus()
var presenter := ui_viewport.get_parent() as SubViewportContainer
assert(presenter != null)
var local_center: Vector2 = control.get_global_transform_with_canvas() * (
control.size * 0.5
)
var center: Vector2 = presenter.position + local_center * presenter.scale
var motion := InputEventMouseMotion.new()
motion.position = center
motion.global_position = center
root.push_input(motion, true)
await process_frame
assert(button.has_focus())
assert(ui_viewport.gui_get_hovered_control() == control)
for is_pressed: bool in [true, false]:
var accept := InputEventAction.new()
accept.action = &"ui_accept"
accept.pressed = is_pressed
ui_viewport.push_input(accept, false)
var click := InputEventMouseButton.new()
click.button_index = MOUSE_BUTTON_LEFT
click.position = center
click.global_position = center
click.pressed = is_pressed
root.push_input(click, true)
await process_frame
@ -560,14 +575,14 @@ func _test_fishing_shop_sale_ui(
assert(art_supplies_tab != null and art_supplies_tab.text == "Art Supplies")
var sell_mode := shop_tabs[5] as Button
assert(sell_mode != null and sell_mode.text == "Sell Fish")
await _activate_focused_button(art_supplies_tab, ui_viewport)
await _activate_pointer_control(art_supplies_tab, ui_viewport)
await process_frame
var stock_sections: Array[String] = []
for child: Node in shop.get_node("%SuppliesList").get_children():
if child is Label:
stock_sections.append((child as Label).text)
assert(stock_sections == ["art kit", "markers", "brushes", "grids"])
await _activate_focused_button(sell_mode, ui_viewport)
await _activate_pointer_control(sell_mode, ui_viewport)
await process_frame
assert(shop.visible and not player_menu.visible)
assert(not shop.has_node("ShopPanel/Margin/Layout/Body/FishSales"))
@ -584,6 +599,11 @@ func _test_fishing_shop_sale_ui(
var water_surface := player_menu.get("_cooler_water_surface") as ColorRect
assert(cooler_outer_wall != null and cooler_outer_wall.visible)
assert(water_surface.visible and water_surface.material is ShaderMaterial)
var cooler_sort_option := player_menu.get("_cooler_sort_option") as Control
await _activate_pointer_control(cooler_sort_option, ui_viewport)
var cooler_choice_panel := cooler_sort_option.get("_choice_panel") as Control
assert(cooler_choice_panel.visible)
cooler_sort_option.call("close_choices")
assert(
StringName(
(player_menu.get("_sale_buyer_override") as FishBuyerProfile).id
@ -594,10 +614,10 @@ func _test_fishing_shop_sale_ui(
var reserved_button := fish_nodes.get(reserved_catch.catch_id) as Button
assert(fish_button != null and fish_button.visible)
assert(reserved_button != null and reserved_button.visible)
await _activate_focused_button(fish_button, ui_viewport)
await _activate_pointer_control(fish_button, ui_viewport)
var sell_button := player_menu.get("_sell_bubble") as Button
assert(sell_button.visible and not sell_button.disabled)
await _activate_focused_button(sell_button, ui_viewport)
await _activate_pointer_control(sell_button, ui_viewport)
await process_frame
var confirmation := player_menu.get("_sale_confirmation") as Control
var confirm_button := player_menu.get("_confirm_sale_button") as Button
@ -607,14 +627,14 @@ func _test_fishing_shop_sale_ui(
> cooler_outer_wall.z_index
)
_sale_result.clear()
await _activate_focused_button(confirm_button, ui_viewport)
await _activate_pointer_control(confirm_button, ui_viewport)
await process_frame
assert(not _sale_result.is_empty() and bool(_sale_result[1]))
assert(not player.inventory.contains_catch_id(fish_catch.catch_id))
assert(player.wallet.get_balance() == balance_before + fish_catch.sale_value)
assert(not sale_service.is_local_sale_pending())
assert(reservations.release(reservation_id))
await _activate_focused_button(shop_tabs[0] as Button, ui_viewport)
await _activate_pointer_control(shop_tabs[0] as Button, ui_viewport)
await process_frame
assert(shop.visible and (shop.get_node("%ShopPanel") as Control).visible)
assert(not (shop.get_node("%ShopCoolerPage") as Control).visible)

View file

@ -3,7 +3,6 @@ extends SceneTree
const MainScene = preload("res://main/main.tscn")
const FishCatchType = preload("res://fish/fish_catch.gd")
const FishDataType = preload("res://fish/fish_data.gd")
const FishingSpotType = preload("res://fishing/fishing_spot.gd")
func _initialize() -> void:
@ -40,7 +39,6 @@ func _run() -> void:
var service := main.get_node(
"%NetworkFishShowcaseService"
) as NetworkFishShowcaseService
var fishing_spot := main.get_node("%FishingSpot") as FishingSpotType
assert(player != null and fish_catalog != null and service != null)
var fish: FishDataType = fish_catalog.get_fish_by_id(&"bluegill")
assert(fish != null)
@ -83,22 +81,18 @@ func _run() -> void:
assert(player.hotbar.get_selected_fish_catch_id() == fish_catch.catch_id)
assert(player.hotbar.get_selected_item_id().is_empty())
var press := InputEventMouseButton.new()
press.button_index = MOUSE_BUTTON_LEFT
press.pressed = true
fishing_spot.call("_unhandled_input", press)
await process_frame
assert(service.is_local_showcase_visible())
assert(service.get_local_showcase_catch_id() == fish_catch.catch_id)
assert((player.get_node("%HeldFishDisplay") as Node3D).visible)
fishing_spot.call("_unhandled_input", press)
await _wait_for_held_fish_visibility(player, true)
assert(service.toggle_selected_fish())
await process_frame
assert(not service.is_local_showcase_visible())
assert(not (player.get_node("%HeldFishDisplay") as Node3D).visible)
await _wait_for_held_fish_visibility(player, false)
var saved_weather: WorldWeatherService.Weather = (
world_weather.get_weather()
)
var saved_weather_seconds: float = world_weather.get_seconds_remaining()
var saved_time_hours: float = world_time.get_time_hours()
assert(save_manager.save_now())
var save_path: String = str(save_manager.get("_save_path"))
@ -116,7 +110,7 @@ func _run() -> void:
== 125
)
assert(absf(
float((parsed as Dictionary)["world"]["time_hours"]) - 19.75
float((parsed as Dictionary)["world"]["time_hours"]) - saved_time_hours
) < 0.01)
assert(
int((parsed as Dictionary)["world"]["weather"])
@ -149,7 +143,7 @@ func _run() -> void:
)
assert(save_manager.load_player_data())
assert(player.experience.get_total_experience() == 125)
assert(absf(world_time.get_time_hours() - 19.75) < 0.01)
assert(absf(world_time.get_time_hours() - saved_time_hours) < 0.01)
assert(world_weather.get_weather() == saved_weather)
assert(absf(
world_weather.get_seconds_remaining() - saved_weather_seconds
@ -163,14 +157,13 @@ func _run() -> void:
FishQuality.Tier.EXCEPTIONAL,
)
)
assert(not service.is_local_showcase_visible())
assert(service.toggle_selected_fish())
assert(service.is_local_showcase_visible())
await _wait_for_held_fish_visibility(player, true)
assert(player.inventory.remove_catch_by_id(fish_catch.catch_id) != null)
await process_frame
assert(player.hotbar.get_fish_catch_id(1).is_empty())
assert(not service.is_local_showcase_visible())
assert(not (player.get_node("%HeldFishDisplay") as Node3D).visible)
await _wait_for_held_fish_visibility(player, false)
var valid_state: Dictionary = {
"session_id": "session",
@ -202,5 +195,26 @@ func _run() -> void:
print("Fish hotbar showcase validation: PASS")
session.disconnect_session("")
main.queue_free()
await process_frame
for _frame: int in 4:
await process_frame
await create_timer(0.1).timeout
quit()
func _wait_for_held_fish_visibility(
player: Player,
expected_visible: bool,
) -> void:
var held_fish_display := player.get("_held_fish_display") as Node3D
assert(held_fish_display != null)
var deadline_msec: int = Time.get_ticks_msec() + 2000
while (
held_fish_display.visible != expected_visible
and Time.get_ticks_msec() < deadline_msec
):
await process_frame
assert(
held_fish_display.visible == expected_visible,
"Held fish display did not become %s within the timeout."
% expected_visible,
)

View file

@ -35,8 +35,8 @@ func _run_host() -> void:
var fish_catch: FishCatch = _add_bluegill(main, player)
assert(player.hotbar.assign_fish(1, fish_catch.catch_id))
assert(player.hotbar.select_slot(1))
assert(service.toggle_selected_fish())
assert(service.is_local_showcase_visible())
await _wait_for_held_fish_visibility(player, true)
assert(session.set_host_open(true))
var remote_peer_id: int = 0
@ -66,7 +66,9 @@ func _run_host() -> void:
print("Fish showcase multiplayer host validation: PASS")
session.disconnect_session("")
main.queue_free()
await process_frame
for _frame: int in 4:
await process_frame
await create_timer(0.1).timeout
quit()
@ -118,8 +120,8 @@ func _run_client() -> void:
var fish_catch: FishCatch = _add_bluegill(main, player)
assert(player.hotbar.assign_fish(1, fish_catch.catch_id))
assert(player.hotbar.select_slot(1))
assert(service.toggle_selected_fish())
assert((player.get("_held_fish_display") as Node3D).visible)
assert(service.is_local_showcase_visible())
await _wait_for_held_fish_visibility(player, true)
await create_timer(2.0).timeout
assert(service.toggle_selected_fish())
var held_display := player.get("_held_fish_display") as Node3D
@ -132,7 +134,9 @@ func _run_client() -> void:
print("Fish showcase multiplayer client validation: PASS")
session.disconnect_session("")
main.queue_free()
await process_frame
for _frame: int in 4:
await process_frame
await create_timer(0.1).timeout
quit()
@ -166,3 +170,18 @@ func _create_initialized_main() -> Node:
await process_frame
assert(bool(main.get("_application_initialized")))
return main
func _wait_for_held_fish_visibility(
player: Player,
expected_visible: bool,
) -> void:
var held_fish_display := player.get("_held_fish_display") as Node3D
assert(held_fish_display != null)
var deadline_msec: int = Time.get_ticks_msec() + 2000
while (
held_fish_display.visible != expected_visible
and Time.get_ticks_msec() < deadline_msec
):
await process_frame
assert(held_fish_display.visible == expected_visible)

View file

@ -36,8 +36,14 @@ func _run() -> void:
assert(not session.is_open_host())
assert(service != null and fishing_spot != null and player != null)
assert(player.hotbar.get_selected_item_id() == &"basic_fishing_rod")
var pond := main.get_node(
"TestWorld/Regions/StarterIslandRegion/WaterBodies/Pond"
) as Node3D
var pond_region := pond.get_node("FishingRegion") as FishableWaterRegion
assert(pond != null and pond_region != null)
var pond_surface_y: float = pond_region.get_surface_height()
player.global_position = Vector3(-0.5, 3.95, 2.1)
player.global_position = pond.global_position + Vector3(8.9, 1.44, 0.0)
var visuals := player.get_node("Visuals") as Node3D
visuals.rotation.y = PI * 0.5
for _frame: int in 4:
@ -50,8 +56,8 @@ func _run() -> void:
fishing_spot.set("_cast_charge", 0.32)
fishing_spot.call("_update_cast_charge", 0.0)
var aimed_target: Vector3 = fishing_spot.get("_cast_target")
assert(aimed_target.x < -1.35)
assert(is_equal_approx(aimed_target.y, 2.51))
assert(aimed_target.x < player.global_position.x - 0.85)
assert(is_equal_approx(aimed_target.y, pond_surface_y))
assert(fishing_spot.is_target_fishable(aimed_target))
fishing_spot.call("_confirm_cast")
assert(fishing_spot.state == FishingSpotType.FishingState.CASTING)
@ -68,7 +74,7 @@ func _run() -> void:
var attempts: Dictionary = service.get("_attempts")
var attempt: NetworkFishingAttempt = attempts.get(session.get_local_peer_id())
assert(attempt != null)
assert(is_equal_approx(attempt.target.y, 2.51))
assert(is_equal_approx(attempt.target.y, pond_surface_y))
assert(attempt.bobber_position.is_equal_approx(attempt.target))
fishing_spot.set("_withdrawal_input_held", true)
@ -124,29 +130,42 @@ func _run() -> void:
fish,
)
assert(fish_catch != null and fish_catch.is_valid())
var baseline_controller := CatchController.new()
root.add_child(baseline_controller)
baseline_controller.start_authoritative_encounter(
var reference_controller := CatchController.new()
root.add_child(reference_controller)
reference_controller.start_authoritative_encounter(
fish.catch_profile,
attempt.reel_speed,
attempt.barrier_damage,
attempt.encounter_seed,
FishQuality.Tier.BORING,
fish_catch.quality,
int(fish.rarity),
fish.get_weight_percentile(fish_catch.weight_lb),
)
var quality_barriers: Array = attempt.controller.get("_barriers")
var baseline_barriers: Array = baseline_controller.get("_barriers")
assert(quality_barriers.size() == baseline_barriers.size())
var reference_barriers: Array = reference_controller.get("_barriers")
assert(quality_barriers.size() == reference_barriers.size())
for barrier_index: int in quality_barriers.size():
var quality_barrier: RefCounted = quality_barriers[barrier_index]
var baseline_barrier: RefCounted = baseline_barriers[barrier_index]
var reference_barrier: RefCounted = reference_barriers[barrier_index]
assert(
int(quality_barrier.get("maximum_health"))
== FishQuality.apply_barrier_health(
int(baseline_barrier.get("maximum_health")),
fish_catch.quality,
is_equal_approx(
float(quality_barrier.get("position")),
float(reference_barrier.get("position")),
)
)
baseline_controller.queue_free()
assert(
int(quality_barrier.get("maximum_health"))
== int(reference_barrier.get("maximum_health"))
)
assert(
int(quality_barrier.get("maximum_health"))
>= FishQuality.BARRIER_HEALTH_MINIMUMS[fish_catch.quality]
)
assert(
int(quality_barrier.get("maximum_health"))
<= FishQuality.BARRIER_HEALTH_MAXIMUMS[fish_catch.quality]
)
reference_controller.queue_free()
service.call("_cancel_attempt", session.get_local_peer_id(), "")
await process_frame
assert(not service.has_local_attempt())
@ -154,5 +173,7 @@ func _run() -> void:
print("Fishing authority validation: PASS")
session.disconnect_session("")
main.queue_free()
await process_frame
for _frame: int in 4:
await process_frame
await create_timer(0.1).timeout
quit()

View file

@ -150,7 +150,9 @@ func _run_host() -> void:
print("Fishing multiplayer host validation: PASS")
session.disconnect_session("")
main.queue_free()
await process_frame
for _frame: int in 4:
await process_frame
await create_timer(0.1).timeout
quit()
@ -325,7 +327,9 @@ func _run_client() -> void:
print("Fishing multiplayer client validation: PASS")
session.disconnect_session("")
main.queue_free()
await process_frame
for _frame: int in 4:
await process_frame
await create_timer(0.1).timeout
quit()

View file

@ -266,11 +266,47 @@ func _validate_bite_wait_distribution() -> void:
if wait_seconds >= FishingSpotType.BITE_LONG_MAX_SECONDS:
very_long_count += 1
var average_wait_seconds: float = total_wait_seconds / 10000.0
assert(quick_count >= 2300 and quick_count <= 2700)
var quick_ratio: float = float(quick_count) / 10000.0
var very_long_ratio: float = float(very_long_count) / 10000.0
var very_long_probability: float = 1.0 - (
FishingSpotType.BITE_QUICK_PROBABILITY
+ FishingSpotType.BITE_TYPICAL_PROBABILITY
+ FishingSpotType.BITE_LONG_PROBABILITY
)
var expected_average_wait_seconds: float = (
FishingSpotType.BITE_QUICK_PROBABILITY
* (
FishingSpotType.BITE_QUICK_MIN_SECONDS
+ FishingSpotType.BITE_QUICK_MAX_SECONDS
)
* 0.5
+ FishingSpotType.BITE_TYPICAL_PROBABILITY
* (
FishingSpotType.BITE_QUICK_MAX_SECONDS
+ FishingSpotType.BITE_TYPICAL_MAX_SECONDS
)
* 0.5
+ FishingSpotType.BITE_LONG_PROBABILITY
* (
FishingSpotType.BITE_TYPICAL_MAX_SECONDS
+ FishingSpotType.BITE_LONG_MAX_SECONDS
)
* 0.5
+ very_long_probability
* (
FishingSpotType.BITE_LONG_MAX_SECONDS
+ FishingSpotType.BITE_MAX_SECONDS
)
* 0.5
)
assert(absf(
quick_ratio - FishingSpotType.BITE_QUICK_PROBABILITY
) <= 0.02)
assert(typical_or_long_count > quick_count)
assert(very_long_count >= 100 and very_long_count <= 300)
assert(average_wait_seconds >= 45.0)
assert(average_wait_seconds <= 49.0)
assert(absf(very_long_ratio - very_long_probability) <= 0.005)
assert(absf(
average_wait_seconds - expected_average_wait_seconds
) <= 1.0)
fishing_spot.queue_free()
await process_frame
@ -305,11 +341,16 @@ func _validate_remote_presentation() -> void:
fish_catch.sale_value = 1
assert(fish_catch.is_valid())
presentation.play_return(fish_catch)
await create_timer(0.6).timeout
var catch_display := player.find_child(
"CatchDisplay", true, false
) as Node3D
assert(catch_display != null)
var showcase_deadline_msec: int = Time.get_ticks_msec() + 2000
while (
not catch_display.visible
and Time.get_ticks_msec() < showcase_deadline_msec
):
await process_frame
assert(catch_display.visible)
await presentation.return_completed
assert(not catch_display.visible)

View file

@ -62,7 +62,9 @@ func _run() -> void:
await _capture_inventory_pages(player_menu)
print("Inventory notepad artwork validation: PASS")
presentation_stage.queue_free()
await process_frame
for _frame: int in 10:
await process_frame
await create_timer(0.1).timeout
quit()

View file

@ -56,7 +56,9 @@ func _run_host() -> void:
print("Job multiplayer host validation: PASS")
session.disconnect_session("")
main.queue_free()
await process_frame
for _frame: int in 4:
await process_frame
await create_timer(0.1).timeout
quit()
@ -93,7 +95,9 @@ func _run_client() -> void:
print("Job multiplayer client validation: PASS")
session.disconnect_session("")
main.queue_free()
await process_frame
for _frame: int in 4:
await process_frame
await create_timer(0.1).timeout
quit()

View file

@ -79,10 +79,15 @@ func _run() -> void:
"_show_section_immediate", PlayerMenu.Section.PROFILE
)
await process_frame
assert(not bool(
assert(bool(
player_menu.call("_handle_direct_page_shortcut", shortcut)
))
await create_timer(0.5).timeout
assert(player_menu.visible)
assert(logbook.visible)
assert(
player_menu.get("_current_section") == PlayerMenu.Section.LOGBOOK
)
player_menu.close_menu(PlayerMenu.CloseReason.TEARDOWN, false)
print(
@ -90,7 +95,8 @@ func _run() -> void:
% [root.size.x, root.size.y]
)
main.queue_free()
await process_frame
for _frame: int in 4:
await process_frame
quit()

View file

@ -171,7 +171,7 @@ func _validate_page() -> void:
page.activate()
await process_frame
assert(page.get("_category") == WaterType.Type.FRESH_WATER)
assert((page.get("_catalog_grid") as GridContainer).columns == 5)
assert((page.get("_catalog_grid") as GridContainer).columns == 4)
var initial_detail_body := page.get("_detail_body") as VBoxContainer
assert(not initial_detail_body.get_parent() is ScrollContainer)
assert(
@ -209,7 +209,7 @@ func _validate_page() -> void:
assert(portrait.source_texture == fish.display_texture)
assert(
portrait.custom_minimum_size
== LogbookPortraitType.ENTRY_FRAME_SIZE
== LogbookPage.CATALOG_PORTRAIT_SIZE
)
assert(
portrait.expand_mode

View file

@ -12,6 +12,14 @@ func _run() -> void:
root.add_child(game_ui)
await process_frame
game_ui.set("_gameplay_ui_enabled", true)
var panel := game_ui.get_node("%ExperienceProgressPanel") as PanelContainer
var bubble := game_ui.get_node("%ExperienceBubble") as PanelContainer
var bubble_label := game_ui.get_node("%ExperienceBubbleLabel") as Label
var award_label := game_ui.get_node("%ExperienceAwardLabel") as Label
assert(panel != null and bubble != null)
assert(not panel.visible and not bubble.visible)
game_ui.call("_on_showcase_changed", "bluegill", "common", 1.0, 0, true)
await process_frame
game_ui.call(
"_on_experience_awarded",
50,
@ -20,13 +28,6 @@ func _run() -> void:
1,
1,
)
var panel := game_ui.get_node("%ExperienceProgressPanel") as PanelContainer
var bubble := game_ui.get_node("%ExperienceBubble") as PanelContainer
var bubble_label := game_ui.get_node("%ExperienceBubbleLabel") as Label
var award_label := game_ui.get_node("%ExperienceAwardLabel") as Label
assert(panel != null and bubble != null)
assert(not panel.visible and not bubble.visible)
game_ui.call("_on_showcase_changed", "bluegill", "common", 1.0, 0, true)
await process_frame
assert(not panel.visible and not bubble.visible)
game_ui.call("_on_showcase_changed", "", "", 0.0, 0, false)
@ -43,5 +44,8 @@ func _run() -> void:
await create_timer(1.2).timeout
assert(not panel.visible and not bubble.visible)
game_ui.queue_free()
for _frame: int in 4:
await process_frame
await create_timer(0.1).timeout
print("Player experience UI validation: PASS")
quit()

View file

@ -114,7 +114,9 @@ func _run_host() -> void:
print("Surface drawing multiplayer host validation: PASS")
session.disconnect_session("")
main.queue_free()
await process_frame
for _frame: int in 4:
await process_frame
await create_timer(0.1).timeout
quit()
@ -207,7 +209,9 @@ func _run_client() -> void:
print("Surface drawing multiplayer client validation: PASS")
session.disconnect_session("")
main.queue_free()
await process_frame
for _frame: int in 4:
await process_frame
await create_timer(0.1).timeout
quit()

View file

@ -110,7 +110,9 @@ func _run() -> void:
print("Surface drawing runtime validation: PASS")
session.disconnect_session("")
main.queue_free()
await process_frame
for _frame: int in 4:
await process_frame
await create_timer(0.1).timeout
quit()

View file

@ -21,6 +21,8 @@ func _run() -> void:
await _validate_blocked_author_visibility()
_validate_peer_capability_tracking()
print("Surface drawing validation: PASS")
for _frame: int in 4:
await process_frame
quit()
@ -118,6 +120,7 @@ func _validate_art_unlocks() -> void:
assert(unlocks.is_brush_size_unlocked(4))
assert(unlocks.is_grid_size_unlocked(128))
assert(not unlocks.restore_mask(PlayerArtUnlocks.ALL_UNLOCK_MASK + 1))
unlocks.free()
func _validate_grid_snapping() -> void:
@ -265,6 +268,7 @@ func _validate_blocked_author_visibility() -> void:
})
var world := Node3D.new()
root.add_child(world)
world.add_child(relationships)
var canvas := SurfaceDrawingCanvas.new()
world.add_child(canvas)
var state: Dictionary = {

View file

@ -205,6 +205,8 @@ func _run() -> void:
presenter.queue_free()
root.size = original_size
await process_frame
for _frame: int in 4:
await process_frame
await create_timer(0.1).timeout
print("UI scaling runtime validation: PASS")
quit()

View file

@ -83,7 +83,9 @@ func _run_host() -> void:
print("World time multiplayer host validation: PASS")
session.disconnect_session("")
main.queue_free()
await process_frame
for _frame: int in 4:
await process_frame
await create_timer(0.1).timeout
quit()
@ -195,7 +197,9 @@ func _run_client() -> void:
print("World time multiplayer client validation: PASS")
session.disconnect_session("")
main.queue_free()
await process_frame
for _frame: int in 4:
await process_frame
await create_timer(0.1).timeout
quit()