@fps-games/vfx 0.3.2 → 0.3.4

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 (234) hide show
  1. package/CHANGELOG.md +16 -0
  2. package/README.md +5 -5
  3. package/dist/effects/treasure-attention/index.d.ts +1 -1
  4. package/package.json +6 -5
  5. package/tooling/vfx-cli.mjs +31 -22
  6. package/tooling/vfx-package-resolution.mjs +8 -8
  7. package/docs/AUTHORING_EFFECTS.md +0 -297
  8. package/docs/INTEGRATION.md +0 -194
  9. package/docs/VFX_LIBRARY_ARCHITECTURE_chatgpt.md +0 -1580
  10. package/docs/VFX_LIBRARY_EXECUTION_PLAN.md +0 -229
  11. package/docs/VFX_LIBRARY_PLAN.md +0 -546
  12. package/docs/hit-flash-red-method.md +0 -155
  13. package/docs/treasure_attention_fx_babylonjs_guide.md +0 -901
  14. package/docs/vfx-ab/RESULTS.md +0 -35
  15. package/docs/vfx-ab/lumber-order/vehicle-exhaust-smoke/after.png +0 -0
  16. package/docs/vfx-ab/lumber-order/vehicle-exhaust-smoke/before.png +0 -0
  17. package/docs/vfx-ab/lumber-truck/vehicle-exhaust-smoke/after.png +0 -0
  18. package/docs/vfx-ab/lumber-truck/vehicle-exhaust-smoke/before.png +0 -0
  19. package/docs/vfx-integration_chatgpt.md +0 -462
  20. package/docs/vfx-placement-design.md +0 -164
  21. package/docs/weapon-trail-visualization.html +0 -241
  22. package/packages/EffectPackageService.ts +0 -346
  23. package/packages/SceneVfxService.ts +0 -96
  24. package/packages/build.mesh.yellow_build_upgrade_indicator/assets/runtime/simpleMeshEffect.v1.js +0 -333
  25. package/packages/build.mesh.yellow_build_upgrade_indicator/assets/shaders/mesh-effect-preview.frag.glsl +0 -25
  26. package/packages/build.mesh.yellow_build_upgrade_indicator/assets/shaders/mesh-effect-preview.vert.glsl +0 -11
  27. package/packages/build.mesh.yellow_build_upgrade_indicator/assets/textures/effect_jianbian.png +0 -0
  28. package/packages/build.mesh.yellow_build_upgrade_indicator/effect.json +0 -927
  29. package/packages/build.mesh.yellow_build_upgrade_indicator/media/contact-sheet.png +0 -0
  30. package/packages/build.mesh.yellow_build_upgrade_indicator/media/preview.gif +0 -0
  31. package/packages/build.mesh.yellow_build_upgrade_indicator/media/preview.mp4 +0 -0
  32. package/packages/build.mesh.yellow_build_upgrade_indicator/media/preview.webm +0 -0
  33. package/packages/build.mesh.yellow_build_upgrade_indicator/media/thumbnail.png +0 -0
  34. package/packages/build.mesh.yellow_build_upgrade_indicator/metadata/description.json +0 -197
  35. package/packages/build.mesh.yellow_build_upgrade_indicator/provenance/03-effect.original.json +0 -895
  36. package/packages/build.mesh.yellow_build_upgrade_indicator/provenance/03-normalized-vfx-to-babylon-report.json +0 -241
  37. package/packages/build.mesh.yellow_build_upgrade_indicator/provenance/04-preview-overrides.json +0 -542
  38. package/packages/build.mesh.yellow_build_upgrade_indicator/provenance/04-preview-tuning-report.json +0 -69
  39. package/packages/build.mesh.yellow_build_upgrade_indicator/provenance/asset-map.json +0 -125
  40. package/packages/build.mesh.yellow_build_upgrade_indicator/provenance/lineage.json +0 -44
  41. package/packages/build.particle.golden_upgrade_starburst/assets/runtime/particleEmitter.v1.js +0 -210
  42. package/packages/build.particle.golden_upgrade_starburst/assets/textures/effect_guangdian.png +0 -0
  43. package/packages/build.particle.golden_upgrade_starburst/effect.json +0 -880
  44. package/packages/build.particle.golden_upgrade_starburst/media/contact-sheet.png +0 -0
  45. package/packages/build.particle.golden_upgrade_starburst/media/preview.gif +0 -0
  46. package/packages/build.particle.golden_upgrade_starburst/media/preview.mp4 +0 -0
  47. package/packages/build.particle.golden_upgrade_starburst/media/preview.webm +0 -0
  48. package/packages/build.particle.golden_upgrade_starburst/media/thumbnail.png +0 -0
  49. package/packages/build.particle.golden_upgrade_starburst/metadata/description.json +0 -161
  50. package/packages/build.particle.golden_upgrade_starburst/provenance/03-effect.original.json +0 -762
  51. package/packages/build.particle.golden_upgrade_starburst/provenance/03-normalized-vfx-to-babylon-report.json +0 -260
  52. package/packages/build.particle.golden_upgrade_starburst/provenance/04-preview-overrides.json +0 -436
  53. package/packages/build.particle.golden_upgrade_starburst/provenance/04-preview-tuning-report.json +0 -40
  54. package/packages/build.particle.golden_upgrade_starburst/provenance/asset-map.json +0 -115
  55. package/packages/build.particle.golden_upgrade_starburst/provenance/lineage.json +0 -40
  56. package/packages/build.particle.orange_upgrade_transform_sparks/assets/runtime/particleEmitter.v1.js +0 -210
  57. package/packages/build.particle.orange_upgrade_transform_sparks/assets/textures/b5b27ab1-e740-4398-b407-848fc2b2c897.png +0 -0
  58. package/packages/build.particle.orange_upgrade_transform_sparks/effect.json +0 -887
  59. package/packages/build.particle.orange_upgrade_transform_sparks/media/preview.gif +0 -0
  60. package/packages/build.particle.orange_upgrade_transform_sparks/media/preview.mp4 +0 -0
  61. package/packages/build.particle.orange_upgrade_transform_sparks/media/preview.webm +0 -0
  62. package/packages/build.particle.orange_upgrade_transform_sparks/media/thumbnail.png +0 -0
  63. package/packages/build.particle.orange_upgrade_transform_sparks/metadata/description.json +0 -179
  64. package/packages/build.particle.orange_upgrade_transform_sparks/provenance/03-effect.original.json +0 -859
  65. package/packages/build.particle.orange_upgrade_transform_sparks/provenance/03-normalized-vfx-to-babylon-report.json +0 -260
  66. package/packages/build.particle.orange_upgrade_transform_sparks/provenance/04-preview-overrides.json +0 -478
  67. package/packages/build.particle.orange_upgrade_transform_sparks/provenance/04-preview-tuning-report.json +0 -40
  68. package/packages/build.particle.orange_upgrade_transform_sparks/provenance/asset-map.json +0 -114
  69. package/packages/build.particle.orange_upgrade_transform_sparks/provenance/lineage.json +0 -41
  70. package/packages/build.particle.wood_chip_dust_burst/assets/runtime/particleEmitter.v1.js +0 -210
  71. package/packages/build.particle.wood_chip_dust_burst/assets/textures/effect_yanwu4.png +0 -0
  72. package/packages/build.particle.wood_chip_dust_burst/assets/textures/suipian3.png +0 -0
  73. package/packages/build.particle.wood_chip_dust_burst/effect.json +0 -1400
  74. package/packages/build.particle.wood_chip_dust_burst/media/contact-sheet.png +0 -0
  75. package/packages/build.particle.wood_chip_dust_burst/media/preview.gif +0 -0
  76. package/packages/build.particle.wood_chip_dust_burst/media/preview.mp4 +0 -0
  77. package/packages/build.particle.wood_chip_dust_burst/media/preview.webm +0 -0
  78. package/packages/build.particle.wood_chip_dust_burst/media/thumbnail.png +0 -0
  79. package/packages/build.particle.wood_chip_dust_burst/metadata/description.json +0 -173
  80. package/packages/build.particle.wood_chip_dust_burst/provenance/03-effect.original.json +0 -1277
  81. package/packages/build.particle.wood_chip_dust_burst/provenance/03-normalized-vfx-to-babylon-report.json +0 -329
  82. package/packages/build.particle.wood_chip_dust_burst/provenance/04-preview-overrides.json +0 -749
  83. package/packages/build.particle.wood_chip_dust_burst/provenance/04-preview-tuning-report.json +0 -60
  84. package/packages/build.particle.wood_chip_dust_burst/provenance/asset-map.json +0 -146
  85. package/packages/build.particle.wood_chip_dust_burst/provenance/lineage.json +0 -69
  86. package/packages/effects/building-upgrade/effect.json +0 -6
  87. package/packages/effects/building-upgrade/index.ts +0 -387
  88. package/packages/effects/character-entrance/effect.json +0 -6
  89. package/packages/effects/character-entrance/index.ts +0 -308
  90. package/packages/effects/coin-burst/index.ts +0 -48
  91. package/packages/effects/comet-trail-flame/assets/textures/trail_5x4.webp +0 -0
  92. package/packages/effects/comet-trail-flame/index.ts +0 -107
  93. package/packages/effects/conveyor-upgrade/effect.json +0 -6
  94. package/packages/effects/conveyor-upgrade/index.ts +0 -401
  95. package/packages/effects/debris-smoke/assets/models/rock_debris.glb +0 -0
  96. package/packages/effects/debris-smoke/assets/textures/smoke22.webp +0 -0
  97. package/packages/effects/debris-smoke/index.ts +0 -102
  98. package/packages/effects/door_open_gold_flakes/assets/runtime/goldFlakes.v1.js +0 -397
  99. package/packages/effects/door_open_gold_flakes/door_open_gold_flakes.json +0 -498
  100. package/packages/effects/door_open_gold_flakes/index.ts +0 -11
  101. package/packages/effects/electric-arc/assets/textures/spark_4x4.webp +0 -0
  102. package/packages/effects/electric-arc/index.ts +0 -63
  103. package/packages/effects/energy-shield/effect.json +0 -7
  104. package/packages/effects/energy-shield/index.ts +0 -432
  105. package/packages/effects/explosion/assets/textures/baozha29.webp +0 -0
  106. package/packages/effects/explosion/assets/textures/glow01.webp +0 -0
  107. package/packages/effects/explosion/assets/textures/lizi01.webp +0 -0
  108. package/packages/effects/explosion/assets/textures/xulie_lizibaozha02_5x5.webp +0 -0
  109. package/packages/effects/explosion/index.ts +0 -115
  110. package/packages/effects/ground-tile-upgrade/effect.json +0 -6
  111. package/packages/effects/ground-tile-upgrade/index.ts +0 -410
  112. package/packages/effects/hit-flash/index.ts +0 -77
  113. package/packages/effects/laser-beam/assets/textures/laser_glow.webp +0 -0
  114. package/packages/effects/laser-beam/assets/textures/laser_noise.webp +0 -0
  115. package/packages/effects/laser-beam/index.ts +0 -6
  116. package/packages/effects/laser-beam-factory.ts +0 -146
  117. package/packages/effects/lumber-cart-suction/effect.json +0 -6
  118. package/packages/effects/lumber-cart-suction/index.ts +0 -399
  119. package/packages/effects/lumber-debris-scatter/assets/models/lumber_prop_model.glb +0 -0
  120. package/packages/effects/lumber-debris-scatter/assets/models/lumber_prop_model.glb.versions/.active +0 -1
  121. package/packages/effects/lumber-debris-scatter/assets/models/lumber_prop_model.glb.versions/1781589063890_upload.glb +0 -0
  122. package/packages/effects/lumber-debris-scatter/assets/runtime/solidParticleScatter.v1.js +0 -236
  123. package/packages/effects/lumber-debris-scatter/effect.json +0 -228
  124. package/packages/effects/lumber-debris-scatter/index.ts +0 -780
  125. package/packages/effects/lumber_vehicle_gear_spin/assets/runtime/gearSpin.v1.js +0 -202
  126. package/packages/effects/lumber_vehicle_gear_spin/index.ts +0 -11
  127. package/packages/effects/lumber_vehicle_gear_spin/lumber_vehicle_gear_spin.json +0 -338
  128. package/packages/effects/lumber_vehicle_upgrade_aura/assets/runtime/upgradeAura.v1.js +0 -353
  129. package/packages/effects/lumber_vehicle_upgrade_aura/index.ts +0 -13
  130. package/packages/effects/lumber_vehicle_upgrade_aura/lumber_vehicle_upgrade_aura.json +0 -365
  131. package/packages/effects/lumber_vehicle_wood_chips/assets/runtime/solidParticleScatter.v1.js +0 -310
  132. package/packages/effects/lumber_vehicle_wood_chips/index.ts +0 -11
  133. package/packages/effects/lumber_vehicle_wood_chips/lumber_vehicle_wood_chips.json +0 -335
  134. package/packages/effects/monster-hit/index.ts +0 -129
  135. package/packages/effects/player-upgrade/effect.json +0 -6
  136. package/packages/effects/player-upgrade/index.ts +0 -640
  137. package/packages/effects/pulse-laser-volley/assets/textures/bolt_guangshu.webp +0 -0
  138. package/packages/effects/pulse-laser-volley/index.ts +0 -215
  139. package/packages/effects/resource-collect-sparkles/effect.json +0 -6
  140. package/packages/effects/resource-collect-sparkles/index.ts +0 -254
  141. package/packages/effects/run-footstep-dust/assets/runtime/runFootstepDust.v1.js +0 -215
  142. package/packages/effects/run-footstep-dust/effect.json +0 -183
  143. package/packages/effects/run-footstep-dust/index.ts +0 -377
  144. package/packages/effects/space-shared.ts +0 -120
  145. package/packages/effects/thruster-flame/index.ts +0 -306
  146. package/packages/effects/treasure-attention/effect.json +0 -7
  147. package/packages/effects/treasure-attention/index.ts +0 -630
  148. package/packages/effects/tree-chop-dust/assets/textures/tree_chop_dust_atlas.png +0 -0
  149. package/packages/effects/tree-chop-dust/effect.json +0 -8
  150. package/packages/effects/tree-chop-dust/index.ts +0 -202
  151. package/packages/effects/tree-leaf-chop-burst/assets/runtime/particleEmitter.v1.js +0 -303
  152. package/packages/effects/tree-leaf-chop-burst/assets/textures/tree_leaf_chop_burst_leaf_atlas.png +0 -0
  153. package/packages/effects/tree-leaf-chop-burst/effect.json +0 -498
  154. package/packages/effects/tree-leaf-chop-burst/index.ts +0 -294
  155. package/packages/effects/tree_chop_dust_burst/assets/runtime/particleEmitter.v1.js +0 -318
  156. package/packages/effects/tree_chop_dust_burst/assets/textures/tree_chop_dust_burst_dust.png +0 -0
  157. package/packages/effects/tree_chop_dust_burst/index.ts +0 -13
  158. package/packages/effects/tree_chop_dust_burst/tree_chop_dust_burst.json +0 -412
  159. package/packages/effects/ufo-thread-flame/assets/textures/flame_flow.webp +0 -0
  160. package/packages/effects/ufo-thread-flame/assets/textures/flame_spike.webp +0 -0
  161. package/packages/effects/ufo-thread-flame/index.ts +0 -153
  162. package/packages/effects/vehicle-exhaust-smoke/assets/textures/vehicle_exhaust_smoke_atlas.png +0 -0
  163. package/packages/effects/vehicle-exhaust-smoke/effect.json +0 -8
  164. package/packages/effects/vehicle-exhaust-smoke/index.ts +0 -298
  165. package/packages/effects/vehicle-upgrade/effect.json +0 -6
  166. package/packages/effects/vehicle-upgrade/index.ts +0 -404
  167. package/packages/effects/weapon-trail/assets/textures/trail_wedge.png +0 -0
  168. package/packages/effects/weapon-trail/index.ts +0 -317
  169. package/packages/effects/wood-crusher-sawdust/assets/runtime/particleEmitter.v1.js +0 -312
  170. package/packages/effects/wood-crusher-sawdust/assets/textures/wood_crusher_sawdust_dust.png +0 -0
  171. package/packages/effects/wood-crusher-sawdust/assets/textures/wood_crusher_sawdust_fiber.png +0 -0
  172. package/packages/effects/wood-crusher-sawdust/index.ts +0 -43
  173. package/packages/effects/wood-crusher-sawdust/wood_crusher_sawdust.json +0 -592
  174. package/packages/effects/wood-cutter-sawdust/assets/runtime/particleEmitter.v1.js +0 -312
  175. package/packages/effects/wood-cutter-sawdust/assets/textures/wood_cutter_sawdust_chip.png +0 -0
  176. package/packages/effects/wood-cutter-sawdust/assets/textures/wood_cutter_sawdust_dust.png +0 -0
  177. package/packages/effects/wood-cutter-sawdust/index.ts +0 -43
  178. package/packages/effects/wood-cutter-sawdust/wood_cutter_sawdust.json +0 -592
  179. package/packages/effects/wood-sawdust-effect-factory.ts +0 -194
  180. package/packages/effects/wood_crusher_sawdust/assets/runtime/particleEmitter.v1.js +0 -318
  181. package/packages/effects/wood_crusher_sawdust/assets/textures/wood_crusher_sawdust_dust.png +0 -0
  182. package/packages/effects/wood_crusher_sawdust/assets/textures/wood_crusher_sawdust_fiber.png +0 -0
  183. package/packages/effects/wood_crusher_sawdust/index.ts +0 -29
  184. package/packages/effects/wood_crusher_sawdust/wood_crusher_sawdust.json +0 -592
  185. package/packages/effects/wood_cutter_sawdust/assets/runtime/particleEmitter.v1.js +0 -318
  186. package/packages/effects/wood_cutter_sawdust/assets/textures/wood_cutter_sawdust_chip.png +0 -0
  187. package/packages/effects/wood_cutter_sawdust/assets/textures/wood_cutter_sawdust_dust.png +0 -0
  188. package/packages/effects/wood_cutter_sawdust/index.ts +0 -29
  189. package/packages/effects/wood_cutter_sawdust/wood_cutter_sawdust.json +0 -592
  190. package/packages/effects/wood_peel_material_test/assets/runtime/woodPeelMaterialTest.v1.js +0 -196
  191. package/packages/effects/wood_peel_material_test/index.ts +0 -11
  192. package/packages/effects/wood_peel_material_test/wood_peel_material_test.json +0 -136
  193. package/packages/env.particle.forest_edge_fog/assets/runtime/particleEmitter.v1.js +0 -210
  194. package/packages/env.particle.forest_edge_fog/assets/textures/f12a23c4-b924-4322-a260-3d982428f1e8.png +0 -0
  195. package/packages/env.particle.forest_edge_fog/assets/textures/yuan.png +0 -0
  196. package/packages/env.particle.forest_edge_fog/effect.json +0 -854
  197. package/packages/env.particle.forest_edge_fog/media/preview.gif +0 -0
  198. package/packages/env.particle.forest_edge_fog/media/preview.mp4 +0 -0
  199. package/packages/env.particle.forest_edge_fog/media/preview.webm +0 -0
  200. package/packages/env.particle.forest_edge_fog/media/thumbnail.png +0 -0
  201. package/packages/env.particle.forest_edge_fog/metadata/description.json +0 -148
  202. package/packages/env.particle.forest_edge_fog/provenance/03-effect.original.json +0 -827
  203. package/packages/env.particle.forest_edge_fog/provenance/03-normalized-vfx-to-babylon-report.json +0 -196
  204. package/packages/env.particle.forest_edge_fog/provenance/04-preview-overrides.json +0 -432
  205. package/packages/env.particle.forest_edge_fog/provenance/04-preview-tuning-report.json +0 -28
  206. package/packages/env.particle.forest_edge_fog/provenance/asset-map.json +0 -124
  207. package/packages/env.particle.forest_edge_fog/provenance/lineage.json +0 -41
  208. package/packages/generation.ts +0 -14
  209. package/packages/index.ts +0 -14
  210. package/packages/legacy-particle-runtime.ts +0 -113
  211. package/packages/manifestRuntimePackage.ts +0 -519
  212. package/packages/registry.ts +0 -85
  213. package/packages/rendering.ts +0 -13
  214. package/packages/resource.particle.viscous_oil_suction/assets/runtime/top_disk_suction/particleEmitter.v1.js +0 -424
  215. package/packages/resource.particle.viscous_oil_suction/assets/textures/Glow ad.png +0 -0
  216. package/packages/resource.particle.viscous_oil_suction/effect.json +0 -1254
  217. package/packages/resource.particle.viscous_oil_suction/media/preview.gif +0 -0
  218. package/packages/resource.particle.viscous_oil_suction/media/preview.mp4 +0 -0
  219. package/packages/resource.particle.viscous_oil_suction/media/preview.webm +0 -0
  220. package/packages/resource.particle.viscous_oil_suction/media/thumbnail.png +0 -0
  221. package/packages/resource.particle.viscous_oil_suction/metadata/description.json +0 -122
  222. package/packages/resource.particle.viscous_oil_suction/provenance/03-effect.original.json +0 -1051
  223. package/packages/resource.particle.viscous_oil_suction/provenance/03-normalized-vfx-to-babylon-report.json +0 -200
  224. package/packages/resource.particle.viscous_oil_suction/provenance/04-preview-overrides.json +0 -581
  225. package/packages/resource.particle.viscous_oil_suction/provenance/04-preview-tuning-report.json +0 -28
  226. package/packages/resource.particle.viscous_oil_suction/provenance/asset-map.json +0 -111
  227. package/packages/resource.particle.viscous_oil_suction/provenance/lineage.json +0 -45
  228. package/packages/types.ts +0 -195
  229. package/tooling/check-dist-runtime.mjs +0 -166
  230. package/tooling/generate-index.mjs +0 -55
  231. package/tooling/test-guardrails.mjs +0 -157
  232. package/tooling/validate-boundary.mjs +0 -92
  233. package/tooling/validate-effects.mjs +0 -304
  234. package/tooling/validate.mjs +0 -53
@@ -1,1580 +0,0 @@
1
- # VFX Library / 特效库平台设计说明
2
-
3
- > 这份文档用于帮助新进入项目的 Agent 快速理解:我们为什么要做特效库、特效库应该放在哪里、用户如何在 Playable 项目里选择和安装特效、安装后如何在游戏编辑器中调试和保存参数。
4
-
5
- ---
6
-
7
- ## 1. 一句话概括
8
-
9
- 我们要做的是一个面向 Playable 制作平台的 **VFX Package Manager + Editor Debug Workflow**。
10
-
11
- 它不是一个简单的 `effects/` 文件夹,而是一套让非技术用户和 Agent 都能稳定使用的特效系统:
12
-
13
- ```text
14
- 中央特效库
15
-
16
- 特效浏览与预览
17
-
18
- 添加到当前 Playable 项目
19
-
20
- 绑定到对象 / 世界坐标 / Gameplay 事件
21
-
22
- 自动打开调试面板
23
-
24
- 调参并保存到当前项目或当前实例
25
-
26
- 构建时把项目实际使用的特效打包进 Playable
27
- ```
28
-
29
- 核心目标是:
30
-
31
- > 让特效像资产一样被浏览、安装、绑定、调试和复用,而不是每次都靠工程师手写 import、手动注册、手动调参数。
32
-
33
- ---
34
-
35
- ## 2. 背景与目标
36
-
37
- Playable 平台面向的是非技术人员。用户希望能通过编辑器或 Agent 快速制作小游戏广告,而不是直接写 Babylon.js 代码。
38
-
39
- 在 Playable 中,特效会大量出现在这些场景:
40
-
41
- - 资源收集
42
- - 金币飞入
43
- - 解锁区域
44
- - 建筑升级
45
- - 车辆尾气
46
- - 角色移动反馈
47
- - 引导箭头
48
- - Endcard 转场
49
- - 点击反馈
50
- - 成功 / 失败 / 奖励反馈
51
-
52
- 如果每个项目都手动写特效,会出现几个问题:
53
-
54
- 1. **复用困难**:同一个“资源收集闪光”在多个项目里反复复制代码。
55
- 2. **导入困难**:新特效需要工程师改代码、注册、打包。
56
- 3. **调试困难**:用户不知道应该在哪里调大小、颜色、粒子数量、挂载位置。
57
- 4. **参数污染**:一个项目里的调参不应该影响中央特效库默认值。
58
- 5. **Agent 难以自动化**:Agent 需要稳定 schema 才能知道有哪些特效、怎么用、怎么验证。
59
-
60
- 所以特效库的目标不是单纯管理代码,而是建立一套稳定工作流:
61
-
62
- ```text
63
- 发现特效 → 预览特效 → 安装特效 → 使用特效 → 调试特效 → 保存参数 → 构建发布
64
- ```
65
-
66
- ---
67
-
68
- ## 3. 核心原则
69
-
70
- ### 3.1 中央库和项目使用必须分离
71
-
72
- 中央特效库保存“特效是什么”。
73
-
74
- Playable 项目保存“这个项目安装了哪些特效,以及在哪里使用这些特效”。
75
-
76
- 不要让项目调参直接修改中央库默认值。
77
-
78
- ---
79
-
80
- ### 3.2 特效应该是 Package,而不是代码片段
81
-
82
- 每个特效都应该有独立 manifest、默认参数、参数 schema、预览图、预览视频和 runtime 入口。
83
-
84
- 也就是说,一个特效应该像这样被理解:
85
-
86
- ```text
87
- VFX Package = 实现代码 + 资源 + 参数定义 + 默认值 + 预览信息 + 版本信息
88
- ```
89
-
90
- ---
91
-
92
- ### 3.3 编辑器面板必须 schema-driven
93
-
94
- 不要给每个特效单独写一个 React 面板。
95
-
96
- 特效包提供 `parameterSchema`,编辑器根据 schema 自动生成滑杆、颜色选择、枚举选择、开关等 UI。
97
-
98
- 这样新特效只要声明参数,就能自动被调试面板支持。
99
-
100
- ---
101
-
102
- ### 3.4 Runtime 接口要保持稳定
103
-
104
- Editor 可以有复杂 UI,VFX Library 可以有复杂 registry,但 Runtime 只应该暴露稳定能力:
105
-
106
- ```text
107
- load package
108
- register package
109
- play effect
110
- dispose effect
111
- ```
112
-
113
- 不要让 Runtime 直接依赖编辑器产品逻辑。
114
-
115
- ---
116
-
117
- ### 3.5 第一版优先做闭环,不做大而全 marketplace
118
-
119
- MVP 应该优先实现:
120
-
121
- ```text
122
- 浏览 → 安装 → 绑定 → 调试 → 保存 → 打包
123
- ```
124
-
125
- 暂时不需要一开始就做:
126
-
127
- - 用户上传特效
128
- - 在线 marketplace
129
- - 多人协作
130
- - 复杂依赖解析
131
- - 自动版本升级
132
- - 可视化特效节点图
133
- - 线上热更新
134
-
135
- ---
136
-
137
- ## 4. 四个必须区分的概念
138
-
139
- 设计时一定要把下面四个概念分开。
140
-
141
- ---
142
-
143
- ### 4.1 VFX Package
144
-
145
- 表示中央库里的一个特效。
146
-
147
- 例如:
148
-
149
- ```text
150
- vehicle-exhaust-smoke@1.2.0
151
- resource-collect-sparkles@1.0.3
152
- building-upgrade-burst@0.4.1
153
- ```
154
-
155
- 它回答的问题是:
156
-
157
- > 这个特效是什么?有哪些参数?需要哪些资源?怎么运行?
158
-
159
- ---
160
-
161
- ### 4.2 VFX Dependency
162
-
163
- 表示当前 Playable 项目安装了哪些特效。
164
-
165
- 例如:
166
-
167
- ```json
168
- {
169
- "vfxDependencies": {
170
- "vehicle-exhaust-smoke": "1.2.0",
171
- "resource-collect-sparkles": "1.0.3"
172
- }
173
- }
174
- ```
175
-
176
- 它回答的问题是:
177
-
178
- > 这个项目依赖哪些特效包?
179
-
180
- ---
181
-
182
- ### 4.3 VFX Usage / Binding
183
-
184
- 表示当前 Playable 项目里某个特效被用在哪里。
185
-
186
- 例如:
187
-
188
- ```text
189
- Truck 节点挂了 vehicle-exhaust-smoke
190
- resource.collected 事件触发 resource-collect-sparkles
191
- UnlockArea 解锁时播放 building-upgrade-burst
192
- ```
193
-
194
- 它回答的问题是:
195
-
196
- > 这个特效在当前游戏中什么时候、在哪里、以什么参数播放?
197
-
198
- ---
199
-
200
- ### 4.4 VFX Preview Session
201
-
202
- 表示用户现在正在调试某个特效。
203
-
204
- 例如:
205
-
206
- ```text
207
- 用户正在右侧 Inspector 中调 Truck 尾气的 scale 和 particleCount
208
- ```
209
-
210
- 它回答的问题是:
211
-
212
- > 当前面板正在临时预览什么?哪些参数还没有保存?
213
-
214
- ---
215
-
216
- ## 5. 推荐总体架构
217
-
218
- ```text
219
- ┌──────────────────────────────┐
220
- │ VFX Library │
221
- │ 源码、manifest、资源、预览 │
222
- └──────────────┬───────────────┘
223
- │ publish
224
-
225
- ┌──────────────────────────────┐
226
- │ VFX Registry / Asset CDN │
227
- │ catalog、版本、bundle、hash │
228
- └──────────────┬───────────────┘
229
- │ install
230
-
231
- ┌──────────────────────────────┐
232
- │ Playable Project │
233
- │ dependencies、lock、presets │
234
- └──────────────┬───────────────┘
235
- │ load
236
-
237
- ┌──────────────────────────────┐
238
- │ VfxPackageLoader │
239
- │ 下载、缓存、动态加载、注册 │
240
- └──────────────┬───────────────┘
241
-
242
- ┌──────────────────────────────┐
243
- │ EffectPackageService │
244
- │ package 注册、查询、参数合并 │
245
- └──────────────┬───────────────┘
246
-
247
- ┌──────────────────────────────┐
248
- │ SceneVfxService │
249
- │ 播放、挂载、追踪、销毁 │
250
- └──────────────┬───────────────┘
251
-
252
- ┌──────────────────────────────┐
253
- │ Editor VFX Inspector │
254
- │ 选择、预览、调参、保存 │
255
- └──────────────────────────────┘
256
- ```
257
-
258
- 一句话:
259
-
260
- > 中央库负责“有哪些特效”,项目负责“安装了哪些特效”,场景和 Gameplay 负责“在哪里、何时使用”,编辑器面板负责“当前正在调什么”。
261
-
262
- ---
263
-
264
- ## 6. 特效库应该放在哪里
265
-
266
- ### 6.1 推荐放法
267
-
268
- 特效库应该是一个独立逻辑模块或独立 repo。
269
-
270
- 推荐目录:
271
-
272
- ```text
273
- vfx-library/
274
- ├── effects/
275
- │ ├── vehicle-exhaust-smoke/
276
- │ ├── resource-collect-sparkles/
277
- │ └── building-upgrade-burst/
278
- ├── registry.json
279
- ├── tooling/
280
- │ ├── build-effect.ts
281
- │ ├── validate-manifest.ts
282
- │ └── publish-effect.ts
283
- └── README.md
284
- ```
285
-
286
- 每个特效是一个独立 package:
287
-
288
- ```text
289
- effects/
290
- └── vehicle-exhaust-smoke/
291
- ├── effect.json
292
- ├── src/
293
- │ └── index.ts
294
- ├── dist/
295
- │ └── index.js
296
- ├── assets/
297
- │ └── smoke.webp
298
- ├── presets/
299
- │ └── default.json
300
- └── previews/
301
- ├── thumbnail.webp
302
- └── preview.mp4
303
- ```
304
-
305
- ---
306
-
307
- ### 6.2 不推荐放法
308
-
309
- 不建议把中央特效库直接放在:
310
-
311
- ```text
312
- 某个具体 Playable 项目的 src/
313
- Babylon 编辑器 repo 的业务 UI 目录里
314
- Runtime 的 internal assets 目录里
315
- 每个游戏项目里复制一份
316
- ```
317
-
318
- 原因:
319
-
320
- - 中央库会被具体项目污染。
321
- - 项目之间无法统一升级。
322
- - 构建产物难以去重。
323
- - Agent 难以知道哪些是平台特效,哪些是项目临时特效。
324
- - 非技术用户无法形成“可浏览的特效库”心智。
325
-
326
- ---
327
-
328
- ### 6.3 推荐职责边界
329
-
330
- | 层 | 放什么 | 不放什么 |
331
- |---|---|---|
332
- | VFX Library | 特效源码、资源、默认参数、schema、预览素材 | 具体项目的调参结果 |
333
- | VFX Registry / CDN | 编译后的 bundle、manifest、版本、hash、缩略图 | 编辑器业务状态 |
334
- | Playable Project | 已安装依赖、lock、项目 preset、usage/binding | 整个中央特效源码 |
335
- | Editor | 特效浏览器、安装按钮、绑定 UI、调试面板 | 每个特效的硬编码面板 |
336
- | Runtime SDK | 加载、注册、播放、销毁接口 | 产品 UI、registry 页面逻辑 |
337
-
338
- ---
339
-
340
- ## 7. 特效 Package Manifest
341
-
342
- 每个特效需要一个 `effect.json`。
343
-
344
- 示例:
345
-
346
- ```json
347
- {
348
- "schemaVersion": 1,
349
- "id": "vehicle-exhaust-smoke",
350
- "version": "1.2.0",
351
- "displayName": {
352
- "zh-CN": "车辆尾气",
353
- "en-US": "Vehicle Exhaust Smoke"
354
- },
355
- "description": {
356
- "zh-CN": "适合挂载在车辆尾部的循环烟雾特效。",
357
- "en-US": "Looping smoke effect designed for vehicle exhaust."
358
- },
359
- "category": "vehicle",
360
- "tags": ["smoke", "loop", "attachable", "vehicle"],
361
- "runtime": {
362
- "engine": "babylon",
363
- "entry": "./dist/index.js"
364
- },
365
- "capabilities": {
366
- "oneShot": false,
367
- "loop": true,
368
- "attachable": true,
369
- "worldPosition": true,
370
- "eventBinding": false
371
- },
372
- "assets": [
373
- "./assets/smoke.webp"
374
- ],
375
- "preview": {
376
- "thumbnail": "./previews/thumbnail.webp",
377
- "video": "./previews/preview.mp4"
378
- },
379
- "defaultParams": {
380
- "scale": 1.35,
381
- "particleCount": 82,
382
- "opacity": 0.6,
383
- "color": "#b7b7b7"
384
- },
385
- "parameterSchema": {
386
- "scale": {
387
- "type": "number",
388
- "label": "整体缩放",
389
- "min": 0.05,
390
- "max": 8,
391
- "step": 0.01,
392
- "default": 1.35
393
- },
394
- "particleCount": {
395
- "type": "number",
396
- "label": "粒子数量",
397
- "min": 1,
398
- "max": 300,
399
- "step": 1,
400
- "default": 82
401
- },
402
- "opacity": {
403
- "type": "number",
404
- "label": "透明度",
405
- "min": 0,
406
- "max": 1,
407
- "step": 0.01,
408
- "default": 0.6
409
- },
410
- "color": {
411
- "type": "color",
412
- "label": "颜色",
413
- "default": "#b7b7b7"
414
- }
415
- },
416
- "performance": {
417
- "maxParticles": 300,
418
- "recommendedInstances": 4
419
- },
420
- "compatibility": {
421
- "runtime": ">=0.1.0",
422
- "babylon": ">=6.0.0"
423
- }
424
- }
425
- ```
426
-
427
- ---
428
-
429
- ## 8. 特效 Runtime 接口建议
430
-
431
- 特效包最终应该被编译成一个标准模块。
432
-
433
- 示例 TypeScript 接口:
434
-
435
- ```ts
436
- export interface VfxEffectPackage<TParams = Record<string, unknown>> {
437
- id: string;
438
- version: string;
439
- create(context: VfxCreateContext, params: TParams): VfxEffectHandle;
440
- }
441
-
442
- export interface VfxCreateContext {
443
- scene: BABYLON.Scene;
444
- parent?: BABYLON.Node;
445
- position?: BABYLON.Vector3;
446
- rotation?: BABYLON.Vector3;
447
- assetResolver: VfxAssetResolver;
448
- }
449
-
450
- export interface VfxEffectHandle {
451
- root: BABYLON.Node;
452
- dispose(): void;
453
-
454
- /**
455
- * 可选。第一版不强制。
456
- * 如果某些循环特效需要不重建就实时调参,可以后续支持。
457
- */
458
- updateParams?: (patch: Record<string, unknown>) => void;
459
- }
460
- ```
461
-
462
- 第一版不要求每个特效实现 `updateParams`。
463
-
464
- 调参时可以采用:
465
-
466
- ```text
467
- 参数变化
468
-
469
- debounce 50-100ms
470
-
471
- dispose 当前预览
472
-
473
- 用新参数重新 create
474
- ```
475
-
476
- 好处:
477
-
478
- - 所有特效都能支持。
479
- - Runtime 接口简单。
480
- - 调试结果确定。
481
- - 更容易做自动截图回归。
482
-
483
- ---
484
-
485
- ## 9. 用户如何“选中特效”
486
-
487
- 这里有两个不同语义的“选中”,必须分开设计。
488
-
489
- ---
490
-
491
- ### 9.1 从中央库中选中 VFX Package
492
-
493
- 用户在编辑器里打开特效库:
494
-
495
- ```text
496
- 资产
497
- ├── 模型
498
- ├── UI
499
- ├── 音效
500
- └── 特效
501
- ```
502
-
503
- 特效库以卡片形式展示:
504
-
505
- ```text
506
- ┌──────────────────────┐
507
- │ thumbnail / video │
508
- │ 车辆尾气 │
509
- │ 循环 / 可挂载 │
510
- │ [预览] [添加到项目] │
511
- └──────────────────────┘
512
- ```
513
-
514
- 点击卡片后右侧显示:
515
-
516
- ```text
517
- 特效名称
518
- 预览视频
519
- 使用说明
520
- 分类 / 标签
521
- 参数列表
522
- 性能预算
523
- 版本信息
524
- [添加到项目]
525
- [绑定到当前选中对象]
526
- [放到场景中]
527
- ```
528
-
529
- 此时选中的是:
530
-
531
- ```text
532
- VFX Package
533
- ```
534
-
535
- 用户还没有真正修改当前游戏。
536
-
537
- ---
538
-
539
- ### 9.2 从当前项目中选中 VFX Usage
540
-
541
- 特效添加到项目并使用后,它应该成为当前项目里的一个对象或绑定。
542
-
543
- 例如:
544
-
545
- ```text
546
- Scene
547
- ├── Truck
548
- │ ├── Model
549
- │ └── VFX: Vehicle Exhaust
550
- ├── Player
551
- └── Gameplay Bindings
552
- └── On Resource Collected
553
- └── VFX: Collect Sparkles
554
- ```
555
-
556
- 此时选中的是:
557
-
558
- ```text
559
- VFX Usage / Binding
560
- ```
561
-
562
- 右侧 Inspector 应该打开当前实例的调试面板。
563
-
564
- ---
565
-
566
- ## 10. 特效如何添加到项目
567
-
568
- ### 10.1 安装流程
569
-
570
- 用户点击“添加到项目”后,推荐流程:
571
-
572
- ```text
573
- 用户点击“添加到项目”
574
-
575
- 读取 package id 和 version
576
-
577
- 检查项目是否已经安装
578
-
579
- 从 registry 下载或读取缓存
580
-
581
- 写入 project.vfxDependencies
582
-
583
- 写入 vfx-lock.json
584
-
585
- 动态加载 package bundle
586
-
587
- 注册到 EffectPackageService
588
-
589
- 创建 Preview Session 或 VFX Usage
590
-
591
- 编辑器自动选中新建对象
592
-
593
- 右侧自动打开 VFX Inspector
594
- ```
595
-
596
- ---
597
-
598
- ### 10.2 项目 dependency 示例
599
-
600
- 可以放在项目配置中:
601
-
602
- ```json
603
- {
604
- "vfxDependencies": {
605
- "vehicle-exhaust-smoke": "1.2.0",
606
- "resource-collect-sparkles": "1.0.3"
607
- }
608
- }
609
- ```
610
-
611
- ---
612
-
613
- ### 10.3 lock 文件示例
614
-
615
- ```json
616
- {
617
- "packages": {
618
- "vehicle-exhaust-smoke@1.2.0": {
619
- "resolved": "https://registry.example.com/vfx/vehicle-exhaust-smoke/1.2.0/index.js",
620
- "integrity": "sha256-xxxxxxxx",
621
- "assets": [
622
- {
623
- "path": "assets/smoke.webp",
624
- "integrity": "sha256-yyyyyyyy"
625
- }
626
- ]
627
- }
628
- }
629
- }
630
- ```
631
-
632
- 项目依赖负责表达:
633
-
634
- ```text
635
- 我需要哪个特效
636
- ```
637
-
638
- lock 文件负责表达:
639
-
640
- ```text
641
- 我实际用了哪个 bundle、哪个资源、哪个 hash
642
- ```
643
-
644
- ---
645
-
646
- ## 11. 三种核心使用方式
647
-
648
- 第一版建议优先支持三种使用方式。
649
-
650
- ---
651
-
652
- ### 11.1 放到世界坐标
653
-
654
- 适合:
655
-
656
- - 爆炸
657
- - 区域解锁
658
- - 建筑升级
659
- - 地面光圈
660
- - 奖励出现
661
-
662
- 数据示例:
663
-
664
- ```json
665
- {
666
- "id": "vfx_usage_unlock_burst_01",
667
- "type": "world",
668
- "package": "building-upgrade-burst@0.4.1",
669
- "position": [2.5, 0.1, -3.2],
670
- "rotation": [0, 0, 0],
671
- "params": {
672
- "scale": 1.2
673
- }
674
- }
675
- ```
676
-
677
- ---
678
-
679
- ### 11.2 挂到场景对象
680
-
681
- 适合:
682
-
683
- - 车辆尾气
684
- - 角色脚步烟尘
685
- - 建筑光环
686
- - 目标提示
687
- - NPC 状态反馈
688
-
689
- 数据示例:
690
-
691
- ```json
692
- {
693
- "id": "vfx_usage_truck_exhaust",
694
- "type": "attachment",
695
- "package": "vehicle-exhaust-smoke@1.2.0",
696
- "targetNodeId": "truck_01",
697
- "transform": {
698
- "position": [0, 0.4, -1.2],
699
- "rotation": [0, 3.14, 0],
700
- "scale": [1, 1, 1]
701
- },
702
- "params": {
703
- "scale": 1.1,
704
- "particleCount": 64
705
- }
706
- }
707
- ```
708
-
709
- ---
710
-
711
- ### 11.3 绑定 Gameplay Event
712
-
713
- 适合:
714
-
715
- - 资源收集
716
- - 金币飞入
717
- - 购买成功
718
- - 解锁完成
719
- - 任务完成
720
- - Endcard 触发
721
-
722
- 数据示例:
723
-
724
- ```json
725
- {
726
- "id": "vfx_binding_collect_wood",
727
- "type": "eventBinding",
728
- "package": "resource-collect-sparkles@1.0.3",
729
- "trigger": {
730
- "event": "resource.collected",
731
- "filter": {
732
- "resourceType": "wood"
733
- }
734
- },
735
- "spawn": {
736
- "source": "event.position"
737
- },
738
- "params": {
739
- "scale": 0.9
740
- }
741
- }
742
- ```
743
-
744
- ---
745
-
746
- ## 12. 添加后如何自动打开调试面板
747
-
748
- 编辑器需要一个统一 selection 事件。
749
-
750
- 示例:
751
-
752
- ```ts
753
- editorSelection.select({
754
- type: 'vfx-usage',
755
- id: usageId
756
- });
757
- ```
758
-
759
- Inspector 根据 selection 类型切换面板:
760
-
761
- ```ts
762
- if (selection.type === 'vfx-usage') {
763
- openInspectorTab('vfx');
764
- }
765
- ```
766
-
767
- 推荐用户体验:
768
-
769
- ```text
770
- 用户选中 Truck
771
-
772
- 打开特效库
773
-
774
- 点击“绑定到当前对象”
775
-
776
- 系统创建 VfxAttachment
777
-
778
- 自动选中新建的 VfxAttachment
779
-
780
- 右侧打开 VFX Inspector
781
-
782
- 自动开始循环预览
783
- ```
784
-
785
- 对于事件型特效:
786
-
787
- ```text
788
- 用户选择 resource.collected 事件
789
-
790
- 点击“添加收集特效”
791
-
792
- 创建 VfxEventBinding
793
-
794
- 右侧打开 VFX Inspector
795
-
796
- 面板显示“播放一次”按钮
797
- ```
798
-
799
- 关键点:
800
-
801
- > 添加特效后,用户不应该再去层级树里手动找它。系统应该自动选中并打开对应调试面板。
802
-
803
- ---
804
-
805
- ## 13. VFX Inspector 设计
806
-
807
- VFX Inspector 是通用调试面板。
808
-
809
- 它不应该写死某个特效的 UI,而应该读取 manifest 的 `parameterSchema` 自动生成控件。
810
-
811
- 推荐面板结构:
812
-
813
- ```text
814
- 车辆尾气
815
-
816
- Package
817
- ID: vehicle-exhaust-smoke
818
- Version: 1.2.0
819
-
820
- Preview
821
- [播放] [暂停] [重播]
822
- [隔离预览] [游戏内预览]
823
-
824
- Target
825
- Type: Attachment
826
- Target: Truck
827
- Position: X / Y / Z
828
- Rotation: X / Y / Z
829
- Scale: X / Y / Z
830
-
831
- Parameters
832
- 整体缩放 [----●-----]
833
- 粒子数量 [------●---]
834
- 透明度 [---●------]
835
- 颜色 [■]
836
-
837
- Save
838
- [保存到当前实例]
839
- [保存为项目 Preset]
840
- [另存为新 Variant]
841
- ```
842
-
843
- ---
844
-
845
- ## 14. 两种预览模式
846
-
847
- ### 14.1 隔离预览
848
-
849
- 在统一 preview stage 中预览特效。
850
-
851
- 特点:
852
-
853
- - 标准相机
854
- - 标准光照
855
- - 标准地面
856
- - 标准角色或车辆参照物
857
- - 自动循环
858
- - 适合浏览和比较特效
859
-
860
- 用于回答:
861
-
862
- > 这个特效大概长什么样?
863
-
864
- ---
865
-
866
- ### 14.2 游戏内预览
867
-
868
- 在当前 Playable 场景中,以当前对象、当前相机、当前光照播放特效。
869
-
870
- 特点:
871
-
872
- - 看到真实大小
873
- - 看到真实遮挡关系
874
- - 看到与当前资产的颜色是否搭配
875
- - 看到相机距离下是否清晰
876
- - 适合最终调参
877
-
878
- 用于回答:
879
-
880
- > 这个特效放到我的游戏里是否合适?
881
-
882
- ---
883
-
884
- ## 15. 参数保存层设计
885
-
886
- 参数保存层是整个特效系统中非常关键的部分。
887
-
888
- 不要让用户在项目里调参时直接覆盖中央库默认值。
889
-
890
- 推荐优先级:
891
-
892
- ```text
893
- 1. Library Default
894
- 中央库默认值,只读
895
-
896
- 2. Published Preset
897
- 中央库发布的官方预设,只读
898
-
899
- 3. Project Preset
900
- 当前 Playable 项目级预设
901
-
902
- 4. Usage Override
903
- 当前对象或事件绑定的实例级覆盖
904
-
905
- 5. Runtime Override
906
- Gameplay 运行时根据上下文传入
907
-
908
- 6. Preview Session Override
909
- 面板临时调试值,尚未保存
910
- ```
911
-
912
- 参数合并顺序:
913
-
914
- ```text
915
- Library Default
916
-
917
- Published Preset
918
-
919
- Project Preset
920
-
921
- Usage Override
922
-
923
- Runtime Override
924
-
925
- Preview Session Override
926
- ```
927
-
928
- 用户保存时必须明确选择保存位置:
929
-
930
- ```text
931
- 保存到当前实例
932
- 保存为项目 Preset
933
- 发布为新的公共 Variant
934
- ```
935
-
936
- 第一版建议只实现:
937
-
938
- ```text
939
- 保存到当前实例
940
- 保存为项目 Preset
941
- ```
942
-
943
- “发布为公共 Variant”可以留到后面。
944
-
945
- ---
946
-
947
- ## 16. 项目内数据结构建议
948
-
949
- 一个 Playable 项目中建议有三类 VFX 数据。
950
-
951
- ---
952
-
953
- ### 16.1 dependencies
954
-
955
- 表示项目安装了哪些特效。
956
-
957
- ```json
958
- {
959
- "vfxDependencies": {
960
- "vehicle-exhaust-smoke": "1.2.0",
961
- "resource-collect-sparkles": "1.0.3"
962
- }
963
- }
964
- ```
965
-
966
- ---
967
-
968
- ### 16.2 usages
969
-
970
- 表示场景中有哪些特效实例。
971
-
972
- ```json
973
- {
974
- "vfxUsages": [
975
- {
976
- "id": "vfx_usage_truck_exhaust",
977
- "type": "attachment",
978
- "package": "vehicle-exhaust-smoke@1.2.0",
979
- "targetNodeId": "truck_01",
980
- "transform": {
981
- "position": [0, 0.4, -1.2],
982
- "rotation": [0, 3.14, 0],
983
- "scale": [1, 1, 1]
984
- },
985
- "params": {
986
- "scale": 1.1
987
- }
988
- }
989
- ]
990
- }
991
- ```
992
-
993
- ---
994
-
995
- ### 16.3 eventBindings
996
-
997
- 表示 Gameplay 事件触发哪些特效。
998
-
999
- ```json
1000
- {
1001
- "vfxEventBindings": [
1002
- {
1003
- "id": "vfx_binding_collect_wood",
1004
- "type": "eventBinding",
1005
- "package": "resource-collect-sparkles@1.0.3",
1006
- "trigger": {
1007
- "event": "resource.collected",
1008
- "filter": {
1009
- "resourceType": "wood"
1010
- }
1011
- },
1012
- "spawn": {
1013
- "source": "event.position"
1014
- },
1015
- "params": {
1016
- "scale": 0.9
1017
- }
1018
- }
1019
- ]
1020
- }
1021
- ```
1022
-
1023
- ---
1024
-
1025
- ## 17. Runtime 加载流程
1026
-
1027
- 推荐新增一个 `VfxPackageLoader`。
1028
-
1029
- 职责:
1030
-
1031
- ```ts
1032
- interface VfxPackageLoader {
1033
- install(packageRef: VfxPackageRef): Promise<VfxInstalledPackage>;
1034
- load(packageRef: VfxPackageRef): Promise<VfxEffectPackage>;
1035
- unload(packageId: string): void;
1036
- getLoaded(packageId: string): VfxEffectPackage | null;
1037
- }
1038
- ```
1039
-
1040
- 加载流程:
1041
-
1042
- ```text
1043
- 读取 project.vfxDependencies
1044
-
1045
- 读取 vfx-lock.json
1046
-
1047
- 下载或读取本地缓存
1048
-
1049
- 动态 import package entry
1050
-
1051
- 加载 package assets
1052
-
1053
- 构造 VfxEffectPackage
1054
-
1055
- EffectPackageService.register(package)
1056
- ```
1057
-
1058
- 播放流程:
1059
-
1060
- ```text
1061
- SceneVfxService.playEffectPackage(packageId, params, target)
1062
-
1063
- EffectPackageService 查找 package
1064
-
1065
- 合并参数
1066
-
1067
- 调用 package.create(...)
1068
-
1069
- 得到 handle
1070
-
1071
- 记录 handle
1072
-
1073
- 需要时 dispose
1074
- ```
1075
-
1076
- ---
1077
-
1078
- ## 18. 构建与发布
1079
-
1080
- 开发态可以动态加载特效。
1081
-
1082
- 但最终导出的 Playable 不应该依赖远程 registry。
1083
-
1084
- 构建时应该:
1085
-
1086
- ```text
1087
- 读取项目 vfxDependencies
1088
-
1089
- 读取 usage / eventBindings,确认实际使用的特效
1090
-
1091
- 收集对应 bundle 和 assets
1092
-
1093
- tree-shake 未使用特效
1094
-
1095
- 把必要资源打入最终 Playable 包
1096
-
1097
- 生成 runtime manifest
1098
- ```
1099
-
1100
- 构建目标:
1101
-
1102
- - 最终包里只包含当前项目实际用到的特效。
1103
- - 不把整个中央库打进去。
1104
- - 不在广告运行时请求远程特效资源。
1105
- - 构建结果可复现。
1106
- - lock 文件能保证同一个项目重复构建结果一致。
1107
-
1108
- ---
1109
-
1110
- ## 19. Agent 应该如何操作特效系统
1111
-
1112
- 新 Agent 进入项目后,应该按这个顺序理解特效系统:
1113
-
1114
- 1. 先读中央库 `registry.json`,知道有哪些特效。
1115
- 2. 再读每个特效的 `effect.json`,知道它的参数和能力。
1116
- 3. 再读当前 Playable 项目的 `vfxDependencies`,知道项目安装了哪些特效。
1117
- 4. 再读当前项目的 `vfxUsages` 和 `vfxEventBindings`,知道特效实际用在哪里。
1118
- 5. 如果要改视觉效果,优先改 usage override 或 project preset。
1119
- 6. 不要直接修改中央库默认参数,除非任务明确要求发布新的 library default。
1120
- 7. 如果新增特效,要补齐 manifest、preview、defaultParams、parameterSchema 和简单验证。
1121
- 8. 如果新增参数,要确保 Inspector 可以通过 schema 自动生成控件。
1122
- 9. 如果改 Runtime 接口,要尽量保持向后兼容。
1123
- 10. 修改完成后要能通过编辑器预览或自动截图验证。
1124
-
1125
- ---
1126
-
1127
- ## 20. MVP 建议
1128
-
1129
- 第一版只做最小闭环。
1130
-
1131
- ### 20.1 必做
1132
-
1133
- ```text
1134
- 中央静态 registry.json
1135
-
1136
- 编辑器显示特效卡片
1137
-
1138
- 支持隔离预览
1139
-
1140
- 添加到项目
1141
-
1142
- 写入 vfxDependencies
1143
-
1144
- 动态加载并注册
1145
-
1146
- 绑定到对象或放到世界坐标
1147
-
1148
- 自动打开 VFX Inspector
1149
-
1150
- 根据 parameterSchema 调参
1151
-
1152
- 保存为 usage override
1153
-
1154
- 构建时打包已安装特效
1155
- ```
1156
-
1157
- ---
1158
-
1159
- ### 20.2 第一版支持的特效类型
1160
-
1161
- 优先支持三类:
1162
-
1163
- ```text
1164
- 1. world
1165
- 放在世界坐标
1166
-
1167
- 2. attachment
1168
- 挂在场景对象上
1169
-
1170
- 3. eventBinding
1171
- 绑定 Gameplay 事件
1172
- ```
1173
-
1174
- ---
1175
-
1176
- ### 20.3 第一版暂不做
1177
-
1178
- ```text
1179
- 用户上传特效
1180
- 公开 marketplace
1181
- 自动版本升级
1182
- 复杂依赖解析
1183
- 多人协作
1184
- 公共 Variant 发布流
1185
- 可视化特效节点编辑器
1186
- 所有参数实时 updateParams
1187
- 线上热更新
1188
- ```
1189
-
1190
- ---
1191
-
1192
- ## 21. 关键 UI 流程
1193
-
1194
- ### 21.1 浏览并添加特效
1195
-
1196
- ```text
1197
- 打开资产面板
1198
-
1199
- 进入“特效”
1200
-
1201
- 浏览卡片
1202
-
1203
- 点击特效
1204
-
1205
- 查看预览和参数
1206
-
1207
- 点击“添加到项目”
1208
-
1209
- 项目安装依赖
1210
-
1211
- 右侧提示安装成功
1212
- ```
1213
-
1214
- ---
1215
-
1216
- ### 21.2 绑定到当前对象
1217
-
1218
- ```text
1219
- 选中 Truck
1220
-
1221
- 打开特效库
1222
-
1223
- 选择“车辆尾气”
1224
-
1225
- 点击“绑定到当前对象”
1226
-
1227
- 创建 VfxAttachment
1228
-
1229
- 自动选中该 VFX Usage
1230
-
1231
- 右侧打开 VFX Inspector
1232
-
1233
- 自动游戏内预览
1234
- ```
1235
-
1236
- ---
1237
-
1238
- ### 21.3 绑定到 Gameplay 事件
1239
-
1240
- ```text
1241
- 打开 Gameplay 面板
1242
-
1243
- 选择 resource.collected 事件
1244
-
1245
- 点击“添加特效”
1246
-
1247
- 选择 resource-collect-sparkles
1248
-
1249
- 创建 VfxEventBinding
1250
-
1251
- 打开 Inspector
1252
-
1253
- 点击“播放一次”验证
1254
-
1255
- 保存参数
1256
- ```
1257
-
1258
- ---
1259
-
1260
- ### 21.4 调参并保存
1261
-
1262
- ```text
1263
- 用户拖动参数滑杆
1264
-
1265
- Preview Session 更新
1266
-
1267
- 重建或更新当前预览
1268
-
1269
- 用户满意
1270
-
1271
- 点击“保存到当前实例”
1272
-
1273
- 写入 usage.params
1274
- ```
1275
-
1276
- ---
1277
-
1278
- ## 22. 常见设计陷阱
1279
-
1280
- ### 22.1 把中央库默认值和项目参数混在一起
1281
-
1282
- 错误:
1283
-
1284
- ```text
1285
- 用户在某个项目里调了车辆尾气
1286
-
1287
- 直接写回 vehicle-exhaust-smoke/effect.json
1288
- ```
1289
-
1290
- 这样会污染所有项目。
1291
-
1292
- 正确:
1293
-
1294
- ```text
1295
- 中央默认值只读
1296
- 项目调参写入 usage override 或 project preset
1297
- ```
1298
-
1299
- ---
1300
-
1301
- ### 22.2 用硬编码 UI 调每个特效
1302
-
1303
- 错误:
1304
-
1305
- ```text
1306
- VehicleExhaustPanel.tsx
1307
- CollectSparklesPanel.tsx
1308
- UpgradeBurstPanel.tsx
1309
- ```
1310
-
1311
- 正确:
1312
-
1313
- ```text
1314
- 统一 VFX Inspector
1315
-
1316
- 读取 parameterSchema
1317
-
1318
- 自动生成 UI
1319
- ```
1320
-
1321
- ---
1322
-
1323
- ### 22.3 添加后不自动选中
1324
-
1325
- 错误体验:
1326
-
1327
- ```text
1328
- 用户添加特效
1329
-
1330
- 系统说添加成功
1331
-
1332
- 用户不知道在哪里调
1333
- ```
1334
-
1335
- 正确体验:
1336
-
1337
- ```text
1338
- 用户添加特效
1339
-
1340
- 系统自动创建 usage
1341
-
1342
- 自动选中
1343
-
1344
- 自动打开 VFX Inspector
1345
- ```
1346
-
1347
- ---
1348
-
1349
- ### 22.4 把整个中央库打进最终 Playable
1350
-
1351
- 错误:
1352
-
1353
- ```text
1354
- 最终包包含所有特效
1355
- ```
1356
-
1357
- 正确:
1358
-
1359
- ```text
1360
- 最终包只包含当前项目使用的特效
1361
- ```
1362
-
1363
- ---
1364
-
1365
- ### 22.5 第一版把版本系统做得太复杂
1366
-
1367
- 第一版可以只支持:
1368
-
1369
- ```text
1370
- 固定版本安装
1371
- lock 文件锁定
1372
- 手动升级
1373
- ```
1374
-
1375
- 不要一开始做复杂 peer dependency、自动升级、兼容迁移。
1376
-
1377
- ---
1378
-
1379
- ## 23. 推荐开发顺序
1380
-
1381
- ### Phase 1:本地静态特效库
1382
-
1383
- 目标:
1384
-
1385
- ```text
1386
- 有一个 registry.json,编辑器能展示特效卡片。
1387
- ```
1388
-
1389
- 任务:
1390
-
1391
- - 定义 `effect.json` schema。
1392
- - 搭建 `vfx-library/effects/*` 目录。
1393
- - 写 2-3 个示例特效。
1394
- - 为每个特效补 thumbnail 和 defaultParams。
1395
- - 编辑器读取 registry 并显示卡片。
1396
-
1397
- ---
1398
-
1399
- ### Phase 2:安装到项目
1400
-
1401
- 目标:
1402
-
1403
- ```text
1404
- 点击“添加到项目”可以写入 project.vfxDependencies。
1405
- ```
1406
-
1407
- 任务:
1408
-
1409
- - 定义 project dependency schema。
1410
- - 定义 lock 文件。
1411
- - 实现 `VfxPackageInstaller`。
1412
- - 实现已安装状态展示。
1413
- - 避免重复安装。
1414
-
1415
- ---
1416
-
1417
- ### Phase 3:Runtime 动态加载和注册
1418
-
1419
- 目标:
1420
-
1421
- ```text
1422
- 项目安装的特效可以被 Runtime 加载并播放。
1423
- ```
1424
-
1425
- 任务:
1426
-
1427
- - 实现 `VfxPackageLoader`。
1428
- - 支持动态 import。
1429
- - 支持 assets resolve。
1430
- - 加载后注册到 `EffectPackageService`。
1431
- - 通过 `SceneVfxService` 播放。
1432
-
1433
- ---
1434
-
1435
- ### Phase 4:编辑器绑定和 Inspector
1436
-
1437
- 目标:
1438
-
1439
- ```text
1440
- 用户可以把特效绑定到对象,自动打开调试面板。
1441
- ```
1442
-
1443
- 任务:
1444
-
1445
- - 定义 `vfxUsages`。
1446
- - 支持 world usage。
1447
- - 支持 attachment usage。
1448
- - 接入 editor selection。
1449
- - 实现通用 VFX Inspector。
1450
- - 根据 parameterSchema 生成控件。
1451
- - 支持保存到 usage override。
1452
-
1453
- ---
1454
-
1455
- ### Phase 5:Gameplay Event Binding
1456
-
1457
- 目标:
1458
-
1459
- ```text
1460
- Gameplay 事件可以触发特效。
1461
- ```
1462
-
1463
- 任务:
1464
-
1465
- - 定义 `vfxEventBindings`。
1466
- - 支持常见事件:collect、unlock、upgrade、purchase、endcard。
1467
- - 支持 event.position / target.node 等 spawn source。
1468
- - Inspector 支持“播放一次”测试。
1469
- - Runtime 事件系统触发对应特效。
1470
-
1471
- ---
1472
-
1473
- ### Phase 6:构建打包
1474
-
1475
- 目标:
1476
-
1477
- ```text
1478
- 发布 Playable 时只打包当前项目使用的特效和资源。
1479
- ```
1480
-
1481
- 任务:
1482
-
1483
- - 构建阶段读取 dependencies 和 usages。
1484
- - 收集 bundle 和 assets。
1485
- - 生成 runtime manifest。
1486
- - 检查包体大小。
1487
- - 检查缺失资源。
1488
- - 保证离线可运行。
1489
-
1490
- ---
1491
-
1492
- ## 24. 判断一个特效功能是否“平台化”的检查项
1493
-
1494
- 一个特效真正平台化,需要满足:
1495
-
1496
- - [ ] 有唯一 ID。
1497
- - [ ] 有版本。
1498
- - [ ] 有 manifest。
1499
- - [ ] 有默认参数。
1500
- - [ ] 有参数 schema。
1501
- - [ ] 有预览图或预览视频。
1502
- - [ ] 能被 registry 发现。
1503
- - [ ] 能被安装到项目。
1504
- - [ ] 能被 Runtime 加载。
1505
- - [ ] 能通过统一服务播放。
1506
- - [ ] 能被挂到对象或事件。
1507
- - [ ] 能在 Inspector 中调参。
1508
- - [ ] 调参结果不会污染中央默认值。
1509
- - [ ] 构建时能被打包进最终 Playable。
1510
- - [ ] 未使用时不会进入最终包。
1511
- - [ ] Agent 能通过 schema 理解怎么使用它。
1512
-
1513
- ---
1514
-
1515
- ## 25. 名词表
1516
-
1517
- | 名词 | 含义 |
1518
- |---|---|
1519
- | VFX Package | 一个可复用特效包,包括代码、资源、参数 schema、默认值和预览信息 |
1520
- | VFX Registry | 特效目录,记录有哪些特效、版本、入口和预览信息 |
1521
- | VFX Dependency | 当前 Playable 项目安装的特效依赖 |
1522
- | VFX Lock | 锁定实际 bundle、资源和 hash 的文件 |
1523
- | VFX Usage | 当前项目中某个特效实例的使用记录 |
1524
- | VFX Event Binding | 某个 Gameplay 事件和特效之间的绑定 |
1525
- | VFX Preview Session | 当前编辑器里正在调试的临时状态 |
1526
- | Parameter Schema | 用于自动生成调参 UI 的参数定义 |
1527
- | Usage Override | 当前实例上的参数覆盖 |
1528
- | Project Preset | 当前项目级别的参数预设 |
1529
- | Library Default | 中央特效库提供的默认参数 |
1530
- | SceneVfxService | Runtime 中负责播放、追踪和销毁特效的服务 |
1531
- | EffectPackageService | Runtime 中负责注册和查询特效包的服务 |
1532
- | VfxPackageLoader | 负责加载、缓存和注册特效 package 的模块 |
1533
-
1534
- ---
1535
-
1536
- ## 26. 最终方向总结
1537
-
1538
- 特效库的核心不是“把特效代码放在哪个目录”,而是建立一套从中央库到项目使用的完整产品链路。
1539
-
1540
- 推荐方向:
1541
-
1542
- ```text
1543
- 中央 VFX Library
1544
- 负责生产和维护特效 package
1545
-
1546
- VFX Registry
1547
- 负责让编辑器发现特效
1548
-
1549
- Playable Project
1550
- 负责记录安装依赖和项目使用
1551
-
1552
- Runtime Loader
1553
- 负责加载和注册 package
1554
-
1555
- SceneVfxService
1556
- 负责播放和生命周期
1557
-
1558
- Editor VFX Inspector
1559
- 负责选择、预览、调参和保存
1560
- ```
1561
-
1562
- 第一版最重要的是跑通这个闭环:
1563
-
1564
- ```text
1565
- 选择特效
1566
-
1567
- 添加到项目
1568
-
1569
- 绑定到对象或事件
1570
-
1571
- 自动打开调试面板
1572
-
1573
- 调参
1574
-
1575
- 保存到当前实例
1576
-
1577
- 构建进最终 Playable
1578
- ```
1579
-
1580
- 只要这条链路稳定,后续再做 marketplace、用户上传、公共 variant、自动推荐、Agent 自动调参都会比较自然。