@zigrivers/scaffold 3.4.1 → 3.5.0

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 (194) hide show
  1. package/README.md +91 -0
  2. package/content/knowledge/game/game-accessibility.md +328 -0
  3. package/content/knowledge/game/game-ai-patterns.md +542 -0
  4. package/content/knowledge/game/game-asset-pipeline.md +359 -0
  5. package/content/knowledge/game/game-audio-design.md +342 -0
  6. package/content/knowledge/game/game-binary-vcs-strategy.md +396 -0
  7. package/content/knowledge/game/game-design-document.md +260 -0
  8. package/content/knowledge/game/game-domain-patterns.md +297 -0
  9. package/content/knowledge/game/game-economy-design.md +355 -0
  10. package/content/knowledge/game/game-engine-selection.md +242 -0
  11. package/content/knowledge/game/game-input-systems.md +357 -0
  12. package/content/knowledge/game/game-level-content-design.md +455 -0
  13. package/content/knowledge/game/game-liveops-analytics.md +280 -0
  14. package/content/knowledge/game/game-localization.md +323 -0
  15. package/content/knowledge/game/game-milestone-definitions.md +337 -0
  16. package/content/knowledge/game/game-modding-ugc.md +390 -0
  17. package/content/knowledge/game/game-narrative-design.md +404 -0
  18. package/content/knowledge/game/game-networking.md +391 -0
  19. package/content/knowledge/game/game-performance-budgeting.md +378 -0
  20. package/content/knowledge/game/game-platform-certification.md +417 -0
  21. package/content/knowledge/game/game-project-structure.md +360 -0
  22. package/content/knowledge/game/game-save-systems.md +452 -0
  23. package/content/knowledge/game/game-testing-strategy.md +470 -0
  24. package/content/knowledge/game/game-ui-patterns.md +475 -0
  25. package/content/knowledge/game/game-vr-ar-design.md +313 -0
  26. package/content/knowledge/review/review-art-bible.md +305 -0
  27. package/content/knowledge/review/review-game-design.md +303 -0
  28. package/content/knowledge/review/review-game-economy.md +272 -0
  29. package/content/knowledge/review/review-netcode.md +280 -0
  30. package/content/knowledge/review/review-platform-cert.md +341 -0
  31. package/content/methodology/custom-defaults.yml +25 -0
  32. package/content/methodology/deep.yml +25 -0
  33. package/content/methodology/game-overlay.yml +145 -0
  34. package/content/methodology/mvp.yml +25 -0
  35. package/content/pipeline/architecture/ai-behavior-design.md +87 -0
  36. package/content/pipeline/architecture/netcode-spec.md +86 -0
  37. package/content/pipeline/architecture/review-netcode.md +78 -0
  38. package/content/pipeline/foundation/performance-budgets.md +91 -0
  39. package/content/pipeline/modeling/narrative-bible.md +84 -0
  40. package/content/pipeline/pre/game-design-document.md +89 -0
  41. package/content/pipeline/pre/review-gdd.md +74 -0
  42. package/content/pipeline/quality/analytics-telemetry.md +98 -0
  43. package/content/pipeline/quality/live-ops-plan.md +99 -0
  44. package/content/pipeline/quality/platform-cert-prep.md +129 -0
  45. package/content/pipeline/quality/playtest-plan.md +83 -0
  46. package/content/pipeline/specification/art-bible.md +87 -0
  47. package/content/pipeline/specification/audio-design.md +96 -0
  48. package/content/pipeline/specification/content-structure-design.md +141 -0
  49. package/content/pipeline/specification/economy-design.md +104 -0
  50. package/content/pipeline/specification/game-accessibility.md +82 -0
  51. package/content/pipeline/specification/game-ui-spec.md +97 -0
  52. package/content/pipeline/specification/input-controls-spec.md +81 -0
  53. package/content/pipeline/specification/localization-plan.md +113 -0
  54. package/content/pipeline/specification/modding-ugc-spec.md +116 -0
  55. package/content/pipeline/specification/online-services-spec.md +104 -0
  56. package/content/pipeline/specification/review-economy.md +87 -0
  57. package/content/pipeline/specification/review-game-ui.md +73 -0
  58. package/content/pipeline/specification/save-system-spec.md +116 -0
  59. package/dist/cli/commands/adopt.d.ts.map +1 -1
  60. package/dist/cli/commands/adopt.js +25 -0
  61. package/dist/cli/commands/adopt.js.map +1 -1
  62. package/dist/cli/commands/adopt.test.js +28 -1
  63. package/dist/cli/commands/adopt.test.js.map +1 -1
  64. package/dist/cli/commands/build.test.js +3 -0
  65. package/dist/cli/commands/build.test.js.map +1 -1
  66. package/dist/cli/commands/init.d.ts +1 -0
  67. package/dist/cli/commands/init.d.ts.map +1 -1
  68. package/dist/cli/commands/init.js +6 -0
  69. package/dist/cli/commands/init.js.map +1 -1
  70. package/dist/cli/commands/init.test.js +12 -1
  71. package/dist/cli/commands/init.test.js.map +1 -1
  72. package/dist/cli/commands/knowledge.test.js +8 -0
  73. package/dist/cli/commands/knowledge.test.js.map +1 -1
  74. package/dist/cli/commands/next.d.ts.map +1 -1
  75. package/dist/cli/commands/next.js +19 -5
  76. package/dist/cli/commands/next.js.map +1 -1
  77. package/dist/cli/commands/next.test.js +56 -0
  78. package/dist/cli/commands/next.test.js.map +1 -1
  79. package/dist/cli/commands/rework.d.ts.map +1 -1
  80. package/dist/cli/commands/rework.js +11 -2
  81. package/dist/cli/commands/rework.js.map +1 -1
  82. package/dist/cli/commands/rework.test.js +5 -0
  83. package/dist/cli/commands/rework.test.js.map +1 -1
  84. package/dist/cli/commands/run.d.ts.map +1 -1
  85. package/dist/cli/commands/run.js +54 -4
  86. package/dist/cli/commands/run.js.map +1 -1
  87. package/dist/cli/commands/run.test.js +384 -0
  88. package/dist/cli/commands/run.test.js.map +1 -1
  89. package/dist/cli/commands/skip.test.js +3 -0
  90. package/dist/cli/commands/skip.test.js.map +1 -1
  91. package/dist/cli/commands/status.d.ts.map +1 -1
  92. package/dist/cli/commands/status.js +16 -3
  93. package/dist/cli/commands/status.js.map +1 -1
  94. package/dist/cli/commands/status.test.js +55 -0
  95. package/dist/cli/commands/status.test.js.map +1 -1
  96. package/dist/cli/output/auto.d.ts +3 -0
  97. package/dist/cli/output/auto.d.ts.map +1 -1
  98. package/dist/cli/output/auto.js +9 -0
  99. package/dist/cli/output/auto.js.map +1 -1
  100. package/dist/cli/output/context.d.ts +6 -0
  101. package/dist/cli/output/context.d.ts.map +1 -1
  102. package/dist/cli/output/context.js.map +1 -1
  103. package/dist/cli/output/context.test.js +87 -0
  104. package/dist/cli/output/context.test.js.map +1 -1
  105. package/dist/cli/output/error-display.test.js +3 -0
  106. package/dist/cli/output/error-display.test.js.map +1 -1
  107. package/dist/cli/output/interactive.d.ts +3 -0
  108. package/dist/cli/output/interactive.d.ts.map +1 -1
  109. package/dist/cli/output/interactive.js +76 -0
  110. package/dist/cli/output/interactive.js.map +1 -1
  111. package/dist/cli/output/json.d.ts +3 -0
  112. package/dist/cli/output/json.d.ts.map +1 -1
  113. package/dist/cli/output/json.js +9 -0
  114. package/dist/cli/output/json.js.map +1 -1
  115. package/dist/config/loader.d.ts.map +1 -1
  116. package/dist/config/loader.js +3 -2
  117. package/dist/config/loader.js.map +1 -1
  118. package/dist/config/schema.d.ts +641 -15
  119. package/dist/config/schema.d.ts.map +1 -1
  120. package/dist/config/schema.js +26 -1
  121. package/dist/config/schema.js.map +1 -1
  122. package/dist/config/schema.test.js +192 -1
  123. package/dist/config/schema.test.js.map +1 -1
  124. package/dist/core/assembly/overlay-loader.d.ts +24 -0
  125. package/dist/core/assembly/overlay-loader.d.ts.map +1 -0
  126. package/dist/core/assembly/overlay-loader.js +190 -0
  127. package/dist/core/assembly/overlay-loader.js.map +1 -0
  128. package/dist/core/assembly/overlay-loader.test.d.ts +2 -0
  129. package/dist/core/assembly/overlay-loader.test.d.ts.map +1 -0
  130. package/dist/core/assembly/overlay-loader.test.js +106 -0
  131. package/dist/core/assembly/overlay-loader.test.js.map +1 -0
  132. package/dist/core/assembly/overlay-resolver.d.ts +15 -0
  133. package/dist/core/assembly/overlay-resolver.d.ts.map +1 -0
  134. package/dist/core/assembly/overlay-resolver.js +58 -0
  135. package/dist/core/assembly/overlay-resolver.js.map +1 -0
  136. package/dist/core/assembly/overlay-resolver.test.d.ts +2 -0
  137. package/dist/core/assembly/overlay-resolver.test.d.ts.map +1 -0
  138. package/dist/core/assembly/overlay-resolver.test.js +246 -0
  139. package/dist/core/assembly/overlay-resolver.test.js.map +1 -0
  140. package/dist/core/assembly/overlay-state-resolver.d.ts +26 -0
  141. package/dist/core/assembly/overlay-state-resolver.d.ts.map +1 -0
  142. package/dist/core/assembly/overlay-state-resolver.js +63 -0
  143. package/dist/core/assembly/overlay-state-resolver.js.map +1 -0
  144. package/dist/core/assembly/overlay-state-resolver.test.d.ts +2 -0
  145. package/dist/core/assembly/overlay-state-resolver.test.d.ts.map +1 -0
  146. package/dist/core/assembly/overlay-state-resolver.test.js +256 -0
  147. package/dist/core/assembly/overlay-state-resolver.test.js.map +1 -0
  148. package/dist/core/assembly/preset-loader.d.ts +1 -0
  149. package/dist/core/assembly/preset-loader.d.ts.map +1 -1
  150. package/dist/core/assembly/preset-loader.js +2 -0
  151. package/dist/core/assembly/preset-loader.js.map +1 -1
  152. package/dist/core/dependency/eligibility.test.js +3 -0
  153. package/dist/core/dependency/eligibility.test.js.map +1 -1
  154. package/dist/e2e/game-pipeline.test.d.ts +10 -0
  155. package/dist/e2e/game-pipeline.test.d.ts.map +1 -0
  156. package/dist/e2e/game-pipeline.test.js +298 -0
  157. package/dist/e2e/game-pipeline.test.js.map +1 -0
  158. package/dist/e2e/init.test.js +3 -0
  159. package/dist/e2e/init.test.js.map +1 -1
  160. package/dist/project/adopt.d.ts +3 -1
  161. package/dist/project/adopt.d.ts.map +1 -1
  162. package/dist/project/adopt.js +29 -1
  163. package/dist/project/adopt.js.map +1 -1
  164. package/dist/project/adopt.test.js +51 -1
  165. package/dist/project/adopt.test.js.map +1 -1
  166. package/dist/types/config.d.ts +50 -4
  167. package/dist/types/config.d.ts.map +1 -1
  168. package/dist/types/config.test.d.ts +2 -0
  169. package/dist/types/config.test.d.ts.map +1 -0
  170. package/dist/types/config.test.js +97 -0
  171. package/dist/types/config.test.js.map +1 -0
  172. package/dist/utils/eligible.d.ts +3 -2
  173. package/dist/utils/eligible.d.ts.map +1 -1
  174. package/dist/utils/eligible.js +18 -4
  175. package/dist/utils/eligible.js.map +1 -1
  176. package/dist/utils/errors.d.ts +4 -0
  177. package/dist/utils/errors.d.ts.map +1 -1
  178. package/dist/utils/errors.js +31 -0
  179. package/dist/utils/errors.js.map +1 -1
  180. package/dist/utils/errors.test.js +4 -1
  181. package/dist/utils/errors.test.js.map +1 -1
  182. package/dist/wizard/questions.d.ts +4 -0
  183. package/dist/wizard/questions.d.ts.map +1 -1
  184. package/dist/wizard/questions.js +59 -1
  185. package/dist/wizard/questions.js.map +1 -1
  186. package/dist/wizard/questions.test.js +178 -4
  187. package/dist/wizard/questions.test.js.map +1 -1
  188. package/dist/wizard/wizard.d.ts +1 -0
  189. package/dist/wizard/wizard.d.ts.map +1 -1
  190. package/dist/wizard/wizard.js +4 -1
  191. package/dist/wizard/wizard.js.map +1 -1
  192. package/dist/wizard/wizard.test.js +102 -4
  193. package/dist/wizard/wizard.test.js.map +1 -1
  194. package/package.json +1 -1
@@ -0,0 +1,475 @@
1
+ ---
2
+ name: game-ui-patterns
3
+ description: HUD patterns, menu hierarchy, controller-first navigation, settings screens, split-screen adaptation, and in-game commerce flows
4
+ topics: [game-dev, ui, hud, menus, controller-navigation, settings]
5
+ ---
6
+
7
+ Game UI serves two fundamentally different purposes simultaneously: it must convey critical gameplay information without obscuring the game world (the HUD), and it must provide navigable menu systems that work equally well with mouse, gamepad, touch, and keyboard (the menu layer). Unlike web or mobile app UI where mouse/touch is assumed, game UI must be designed controller-first for any title shipping on console — focus management, D-pad navigation flow, and button prompt adaptation are not optional features bolted on later but architectural decisions made at the start of UI development.
8
+
9
+ ## Summary
10
+
11
+ ### HUD Design Patterns
12
+
13
+ The HUD (Heads-Up Display) is the persistent or semi-persistent overlay that conveys gameplay state during active play. Four primary HUD philosophies exist, and most games blend them:
14
+
15
+ 1. **Minimal HUD** — Shows only essential information (health, ammo) in small, unobtrusive elements at screen edges. Maximizes immersion. Used in narrative games, horror, exploration titles. Examples: Journey, Limbo, Inside.
16
+
17
+ 2. **Contextual HUD** — Elements appear only when relevant and fade when not needed. Health bar appears when damaged and fades after recovery. Ammo count appears when weapon is drawn. Reduces visual noise while maintaining information access. Examples: Dead Space (contextual + diegetic), Horizon Zero Dawn.
18
+
19
+ 3. **Diegetic HUD** — Information is embedded in the game world itself rather than overlaid on the screen. Health displayed on the character's back (Dead Space), ammo on the weapon model, map as a physical object the character holds. Maximum immersion but limited information density and potential readability issues.
20
+
21
+ 4. **Meta HUD** — Traditional full-screen overlay with persistent bars, numbers, and icons. Health bar, mana bar, minimap, quest tracker, cooldown indicators, buff timers all visible simultaneously. Maximizes information density at the cost of screen real estate. Standard for MMOs, MOBAs, strategy games, complex RPGs. Examples: World of Warcraft, Diablo, League of Legends.
22
+
23
+ ### HUD Element Placement Conventions
24
+
25
+ Screen regions have established conventions that players have internalized over decades:
26
+
27
+ - **Top-left**: Health, shields, player status — the first place players look for survival information
28
+ - **Top-right**: Minimap, compass, or objective markers — spatial/navigation information
29
+ - **Bottom-left**: Chat, text log, or interaction prompts in multiplayer games
30
+ - **Bottom-right**: Ammo, ability cooldowns, weapon status — action-related information
31
+ - **Bottom-center**: Action bar, hotbar, or quick-access abilities (MMO/ARPG pattern)
32
+ - **Center**: Crosshair, hit markers, interaction prompts (contextual, appears and disappears)
33
+ - **Top-center**: Notifications, boss health bars, objective updates (temporary)
34
+ - **Screen edges**: Damage direction indicators (red vignette or directional arrows)
35
+
36
+ Breaking these conventions is possible but creates a learning curve. Document any non-standard placement decisions and validate with playtesting.
37
+
38
+ ### Menu Hierarchy Conventions
39
+
40
+ Game menus follow a standard hierarchy that players expect:
41
+
42
+ - **Main Menu**: New Game, Continue, Load Game, Options/Settings, Credits, Quit
43
+ - **Pause Menu**: Resume, Settings, Save, Load, Quit to Main Menu
44
+ - **Settings**: Graphics, Audio, Controls, Gameplay, Accessibility (each a sub-screen)
45
+ - **Inventory/Character**: Equipment, Stats, Skills/Abilities, Crafting, Quest Log
46
+ - **Map**: World map, area map, fast travel, markers/waypoints
47
+ - **Social/Multiplayer**: Friends list, party, clan/guild, matchmaking, leaderboards
48
+
49
+ ### Controller-First Navigation
50
+
51
+ Controller navigation requires explicit focus management — there is no cursor to hover arbitrary elements. Every interactive element must be reachable via D-pad movement in a logical spatial flow.
52
+
53
+ **Core principles:**
54
+ - Every screen has exactly one focused element at all times
55
+ - D-pad movement follows spatial layout (up goes to the element above, left goes to the element to the left)
56
+ - Wrap-around is optional but should be consistent (if right wraps on one screen, it should wrap on all screens)
57
+ - Confirm (A/Cross) and Back (B/Circle) must work on every screen without exception
58
+ - Shoulder buttons (L1/R1) switch between tabs or major sections
59
+ - The "Back" action should always return to the parent screen — never trap the player
60
+
61
+ ## Deep Guidance
62
+
63
+ ### Focus Management Architecture
64
+
65
+ Controller navigation requires a focus system that tracks which UI element is currently selected and handles directional input to move focus.
66
+
67
+ ```csharp
68
+ // FocusManager.cs — Controller-first UI focus management
69
+ // Attach to a root UI canvas; manages focus across all child elements
70
+
71
+ using UnityEngine;
72
+ using UnityEngine.UI;
73
+ using UnityEngine.EventSystems;
74
+ using System.Collections.Generic;
75
+
76
+ public class FocusManager : MonoBehaviour
77
+ {
78
+ [Header("Focus Settings")]
79
+ [SerializeField] private float inputRepeatDelay = 0.4f;
80
+ [SerializeField] private float inputRepeatRate = 0.1f;
81
+ [SerializeField] private AudioClip focusMoveSound;
82
+ [SerializeField] private AudioClip confirmSound;
83
+ [SerializeField] private AudioClip backSound;
84
+
85
+ private Selectable _currentFocus;
86
+ private float _nextInputTime;
87
+ private Stack<Selectable> _focusHistory = new();
88
+
89
+ public Selectable CurrentFocus => _currentFocus;
90
+
91
+ /// <summary>
92
+ /// Set initial focus when a screen opens.
93
+ /// Call this from every menu screen's OnEnable.
94
+ /// </summary>
95
+ public void SetInitialFocus(Selectable element)
96
+ {
97
+ if (element == null) return;
98
+
99
+ _currentFocus = element;
100
+ EventSystem.current.SetSelectedGameObject(element.gameObject);
101
+ HighlightElement(element);
102
+ }
103
+
104
+ /// <summary>
105
+ /// Push current focus onto history stack before navigating
106
+ /// to a sub-menu. Call RestoreFocus() when returning.
107
+ /// </summary>
108
+ public void PushFocus()
109
+ {
110
+ if (_currentFocus != null)
111
+ _focusHistory.Push(_currentFocus);
112
+ }
113
+
114
+ /// <summary>
115
+ /// Restore focus to the element that was active before
116
+ /// the sub-menu was opened.
117
+ /// </summary>
118
+ public void RestoreFocus()
119
+ {
120
+ if (_focusHistory.Count > 0)
121
+ {
122
+ var previous = _focusHistory.Pop();
123
+ if (previous != null && previous.gameObject.activeInHierarchy)
124
+ SetInitialFocus(previous);
125
+ }
126
+ }
127
+
128
+ private void Update()
129
+ {
130
+ // Guard: only process when a UI element is focused
131
+ if (_currentFocus == null) return;
132
+
133
+ // Ensure EventSystem selection stays in sync
134
+ if (EventSystem.current.currentSelectedGameObject != _currentFocus.gameObject)
135
+ {
136
+ var selected = EventSystem.current.currentSelectedGameObject;
137
+ if (selected != null)
138
+ {
139
+ var selectable = selected.GetComponent<Selectable>();
140
+ if (selectable != null)
141
+ {
142
+ _currentFocus = selectable;
143
+ HighlightElement(selectable);
144
+ }
145
+ }
146
+ }
147
+ }
148
+
149
+ private void HighlightElement(Selectable element)
150
+ {
151
+ // Visual feedback: scale pulse, outline, glow, etc.
152
+ // Implementation depends on your UI style
153
+ element.Select();
154
+ }
155
+
156
+ public void PlayNavigationSound()
157
+ {
158
+ if (focusMoveSound != null)
159
+ AudioSource.PlayClipAtPoint(focusMoveSound, Vector3.zero, 0.5f);
160
+ }
161
+ }
162
+ ```
163
+
164
+ ### D-Pad Navigation Flow Design
165
+
166
+ Designing D-pad flow requires thinking about UI layout as a grid or graph of navigable nodes, not as a freeform canvas.
167
+
168
+ **Grid-based layouts** (inventory, shop, skill tree):
169
+ - Arrange items in a strict grid
170
+ - D-pad moves exactly one cell in the pressed direction
171
+ - Wrap behavior: horizontal wrap within rows, vertical wrap optional
172
+ - When navigating off the grid edge, focus moves to the nearest adjacent panel element
173
+
174
+ **List-based layouts** (settings, save slots, quest log):
175
+ - Up/Down scrolls through list items
176
+ - Left/Right may adjust values (sliders, toggles) or switch panels
177
+ - Scrolling long lists: move focus to the last visible item, then scroll the list while keeping focus on the bottom-visible element
178
+
179
+ **Tab-based layouts** (settings categories, inventory tabs):
180
+ - L1/R1 (or shoulder bumpers) switch between tabs
181
+ - Focus resets to the first element of the new tab (or remembers last position per tab)
182
+ - Visual indicator shows which tab is active
183
+
184
+ **Radial menus** (weapon wheels, ability selectors):
185
+ - Right stick position maps to a sector of the wheel
186
+ - Release to confirm selection
187
+ - Highlight follows stick direction in real time
188
+ - Works poorly with D-pad — provide an alternative sequential selection
189
+
190
+ ### Settings Screen Structure
191
+
192
+ A well-organized settings screen follows industry conventions that players expect. Each category should be a tab accessible via shoulder buttons.
193
+
194
+ **Graphics settings (PC — console exposes a subset):**
195
+
196
+ ```yaml
197
+ graphics_settings:
198
+ display:
199
+ - resolution: [dropdown, system-detected options]
200
+ - display_mode: [fullscreen, borderless, windowed]
201
+ - v_sync: [off, on, adaptive]
202
+ - frame_rate_limit: [30, 60, 120, 144, unlimited]
203
+ - hdr: [off, on] # only if display supports it
204
+ - monitor_selection: [dropdown, numbered]
205
+
206
+ quality_presets:
207
+ - preset: [low, medium, high, ultra, custom]
208
+ # Selecting a preset fills all values below
209
+ # Changing any individual value switches preset to "custom"
210
+
211
+ rendering:
212
+ - texture_quality: [low, medium, high, ultra]
213
+ - shadow_quality: [off, low, medium, high, ultra]
214
+ - shadow_distance: [slider, meters]
215
+ - anti_aliasing: [off, FXAA, TAA, MSAA_2x, MSAA_4x]
216
+ - ambient_occlusion: [off, SSAO, HBAO+]
217
+ - global_illumination: [off, screen-space, Lumen/RT]
218
+ - reflection_quality: [off, SSR, RT_reflections]
219
+ - volumetric_effects: [off, low, high]
220
+ - post_processing: [low, medium, high]
221
+ - view_distance: [slider, low-ultra]
222
+ - foliage_density: [low, medium, high, ultra]
223
+ - particle_quality: [low, medium, high]
224
+ - motion_blur: [off, low, medium, high]
225
+ - depth_of_field: [off, on]
226
+ - film_grain: [off, on, slider]
227
+ - chromatic_aberration: [off, on]
228
+
229
+ performance_overlay:
230
+ - show_fps: [off, on]
231
+ - show_gpu_temp: [off, on] # if available
232
+ - show_frame_time: [off, on]
233
+ ```
234
+
235
+ **Audio settings:**
236
+
237
+ ```yaml
238
+ audio_settings:
239
+ volume:
240
+ - master: [slider, 0-100]
241
+ - music: [slider, 0-100]
242
+ - sfx: [slider, 0-100]
243
+ - voice: [slider, 0-100]
244
+ - ambient: [slider, 0-100]
245
+ - ui: [slider, 0-100]
246
+
247
+ output:
248
+ - speaker_setup: [stereo, 5.1, 7.1, headphones]
249
+ - dynamic_range: [full, night_mode, compressed] # night mode = reduced dynamic range
250
+ - spatial_audio: [off, platform_default, Dolby_Atmos]
251
+
252
+ subtitles:
253
+ - show_subtitles: [off, dialogue_only, all_audio]
254
+ - subtitle_size: [small, medium, large, extra_large]
255
+ - subtitle_background: [off, translucent, opaque]
256
+ - speaker_name: [off, on]
257
+ - sound_captions: [off, on] # "[footsteps approaching]", "[explosion]"
258
+ ```
259
+
260
+ **Controls settings:**
261
+
262
+ ```yaml
263
+ controls_settings:
264
+ controller:
265
+ - invert_y_axis: [off, on]
266
+ - sensitivity_horizontal: [slider]
267
+ - sensitivity_vertical: [slider]
268
+ - aim_sensitivity_multiplier: [slider] # separate from look sens
269
+ - dead_zone_inner: [slider, 0.05-0.30]
270
+ - dead_zone_outer: [slider, 0.85-0.99]
271
+ - vibration: [off, on]
272
+ - vibration_intensity: [slider, 0-100]
273
+ - trigger_effect: [off, on] # DualSense adaptive triggers
274
+ - button_layout: [default, southpaw, custom_remap]
275
+
276
+ keyboard_mouse:
277
+ - mouse_sensitivity: [slider]
278
+ - mouse_acceleration: [off, on] # default OFF for games
279
+ - key_bindings: [rebindable list of all actions]
280
+ - swap_mouse_buttons: [off, on]
281
+
282
+ accessibility:
283
+ - hold_vs_toggle: [per-action setting: sprint, crouch, aim]
284
+ - auto_aim_strength: [off, low, medium, high]
285
+ - input_buffering: [slider, frames]
286
+ ```
287
+
288
+ **Accessibility settings:**
289
+
290
+ ```yaml
291
+ accessibility_settings:
292
+ visual:
293
+ - colorblind_mode: [off, protanopia, deuteranopia, tritanopia]
294
+ - colorblind_intensity: [slider, 0-100]
295
+ - screen_shake: [slider, 0-100]
296
+ - camera_bob: [off, reduced, full]
297
+ - flash_reduction: [off, on]
298
+ - high_contrast_mode: [off, on]
299
+ - ui_scale: [slider, 75-150%]
300
+ - hud_opacity: [slider, 0-100%]
301
+
302
+ audio:
303
+ - mono_audio: [off, on] # collapses stereo for single-ear hearing
304
+ - visual_sound_indicators: [off, on] # directional icons for sounds
305
+ # Subtitle options from audio section also apply
306
+
307
+ input:
308
+ - one_handed_mode: [off, left, right]
309
+ - auto_run: [off, on]
310
+ - simplified_controls: [off, on]
311
+ - qte_auto_complete: [off, on] # skip quick-time events
312
+ - aim_assist: [off, low, medium, high]
313
+ - lock_on_targeting: [off, on]
314
+
315
+ gameplay:
316
+ - difficulty_at_any_time: [allow changing difficulty freely]
317
+ - skip_puzzles: [off, on]
318
+ - navigation_assist: [off, on] # highlight path to objective
319
+ - extended_timers: [off, on] # double time limits
320
+ ```
321
+
322
+ ### Split-Screen UI Adaptation
323
+
324
+ Split-screen multiplayer requires UI that remains legible at half (or quarter) screen resolution.
325
+
326
+ **Adaptation strategies:**
327
+ - Scale HUD elements up proportionally (a health bar designed for 1920x1080 needs to be twice as large per-pixel at 960x1080 to remain readable)
328
+ - Reduce information density — show only critical HUD elements in split-screen, hide secondary information
329
+ - Reposition elements to avoid the split boundary — no element should be clipped by the screen split
330
+ - Pause menus in split-screen: either pause for all players (simpler) or overlay the paused player's menu over their viewport only (more complex but doesn't interrupt other players)
331
+
332
+ **Minimap in split-screen:**
333
+ - Reduce minimap size or replace with a compass bar (horizontal strip showing cardinal directions and objectives)
334
+ - Consider a shared overview map that any player can request, pausing the game
335
+
336
+ ### Damage Direction Indicators
337
+
338
+ Players need to know where damage is coming from. Common patterns:
339
+
340
+ - **Screen-edge vignette**: Red tint on the edge of the screen closest to the damage source. Simple, non-intrusive, but imprecise in 3D space.
341
+ - **Directional arc indicators**: Small UI arcs around the crosshair pointing toward the damage source. More precise, standard in shooters.
342
+ - **Hit markers**: Small X or chevrons at screen center confirming outgoing damage. Critical feedback for shooter feel.
343
+ - **Damage numbers**: Floating numbers at the world-space hit location. Standard in RPGs and looter-shooters.
344
+
345
+ ### Quest and Objective Tracking
346
+
347
+ Quest tracking UI must handle varying quest complexity without overwhelming the player.
348
+
349
+ **Single active quest highlight:**
350
+ - Show only the currently tracked quest's next objective
351
+ - Objective marker in the world (waypoint, GPS line, compass marker)
352
+ - Minimal HUD text: quest name + current step
353
+ - Players manually switch tracked quest
354
+
355
+ **Multi-quest tracker:**
356
+ - Side panel (typically right edge) listing 3–5 active quests with current objectives
357
+ - Each quest color-coded by type (main story, side quest, daily, etc.)
358
+ - World markers for all tracked quests with distance indicators
359
+ - Risk: visual clutter when multiple markers overlap — use priority stacking and distance-based filtering
360
+
361
+ ### In-Game Commerce and Store Flows
362
+
363
+ For games with microtransactions or in-game stores, the UI flow must be clear, non-deceptive, and compliant with platform regulations.
364
+
365
+ **Store UI principles:**
366
+ - Always display the real-money cost in local currency alongside any virtual currency cost
367
+ - Show the item clearly (3D preview, zoom, rotate) before purchase
368
+ - Two-step purchase confirmation: select item, then confirm on a separate dialog
369
+ - Clearly distinguish between items purchasable with earned currency vs premium currency vs real money
370
+ - Bundle pricing must show individual item values for comparison
371
+ - Owned items must be clearly marked (grayed out, "Owned" badge) to prevent accidental duplicate purchase
372
+ - Purchase history accessible from the store screen
373
+
374
+ **Platform compliance:**
375
+ - Apple App Store and Google Play require in-app purchase via their payment systems (30% revenue share) for digital goods
376
+ - Console stores (PlayStation Store, Xbox Store, Nintendo eShop) have similar requirements
377
+ - Loot box / randomized reward probabilities must be disclosed in many jurisdictions (China, Belgium, Netherlands — and expanding)
378
+ - Age-gating for purchase flows may be required depending on jurisdiction and content rating
379
+ - Parental controls must be respected — if a platform's parental controls restrict purchases, the game must honor that
380
+
381
+ ### Button Prompt System
382
+
383
+ Games shipping on multiple platforms must display the correct button prompts for the currently active input device.
384
+
385
+ **Implementation requirements:**
386
+ - Detect input device change in real time (player switches from controller to keyboard mid-game)
387
+ - Swap all on-screen button prompts within one frame of the input device change
388
+ - Support at minimum: Xbox controller, PlayStation controller, Nintendo controller, keyboard+mouse
389
+ - Use platform-appropriate iconography (Xbox A button is green circle, PlayStation Cross is blue X, etc.)
390
+ - For PC: detect specific controller type via input system (Steam Input, XInput, DirectInput) and show correct brand icons
391
+ - For text prompts (e.g., "Press [Interact]"), use the action name mapped to the current binding, not a hardcoded key name
392
+
393
+ ```gdscript
394
+ # Godot — Dynamic button prompt system
395
+ # Detects active input device and returns correct prompt texture
396
+
397
+ extends Node
398
+
399
+ enum InputDevice { KEYBOARD, XBOX, PLAYSTATION, SWITCH }
400
+
401
+ var current_device: InputDevice = InputDevice.KEYBOARD
402
+ var _last_input_frame: int = 0
403
+
404
+ # Prompt texture paths organized by device and action
405
+ var prompt_textures := {
406
+ InputDevice.KEYBOARD: {
407
+ "interact": "res://ui/prompts/kb_e.png",
408
+ "jump": "res://ui/prompts/kb_space.png",
409
+ "attack": "res://ui/prompts/mouse_left.png",
410
+ "back": "res://ui/prompts/kb_esc.png",
411
+ },
412
+ InputDevice.XBOX: {
413
+ "interact": "res://ui/prompts/xbox_a.png",
414
+ "jump": "res://ui/prompts/xbox_a.png",
415
+ "attack": "res://ui/prompts/xbox_x.png",
416
+ "back": "res://ui/prompts/xbox_b.png",
417
+ },
418
+ InputDevice.PLAYSTATION: {
419
+ "interact": "res://ui/prompts/ps_cross.png",
420
+ "jump": "res://ui/prompts/ps_cross.png",
421
+ "attack": "res://ui/prompts/ps_square.png",
422
+ "back": "res://ui/prompts/ps_circle.png",
423
+ },
424
+ InputDevice.SWITCH: {
425
+ "interact": "res://ui/prompts/switch_b.png", # Note: A/B swapped
426
+ "jump": "res://ui/prompts/switch_b.png",
427
+ "attack": "res://ui/prompts/switch_y.png",
428
+ "back": "res://ui/prompts/switch_a.png",
429
+ },
430
+ }
431
+
432
+ signal device_changed(new_device: InputDevice)
433
+
434
+ func _input(event: InputEvent) -> void:
435
+ var detected := current_device
436
+ if event is InputEventKey or event is InputEventMouseButton:
437
+ detected = InputDevice.KEYBOARD
438
+ elif event is InputEventJoypadButton or event is InputEventJoypadMotion:
439
+ detected = _detect_controller_type()
440
+
441
+ if detected != current_device:
442
+ current_device = detected
443
+ device_changed.emit(current_device)
444
+
445
+ func _detect_controller_type() -> InputDevice:
446
+ var joy_name := Input.get_joy_name(0).to_lower()
447
+ if "playstation" in joy_name or "dualsense" in joy_name or "dualshock" in joy_name:
448
+ return InputDevice.PLAYSTATION
449
+ elif "nintendo" in joy_name or "pro controller" in joy_name:
450
+ return InputDevice.SWITCH
451
+ return InputDevice.XBOX # Default fallback for XInput/generic
452
+
453
+ func get_prompt_texture(action: String) -> Texture2D:
454
+ if current_device in prompt_textures:
455
+ var device_prompts: Dictionary = prompt_textures[current_device]
456
+ if action in device_prompts:
457
+ return load(device_prompts[action])
458
+ # Fallback to keyboard
459
+ return load(prompt_textures[InputDevice.KEYBOARD].get(action, ""))
460
+ ```
461
+
462
+ ### HUD Scaling and Safe Zones
463
+
464
+ Console displays and televisions have "overscan" areas near the screen edges that may be cropped. Platform certification requires all critical UI to be within the safe zone.
465
+
466
+ **Safe zone standards:**
467
+ - **Action safe area**: 90% of screen (5% inset from each edge) — all interactive/critical UI elements must be within this area
468
+ - **Title safe area**: 80% of screen (10% inset) — text and important static information should be within this area
469
+ - Both PlayStation and Xbox certification require respecting safe areas
470
+ - PC games should offer a "safe zone adjustment" slider in settings for TV-connected setups
471
+
472
+ **HUD scale options:**
473
+ - Provide a HUD scale slider (75%–150%) in accessibility or UI settings
474
+ - Scale relative to the screen's shorter dimension to maintain proportions across aspect ratios
475
+ - Test at minimum at 720p, 1080p, 1440p, and 4K to ensure readability at all resolutions