This repository has been archived on 2026-05-24. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
AgrarianGameArchive/Scripts/verify_reconnect_state_retention_qa_gate.py

97 lines
3.8 KiB
Python

#!/usr/bin/env python3
"""Verify the MVP reconnect state-retention QA gate is covered."""
from pathlib import Path
ROOT = Path(__file__).resolve().parents[1]
ROADMAP = ROOT / "AGRARIAN_DEVELOPMENT_ROADMAP.md"
QA_DOC = ROOT / "Docs" / "QA" / "MvpQaGates.md"
NETWORKING = ROOT / "Docs" / "MultiplayerNetworkingDesign.md"
GAME_MODE_H = ROOT / "Source" / "AgrarianGame" / "AgrarianGameGameMode.h"
GAME_MODE_CPP = ROOT / "Source" / "AgrarianGame" / "AgrarianGameGameMode.cpp"
PERSISTENCE_H = ROOT / "Source" / "AgrarianGame" / "AgrarianPersistenceSubsystem.h"
PERSISTENCE_CPP = ROOT / "Source" / "AgrarianGame" / "AgrarianPersistenceSubsystem.cpp"
SAVE_GAME_H = ROOT / "Source" / "AgrarianGame" / "AgrarianSaveGame.h"
INVENTORY_CPP = ROOT / "Source" / "AgrarianGame" / "AgrarianInventoryComponent.cpp"
DISCONNECT_VERIFY = ROOT / "Scripts" / "verify_disconnect_reconnect_handling.py"
IDENTITY_VERIFY = ROOT / "Scripts" / "verify_player_identity_persistence.py"
STATS_VERIFY = ROOT / "Scripts" / "verify_player_stats_persistence.py"
INVENTORY_VERIFY = ROOT / "Scripts" / "verify_inventory_persistence.py"
TWO_CLIENT_VERIFY = ROOT / "Scripts" / "verify_two_client_connection_gate.py"
REQUIRED = {
QA_DOC: [
"## Reconnect State Retention",
"Logout",
"RestartPlayer",
"transform, safe player identity, survival",
"RestoreSavedItems",
],
NETWORKING: [
"## Disconnect And Reconnect",
"player reconnect snapshot",
"preserves transform, survival, care history, and",
"inventory through `UAgrarianPersistenceSubsystem::SavePlayerSnapshot`",
"normal MVP spawn point",
],
GAME_MODE_H: [
"virtual void RestartPlayer(AController* NewPlayer) override;",
"virtual void Logout(AController* Exiting) override;",
],
GAME_MODE_CPP: [
"Super::RestartPlayer(NewPlayer)",
"Persistence->RestorePlayerSnapshot(AgrarianCharacter)",
"Persistence->SavePlayerSnapshot(AgrarianCharacter)",
"Super::Logout(Exiting)",
],
PERSISTENCE_H: [
"bool SavePlayerSnapshot(const AAgrarianGameCharacter* Character) const;",
"bool RestorePlayerSnapshot(AAgrarianGameCharacter* Character) const;",
],
PERSISTENCE_CPP: [
"SavedPlayer.Transform = Character->GetActorTransform();",
"SavedPlayer.Survival = SurvivalComponent->Survival;",
"SavedPlayer.CareHistory = SurvivalComponent->CareHistory;",
"SavedPlayer.Inventory = InventoryComponent->Items;",
"Character->SetActorTransform(SavedPlayer->Transform",
"InventoryComponent->RestoreSavedItems(SavedPlayer->Inventory);",
"return UniqueId->ToString();",
],
SAVE_GAME_H: [
"struct FAgrarianSavedPlayer",
"FAgrarianSavedPlayerIdentity Identity;",
"FTransform Transform;",
"FAgrarianSurvivalSnapshot Survival;",
"TArray<FAgrarianItemStack> Inventory;",
],
INVENTORY_CPP: [
"UAgrarianInventoryComponent::RestoreSavedItems",
"BroadcastInventoryChanged()",
],
DISCONNECT_VERIFY: ["PASS: MVP disconnect/reconnect snapshot handling"],
IDENTITY_VERIFY: ["player identity persistence"],
STATS_VERIFY: ["player stats persist"],
INVENTORY_VERIFY: ["inventory persistence"],
TWO_CLIENT_VERIFY: ["Two-Client Connection"],
ROADMAP: [
"[x] Can reconnect and retain state.",
],
}
def main() -> None:
missing: list[str] = []
for path, snippets in REQUIRED.items():
text = path.read_text(encoding="utf-8")
for snippet in snippets:
if snippet not in text:
missing.append(f"{path.relative_to(ROOT)} missing {snippet!r}")
if missing:
raise SystemExit("FAILED: " + "; ".join(missing))
print("OK: reconnect state-retention QA gate is tied to logout/restart snapshots and persistence coverage.")
if __name__ == "__main__":
main()