@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,378 @@
1
+ ---
2
+ name: game-performance-budgeting
3
+ description: Frame budget allocation, memory budgets per platform, GPU/draw call limits, loading targets, thermal constraints, and profiling tools
4
+ topics: [game-dev, performance, frame-budget, memory, gpu, optimization]
5
+ ---
6
+
7
+ Performance budgeting is the discipline of allocating fixed time, memory, and GPU resource envelopes to each game subsystem and enforcing those limits throughout development. Unlike web performance where a slow page is merely annoying, a missed frame budget in a game causes visible hitches, input lag, and motion sickness in VR. Budgets must be established at project start, measured continuously with profiling tools, and treated as hard constraints — not aspirational targets.
8
+
9
+ ## Summary
10
+
11
+ ### Frame Budget Fundamentals
12
+
13
+ Every rendering frame must complete within a fixed time window determined by the target frame rate:
14
+
15
+ - **60 fps** = 16.67 ms per frame (standard for action games, shooters)
16
+ - **30 fps** = 33.33 ms per frame (acceptable for strategy, narrative, some open-world)
17
+ - **120 fps** = 8.33 ms per frame (competitive shooters, high-refresh displays)
18
+ - **VR targets**: 72 Hz (Quest 2 minimum) = 13.89 ms, 90 Hz (standard) = 11.11 ms, 120 Hz (high-end) = 8.33 ms — missed frames in VR cause motion sickness, making these hard requirements
19
+
20
+ The frame budget is divided across the CPU and GPU. On modern hardware, CPU and GPU run in parallel — the frame time is the **longer** of the two, not their sum. However, CPU work that feeds GPU work (draw call submission, compute dispatch) creates dependencies that can serialize the pipeline.
21
+
22
+ A typical 16.67 ms budget breakdown for a 60 fps action game:
23
+
24
+ - **Game logic / simulation**: 3–4 ms (physics, AI, gameplay scripts, animation)
25
+ - **Rendering preparation**: 2–3 ms (culling, sorting, draw call setup)
26
+ - **Audio**: 1–2 ms (mixing, DSP, spatial calculations)
27
+ - **UI**: 0.5–1 ms (layout, rendering, input processing)
28
+ - **Networking**: 0.5–1 ms (send/receive, serialization, prediction)
29
+ - **Engine overhead**: 1–2 ms (garbage collection, job scheduling, memory management)
30
+ - **Headroom**: 2–4 ms (reserved for spikes, debug builds, min-spec hardware)
31
+
32
+ The headroom allocation is critical. A budget that uses 100% of the frame time on average will miss the target 50% of the time due to variance.
33
+
34
+ ### Memory Budgets by Platform
35
+
36
+ Memory budgets vary dramatically across target platforms:
37
+
38
+ - **PC (mid-range)**: 4–8 GB available to the game (total system RAM 16 GB, shared with OS and other apps)
39
+ - **PlayStation 5**: 16 GB unified memory, ~12 GB available to games (rest reserved by OS)
40
+ - **Xbox Series X**: 16 GB, split into 10 GB fast (GPU-optimal) and 6 GB standard
41
+ - **Nintendo Switch**: 4 GB total, ~3.2 GB available to games (docked and handheld share the same budget)
42
+ - **Mobile (mid-range)**: 2–3 GB available (total 4–6 GB, aggressive OS memory management)
43
+ - **Mobile (low-end)**: 1–1.5 GB available (devices with 2–3 GB total)
44
+
45
+ Memory budgets must be subdivided by subsystem: textures (typically 40–60% of total), meshes (10–20%), audio (5–10%), scripts/game state (5–10%), engine overhead (10–15%).
46
+
47
+ ### GPU and Draw Call Budgets
48
+
49
+ - **Draw calls**: 2,000–5,000 per frame on modern hardware (batching and instancing reduce this)
50
+ - **Triangle count**: 2–10 million per frame depending on platform and LOD strategy
51
+ - **Texture memory**: Budget per-platform; use streaming and virtual textures for open worlds
52
+ - **Shader complexity**: Measure in GPU ms per material; flag any material exceeding 0.5 ms in isolation
53
+ - **Post-processing**: Budget 2–4 ms total for all post-process effects combined
54
+
55
+ ### Loading Time Targets
56
+
57
+ - **Initial boot to menu**: Under 10 seconds on console (platform certification requirement areas)
58
+ - **Level load**: Under 15 seconds with SSD, under 30 seconds with HDD
59
+ - **Fast travel / respawn**: Under 3 seconds (use streaming, not full loads)
60
+ - **Asset streaming during gameplay**: Zero visible pop-in at normal movement speed
61
+
62
+ ### Mobile Thermal and Battery Constraints
63
+
64
+ Mobile devices throttle CPU and GPU when they overheat. A game that runs at 60 fps for the first five minutes and drops to 30 fps after thermal throttling has a broken performance budget.
65
+
66
+ - Target sustained performance, not peak performance
67
+ - Measure thermal state after 30 minutes of continuous play
68
+ - Budget power draw to allow 2–3 hours of gameplay per charge
69
+ - Reduce target frame rate to 30 fps on mobile unless the game genre demands 60 fps
70
+
71
+ ## Deep Guidance
72
+
73
+ ### Frame Budget Allocation Template
74
+
75
+ ```yaml
76
+ # Frame Budget Allocation — 60 fps target (16.67 ms)
77
+ # Assign budgets at project start, enforce via automated profiling
78
+
79
+ target_fps: 60
80
+ frame_budget_ms: 16.67
81
+ headroom_ms: 3.0 # Reserve for spikes and min-spec variance
82
+ usable_budget_ms: 13.67 # What subsystems share
83
+
84
+ cpu_budget:
85
+ simulation:
86
+ physics: 1.5 # Rigid bodies, collision detection
87
+ ai: 1.0 # Behavior trees, pathfinding queries (not bake)
88
+ gameplay: 1.5 # Scripts, abilities, damage, spawning
89
+ animation: 0.5 # Blend tree evaluation, IK solving
90
+ subtotal: 4.5
91
+
92
+ rendering_prep:
93
+ culling: 0.5 # Frustum + occlusion culling
94
+ sorting: 0.3 # Render queue sorting
95
+ draw_submit: 1.2 # Draw call submission to GPU
96
+ subtotal: 2.0
97
+
98
+ audio:
99
+ mix: 0.5 # Final mix, bus processing
100
+ spatial: 0.3 # 3D positioning, HRTF, occlusion
101
+ decode: 0.2 # Streaming decode (Vorbis/Opus)
102
+ subtotal: 1.0
103
+
104
+ networking:
105
+ recv_deser: 0.3 # Receive and deserialize packets
106
+ prediction: 0.2 # Client prediction + reconciliation
107
+ send_ser: 0.2 # Serialize and send packets
108
+ subtotal: 0.7
109
+
110
+ ui:
111
+ layout: 0.3 # UI layout calculation
112
+ render: 0.2 # UI draw calls
113
+ subtotal: 0.5
114
+
115
+ engine:
116
+ gc_memory: 0.5 # Garbage collection / allocator maintenance
117
+ job_scheduler: 0.2 # Job system overhead
118
+ subsystem_tick: 0.3 # Misc engine ticks
119
+ subtotal: 1.0
120
+
121
+ # CPU total: 9.7 ms (leaves 3.97 ms headroom — good)
122
+
123
+ gpu_budget:
124
+ depth_prepass: 1.0 # Z-prepass for early-Z rejection
125
+ gbuffer: 3.0 # Geometry rendering (deferred) or forward pass
126
+ lighting: 2.5 # Direct + indirect lighting, shadows
127
+ post_process: 2.0 # Bloom, tone mapping, AA, motion blur
128
+ ui_overlay: 0.5 # UI rendering on GPU
129
+ particles: 1.0 # VFX / particle rendering
130
+ # GPU total: 10.0 ms (leaves 3.67 ms headroom)
131
+
132
+ memory_budget_mb: # Example: console target (12 GB available)
133
+ textures: 5000 # ~42% — streaming pool + resident
134
+ meshes: 2000 # ~17% — vertex/index buffers, LOD chain
135
+ audio: 800 # ~7% — loaded banks + streaming buffers
136
+ animation: 400 # ~3% — skeletal data, blend trees
137
+ physics: 300 # ~2.5% — collision meshes, solver state
138
+ game_state: 500 # ~4% — entity data, scripts, save state
139
+ render_targets: 1500 # ~12.5% — GBuffer, shadow maps, post-FX
140
+ engine: 1000 # ~8% — job system, allocator overhead
141
+ headroom: 500 # ~4% — reserved for spikes
142
+ # Total: 12000 MB
143
+ ```
144
+
145
+ ### Profiling Tools by Engine
146
+
147
+ **Unity profiling stack:**
148
+ - **Unity Profiler**: Built-in CPU/GPU/memory profiler; use Deep Profile mode sparingly (10x overhead)
149
+ - **Frame Debugger**: Step through draw calls one at a time to find redundant draws
150
+ - **Memory Profiler package**: Snapshot-based memory analysis; compare snapshots to find leaks
151
+ - **Profile Analyzer**: Compare profiler captures across runs to detect regressions
152
+ - **Rendering Statistics**: Real-time overlay showing batches, triangles, set-pass calls
153
+ - **Platform-specific**: Xcode Instruments (iOS), Android GPU Inspector, RenderDoc (PC)
154
+
155
+ **Unreal profiling stack:**
156
+ - **Unreal Insights**: Modern trace-based profiler replacing the legacy stat system
157
+ - **stat commands**: `stat unit`, `stat fps`, `stat gpu`, `stat scenerendering` for real-time overlay
158
+ - **GPU Visualizer**: `ProfileGPU` command for per-pass GPU timing
159
+ - **Memreport**: Memory reporting by category
160
+ - **RenderDoc integration**: Capture and inspect individual frames
161
+ - **Platform-specific**: PIX (Xbox/Windows), Razor (PlayStation), Snapdragon Profiler (Android)
162
+
163
+ **Godot profiling stack:**
164
+ - **Built-in Profiler**: CPU time per function, physics, and rendering
165
+ - **Monitor panel**: FPS, draw calls, memory, physics bodies
166
+ - **Visual Profiler**: GPU frame breakdown
167
+ - External tools: RenderDoc, platform-native profilers
168
+
169
+ **Cross-engine tools:**
170
+ - **RenderDoc**: Free, open-source GPU frame capture and analysis (works with Vulkan, D3D11/12, OpenGL)
171
+ - **PIX**: Microsoft's GPU profiler for DirectX (Windows and Xbox)
172
+ - **Xcode Metal Debugger**: GPU profiling for Apple platforms
173
+ - **Tracy**: High-performance C++ profiler with frame-by-frame timeline view
174
+ - **Superluminal**: Low-overhead CPU profiler for Windows
175
+
176
+ ### Draw Call Optimization Strategies
177
+
178
+ Draw calls are the primary CPU-side rendering bottleneck. Each draw call has fixed overhead from API state changes and command buffer submission.
179
+
180
+ **Batching techniques:**
181
+ - **Static batching**: Combine meshes that never move into a single draw call at build time. Costs memory (duplicated vertex data) but eliminates per-frame draw overhead.
182
+ - **Dynamic batching**: Combine small meshes (under ~300 vertices in Unity) at runtime. CPU overhead for combining may exceed the draw call savings for complex meshes.
183
+ - **GPU instancing**: Render many copies of the same mesh with a single draw call plus an instance buffer. Ideal for vegetation, debris, crowds.
184
+ - **Indirect drawing**: GPU-driven rendering where the GPU itself decides what to draw. Used in Nanite (Unreal) and custom engines for massive scene complexity.
185
+
186
+ **State change reduction:**
187
+ - Sort draws by material to minimize shader/texture state changes
188
+ - Use texture atlases and texture arrays to reduce texture bind changes
189
+ - Merge materials where possible (combine multiple texture maps into channels of a single texture)
190
+
191
+ **LOD (Level of Detail):**
192
+ - Every mesh visible beyond 10 meters should have at least 3 LOD levels
193
+ - LOD0: full detail (within 10 m), LOD1: 50% triangles (10–30 m), LOD2: 25% (30–100 m), LOD3: billboard or removed (100 m+)
194
+ - Cross-fade or dither between LOD levels to hide transitions
195
+ - Measure LOD savings: a scene with proper LODs typically uses 60–80% fewer triangles than LOD0 everywhere
196
+
197
+ ### Memory Leak Detection
198
+
199
+ Memory leaks in games manifest as gradually increasing memory use over play sessions, eventually causing crashes or OOM kills (especially on mobile).
200
+
201
+ **Common leak sources:**
202
+ - Event listeners not unsubscribed when objects are destroyed
203
+ - Loaded assets (textures, audio clips) referenced by destroyed objects preventing GC
204
+ - Growing collections (lists, dictionaries) that are appended to but never pruned
205
+ - Pooled objects that accumulate component references over their reuse lifecycle
206
+ - Native/unmanaged resources (file handles, GPU buffers) not explicitly released
207
+
208
+ **Detection workflow:**
209
+ 1. Take a memory snapshot at a known-good state (e.g., main menu after fresh boot)
210
+ 2. Play through a level, return to main menu
211
+ 3. Force garbage collection
212
+ 4. Take a second snapshot
213
+ 5. Diff the snapshots — any growth is a potential leak
214
+ 6. Repeat the cycle 3–5 times — true leaks show linear growth
215
+
216
+ ```csharp
217
+ // Unity: Automated leak detection in development builds
218
+ using UnityEngine;
219
+ using UnityEngine.Profiling;
220
+ using System.Collections;
221
+
222
+ public class MemoryLeakDetector : MonoBehaviour
223
+ {
224
+ private long _baselineBytes;
225
+ private int _cycleCount;
226
+ private const int WarningThresholdMB = 50;
227
+
228
+ public void CaptureBaseline()
229
+ {
230
+ // Force GC before capturing baseline
231
+ System.GC.Collect();
232
+ System.GC.WaitForPendingFinalizers();
233
+ System.GC.Collect();
234
+
235
+ _baselineBytes = Profiler.GetTotalAllocatedMemoryLong();
236
+ _cycleCount = 0;
237
+ Debug.Log($"[LeakDetector] Baseline: {_baselineBytes / (1024 * 1024)} MB");
238
+ }
239
+
240
+ public void CheckForLeaks()
241
+ {
242
+ System.GC.Collect();
243
+ System.GC.WaitForPendingFinalizers();
244
+ System.GC.Collect();
245
+
246
+ long currentBytes = Profiler.GetTotalAllocatedMemoryLong();
247
+ long deltaBytes = currentBytes - _baselineBytes;
248
+ float deltaMB = deltaBytes / (1024f * 1024f);
249
+ _cycleCount++;
250
+
251
+ Debug.Log($"[LeakDetector] Cycle {_cycleCount}: " +
252
+ $"Current={currentBytes / (1024 * 1024)} MB, " +
253
+ $"Delta={deltaMB:F1} MB from baseline");
254
+
255
+ if (deltaMB > WarningThresholdMB)
256
+ {
257
+ Debug.LogError($"[LeakDetector] LEAK SUSPECTED: " +
258
+ $"{deltaMB:F1} MB growth after {_cycleCount} cycles. " +
259
+ $"Take a memory snapshot NOW for comparison.");
260
+ }
261
+ }
262
+ }
263
+ ```
264
+
265
+ ### Platform Certification Performance Requirements
266
+
267
+ Console platform holders enforce performance requirements during certification:
268
+
269
+ **PlayStation:**
270
+ - Game must not drop below target frame rate during normal gameplay for extended periods
271
+ - Loading screens must show activity (progress bar, animation) — no static screens over 3 seconds
272
+ - Suspend/resume must complete within platform-specified time limits
273
+ - Memory must not exceed allocation — OOM crashes are automatic certification failures
274
+
275
+ **Xbox:**
276
+ - Xbox Reliability (XR) requirements specify maximum memory usage per title profile
277
+ - Frame rate must be stable at the advertised rate (30 or 60 fps)
278
+ - Quick Resume must be supported — game state must survive suspend/resume cycles
279
+ - Loading from SSD must meet platform guidance (<2 seconds for fast travel)
280
+
281
+ **Nintendo Switch:**
282
+ - Must run acceptably in both docked (1080p target) and handheld (720p target) modes
283
+ - Dynamic resolution scaling is expected — games should lower resolution to maintain frame rate
284
+ - Memory budget is tight (~3.2 GB) — aggressive texture compression and streaming required
285
+ - Thermal throttling is common — test performance after 30+ minutes of handheld play
286
+
287
+ **Mobile (App Store / Google Play):**
288
+ - No hard certification for performance, but review teams flag severe issues
289
+ - ANR (Application Not Responding) on Android triggers if the main thread blocks >5 seconds
290
+ - iOS watchdog kills apps that take too long to launch (~20 seconds)
291
+ - App size limits: 200 MB for cellular download on iOS; use asset bundles for larger content
292
+
293
+ ### Automated Performance Regression Testing
294
+
295
+ Manual profiling catches issues reactively. Automated performance tests catch regressions before they ship.
296
+
297
+ ```python
298
+ # performance_gate.py — CI script that fails the build on perf regression
299
+ # Run after automated playthrough captures profiler data
300
+
301
+ import json
302
+ import sys
303
+
304
+ # Load profiler output from automated test run
305
+ with open("profiler_results.json") as f:
306
+ results = json.load(f)
307
+
308
+ # Define per-subsystem budgets (in milliseconds)
309
+ budgets = {
310
+ "frame_time_p95": 16.67, # 95th percentile frame time
311
+ "frame_time_p99": 20.0, # 99th percentile (allow some spikes)
312
+ "physics_avg": 1.5,
313
+ "ai_avg": 1.0,
314
+ "rendering_avg": 3.0,
315
+ "audio_avg": 1.0,
316
+ "gc_max": 2.0, # Max single GC pause
317
+ "draw_calls_avg": 3000, # Average draw calls per frame
318
+ "memory_peak_mb": 3200, # Peak memory (Switch target)
319
+ }
320
+
321
+ failures = []
322
+ for metric, budget in budgets.items():
323
+ actual = results.get(metric, 0)
324
+ if actual > budget:
325
+ pct_over = ((actual - budget) / budget) * 100
326
+ failures.append(
327
+ f" FAIL: {metric} = {actual:.1f} "
328
+ f"(budget: {budget:.1f}, {pct_over:.0f}% over)"
329
+ )
330
+
331
+ if failures:
332
+ print("PERFORMANCE BUDGET VIOLATIONS:")
333
+ print("\n".join(failures))
334
+ sys.exit(1)
335
+ else:
336
+ print("All performance budgets passed.")
337
+ sys.exit(0)
338
+ ```
339
+
340
+ ### Thermal Profiling for Mobile
341
+
342
+ Mobile thermal throttling is the single most common cause of "it runs fine in the office" performance failures. Devices heat up during extended play and reduce clock speeds.
343
+
344
+ **Testing protocol:**
345
+ 1. Charge the device to 100% and unplug it
346
+ 2. Close all background apps
347
+ 3. Run the game for 45 minutes continuously
348
+ 4. Log frame time, CPU frequency, GPU frequency, and skin temperature every second
349
+ 5. Plot all four on a timeline — look for the "thermal cliff" where clocks drop
350
+ 6. The sustained performance after throttling is the real frame budget, not the initial burst
351
+
352
+ **Mitigation strategies:**
353
+ - Reduce simulation quality when thermal state is elevated (lower physics tick rate, simplified AI, reduced particle counts)
354
+ - Implement a "thermal budget" system that queries the OS for thermal state (iOS: `ProcessInfo.thermalState`, Android: `PowerManager` thermal API)
355
+ - Use lower rendering resolution with upscaling rather than reducing frame rate
356
+ - Schedule heavy background work (asset loading, pathfinding bakes) during low-activity gameplay moments
357
+ - Test on the oldest supported device in a warm environment (30+ C ambient)
358
+
359
+ ### Profiling Discipline
360
+
361
+ Performance optimization without profiling data is guesswork. Follow these rules:
362
+
363
+ 1. **Measure first, optimize second** — never optimize based on assumptions about what is slow
364
+ 2. **Profile on target hardware** — a developer PC with an RTX 4090 tells you nothing about Switch or mobile performance
365
+ 3. **Profile release builds** — debug builds have 2–10x overhead from assertions, logging, and disabled optimizations
366
+ 4. **Profile representative content** — the title screen is not representative; profile the most complex gameplay scenario
367
+ 5. **Track metrics over time** — a single profile session is a snapshot; daily automated profiling catches regressions
368
+ 6. **Budget from day one** — retrofitting performance into a game that has been running 3x over budget for a year is brutal; establish and enforce budgets from the first playable build
369
+
370
+ ### Common Performance Antipatterns
371
+
372
+ - **Allocating during gameplay**: Any `new` call or list resize during the game loop risks GC pauses. Pre-allocate and pool everything.
373
+ - **Synchronous I/O on the main thread**: File reads, network calls, or asset loads on the main thread cause frame spikes. Use async I/O and streaming.
374
+ - **Per-frame string operations**: String concatenation, formatting, and parsing allocate memory every frame. Cache results, use `StringBuilder`, or use integer identifiers instead of strings.
375
+ - **Unbounded spatial queries**: "Find all enemies" without a spatial index (quadtree, grid) is O(n^2) and degrades as entity count grows.
376
+ - **Overdraw**: Transparent objects rendered back-to-front can cause massive pixel fill rate waste. Sort, z-test, and minimize layered transparency.
377
+ - **Shader complexity creep**: Artists add features to materials over time. Each additional texture sample, branch, or math operation costs GPU time multiplied by every pixel that material covers. Audit materials monthly.
378
+ - **Excessive raycasts**: Physics raycasts are not free. Budget them (e.g., max 50 per frame for AI line-of-sight checks) and use layers to filter collision masks.