M1b: Brücke und Hülle #6

Merged
steven merged 21 commits from m1b-bruecke-und-huelle into main 2026-10-01 11:46:02 +00:00
2 changed files with 34 additions and 5 deletions
Showing only changes of commit 754d7f1e92 - Show all commits
+17 -4
View File
@@ -25,6 +25,9 @@ var hud: Hud
var _player_key: PackedByteArray var _player_key: PackedByteArray
var _next_dig_tick := 0 var _next_dig_tick := 0
## True while an unusable save could not be set aside. Saving is refused
## then, so that the unusable save is never overwritten.
var _save_blocked := false
func _ready() -> void: func _ready() -> void:
@@ -72,7 +75,8 @@ func _unhandled_input(event: InputEvent) -> void:
func _notification(what: int) -> void: func _notification(what: int) -> void:
if what == NOTIFICATION_WM_CLOSE_REQUEST and session != null: if what == NOTIFICATION_WM_CLOSE_REQUEST and session != null:
save_game() if not save_game():
push_warning("the game could not be saved on close")
_write_recording() _write_recording()
@@ -90,9 +94,14 @@ func _start_from_save() -> bool:
var loaded := GwSession.new() var loaded := GwSession.new()
if not loaded.start_loaded(store.read_save()): if not loaded.start_loaded(store.read_save()):
var aside := store.set_aside_save() var aside := store.set_aside_save()
if aside.is_empty():
_save_blocked = true
push_warning("save not usable (%s) and could not be set aside; saving is off" % loaded.last_error())
else:
push_warning("save not usable (%s), kept as %s" % [loaded.last_error(), aside]) push_warning("save not usable (%s), kept as %s" % [loaded.last_error(), aside])
hud.flash("LOAD_FAILED") hud.flash("LOAD_FAILED")
return false return false
_save_blocked = false
_enter(loaded) _enter(loaded)
return true return true
@@ -112,8 +121,9 @@ func _enter(next: GwSession) -> void:
func _run_tick() -> void: func _run_tick() -> void:
_apply(session.step()) _apply(session.step())
if session.tick() % AUTOSAVE_TICKS == 0: if session.tick() % AUTOSAVE_TICKS == 0 and not save_game():
save_game() hud.flash("SAVE_FAILED")
push_warning("the automatic save failed")
func _apply(events: Array[Dictionary]) -> void: func _apply(events: Array[Dictionary]) -> void:
@@ -153,8 +163,11 @@ func dig_at(tile: Vector2i) -> void:
_next_dig_tick = session.tick() + GwSession.DIG_COOLDOWN_TICKS _next_dig_tick = session.tick() + GwSession.DIG_COOLDOWN_TICKS
## Writes the running world as the save. Returns false if nothing was written. ## Writes the running world as the save. Returns false if nothing was
## written, also while an unusable save could not be set aside.
func save_game() -> bool: func save_game() -> bool:
if _save_blocked:
return false
return store.write_save(session.save()) return store.write_save(session.save())
+16
View File
@@ -58,3 +58,19 @@ func test_an_unusable_save_is_set_aside_and_a_new_world_starts() -> void:
check_eq(main.hud.message(), tr("LOAD_FAILED"), "the player is told") check_eq(main.hud.message(), tr("LOAD_FAILED"), "the player is told")
_stop_main(main) _stop_main(main)
TestFiles.remove_dir(directory) TestFiles.remove_dir(directory)
func test_an_unusable_save_that_cannot_be_set_aside_is_never_overwritten() -> void:
var directory := TestFiles.temporary_dir("stuck")
var store := SaveStore.new(directory)
store.write_save(PackedByteArray([1, 2, 3]))
# A folder under the set-aside name keeps the unusable save from moving.
DirAccess.make_dir_absolute(directory.path_join(SaveStore.SAVE_FILE + ".broken"))
var main := _start_main(directory)
await tree.process_frame
check(main.session.is_running(), "a new world runs")
check(not main.save_game(), "saving is refused")
check_eq(store.read_save(), PackedByteArray([1, 2, 3]), "the unusable save is untouched")
check_eq(main.hud.message(), tr("LOAD_FAILED"), "the player is told")
_stop_main(main)
TestFiles.remove_dir(directory)