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,304 @@
1
+ # Localization Testing Guide
2
+
3
+ ## Overview
4
+
5
+ Localization testing ensures games work correctly across languages, regions, and cultures. Beyond translation, it validates text display, cultural appropriateness, and regional compliance.
6
+
7
+ ## Test Categories
8
+
9
+ ### Linguistic Testing
10
+
11
+ | Category | Focus | Examples |
12
+ | -------------------- | ----------------------- | ------------------------------ |
13
+ | Translation accuracy | Meaning preserved | Idioms, game terminology |
14
+ | Grammar/spelling | Language correctness | Verb tense, punctuation |
15
+ | Consistency | Same terms throughout | "Health" vs "HP" vs "Life" |
16
+ | Context | Meaning in game context | Item names, skill descriptions |
17
+
18
+ ### Functional Testing
19
+
20
+ | Category | Focus | Examples |
21
+ | -------------- | ----------------------- | --------------------------- |
22
+ | Text display | Fits in UI | Button labels, dialog boxes |
23
+ | Font support | Characters render | CJK, Cyrillic, Arabic |
24
+ | Text expansion | Longer translations | German is ~30% longer |
25
+ | RTL support | Right-to-left languages | Arabic, Hebrew layouts |
26
+
27
+ ### Cultural Testing
28
+
29
+ | Category | Focus | Examples |
30
+ | -------------------- | ------------------ | ------------------------- |
31
+ | Cultural sensitivity | Offensive content | Gestures, symbols, colors |
32
+ | Regional compliance | Legal requirements | Ratings, gambling laws |
33
+ | Date/time formats | Local conventions | DD/MM/YYYY vs MM/DD/YYYY |
34
+ | Number formats | Decimal separators | 1,000.00 vs 1.000,00 |
35
+
36
+ ## Test Scenarios
37
+
38
+ ### Text Display
39
+
40
+ ```
41
+ SCENARIO: Text Fits UI Elements
42
+ GIVEN all localized strings
43
+ WHEN displayed in target language
44
+ THEN text fits within UI boundaries
45
+ AND no truncation or overflow occurs
46
+ AND text remains readable
47
+
48
+ SCENARIO: Dynamic Text Insertion
49
+ GIVEN template "Player {name} scored {points} points"
50
+ WHEN name="Alexander" and points=1000
51
+ THEN German: "Spieler Alexander hat 1.000 Punkte erzielt"
52
+ AND text fits UI element
53
+ AND variables are correctly formatted for locale
54
+
55
+ SCENARIO: Plural Forms
56
+ GIVEN English "1 coin" / "5 coins"
57
+ WHEN displaying in Polish (4 plural forms)
58
+ THEN correct plural form is used
59
+ AND all plural forms are translated
60
+ ```
61
+
62
+ ### Character Support
63
+
64
+ ```
65
+ SCENARIO: CJK Character Rendering
66
+ GIVEN Japanese localization
67
+ WHEN displaying text with kanji/hiragana/katakana
68
+ THEN all characters render correctly
69
+ AND no missing glyphs (tofu boxes)
70
+ AND line breaks respect CJK rules
71
+
72
+ SCENARIO: Special Characters
73
+ GIVEN text with accented characters (é, ñ, ü)
74
+ WHEN displayed in-game
75
+ THEN all characters render correctly
76
+ AND sorting works correctly
77
+
78
+ SCENARIO: User-Generated Content
79
+ GIVEN player can name character
80
+ WHEN name includes non-Latin characters
81
+ THEN name displays correctly
82
+ AND name saves/loads correctly
83
+ AND name appears correctly to other players
84
+ ```
85
+
86
+ ### Layout and Direction
87
+
88
+ ```
89
+ SCENARIO: Right-to-Left Layout
90
+ GIVEN Arabic localization
91
+ WHEN viewing UI
92
+ THEN text reads right-to-left
93
+ AND UI elements mirror appropriately
94
+ AND numbers remain left-to-right
95
+ AND mixed content (Arabic + English) displays correctly
96
+
97
+ SCENARIO: Text Expansion Accommodation
98
+ GIVEN English UI "OK" / "Cancel" buttons
99
+ WHEN localized to German "OK" / "Abbrechen"
100
+ THEN button expands or text size adjusts
101
+ AND button remains clickable
102
+ AND layout doesn't break
103
+ ```
104
+
105
+ ## Locale-Specific Formatting
106
+
107
+ ### Date and Time
108
+
109
+ | Locale | Date Format | Time Format |
110
+ | ------ | -------------- | ----------- |
111
+ | en-US | 12/25/2024 | 3:30 PM |
112
+ | en-GB | 25/12/2024 | 15:30 |
113
+ | de-DE | 25.12.2024 | 15:30 Uhr |
114
+ | ja-JP | 2024年12月25日 | 15時30分 |
115
+
116
+ ### Numbers and Currency
117
+
118
+ | Locale | Number | Currency |
119
+ | ------ | -------- | ---------- |
120
+ | en-US | 1,234.56 | $1,234.56 |
121
+ | de-DE | 1.234,56 | 1.234,56 € |
122
+ | fr-FR | 1 234,56 | 1 234,56 € |
123
+ | ja-JP | 1,234.56 | ¥1,235 |
124
+
125
+ ## Automated Test Examples
126
+
127
+ ### Unity
128
+
129
+ ```csharp
130
+ using UnityEngine.Localization;
131
+
132
+ [Test]
133
+ public void Localization_AllKeysHaveTranslations([Values("en", "de", "ja", "zh-CN")] string locale)
134
+ {
135
+ var stringTable = LocalizationSettings.StringDatabase
136
+ .GetTable("GameStrings", new Locale(locale));
137
+
138
+ foreach (var entry in stringTable)
139
+ {
140
+ Assert.IsFalse(string.IsNullOrEmpty(entry.Value.LocalizedValue),
141
+ $"Missing translation for '{entry.Key}' in {locale}");
142
+ }
143
+ }
144
+
145
+ [Test]
146
+ public void TextFits_AllUIElements()
147
+ {
148
+ var languages = new[] { "en", "de", "fr", "ja" };
149
+
150
+ foreach (var lang in languages)
151
+ {
152
+ LocalizationSettings.SelectedLocale = new Locale(lang);
153
+
154
+ foreach (var textElement in FindObjectsOfType<LocalizedText>())
155
+ {
156
+ var rectTransform = textElement.GetComponent<RectTransform>();
157
+ var textComponent = textElement.GetComponent<Text>();
158
+
159
+ Assert.LessOrEqual(
160
+ textComponent.preferredWidth,
161
+ rectTransform.rect.width,
162
+ $"Text overflows in {lang}: {textElement.name}");
163
+ }
164
+ }
165
+ }
166
+
167
+ [TestCase("en", 1, "1 coin")]
168
+ [TestCase("en", 5, "5 coins")]
169
+ [TestCase("ru", 1, "1 монета")]
170
+ [TestCase("ru", 2, "2 монеты")]
171
+ [TestCase("ru", 5, "5 монет")]
172
+ public void Pluralization_ReturnsCorrectForm(string locale, int count, string expected)
173
+ {
174
+ var result = Localization.GetPlural("coin", count, locale);
175
+ Assert.AreEqual(expected, result);
176
+ }
177
+ ```
178
+
179
+ ### Unreal
180
+
181
+ ```cpp
182
+ bool FLocalizationTest::RunTest(const FString& Parameters)
183
+ {
184
+ TArray<FString> Cultures = {"en", "de", "ja", "ko"};
185
+
186
+ for (const FString& Culture : Cultures)
187
+ {
188
+ FInternationalization::Get().SetCurrentCulture(Culture);
189
+
190
+ // Test critical strings exist
191
+ FText LocalizedText = NSLOCTEXT("Game", "StartButton", "Start");
192
+ TestFalse(
193
+ FString::Printf(TEXT("Missing StartButton in %s"), *Culture),
194
+ LocalizedText.IsEmpty());
195
+
196
+ // Test number formatting
197
+ FText NumberText = FText::AsNumber(1234567);
198
+ TestTrue(
199
+ TEXT("Number should be formatted"),
200
+ NumberText.ToString().Len() > 7); // Has separators
201
+ }
202
+
203
+ return true;
204
+ }
205
+ ```
206
+
207
+ ### Godot
208
+
209
+ ```gdscript
210
+ func test_all_translations_complete():
211
+ var locales = ["en", "de", "ja", "es"]
212
+ var keys = TranslationServer.get_all_keys()
213
+
214
+ for locale in locales:
215
+ TranslationServer.set_locale(locale)
216
+ for key in keys:
217
+ var translated = tr(key)
218
+ assert_ne(translated, key,
219
+ "Missing translation for '%s' in %s" % [key, locale])
220
+
221
+ func test_plural_forms():
222
+ TranslationServer.set_locale("ru")
223
+
224
+ assert_eq(tr_n("coin", "coins", 1), "1 монета")
225
+ assert_eq(tr_n("coin", "coins", 2), "2 монеты")
226
+ assert_eq(tr_n("coin", "coins", 5), "5 монет")
227
+ assert_eq(tr_n("coin", "coins", 21), "21 монета")
228
+
229
+ func test_text_fits_buttons():
230
+ var locales = ["en", "de", "fr"]
231
+
232
+ for locale in locales:
233
+ TranslationServer.set_locale(locale)
234
+ await get_tree().process_frame # Allow UI update
235
+
236
+ for button in get_tree().get_nodes_in_group("localized_buttons"):
237
+ var label = button.get_node("Label")
238
+ assert_lt(label.size.x, button.size.x,
239
+ "Button text overflows in %s: %s" % [locale, button.name])
240
+ ```
241
+
242
+ ## Visual Verification Checklist
243
+
244
+ ### Text Display
245
+
246
+ - [ ] No truncation in any language
247
+ - [ ] Consistent font sizing
248
+ - [ ] Proper line breaks
249
+ - [ ] No overlapping text
250
+
251
+ ### UI Layout
252
+
253
+ - [ ] Buttons accommodate longer text
254
+ - [ ] Dialog boxes resize appropriately
255
+ - [ ] Menu items align correctly
256
+ - [ ] Scrollbars appear when needed
257
+
258
+ ### Cultural Elements
259
+
260
+ - [ ] Icons are culturally appropriate
261
+ - [ ] Colors don't have negative connotations
262
+ - [ ] Gestures are region-appropriate
263
+ - [ ] No unintended political references
264
+
265
+ ## Regional Compliance
266
+
267
+ ### Ratings Requirements
268
+
269
+ | Region | Rating Board | Special Requirements |
270
+ | ------------- | ------------ | ------------------------- |
271
+ | North America | ESRB | Content descriptors |
272
+ | Europe | PEGI | Age-appropriate icons |
273
+ | Japan | CERO | Strict content guidelines |
274
+ | Germany | USK | Violence restrictions |
275
+ | China | GRAC | Approval process |
276
+
277
+ ### Common Regional Issues
278
+
279
+ | Issue | Regions Affected | Solution |
280
+ | ---------------- | ---------------- | ------------------------ |
281
+ | Blood color | Japan, Germany | Option for green/disable |
282
+ | Gambling imagery | Many regions | Remove or modify |
283
+ | Skulls/bones | China | Alternative designs |
284
+ | Nazi imagery | Germany | Remove entirely |
285
+
286
+ ## Best Practices
287
+
288
+ ### DO
289
+
290
+ - Test with native speakers
291
+ - Plan for text expansion (reserve 30% extra space)
292
+ - Use placeholder text during development (Lorem ipsum-style)
293
+ - Support multiple input methods (IME for CJK)
294
+ - Test all language combinations (UI language + audio language)
295
+ - Validate string format parameters
296
+
297
+ ### DON'T
298
+
299
+ - Hard-code strings in source code
300
+ - Assume left-to-right layout
301
+ - Concatenate translated strings
302
+ - Use machine translation without review
303
+ - Forget about date/time/number formatting
304
+ - Ignore cultural context of images and icons
@@ -0,0 +1,322 @@
1
+ # Multiplayer Testing Guide
2
+
3
+ ## Overview
4
+
5
+ Multiplayer testing validates network code, synchronization, and the player experience under real-world conditions. Network bugs are notoriously hard to reproduce—systematic testing is essential.
6
+
7
+ ## Test Categories
8
+
9
+ ### Synchronization Testing
10
+
11
+ | Test Type | Description | Priority |
12
+ | ------------------- | ---------------------------------------- | -------- |
13
+ | State sync | All clients see consistent game state | P0 |
14
+ | Position sync | Character positions match across clients | P0 |
15
+ | Event ordering | Actions occur in correct sequence | P0 |
16
+ | Conflict resolution | Simultaneous actions handled correctly | P1 |
17
+ | Late join | New players sync correctly mid-game | P1 |
18
+
19
+ ### Network Conditions
20
+
21
+ | Condition | Simulation Method | Test Focus |
22
+ | --------------- | ----------------- | ------------------------ |
23
+ | High latency | 200-500ms delay | Input responsiveness |
24
+ | Packet loss | 5-20% drop rate | State recovery |
25
+ | Jitter | Variable delay | Interpolation smoothness |
26
+ | Bandwidth limit | Throttle to 1Mbps | Data prioritization |
27
+ | Disconnection | Kill connection | Reconnection handling |
28
+
29
+ ## Test Scenarios
30
+
31
+ ### Basic Multiplayer
32
+
33
+ ```
34
+ SCENARIO: Player Join/Leave
35
+ GIVEN host has started multiplayer session
36
+ WHEN Player 2 joins
37
+ THEN Player 2 appears in host's game
38
+ AND Player 1 appears in Player 2's game
39
+ AND player counts sync across all clients
40
+
41
+ SCENARIO: State Synchronization
42
+ GIVEN 4 players in match
43
+ WHEN Player 1 picks up item at position (10, 5)
44
+ THEN item disappears for all players
45
+ AND Player 1's inventory updates for all players
46
+ AND no duplicate pickups possible
47
+
48
+ SCENARIO: Combat Synchronization
49
+ GIVEN Player 1 attacks Player 2
50
+ WHEN attack hits
51
+ THEN damage is consistent on all clients
52
+ AND hit effects play for all players
53
+ AND health updates sync within 100ms
54
+ ```
55
+
56
+ ### Network Degradation
57
+
58
+ ```
59
+ SCENARIO: High Latency Gameplay
60
+ GIVEN 200ms latency between players
61
+ WHEN Player 1 moves forward
62
+ THEN movement is smooth on Player 1's screen
63
+ AND other players see interpolated movement
64
+ AND position converges within 500ms
65
+
66
+ SCENARIO: Packet Loss Recovery
67
+ GIVEN 10% packet loss
68
+ WHEN important game event occurs (goal, kill, etc.)
69
+ THEN event is eventually delivered
70
+ AND game state remains consistent
71
+ AND no duplicate events processed
72
+
73
+ SCENARIO: Player Disconnection
74
+ GIVEN Player 2 disconnects unexpectedly
75
+ WHEN 5 seconds pass
76
+ THEN other players are notified
77
+ AND Player 2's character handles gracefully (despawn/AI takeover)
78
+ AND game continues without crash
79
+ ```
80
+
81
+ ### Edge Cases
82
+
83
+ ```
84
+ SCENARIO: Simultaneous Actions
85
+ GIVEN Player 1 and Player 2 grab same item simultaneously
86
+ WHEN both inputs arrive at server
87
+ THEN only one player receives item
88
+ AND other player sees consistent state
89
+ AND no item duplication
90
+
91
+ SCENARIO: Host Migration
92
+ GIVEN host disconnects
93
+ WHEN migration begins
94
+ THEN new host is selected
95
+ AND game state transfers correctly
96
+ AND gameplay resumes within 10 seconds
97
+
98
+ SCENARIO: Reconnection
99
+ GIVEN Player 2 disconnects temporarily
100
+ WHEN Player 2 reconnects within 60 seconds
101
+ THEN Player 2 rejoins same session
102
+ AND state is synchronized
103
+ AND progress is preserved
104
+ ```
105
+
106
+ ## Network Simulation Tools
107
+
108
+ ### Unity
109
+
110
+ ```csharp
111
+ // Using Unity Transport with Network Simulator
112
+ using Unity.Netcode;
113
+
114
+ public class NetworkSimulator : MonoBehaviour
115
+ {
116
+ [SerializeField] private int latencyMs = 100;
117
+ [SerializeField] private float packetLossPercent = 5f;
118
+ [SerializeField] private int jitterMs = 20;
119
+
120
+ void Start()
121
+ {
122
+ var transport = NetworkManager.Singleton.GetComponent<UnityTransport>();
123
+ var simulator = transport.GetSimulatorParameters();
124
+
125
+ simulator.PacketDelayMS = latencyMs;
126
+ simulator.PacketDropRate = (int)(packetLossPercent * 100);
127
+ simulator.PacketJitterMS = jitterMs;
128
+ }
129
+ }
130
+
131
+ // Test
132
+ [UnityTest]
133
+ public IEnumerator Position_UnderLatency_ConvergesWithinThreshold()
134
+ {
135
+ EnableNetworkSimulation(latencyMs: 200);
136
+
137
+ // Move player
138
+ player1.Move(Vector3.forward * 10);
139
+
140
+ yield return new WaitForSeconds(1f);
141
+
142
+ // Check other client's view
143
+ var player1OnClient2 = client2.GetPlayerPosition(player1.Id);
144
+ var actualPosition = player1.transform.position;
145
+
146
+ Assert.Less(Vector3.Distance(player1OnClient2, actualPosition), 0.5f);
147
+ }
148
+ ```
149
+
150
+ ### Unreal
151
+
152
+ ```cpp
153
+ // Using Network Emulation
154
+ void UNetworkTestHelper::EnableLatencySimulation(int32 LatencyMs)
155
+ {
156
+ if (UNetDriver* NetDriver = GetWorld()->GetNetDriver())
157
+ {
158
+ FPacketSimulationSettings Settings;
159
+ Settings.PktLag = LatencyMs;
160
+ Settings.PktLagVariance = LatencyMs / 10;
161
+ Settings.PktLoss = 0;
162
+
163
+ NetDriver->SetPacketSimulationSettings(Settings);
164
+ }
165
+ }
166
+
167
+ // Functional test for sync
168
+ void AMultiplayerSyncTest::StartTest()
169
+ {
170
+ Super::StartTest();
171
+
172
+ // Spawn item on server
173
+ APickupItem* Item = GetWorld()->SpawnActor<APickupItem>(
174
+ ItemClass, FVector(0, 0, 100));
175
+
176
+ // Wait for replication
177
+ FTimerHandle TimerHandle;
178
+ GetWorld()->GetTimerManager().SetTimer(TimerHandle, [this, Item]()
179
+ {
180
+ // Verify client has item
181
+ if (VerifyItemExistsOnAllClients(Item))
182
+ {
183
+ FinishTest(EFunctionalTestResult::Succeeded, "Item replicated");
184
+ }
185
+ else
186
+ {
187
+ FinishTest(EFunctionalTestResult::Failed, "Item not found on clients");
188
+ }
189
+ }, 2.0f, false);
190
+ }
191
+ ```
192
+
193
+ ### Godot
194
+
195
+ ```gdscript
196
+ # Network simulation
197
+ extends Node
198
+
199
+ var simulated_latency_ms := 0
200
+ var packet_loss_percent := 0.0
201
+
202
+ func _ready():
203
+ # Hook into network to simulate conditions
204
+ multiplayer.peer_packet_received.connect(_on_packet_received)
205
+
206
+ func _on_packet_received(id: int, packet: PackedByteArray):
207
+ if packet_loss_percent > 0 and randf() < packet_loss_percent / 100:
208
+ return # Drop packet
209
+
210
+ if simulated_latency_ms > 0:
211
+ await get_tree().create_timer(simulated_latency_ms / 1000.0).timeout
212
+
213
+ _process_packet(id, packet)
214
+
215
+ # Test
216
+ func test_position_sync_under_latency():
217
+ NetworkSimulator.simulated_latency_ms = 200
218
+
219
+ # Move player on host
220
+ host_player.position = Vector3(100, 0, 100)
221
+
222
+ await get_tree().create_timer(1.0).timeout
223
+
224
+ # Check client view
225
+ var client_view_position = client.get_remote_player_position(host_player.id)
226
+ var distance = host_player.position.distance_to(client_view_position)
227
+
228
+ assert_lt(distance, 1.0, "Position should converge within 1 unit")
229
+ ```
230
+
231
+ ## Dedicated Server Testing
232
+
233
+ ### Test Matrix
234
+
235
+ | Scenario | Test Focus |
236
+ | --------------------- | ------------------------------------ |
237
+ | Server startup | Clean initialization, port binding |
238
+ | Client authentication | Login validation, session management |
239
+ | Server tick rate | Consistent updates under load |
240
+ | Maximum players | Performance at player cap |
241
+ | Server crash recovery | State preservation, reconnection |
242
+
243
+ ### Load Testing
244
+
245
+ ```
246
+ SCENARIO: Maximum Players
247
+ GIVEN server configured for 64 players
248
+ WHEN 64 players connect
249
+ THEN all connections succeed
250
+ AND server tick rate stays above 60Hz
251
+ AND latency stays below 50ms
252
+
253
+ SCENARIO: Stress Test
254
+ GIVEN 64 players performing actions simultaneously
255
+ WHEN running for 10 minutes
256
+ THEN no memory leaks
257
+ AND no desync events
258
+ AND server CPU below 80%
259
+ ```
260
+
261
+ ## Matchmaking Testing
262
+
263
+ ```
264
+ SCENARIO: Skill-Based Matching
265
+ GIVEN players with skill ratings [1000, 1050, 2000, 2100]
266
+ WHEN matchmaking runs
267
+ THEN [1000, 1050] are grouped together
268
+ AND [2000, 2100] are grouped together
269
+
270
+ SCENARIO: Region Matching
271
+ GIVEN players from US-East, US-West, EU
272
+ WHEN matchmaking runs
273
+ THEN players prefer same-region matches
274
+ AND cross-region only when necessary
275
+ AND latency is acceptable for all players
276
+
277
+ SCENARIO: Queue Timeout
278
+ GIVEN player waiting in queue
279
+ WHEN 3 minutes pass without match
280
+ THEN matchmaking expands search criteria
281
+ AND player is notified of expanded search
282
+ ```
283
+
284
+ ## Security Testing
285
+
286
+ | Vulnerability | Test Method |
287
+ | ---------------- | --------------------------- |
288
+ | Speed hacking | Validate movement on server |
289
+ | Teleportation | Check position delta limits |
290
+ | Damage hacking | Server-authoritative damage |
291
+ | Packet injection | Validate packet checksums |
292
+ | Replay attacks | Use unique session tokens |
293
+
294
+ ## Performance Metrics
295
+
296
+ | Metric | Good | Acceptable | Poor |
297
+ | --------------------- | --------- | ---------- | ---------- |
298
+ | Round-trip latency | < 50ms | < 100ms | > 150ms |
299
+ | Sync delta | < 100ms | < 200ms | > 500ms |
300
+ | Packet loss tolerance | < 5% | < 10% | > 15% |
301
+ | Bandwidth per player | < 10 KB/s | < 50 KB/s | > 100 KB/s |
302
+ | Server tick rate | 60+ Hz | 30+ Hz | < 20 Hz |
303
+
304
+ ## Best Practices
305
+
306
+ ### DO
307
+
308
+ - Test with real network conditions, not just localhost
309
+ - Simulate worst-case scenarios (high latency + packet loss)
310
+ - Use server-authoritative design for competitive games
311
+ - Implement lag compensation for fast-paced games
312
+ - Test host migration paths
313
+ - Log network events for debugging
314
+
315
+ ### DON'T
316
+
317
+ - Trust client data for important game state
318
+ - Assume stable connections
319
+ - Skip testing with maximum player counts
320
+ - Ignore edge cases (simultaneous actions)
321
+ - Test only in ideal network conditions
322
+ - Forget to test reconnection flows