From 0a40d2ae6c8abe6e878131d26739186d544463e4 Mon Sep 17 00:00:00 2001 From: nathan Date: Tue, 19 May 2026 13:55:15 -0700 Subject: [PATCH] Add craft shelter QA gate --- AGRARIAN_DEVELOPMENT_ROADMAP.md | 2 +- Docs/QA/MvpQaGates.md | 17 ++++++ Scripts/verify_craft_shelter_qa_gate.py | 70 +++++++++++++++++++++++++ 3 files changed, 88 insertions(+), 1 deletion(-) create mode 100644 Scripts/verify_craft_shelter_qa_gate.py diff --git a/AGRARIAN_DEVELOPMENT_ROADMAP.md b/AGRARIAN_DEVELOPMENT_ROADMAP.md index d2b8433..0f81e7f 100644 --- a/AGRARIAN_DEVELOPMENT_ROADMAP.md +++ b/AGRARIAN_DEVELOPMENT_ROADMAP.md @@ -859,7 +859,7 @@ Target deliverable: A small group can join a server, spawn into one biome, gathe - [x] Can connect two clients. Added a two-client connection QA gate and Windows helper that checks the packaged client, launches two client instances against the same `play.agrariangame.com:7777` or LAN endpoint, and ties the manual observation steps to the multiplayer latency smoke plan. - [x] Can gather resources. Added a resource gathering QA gate tied to Ground Zero wood/fiber nodes, server-authoritative resource interaction, replicated harvest depletion, inventory grants, resource persistence coverage, and the natural shelter playable-loop smoke test. - [x] Can craft a fire. Added a craft-fire QA gate tied to `DA_Recipe_Campfire`, the player recipe setup, `BP_Campfire`, replicated campfire lit/fuel state, fire interaction prompts, campfire persistence, and fire-risk QA coverage. -- [ ] Can craft a shelter. +- [x] Can craft a shelter. Added a craft-shelter QA gate tied to primitive frame/wall/roof/shelter recipes, native build placement, `BP_PrimitiveShelter`, shelter persistence/protection hooks, and the natural shelter playable-loop smoke test. - [ ] Can survive one full day/night cycle. - [ ] Can die from survival pressure. - [ ] Can reconnect and retain state. diff --git a/Docs/QA/MvpQaGates.md b/Docs/QA/MvpQaGates.md index 4ad5dab..45b65ab 100644 --- a/Docs/QA/MvpQaGates.md +++ b/Docs/QA/MvpQaGates.md @@ -91,6 +91,23 @@ Required evidence: This gate is gameplay/server-relevant and should be covered by the next server package deployment. +## Craft Shelter + +The craft-shelter gate proves the MVP can build a primitive shelter path from +resources through recipes and world placement. + +Required evidence: + +- Primitive frame, wall panel, roof panel, and shelter recipes exist. +- `BP_PrimitiveShelter` derives from the native shelter actor. +- Building placement consumes active buildable cost on the server. +- Shelter actors persist through the world-actor persistence path. +- `Scripts/verify_playable_loop_smoke.py` runs the natural shelter loop using + wood, fiber, wildlife, shelter-piece recipes, and the primitive shelter class. + +This gate is gameplay/server-relevant and should be covered by the next server +package deployment. + ## Craft Fire The craft-fire gate proves the MVP can produce or use a campfire through the diff --git a/Scripts/verify_craft_shelter_qa_gate.py b/Scripts/verify_craft_shelter_qa_gate.py new file mode 100644 index 0000000..93cdae9 --- /dev/null +++ b/Scripts/verify_craft_shelter_qa_gate.py @@ -0,0 +1,70 @@ +#!/usr/bin/env python3 +"""Verify the MVP craft-shelter 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" +SMOKE = ROOT / "Scripts" / "verify_playable_loop_smoke.py" +BUILD_CPP = ROOT / "Source" / "AgrarianGame" / "AgrarianBuildingPlacementComponent.cpp" +SHELTER_CPP = ROOT / "Source" / "AgrarianGame" / "AgrarianShelterActor.cpp" +SHELTER_H = ROOT / "Source" / "AgrarianGame" / "AgrarianShelterActor.h" +BLUEPRINT_SETUP = ROOT / "Scripts" / "setup_playable_blueprints.py" +PERSISTENCE_VERIFY = ROOT / "Scripts" / "verify_shelter_weather_protection.py" + +REQUIRED = { + QA_DOC: [ + "## Craft Shelter", + "Primitive frame, wall panel, roof panel, and shelter recipes", + "BP_PrimitiveShelter", + "verify_playable_loop_smoke.py", + ], + SMOKE: [ + "DA_Recipe_PrimitiveShelter", + "DA_Recipe_PrimitiveFrame", + "DA_Recipe_PrimitiveWallPanel", + "DA_Recipe_PrimitiveRoofPanel", + "run_natural_shelter_loop_smoke_test", + ], + BUILD_CPP: [ + "ServerPlaceBuildable_Implementation", + "PlacementCost", + "SpawnActor", + ], + SHELTER_H: [ + "class AAgrarianShelterActor", + ], + SHELTER_CPP: [ + "PersistentActorComponent->ActorTypeId = TEXT(\"primitive_shelter\")", + "ProtectionVolume->SetBoxExtent", + ], + BLUEPRINT_SETUP: [ + "BP_PrimitiveShelter", + "unreal.AgrarianShelterActor", + ], + PERSISTENCE_VERIFY: [ + "shelter", + "weather protection", + ], + ROADMAP: [ + "[x] Can craft a 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: craft-shelter QA gate is covered by recipes, placement, and smoke-test hooks.") + + +if __name__ == "__main__": + main()