evomeme 0.1.9 → 0.1.10-beta.13

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 (477) hide show
  1. package/README.md +2 -0
  2. package/dist/canvas-public/app.js +509 -5999
  3. package/dist/canvas-public/assets/presets/catalog.json +47 -0
  4. package/dist/canvas-public/assets/presets/tiles/A_01_CaoDi.png +0 -0
  5. package/dist/canvas-public/assets/presets/tiles/A_02_ShaMo.png +0 -0
  6. package/dist/canvas-public/assets/presets/tiles/A_03_TianKong.png +0 -0
  7. package/dist/canvas-public/assets/presets/tiles/A_04_ShuiBo.png +0 -0
  8. package/dist/canvas-public/assets/presets/tiles/A_05_HaiMian.png +0 -0
  9. package/dist/canvas-public/assets/presets/tiles/A_06_MuDiBan.png +0 -0
  10. package/dist/canvas-public/assets/presets/tiles/A_07_ShiZhuan.png +0 -0
  11. package/dist/canvas-public/assets/presets/tiles/A_08_AnRongYan.png +0 -0
  12. package/dist/canvas-public/assets/presets/tiles/A_09_QingTaiShi.png +0 -0
  13. package/dist/canvas-public/assets/presets/tiles/A_10_ShenHai.png +0 -0
  14. package/dist/canvas-public/assets/presets/tiles/A_11_HuiYanShi.png +0 -0
  15. package/dist/canvas-public/assets/presets/tiles/A_12_HongTu.png +0 -0
  16. package/dist/canvas-public/assets/presets/tiles/A_13_GengDi.png +0 -0
  17. package/dist/canvas-public/assets/presets/tiles/A_14_HuoShanYan.png +0 -0
  18. package/dist/canvas-public/assets/presets/tiles/A_15_NiTu.png +0 -0
  19. package/dist/canvas-public/assets/presets/tiles/A_16_HuangSha.png +0 -0
  20. package/dist/canvas-public/assets/presets/tiles/A_17_CongLin.png +0 -0
  21. package/dist/canvas-public/assets/presets/tiles/A_18_ZiYanShi.png +0 -0
  22. package/dist/canvas-public/assets/presets/tiles/A_19_MoGuTu.png +0 -0
  23. package/dist/canvas-public/assets/presets/tiles/A_20_HuaDian.png +0 -0
  24. package/dist/canvas-public/assets/presets/tiles/A_21_HaiLang.png +0 -0
  25. package/dist/canvas-public/assets/presets/tiles/A_22_GanTu.png +0 -0
  26. package/dist/canvas-public/assets/presets/tiles/A_23_QingTaiShiBan.png +0 -0
  27. package/dist/canvas-public/assets/presets/tiles/A_24_XingKong.png +0 -0
  28. package/dist/canvas-public/assets/presets/tiles/A_25_MoFaFuWen.png +0 -0
  29. package/dist/canvas-public/assets/presets/tiles/A_26_ShiTuYeDi.png +0 -0
  30. package/dist/canvas-public/assets/presets/tiles/A_27_LanZhuan.png +0 -0
  31. package/dist/canvas-public/assets/presets/tiles/A_28_HongZhuan.png +0 -0
  32. package/dist/canvas-public/assets/presets/tiles/A_29_YueQiu.png +0 -0
  33. package/dist/canvas-public/assets/presets/tiles/A_30_JinShuGe.png +0 -0
  34. package/dist/canvas-public/assets/presets/tiles/A_31_JinShuJingGai.png +0 -0
  35. package/dist/canvas-public/assets/presets/tiles/A_32_ShuZiChuang.png +0 -0
  36. package/dist/canvas-public/canvas/actions.js +144 -0
  37. package/dist/canvas-public/canvas/camera.js +28 -0
  38. package/dist/canvas-public/canvas/chrome.js +14 -0
  39. package/dist/canvas-public/canvas/data.js +123 -0
  40. package/dist/canvas-public/canvas/dependencies.js +19 -0
  41. package/dist/canvas-public/canvas/interactions.js +544 -0
  42. package/dist/canvas-public/canvas/panel-resize.js +5 -0
  43. package/dist/canvas-public/canvas/renderer.js +297 -0
  44. package/dist/canvas-public/canvas/selection.js +62 -0
  45. package/dist/canvas-public/canvas/serialization.js +118 -0
  46. package/dist/canvas-public/canvas/sync.js +202 -0
  47. package/dist/canvas-public/core/api.js +32 -0
  48. package/dist/canvas-public/core/feature-registry.js +29 -0
  49. package/dist/canvas-public/core/feature-state.js +228 -0
  50. package/dist/canvas-public/core/layout.js +133 -0
  51. package/dist/canvas-public/core/operations.js +38 -0
  52. package/dist/canvas-public/core/project.js +203 -0
  53. package/dist/canvas-public/core/state.js +27 -0
  54. package/dist/canvas-public/dialogs/context-menu.js +118 -0
  55. package/dist/canvas-public/elements/base.js +100 -0
  56. package/dist/canvas-public/elements/connections.js +105 -0
  57. package/dist/canvas-public/elements/drag.js +53 -0
  58. package/dist/canvas-public/elements/image.js +259 -0
  59. package/dist/canvas-public/elements/loading-recovery.js +5 -0
  60. package/dist/canvas-public/elements/loading.js +21 -0
  61. package/dist/canvas-public/elements/map.js +64 -0
  62. package/dist/canvas-public/elements/registry.js +58 -0
  63. package/dist/canvas-public/elements/replacement.js +78 -0
  64. package/dist/canvas-public/elements/resize.js +210 -0
  65. package/dist/canvas-public/elements/task-pipeline.js +235 -0
  66. package/dist/canvas-public/elements/types.js +21 -0
  67. package/dist/canvas-public/elements/ui.js +14 -0
  68. package/dist/canvas-public/elements/video.js +64 -0
  69. package/dist/canvas-public/features/assets/local-assets.js +72 -0
  70. package/dist/canvas-public/features/assets/official-assets.js +539 -0
  71. package/dist/canvas-public/features/editing/canvas-size.js +532 -0
  72. package/dist/canvas-public/features/editing/color-key.js +471 -0
  73. package/dist/canvas-public/features/editing/cutout.js +20 -0
  74. package/dist/canvas-public/features/editing/interactive-image-editing.js +982 -0
  75. package/dist/canvas-public/features/editing/layer-decomposition.js +45 -0
  76. package/dist/canvas-public/features/editing/manual-split.js +115 -0
  77. package/dist/canvas-public/features/editing/perfect-pixel.js +299 -0
  78. package/dist/canvas-public/features/editing/scroll-preview.js +130 -0
  79. package/dist/canvas-public/features/editing/scroll-seam-elimination.js +71 -0
  80. package/dist/canvas-public/features/editing/seam-elimination.js +46 -0
  81. package/dist/canvas-public/features/editing/smart-split.js +49 -0
  82. package/dist/canvas-public/features/editing/source-preview.js +43 -0
  83. package/dist/canvas-public/features/editing/video-cycle.js +49 -0
  84. package/dist/canvas-public/features/editing/video-frames.js +35 -0
  85. package/dist/canvas-public/features/frame-editor/frame-editing.js +755 -0
  86. package/dist/canvas-public/features/frame-editor/frame-model.js +63 -0
  87. package/dist/canvas-public/features/frame-editor/playback.js +83 -0
  88. package/dist/canvas-public/features/frame-editor/preview.js +151 -0
  89. package/dist/canvas-public/features/generation/animation.js +272 -0
  90. package/dist/canvas-public/features/generation/asset-batch.js +102 -0
  91. package/dist/canvas-public/features/generation/direction.js +163 -0
  92. package/dist/canvas-public/features/generation/fields.js +73 -0
  93. package/dist/canvas-public/features/generation/game-ui.js +64 -0
  94. package/dist/canvas-public/features/generation/image.js +96 -0
  95. package/dist/canvas-public/features/generation/scroll-image.js +157 -0
  96. package/dist/canvas-public/features/generation/seamless-tile.js +52 -0
  97. package/dist/canvas-public/features/generation/tile-transition-atlas.js +79 -0
  98. package/dist/canvas-public/features/generation/video.js +105 -0
  99. package/dist/canvas-public/features/map/creation.js +73 -0
  100. package/dist/canvas-public/features/map/tile-map-editor.js +2520 -0
  101. package/dist/canvas-public/features/registry.js +59 -0
  102. package/dist/canvas-public/index.html +84 -259
  103. package/dist/canvas-public/inspector/controls.js +49 -0
  104. package/dist/canvas-public/inspector/frame-preview.js +11 -0
  105. package/dist/canvas-public/inspector/inspector.js +190 -0
  106. package/dist/canvas-public/inspector/media-inspector.js +517 -0
  107. package/dist/canvas-public/inspector/media-preview.js +56 -0
  108. package/dist/canvas-public/inspector/number-stepper.js +96 -0
  109. package/dist/canvas-public/inspector/resize.js +88 -0
  110. package/dist/canvas-public/inspector/scroll-preview.js +11 -0
  111. package/dist/canvas-public/inspector/ui-inspector.js +14 -0
  112. package/dist/canvas-public/language/en-US.js +1059 -0
  113. package/dist/canvas-public/language/index.js +91 -0
  114. package/dist/canvas-public/language/zh-CN.js +1059 -0
  115. package/dist/canvas-public/map/export.js +10 -0
  116. package/dist/canvas-public/map/inspector.js +8 -0
  117. package/dist/canvas-public/map/model.js +409 -0
  118. package/dist/canvas-public/map/tile-map-editor.js +2 -0
  119. package/dist/canvas-public/media/metadata.js +183 -0
  120. package/dist/canvas-public/media/support.js +183 -0
  121. package/dist/canvas-public/styles/base.css +49 -0
  122. package/dist/canvas-public/styles/canvas.css +127 -0
  123. package/dist/canvas-public/styles/controls.css +203 -0
  124. package/dist/canvas-public/styles/dialogs.css +521 -0
  125. package/dist/canvas-public/styles/feature-form.css +409 -0
  126. package/dist/canvas-public/styles/inspector.css +441 -0
  127. package/dist/canvas-public/styles/layout.css +344 -0
  128. package/dist/canvas-public/styles/map.css +11 -0
  129. package/dist/canvas-public/styles/nodes.css +636 -0
  130. package/dist/canvas-public/styles.css +9 -2247
  131. package/dist/canvas-public/ui/controls.js +222 -0
  132. package/dist/canvas-public/ui/elements.js +9 -0
  133. package/dist/canvas-public/ui/feature-controller.js +296 -0
  134. package/dist/canvas-public/ui/feature-form.js +402 -0
  135. package/dist/canvas-public/ui/settings.js +84 -0
  136. package/dist/canvas-public/ui/toolbar.js +55 -0
  137. package/dist/canvas-public/vendor/pixi-tilemap.js +126 -0
  138. package/dist/canvas-public/vendor/pixi.min.js +2340 -0
  139. package/dist/canvas-public/workers/color-key-worker.js +289 -0
  140. package/dist/image-workers/perfect-pixel/perfect-pixel-core.js +441 -0
  141. package/dist/image-workers/perfect-pixel/perfect-pixel-worker.cjs +10 -0
  142. package/dist/index.js +46710 -12400
  143. package/dist/skills/en-US/evomeme-canvas/SKILL.md +52 -0
  144. package/dist/skills/en-US/evomeme-canvas/agents/openai.yaml +7 -0
  145. package/dist/skills/en-US/evomeme-cloud-fs/SKILL.md +203 -0
  146. package/dist/skills/en-US/evomeme-cloud-fs/agents/openai.yaml +7 -0
  147. package/dist/skills/en-US/evomeme-cover/SKILL.md +131 -0
  148. package/dist/skills/en-US/evomeme-cover/agents/openai.yaml +7 -0
  149. package/dist/skills/en-US/evomeme-game-maker/SKILL.md +288 -0
  150. package/dist/skills/en-US/evomeme-game-maker/agents/openai.yaml +4 -0
  151. package/dist/skills/en-US/evomeme-login/SKILL.md +97 -0
  152. package/dist/skills/en-US/evomeme-login/agents/openai.yaml +7 -0
  153. package/dist/skills/en-US/evomeme-mcp/SKILL.md +71 -0
  154. package/dist/skills/en-US/evomeme-mcp/agents/openai.yaml +7 -0
  155. package/dist/skills/en-US/evomeme-mcp/references/troubleshooting.md +55 -0
  156. package/dist/skills/en-US/evomeme-native-bridge-sdk/SKILL.md +286 -0
  157. package/dist/skills/en-US/evomeme-native-bridge-sdk/agents/openai.yaml +8 -0
  158. package/dist/skills/en-US/evomeme-tos-upload/SKILL.md +47 -0
  159. package/dist/skills/en-US/evomeme-tos-upload/agents/openai.yaml +5 -0
  160. package/dist/skills/en-US/evomeme-ui/SKILL.md +123 -0
  161. package/dist/skills/en-US/evomeme-ui/agents/openai.yaml +4 -0
  162. package/dist/skills/en-US/evomeme-ui/references/host-layout.md +69 -0
  163. package/dist/skills/en-US/game-art/SKILL.md +121 -0
  164. package/dist/skills/en-US/game-art/agents/openai.yaml +8 -0
  165. package/dist/skills/en-US/game-asset-align/SKILL.md +47 -0
  166. package/dist/skills/en-US/game-asset-align/agents/openai.yaml +8 -0
  167. package/dist/skills/en-US/game-asset-align/references/alignment-contract.md +61 -0
  168. package/dist/skills/en-US/game-asset-align/references/blender-scene-pipeline.md +35 -0
  169. package/dist/skills/en-US/game-asset-align/references/canonical-package.md +26 -0
  170. package/dist/skills/en-US/game-asset-align/references/engine-capabilities.md +14 -0
  171. package/dist/skills/en-US/game-asset-align/references/lightweight-review.md +34 -0
  172. package/dist/skills/en-US/game-asset-align/references/repair-policy.md +30 -0
  173. package/dist/skills/en-US/game-asset-align/references/tool-contract.md +69 -0
  174. package/dist/skills/en-US/game-asset-align/references/visual-review.md +26 -0
  175. package/dist/skills/en-US/game-asset-batch-generator/SKILL.md +117 -0
  176. package/dist/skills/en-US/game-asset-batch-generator/agents/openai.yaml +7 -0
  177. package/dist/skills/en-US/game-asset-image-generator/SKILL.md +86 -0
  178. package/dist/skills/en-US/game-asset-image-generator/agents/openai.yaml +7 -0
  179. package/dist/skills/en-US/game-asset-image-generator/references/background.md +34 -0
  180. package/dist/skills/en-US/game-asset-image-generator/references/static-game-assets.md +38 -0
  181. package/dist/skills/en-US/game-asset-mesh-generator/SKILL.md +35 -0
  182. package/dist/skills/en-US/game-asset-mesh-generator/agents/openai.yaml +7 -0
  183. package/dist/skills/en-US/game-asset-mesh-generator/references/animation-presets.md +313 -0
  184. package/dist/skills/en-US/game-asset-mesh-generator/references/generation-contracts.md +131 -0
  185. package/dist/skills/en-US/game-asset-mesh-generator/references/image-generator-workflows.md +65 -0
  186. package/dist/skills/en-US/game-asset-mesh-generator/references/postprocess-contracts.md +187 -0
  187. package/dist/skills/en-US/game-asset-mesh-generator/references/threejs-integration.md +113 -0
  188. package/dist/skills/en-US/game-asset-mesh-generator/references/tool-reference.md +67 -0
  189. package/dist/skills/en-US/game-audio/SKILL.md +121 -0
  190. package/dist/skills/en-US/game-audio/agents/openai.yaml +4 -0
  191. package/{skills → dist/skills/en-US}/game-audio/references/bgm-cdn.md +7 -11
  192. package/{skills → dist/skills/en-US}/game-audio/references/sfx-cdn.md +6 -4
  193. package/dist/skills/en-US/game-character-view-generator/SKILL.md +110 -0
  194. package/dist/skills/en-US/game-character-view-generator/agents/openai.yaml +7 -0
  195. package/dist/skills/en-US/game-demo/SKILL.md +103 -0
  196. package/dist/skills/en-US/game-demo/agents/openai.yaml +7 -0
  197. package/dist/skills/en-US/game-image-layer-decomposer/SKILL.md +99 -0
  198. package/dist/skills/en-US/game-image-layer-decomposer/agents/openai.yaml +7 -0
  199. package/dist/skills/en-US/game-image-splitter/SKILL.md +114 -0
  200. package/dist/skills/en-US/game-image-splitter/agents/openai.yaml +7 -0
  201. package/dist/skills/en-US/game-maker/SKILL.md +111 -0
  202. package/dist/skills/en-US/game-maker/agents/openai.yaml +4 -0
  203. package/dist/skills/en-US/game-perfect-pixel/SKILL.md +123 -0
  204. package/dist/skills/en-US/game-perfect-pixel/agents/openai.yaml +7 -0
  205. package/dist/skills/en-US/game-scroll-generator/SKILL.md +110 -0
  206. package/dist/skills/en-US/game-scroll-generator/agents/openai.yaml +7 -0
  207. package/dist/skills/en-US/game-test/SKILL.md +58 -0
  208. package/dist/skills/en-US/game-test/agents/openai.yaml +7 -0
  209. package/dist/skills/en-US/game-tile-generator/SKILL.md +152 -0
  210. package/dist/skills/en-US/game-tile-generator/agents/openai.yaml +7 -0
  211. package/dist/skills/en-US/game-ui/SKILL.md +177 -0
  212. package/dist/skills/en-US/game-ui/agents/openai.yaml +4 -0
  213. package/dist/skills/en-US/game-ui-generator/SKILL.md +82 -0
  214. package/dist/skills/en-US/game-ui-generator/agents/openai.yaml +7 -0
  215. package/dist/skills/en-US/game-ui-generator/references/component-patterns.md +65 -0
  216. package/dist/skills/en-US/game-ui-generator/references/runtime-integration.md +45 -0
  217. package/dist/skills/en-US/game-video-cycle/SKILL.md +98 -0
  218. package/dist/skills/en-US/game-video-cycle/agents/openai.yaml +7 -0
  219. package/dist/skills/en-US/game-video-generator/SKILL.md +78 -0
  220. package/dist/skills/en-US/game-video-generator/agents/openai.yaml +7 -0
  221. package/dist/skills/en-US/godot-3d-game/SKILL.md +41 -0
  222. package/dist/skills/en-US/godot-3d-game/agents/openai.yaml +8 -0
  223. package/dist/skills/en-US/godot-3d-game/references/alignment-gates.md +26 -0
  224. package/dist/skills/en-US/godot-3d-game/references/appearance-alignment.md +54 -0
  225. package/dist/skills/en-US/godot-3d-game/references/build-and-qa.md +22 -0
  226. package/dist/skills/en-US/godot-3d-game/references/canonical-asset-runtime.md +27 -0
  227. package/dist/skills/en-US/godot-3d-game/references/import-and-wrapper-scenes.md +20 -0
  228. package/dist/skills/en-US/godot-3d-game/references/physics-colliders.md +13 -0
  229. package/dist/skills/en-US/godot-3d-game/references/project-structure.md +22 -0
  230. package/dist/skills/en-US/godot-3d-game/references/skeleton-animation.md +16 -0
  231. package/dist/skills/en-US/phaser-2d-game/SKILL.md +127 -0
  232. package/dist/skills/en-US/phaser-2d-game/agents/openai.yaml +8 -0
  233. package/dist/skills/en-US/phaser-2d-game/references/engine-performance.md +64 -0
  234. package/dist/skills/en-US/phaser-2d-game/references/engine-physics.md +139 -0
  235. package/dist/skills/en-US/phaser-2d-game/references/engine-runtime.md +129 -0
  236. package/dist/skills/en-US/phaser-2d-game/references/engine-spritesheets.md +99 -0
  237. package/dist/skills/en-US/phaser-2d-game/references/engine-tilemaps.md +80 -0
  238. package/dist/skills/en-US/phaser-2d-game/references/file-structure.md +94 -0
  239. package/dist/skills/en-US/phaser-2d-graphics-builder/SKILL.md +68 -0
  240. package/dist/skills/en-US/phaser-2d-graphics-builder/agents/openai.yaml +7 -0
  241. package/dist/skills/en-US/threejs-3d-game/SKILL.md +117 -0
  242. package/dist/skills/en-US/threejs-3d-game/agents/openai.yaml +7 -0
  243. package/dist/skills/en-US/threejs-3d-game/references/engine-asset-pipeline.md +155 -0
  244. package/dist/skills/en-US/threejs-3d-game/references/engine-audio.md +70 -0
  245. package/dist/skills/en-US/threejs-3d-game/references/engine-input-camera.md +84 -0
  246. package/dist/skills/en-US/threejs-3d-game/references/engine-performance.md +96 -0
  247. package/dist/skills/en-US/threejs-3d-game/references/engine-physics.md +142 -0
  248. package/dist/skills/en-US/threejs-3d-game/references/engine-runtime.md +199 -0
  249. package/dist/skills/en-US/threejs-3d-game/references/file-structure.md +353 -0
  250. package/dist/skills/en-US/threejs-aaa-graphics-builder/SKILL.md +62 -0
  251. package/dist/skills/en-US/threejs-aaa-graphics-builder/agents/openai.yaml +7 -0
  252. package/{skills → dist/skills/zh-CN}/evomeme-cloud-fs/SKILL.md +33 -6
  253. package/{skills → dist/skills/zh-CN}/evomeme-cover/SKILL.md +7 -8
  254. package/{skills → dist/skills/zh-CN}/evomeme-game-maker/SKILL.md +91 -88
  255. package/{skills → dist/skills/zh-CN}/evomeme-login/SKILL.md +5 -0
  256. package/dist/skills/zh-CN/evomeme-mcp/SKILL.md +71 -0
  257. package/dist/skills/zh-CN/evomeme-mcp/agents/openai.yaml +7 -0
  258. package/dist/skills/zh-CN/evomeme-mcp/references/troubleshooting.md +55 -0
  259. package/{skills → dist/skills/zh-CN}/evomeme-tos-upload/SKILL.md +6 -5
  260. package/dist/skills/zh-CN/evomeme-ui/SKILL.md +123 -0
  261. package/dist/skills/zh-CN/evomeme-ui/agents/openai.yaml +4 -0
  262. package/dist/skills/zh-CN/evomeme-ui/references/host-layout.md +69 -0
  263. package/dist/skills/zh-CN/game-asset-align/SKILL.md +47 -0
  264. package/dist/skills/zh-CN/game-asset-align/agents/openai.yaml +8 -0
  265. package/dist/skills/zh-CN/game-asset-align/references/alignment-contract.md +61 -0
  266. package/dist/skills/zh-CN/game-asset-align/references/blender-scene-pipeline.md +35 -0
  267. package/dist/skills/zh-CN/game-asset-align/references/canonical-package.md +26 -0
  268. package/dist/skills/zh-CN/game-asset-align/references/engine-capabilities.md +14 -0
  269. package/dist/skills/zh-CN/game-asset-align/references/lightweight-review.md +34 -0
  270. package/dist/skills/zh-CN/game-asset-align/references/repair-policy.md +30 -0
  271. package/dist/skills/zh-CN/game-asset-align/references/tool-contract.md +69 -0
  272. package/dist/skills/zh-CN/game-asset-align/references/visual-review.md +26 -0
  273. package/dist/skills/zh-CN/game-asset-batch-generator/SKILL.md +117 -0
  274. package/dist/skills/zh-CN/game-asset-batch-generator/agents/openai.yaml +7 -0
  275. package/dist/skills/zh-CN/game-asset-image-generator/SKILL.md +86 -0
  276. package/{skills → dist/skills/zh-CN}/game-asset-image-generator/references/background.md +3 -1
  277. package/{skills → dist/skills/zh-CN}/game-asset-image-generator/references/static-game-assets.md +2 -2
  278. package/dist/skills/zh-CN/game-asset-mesh-generator/SKILL.md +35 -0
  279. package/dist/skills/zh-CN/game-asset-mesh-generator/agents/openai.yaml +7 -0
  280. package/dist/skills/zh-CN/game-asset-mesh-generator/references/animation-presets.md +313 -0
  281. package/dist/skills/zh-CN/game-asset-mesh-generator/references/generation-contracts.md +131 -0
  282. package/dist/skills/zh-CN/game-asset-mesh-generator/references/image-generator-workflows.md +65 -0
  283. package/dist/skills/zh-CN/game-asset-mesh-generator/references/postprocess-contracts.md +187 -0
  284. package/dist/skills/zh-CN/game-asset-mesh-generator/references/threejs-integration.md +113 -0
  285. package/dist/skills/zh-CN/game-asset-mesh-generator/references/tool-reference.md +67 -0
  286. package/dist/skills/zh-CN/game-audio/SKILL.md +121 -0
  287. package/dist/skills/zh-CN/game-audio/agents/openai.yaml +4 -0
  288. package/dist/skills/zh-CN/game-audio/references/bgm-cdn.md +123 -0
  289. package/dist/skills/zh-CN/game-audio/references/sfx-cdn.md +79 -0
  290. package/dist/skills/zh-CN/game-character-view-generator/SKILL.md +110 -0
  291. package/dist/skills/zh-CN/game-character-view-generator/agents/openai.yaml +7 -0
  292. package/dist/skills/zh-CN/game-image-layer-decomposer/SKILL.md +99 -0
  293. package/dist/skills/zh-CN/game-image-layer-decomposer/agents/openai.yaml +7 -0
  294. package/dist/skills/zh-CN/game-image-splitter/SKILL.md +114 -0
  295. package/dist/skills/zh-CN/game-image-splitter/agents/openai.yaml +7 -0
  296. package/dist/skills/zh-CN/game-perfect-pixel/SKILL.md +123 -0
  297. package/dist/skills/zh-CN/game-perfect-pixel/agents/openai.yaml +7 -0
  298. package/dist/skills/zh-CN/game-scroll-generator/SKILL.md +110 -0
  299. package/dist/skills/zh-CN/game-scroll-generator/agents/openai.yaml +7 -0
  300. package/dist/skills/zh-CN/game-test/references/checklists/playtest-qa.md +12 -0
  301. package/dist/skills/zh-CN/game-tile-generator/SKILL.md +151 -0
  302. package/dist/skills/zh-CN/game-tile-generator/agents/openai.yaml +7 -0
  303. package/{skills → dist/skills/zh-CN}/game-ui/SKILL.md +9 -1
  304. package/dist/skills/zh-CN/game-ui/references/checklists/game-ui-quality.md +14 -0
  305. package/dist/skills/zh-CN/game-ui/references/checklists/hud-readability.md +12 -0
  306. package/dist/skills/zh-CN/game-ui/references/checklists/mobile-input.md +12 -0
  307. package/dist/skills/zh-CN/game-ui/references/checklists/responsive-ui-fit.md +12 -0
  308. package/dist/skills/zh-CN/game-ui/references/ui-patterns.md +140 -0
  309. package/dist/skills/zh-CN/game-ui/references/ui-prompt-templates.md +63 -0
  310. package/dist/skills/zh-CN/game-ui-generator/SKILL.md +82 -0
  311. package/dist/skills/zh-CN/game-ui-generator/agents/openai.yaml +7 -0
  312. package/dist/skills/zh-CN/game-ui-generator/references/component-patterns.md +65 -0
  313. package/dist/skills/zh-CN/game-ui-generator/references/runtime-integration.md +45 -0
  314. package/dist/skills/zh-CN/game-video-cycle/SKILL.md +98 -0
  315. package/dist/skills/zh-CN/game-video-cycle/agents/openai.yaml +7 -0
  316. package/dist/skills/zh-CN/game-video-generator/SKILL.md +78 -0
  317. package/dist/skills/zh-CN/game-video-generator/agents/openai.yaml +7 -0
  318. package/dist/skills/zh-CN/godot-3d-game/SKILL.md +41 -0
  319. package/dist/skills/zh-CN/godot-3d-game/agents/openai.yaml +8 -0
  320. package/dist/skills/zh-CN/godot-3d-game/references/alignment-gates.md +26 -0
  321. package/dist/skills/zh-CN/godot-3d-game/references/appearance-alignment.md +54 -0
  322. package/dist/skills/zh-CN/godot-3d-game/references/build-and-qa.md +22 -0
  323. package/dist/skills/zh-CN/godot-3d-game/references/canonical-asset-runtime.md +27 -0
  324. package/dist/skills/zh-CN/godot-3d-game/references/import-and-wrapper-scenes.md +20 -0
  325. package/dist/skills/zh-CN/godot-3d-game/references/physics-colliders.md +13 -0
  326. package/dist/skills/zh-CN/godot-3d-game/references/project-structure.md +22 -0
  327. package/dist/skills/zh-CN/godot-3d-game/references/skeleton-animation.md +16 -0
  328. package/dist/skills/zh-CN/phaser-2d-graphics-builder/assets/scorecard-anchors/scene-1.jpeg +0 -0
  329. package/dist/skills/zh-CN/phaser-2d-graphics-builder/assets/scorecard-anchors/scene-2.jpeg +0 -0
  330. package/dist/skills/zh-CN/phaser-2d-graphics-builder/assets/scorecard-anchors/scene-3.jpg +0 -0
  331. package/dist/skills/zh-CN/phaser-2d-graphics-builder/references/checklists/compose-quality.md +10 -0
  332. package/dist/skills/zh-CN/phaser-2d-graphics-builder/references/checklists/performance-safe-visual-detail.md +9 -0
  333. package/dist/skills/zh-CN/phaser-2d-graphics-builder/references/checklists/premium-game-quality-gate.md +15 -0
  334. package/dist/skills/zh-CN/phaser-2d-graphics-builder/references/checklists/sprite-quality.md +10 -0
  335. package/dist/skills/zh-CN/phaser-2d-graphics-builder/references/checklists/technical-art-quality.md +9 -0
  336. package/dist/skills/zh-CN/phaser-2d-graphics-builder/references/checklists/visual-scorecard.md +9 -0
  337. package/dist/skills/zh-CN/phaser-2d-graphics-builder/references/compose-recipes.md +71 -0
  338. package/dist/skills/zh-CN/phaser-2d-graphics-builder/references/graphics-prompt-templates.md +33 -0
  339. package/dist/skills/zh-CN/phaser-2d-graphics-builder/references/implementation-blueprint.md +82 -0
  340. package/dist/skills/zh-CN/phaser-2d-graphics-builder/references/sprite-recipes.md +90 -0
  341. package/dist/skills/zh-CN/phaser-2d-graphics-builder/references/technical-art.md +67 -0
  342. package/dist/skills/zh-CN/phaser-2d-graphics-builder/references/vfx-recipes.md +67 -0
  343. package/dist/skills/zh-CN/phaser-2d-graphics-builder/references/visual-scorecard.md +129 -0
  344. package/{skills → dist/skills/zh-CN}/threejs-3d-game/SKILL.md +6 -2
  345. package/dist/skills/zh-CN/threejs-3d-game/references/engine-asset-pipeline.md +155 -0
  346. package/{skills → dist/skills/zh-CN}/threejs-aaa-graphics-builder/SKILL.md +6 -6
  347. package/dist/skills/zh-CN/threejs-aaa-graphics-builder/assets/scorecard-anchors/scene-1.jpg +0 -0
  348. package/dist/skills/zh-CN/threejs-aaa-graphics-builder/assets/scorecard-anchors/scene-2.jpg +0 -0
  349. package/dist/skills/zh-CN/threejs-aaa-graphics-builder/assets/scorecard-anchors/scene-3.jpg +0 -0
  350. package/dist/skills/zh-CN/threejs-aaa-graphics-builder/references/checklists/aaa-game-quality-gate.md +23 -0
  351. package/dist/skills/zh-CN/threejs-aaa-graphics-builder/references/checklists/aaa-visual-scorecard.md +19 -0
  352. package/dist/skills/zh-CN/threejs-aaa-graphics-builder/references/checklists/material-lighting-quality.md +14 -0
  353. package/dist/skills/zh-CN/threejs-aaa-graphics-builder/references/checklists/performance-safe-visual-detail.md +14 -0
  354. package/dist/skills/zh-CN/threejs-aaa-graphics-builder/references/checklists/procedural-model-quality.md +15 -0
  355. package/dist/skills/zh-CN/threejs-aaa-graphics-builder/references/checklists/technical-art-quality.md +17 -0
  356. package/dist/skills/zh-CN/threejs-aaa-graphics-builder/references/graphics-prompt-templates.md +236 -0
  357. package/dist/skills/zh-CN/threejs-aaa-graphics-builder/references/implementation-blueprint.md +161 -0
  358. package/dist/skills/zh-CN/threejs-aaa-graphics-builder/references/model-recipes.md +146 -0
  359. package/dist/skills/zh-CN/threejs-aaa-graphics-builder/references/render-recipes.md +90 -0
  360. package/dist/skills/zh-CN/threejs-aaa-graphics-builder/references/shader-cookbook.md +292 -0
  361. package/dist/skills/zh-CN/threejs-aaa-graphics-builder/references/technical-art.md +167 -0
  362. package/dist/skills/zh-CN/threejs-aaa-graphics-builder/references/visual-scorecard.md +147 -0
  363. package/dist/stage-blender/bake_materials.py +102 -0
  364. package/dist/stage-blender/export_scene.py +275 -0
  365. package/dist/stage-blender/preview_camera.py +90 -0
  366. package/dist/stage-blender/repair_mesh.py +112 -0
  367. package/dist/stage-public/app.js +759 -0
  368. package/dist/stage-public/baked/bakePilot.js +44 -0
  369. package/dist/stage-public/baked/bakedScene.js +129 -0
  370. package/dist/stage-public/baked/sceneAppearance.js +225 -0
  371. package/dist/stage-public/baked/sceneCamera.js +45 -0
  372. package/dist/stage-public/comparison-contract.js +28 -0
  373. package/dist/stage-public/delivery.html +4 -0
  374. package/dist/stage-public/delivery.js +17 -0
  375. package/dist/stage-public/godot/appearance.gd +170 -0
  376. package/dist/stage-public/godot/preview.gd +79 -0
  377. package/dist/stage-public/index.html +141 -0
  378. package/dist/stage-public/review-app.js +289 -0
  379. package/dist/stage-public/review-runtime.js +63 -0
  380. package/dist/stage-public/review.css +24 -0
  381. package/dist/stage-public/review.html +47 -0
  382. package/dist/stage-public/scene-runtime.js +212 -0
  383. package/dist/stage-public/sceneContractRuntime.js +235 -0
  384. package/dist/stage-public/styles.css +328 -0
  385. package/dist/stage-public/three-appearance.js +104 -0
  386. package/dist/stage-public/vendor/three170/LICENSE +21 -0
  387. package/dist/stage-public/vendor/three170/build/three.module.js +54571 -0
  388. package/dist/stage-public/vendor/three170/examples/jsm/controls/OrbitControls.js +1523 -0
  389. package/dist/stage-public/vendor/three170/examples/jsm/environments/RoomEnvironment.js +144 -0
  390. package/dist/stage-public/vendor/three170/examples/jsm/libs/fflate.module.js +2672 -0
  391. package/dist/stage-public/vendor/three170/examples/jsm/loaders/EXRLoader.js +2563 -0
  392. package/dist/stage-public/vendor/three170/examples/jsm/loaders/GLTFLoader.js +4727 -0
  393. package/dist/stage-public/vendor/three170/examples/jsm/utils/BufferGeometryUtils.js +1373 -0
  394. package/dist/tile-transition-mask.svg +40 -0
  395. package/package.json +24 -8
  396. package/dist/canvas-public/cycle-detect.js +0 -166
  397. package/dist/canvas-public/smart-split.js +0 -185
  398. package/skills/game-asset-image-generator/SKILL.md +0 -104
  399. package/skills/game-audio/SKILL.md +0 -82
  400. package/skills/game-audio/agents/openai.yaml +0 -4
  401. package/skills/threejs-3d-game/references/engine-asset-pipeline.md +0 -116
  402. /package/{skills → dist/skills/en-US}/game-test/references/checklists/playtest-qa.md +0 -0
  403. /package/{skills → dist/skills/en-US}/game-ui/references/checklists/game-ui-quality.md +0 -0
  404. /package/{skills → dist/skills/en-US}/game-ui/references/checklists/hud-readability.md +0 -0
  405. /package/{skills → dist/skills/en-US}/game-ui/references/checklists/mobile-input.md +0 -0
  406. /package/{skills → dist/skills/en-US}/game-ui/references/checklists/responsive-ui-fit.md +0 -0
  407. /package/{skills → dist/skills/en-US}/game-ui/references/ui-patterns.md +0 -0
  408. /package/{skills → dist/skills/en-US}/game-ui/references/ui-prompt-templates.md +0 -0
  409. /package/{skills → dist/skills/en-US}/phaser-2d-graphics-builder/assets/scorecard-anchors/scene-1.jpeg +0 -0
  410. /package/{skills → dist/skills/en-US}/phaser-2d-graphics-builder/assets/scorecard-anchors/scene-2.jpeg +0 -0
  411. /package/{skills → dist/skills/en-US}/phaser-2d-graphics-builder/assets/scorecard-anchors/scene-3.jpg +0 -0
  412. /package/{skills → dist/skills/en-US}/phaser-2d-graphics-builder/references/checklists/compose-quality.md +0 -0
  413. /package/{skills → dist/skills/en-US}/phaser-2d-graphics-builder/references/checklists/performance-safe-visual-detail.md +0 -0
  414. /package/{skills → dist/skills/en-US}/phaser-2d-graphics-builder/references/checklists/premium-game-quality-gate.md +0 -0
  415. /package/{skills → dist/skills/en-US}/phaser-2d-graphics-builder/references/checklists/sprite-quality.md +0 -0
  416. /package/{skills → dist/skills/en-US}/phaser-2d-graphics-builder/references/checklists/technical-art-quality.md +0 -0
  417. /package/{skills → dist/skills/en-US}/phaser-2d-graphics-builder/references/checklists/visual-scorecard.md +0 -0
  418. /package/{skills → dist/skills/en-US}/phaser-2d-graphics-builder/references/compose-recipes.md +0 -0
  419. /package/{skills → dist/skills/en-US}/phaser-2d-graphics-builder/references/graphics-prompt-templates.md +0 -0
  420. /package/{skills → dist/skills/en-US}/phaser-2d-graphics-builder/references/implementation-blueprint.md +0 -0
  421. /package/{skills → dist/skills/en-US}/phaser-2d-graphics-builder/references/sprite-recipes.md +0 -0
  422. /package/{skills → dist/skills/en-US}/phaser-2d-graphics-builder/references/technical-art.md +0 -0
  423. /package/{skills → dist/skills/en-US}/phaser-2d-graphics-builder/references/vfx-recipes.md +0 -0
  424. /package/{skills → dist/skills/en-US}/phaser-2d-graphics-builder/references/visual-scorecard.md +0 -0
  425. /package/{skills → dist/skills/en-US}/threejs-aaa-graphics-builder/assets/scorecard-anchors/scene-1.jpg +0 -0
  426. /package/{skills → dist/skills/en-US}/threejs-aaa-graphics-builder/assets/scorecard-anchors/scene-2.jpg +0 -0
  427. /package/{skills → dist/skills/en-US}/threejs-aaa-graphics-builder/assets/scorecard-anchors/scene-3.jpg +0 -0
  428. /package/{skills → dist/skills/en-US}/threejs-aaa-graphics-builder/references/checklists/aaa-game-quality-gate.md +0 -0
  429. /package/{skills → dist/skills/en-US}/threejs-aaa-graphics-builder/references/checklists/aaa-visual-scorecard.md +0 -0
  430. /package/{skills → dist/skills/en-US}/threejs-aaa-graphics-builder/references/checklists/material-lighting-quality.md +0 -0
  431. /package/{skills → dist/skills/en-US}/threejs-aaa-graphics-builder/references/checklists/performance-safe-visual-detail.md +0 -0
  432. /package/{skills → dist/skills/en-US}/threejs-aaa-graphics-builder/references/checklists/procedural-model-quality.md +0 -0
  433. /package/{skills → dist/skills/en-US}/threejs-aaa-graphics-builder/references/checklists/technical-art-quality.md +0 -0
  434. /package/{skills → dist/skills/en-US}/threejs-aaa-graphics-builder/references/graphics-prompt-templates.md +0 -0
  435. /package/{skills → dist/skills/en-US}/threejs-aaa-graphics-builder/references/implementation-blueprint.md +0 -0
  436. /package/{skills → dist/skills/en-US}/threejs-aaa-graphics-builder/references/model-recipes.md +0 -0
  437. /package/{skills → dist/skills/en-US}/threejs-aaa-graphics-builder/references/render-recipes.md +0 -0
  438. /package/{skills → dist/skills/en-US}/threejs-aaa-graphics-builder/references/shader-cookbook.md +0 -0
  439. /package/{skills → dist/skills/en-US}/threejs-aaa-graphics-builder/references/technical-art.md +0 -0
  440. /package/{skills → dist/skills/en-US}/threejs-aaa-graphics-builder/references/visual-scorecard.md +0 -0
  441. /package/{skills → dist/skills/zh-CN}/evomeme-canvas/SKILL.md +0 -0
  442. /package/{skills → dist/skills/zh-CN}/evomeme-canvas/agents/openai.yaml +0 -0
  443. /package/{skills → dist/skills/zh-CN}/evomeme-cloud-fs/agents/openai.yaml +0 -0
  444. /package/{skills → dist/skills/zh-CN}/evomeme-cover/agents/openai.yaml +0 -0
  445. /package/{skills → dist/skills/zh-CN}/evomeme-game-maker/agents/openai.yaml +0 -0
  446. /package/{skills → dist/skills/zh-CN}/evomeme-login/agents/openai.yaml +0 -0
  447. /package/{skills → dist/skills/zh-CN}/evomeme-native-bridge-sdk/SKILL.md +0 -0
  448. /package/{skills → dist/skills/zh-CN}/evomeme-native-bridge-sdk/agents/openai.yaml +0 -0
  449. /package/{skills → dist/skills/zh-CN}/evomeme-tos-upload/agents/openai.yaml +0 -0
  450. /package/{skills → dist/skills/zh-CN}/game-art/SKILL.md +0 -0
  451. /package/{skills → dist/skills/zh-CN}/game-art/agents/openai.yaml +0 -0
  452. /package/{skills → dist/skills/zh-CN}/game-asset-image-generator/agents/openai.yaml +0 -0
  453. /package/{skills → dist/skills/zh-CN}/game-demo/SKILL.md +0 -0
  454. /package/{skills → dist/skills/zh-CN}/game-demo/agents/openai.yaml +0 -0
  455. /package/{skills → dist/skills/zh-CN}/game-maker/SKILL.md +0 -0
  456. /package/{skills → dist/skills/zh-CN}/game-maker/agents/openai.yaml +0 -0
  457. /package/{skills → dist/skills/zh-CN}/game-test/SKILL.md +0 -0
  458. /package/{skills → dist/skills/zh-CN}/game-test/agents/openai.yaml +0 -0
  459. /package/{skills → dist/skills/zh-CN}/game-ui/agents/openai.yaml +0 -0
  460. /package/{skills → dist/skills/zh-CN}/phaser-2d-game/SKILL.md +0 -0
  461. /package/{skills → dist/skills/zh-CN}/phaser-2d-game/agents/openai.yaml +0 -0
  462. /package/{skills → dist/skills/zh-CN}/phaser-2d-game/references/engine-performance.md +0 -0
  463. /package/{skills → dist/skills/zh-CN}/phaser-2d-game/references/engine-physics.md +0 -0
  464. /package/{skills → dist/skills/zh-CN}/phaser-2d-game/references/engine-runtime.md +0 -0
  465. /package/{skills → dist/skills/zh-CN}/phaser-2d-game/references/engine-spritesheets.md +0 -0
  466. /package/{skills → dist/skills/zh-CN}/phaser-2d-game/references/engine-tilemaps.md +0 -0
  467. /package/{skills → dist/skills/zh-CN}/phaser-2d-game/references/file-structure.md +0 -0
  468. /package/{skills → dist/skills/zh-CN}/phaser-2d-graphics-builder/SKILL.md +0 -0
  469. /package/{skills → dist/skills/zh-CN}/phaser-2d-graphics-builder/agents/openai.yaml +0 -0
  470. /package/{skills → dist/skills/zh-CN}/threejs-3d-game/agents/openai.yaml +0 -0
  471. /package/{skills → dist/skills/zh-CN}/threejs-3d-game/references/engine-audio.md +0 -0
  472. /package/{skills → dist/skills/zh-CN}/threejs-3d-game/references/engine-input-camera.md +0 -0
  473. /package/{skills → dist/skills/zh-CN}/threejs-3d-game/references/engine-performance.md +0 -0
  474. /package/{skills → dist/skills/zh-CN}/threejs-3d-game/references/engine-physics.md +0 -0
  475. /package/{skills → dist/skills/zh-CN}/threejs-3d-game/references/engine-runtime.md +0 -0
  476. /package/{skills → dist/skills/zh-CN}/threejs-3d-game/references/file-structure.md +0 -0
  477. /package/{skills → dist/skills/zh-CN}/threejs-aaa-graphics-builder/agents/openai.yaml +0 -0
@@ -0,0 +1,63 @@
1
+ export const FRAME_EDITOR_WIDTH = 780
2
+
3
+ export function normalizeFrameEditorFrame(value, sourceRows, sourceColumns) {
4
+ if (!value || typeof value !== 'object') return null
5
+ if (value.kind === 'source_cell') {
6
+ const index = Math.round(Number(value.index))
7
+ if (!Number.isFinite(index) || index < 0 || index >= sourceRows * sourceColumns) return null
8
+ return { kind: 'source_cell', index }
9
+ }
10
+ if (value.kind === 'asset') {
11
+ const assetId = String(value.assetId || value.asset_id || '').trim()
12
+ return assetId ? { kind: 'asset', assetId } : null
13
+ }
14
+ return null
15
+ }
16
+
17
+ export function normalizeFrameEditor(item) {
18
+ if (item?.type !== 'frame_editor') return null
19
+ const sourceId = String(item.sourceId || '').trim()
20
+ const sourceRows = Math.round(Number(item.sourceRows))
21
+ const sourceColumns = Math.round(Number(item.sourceColumns))
22
+ const rows = Math.round(Number(item.rows))
23
+ const columns = Math.round(Number(item.columns))
24
+ const fps = Number(item.fps)
25
+ if (
26
+ !sourceId ||
27
+ !Number.isFinite(sourceRows) ||
28
+ !Number.isFinite(sourceColumns) ||
29
+ !Number.isFinite(rows) ||
30
+ !Number.isFinite(columns) ||
31
+ !Number.isFinite(fps) ||
32
+ sourceRows < 1 ||
33
+ sourceRows > 64 ||
34
+ sourceColumns < 1 ||
35
+ sourceColumns > 64 ||
36
+ rows < 1 ||
37
+ rows > 64 ||
38
+ columns < 1 ||
39
+ columns > 64 ||
40
+ fps <= 0
41
+ ) {
42
+ return null
43
+ }
44
+ const frames = (Array.isArray(item.frames) ? item.frames : [])
45
+ .map((frame) => normalizeFrameEditorFrame(frame, sourceRows, sourceColumns))
46
+ .filter(Boolean)
47
+ .slice(0, rows * columns)
48
+ return { sourceId, sourceRows, sourceColumns, rows, columns, fps, frames }
49
+ }
50
+
51
+ export function frameEditorWidth(value) {
52
+ const width = Number(value)
53
+ return Number.isFinite(width) ? Math.max(FRAME_EDITOR_WIDTH, width) : FRAME_EDITOR_WIDTH
54
+ }
55
+
56
+ export function frameEditorParentIds(item) {
57
+ const editor = normalizeFrameEditor(item)
58
+ if (!editor) return []
59
+ return [
60
+ editor.sourceId,
61
+ ...editor.frames.filter((frame) => frame.kind === 'asset').map((frame) => frame.assetId),
62
+ ].filter((id, index, ids) => id && ids.indexOf(id) === index)
63
+ }
@@ -0,0 +1,83 @@
1
+ import { state } from '../../core/state.js'
2
+ import {
3
+ advanceScrollPreviewOffset,
4
+ applyFrameSheetPreviewFrame,
5
+ applyScrollImagePreviewOffset,
6
+ frameSheetPreviewMeta,
7
+ scrollImagePreviewMeta,
8
+ } from '../../elements/image.js'
9
+ import { applyFrameEditorPreviewFrame } from './frame-editing.js'
10
+ import { normalizeFrameEditor } from './frame-model.js'
11
+
12
+ // Media playback is independent of feature parameter forms and shares one animation clock.
13
+ export function startFramePlayback({ elements, imageUrl }) {
14
+ let lastFrameSheetPreviewTimestamp = 0
15
+
16
+ function tickFrameSheetPreviews(timestamp) {
17
+ if (!lastFrameSheetPreviewTimestamp) lastFrameSheetPreviewTimestamp = timestamp
18
+ const deltaSeconds = Math.min(
19
+ 0.25,
20
+ Math.max(0, timestamp - lastFrameSheetPreviewTimestamp) / 1000,
21
+ )
22
+ lastFrameSheetPreviewTimestamp = timestamp
23
+
24
+ for (const preview of elements.world.querySelectorAll('.frame-sheet-preview[data-asset-id]')) {
25
+ const assetId = preview.dataset.assetId
26
+ const item = state.layoutItems.find((candidate) => candidate.id === assetId)
27
+ const meta = frameSheetPreviewMeta(item)
28
+ if (!meta || meta.frameCount < 2) continue
29
+ const play = state.frameSheetPlayback[assetId] || { index: 0, acc: 0 }
30
+ play.acc += deltaSeconds
31
+ const frameDuration = 1 / meta.fps
32
+ let changed = false
33
+ const elapsedFrames = Math.floor(play.acc / frameDuration)
34
+ if (elapsedFrames > 0) {
35
+ play.acc -= elapsedFrames * frameDuration
36
+ play.index = (play.index + elapsedFrames) % meta.frameCount
37
+ changed = true
38
+ }
39
+ state.frameSheetPlayback[assetId] = play
40
+ if (changed) applyFrameSheetPreviewFrame(preview, meta, play.index)
41
+ }
42
+
43
+ for (const preview of elements.world.querySelectorAll('.scroll-image-preview[data-asset-id]')) {
44
+ const assetId = preview.dataset.assetId
45
+ const item = state.layoutItems.find((candidate) => candidate.id === assetId)
46
+ const meta = scrollImagePreviewMeta(item)
47
+ if (!meta) continue
48
+ const play = state.scrollImagePlayback[assetId] || { offset: 0 }
49
+ play.offset = advanceScrollPreviewOffset(
50
+ play.offset,
51
+ meta,
52
+ deltaSeconds,
53
+ preview.clientWidth,
54
+ )
55
+ state.scrollImagePlayback[assetId] = play
56
+ applyScrollImagePreviewOffset(preview, play.offset)
57
+ }
58
+
59
+ for (const preview of elements.world.querySelectorAll(
60
+ '.frame-editor-preview-stage[data-editor-id]',
61
+ )) {
62
+ const editorId = preview.dataset.editorId
63
+ const editor = normalizeFrameEditor(
64
+ state.layoutItems.find((candidate) => candidate.id === editorId),
65
+ )
66
+ if (!editor || editor.frames.length < 2) continue
67
+ const play = state.frameSheetPlayback[editorId] || { index: 0, acc: 0 }
68
+ play.acc += deltaSeconds
69
+ const frameDuration = 1 / editor.fps
70
+ const elapsedFrames = Math.floor(play.acc / frameDuration)
71
+ if (elapsedFrames > 0) {
72
+ play.acc -= elapsedFrames * frameDuration
73
+ play.index = (play.index + elapsedFrames) % editor.frames.length
74
+ applyFrameEditorPreviewFrame(preview, editor, play.index, imageUrl)
75
+ }
76
+ state.frameSheetPlayback[editorId] = play
77
+ }
78
+
79
+ requestAnimationFrame(tickFrameSheetPreviews)
80
+ }
81
+
82
+ requestAnimationFrame(tickFrameSheetPreviews)
83
+ }
@@ -0,0 +1,151 @@
1
+ import { errorT } from '../../language/index.js'
2
+ import { t } from '../../language/index.js'
3
+ import { state } from '../../core/state.js'
4
+ import {
5
+ frameSheetPreviewMeta,
6
+ normalizeFramePreviewConfig,
7
+ normalizeScrollPreviewConfig,
8
+ sourceFramePreviewConfig,
9
+ suggestedFramePreviewConfig,
10
+ } from '../../elements/image.js'
11
+
12
+ export async function detectFramePreviewCount(imageId, rows, columns, imageUrl) {
13
+ const image = new Image()
14
+ image.crossOrigin = 'anonymous'
15
+ await new Promise((resolve, reject) => {
16
+ image.onload = resolve
17
+ image.onerror = () => reject(new Error(errorT('features.frameEditor.frameEditingDialogs.text007')))
18
+ image.src = imageUrl(imageId)
19
+ })
20
+ const canvas = document.createElement('canvas')
21
+ for (let index = rows * columns - 1; index >= 0; index -= 1) {
22
+ const row = Math.floor(index / columns),
23
+ column = index % columns
24
+ const left = Math.floor((column * image.naturalWidth) / columns),
25
+ top = Math.floor((row * image.naturalHeight) / rows)
26
+ const width = Math.max(1, Math.floor(((column + 1) * image.naturalWidth) / columns) - left)
27
+ const height = Math.max(1, Math.floor(((row + 1) * image.naturalHeight) / rows) - top)
28
+ canvas.width = width
29
+ canvas.height = height
30
+ const context = canvas.getContext('2d', { willReadFrequently: true })
31
+ if (!context) return rows * columns
32
+ context.drawImage(image, left, top, width, height, 0, 0, width, height)
33
+ const pixels = context.getImageData(0, 0, width, height).data
34
+ for (let offset = 3; offset < pixels.length; offset += 4)
35
+ if (pixels[offset] !== 0) return index + 1
36
+ }
37
+ return 1
38
+ }
39
+
40
+ export async function applyFramePreview(source, params, services) {
41
+ const hadFramePreview = Object.prototype.hasOwnProperty.call(source, 'framePreview')
42
+ const previousFramePreview = source.framePreview
43
+ const hadScrollPreview = Object.prototype.hasOwnProperty.call(source, 'scrollPreview')
44
+ const previousScrollPreview = source.scrollPreview
45
+ const known = normalizeFramePreviewConfig(previousFramePreview) || sourceFramePreviewConfig(source)
46
+ const frameCount =
47
+ known && known.rows === params.rows && known.columns === params.columns
48
+ ? Math.min(known.frameCount, params.rows * params.columns)
49
+ : await detectFramePreviewCount(source.id, params.rows, params.columns, services.imageUrl)
50
+ source.framePreview = {
51
+ enabled: params.enabled,
52
+ rows: params.rows,
53
+ columns: params.columns,
54
+ fps: params.fps,
55
+ frameCount,
56
+ }
57
+ if (params.enabled) {
58
+ const scrollPreview = normalizeScrollPreviewConfig(source.scrollPreview)
59
+ if (scrollPreview?.enabled) source.scrollPreview = { ...scrollPreview, enabled: false }
60
+ }
61
+ try {
62
+ await services.saveLayout()
63
+ } catch (error) {
64
+ if (hadFramePreview) source.framePreview = previousFramePreview
65
+ else delete source.framePreview
66
+ if (hadScrollPreview) source.scrollPreview = previousScrollPreview
67
+ else delete source.scrollPreview
68
+ throw error
69
+ }
70
+ if (params.enabled) {
71
+ state.frameSheetPlayback[source.id] = { index: 0, acc: 0 }
72
+ delete state.scrollImagePlayback[source.id]
73
+ }
74
+ else delete state.frameSheetPlayback[source.id]
75
+ services.renderCanvasItem(source.id)
76
+ }
77
+
78
+ export default {
79
+ render: (ui) =>
80
+ ui.stack(ui.field('enabled'), ui.row(ui.field('rows'), ui.field('columns')), ui.field('fps')),
81
+ id: 'frame-sheet-preview',
82
+ title: 'inspector.framePreview.text001',
83
+ storage: 'parameters',
84
+ node: {
85
+ type: 'feature_dialog',
86
+ width: 320,
87
+ minWidth: 280,
88
+ minHeight: 220,
89
+ generationInput: true,
90
+ classNames: ['is-interactive-ui'],
91
+ },
92
+ menu: [
93
+ {
94
+ group: 'frame-sheet',
95
+ title: 'html.text061',
96
+ titleFor: (source) =>
97
+ frameSheetPreviewMeta(source)
98
+ ? 'dialogs.contextMenu.text001'
99
+ : 'dialogs.contextMenu.text002',
100
+ accepts: ['image'],
101
+ },
102
+ ],
103
+ fields: [
104
+ { path: 'enabled', type: 'boolean', default: true, label: 'inspector.framePreview.text008' },
105
+ {
106
+ path: 'rows',
107
+ type: 'integer',
108
+ default: 2,
109
+ min: 1,
110
+ max: 64,
111
+ required: true,
112
+ label: 'common.rows',
113
+ },
114
+ {
115
+ path: 'columns',
116
+ type: 'integer',
117
+ default: 2,
118
+ min: 1,
119
+ max: 64,
120
+ required: true,
121
+ label: 'common.columns',
122
+ },
123
+ {
124
+ path: 'fps',
125
+ type: 'number',
126
+ default: 8,
127
+ min: 0.000001,
128
+ step: 'any',
129
+ required: true,
130
+ label: 'common.framesPerSecond',
131
+ },
132
+ ],
133
+ async sourceAction(source, services) {
134
+ const config = frameSheetPreviewMeta(source)
135
+ if (!config) return false
136
+ await applyFramePreview(source, { ...config, enabled: false }, services)
137
+ services.renderChrome()
138
+ return true
139
+ },
140
+ prefill: (source) => ({ ...suggestedFramePreviewConfig(source), enabled: true }),
141
+ validate: (p) => (p.rows * p.columns >= 2 ? '' : t('inspector.framePreview.text009')),
142
+ submitLabel: 'html.text072',
143
+ async execute(p, item, services) {
144
+ const source = state.layoutItems.find((entry) => entry.id === item.sourceId)
145
+ if (!source) throw new Error(errorT('inspector.framePreview.text011'))
146
+ await applyFramePreview(source, p, services)
147
+ await services.replaceLocal(item, [])
148
+ services.setSelection([source.id])
149
+ services.renderChrome()
150
+ },
151
+ }
@@ -0,0 +1,272 @@
1
+ import { state } from '../../core/state.js'
2
+ import { t } from '../../language/index.js'
3
+ import { featureDefaults } from '../../core/feature-state.js'
4
+ import {
5
+ generationNode,
6
+ promptField,
7
+ modelField,
8
+ refsField,
9
+ booleanField,
10
+ colorField,
11
+ } from './fields.js'
12
+
13
+ const key = (n) => `features.generation.animationGeneration.text${String(n).padStart(3, '0')}`
14
+ const enabled = (path, value = true) => ({ path, type: 'hidden', default: value })
15
+ const number = (path, label, value, min, max, extra = {}) => ({
16
+ path,
17
+ type: 'number',
18
+ label,
19
+ default: value,
20
+ min,
21
+ max,
22
+ step: 0.1,
23
+ ...extra,
24
+ })
25
+ const size = (value) =>
26
+ String(value || '')
27
+ .trim()
28
+ .replace(/[×*X]/g, 'x')
29
+ .replace(/\s+/g, '')
30
+
31
+ const animationFeature = {
32
+ styles:
33
+ '[data-feature-form="animation"][data-surface="canvas"] .feature-form-content { max-height: 600px; }',
34
+ render(ui, { inspector }) {
35
+ const first = ui.section(
36
+ 'firstFrameEnabled',
37
+ ui.field('firstFrameRefs'),
38
+ ui.prompt('firstFramePrompt'),
39
+ ui.row(ui.field('imageModel'), ui.field('imageSize')),
40
+ ui.field('backgroundColor'),
41
+ ui.field('expandImage'),
42
+ )
43
+ const video = ui.section(
44
+ 'video',
45
+ ui.field('reuseFirstFrameAsLast'),
46
+ ui.row(ui.field('videoFirstFrameRef'), ui.field('videoLastFrameRef')),
47
+ ui.prompt('videoPrompt'),
48
+ ui.row(ui.field('duration'), ui.field('videoResolution')),
49
+ )
50
+ const keying = ui.section(
51
+ 'colorKeyEnabled',
52
+ ui.field('keyBackgroundColor'),
53
+ ui.field('colorKeyStrength'),
54
+ ui.field('colorKeyContiguousOnly'),
55
+ ui.field('colorKeyDespill'),
56
+ )
57
+ const cycle = ui.section('cycleEnabled')
58
+ const extraction = ui.section('frameExtractionEnabled')
59
+ const modules = inspector
60
+ ? ui.stack(first, video, cycle, extraction, keying)
61
+ : ui.row(ui.stack(first, keying), ui.stack(video, cycle, extraction))
62
+ modules.style.setProperty('--field-min', '330px')
63
+ return ui.stack(ui.field('animationPreset'), modules)
64
+ },
65
+ toolbar: [
66
+ { id: 'tool-animation-gen', group: 'video', label: 'html.text043', title: 'html.text014' },
67
+ ],
68
+ id: 'animation',
69
+ title: 'features.generation.generationDialog.text001',
70
+ node: generationNode('animation_dialog', 900, {
71
+ minWidth: 400,
72
+ minHeight: 360,
73
+ classNames: ['is-interactive-ui', 'is-gen-dialog', 'is-animation-dialog'],
74
+ }),
75
+ storage: 'animationGeneration',
76
+ submitLabel: key(46),
77
+ fields: [
78
+ {
79
+ path: 'animationPreset',
80
+ type: 'enum',
81
+ default: 'custom',
82
+ label: key(14),
83
+ options: ['walk', 'run', 'attack', 'jump', 'custom'].map((value, index) => ({
84
+ value,
85
+ labelKey: key(15 + index),
86
+ })),
87
+ },
88
+ {
89
+ label: key(21),
90
+ enablePath: 'firstFrameEnabled',
91
+ fields: [
92
+ enabled('firstFrameEnabled'),
93
+ refsField({
94
+ path: 'firstFrameRefs',
95
+ required: true,
96
+ label: 'features.generation.directionGeneration.text012',
97
+ }),
98
+ promptField({ path: 'firstFramePrompt', label: key(23), placeholder: key(22) }),
99
+ colorField(),
100
+ modelField({ path: 'imageModel', default: 'asset-pro' }),
101
+ { path: 'imageSize', type: 'text', default: '2048x2048', label: key(26) },
102
+ booleanField('expandImage', key(27), true),
103
+ ],
104
+ },
105
+ {
106
+ id: 'video',
107
+ label: key(28),
108
+ fields: [
109
+ booleanField('reuseFirstFrameAsLast', key(29), false, {
110
+ visible: (p) => p.firstFrameEnabled,
111
+ }),
112
+ refsField({
113
+ path: 'videoFirstFrameRef',
114
+ default: null,
115
+ multiple: false,
116
+ required: true,
117
+ label: key(30),
118
+ visible: (p) => !p.firstFrameEnabled,
119
+ }),
120
+ refsField({
121
+ path: 'videoLastFrameRef',
122
+ default: null,
123
+ multiple: false,
124
+ label: key(31),
125
+ visible: (p) => !p.firstFrameEnabled,
126
+ }),
127
+ promptField({ path: 'videoPrompt', label: key(23), required: true, placeholder: key(32) }),
128
+ number('duration', key(33), 4, 4, 15, { type: 'integer', step: 1 }),
129
+ {
130
+ path: 'videoResolution',
131
+ type: 'enum',
132
+ default: '720p',
133
+ label: key(34),
134
+ options: () => state.meta?.video?.resolutions || ['480p', '720p', '1080p'],
135
+ },
136
+ ],
137
+ },
138
+ {
139
+ label: key(35),
140
+ enablePath: 'cycleEnabled',
141
+ fields: [enabled('cycleEnabled'), number('cycleSimilarity', key(36), 95, 0, 100)],
142
+ },
143
+ {
144
+ label: key(37),
145
+ enablePath: 'frameExtractionEnabled',
146
+ fields: [
147
+ enabled('frameExtractionEnabled'),
148
+ number('fps', 'common.framesPerSecond', 8, 0.1, 60),
149
+ ],
150
+ },
151
+ {
152
+ label: key(38),
153
+ enablePath: 'colorKeyEnabled',
154
+ disabled: (p) => !p.frameExtractionEnabled,
155
+ fields: [
156
+ enabled('colorKeyEnabled'),
157
+ colorField('backgroundColor', {
158
+ id: 'keyBackgroundColor',
159
+ visible: (p) => !p.firstFrameEnabled,
160
+ }),
161
+ number('colorKeyStrength', key(39), 80, 0, 100, { step: 1 }),
162
+ booleanField('colorKeyContiguousOnly', key(40)),
163
+ booleanField('colorKeyDespill', key(41)),
164
+ ],
165
+ },
166
+ ],
167
+ migrate(saved) {
168
+ if (!saved.firstFrameRefs && saved.firstFrameRef?.id)
169
+ saved.firstFrameRefs = [saved.firstFrameRef]
170
+ return saved
171
+ },
172
+ changed(p, path) {
173
+ if (path === 'animationPreset') applyAnimationPreset(p, p.animationPreset)
174
+ },
175
+ validate(p) {
176
+ if (p.firstFrameEnabled && !/^([1-9]\d*)x([1-9]\d*)$/.test(size(p.imageSize))) return t(key(50))
177
+ const durations = state.meta?.video?.durations || [4, 5, 6, 8, 10, 12, 15]
178
+ return durations.includes(Number(p.duration))
179
+ ? ''
180
+ : t(key(51)) + durations.filter((v) => v >= 4).join('、') + t(`${key(51)}.part1`)
181
+ },
182
+ task(p) {
183
+ const references = (
184
+ p.firstFrameEnabled ? p.firstFrameRefs : [p.videoFirstFrameRef, p.videoLastFrameRef]
185
+ )
186
+ .filter(Boolean)
187
+ .map((r) => ({ id: r.id, role: 'source', kind: 'image' }))
188
+ return {
189
+ endpoint: '/api/generate-animation',
190
+ options: { allowExternalSync: true, retainUntilSettled: true },
191
+ wait: {
192
+ name: t(key(52)),
193
+ width: 360,
194
+ height: 240,
195
+ prompt: p.videoPrompt.trim(),
196
+ media: p.frameExtractionEnabled ? 'image' : 'video',
197
+ ratio: 'adaptive',
198
+ model: 'animation-pipeline',
199
+ size: `${p.videoResolution} · ${p.duration}s · ${p.fps} FPS`,
200
+ references,
201
+ },
202
+ body: {
203
+ first_frame_enabled: p.firstFrameEnabled,
204
+ first_frame_prompt: p.firstFramePrompt,
205
+ first_frame_reference_ids: p.firstFrameRefs.map((r) => r.id),
206
+ background_color: p.backgroundColor,
207
+ expand_image: p.expandImage,
208
+ image_model: p.imageModel,
209
+ image_size: size(p.imageSize),
210
+ video_first_frame_id: p.videoFirstFrameRef?.id || null,
211
+ video_last_frame_id: p.videoLastFrameRef?.id || null,
212
+ reuse_first_frame_as_last: p.reuseFirstFrameAsLast,
213
+ video_prompt: p.videoPrompt.trim(),
214
+ duration: Number(p.duration),
215
+ video_resolution: p.videoResolution,
216
+ cycle_enabled: p.cycleEnabled,
217
+ cycle_similarity: p.cycleSimilarity,
218
+ frame_extraction_enabled: p.frameExtractionEnabled,
219
+ fps: p.fps,
220
+ color_key_enabled: p.colorKeyEnabled && p.frameExtractionEnabled,
221
+ color_key_strength: p.colorKeyStrength,
222
+ color_key_contiguous_only: p.colorKeyContiguousOnly,
223
+ color_key_despill: p.colorKeyDespill,
224
+ place: false,
225
+ },
226
+ }
227
+ },
228
+ }
229
+
230
+ export default animationFeature
231
+
232
+ export function applyAnimationPreset(dialog, preset) {
233
+ dialog.animationPreset = preset
234
+ if (!['walk', 'run', 'attack', 'jump'].includes(preset)) return
235
+ const defaults = featureDefaults(animationFeature)
236
+ const firstFrameRefs = dialog.firstFrameRefs || []
237
+ const videoFirstFrameRef = dialog.videoFirstFrameRef || null
238
+ const videoLastFrameRef = dialog.videoLastFrameRef || null
239
+ const messages = dialog.messages || []
240
+ const busy = dialog.busy === true
241
+ Object.assign(dialog, defaults, {
242
+ animationPreset: preset,
243
+ firstFrameRefs,
244
+ ...(preset === 'attack' ? { videoFirstFrameRef, videoLastFrameRef } : {}),
245
+ messages,
246
+ busy,
247
+ firstFrameEnabled: preset !== 'attack',
248
+ firstFramePrompt:
249
+ preset === 'attack'
250
+ ? ''
251
+ : preset === 'jump'
252
+ ? t('features.generation.animationState.text001')
253
+ : preset === 'run'
254
+ ? t('features.generation.animationState.text002')
255
+ : t('features.generation.animationState.text003'),
256
+ imageSize: '2048x2048',
257
+ expandImage: true,
258
+ reuseFirstFrameAsLast: preset !== 'attack',
259
+ videoPrompt:
260
+ preset === 'attack'
261
+ ? t('features.generation.animationState.text004')
262
+ : preset === 'jump'
263
+ ? t('features.generation.animationState.text005')
264
+ : preset === 'run'
265
+ ? t('features.generation.animationState.text006')
266
+ : t('features.generation.animationState.text007'),
267
+ duration: 4,
268
+ videoResolution: '480p',
269
+ cycleEnabled: !['attack', 'jump'].includes(preset),
270
+ fps: ['attack', 'jump'].includes(preset) ? 4 : defaults.fps,
271
+ })
272
+ }
@@ -0,0 +1,102 @@
1
+ import { state } from '../../core/state.js'
2
+ import { t } from '../../language/index.js'
3
+ import {
4
+ generationNode,
5
+ promptField,
6
+ modelField,
7
+ refsField,
8
+ transparentField,
9
+ colorField,
10
+ clearUnsupportedTransparency,
11
+ imageWait,
12
+ } from './fields.js'
13
+
14
+ const key = (name) => `features.generation.assetBatch.${name}`
15
+
16
+ export default {
17
+ render: (ui) =>
18
+ ui.stack(
19
+ ui.field('assetType'),
20
+ ui.field('customAssetType'),
21
+ ui.prompt('prompt', 'refs'),
22
+ ui.row(ui.field('model'), ui.field('size')),
23
+ ui.field('transparentBackground'),
24
+ ui.field('backgroundColor'),
25
+ ),
26
+ toolbar: [
27
+ {
28
+ id: 'tool-asset-batch-gen',
29
+ group: 'image',
30
+ label: key('toolbar'),
31
+ title: key('toolbarTitle'),
32
+ },
33
+ ],
34
+ id: 'asset-batch',
35
+ title: key('title'),
36
+ node: generationNode('asset_batch_dialog', 460, { minWidth: 340, minHeight: 360 }),
37
+ storage: 'assetBatch',
38
+ submitLabel: key('submit'),
39
+ fields: [
40
+ {
41
+ path: 'assetType',
42
+ type: 'enum',
43
+ default: 'top-down',
44
+ label: key('assetType'),
45
+ options: [
46
+ { value: 'top-down', labelKey: key('topDown') },
47
+ { value: 'isometric', labelKey: key('isometric') },
48
+ { value: 'side-view', labelKey: key('sideView') },
49
+ { value: 'custom', labelKey: key('custom') },
50
+ ],
51
+ },
52
+ {
53
+ path: 'customAssetType',
54
+ type: 'text',
55
+ default: '',
56
+ required: true,
57
+ visible: (p) => p.assetType === 'custom',
58
+ label: key('customAssetType'),
59
+ placeholder: key('customAssetTypePlaceholder'),
60
+ },
61
+ promptField({
62
+ required: true,
63
+ label: key('prompt'),
64
+ placeholder: key('promptPlaceholder'),
65
+ }),
66
+ refsField({ label: key('references') }),
67
+ modelField({ default: 'asset-max' }),
68
+ {
69
+ path: 'size',
70
+ type: 'enum',
71
+ default: '1664x2496',
72
+ label: key('size'),
73
+ options: () => [...new Set(['1664x2496', ...(state.meta?.size_presets || [])])],
74
+ },
75
+ transparentField({ label: key('transparentBackground') }),
76
+ colorField('backgroundColor', {
77
+ label: key('backgroundColor'),
78
+ visible: (p) => !p.transparentBackground,
79
+ }),
80
+ ],
81
+ changed: clearUnsupportedTransparency,
82
+ validate: (p) => (p.refs.length > 14 ? t(key('tooManyReferences')) : ''),
83
+ task(p, services) {
84
+ return {
85
+ endpoint: '/api/generate-asset-batch',
86
+ options: { allowExternalSync: true },
87
+ wait: imageWait(p, services, p.size, key('generating')),
88
+ body: {
89
+ asset_type: p.assetType,
90
+ ...(p.assetType === 'custom'
91
+ ? { custom_asset_type: p.customAssetType.trim() }
92
+ : {}),
93
+ prompt: p.prompt.trim(),
94
+ size: p.size,
95
+ model: p.model,
96
+ background_color: p.backgroundColor,
97
+ transparent_background: p.model === 'asset-max' && p.transparentBackground,
98
+ reference_ids: p.refs.map((reference) => reference.id),
99
+ },
100
+ }
101
+ },
102
+ }