straywild/tests/surface_drawing_runtime_validation.gd
Voyager 3b84bfe3a0 feat: expand progression and multiplayer systems
Add named save slots, progression import/export, and a unified play flow. Add live friend requests, presence, invitations, and relationship controls without durable discovery-server social storage. Advance the network protocol with isolated channels, movement reconciliation, late-join recovery, fishing replication, and animation synchronization. Preserve per-species catch totals, refine generated-world startup and water recovery, and complete the related input and interface improvements.
2026-08-23 20:49:54 -04:00

234 lines
9 KiB
GDScript

extends SceneTree
const MainScene: PackedScene = preload("res://main/main.tscn")
const TEST_PORT: int = 18132
func _initialize() -> void:
call_deferred("_run")
func _run() -> void:
root.size = Vector2i(1280, 720)
var main: Node = MainScene.instantiate()
root.add_child(main)
for _frame: int in 4:
await process_frame
if not bool(main.get("_application_initialized")):
main.call("_activate_selected_data_path", "", true)
for _frame: int in 8:
await process_frame
assert(bool(main.get("_application_initialized")))
var session := main.get_node("%NetworkSession") as NetworkSession
assert(session.start_private_host(TEST_PORT))
var save_manager := main.get("_save_manager") as PlayerSaveManager
assert(save_manager.initialize_new_game())
main.call("_enter_gameplay")
await physics_frame
await physics_frame
var player := main.get("_player") as Player
assert(player.bag.add_item(&"art_kit", 1))
assert(player.hotbar.assign_item(0, &"art_kit"))
assert(player.hotbar.select_slot(0))
assert(player.art_unlocks.restore_mask(PlayerArtUnlocks.ALL_UNLOCK_MASK))
var service := main.get_node(
"%NetworkSurfaceDrawingService"
) as NetworkSurfaceDrawingService
assert(service != null)
assert(session.supports_server_capability(SurfaceDrawingProtocol.CAPABILITY))
service.deactivate()
_validate_marker_controls(service, player)
var query := PhysicsRayQueryParameters3D.create(
player.global_position + Vector3.UP * 3.0,
player.global_position + Vector3.DOWN * 6.0,
1,
)
query.collide_with_areas = false
query.collide_with_bodies = true
query.exclude = [player.get_rid()]
var hit: Dictionary = player.get_world_3d().direct_space_state.intersect_ray(query)
assert(not hit.is_empty())
assert(service.request_canvas_at_surface(
hit["position"], hit["normal"], Vector3.RIGHT
))
assert(service.get_canvas_ids().size() == 1)
var canvas_id: String = service.get_canvas_ids()[0]
assert(service.request_cell_edits(canvas_id, [{
"x": 8,
"y": 8,
"color_id": "ocean_teal",
}]))
var state: Dictionary = service.get_canvas_state(canvas_id)
assert(int(state["revision"]) == 1)
assert((state["cells"] as Array).size() == 1)
assert(state["cells"][0]["color_id"] == "ocean_teal")
assert(
state["cells"][0]["author_fingerprint"]
== session.get_local_identity_fingerprint()
)
service.set("_last_hovered_canvas_id", canvas_id)
service.set("_hovered_canvas_id", "")
var game_ui := main.get_node("%GameUI") as GameUI
var toolbar := game_ui.get_node(
"%SurfaceDrawingToolbar"
) as SurfaceDrawingToolbar
var export_button := toolbar.get_node("%ExportButton") as Button
export_button.pressed.emit()
var exported_entries: Array[Dictionary] = service.get_saved_stamp_entries()
assert(exported_entries.size() == 1)
var export_path: String = str(exported_entries[0]["path"])
assert(not export_path.is_empty())
var data_root := main.get("_data_root") as PlayerDataRoot
assert(export_path.begins_with(data_root.root_path.path_join("artwork")))
assert(FileAccess.file_exists(export_path))
var status_label := game_ui.get_node("%StatusLabel") as Label
assert(status_label.text == "artwork exported to the data folder • artwork")
var exported_image: Image = Image.load_from_file(export_path)
assert(exported_image.get_size() == Vector2i(16, 16))
assert(exported_image.get_pixel(8, 7).is_equal_approx(
SurfaceDrawingPalette.get_color(&"ocean_teal")
))
assert(service.request_guide_visibility(canvas_id, false))
state = service.get_canvas_state(canvas_id)
assert(not bool(state["guide_visible"]))
var canvas_nodes: Dictionary = service.get("_canvas_nodes")
var canvas := canvas_nodes[canvas_id] as SurfaceDrawingCanvas
assert(not canvas.is_guide_visible())
assert(service.request_guide_visibility(canvas_id, true))
assert(bool(service.get_canvas_state(canvas_id)["guide_visible"]))
assert(service.request_guide_visibility(canvas_id, false, true))
assert(bool(service.get_canvas_state(canvas_id)["finalized"]))
assert(canvas.is_finalized())
assert(not canvas.has_guide_geometry())
assert(service.request_canvas_at_surface(
hit["position"], hit["normal"], Vector3.RIGHT
))
assert(service.get_canvas_ids().size() == 2)
var replacement_canvas_id: String = ""
for candidate_id: String in service.get_canvas_ids():
if candidate_id != canvas_id:
replacement_canvas_id = candidate_id
assert(not replacement_canvas_id.is_empty())
assert(service.request_cell_edits(replacement_canvas_id, [{
"x": 8,
"y": 8,
"color_id": "blue",
}]))
assert((service.get_canvas_state(canvas_id)["cells"] as Array).is_empty())
assert(
str(service.get_canvas_state(replacement_canvas_id)["cells"][0]["color_id"])
== "blue"
)
assert(service.request_undo_last_stroke())
assert((service.get_canvas_state(replacement_canvas_id)["cells"] as Array).is_empty())
assert(
str(service.get_canvas_state(canvas_id)["cells"][0]["color_id"])
== "ocean_teal"
)
var player_list := main.get_node(
"%NetworkPlayerListService"
) as NetworkPlayerListService
assert(player_list.get_session_artwork_counts() == Vector2i(2, 1))
assert(player_list.reset_session_artwork())
assert(service.get_canvas_ids().is_empty())
var stamp_entries: Array[Dictionary] = service.get_saved_stamp_entries()
assert(stamp_entries.size() == 1)
assert(str(stamp_entries[0]["path"]) == export_path)
assert(int(stamp_entries[0]["grid_size"]) == 16)
assert(bool(stamp_entries[0]["available"]))
service.activate(Vector2(640.0, 360.0))
assert(service.select_saved_stamp(export_path))
assert(service.is_stamp_mode())
assert(service.request_stamp_at_surface(
hit["position"], hit["normal"], Vector3.RIGHT
))
assert(service.get_canvas_ids().size() == 1)
var stamp_id: String = service.get_canvas_ids()[0]
var stamp_state: Dictionary = service.get_canvas_state(stamp_id)
assert(bool(stamp_state["stamp"]))
assert(bool(stamp_state["finalized"]))
assert(not bool(stamp_state["guide_visible"]))
assert((stamp_state["cells"] as Array).size() == 1)
assert(int(stamp_state["cells"][0]["x"]) == 8)
assert(int(stamp_state["cells"][0]["y"]) == 8)
assert(str(stamp_state["cells"][0]["color_id"]) == "ocean_teal")
assert(
stamp_state.get("participant_fingerprints", [])
== [session.get_local_identity_fingerprint()]
)
var stamp_canvas_nodes: Dictionary = service.get("_canvas_nodes")
var stamp_canvas := stamp_canvas_nodes[stamp_id] as SurfaceDrawingCanvas
assert(stamp_canvas.is_finalized())
assert(not stamp_canvas.has_guide_geometry())
service.set_placement_mode(false)
assert(not service.is_stamp_mode())
assert(service.clear_session_artwork())
print("Surface drawing runtime validation: PASS")
session.disconnect_session("")
main.queue_free()
for _frame: int in 4:
await process_frame
await create_timer(0.1).timeout
quit()
func _validate_marker_controls(
service: NetworkSurfaceDrawingService,
player: Player,
) -> void:
var prior_mouse_mode: Input.MouseMode = Input.mouse_mode
var activation_pointer := Vector2(824.0, 318.0)
service.activate(activation_pointer)
assert(service.is_active())
assert(not service.is_placement_mode())
assert(service.get_pointer_screen_position() == activation_pointer)
if DisplayServer.get_name() != "headless":
assert(Input.mouse_mode == Input.MOUSE_MODE_VISIBLE)
var placement_key := InputEventKey.new()
placement_key.physical_keycode = KEY_R
placement_key.pressed = true
assert(service.handle_input(placement_key, true))
assert(service.is_placement_mode())
var pointer_before: Vector2 = service.get_pointer_screen_position()
var pointer_motion := InputEventMouseMotion.new()
pointer_motion.position = pointer_before + Vector2(30.0, -12.0)
assert(service.handle_input(pointer_motion, true))
assert(service.get_pointer_screen_position() != pointer_before)
var scaled_ui_motion := InputEventMouseMotion.new()
scaled_ui_motion.position = Vector2(260.0, 140.0)
var root_viewport_pointer := Vector2(960.0, 540.0)
assert(service.handle_input(
scaled_ui_motion,
true,
root_viewport_pointer,
))
assert(service.get_pointer_screen_position() == root_viewport_pointer)
var zoom_event := InputEventMouseButton.new()
zoom_event.button_index = MOUSE_BUTTON_WHEEL_UP
zoom_event.shift_pressed = true
zoom_event.pressed = true
assert(not service.handle_input(zoom_event, true))
var prior_zoom: float = float(player.get("_target_zoom"))
player.call("_unhandled_input", zoom_event)
assert(float(player.get("_target_zoom")) < prior_zoom)
var camera_press := InputEventMouseButton.new()
camera_press.button_index = MOUSE_BUTTON_RIGHT
camera_press.pressed = true
assert(not service.handle_input(camera_press, true))
var pointer_before_camera: Vector2 = service.get_pointer_screen_position()
assert(not service.handle_input(pointer_motion, true))
assert(service.get_pointer_screen_position() == pointer_before_camera)
var camera_release := InputEventMouseButton.new()
camera_release.button_index = MOUSE_BUTTON_RIGHT
camera_release.pressed = false
assert(not service.handle_input(camera_release, true))
assert(service.handle_input(placement_key, true))
assert(not service.is_placement_mode())
service.deactivate()
assert(Input.mouse_mode == prior_mouse_mode)