- Defer LOAD_GAME dispatch until SimBridge reaches CONNECTED (critical) - Guard _build_saves_list() against queue_free() race on rapid reopen - Disable save entries with empty newest_save, guard in _on_save_selected - Send before show_loading on F6 quickload, skip overlay on send failure - Clear pending_load_path in _on_new_game()/_on_continue() (stale path) - Add hide_loading(success: bool) API for future failure-state UI - Add test_save_load_flow_sprint21.gd covering LoadingScreen + GameState Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -39,5 +39,6 @@ func show_loading() -> void:
|
||||
visible = true
|
||||
|
||||
|
||||
func hide_loading() -> void:
|
||||
## Hide the loading overlay. success=false is reserved for future failure-state UI.
|
||||
func hide_loading(success: bool = true) -> void:
|
||||
visible = false
|
||||
|
||||
+21
-7
@@ -41,6 +41,7 @@ func _refresh_continue_state() -> void:
|
||||
|
||||
|
||||
func _on_new_game() -> void:
|
||||
GameState.pending_load_path = "" # clear stale load path from previous Load selection
|
||||
var game_id := SessionManager.new_game()
|
||||
if game_id.is_empty():
|
||||
push_error("MainMenu: new_game() failed to create save directory — cannot start")
|
||||
@@ -49,6 +50,7 @@ func _on_new_game() -> void:
|
||||
|
||||
|
||||
func _on_continue() -> void:
|
||||
GameState.pending_load_path = "" # clear stale load path from previous Load selection
|
||||
var saves := SessionManager.list_game_dirs()
|
||||
if saves.is_empty():
|
||||
return
|
||||
@@ -56,13 +58,19 @@ func _on_continue() -> void:
|
||||
get_tree().change_scene_to_file(GAME_SCENE)
|
||||
|
||||
|
||||
var _list_built: bool = false # guard against queue_free() race on rapid reopen
|
||||
|
||||
|
||||
func _on_load_game_browse() -> void:
|
||||
_build_saves_list()
|
||||
if not _list_built:
|
||||
_build_saves_list()
|
||||
_list_built = true
|
||||
_load_panel.visible = true
|
||||
|
||||
|
||||
func _on_load_back() -> void:
|
||||
_load_panel.visible = false
|
||||
_list_built = false # allow rebuild on next open
|
||||
|
||||
|
||||
func _on_quit() -> void:
|
||||
@@ -87,18 +95,24 @@ func _build_saves_list() -> void:
|
||||
var btn := Button.new()
|
||||
btn.text = _format_save_entry(save)
|
||||
btn.add_theme_font_size_override("font_size", FONT_SIZE_BTN)
|
||||
btn.add_theme_color_override("font_color", BTN_NORMAL_COLOR)
|
||||
btn.pressed.connect(_on_save_selected.bind(save))
|
||||
var has_save_file: bool = not save.get("newest_save", "").is_empty()
|
||||
if has_save_file:
|
||||
btn.add_theme_color_override("font_color", BTN_NORMAL_COLOR)
|
||||
btn.pressed.connect(_on_save_selected.bind(save))
|
||||
else:
|
||||
btn.add_theme_color_override("font_color", BTN_DISABLED_COLOR)
|
||||
btn.disabled = true
|
||||
_saves_list.add_child(btn)
|
||||
|
||||
|
||||
func _on_save_selected(save: Dictionary) -> void:
|
||||
var game_id: String = save.get("game_id", "")
|
||||
var save_file: String = save.get("newest_save", "quicksave.sav")
|
||||
var save_file: String = save.get("newest_save", "")
|
||||
if save_file.is_empty():
|
||||
push_error("MainMenu: save entry '%s' has no newest_save — load cancelled" % game_id)
|
||||
return
|
||||
SessionManager.resume_game(game_id)
|
||||
# #257: Signal main.gd to send LOAD_GAME on scene startup
|
||||
if not save_file.is_empty():
|
||||
GameState.pending_load_path = "user://saves/" + game_id + "/" + save_file
|
||||
GameState.pending_load_path = "user://saves/" + game_id + "/" + save_file
|
||||
get_tree().change_scene_to_file(GAME_SCENE)
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user