@zigrivers/scaffold 3.4.1 → 3.5.1

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