Ship the 0.8.0 first-hour and campaign milestone
Add the campaign shell, pause-safe checkpoint resume, post-shift campaign continue, confirmed campaign reset, difficulty presets, searchable Help, content-matrix validation, recovery events, contextual dialogue, policy/debrief context and eligible-event previews. Extend persistence with atomic separate files and add campaign/checkpoint/tutorial smokes. Headless 247/247, Python 94/94, tutorial/campaign/session/scenario smokes green.
This commit is contained in:
1 parent
86332cd401
commit
aa51ee331e
38 files changed
+1361
-1144
No files matched your search
+31
-2
@@ -4,6 +4,8 @@ extends Node
|
||||
|
||||
const SHIFT_RESULTS_FILE := "shift_results.json"
|
||||
const SETTINGS_FILE := "settings.json"
|
||||
const CAMPAIGN_FILE := "campaign.json"
|
||||
const SHIFT_STATE_FILE := "shift_state.json"
|
||||
|
||||
func _load_json(file_name: String) -> Variant:
|
||||
var path := "user://" + file_name
|
||||
@@ -17,13 +19,17 @@ func _load_json(file_name: String) -> Variant:
|
||||
|
||||
func _save_json(file_name: String, data: Variant) -> Error:
|
||||
var path := "user://" + file_name
|
||||
var temp := path + ".tmp"
|
||||
var text := JSON.stringify(data, "\t")
|
||||
var f := FileAccess.open(path, FileAccess.WRITE)
|
||||
var f := FileAccess.open(temp, FileAccess.WRITE)
|
||||
if f == null:
|
||||
return FileAccess.get_open_error()
|
||||
f.store_string(text)
|
||||
f.close()
|
||||
return OK
|
||||
# Replace the target only after the complete JSON has been written, so a
|
||||
# crash cannot leave a partial save in place.
|
||||
return DirAccess.rename_absolute(ProjectSettings.globalize_path(temp),
|
||||
ProjectSettings.globalize_path(path))
|
||||
|
||||
## Load previous shift results. Returns Array of Dictionaries or [].
|
||||
func load_shift_results() -> Array:
|
||||
@@ -38,6 +44,29 @@ func save_shift_result(result: Dictionary) -> Error:
|
||||
results.append(result)
|
||||
return _save_json(SHIFT_RESULTS_FILE, results)
|
||||
|
||||
## Campaign/session progression (separate from settings and shift history).
|
||||
func load_campaign() -> Dictionary:
|
||||
var data = _load_json(CAMPAIGN_FILE)
|
||||
return data if data is Dictionary else {}
|
||||
|
||||
func save_campaign(data: Dictionary) -> Error:
|
||||
return _save_json(CAMPAIGN_FILE, data)
|
||||
|
||||
func reset_campaign() -> Error:
|
||||
return _save_json(CAMPAIGN_FILE, {})
|
||||
|
||||
## Mid-shift checkpoint. Kept separate so a completed shift history is never
|
||||
## overwritten by a resumable snapshot.
|
||||
func load_shift_state() -> Dictionary:
|
||||
var data = _load_json(SHIFT_STATE_FILE)
|
||||
return data if data is Dictionary else {}
|
||||
|
||||
func save_shift_state(data: Dictionary) -> Error:
|
||||
return _save_json(SHIFT_STATE_FILE, data)
|
||||
|
||||
func clear_shift_state() -> Error:
|
||||
return _save_json(SHIFT_STATE_FILE, {})
|
||||
|
||||
## Defaults for player settings. Kept in code so a missing or partial
|
||||
## settings.json still produces a usable config.
|
||||
const DEFAULT_SETTINGS := {
|
||||
|
||||
Reference in new issue
Block a user