92 lines
3.8 KiB
Python
92 lines
3.8 KiB
Python
#!/usr/bin/env python3
|
|
"""Verify the MVP server-restart shelter persistence 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"
|
|
PERSISTENCE_DOC = ROOT / "Docs" / "PersistenceDesignDocument.md"
|
|
GAME_MODE_H = ROOT / "Source" / "AgrarianGame" / "AgrarianGameGameMode.h"
|
|
GAME_MODE_CPP = ROOT / "Source" / "AgrarianGame" / "AgrarianGameGameMode.cpp"
|
|
PERSISTENCE_CPP = ROOT / "Source" / "AgrarianGame" / "AgrarianPersistenceSubsystem.cpp"
|
|
SHELTER_CPP = ROOT / "Source" / "AgrarianGame" / "AgrarianShelterActor.cpp"
|
|
PERSISTENT_COMPONENT_CPP = ROOT / "Source" / "AgrarianGame" / "AgrarianPersistentActorComponent.cpp"
|
|
EDITOR_AUTOMATION_CPP = ROOT / "Source" / "AgrarianGame" / "AgrarianEditorAutomationLibrary.cpp"
|
|
LOAD_ON_START_VERIFY = ROOT / "Scripts" / "verify_load_on_server_start.py"
|
|
SHELTER_VERIFY = ROOT / "Scripts" / "verify_shelter_weather_protection.py"
|
|
CRAFT_SHELTER_VERIFY = ROOT / "Scripts" / "verify_craft_shelter_qa_gate.py"
|
|
|
|
REQUIRED = {
|
|
QA_DOC: [
|
|
"## Server Restart Shelter Persistence",
|
|
"ActorTypeId = primitive_shelter",
|
|
"bLoadWorldOnServerStart",
|
|
"SaveCurrentWorld",
|
|
"LoadCurrentWorld",
|
|
],
|
|
PERSISTENCE_DOC: [
|
|
"`bLoadWorldOnServerStart`",
|
|
"`DoesSaveExist`",
|
|
"`LoadCurrentWorld` without clearing existing map",
|
|
],
|
|
GAME_MODE_H: [
|
|
"bool bLoadWorldOnServerStart = true;",
|
|
"void RegisterPersistentActorClasses",
|
|
"void LoadWorldOnServerStart();",
|
|
],
|
|
GAME_MODE_CPP: [
|
|
"RegisterPersistentActorClasses(Persistence);",
|
|
"Persistence->RegisterWorldActorClass(TEXT(\"primitive_shelter\"), AAgrarianShelterActor::StaticClass());",
|
|
"Persistence->DoesSaveExist()",
|
|
"constexpr bool bClearExistingActors = false;",
|
|
"Persistence->LoadCurrentWorld(RestoredPlayerCount, RestoredActorCount, bClearExistingActors);",
|
|
"Persistence->SaveCurrentWorld()",
|
|
],
|
|
PERSISTENCE_CPP: [
|
|
"int32 UAgrarianPersistenceSubsystem::CaptureWorldActors",
|
|
"int32 UAgrarianPersistenceSubsystem::RestoreWorldActors",
|
|
"WorldActorClassRegistry.Find(SavedActor.ActorTypeId)",
|
|
"Component->ApplySaveState(SavedActor);",
|
|
"CaptureWorldActors(SaveGame);",
|
|
"RestoreWorldActors(SaveGame, bClearExistingActors);",
|
|
],
|
|
SHELTER_CPP: [
|
|
"PersistentActorComponent = CreateDefaultSubobject<UAgrarianPersistentActorComponent>(TEXT(\"PersistentActorComponent\"));",
|
|
"PersistentActorComponent->ActorTypeId = TEXT(\"primitive_shelter\")",
|
|
"ProtectionVolume->SetBoxExtent",
|
|
],
|
|
PERSISTENT_COMPONENT_CPP: [
|
|
"SavedActor.ActorTypeId = ActorTypeId;",
|
|
"SavedActor.Transform = GetOwner()->GetActorTransform();",
|
|
"GetOwner()->SetActorTransform(SavedActor.Transform",
|
|
],
|
|
EDITOR_AUTOMATION_CPP: [
|
|
"crafted and placed primitive_shelter",
|
|
"saved %d persistent actor(s), restored %d actor(s)",
|
|
],
|
|
LOAD_ON_START_VERIFY: ["PASS: authoritative server startup load"],
|
|
SHELTER_VERIFY: ["shelter weather protection"],
|
|
CRAFT_SHELTER_VERIFY: ["## Craft Shelter"],
|
|
ROADMAP: [
|
|
"[x] Can restart server and retain placed shelter.",
|
|
],
|
|
}
|
|
|
|
|
|
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: server-restart shelter persistence QA gate is tied to world actor persistence and load-on-start coverage.")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|