bmad-method 6.0.0-alpha.17 → 6.0.0-alpha.18

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (186) hide show
  1. package/CHANGELOG.md +97 -0
  2. package/package.json +1 -1
  3. package/src/modules/bmgd/_module-installer/installer.js +160 -0
  4. package/src/modules/bmgd/_module-installer/platform-specifics/claude-code.js +23 -0
  5. package/src/modules/bmgd/_module-installer/platform-specifics/windsurf.js +18 -0
  6. package/src/modules/bmgd/agents/game-architect.agent.yaml +23 -8
  7. package/src/modules/bmgd/agents/game-designer.agent.yaml +38 -18
  8. package/src/modules/bmgd/agents/game-dev.agent.yaml +30 -14
  9. package/src/modules/bmgd/agents/game-qa.agent.yaml +64 -0
  10. package/src/modules/bmgd/agents/game-scrum-master.agent.yaml +27 -39
  11. package/src/modules/bmgd/agents/game-solo-dev.agent.yaml +56 -0
  12. package/src/modules/bmgd/docs/README.md +180 -0
  13. package/src/modules/bmgd/docs/agents-guide.md +407 -0
  14. package/src/modules/bmgd/docs/game-types-guide.md +503 -0
  15. package/src/modules/bmgd/docs/glossary.md +294 -0
  16. package/src/modules/bmgd/docs/quick-flow-guide.md +288 -0
  17. package/src/modules/bmgd/docs/quick-start.md +250 -0
  18. package/src/modules/bmgd/docs/troubleshooting.md +259 -0
  19. package/src/modules/bmgd/docs/workflow-overview.jpg +0 -0
  20. package/src/modules/bmgd/docs/workflows-guide.md +463 -0
  21. package/src/modules/bmgd/gametest/knowledge/balance-testing.md +220 -0
  22. package/src/modules/bmgd/gametest/knowledge/certification-testing.md +319 -0
  23. package/src/modules/bmgd/gametest/knowledge/compatibility-testing.md +228 -0
  24. package/src/modules/bmgd/gametest/knowledge/godot-testing.md +376 -0
  25. package/src/modules/bmgd/gametest/knowledge/input-testing.md +315 -0
  26. package/src/modules/bmgd/gametest/knowledge/localization-testing.md +304 -0
  27. package/src/modules/bmgd/gametest/knowledge/multiplayer-testing.md +322 -0
  28. package/src/modules/bmgd/gametest/knowledge/performance-testing.md +204 -0
  29. package/src/modules/bmgd/gametest/knowledge/playtesting.md +384 -0
  30. package/src/modules/bmgd/gametest/knowledge/qa-automation.md +190 -0
  31. package/src/modules/bmgd/gametest/knowledge/regression-testing.md +280 -0
  32. package/src/modules/bmgd/gametest/knowledge/save-testing.md +280 -0
  33. package/src/modules/bmgd/gametest/knowledge/smoke-testing.md +404 -0
  34. package/src/modules/bmgd/gametest/knowledge/test-priorities.md +271 -0
  35. package/src/modules/bmgd/gametest/knowledge/unity-testing.md +383 -0
  36. package/src/modules/bmgd/gametest/knowledge/unreal-testing.md +388 -0
  37. package/src/modules/bmgd/gametest/qa-index.csv +17 -0
  38. package/src/modules/bmgd/module.yaml +25 -9
  39. package/src/modules/bmgd/teams/default-party.csv +2 -0
  40. package/src/modules/bmgd/teams/team-gamedev.yaml +12 -1
  41. package/src/modules/bmgd/workflows/1-preproduction/brainstorm-game/steps/step-01-init.md +164 -0
  42. package/src/modules/bmgd/workflows/1-preproduction/brainstorm-game/steps/step-02-context.md +210 -0
  43. package/src/modules/bmgd/workflows/1-preproduction/brainstorm-game/steps/step-03-ideation.md +289 -0
  44. package/src/modules/bmgd/workflows/1-preproduction/brainstorm-game/steps/step-04-complete.md +275 -0
  45. package/src/modules/bmgd/workflows/1-preproduction/brainstorm-game/workflow.md +49 -0
  46. package/src/modules/bmgd/workflows/1-preproduction/brainstorm-game/workflow.yaml +29 -8
  47. package/src/modules/bmgd/workflows/1-preproduction/game-brief/steps/step-01-init.md +223 -0
  48. package/src/modules/bmgd/workflows/1-preproduction/game-brief/steps/step-01b-continue.md +151 -0
  49. package/src/modules/bmgd/workflows/1-preproduction/game-brief/steps/step-02-vision.md +218 -0
  50. package/src/modules/bmgd/workflows/1-preproduction/game-brief/steps/step-03-market.md +218 -0
  51. package/src/modules/bmgd/workflows/1-preproduction/game-brief/steps/step-04-fundamentals.md +231 -0
  52. package/src/modules/bmgd/workflows/1-preproduction/game-brief/steps/step-05-scope.md +242 -0
  53. package/src/modules/bmgd/workflows/1-preproduction/game-brief/steps/step-06-references.md +224 -0
  54. package/src/modules/bmgd/workflows/1-preproduction/game-brief/steps/step-07-content.md +282 -0
  55. package/src/modules/bmgd/workflows/1-preproduction/game-brief/steps/step-08-complete.md +296 -0
  56. package/src/modules/bmgd/workflows/1-preproduction/game-brief/workflow.md +62 -0
  57. package/src/modules/bmgd/workflows/1-preproduction/game-brief/workflow.yaml +40 -9
  58. package/src/modules/bmgd/workflows/2-design/gdd/steps/step-01-init.md +248 -0
  59. package/src/modules/bmgd/workflows/2-design/gdd/steps/step-01b-continue.md +173 -0
  60. package/src/modules/bmgd/workflows/2-design/gdd/steps/step-02-context.md +332 -0
  61. package/src/modules/bmgd/workflows/2-design/gdd/steps/step-03-platforms.md +245 -0
  62. package/src/modules/bmgd/workflows/2-design/gdd/steps/step-04-vision.md +229 -0
  63. package/src/modules/bmgd/workflows/2-design/gdd/steps/step-05-core-gameplay.md +258 -0
  64. package/src/modules/bmgd/workflows/2-design/gdd/steps/step-06-mechanics.md +249 -0
  65. package/src/modules/bmgd/workflows/2-design/gdd/steps/step-07-game-type.md +266 -0
  66. package/src/modules/bmgd/workflows/2-design/gdd/steps/step-08-progression.md +272 -0
  67. package/src/modules/bmgd/workflows/2-design/gdd/steps/step-09-levels.md +264 -0
  68. package/src/modules/bmgd/workflows/2-design/gdd/steps/step-10-art-audio.md +255 -0
  69. package/src/modules/bmgd/workflows/2-design/gdd/steps/step-11-technical.md +275 -0
  70. package/src/modules/bmgd/workflows/2-design/gdd/steps/step-12-epics.md +284 -0
  71. package/src/modules/bmgd/workflows/2-design/gdd/steps/step-13-metrics.md +250 -0
  72. package/src/modules/bmgd/workflows/2-design/gdd/steps/step-14-complete.md +335 -0
  73. package/src/modules/bmgd/workflows/2-design/gdd/workflow.md +61 -0
  74. package/src/modules/bmgd/workflows/2-design/gdd/workflow.yaml +27 -7
  75. package/src/modules/bmgd/workflows/2-design/narrative/steps/step-01-init.md +228 -0
  76. package/src/modules/bmgd/workflows/2-design/narrative/steps/step-01b-continue.md +163 -0
  77. package/src/modules/bmgd/workflows/2-design/narrative/steps/step-02-foundation.md +262 -0
  78. package/src/modules/bmgd/workflows/2-design/narrative/steps/step-03-story.md +238 -0
  79. package/src/modules/bmgd/workflows/2-design/narrative/steps/step-04-characters.md +297 -0
  80. package/src/modules/bmgd/workflows/2-design/narrative/steps/step-05-world.md +262 -0
  81. package/src/modules/bmgd/workflows/2-design/narrative/steps/step-06-dialogue.md +250 -0
  82. package/src/modules/bmgd/workflows/2-design/narrative/steps/step-07-environmental.md +244 -0
  83. package/src/modules/bmgd/workflows/2-design/narrative/steps/step-08-delivery.md +264 -0
  84. package/src/modules/bmgd/workflows/2-design/narrative/steps/step-09-integration.md +254 -0
  85. package/src/modules/bmgd/workflows/2-design/narrative/steps/step-10-production.md +262 -0
  86. package/src/modules/bmgd/workflows/2-design/narrative/steps/step-11-complete.md +331 -0
  87. package/src/modules/bmgd/workflows/2-design/narrative/workflow.md +57 -0
  88. package/src/modules/bmgd/workflows/2-design/narrative/workflow.yaml +53 -8
  89. package/src/modules/bmgd/workflows/3-technical/game-architecture/steps/step-01-init.md +223 -0
  90. package/src/modules/bmgd/workflows/3-technical/game-architecture/steps/step-01b-continue.md +153 -0
  91. package/src/modules/bmgd/workflows/3-technical/game-architecture/steps/step-02-context.md +262 -0
  92. package/src/modules/bmgd/workflows/3-technical/game-architecture/steps/step-03-starter.md +290 -0
  93. package/src/modules/bmgd/workflows/3-technical/game-architecture/steps/step-04-decisions.md +300 -0
  94. package/src/modules/bmgd/workflows/3-technical/game-architecture/steps/step-05-crosscutting.md +319 -0
  95. package/src/modules/bmgd/workflows/3-technical/game-architecture/steps/step-06-structure.md +304 -0
  96. package/src/modules/bmgd/workflows/3-technical/game-architecture/steps/step-07-patterns.md +349 -0
  97. package/src/modules/bmgd/workflows/3-technical/game-architecture/steps/step-08-validation.md +293 -0
  98. package/src/modules/bmgd/workflows/3-technical/game-architecture/steps/step-09-complete.md +302 -0
  99. package/src/modules/bmgd/workflows/3-technical/game-architecture/workflow.md +55 -0
  100. package/src/modules/bmgd/workflows/3-technical/game-architecture/workflow.yaml +50 -21
  101. package/src/modules/bmgd/workflows/4-production/code-review/checklist.md +23 -0
  102. package/src/modules/bmgd/workflows/4-production/code-review/instructions.xml +225 -0
  103. package/src/modules/bmgd/workflows/4-production/code-review/workflow.yaml +18 -15
  104. package/src/modules/bmgd/workflows/4-production/correct-course/checklist.md +1 -1
  105. package/src/modules/bmgd/workflows/4-production/correct-course/instructions.md +1 -1
  106. package/src/modules/bmgd/workflows/4-production/correct-course/workflow.yaml +11 -6
  107. package/src/modules/bmgd/workflows/4-production/create-story/checklist.md +332 -214
  108. package/src/modules/bmgd/workflows/4-production/create-story/instructions.xml +298 -0
  109. package/src/modules/bmgd/workflows/4-production/create-story/template.md +3 -5
  110. package/src/modules/bmgd/workflows/4-production/create-story/workflow.yaml +12 -7
  111. package/src/modules/bmgd/workflows/4-production/dev-story/checklist.md +65 -23
  112. package/src/modules/bmgd/workflows/4-production/dev-story/instructions.xml +409 -0
  113. package/src/modules/bmgd/workflows/4-production/dev-story/workflow.yaml +13 -3
  114. package/src/modules/bmgd/workflows/4-production/retrospective/instructions.md +4 -4
  115. package/src/modules/bmgd/workflows/4-production/retrospective/workflow.yaml +12 -7
  116. package/src/modules/bmgd/workflows/4-production/sprint-planning/instructions.md +32 -41
  117. package/src/modules/bmgd/workflows/4-production/sprint-planning/sprint-status-template.yaml +13 -13
  118. package/src/modules/bmgd/workflows/4-production/sprint-planning/workflow.yaml +6 -1
  119. package/src/modules/bmgd/workflows/4-production/sprint-status/instructions.md +229 -0
  120. package/src/modules/bmgd/workflows/4-production/sprint-status/workflow.yaml +35 -0
  121. package/src/modules/bmgd/workflows/bmgd-quick-flow/create-tech-spec/instructions.md +140 -0
  122. package/src/modules/bmgd/workflows/bmgd-quick-flow/create-tech-spec/workflow.yaml +27 -0
  123. package/src/modules/bmgd/workflows/bmgd-quick-flow/quick-dev/checklist.md +37 -0
  124. package/src/modules/bmgd/workflows/bmgd-quick-flow/quick-dev/instructions.md +220 -0
  125. package/src/modules/bmgd/workflows/bmgd-quick-flow/quick-dev/workflow.yaml +45 -0
  126. package/src/modules/bmgd/workflows/bmgd-quick-flow/quick-prototype/checklist.md +26 -0
  127. package/src/modules/bmgd/workflows/bmgd-quick-flow/quick-prototype/instructions.md +156 -0
  128. package/src/modules/bmgd/workflows/bmgd-quick-flow/quick-prototype/workflow.yaml +36 -0
  129. package/src/modules/bmgd/workflows/gametest/automate/checklist.md +93 -0
  130. package/src/modules/bmgd/workflows/gametest/automate/instructions.md +317 -0
  131. package/src/modules/bmgd/workflows/gametest/automate/workflow.yaml +50 -0
  132. package/src/modules/bmgd/workflows/gametest/performance/checklist.md +96 -0
  133. package/src/modules/bmgd/workflows/gametest/performance/instructions.md +323 -0
  134. package/src/modules/bmgd/workflows/gametest/performance/performance-template.md +256 -0
  135. package/src/modules/bmgd/workflows/gametest/performance/workflow.yaml +48 -0
  136. package/src/modules/bmgd/workflows/gametest/playtest-plan/checklist.md +93 -0
  137. package/src/modules/bmgd/workflows/gametest/playtest-plan/instructions.md +297 -0
  138. package/src/modules/bmgd/workflows/gametest/playtest-plan/playtest-template.md +208 -0
  139. package/src/modules/bmgd/workflows/gametest/playtest-plan/workflow.yaml +59 -0
  140. package/src/modules/bmgd/workflows/gametest/test-design/checklist.md +98 -0
  141. package/src/modules/bmgd/workflows/gametest/test-design/instructions.md +280 -0
  142. package/src/modules/bmgd/workflows/gametest/test-design/test-design-template.md +205 -0
  143. package/src/modules/bmgd/workflows/gametest/test-design/workflow.yaml +47 -0
  144. package/src/modules/bmgd/workflows/gametest/test-framework/checklist.md +103 -0
  145. package/src/modules/bmgd/workflows/gametest/test-framework/instructions.md +348 -0
  146. package/src/modules/bmgd/workflows/gametest/test-framework/workflow.yaml +48 -0
  147. package/src/modules/bmgd/workflows/gametest/test-review/checklist.md +87 -0
  148. package/src/modules/bmgd/workflows/gametest/test-review/instructions.md +272 -0
  149. package/src/modules/bmgd/workflows/gametest/test-review/test-review-template.md +203 -0
  150. package/src/modules/bmgd/workflows/gametest/test-review/workflow.yaml +48 -0
  151. package/src/modules/bmgd/workflows/workflow-status/init/instructions.md +299 -0
  152. package/src/modules/bmgd/workflows/workflow-status/init/workflow.yaml +29 -0
  153. package/src/modules/bmgd/workflows/workflow-status/instructions.md +395 -0
  154. package/src/modules/bmgd/workflows/workflow-status/paths/gamedev-brownfield.yaml +65 -0
  155. package/src/modules/bmgd/workflows/workflow-status/paths/gamedev-greenfield.yaml +71 -0
  156. package/src/modules/bmgd/workflows/workflow-status/paths/quickflow-brownfield.yaml +29 -0
  157. package/src/modules/bmgd/workflows/workflow-status/paths/quickflow-greenfield.yaml +39 -0
  158. package/src/modules/bmgd/workflows/workflow-status/project-levels.yaml +63 -0
  159. package/src/modules/bmgd/workflows/workflow-status/workflow-status-template.yaml +24 -0
  160. package/src/modules/bmgd/workflows/workflow-status/workflow.yaml +30 -0
  161. package/tools/cli/commands/install.js +9 -0
  162. package/tools/cli/installers/lib/core/installer.js +109 -109
  163. package/tools/cli/installers/lib/core/installer.js.bak +3204 -0
  164. package/tools/cli/installers/lib/modules/manager.js +16 -4
  165. package/tools/cli/lib/agent/compiler.js +99 -0
  166. package/tools/cli/lib/ui.js +78 -27
  167. package/src/modules/bmgd/workflows/2-design/gdd/instructions-gdd.md +0 -502
  168. package/src/modules/bmgd/workflows/4-production/code-review/instructions.md +0 -398
  169. package/src/modules/bmgd/workflows/4-production/create-story/instructions.md +0 -256
  170. package/src/modules/bmgd/workflows/4-production/dev-story/instructions.md +0 -267
  171. package/src/modules/bmgd/workflows/4-production/epic-tech-context/checklist.md +0 -17
  172. package/src/modules/bmgd/workflows/4-production/epic-tech-context/instructions.md +0 -164
  173. package/src/modules/bmgd/workflows/4-production/epic-tech-context/template.md +0 -76
  174. package/src/modules/bmgd/workflows/4-production/epic-tech-context/workflow.yaml +0 -58
  175. package/src/modules/bmgd/workflows/4-production/story-context/checklist.md +0 -16
  176. package/src/modules/bmgd/workflows/4-production/story-context/context-template.xml +0 -34
  177. package/src/modules/bmgd/workflows/4-production/story-context/instructions.md +0 -209
  178. package/src/modules/bmgd/workflows/4-production/story-context/workflow.yaml +0 -63
  179. package/src/modules/bmgd/workflows/4-production/story-done/instructions.md +0 -111
  180. package/src/modules/bmgd/workflows/4-production/story-done/workflow.yaml +0 -28
  181. package/src/modules/bmgd/workflows/4-production/story-ready/instructions.md +0 -117
  182. package/src/modules/bmgd/workflows/4-production/story-ready/workflow.yaml +0 -25
  183. /package/src/modules/bmgd/workflows/1-preproduction/game-brief/{template.md → templates/game-brief-template.md} +0 -0
  184. /package/src/modules/bmgd/workflows/2-design/gdd/{gdd-template.md → templates/gdd-template.md} +0 -0
  185. /package/src/modules/bmgd/workflows/2-design/narrative/{narrative-template.md → templates/narrative-template.md} +0 -0
  186. /package/src/modules/bmgd/workflows/3-technical/game-architecture/{architecture-template.md → templates/architecture-template.md} +0 -0
@@ -0,0 +1,280 @@
1
+ # Save System Testing Guide
2
+
3
+ ## Overview
4
+
5
+ Save system testing ensures data persistence, integrity, and compatibility across game versions. Save bugs are among the most frustrating for players—data loss destroys trust.
6
+
7
+ ## Test Categories
8
+
9
+ ### Data Integrity
10
+
11
+ | Test Type | Description | Priority |
12
+ | -------------------- | ------------------------------------------- | -------- |
13
+ | Round-trip | Save → Load → Verify all data matches | P0 |
14
+ | Corruption detection | Tampered/corrupted files handled gracefully | P0 |
15
+ | Partial write | Power loss during save doesn't corrupt | P0 |
16
+ | Large saves | Performance with max-size save files | P1 |
17
+ | Edge values | Min/max values for all saved fields | P1 |
18
+
19
+ ### Version Compatibility
20
+
21
+ | Scenario | Expected Behavior |
22
+ | ----------------------- | ------------------------------------- |
23
+ | Current → Current | Full compatibility |
24
+ | Old → New (upgrade) | Migration with data preservation |
25
+ | New → Old (downgrade) | Graceful rejection or limited support |
26
+ | Corrupted version field | Fallback to recovery mode |
27
+
28
+ ## Test Scenarios
29
+
30
+ ### Core Save/Load Tests
31
+
32
+ ```
33
+ SCENARIO: Basic Save Round-Trip
34
+ GIVEN player has 100 health, 50 gold, position (10, 5, 20)
35
+ AND player has inventory: ["sword", "potion", "key"]
36
+ WHEN game is saved
37
+ AND game is reloaded
38
+ THEN player health equals 100
39
+ AND player gold equals 50
40
+ AND player position equals (10, 5, 20)
41
+ AND inventory contains exactly ["sword", "potion", "key"]
42
+
43
+ SCENARIO: Save During Gameplay
44
+ GIVEN player is in combat
45
+ AND enemy has 50% health remaining
46
+ WHEN autosave triggers
47
+ AND game is reloaded
48
+ THEN combat state is restored
49
+ AND enemy health equals 50%
50
+
51
+ SCENARIO: Multiple Save Slots
52
+ GIVEN save slot 1 has character "Hero" at level 10
53
+ AND save slot 2 has character "Mage" at level 5
54
+ WHEN switching between slots
55
+ THEN correct character data loads for each slot
56
+ AND no cross-contamination between slots
57
+ ```
58
+
59
+ ### Edge Cases
60
+
61
+ ```
62
+ SCENARIO: Maximum Inventory Save
63
+ GIVEN player has 999 items in inventory
64
+ WHEN game is saved
65
+ AND game is reloaded
66
+ THEN all 999 items are preserved
67
+ AND save/load completes within 5 seconds
68
+
69
+ SCENARIO: Unicode Character Names
70
+ GIVEN player name is "プレイヤー名"
71
+ WHEN game is saved
72
+ AND game is reloaded
73
+ THEN player name displays correctly
74
+
75
+ SCENARIO: Extreme Play Time
76
+ GIVEN play time is 9999:59:59
77
+ WHEN game is saved
78
+ AND game is reloaded
79
+ THEN play time displays correctly
80
+ AND timer continues from saved value
81
+ ```
82
+
83
+ ### Corruption Recovery
84
+
85
+ ```
86
+ SCENARIO: Corrupted Save Detection
87
+ GIVEN save file has been manually corrupted
88
+ WHEN game attempts to load
89
+ THEN error is detected before loading
90
+ AND user is informed of corruption
91
+ AND game does not crash
92
+
93
+ SCENARIO: Missing Save File
94
+ GIVEN save file has been deleted externally
95
+ WHEN game attempts to load
96
+ THEN graceful error handling
97
+ AND option to start new game or restore backup
98
+
99
+ SCENARIO: Interrupted Save (Power Loss)
100
+ GIVEN save operation is interrupted mid-write
101
+ WHEN game restarts
102
+ THEN backup save is detected and offered
103
+ AND no data loss from previous valid save
104
+ ```
105
+
106
+ ## Platform-Specific Testing
107
+
108
+ ### PC (Steam/Epic)
109
+
110
+ - Cloud save sync conflicts
111
+ - Multiple Steam accounts on same PC
112
+ - Offline → Online sync
113
+ - Save location permissions (Program Files issues)
114
+
115
+ ### Console (PlayStation/Xbox/Switch)
116
+
117
+ - System-level save management
118
+ - Storage full scenarios
119
+ - User switching mid-game
120
+ - Suspend/resume with unsaved changes
121
+ - Cloud save quota limits
122
+
123
+ ### Mobile
124
+
125
+ - App termination during save
126
+ - Low storage warnings
127
+ - iCloud/Google Play sync
128
+ - Device migration
129
+
130
+ ## Automated Test Examples
131
+
132
+ ### Unity
133
+
134
+ ```csharp
135
+ [Test]
136
+ public void SaveLoad_PlayerStats_PreservesAllValues()
137
+ {
138
+ var original = new PlayerData
139
+ {
140
+ Health = 75,
141
+ MaxHealth = 100,
142
+ Gold = 1234567,
143
+ Position = new Vector3(100.5f, 0, -50.25f),
144
+ PlayTime = 36000f // 10 hours
145
+ };
146
+
147
+ SaveManager.Save(original, "test_slot");
148
+ var loaded = SaveManager.Load("test_slot");
149
+
150
+ Assert.AreEqual(original.Health, loaded.Health);
151
+ Assert.AreEqual(original.Gold, loaded.Gold);
152
+ Assert.AreEqual(original.Position, loaded.Position);
153
+ Assert.AreEqual(original.PlayTime, loaded.PlayTime, 0.01f);
154
+ }
155
+
156
+ [Test]
157
+ public void SaveLoad_CorruptedFile_HandlesGracefully()
158
+ {
159
+ File.WriteAllText(SaveManager.GetPath("corrupt"), "INVALID DATA");
160
+
161
+ Assert.Throws<SaveCorruptedException>(() =>
162
+ SaveManager.Load("corrupt"));
163
+
164
+ // Game should not crash
165
+ Assert.IsTrue(SaveManager.IsValidSaveSlot("corrupt") == false);
166
+ }
167
+ ```
168
+
169
+ ### Unreal
170
+
171
+ ```cpp
172
+ bool FSaveSystemTest::RunTest(const FString& Parameters)
173
+ {
174
+ // Create test save
175
+ USaveGame* SaveGame = UGameplayStatics::CreateSaveGameObject(
176
+ UMySaveGame::StaticClass());
177
+ UMySaveGame* MySave = Cast<UMySaveGame>(SaveGame);
178
+
179
+ MySave->PlayerLevel = 50;
180
+ MySave->Gold = 999999;
181
+ MySave->QuestsCompleted = {"Quest1", "Quest2", "Quest3"};
182
+
183
+ // Save
184
+ UGameplayStatics::SaveGameToSlot(MySave, "TestSlot", 0);
185
+
186
+ // Load
187
+ USaveGame* Loaded = UGameplayStatics::LoadGameFromSlot("TestSlot", 0);
188
+ UMySaveGame* LoadedSave = Cast<UMySaveGame>(Loaded);
189
+
190
+ TestEqual("Level preserved", LoadedSave->PlayerLevel, 50);
191
+ TestEqual("Gold preserved", LoadedSave->Gold, 999999);
192
+ TestEqual("Quests count", LoadedSave->QuestsCompleted.Num(), 3);
193
+
194
+ return true;
195
+ }
196
+ ```
197
+
198
+ ### Godot
199
+
200
+ ```gdscript
201
+ func test_save_load_round_trip():
202
+ var original = {
203
+ "health": 100,
204
+ "position": Vector3(10, 0, 20),
205
+ "inventory": ["sword", "shield"],
206
+ "quest_flags": {"intro_complete": true, "boss_defeated": false}
207
+ }
208
+
209
+ SaveManager.save_game(original, "test_save")
210
+ var loaded = SaveManager.load_game("test_save")
211
+
212
+ assert_eq(loaded.health, 100)
213
+ assert_eq(loaded.position, Vector3(10, 0, 20))
214
+ assert_eq(loaded.inventory.size(), 2)
215
+ assert_true(loaded.quest_flags.intro_complete)
216
+ assert_false(loaded.quest_flags.boss_defeated)
217
+
218
+ func test_corrupted_save_detection():
219
+ var file = FileAccess.open("user://saves/corrupt.sav", FileAccess.WRITE)
220
+ file.store_string("CORRUPTED GARBAGE DATA")
221
+ file.close()
222
+
223
+ var result = SaveManager.load_game("corrupt")
224
+
225
+ assert_null(result, "Should return null for corrupted save")
226
+ assert_false(SaveManager.is_valid_save("corrupt"))
227
+ ```
228
+
229
+ ## Migration Testing
230
+
231
+ ### Version Upgrade Matrix
232
+
233
+ | From Version | To Version | Test Focus |
234
+ | -------------- | ---------------- | ---------------------------- |
235
+ | 1.0 → 1.1 | Minor update | New fields default correctly |
236
+ | 1.x → 2.0 | Major update | Schema migration works |
237
+ | Beta → Release | Launch migration | All beta saves convert |
238
+
239
+ ### Migration Test Template
240
+
241
+ ```
242
+ SCENARIO: Save Migration v1.0 to v2.0
243
+ GIVEN save file from version 1.0
244
+ AND save contains old inventory format (array)
245
+ WHEN game version 2.0 loads the save
246
+ THEN inventory is migrated to new format (dictionary)
247
+ AND all items are preserved
248
+ AND migration is logged
249
+ AND backup of original is created
250
+ ```
251
+
252
+ ## Performance Benchmarks
253
+
254
+ | Metric | Target | Maximum |
255
+ | ------------------------ | --------------- | ------- |
256
+ | Save time (typical) | < 500ms | 2s |
257
+ | Save time (large) | < 2s | 5s |
258
+ | Load time (typical) | < 1s | 3s |
259
+ | Save file size (typical) | < 1MB | 10MB |
260
+ | Memory during save | < 50MB overhead | 100MB |
261
+
262
+ ## Best Practices
263
+
264
+ ### DO
265
+
266
+ - Use atomic saves (write to temp, then rename)
267
+ - Keep backup of previous save
268
+ - Version your save format
269
+ - Encrypt sensitive data
270
+ - Test on minimum-spec hardware
271
+ - Compress large saves
272
+
273
+ ### DON'T
274
+
275
+ - Store absolute file paths
276
+ - Save derived/calculated data
277
+ - Trust save file contents blindly
278
+ - Block gameplay during save
279
+ - Forget to handle storage-full scenarios
280
+ - Skip testing save migration paths
@@ -0,0 +1,404 @@
1
+ # Smoke Testing Guide
2
+
3
+ ## Overview
4
+
5
+ Smoke testing (Build Verification Testing) validates that a build's critical functionality works before investing time in detailed testing. A failed smoke test means "stop, this build is broken."
6
+
7
+ ## Purpose
8
+
9
+ | Goal | Description |
10
+ | ------------------- | ---------------------------------------------- |
11
+ | Fast feedback | Know within minutes if build is viable |
12
+ | Block bad builds | Prevent broken builds from reaching QA/players |
13
+ | Critical path focus | Test only what matters most |
14
+ | CI/CD integration | Automated gate before deployment |
15
+
16
+ ## Smoke Test Principles
17
+
18
+ ### What Makes a Good Smoke Test
19
+
20
+ - **Fast**: Complete in 5-15 minutes
21
+ - **Critical**: Tests only essential functionality
22
+ - **Deterministic**: Same result every run
23
+ - **Automated**: No human intervention required
24
+ - **Clear**: Pass/fail with actionable feedback
25
+
26
+ ### What to Include
27
+
28
+ | Category | Examples |
29
+ | ----------------- | ------------------------------ |
30
+ | Boot sequence | Game launches without crash |
31
+ | Core loop | Player can perform main action |
32
+ | Save/Load | Data persists correctly |
33
+ | Critical UI | Menus are navigable |
34
+ | Platform services | Connects to required services |
35
+
36
+ ### What NOT to Include
37
+
38
+ - Edge cases and boundary conditions
39
+ - Performance benchmarks (separate tests)
40
+ - Full feature coverage
41
+ - Content verification
42
+ - Balance testing
43
+
44
+ ## Smoke Test Scenarios
45
+
46
+ ### Boot and Load
47
+
48
+ ```
49
+ TEST: Game Launches
50
+ WHEN game executable is started
51
+ THEN main menu appears within 60 seconds
52
+ AND no crashes occur
53
+ AND required services connect
54
+
55
+ TEST: New Game Start
56
+ GIVEN game at main menu
57
+ WHEN "New Game" is selected
58
+ THEN gameplay loads within 30 seconds
59
+ AND player can control character
60
+
61
+ TEST: Continue Game
62
+ GIVEN existing save file
63
+ WHEN "Continue" is selected
64
+ THEN correct save loads
65
+ AND game state matches saved state
66
+ ```
67
+
68
+ ### Core Gameplay
69
+
70
+ ```
71
+ TEST: Player Movement
72
+ GIVEN player in game world
73
+ WHEN movement input applied
74
+ THEN player moves in expected direction
75
+ AND no physics glitches occur
76
+
77
+ TEST: Core Action (Game-Specific)
78
+ GIVEN player can perform primary action
79
+ WHEN action is triggered
80
+ THEN action executes correctly
81
+ AND expected results occur
82
+
83
+ Examples:
84
+ - Shooter: Can fire weapon, bullets hit targets
85
+ - RPG: Can attack enemy, damage is applied
86
+ - Puzzle: Can interact with puzzle elements
87
+ - Platformer: Can jump, platforms are solid
88
+ ```
89
+
90
+ ### Save System
91
+
92
+ ```
93
+ TEST: Save Creates File
94
+ GIVEN player makes progress
95
+ WHEN save is triggered
96
+ THEN save file is created
97
+ AND save completes without error
98
+
99
+ TEST: Load Restores State
100
+ GIVEN valid save file exists
101
+ WHEN load is triggered
102
+ THEN saved state is restored
103
+ AND gameplay can continue
104
+ ```
105
+
106
+ ### Critical UI
107
+
108
+ ```
109
+ TEST: Menu Navigation
110
+ GIVEN main menu is displayed
111
+ WHEN each menu option is selected
112
+ THEN correct screen/action occurs
113
+ AND navigation back works
114
+
115
+ TEST: Settings Persist
116
+ GIVEN settings are changed
117
+ WHEN game is restarted
118
+ THEN settings remain changed
119
+ ```
120
+
121
+ ## Automated Smoke Test Examples
122
+
123
+ ### Unity
124
+
125
+ ```csharp
126
+ using System.Collections;
127
+ using NUnit.Framework;
128
+ using UnityEngine;
129
+ using UnityEngine.UI;
130
+ using UnityEngine.TestTools;
131
+ using UnityEngine.SceneManagement;
132
+
133
+ [TestFixture]
134
+ public class SmokeTests
135
+ {
136
+ [UnityTest, Timeout(60000)]
137
+ public IEnumerator Game_Launches_ToMainMenu()
138
+ {
139
+ // Load main menu scene
140
+ SceneManager.LoadScene("MainMenu");
141
+ yield return new WaitForSeconds(5f);
142
+
143
+ // Verify menu is active
144
+ var mainMenu = GameObject.Find("MainMenuCanvas");
145
+ Assert.IsNotNull(mainMenu, "Main menu should be present");
146
+ Assert.IsTrue(mainMenu.activeInHierarchy, "Main menu should be active");
147
+ }
148
+
149
+ [UnityTest, Timeout(120000)]
150
+ public IEnumerator NewGame_LoadsGameplay()
151
+ {
152
+ // Start from main menu
153
+ SceneManager.LoadScene("MainMenu");
154
+ yield return new WaitForSeconds(2f);
155
+
156
+ // Click new game
157
+ var newGameButton = GameObject.Find("NewGameButton")
158
+ .GetComponent<Button>();
159
+ newGameButton.onClick.Invoke();
160
+
161
+ yield return new WaitForSeconds(10f);
162
+
163
+ // Verify gameplay scene loaded
164
+ Assert.AreEqual("GameplayScene", SceneManager.GetActiveScene().name);
165
+
166
+ // Verify player exists and can be controlled
167
+ var player = GameObject.FindWithTag("Player");
168
+ Assert.IsNotNull(player, "Player should exist");
169
+ }
170
+
171
+ [UnityTest, Timeout(30000)]
172
+ public IEnumerator Player_CanMove()
173
+ {
174
+ // Load gameplay
175
+ SceneManager.LoadScene("GameplayScene");
176
+ yield return new WaitForSeconds(3f);
177
+
178
+ var player = GameObject.FindWithTag("Player");
179
+ var startPos = player.transform.position;
180
+
181
+ // Simulate movement input
182
+ var controller = player.GetComponent<PlayerController>();
183
+ controller.SetMoveInput(Vector2.right);
184
+
185
+ yield return new WaitForSeconds(1f);
186
+
187
+ // Verify movement occurred
188
+ Assert.Greater(player.transform.position.x, startPos.x,
189
+ "Player should have moved");
190
+ }
191
+
192
+ [UnityTest, Timeout(30000)]
193
+ public IEnumerator SaveLoad_RoundTrip_Works()
194
+ {
195
+ // Setup test state
196
+ SceneManager.LoadScene("GameplayScene");
197
+ yield return new WaitForSeconds(2f);
198
+
199
+ var player = GameObject.FindWithTag("Player");
200
+ player.transform.position = new Vector3(100, 0, 100);
201
+
202
+ // Save
203
+ SaveManager.Save("smoke_test");
204
+ yield return null;
205
+
206
+ // Reset position
207
+ player.transform.position = Vector3.zero;
208
+
209
+ // Load
210
+ SaveManager.Load("smoke_test");
211
+ yield return null;
212
+
213
+ // Verify
214
+ Assert.AreEqual(100f, player.transform.position.x, 1f);
215
+ }
216
+ }
217
+ ```
218
+
219
+ ### Unreal
220
+
221
+ ```cpp
222
+ // SmokeTests.cpp
223
+ IMPLEMENT_SIMPLE_AUTOMATION_TEST(
224
+ FGameLaunchTest,
225
+ "Smoke.Launch.MainMenu",
226
+ EAutomationTestFlags::ApplicationContextMask | EAutomationTestFlags::SmokeFilter
227
+ )
228
+
229
+ bool FGameLaunchTest::RunTest(const FString& Parameters)
230
+ {
231
+ // Verify main menu widget exists
232
+ UWorld* World = GEngine->GetWorldContexts()[0].World();
233
+ APlayerController* PC = World->GetFirstPlayerController();
234
+
235
+ TestNotNull("Player controller exists", PC);
236
+
237
+ // Check main menu is visible
238
+ AMyHUD* HUD = Cast<AMyHUD>(PC->GetHUD());
239
+ TestTrue("Main menu is visible", HUD->IsMainMenuVisible());
240
+
241
+ return true;
242
+ }
243
+
244
+ IMPLEMENT_SIMPLE_AUTOMATION_TEST(
245
+ FPlayerMovementTest,
246
+ "Smoke.Gameplay.Movement",
247
+ EAutomationTestFlags::ApplicationContextMask | EAutomationTestFlags::SmokeFilter
248
+ )
249
+
250
+ bool FPlayerMovementTest::RunTest(const FString& Parameters)
251
+ {
252
+ APawn* Player = GetTestPlayer();
253
+ FVector StartPos = Player->GetActorLocation();
254
+
255
+ // Apply movement
256
+ APlayerController* PC = Cast<APlayerController>(Player->GetController());
257
+ PC->AddMovementInput(FVector::ForwardVector, 1.0f);
258
+
259
+ // Wait for physics
260
+ ADD_LATENT_AUTOMATION_COMMAND(FWaitForSeconds(0.5f));
261
+ // Note: FVerifyPlayerMoved is a custom latent command - implement to verify player position changed
262
+ ADD_LATENT_AUTOMATION_COMMAND(FVerifyPlayerMoved(StartPos));
263
+
264
+ return true;
265
+ }
266
+ ```
267
+
268
+ ### Godot
269
+
270
+ ```gdscript
271
+ # test_smoke.gd
272
+ extends GutTest
273
+
274
+ func test_game_launches():
275
+ # Switch to main menu
276
+ get_tree().change_scene_to_file("res://scenes/main_menu.tscn")
277
+ await get_tree().process_frame
278
+ await get_tree().create_timer(2.0).timeout
279
+
280
+ # Verify main menu loaded
281
+ var menu = get_tree().current_scene
282
+ assert_not_null(menu, "Main menu should load")
283
+ assert_eq(menu.name, "MainMenu", "Should be main menu scene")
284
+
285
+ func test_new_game_starts():
286
+ get_tree().change_scene_to_file("res://scenes/main_menu.tscn")
287
+ await get_tree().process_frame
288
+
289
+ # Find and click new game button
290
+ var button = get_tree().current_scene.get_node("NewGameButton")
291
+ button.pressed.emit()
292
+
293
+ await get_tree().create_timer(5.0).timeout
294
+
295
+ # Verify gameplay loaded
296
+ var scene = get_tree().current_scene
297
+ assert_eq(scene.name, "GameWorld", "Should load gameplay scene")
298
+
299
+ var player = scene.get_node("Player")
300
+ assert_not_null(player, "Player should exist")
301
+
302
+ func test_player_can_move():
303
+ get_tree().change_scene_to_file("res://scenes/game_world.tscn")
304
+ await get_tree().create_timer(1.0).timeout
305
+
306
+ var player = get_tree().current_scene.get_node("Player")
307
+ var start_pos = player.position
308
+
309
+ # Simulate input
310
+ Input.action_press("move_right")
311
+ await get_tree().create_timer(0.5).timeout
312
+ Input.action_release("move_right")
313
+
314
+ assert_gt(player.position.x, start_pos.x, "Player should have moved right")
315
+
316
+ func test_save_load_works():
317
+ get_tree().change_scene_to_file("res://scenes/game_world.tscn")
318
+ await get_tree().create_timer(1.0).timeout
319
+
320
+ var player = get_tree().current_scene.get_node("Player")
321
+ player.position = Vector2(500, 300)
322
+
323
+ # Save
324
+ SaveManager.save_game("smoke_test")
325
+ await get_tree().process_frame
326
+
327
+ # Reset
328
+ player.position = Vector2.ZERO
329
+
330
+ # Load
331
+ SaveManager.load_game("smoke_test")
332
+ await get_tree().process_frame
333
+
334
+ assert_almost_eq(player.position.x, 500.0, 1.0, "Position should restore")
335
+ ```
336
+
337
+ ## CI/CD Integration
338
+
339
+ ### GitHub Actions Example
340
+
341
+ ```yaml
342
+ name: Smoke Tests
343
+
344
+ on: [push, pull_request]
345
+
346
+ jobs:
347
+ smoke-test:
348
+ runs-on: ubuntu-latest
349
+ timeout-minutes: 20
350
+
351
+ steps:
352
+ - uses: actions/checkout@v4
353
+
354
+ - name: Build Game
355
+ run: ./build.sh --configuration Release
356
+
357
+ - name: Run Smoke Tests
358
+ run: |
359
+ ./game --headless --run-tests=Smoke --test-timeout=600
360
+
361
+ - name: Upload Results
362
+ if: always()
363
+ uses: actions/upload-artifact@v4
364
+ with:
365
+ name: smoke-test-results
366
+ path: test-results/
367
+ ```
368
+
369
+ ### Test Execution Order
370
+
371
+ 1. **Build verification** - Binary exists and is valid
372
+ 2. **Launch test** - Game starts without crash
373
+ 3. **Menu navigation** - Can navigate to gameplay
374
+ 4. **Core loop** - Primary mechanic works
375
+ 5. **Save/Load** - Persistence functions
376
+ 6. **Cleanup** - No resource leaks
377
+
378
+ ## Smoke Test Metrics
379
+
380
+ | Metric | Target | Action if Failed |
381
+ | -------------- | -------- | ------------------ |
382
+ | Pass rate | 100% | Block deployment |
383
+ | Execution time | < 15 min | Optimize tests |
384
+ | Flakiness | 0% | Fix or remove test |
385
+
386
+ ## Best Practices
387
+
388
+ ### DO
389
+
390
+ - Run smoke tests on every build
391
+ - Keep tests fast and focused
392
+ - Fail loudly and clearly
393
+ - Test on target platform, not just dev environment
394
+ - Include platform service connectivity
395
+ - Run before any manual QA begins
396
+
397
+ ### DON'T
398
+
399
+ - Include slow or flaky tests
400
+ - Test edge cases or rare scenarios
401
+ - Allow smoke test failures to ship
402
+ - Skip smoke tests for "small" changes
403
+ - Make smoke tests depend on external services
404
+ - Let smoke suite grow beyond 15 minutes