From fdc919c35fdb924343069c8fc62b7ad8ad415041 Mon Sep 17 00:00:00 2001 From: nathan Date: Mon, 18 May 2026 19:22:27 -0700 Subject: [PATCH] Document world time persistence --- AGRARIAN_DEVELOPMENT_ROADMAP.md | 4 ++- Docs/PersistenceDesignDocument.md | 4 +++ Scripts/verify_world_time_persistence.py | 43 ++++++++++++++++++++++++ 3 files changed, 50 insertions(+), 1 deletion(-) create mode 100644 Scripts/verify_world_time_persistence.py diff --git a/AGRARIAN_DEVELOPMENT_ROADMAP.md b/AGRARIAN_DEVELOPMENT_ROADMAP.md index e65c826..f05b841 100644 --- a/AGRARIAN_DEVELOPMENT_ROADMAP.md +++ b/AGRARIAN_DEVELOPMENT_ROADMAP.md @@ -755,7 +755,9 @@ Target deliverable: A small group can join a server, spawn into one biome, gathe persist stable `ResourceNodeId`, remaining harvest count, and MVP respawn flag through `FAgrarianSavedResourceNode`, then restore depletion to matching map-authored nodes on load. -- [ ] Save world time. +- [x] Save world time. World saves persist `UAgrarianSaveGame::WorldHours` + from `AAgrarianGameState::WorldHours` and restore it on server authority + during world load. - [ ] Save weather seed/state. - [ ] Save containers. - [ ] Add server-side save interval. diff --git a/Docs/PersistenceDesignDocument.md b/Docs/PersistenceDesignDocument.md index ffbc220..a13486b 100644 --- a/Docs/PersistenceDesignDocument.md +++ b/Docs/PersistenceDesignDocument.md @@ -429,6 +429,10 @@ from `UAgrarianInventoryComponent::Items`, and restored through values and broadcasts inventory changes so HUD/debug listeners see loaded item state. +World time is stored in `UAgrarianSaveGame::WorldHours`. The persistence +subsystem captures it from `AAgrarianGameState::WorldHours` during world save +and restores it only on authority during world load. + ## Testing Gates Minimum persistence smoke test: diff --git a/Scripts/verify_world_time_persistence.py b/Scripts/verify_world_time_persistence.py new file mode 100644 index 0000000..199506c --- /dev/null +++ b/Scripts/verify_world_time_persistence.py @@ -0,0 +1,43 @@ +from pathlib import Path + + +ROOT = Path(__file__).resolve().parents[1] + +EXPECTED = { + ROOT / "Source" / "AgrarianGame" / "AgrarianSaveGame.h": [ + "float WorldHours = 8.0f;", + ], + ROOT / "Source" / "AgrarianGame" / "AgrarianPersistenceSubsystem.cpp": [ + "SaveGame->WorldHours = GameState->WorldHours;", + "GameState->WorldHours = SaveGame->WorldHours;", + "!GameState->HasAuthority()", + ], + ROOT / "Docs" / "PersistenceDesignDocument.md": [ + "`UAgrarianSaveGame::WorldHours`", + "`AAgrarianGameState::WorldHours`", + "restores it only on authority", + ], + ROOT / "AGRARIAN_DEVELOPMENT_ROADMAP.md": [ + "[x] Save world time.", + "`UAgrarianSaveGame::WorldHours`", + "restore it on server authority", + ], +} + + +def main() -> None: + missing = [] + for path, snippets in EXPECTED.items(): + text = path.read_text(encoding="utf-8") + for snippet in snippets: + if snippet not in text: + missing.append(f"{path.relative_to(ROOT)}: {snippet}") + + if missing: + raise RuntimeError("World time persistence verification failed: " + "; ".join(missing)) + + print("PASS: world time persists through the authoritative world save state.") + + +if __name__ == "__main__": + main()