from pathlib import Path ROOT = Path(__file__).resolve().parents[1] EXPECTED = { ROOT / "Source" / "AgrarianGame" / "AgrarianSaveGame.h": [ "struct FAgrarianSavedResourceNode", "FName ResourceNodeId = NAME_None;", "int32 RemainingHarvests = 0;", "TArray ResourceNodes;", ], ROOT / "Source" / "AgrarianGame" / "AgrarianResourceNode.h": [ "FName PersistenceNodeId = NAME_None;", "FName GetResourcePersistenceId() const;", "FAgrarianSavedResourceNode CaptureResourceSaveState() const;", "void ApplyResourceSaveState(const FAgrarianSavedResourceNode& SavedNode);", ], ROOT / "Source" / "AgrarianGame" / "AgrarianResourceNode.cpp": [ "AAgrarianResourceNode::GetResourcePersistenceId", "PersistenceNodeId != NAME_None ? PersistenceNodeId : GetFName()", "SavedNode.RemainingHarvests = RemainingHarvests;", "RemainingHarvests = FMath::Clamp", "ScheduleRespawnIfNeeded();", ], ROOT / "Source" / "AgrarianGame" / "AgrarianPersistenceSubsystem.h": [ "int32 CaptureResourceNodes(UAgrarianSaveGame* SaveGame) const;", "int32 RestoreResourceNodes(const UAgrarianSaveGame* SaveGame) const;", "void FindResourceNodes(TArray& OutResourceNodes) const;", ], ROOT / "Source" / "AgrarianGame" / "AgrarianPersistenceSubsystem.cpp": [ "SaveGame->ResourceNodes.Reset();", "SaveGame->ResourceNodes.Add(SavedNode);", "RestoreResourceNodes(SaveGame);", "TActorIterator", "ResourceNode->ApplyResourceSaveState(*SavedNode);", ], ROOT / "Scripts" / "setup_ground_zero_demo_map.py": [ 'actor.set_editor_property("persistence_node_id", spec["label"])', ], ROOT / "Scripts" / "verify_ground_zero_resources.py": [ 'actor.get_editor_property("persistence_node_id")', "persistence node id expected", ], ROOT / "Docs" / "TechnicalDesignDocument.md": [ "Resource node persistence is map/tile state", "captures only resource nodes that exist in the", ], ROOT / "Docs" / "PersistenceDesignDocument.md": [ "`FAgrarianSavedResourceNode`", "`ResourceNodeId`, remaining harvest count, and the MVP respawn flag", "matching map-authored nodes during load", ], ROOT / "Docs" / "Terrain" / "GroundZeroResourcePass.md": [ "Ground Zero resource actors receive stable `PersistenceNodeId` values", "resource nodes that exist in the loaded world", ], ROOT / "AGRARIAN_DEVELOPMENT_ROADMAP.md": [ "[x] Add resource node persistence.", "[x] Save resource depletion state if needed.", "`FAgrarianSavedResourceNode`", ], } 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("Resource node persistence verification failed: " + "; ".join(missing)) print("PASS: resource node persistence captures loaded map/tile nodes by stable id and restores depletion state.") if __name__ == "__main__": main()