From 5de5c11faae205df3d312ea17bcc645290d51c44 Mon Sep 17 00:00:00 2001 From: nathan Date: Tue, 19 May 2026 14:14:17 -0700 Subject: [PATCH] Add target player count stability QA gate --- AGRARIAN_DEVELOPMENT_ROADMAP.md | 2 +- Docs/QA/MvpQaGates.md | 29 ++++++++ ...y_server_stability_player_count_qa_gate.py | 72 +++++++++++++++++++ 3 files changed, 102 insertions(+), 1 deletion(-) create mode 100644 Scripts/verify_server_stability_player_count_qa_gate.py diff --git a/AGRARIAN_DEVELOPMENT_ROADMAP.md b/AGRARIAN_DEVELOPMENT_ROADMAP.md index 4604926..bb0238e 100644 --- a/AGRARIAN_DEVELOPMENT_ROADMAP.md +++ b/AGRARIAN_DEVELOPMENT_ROADMAP.md @@ -873,7 +873,7 @@ Target deliverable: A small group can join a server, spawn into one biome, gathe nodes, campfires, shelters, wildlife, water sources, weather exposure zones, and wildlife spawn managers, then added verifier coverage to prevent the deprecated assignment style from returning. -- [ ] Server remains stable with target test player count. +- [x] Server remains stable with target test player count. Added a target player count server-stability QA gate using the MVP audience definition: 2-player minimum proof, 4-player closed-test smoke target, and 8-player stretch test only after the server path is stable, with evidence tied to server launch, two-client connection, reconnect retention, critical log scanning, active service state, and UDP `7777` listener checks. ## 0.1.R Knowledge And Skill Foundation diff --git a/Docs/QA/MvpQaGates.md b/Docs/QA/MvpQaGates.md index 43101b1..dbed107 100644 --- a/Docs/QA/MvpQaGates.md +++ b/Docs/QA/MvpQaGates.md @@ -251,3 +251,32 @@ Required evidence: This gate is both client and server relevant. It must be re-run for final milestone packages before sending an investor demo as stable. + +## Target Player Count Server Stability + +The target player count server stability gate proves the MVP server can hold +the defined early test population long enough to exercise the core survival loop +without a crash, disconnect cascade, or critical log spam. + +MVP target: + +- minimum proof: 2 players connected to the same server; +- target closed-test smoke group: 4 players on one server; +- stretch test: 8 players only after the dedicated/listen server path is + stable. + +Required evidence: + +- The server launch gate passes on the target host. +- The two-client connection gate passes at minimum. +- For closed-test readiness, repeat the same smoke with 4 connected clients. +- During the run, connected clients exercise join, gather, craft/use fire, + craft/place shelter, survival pressure, disconnect, and reconnect where + possible. +- Run the critical log scanner on the captured client and server logs. +- Server-side UDP `7777` remains listening and the service remains active after + the smoke. + +This gate is server-relevant and should be re-run after every server package +deployment that changes gameplay, persistence, networking, map content, or +server startup behavior. diff --git a/Scripts/verify_server_stability_player_count_qa_gate.py b/Scripts/verify_server_stability_player_count_qa_gate.py new file mode 100644 index 0000000..b0e5ccc --- /dev/null +++ b/Scripts/verify_server_stability_player_count_qa_gate.py @@ -0,0 +1,72 @@ +#!/usr/bin/env python3 +"""Verify the MVP target player count server-stability 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" +MVP_DEF = ROOT / "Docs" / "SixMonthMvpDefinition.md" +LATENCY_DOC = ROOT / "Docs" / "Ops" / "MultiplayerLatencyTestPlan.md" +SERVER_GATE = ROOT / "Scripts" / "verify_server_launch_gate.py" +TWO_CLIENT_GATE = ROOT / "Scripts" / "verify_two_client_connection_gate.py" +RECONNECT_GATE = ROOT / "Scripts" / "verify_reconnect_state_retention_qa_gate.py" +LOG_GATE = ROOT / "Scripts" / "verify_critical_log_spam_qa_gate.py" +LOG_SCANNER = ROOT / "Scripts" / "scan_critical_log_spam.py" + +REQUIRED = { + QA_DOC: [ + "## Target Player Count Server Stability", + "minimum proof: 2 players connected to the same server", + "target closed-test smoke group: 4 players on one server", + "stretch test: 8 players", + "UDP `7777` remains listening", + ], + MVP_DEF: [ + "minimum proof: 2 players connected to the same server", + "target closed-test smoke group: 4 players on one server", + "stretch test: 8 players", + ], + LATENCY_DOC: [ + "Connect two packaged Windows clients.", + "Confirm both clients see the same world time and weather.", + "Core interactions eventually reconcile", + ], + SERVER_GATE: [ + "agrarian-game-server.service", + "0.0.0.0:7777/udp", + ], + TWO_CLIENT_GATE: [ + "## Two-Client Connection", + "play.agrariangame.com:7777", + ], + RECONNECT_GATE: [ + "## Reconnect State Retention", + ], + LOG_GATE: [ + "## Thirty-Minute Critical Log Soak", + ], + LOG_SCANNER: [ + "no critical log spam detected", + ], + ROADMAP: [ + "[x] Server remains stable with target test player count.", + ], +} + + +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: target player count server-stability QA gate is documented and tied to launch, connection, reconnect, and log-soak coverage.") + + +if __name__ == "__main__": + main()