Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions godot_project/export_presets.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,8 @@ application/product_name=""
application/file_description=""
application/copyright=""
application/trademarks=""
application/export_angle=0
application/export_d3d12=0
application/export_angle=2
application/export_d3d12=1
application/d3d12_agility_sdk_multiarch=true
ssh_remote_deploy/enabled=false
ssh_remote_deploy/host="user@host_ip"
Expand Down
48 changes: 31 additions & 17 deletions godot_project/scripts/autoload/scene_transition_manager.gd
Original file line number Diff line number Diff line change
Expand Up @@ -20,30 +20,44 @@ func _ready():
canvas_layer.add_child(fade_rect)


# Transition to a new scene with fade
# Transition to a new scene with fade (uses threaded loading to prevent main thread hangs)
func transition_to_scene(scene_path: String):
# Fade out
var fade_tween = create_tween()
fade_tween.tween_property(fade_rect, "color", Color(0, 0, 0, 1), 0.5)
await fade_tween.finished

# Load new scene
if scene_path.ends_with(".tscn"):
# Direct scene change
get_tree().change_scene_to_file(scene_path)
# Start threaded scene load to prevent main thread blocking
var err = ResourceLoader.load_threaded_request(scene_path)
if err == OK:
# Wait for load to complete with timeout to prevent infinite hang
var timeout: float = 30.0
var elapsed: float = 0.0
while elapsed < timeout:
var status = ResourceLoader.load_threaded_get_status(scene_path)
if status == ResourceLoader.THREAD_LOAD_LOADED:
var scene_resource = ResourceLoader.load_threaded_get(scene_path)
var new_scene = scene_resource.instantiate()
var root = get_tree().root
var current_scene = get_tree().current_scene
if current_scene:
root.remove_child(current_scene)
current_scene.queue_free()
root.add_child(new_scene)
get_tree().current_scene = new_scene
break
elif status == ResourceLoader.THREAD_LOAD_FAILED or status == ResourceLoader.THREAD_LOAD_INVALID_RESOURCE:
push_error("Failed to load scene: " + scene_path + ", using fallback")
get_tree().change_scene_to_file(scene_path)
break
await get_tree().create_timer(0.016).timeout
elapsed += 0.016
if elapsed >= timeout:
push_error("Scene load timeout after 30s, using fallback: " + scene_path)
get_tree().change_scene_to_file(scene_path)
else:
# Try to use instantiated PackedScene
var new_scene = load(scene_path).instantiate()

# Get the current scene and replace it
var root = get_tree().root
var current_scene = get_tree().current_scene

root.remove_child(current_scene)
current_scene.queue_free()

root.add_child(new_scene)
get_tree().current_scene = new_scene
# Fallback to direct scene change if threaded request fails
get_tree().change_scene_to_file(scene_path)

# Fade back in
fade_tween = create_tween()
Expand Down
16 changes: 15 additions & 1 deletion godot_project/scripts/systems/ShiftSummaryScreen.gd
Original file line number Diff line number Diff line change
Expand Up @@ -953,8 +953,10 @@ func transition_within_viewport(scene_path: String):
tween.tween_property(fade_rect, "color", Color(0, 0, 0, 1), 0.5)
await tween.finished

# Wait for threaded load to complete
# Wait for threaded load to complete with timeout to prevent infinite hang
var scene_resource = null
var load_timeout: float = 30.0 # Maximum 30 seconds to load a scene
var load_elapsed: float = 0.0
while true:
var status = ResourceLoader.load_threaded_get_status(scene_path)
if status == ResourceLoader.THREAD_LOAD_LOADED:
Expand All @@ -964,6 +966,18 @@ func transition_within_viewport(scene_path: String):
push_error("Failed to load scene: " + scene_path)
fade_rect.queue_free()
return
elif status == ResourceLoader.THREAD_LOAD_INVALID_RESOURCE:
push_error("Invalid resource while loading scene: " + scene_path)
fade_rect.queue_free()
get_tree().change_scene_to_file(scene_path) # Fallback to direct load
return
# Timeout check to prevent infinite hang
load_elapsed += 0.016
if load_elapsed >= load_timeout:
push_error("Scene load timeout after " + str(load_timeout) + " seconds: " + scene_path)
fade_rect.queue_free()
get_tree().change_scene_to_file(scene_path) # Fallback to direct load
return
# Small delay before checking again
await get_tree().create_timer(0.016).timeout

Expand Down
10 changes: 10 additions & 0 deletions godot_project/scripts/utils/simple_scene_loader.gd
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ func load_scene(path: String, use_sub_threads: bool = false):
func _thread_load(path, use_sub_threads):
var loader = ResourceLoader.load_threaded_request(path, "", use_sub_threads)
if loader == OK:
var timeout_ms: int = 60000 # 60 second timeout to prevent infinite hang
var elapsed_ms: int = 0
while true:
var status = ResourceLoader.load_threaded_get_status(path)
match status:
Expand All @@ -41,8 +43,16 @@ func _thread_load(path, use_sub_threads):
ResourceLoader.THREAD_LOAD_FAILED:
call_deferred("_loading_failed")
break
ResourceLoader.THREAD_LOAD_INVALID_RESOURCE:
call_deferred("_loading_failed")
break
ResourceLoader.THREAD_LOAD_IN_PROGRESS:
OS.delay_msec(50) # Wait before checking again
elapsed_ms += 50
if elapsed_ms >= timeout_ms:
push_error("Scene load timeout: " + path)
call_deferred("_loading_failed")
break


func _loading_done():
Expand Down
Loading