claude-code-arcane 2.9.7 → 2.9.9

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 (129) hide show
  1. package/CHANGELOG.md +21 -0
  2. package/agents/business/business-ops-lead.md +1 -14
  3. package/agents/game/gameplay-programmer.md +3 -4
  4. package/agents/game/technical-artist.md +3 -4
  5. package/dist/cli.js +74 -24
  6. package/docs/USER-GUIDE.md +1 -1
  7. package/docs/coordination-rules.md +1 -1
  8. package/docs/directory-structure.md +93 -122
  9. package/package.json +1 -1
  10. package/profiles/backend-go.yaml +1 -0
  11. package/profiles/core.yaml +0 -1
  12. package/rules/gamedev/engine-code.md +1 -1
  13. package/rules/gamedev/shader-code.md +1 -2
  14. package/rules/gamedev/vn-code.md +3 -2
  15. package/rules/implementation-workflow.md +1 -1
  16. package/rules/{ai-code.md → llm-code.md} +5 -5
  17. package/skills/agent-designer/README.md +2 -1
  18. package/skills/agent-designer/agent_evaluator.py +0 -5
  19. package/skills/ai-sdk-setup/SKILL.md +4 -4
  20. package/skills/architecture-decision/SKILL.md +3 -4
  21. package/skills/architecture-review/SKILL.md +1 -1
  22. package/skills/asset-audit/SKILL.md +0 -1
  23. package/skills/balance-check/SKILL.md +1 -1
  24. package/skills/brainstorm/SKILL.md +3 -3
  25. package/skills/brainstorm/references/next-steps-pipeline.md +8 -9
  26. package/skills/consistency-check/SKILL.md +2 -2
  27. package/skills/design-system/SKILL.md +1 -1
  28. package/skills/design-system/references/post-design-validation.md +2 -3
  29. package/skills/frontend-dev/SKILL.md +27 -28
  30. package/skills/frontend-dev/references/asset-prompt-guide.md +1 -1
  31. package/skills/frontend-dev/references/motion-recipes.md +1 -1
  32. package/skills/help/SKILL.md +1 -2
  33. package/skills/hotfix/SKILL.md +2 -2
  34. package/skills/milestone-review/SKILL.md +1 -1
  35. package/skills/patch-notes/SKILL.md +1 -1
  36. package/skills/playtest-report/SKILL.md +2 -3
  37. package/skills/playwright-pro/CLAUDE.md +2 -2
  38. package/skills/playwright-pro/SKILL.md +13 -9
  39. package/skills/playwright-pro/agents/migration-planner.md +2 -2
  40. package/skills/playwright-pro/agents/test-architect.md +1 -2
  41. package/skills/playwright-pro/agents/test-debugger.md +1 -1
  42. package/skills/playwright-pro/hooks/detect-playwright.sh +1 -1
  43. package/skills/playwright-pro/skills/browserstack/SKILL.md +5 -5
  44. package/skills/playwright-pro/skills/migrate/SKILL.md +1 -1
  45. package/skills/playwright-pro/skills/report/SKILL.md +2 -2
  46. package/skills/playwright-pro/skills/testrail/SKILL.md +5 -5
  47. package/skills/playwright-pro/templates/README.md +2 -2
  48. package/skills/prototype/SKILL.md +1 -1
  49. package/skills/quick-design/SKILL.md +1 -1
  50. package/skills/release-checklist/SKILL.md +0 -1
  51. package/skills/security-audit/SKILL.md +1 -1
  52. package/skills/self-improving-agent/CLAUDE.md +12 -12
  53. package/skills/self-improving-agent/SKILL.md +16 -12
  54. package/skills/self-improving-agent/agents/memory-analyst.md +1 -1
  55. package/skills/self-improving-agent/hooks/error-capture.sh +2 -2
  56. package/skills/self-improving-agent/reference/memory-architecture.md +2 -2
  57. package/skills/self-improving-agent/reference/promotion-rules.md +3 -3
  58. package/skills/self-improving-agent/reference/rules-directory-patterns.md +1 -1
  59. package/skills/self-improving-agent/settings.json +5 -5
  60. package/skills/self-improving-agent/skills/extract/SKILL.md +7 -7
  61. package/skills/self-improving-agent/skills/promote/SKILL.md +5 -5
  62. package/skills/self-improving-agent/skills/remember/SKILL.md +9 -9
  63. package/skills/self-improving-agent/skills/review/SKILL.md +7 -7
  64. package/skills/self-improving-agent/skills/status/SKILL.md +8 -8
  65. package/skills/senior-ml-engineer/references/llm_integration_guide.md +14 -31
  66. package/skills/senior-prompt-engineer/SKILL.md +10 -10
  67. package/skills/senior-prompt-engineer/references/prompt_engineering_patterns.md +1 -1
  68. package/skills/senior-prompt-engineer/scripts/agent_orchestrator.py +43 -40
  69. package/skills/senior-prompt-engineer/scripts/prompt_optimizer.py +23 -66
  70. package/skills/shader-dev/reference/fluid-simulation.md +4 -4
  71. package/skills/shader-dev/reference/simulation-physics.md +6 -6
  72. package/skills/shader-dev/reference/voxel-rendering.md +1 -1
  73. package/skills/shader-dev/techniques/ambient-occlusion.md +1 -1
  74. package/skills/shader-dev/techniques/analytic-ray-tracing.md +2 -2
  75. package/skills/shader-dev/techniques/domain-warping.md +2 -2
  76. package/skills/shader-dev/techniques/fluid-simulation.md +45 -45
  77. package/skills/shader-dev/techniques/multipass-buffer.md +24 -24
  78. package/skills/shader-dev/techniques/normal-estimation.md +1 -1
  79. package/skills/shader-dev/techniques/particle-system.md +16 -16
  80. package/skills/shader-dev/techniques/polar-uv-manipulation.md +1 -1
  81. package/skills/shader-dev/techniques/post-processing.md +7 -7
  82. package/skills/shader-dev/techniques/sdf-3d.md +1 -1
  83. package/skills/shader-dev/techniques/simulation-physics.md +24 -24
  84. package/skills/shader-dev/techniques/sound-synthesis.md +2 -2
  85. package/skills/shader-dev/techniques/voronoi-cellular-noise.md +1 -1
  86. package/skills/shader-dev/techniques/voxel-rendering.md +60 -60
  87. package/skills/smoke-check/SKILL.md +1 -1
  88. package/skills/sprint-plan/SKILL.md +1 -2
  89. package/skills/start/SKILL.md +7 -7
  90. package/skills/story-done/SKILL.md +1 -1
  91. package/skills/test-helpers/SKILL.md +7 -2
  92. package/skills/test-setup/SKILL.md +1 -1
  93. package/skills/ue-actor-component-architecture/SKILL.md +0 -1
  94. package/skills/ue-ai-navigation/SKILL.md +0 -1
  95. package/skills/ue-animation-system/SKILL.md +0 -1
  96. package/skills/ue-async-threading/SKILL.md +0 -1
  97. package/skills/ue-audio-system/SKILL.md +0 -1
  98. package/skills/ue-blueprints/SKILL.md +0 -1
  99. package/skills/ue-character-movement/SKILL.md +0 -1
  100. package/skills/ue-cpp-foundations/SKILL.md +0 -1
  101. package/skills/ue-data-assets-tables/SKILL.md +0 -1
  102. package/skills/ue-editor-tools/SKILL.md +0 -1
  103. package/skills/ue-game-features/SKILL.md +0 -1
  104. package/skills/ue-gameplay-abilities/SKILL.md +0 -1
  105. package/skills/ue-gameplay-framework/SKILL.md +0 -1
  106. package/skills/ue-input-system/SKILL.md +0 -1
  107. package/skills/ue-mass-entity/SKILL.md +0 -1
  108. package/skills/ue-materials-rendering/SKILL.md +0 -1
  109. package/skills/ue-module-build-system/SKILL.md +0 -1
  110. package/skills/ue-naming-conventions/SKILL.md +0 -1
  111. package/skills/ue-networking-replication/SKILL.md +0 -1
  112. package/skills/ue-niagara-effects/SKILL.md +0 -1
  113. package/skills/ue-packaging/SKILL.md +0 -1
  114. package/skills/ue-physics-collision/SKILL.md +0 -1
  115. package/skills/ue-procedural-generation/SKILL.md +0 -1
  116. package/skills/ue-project-context/SKILL.md +0 -1
  117. package/skills/ue-sequencer-cinematics/SKILL.md +0 -1
  118. package/skills/ue-serialization-savegames/SKILL.md +0 -1
  119. package/skills/ue-state-trees/SKILL.md +0 -1
  120. package/skills/ue-testing-debugging/SKILL.md +0 -1
  121. package/skills/ue-ui-umg-slate/SKILL.md +0 -1
  122. package/skills/ue-world-level-streaming/SKILL.md +0 -1
  123. package/skills/ux-review/SKILL.md +1 -1
  124. package/docs/RELEASE-SETUP.md +0 -99
  125. package/docs/presentations/arcane-overview-12.pptx +0 -0
  126. package/docs/presentations/arcane-overview.pptx +0 -0
  127. package/docs/presentations/build_arcane_deck.py +0 -310
  128. package/docs/presentations/build_arcane_deck_12.py +0 -399
  129. package/docs/trusted-publishing-setup.md +0 -163
@@ -26,31 +26,31 @@ precision highp float;
26
26
  uniform float iTime;
27
27
  uniform vec2 iResolution;
28
28
 
29
- // IMPORTANT: Important: WebGL2 must declare the output variable!
29
+ // WebGL2 must declare the output variable.
30
30
  out vec4 fragColor;
31
31
 
32
32
  // ... other functions ...
33
33
 
34
34
  void main() {
35
- // IMPORTANT: Use gl_FragCoord.xy instead of fragCoord
35
+ // Use gl_FragCoord.xy instead of fragCoord
36
36
  vec2 fragCoord = gl_FragCoord.xy;
37
37
 
38
38
  vec3 col = vec3(0.0);
39
39
 
40
40
  // ... rendering logic ...
41
41
 
42
- // IMPORTANT: Write to fragColor, not gl_FragColor!
42
+ // Write to fragColor, not gl_FragColor!
43
43
  fragColor = vec4(col, 1.0);
44
44
  }`;
45
45
  ```
46
46
 
47
- **IMPORTANT: Common GLSL compile errors:**
47
+ **Common GLSL compile errors:**
48
48
  - `in/out storage qualifier supported in GLSL ES 3.00 only` → Check that you are using `getContext("webgl2")` and `#version 300 es`
49
49
  - `#version directive must occur on the first line` → Check that the shader string starts with #version, with no characters before it
50
50
  - **IMPORTANT: GLSL reserved words**: `cast`, `class`, `template`, `namespace`, `union`, `enum`, `typedef`, `sizeof`, `input`, `output`, `filter`, `image`, `sampler`, `fixed`, `volatile`, `public`, `static`, `extern`, `external`, `interface`, `long`, `short`, `double`, `half`, `unsigned`, `superp`, `inline`, `noinline`, etc. are all GLSL reserved words and **must never be used as variable or function names**! Common pitfall: naming a function `cast` for ray casting → compile failure. **Use compound names like `castRay`, `castShadow`, `shootRay` instead**.
51
- - **IMPORTANT: GLSL strict typing**: float/int cannot be mixed. `if (x > 0)` for int, `if (y < 0.0)` for float. Comparing ivec3 members to float requires explicit conversion: `float(c.y) < height`. When getVoxel returns int, compare with `> 0` not `> 0.0`. Function parameter types must match exactly.
52
- - **IMPORTANT: Vector dimension mismatch (vec2 vs vec3)**: `p.xz` returns `vec2` and **must never** be added to `vec3` or passed to functions expecting `vec3` parameters (e.g., `fbm(vec3)`, `noise(vec3)`)! Common error: `fbm(p.xz * 0.08 + vec3(...))` — `vec2 + vec3` compile failure. **Fix**: either use a `vec2` version of noise/fbm, or construct a full vec3: `fbm(vec3(p.xz * 0.08, p.y * 0.05))`. Similarly, `vec2` only has `.x`/`.y`, cannot access `.z`/`.w`.
53
- - **IMPORTANT: length() / floating-point precision**: `length(ivec2)` must first convert to `vec2`: `length(vec2(d))`. Exact floating-point equality comparison almost never works; use range comparison: `floor(p.y) == floor(height)`
51
+ - **GLSL strict typing**: float/int cannot be mixed. `if (x > 0)` for int, `if (y < 0.0)` for float. Comparing ivec3 members to float requires explicit conversion: `float(c.y) < height`. When getVoxel returns int, compare with `> 0` not `> 0.0`. Function parameter types must match exactly.
52
+ - **Vector dimension mismatch (vec2 vs vec3)**: `p.xz` returns `vec2` and **must never** be added to `vec3` or passed to functions expecting `vec3` parameters (e.g., `fbm(vec3)`, `noise(vec3)`)! Common error: `fbm(p.xz * 0.08 + vec3(...))` — `vec2 + vec3` compile failure. **Fix**: either use a `vec2` version of noise/fbm, or construct a full vec3: `fbm(vec3(p.xz * 0.08, p.y * 0.05))`. Similarly, `vec2` only has `.x`/`.y`, cannot access `.z`/`.w`.
53
+ - **length() / floating-point precision**: `length(ivec2)` must first convert to `vec2`: `length(vec2(d))`. Exact floating-point equality comparison almost never works; use range comparison: `floor(p.y) == floor(height)`
54
54
 
55
55
  # Voxel Rendering Skill
56
56
 
@@ -120,7 +120,7 @@ mapPos += mask * rayStep;
120
120
  ### Step 4: Voxel Occupancy Function
121
121
  ```glsl
122
122
  // Basic version: solid block (most common; use this when user asks for "voxel cube")
123
- // IMPORTANT: Important: getVoxel receives ivec3, but all internal calculations must use float!
123
+ // getVoxel receives ivec3, but all internal calculations must use float!
124
124
  bool getVoxel(ivec3 c) {
125
125
  vec3 p = vec3(c) + vec3(0.5); // ivec3 → vec3 conversion (required!)
126
126
  float d = sdBox(p, vec3(6.0)); // Solid 12x12x12 cube
@@ -135,8 +135,8 @@ bool getVoxelCarved(ivec3 c) {
135
135
  }
136
136
 
137
137
  // Advanced version: height map terrain with material IDs
138
- // IMPORTANT: Key: all comparisons must use float! c.y is int and must be converted to float for comparison
139
- // IMPORTANT: Important: must use range comparison, not exact equality (floating-point precision issues)
138
+ // all comparisons must use float! c.y is int and must be converted to float for comparison
139
+ // must use range comparison, not exact equality (floating-point precision issues)
140
140
  int getVoxelMaterial(ivec3 c) {
141
141
  vec3 p = vec3(c); // ivec3 → vec3 conversion (required!)
142
142
  float groundHeight = getTerrainHeight(p.xz); // p.xz is vec2, passes float parameters
@@ -148,7 +148,7 @@ int getVoxelMaterial(ivec3 c) {
148
148
  // Pure float version (simpler, recommended):
149
149
  int getVoxelMaterial(vec3 c) {
150
150
  float groundHeight = getTerrainHeight(c.xz);
151
- // IMPORTANT: Use range comparison, never exact equality!
151
+ // Use range comparison, never exact equality!
152
152
  if (c.y >= groundHeight && c.y < groundHeight + 1.0) return 1; // Grass top layer
153
153
  if (c.y >= groundHeight - 3.0 && c.y < groundHeight) return 2; // Dirt layer
154
154
  if (c.y < groundHeight - 3.0) return 3; // Stone layer
@@ -156,30 +156,30 @@ int getVoxelMaterial(vec3 c) {
156
156
  }
157
157
 
158
158
  // Advanced version: mountain terrain (height-based coloring: grass green → rock gray → snow white)
159
- // IMPORTANT: Key 1: color thresholds must be based on heightRatio (normalized height 0~1), not absolute height!
160
- // IMPORTANT: Key 2: maxH must match the actual maximum return value of getMountainHeight!
159
+ // Key 1: color thresholds must be based on heightRatio (normalized height 0~1), not absolute height!
160
+ // Key 2: maxH must match the actual maximum return value of getMountainHeight!
161
161
  // If getMountainHeight returns at most 15.0, maxH must be 15.0, not arbitrarily 20.0
162
- // IMPORTANT: Key 3: threshold spacing must be large enough (at least 0.2), otherwise color bands are too narrow to see
163
- // IMPORTANT: Key 4: grass area typically covers the largest terrain area (low elevation); set grass threshold high (0.4) to ensure green is clearly visible
164
- float maxH = 15.0; // IMPORTANT: Must equal the actual max value of getMountainHeight!
162
+ // Key 3: threshold spacing must be large enough (at least 0.2), otherwise color bands are too narrow to see
163
+ // Key 4: grass area typically covers the largest terrain area (low elevation); set grass threshold high (0.4) to ensure green is clearly visible
164
+ float maxH = 15.0; // Must equal the actual max value of getMountainHeight!
165
165
  int getMountainVoxel(vec3 c) {
166
166
  float height = getMountainHeight(c.xz); // Returns 0 ~ maxH
167
167
  if (c.y > height) return 0; // Air
168
168
  float heightRatio = c.y / maxH; // Normalize to 0~1
169
- // IMPORTANT: Thresholds from low to high: grass < 0.4, rock 0.4~0.7, snow > 0.7
169
+ // Thresholds from low to high: grass < 0.4, rock 0.4~0.7, snow > 0.7
170
170
  if (heightRatio < 0.4) return 1; // Grass (green) — largest area
171
171
  if (heightRatio < 0.7) return 2; // Rock (gray)
172
172
  return 3; // Snow cap (white)
173
173
  }
174
- // IMPORTANT: Corresponding material colors must have sufficient saturation and clear contrast:
174
+ // Corresponding material colors must have sufficient saturation and clear contrast:
175
175
  // mat==1: vec3(0.25, 0.55, 0.15) Grass green (saturated green, must not be grayish!)
176
176
  // mat==2: vec3(0.5, 0.45, 0.4) Rock gray-brown
177
177
  // mat==3: vec3(0.92, 0.93, 0.96) Snow white
178
- // IMPORTANT: Lighting must not be too bright or it washes out colors! Sun intensity ≤ 2.0, sky light ≤ 1.0
179
- // IMPORTANT: Gamma correction pow(col, vec3(0.4545)) brightens dark colors and reduces saturation;
178
+ // Lighting must not be too bright or it washes out colors! Sun intensity ≤ 2.0, sky light ≤ 1.0
179
+ // Gamma correction pow(col, vec3(0.4545)) brightens dark colors and reduces saturation;
180
180
  // if colors look grayish-white, make grass green more saturated: vec3(0.2, 0.5, 0.1)
181
181
 
182
- // IMPORTANT: Rotating objects: to rotate a voxel object, apply inverse rotation to the sample point in getVoxel!
182
+ // Rotating objects: to rotate a voxel object, apply inverse rotation to the sample point in getVoxel!
183
183
  // Do not rotate the camera to simulate object rotation (that only changes the viewpoint)
184
184
  bool getVoxelRotating(ivec3 c) {
185
185
  vec3 p = vec3(c) + vec3(0.5);
@@ -240,7 +240,7 @@ ao = pow(ao, 1.0 / 3.0); // Gamma correction to control AO intensity
240
240
 
241
241
  ### Step 8: DDA Shadow Ray
242
242
  ```glsl
243
- // IMPORTANT: Shadow steps must be capped at 16; total main ray + shadow ray steps should not exceed 80
243
+ // Shadow steps must be capped at 16; total main ray + shadow ray steps should not exceed 80
244
244
  #define MAX_SHADOW_STEPS 16
245
245
 
246
246
  float castShadow(vec3 ro, vec3 rd) {
@@ -268,7 +268,7 @@ float diffuse = max(dot(normal, sundir), 0.0) * shadow;
268
268
  // === Voxel Rendering - Complete ShaderToy Template ===
269
269
  // Includes: DDA traversal, face shading, neighbor AO, hard shadows
270
270
 
271
- // IMPORTANT: Performance critical: SwiftShader software renderer (headless browser evaluation environment) cannot handle too many loop iterations
271
+ // Performance critical: SwiftShader software renderer (headless browser evaluation environment) cannot handle too many loop iterations
272
272
  // Default 64+16=80 steps, suitable for most scenes. Simple scenes (single cube) can increase to 96+24
273
273
  // Multi-building/character/Minecraft scenes must keep 64+16 or lower!
274
274
  #define MAX_RAY_STEPS 64
@@ -289,7 +289,7 @@ vec2 rotate2d(vec2 v, float a) {
289
289
  }
290
290
 
291
291
  // ---- Voxel Scene Definition ----
292
- // IMPORTANT: Default solid cube. Use sdBox for "voxel cube"; add SDF boolean ops for carved/sculpted shapes
292
+ // Default solid cube. Use sdBox for "voxel cube"; add SDF boolean ops for carved/sculpted shapes
293
293
  int getVoxel(vec3 c) {
294
294
  vec3 p = c + 0.5;
295
295
  float d = sdBox(p, vec3(6.0)); // Solid 12x12x12 block
@@ -366,14 +366,14 @@ HitInfo castRay(vec3 ro, vec3 rd, int maxSteps) {
366
366
  }
367
367
 
368
368
  // ---- Shadow Ray ----
369
- // IMPORTANT: Shadow steps at 16 (combined with main ray 64 = 80, within SwiftShader safe range)
369
+ // Shadow steps at 16 (combined with main ray 64 = 80, within SwiftShader safe range)
370
370
  float castShadow(vec3 ro, vec3 rd) {
371
371
  vec3 pos = floor(ro);
372
372
  vec3 ri = 1.0 / rd;
373
373
  vec3 rs = sign(rd);
374
374
  vec3 dis = (pos - ro + 0.5 + rs * 0.5) * ri;
375
375
  for (int i = 0; i < MAX_SHADOW_STEPS; i++) {
376
- // IMPORTANT: getVoxel returns int; comparison must use int constant (0), not float (0.0)
376
+ // getVoxel returns int; comparison must use int constant (0), not float (0.0)
377
377
  if (getVoxel(pos) > 0) return 0.0;
378
378
  vec3 mm = step(dis.xyz, dis.yzx) * step(dis.xyz, dis.zxy);
379
379
  dis += mm * rs * ri;
@@ -383,7 +383,7 @@ float castShadow(vec3 ro, vec3 rd) {
383
383
  }
384
384
 
385
385
  // ---- Material Colors ----
386
- // IMPORTANT: Texture coloring key: "low saturation" does not mean "near white/gray"!
386
+ // Texture coloring key: "low saturation" does not mean "near white/gray"!
387
387
  // Low saturation = colorful but not vivid, must retain clear hue differences (e.g., brick red 0.55,0.35,0.3 not gray-white 0.8,0.8,0.8)
388
388
  // Brick/stone textures: use UV periodic patterns (mortar lines = dark lines), never use solid colors!
389
389
  vec3 getMaterialColor(int mat, vec2 uv) {
@@ -396,7 +396,7 @@ vec3 getMaterialColor(int mat, vec2 uv) {
396
396
  }
397
397
 
398
398
  // ---- Brick/Stone Texture Coloring (use this to replace getMaterialColor when user requests "brick texture") ----
399
- // IMPORTANT: Key: brick texture = UV periodic pattern (staggered rows + mortar dark lines), not solid color!
399
+ // brick texture = UV periodic pattern (staggered rows + mortar dark lines), not solid color!
400
400
  vec3 getBrickColor(vec2 uv, vec3 baseColor, vec3 mortarColor) {
401
401
  vec2 brickUV = uv * vec2(4.0, 8.0);
402
402
  float row = floor(brickUV.y);
@@ -447,14 +447,14 @@ void mainImage(out vec4 fragColor, in vec2 fragCoord) {
447
447
  float sky = 0.5 + 0.5 * hit.normal.y;
448
448
 
449
449
  vec3 lighting = vec3(0.0);
450
- // IMPORTANT: Mountain/terrain scenes: sun light ≤ 2.0, sky light ≤ 1.0; too bright washes out material color differences
450
+ // Mountain/terrain scenes: sun light ≤ 2.0, sky light ≤ 1.0; too bright washes out material color differences
451
451
  lighting += 2.0 * diff * vec3(1.0, 0.95, 0.8) * shadow;
452
452
  lighting += 1.0 * sky * skyColor;
453
453
  lighting *= ao;
454
454
 
455
455
  col = matCol * lighting;
456
456
 
457
- // IMPORTANT: Fog: coefficient should not be too large, otherwise nearby objects get swallowed into pure sky color
457
+ // Fog: coefficient should not be too large, otherwise nearby objects get swallowed into pure sky color
458
458
  // 0.0002 suits GRID_SIZE=16 scenes; use smaller coefficients for larger scenes
459
459
  float fog = 1.0 - exp(-0.0002 * hit.t * hit.t);
460
460
  col = mix(col, skyColor, clamp(fog, 0.0, 0.7)); // Clamp prevents objects from disappearing entirely
@@ -564,7 +564,7 @@ Water surface ripple reflections, underwater refraction, sand and seaweed for a
564
564
  float waterY = 0.0;
565
565
 
566
566
  // Underwater voxel scene definition (sand + seaweed)
567
- // IMPORTANT: All coordinate operations must use correct vector dimensions!
567
+ // All coordinate operations must use correct vector dimensions!
568
568
  // c.xz returns vec2, only has .x/.y components, cannot use .z!
569
569
  int getVoxel(vec3 c) {
570
570
  float sandHeight = -3.0 + 0.5 * sin(c.x * 0.3) * cos(c.z * 0.4);
@@ -572,7 +572,7 @@ int getVoxel(vec3 c) {
572
572
  if (c.y < sandHeight + 1.0) return 2; // Sand surface
573
573
  // Seaweed: only grows underwater, above sand
574
574
  float grassHash = fract(sin(dot(floor(c.xz), vec2(12.9898, 78.233))) * 43758.5453);
575
- // IMPORTANT: floor(c.xz) is vec2; the second argument to dot() must also be vec2
575
+ // floor(c.xz) is vec2; the second argument to dot() must also be vec2
576
576
  if (grassHash > 0.85 && c.y >= sandHeight + 1.0 && c.y < sandHeight + 1.0 + 3.0 * grassHash) {
577
577
  return 3; // Seaweed
578
578
  }
@@ -586,7 +586,7 @@ bool hitWater = tWater > 0.0 && (tWater < hit.t || !hit.hit);
586
586
  if (hitWater) {
587
587
  vec3 waterPos = ro + rd * tWater;
588
588
  vec3 waterNormal = vec3(0.0, 1.0, 0.0);
589
- // IMPORTANT: waterPos.xz is vec2; access with .x/.y (not .x/.z)
589
+ // waterPos.xz is vec2; access with .x/.y (not .x/.z)
590
590
  vec2 waveXZ = waterPos.xz; // vec2: waveXZ.x = worldX, waveXZ.y = worldZ
591
591
  waterNormal.x += 0.05 * sin(waveXZ.x * 3.0 + iTime);
592
592
  waterNormal.z += 0.05 * cos(waveXZ.y * 2.0 + iTime * 0.7);
@@ -619,7 +619,7 @@ if (hitWater) {
619
619
  ### Variant 7: Rotating Voxel Objects
620
620
  Rotate voxel objects as a whole. Core: apply inverse rotation to sample points in getVoxel.
621
621
  ```glsl
622
- // IMPORTANT: Correct way to rotate objects: apply inverse rotation to sample coordinates in getVoxel
622
+ // Correct way to rotate objects: apply inverse rotation to sample coordinates in getVoxel
623
623
  // Wrong approach: only rotate the camera (that just changes the viewpoint, not the object)
624
624
  int getVoxel(vec3 c) {
625
625
  vec3 p = c + 0.5;
@@ -638,7 +638,7 @@ int getVoxel(vec3 c) {
638
638
  ### Variant 8: Indoor/Cave/Enclosed Scenes (Point Lights + High Ambient Lighting)
639
639
  Indoor, cave, underground, sci-fi base, and other enclosed or semi-enclosed scenes require point lights and high ambient lighting.
640
640
  ```glsl
641
- // IMPORTANT: Key points for enclosed/semi-enclosed scenes (caves, interiors, sci-fi bases, mazes, etc.):
641
+ // Key points for enclosed/semi-enclosed scenes (caves, interiors, sci-fi bases, mazes, etc.):
642
642
  // 1. Camera must be placed inside the cavity (a position where getVoxel returns 0)
643
643
  // 2. Must use point lights, not just directional light (directional light blocked by walls/ceiling = total darkness!)
644
644
  // 3. Ambient light must be high enough (at least 0.2-0.3) to prevent scene from being too dark to see details
@@ -647,13 +647,13 @@ Indoor, cave, underground, sci-fi base, and other enclosed or semi-enclosed scen
647
647
  // 6. Emissive elements (holographic screens, indicator lights, magic circles) use emissive materials: add emissive color directly to lighting
648
648
 
649
649
  // Cave scene: cavity = area where getVoxel returns 0
650
- // IMPORTANT: Cave/terrain noise functions must respect vector dimensions!
650
+ // Cave/terrain noise functions must respect vector dimensions!
651
651
  // p.xz is vec2; if noise/fbm function takes vec3, construct a full vec3:
652
652
  // Correct: fbm(vec3(p.xz, p.y * 0.5)) or use vec2 version of noise
653
653
  // Wrong: fbm(p.xz + vec3(...)) ← vec2 + vec3 compile failure!
654
654
  int getVoxel(vec3 c) {
655
655
  float cave = sdSphere(c + 0.5, 12.0);
656
- // IMPORTANT: For noise-carved detail, use c's components directly (all float)
656
+ // For noise-carved detail, use c's components directly (all float)
657
657
  cave += 2.0 * sin(c.x * 0.3) * sin(c.y * 0.4) * sin(c.z * 0.35);
658
658
  if (cave > 0.0) return 1; // Rock wall
659
659
  return 0; // Cavity (camera goes here)
@@ -670,7 +670,7 @@ float diff = max(dot(hit.normal, lightDir), 0.0);
670
670
  float shadow = castShadow(hit.pos + hit.normal * 0.01, lightDir);
671
671
 
672
672
  vec3 lighting = vec3(0.0);
673
- // IMPORTANT: High ambient light to prevent total darkness (required for enclosed scenes! at least 0.2)
673
+ // High ambient light to prevent total darkness (required for enclosed scenes! at least 0.2)
674
674
  lighting += vec3(0.25, 0.22, 0.2); // Warm ambient light
675
675
  lighting += 3.0 * diff * attenuation * vec3(1.0, 0.8, 0.5) * shadow; // Point light
676
676
 
@@ -683,7 +683,7 @@ lighting += calcPointLight(hit.pos, hit.normal, torch1, vec3(1.0, 0.6, 0.2)) * f
683
683
  lighting += calcPointLight(hit.pos, hit.normal, torch2, vec3(0.2, 1.0, 0.5)) * flicker2;
684
684
 
685
685
  // Emissive materials (holographic displays, fluorescent moss, indicator lights, magic circles, etc.)
686
- // IMPORTANT: Emissive colors are added directly to lighting, unaffected by shadows
686
+ // Emissive colors are added directly to lighting, unaffected by shadows
687
687
  if (hit.mat == 2) {
688
688
  lighting += vec3(0.1, 0.4, 0.15); // Fluorescent moss (faint green)
689
689
  }
@@ -698,12 +698,12 @@ col = matCol * lighting;
698
698
  ### Variant 9: Voxel Character Animation
699
699
  Simple voxel character animation using time-driven offsets and rotations.
700
700
  ```glsl
701
- // IMPORTANT: Voxel character animation core approach:
701
+ // Voxel character animation core approach:
702
702
  // 1. Split the character into multiple body parts (head, torso, left arm, right arm, left leg, right leg)
703
703
  // 2. Each part is an sdBox with independent offset/rotation parameters
704
704
  // 3. iTime drives limb swinging (sin/cos periodic motion)
705
705
  // 4. Combine all parts using SDF min()
706
- // IMPORTANT: SwiftShader performance critical: character function is called at every DDA step!
706
+ // SwiftShader performance critical: character function is called at every DDA step!
707
707
  // Must add AABB bounding box check in getVoxel: first check if c is near the character,
708
708
  // skip sdBox calculations for that character if not nearby. Otherwise frame timeout → black screen
709
709
  // Reduce MAX_RAY_STEPS to 64, MAX_SHADOW_STEPS to 16
@@ -737,12 +737,12 @@ int getCharacter(vec3 p, vec3 charPos, float animPhase) {
737
737
  }
738
738
 
739
739
  // Combine scene + characters in getVoxel
740
- // IMPORTANT: Must add AABB bounding box early exit! Character sdBox calculations are expensive
740
+ // Must add AABB bounding box early exit! Character sdBox calculations are expensive
741
741
  int getVoxel(vec3 c) {
742
742
  // Scene (floor, walls, etc.)
743
743
  int scene = getSceneVoxel(c);
744
744
  if (scene > 0) return scene;
745
- // IMPORTANT: AABB check: only call getCharacter near the character
745
+ // AABB check: only call getCharacter near the character
746
746
  // Character 1: warrior (at position (5,0,0)), bounding box ±5 cells
747
747
  if (abs(c.x - 5.0) < 5.0 && c.y >= 0.0 && c.y < 10.0 && abs(c.z) < 5.0) {
748
748
  int char1 = getCharacter(c, vec3(5, 0, 0), 0.0);
@@ -760,7 +760,7 @@ int getVoxel(vec3 c) {
760
760
  ### Variant 10: Waterfall / Flowing Water Particle Effects
761
761
  Dynamic waterfall, splash particles, water mist effects. Core: time-offset noise simulates water flow, hashed particles simulate splashes, exponential decay simulates mist.
762
762
  ```glsl
763
- // IMPORTANT: Key points for waterfall/flowing water/particle effects:
763
+ // Key points for waterfall/flowing water/particle effects:
764
764
  // 1. Waterfall stream: noise + iTime vertical offset simulates water column flowing down
765
765
  // 2. Splash particles: hash-distributed voxels at the bottom, positions change with iTime to simulate splashing
766
766
  // 3. Water mist: semi-transparent accumulation (reduced alpha) or density field at the bottom simulates mist diffusion
@@ -782,14 +782,14 @@ int getVoxel(vec3 c) {
782
782
  // Bottom pool floor
783
783
  if (c.y < -2.0 && abs(c.x) < 8.0 && c.z > -6.0 && c.z < 3.0) return 2; // Pool bottom
784
784
 
785
- // IMPORTANT: Waterfall stream: narrow band x ∈ [-2, 2], falling from y=13 to y=0
785
+ // Waterfall stream: narrow band x ∈ [-2, 2], falling from y=13 to y=0
786
786
  // Use iTime offset on y-coordinate noise to simulate downward water flow
787
787
  if (abs(c.x) < 2.0 && c.y >= 0.0 && c.y < 13.0 && c.z > -1.0 && c.z < 1.0) {
788
788
  float flowNoise = hash21(vec2(floor(c.x), floor(c.y - iTime * 8.0)));
789
789
  if (flowNoise > 0.25) return 3; // Water (gaps simulate translucent water curtain)
790
790
  }
791
791
 
792
- // IMPORTANT: Splash particles: bottom y ∈ [-1, 3], x ∈ [-4, 4]
792
+ // Splash particles: bottom y ∈ [-1, 3], x ∈ [-4, 4]
793
793
  // Use hash + iTime to generate randomly bouncing voxel particles
794
794
  if (c.y >= -1.0 && c.y < 3.0 && abs(c.x) < 4.0 && c.z > -3.0 && c.z < 2.0) {
795
795
  float t = iTime * 3.0;
@@ -798,7 +798,7 @@ int getVoxel(vec3 c) {
798
798
  if (abs(c.y - yOffset) < 0.6 && particleHash > 0.7) return 4; // Splash particle
799
799
  }
800
800
 
801
- // IMPORTANT: Water mist: bottom y ∈ [-1, 2], wider range than splashes
801
+ // Water mist: bottom y ∈ [-1, 2], wider range than splashes
802
802
  // Density decreases with height and distance from waterfall center
803
803
  if (c.y >= -1.0 && c.y < 2.0 && abs(c.x) < 6.0 && c.z > -5.0 && c.z < 3.0) {
804
804
  float distFromCenter = length(vec2(c.x, c.z));
@@ -823,7 +823,7 @@ vec3 getMaterialColor(int mat, vec2 uv) {
823
823
  return vec3(0.5);
824
824
  }
825
825
 
826
- // IMPORTANT: Water mist material needs special lighting: high emissive + translucent feel
826
+ // Water mist material needs special lighting: high emissive + translucent feel
827
827
  // During shading:
828
828
  if (hit.mat == 5) {
829
829
  lighting += vec3(0.4, 0.5, 0.6); // Water mist emissive (unaffected by shadows)
@@ -835,19 +835,19 @@ if (hit.mat == 5) {
835
835
 
836
836
  ### Variant 11: Multi-Building / Town / Minecraft-Style Scenes (Multi-Structure Town Composition)
837
837
  Towns, villages, Minecraft-style worlds, and other scenes requiring multiple discrete structures (houses, trees, lampposts, etc.) placed on the ground.
838
- **IMPORTANT: "Minecraft-like voxel scene" = multi-building scene; must follow the performance constraints of this template!**
838
+ **"Minecraft-like voxel scene" = multi-building scene; must follow the performance constraints of this template!**
839
839
  ```glsl
840
- // IMPORTANT: Key points for multi-building scenes:
840
+ // Key points for multi-building scenes:
841
841
  // 1. Define the ground first (height map or flat plane), ensure ground getVoxel returns correct material
842
842
  // 2. Each building uses an independent helper function, receiving local coordinates, returning material ID
843
843
  // 3. In getVoxel, check each building sequentially (using offset coordinates), return on first hit
844
844
  // 4. Camera must be outside the scene facing the center, far enough to see the full view
845
- // 5. IMPORTANT: Building coordinate ranges must be within DDA traversal range (MAX_RAY_STEPS * cell ≈ reachable distance)
846
- // 6. IMPORTANT: Scene range should not be too large! Concentrate all buildings within -20~20 range, camera 30-50 cells away
847
- // 7. IMPORTANT: SwiftShader performance critical: getVoxel must have AABB bounding box early exit!
845
+ // 5. Building coordinate ranges must be within DDA traversal range (MAX_RAY_STEPS * cell ≈ reachable distance)
846
+ // 6. Scene range should not be too large! Concentrate all buildings within -20~20 range, camera 30-50 cells away
847
+ // 7. SwiftShader performance critical: getVoxel must have AABB bounding box early exit!
848
848
  // Above ground (c.y > 0), check AABB range first; return 0 immediately if outside building area
849
849
  // Otherwise every DDA step checks all buildings → frame timeout → black screen / only sky renders
850
- // 8. IMPORTANT: MAX_RAY_STEPS reduced to 64, MAX_SHADOW_STEPS to 16 (complex getVoxel requires lower step counts)
850
+ // 8. MAX_RAY_STEPS reduced to 64, MAX_SHADOW_STEPS to 16 (complex getVoxel requires lower step counts)
851
851
 
852
852
  // Single house: width w, depth d, height h, with triangular roof
853
853
  int makeHouse(vec3 p, float w, float d, float h, int wallMat, int roofMat) {
@@ -902,13 +902,13 @@ int getVoxel(vec3 c) {
902
902
  // 2. Road (along z direction, x range -2~2)
903
903
  if (c.y < 1.0 && abs(c.x) < 2.0) return 2; // Road surface
904
904
 
905
- // IMPORTANT: AABB bounding box early exit (required for SwiftShader!)
905
+ // AABB bounding box early exit (required for SwiftShader!)
906
906
  // All buildings are within x:-15~15, y:0~12, z:-5~15
907
907
  // Return 0 immediately outside this range, avoiding per-building checks
908
908
  if (c.x < -15.0 || c.x > 15.0 || c.y > 12.0 || c.z < -5.0 || c.z > 15.0) return 0;
909
909
 
910
910
  // 3. Place buildings (each with offset coordinates)
911
- // IMPORTANT: House width/height must be ≥ 5 cells, otherwise they look like dots from far away! Use bright material colors
911
+ // House width/height must be ≥ 5 cells, otherwise they look like dots from far away! Use bright material colors
912
912
  int m;
913
913
 
914
914
  // House A: position (5, 0, 3), width 6, depth 5, height 5
@@ -930,7 +930,7 @@ int getVoxel(vec3 c) {
930
930
  return 0;
931
931
  }
932
932
 
933
- // IMPORTANT: Camera setup: must be far enough to overlook the entire town
933
+ // Camera setup: must be far enough to overlook the entire town
934
934
  // Recommended: ro = vec3(0, 15, -35), looking at scene center vec3(0, 3, 5)
935
935
  vec3 ro = vec3(0.0, 15.0, -35.0);
936
936
  vec3 lookAt = vec3(0.0, 3.0, 5.0);
@@ -939,12 +939,12 @@ vec3 right = normalize(cross(forward, vec3(0, 1, 0)));
939
939
  vec3 up = cross(right, forward);
940
940
  vec3 rd = normalize(forward * 0.8 + right * screenPos.x + up * screenPos.y);
941
941
 
942
- // IMPORTANT: Sunset/side-lit scene key: when light comes from the side or at low angle, building fronts may be completely backlit turning into black silhouettes!
942
+ // Sunset/side-lit scene key: when light comes from the side or at low angle, building fronts may be completely backlit turning into black silhouettes!
943
943
  // Must satisfy all: (1) ambient light ≥ 0.3 (prevent backlit faces from going black); (2) house walls use bright materials (e.g., light yellow 0.85,0.75,0.55)
944
944
  // (3) house dimensions must not be too small (width/height ≥ 5 cells), otherwise they look like dots from far away
945
945
  vec3 sunDir = normalize(vec3(-0.8, 0.3, 0.5)); // Sunset low angle
946
946
  vec3 sunColor = vec3(1.0, 0.6, 0.3); // Warm orange
947
- vec3 ambientColor = vec3(0.35, 0.3, 0.4); // IMPORTANT: High ambient light (≥0.3) to prevent silhouettes
947
+ vec3 ambientColor = vec3(0.35, 0.3, 0.4); // High ambient light (≥0.3) to prevent silhouettes
948
948
  // lighting = ambientColor + diff * sunColor * shadow;
949
949
  ```
950
950
 
@@ -957,7 +957,7 @@ vec3 ambientColor = vec3(0.35, 0.3, 0.4); // IMPORTANT: High ambient light (≥
957
957
  - Material queries, AO, normals, etc. are only computed after hit
958
958
  - Replace procedural voxel queries with `texelFetch` texture sampling
959
959
  - Multi-frame accumulation + reprojection for low-noise results
960
- - **IMPORTANT: MAX_RAY_STEPS defaults to 64, MAX_SHADOW_STEPS defaults to 16 (total 80)**. Only simple scenes (single cube/sphere) can increase to 96+24. Multi-building/Minecraft/character scenes with complex getVoxel must keep 64+16 or lower, otherwise SwiftShader frame timeout → only sky background renders
960
+ - **MAX_RAY_STEPS defaults to 64, MAX_SHADOW_STEPS defaults to 16 (total 80)**. Only simple scenes (single cube/sphere) can increase to 96+24. Multi-building/Minecraft/character scenes with complex getVoxel must keep 64+16 or lower, otherwise SwiftShader frame timeout → only sky background renders
961
961
 
962
962
  **Composition Tips:**
963
963
  - **Procedural noise terrain**: use FBM/Perlin noise height maps inside `getVoxel()`
@@ -22,7 +22,7 @@ Output: `production/qa/smoke-[date].md`
22
22
 
23
23
  1. Verify `tests/` exists (else stop → `/test-setup`)
24
24
  2. Check CI workflow for test refs
25
- 3. Read engine from `.claude/docs/technical-preferences.md`
25
+ 3. Detect the engine from `ProjectSettings/ProjectVersion.txt` (Unity) or the `.uproject` (Unreal)
26
26
  4. Load smoke test list from `production/qa/smoke-tests.md` or `tests/smoke/`
27
27
  5. Load QA plan from `production/qa/qa-plan-*.md` (most recent)
28
28
 
@@ -44,6 +44,5 @@ Glob for `production/qa/qa-plan-sprint-[N].md`. Found → note in output. Not fo
44
44
 
45
45
  - `/qa-plan sprint` — required before implementation
46
46
  - `/story-readiness [story-file]` — validate before starting
47
- - `/dev-story [story-file]` — begin implementing
48
- - `/sprint-status` — check progress mid-sprint
47
+ - `/sprint-report` — check progress mid-sprint
49
48
  - `/scope-check [epic]` — verify no scope creep
@@ -35,13 +35,13 @@ AskUserQuestion multi-tab:
35
35
 
36
36
  | Tipo | Rol | División | Skills clave |
37
37
  |------|-----|----------|-------------|
38
- | Juego | Dev | Game Dev | `/brainstorm`, `/setup-engine`, `/design-system` |
39
- | Web app | Dev | Software Eng | `/scaffold-nextjs`, `/create-architecture` |
40
- | API | Dev | Software Eng | `/scaffold-go`, `/scaffold-fastapi` |
41
- | Móvil | Dev | Software Eng | `/scaffold-flutter`, `/scaffold-react-native` |
38
+ | Juego | Dev | Game Dev | `/brainstorm`, `/scaffold-unity` (Unity) o `/ue-project-context` (Unreal), `/design-system` |
39
+ | Web app | Dev | Software Eng | `/nextjs-scaffold`, `/architecture-decision` |
40
+ | API | Dev | Software Eng | `/scaffold-go`, `/scaffold-fastify-ts` |
41
+ | Móvil | Dev | Software Eng | `/scaffold-react-native` |
42
42
  | Juego | Designer | Game Dev | `/brainstorm`, `/quick-design`, `/doc-gdd` |
43
43
  | Web | Designer | Product | `/ux-design`, `/design-handoff` |
44
- | Any | PM | PMO | `/sprint-planning`, `/clickup`, `/jira-tickets` |
44
+ | Any | PM | PMO | `/sprint-plan`, `/clickup`, `/jira-tickets` |
45
45
 
46
46
  ## Paso 5: Set session state
47
47
 
@@ -53,8 +53,8 @@ AskUserQuestion: primary recommendation (Recommended), secondary option, "Ver to
53
53
 
54
54
  ## Routing Cheatsheet
55
55
 
56
- - Game from scratch: `/start` → `/brainstorm` → `/setup-engine` → `/art-bible` → `/design-system`
57
- - Web app: `/start` → `/scaffold-nextjs` → `/create-architecture` → `/design-api`
56
+ - Game from scratch: `/start` → `/brainstorm` → `/scaffold-unity` (Unity) o `/ue-project-context` (Unreal) → `/art-bible` → `/design-system`
57
+ - Web app: `/start` → `/nextjs-scaffold` → `/architecture-decision` → `/api-design`
58
58
  - Sprint en curso: `/start` → `/clickup status` → `/standup-report`
59
59
 
60
60
  ## Reglas
@@ -59,7 +59,7 @@ Ask approval → edit story: `Status: Complete` + `## Completion Notes` (date, c
59
59
 
60
60
  ## Phase 8: Surface Next Story
61
61
 
62
- Read sprint plan → find READY/NOT STARTED stories (not blocked, Must/Should Have). Present up to 3 options. If all Must Have complete → sprint close-out sequence: `/smoke-check sprint` → `/team-qa sprint` → `/gate-check`.
62
+ Read sprint plan → find READY/NOT STARTED stories (not blocked, Must/Should Have). Present up to 3 options. If all Must Have complete → sprint close-out sequence: `/smoke-check sprint` → `/gate-check`.
63
63
 
64
64
  ## Protocol
65
65
 
@@ -21,8 +21,8 @@ Output: `tests/helpers/` with engine-specific helpers. Run after `/test-setup`,
21
21
 
22
22
  ## Detection
23
23
 
24
- - Read `.claude/docs/technical-preferences.md` → Engine, Language, Framework
25
- - No engine → stop: "Run `/setup-engine` first"
24
+ - Detect the engine from the project: `ProjectSettings/ProjectVersion.txt` (Unity) or a `*.uproject` file (Unreal); language and test framework from the project files
25
+ - No engine detected → ask the user which engine the project uses
26
26
  - Scan `tests/**/*_test.*` (up to 5 files): extract setup, assertion, factory, mock patterns
27
27
  - Read `design/gdd/systems-index.md`, in-scope GDDs, `docs/architecture/tr-registry.yaml`
28
28
 
@@ -48,3 +48,8 @@ Present summary of files to create → ask approval → write. **Never overwrite
48
48
  - Helpers reflect GDD bounds and constants, not invented values
49
49
  - Generated code is a starting point — adapt to actual class structure
50
50
  - Ask before writing to `tests/`
51
+
52
+ ## Next Steps
53
+
54
+ - `/regression-suite` — map the new helpers onto critical paths that still lack regression tests
55
+ - `/smoke-check` — run the suite before QA hand-off
@@ -12,7 +12,7 @@ Scaffold automated testing infrastructure. Run once during Technical Setup phase
12
12
 
13
13
  ## Phase 1: Detect Engine & State
14
14
 
15
- 1. Read `.claude/docs/technical-preferences.md` → Engine. Not configured → stop: "Run `/setup-engine` first"
15
+ 1. Detect the engine from the project: `ProjectSettings/ProjectVersion.txt` (Unity) or a `*.uproject` file (Unreal). None found → ask the user which engine the project uses
16
16
  2. Check existing: `tests/`, `tests/unit/`, `tests/integration/`, `.github/workflows/`, engine-specific dirs
17
17
  3. Report findings. If everything exists and no `force` arg → "Already in place. Re-run with `force` to regenerate"
18
18
  4. `force` skips early-exit but never overwrites existing files
@@ -498,7 +498,6 @@ Validate before considering the work done:
498
498
  - [ ] Ownership and attachment are explicit, with no dangling component references
499
499
  - [ ] Initialization happens in the correct lifecycle stage, not all in `BeginPlay`
500
500
  - [ ] Conventions in `docs/unreal/project-context.md` were read and followed
501
- - [ ] The Common Mistakes section of this skill was reviewed against the change
502
501
 
503
502
  **PASS** — every item holds. **CONCERNS** — the work stands but at least one item is unresolved and worth flagging to the user. **FAIL** — an item is violated in a way that breaks correctness, replication or the frame budget; fix it before handing the work over.
504
503
 
@@ -515,7 +515,6 @@ Validate before considering the work done:
515
515
  - [ ] Perception configuration matches the intended detection ranges and teams
516
516
  - [ ] NavMesh generation settings cover the agent sizes actually used
517
517
  - [ ] Conventions in `docs/unreal/project-context.md` were read and followed
518
- - [ ] The Common Mistakes section of this skill was reviewed against the change
519
518
 
520
519
  **PASS** — every item holds. **CONCERNS** — the work stands but at least one item is unresolved and worth flagging to the user. **FAIL** — an item is violated in a way that breaks correctness, replication or the frame budget; fix it before handing the work over.
521
520
 
@@ -510,7 +510,6 @@ Validate before considering the work done:
510
510
  - [ ] Montage sections and notifies are named consistently and documented
511
511
  - [ ] No gameplay decisions are made inside the animation graph
512
512
  - [ ] Conventions in `docs/unreal/project-context.md` were read and followed
513
- - [ ] The Common Mistakes section of this skill was reviewed against the change
514
513
 
515
514
  **PASS** — every item holds. **CONCERNS** — the work stands but at least one item is unresolved and worth flagging to the user. **FAIL** — an item is violated in a way that breaks correctness, replication or the frame budget; fix it before handing the work over.
516
515
 
@@ -422,7 +422,6 @@ Validate before considering the work done:
422
422
  - [ ] Every async completion path handles the owner being destroyed mid-flight
423
423
  - [ ] Shared state is protected, or ownership is transferred instead of shared
424
424
  - [ ] Conventions in `docs/unreal/project-context.md` were read and followed
425
- - [ ] The Common Mistakes section of this skill was reviewed against the change
426
425
 
427
426
  **PASS** — every item holds. **CONCERNS** — the work stands but at least one item is unresolved and worth flagging to the user. **FAIL** — an item is violated in a way that breaks correctness, replication or the frame budget; fix it before handing the work over.
428
427
 
@@ -515,7 +515,6 @@ Validate before considering the work done:
515
515
  - [ ] Attenuation settings are shared through assets rather than tuned per instance
516
516
  - [ ] Sounds are not started every frame or on every overlap event
517
517
  - [ ] Conventions in `docs/unreal/project-context.md` were read and followed
518
- - [ ] The Common Mistakes section of this skill was reviewed against the change
519
518
 
520
519
  **PASS** — every item holds. **CONCERNS** — the work stands but at least one item is unresolved and worth flagging to the user. **FAIL** — an item is violated in a way that breaks correctness, replication or the frame budget; fix it before handing the work over.
521
520
 
@@ -122,7 +122,6 @@ Validate before considering the work done:
122
122
  - [ ] Reusable logic lives in a Blueprint Class, not the Level Blueprint
123
123
  - [ ] Construction Script does editor-time setup only, with no gameplay side effects
124
124
  - [ ] Conventions in `docs/unreal/project-context.md` were read and followed
125
- - [ ] The Common Mistakes section of this skill was reviewed against the change
126
125
 
127
126
  **PASS** — every item holds. **CONCERNS** — the work stands but at least one item is unresolved and worth flagging to the user. **FAIL** — an item is violated in a way that breaks correctness, load times or the frame budget; fix it before handing the work over.
128
127
 
@@ -464,7 +464,6 @@ Validate before considering the work done:
464
464
  - [ ] Network prediction data was extended correctly for any new movement state
465
465
  - [ ] Root motion sources are used for authored displacement
466
466
  - [ ] Conventions in `docs/unreal/project-context.md` were read and followed
467
- - [ ] The Common Mistakes section of this skill was reviewed against the change
468
467
 
469
468
  **PASS** — every item holds. **CONCERNS** — the work stands but at least one item is unresolved and worth flagging to the user. **FAIL** — an item is violated in a way that breaks correctness, replication or the frame budget; fix it before handing the work over.
470
469
 
@@ -522,7 +522,6 @@ Validate before considering the work done:
522
522
  - [ ] Containers are `TArray`/`TMap`/`TSet`, strings use the right `FName`/`FText`/`FString` role
523
523
  - [ ] No `new`/`delete` on UObjects — `NewObject<>`/`CreateDefaultSubobject<>` only
524
524
  - [ ] Conventions in `docs/unreal/project-context.md` were read and followed
525
- - [ ] The Common Mistakes section of this skill was reviewed against the change
526
525
 
527
526
  **PASS** — every item holds. **CONCERNS** — the work stands but at least one item is unresolved and worth flagging to the user. **FAIL** — an item is violated in a way that breaks correctness, replication or the frame budget; fix it before handing the work over.
528
527
 
@@ -516,7 +516,6 @@ Validate before considering the work done:
516
516
  - [ ] Primary Asset types are registered so scanning and cooking behave correctly
517
517
  - [ ] No synchronous load of large assets on the game thread during gameplay
518
518
  - [ ] Conventions in `docs/unreal/project-context.md` were read and followed
519
- - [ ] The Common Mistakes section of this skill was reviewed against the change
520
519
 
521
520
  **PASS** — every item holds. **CONCERNS** — the work stands but at least one item is unresolved and worth flagging to the user. **FAIL** — an item is violated in a way that breaks correctness, replication or the frame budget; fix it before handing the work over.
522
521
 
@@ -512,7 +512,6 @@ Validate before considering the work done:
512
512
  - [ ] The tool fails safely on unexpected asset state instead of corrupting data
513
513
  - [ ] Bulk operations are undoable or clearly warn before running
514
514
  - [ ] Conventions in `docs/unreal/project-context.md` were read and followed
515
- - [ ] The Common Mistakes section of this skill was reviewed against the change
516
515
 
517
516
  **PASS** — every item holds. **CONCERNS** — the work stands but at least one item is unresolved and worth flagging to the user. **FAIL** — an item is violated in a way that breaks correctness, replication or the frame budget; fix it before handing the work over.
518
517
 
@@ -466,7 +466,6 @@ Validate before considering the work done:
466
466
  - [ ] Actions register and unregister symmetrically on activate/deactivate
467
467
  - [ ] The feature can be disabled without breaking a packaged build
468
468
  - [ ] Conventions in `docs/unreal/project-context.md` were read and followed
469
- - [ ] The Common Mistakes section of this skill was reviewed against the change
470
469
 
471
470
  **PASS** — every item holds. **CONCERNS** — the work stands but at least one item is unresolved and worth flagging to the user. **FAIL** — an item is violated in a way that breaks correctness, replication or the frame budget; fix it before handing the work over.
472
471
 
@@ -506,7 +506,6 @@ Validate before considering the work done:
506
506
  - [ ] State is identified by Gameplay Tags rather than booleans
507
507
  - [ ] Ability activation policy and prediction were chosen deliberately
508
508
  - [ ] Conventions in `docs/unreal/project-context.md` were read and followed
509
- - [ ] The Common Mistakes section of this skill was reviewed against the change
510
509
 
511
510
  **PASS** — every item holds. **CONCERNS** — the work stands but at least one item is unresolved and worth flagging to the user. **FAIL** — an item is violated in a way that breaks correctness, replication or the frame budget; fix it before handing the work over.
512
511
 
@@ -455,7 +455,6 @@ Validate before considering the work done:
455
455
  - [ ] Nothing authoritative lives on the Pawn, which can be destroyed and respawned
456
456
  - [ ] Server and client paths were both considered for every piece of state
457
457
  - [ ] Conventions in `docs/unreal/project-context.md` were read and followed
458
- - [ ] The Common Mistakes section of this skill was reviewed against the change
459
458
 
460
459
  **PASS** — every item holds. **CONCERNS** — the work stands but at least one item is unresolved and worth flagging to the user. **FAIL** — an item is violated in a way that breaks correctness, replication or the frame budget; fix it before handing the work over.
461
460