@playcraft/skills 0.0.2

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 (479) hide show
  1. package/README.md +333 -0
  2. package/dist/src/index.d.ts +3 -0
  3. package/dist/src/index.d.ts.map +1 -0
  4. package/dist/src/index.js +2 -0
  5. package/dist/src/index.js.map +1 -0
  6. package/dist/src/skills.loader.d.ts +31 -0
  7. package/dist/src/skills.loader.d.ts.map +1 -0
  8. package/dist/src/skills.loader.js +200 -0
  9. package/dist/src/skills.loader.js.map +1 -0
  10. package/dist/src/skills.types.d.ts +44 -0
  11. package/dist/src/skills.types.d.ts.map +1 -0
  12. package/dist/src/skills.types.js +9 -0
  13. package/dist/src/skills.types.js.map +1 -0
  14. package/package.json +35 -0
  15. package/skills/2048_core.aigameplay/SKILL.md +123 -0
  16. package/skills/2048_core.aigameplay/manifest.json +159 -0
  17. package/skills/2048_core.aigameplay/ref/pgs-schema.json +194 -0
  18. package/skills/2048_core.aigameplay/ref/reducer.template.ts +189 -0
  19. package/skills/SKILL.md +46 -0
  20. package/skills/ad_compliance_rules.aiconfig/SKILL.md +85 -0
  21. package/skills/ad_compliance_rules.aiconfig/manifest.json +60 -0
  22. package/skills/agent_remix_orchestrator.aicomponent/SKILL.md +257 -0
  23. package/skills/agent_remix_orchestrator.aicomponent/manifest.json +12 -0
  24. package/skills/app_metadata.aiconfig/SKILL.md +53 -0
  25. package/skills/app_metadata.aiconfig/manifest.json +32 -0
  26. package/skills/appear_sfx.aiaudio/SKILL.md +59 -0
  27. package/skills/appear_sfx.aiaudio/manifest.json +45 -0
  28. package/skills/appear_sfx.aiaudio/ref/appear.mp3 +0 -0
  29. package/skills/arrow_move_error_sfx.aiaudio/SKILL.md +59 -0
  30. package/skills/arrow_move_error_sfx.aiaudio/manifest.json +45 -0
  31. package/skills/arrow_move_error_sfx.aiaudio/ref/arrow_move_error.mp3 +0 -0
  32. package/skills/arrow_path_data_format.aicomponent/SKILL.md +152 -0
  33. package/skills/arrow_path_data_format.aicomponent/manifest.json +57 -0
  34. package/skills/arrow_path_data_format.aicomponent/ref/LevelParser.ts +188 -0
  35. package/skills/arrow_path_data_format.aicomponent/ref/LevelTypes.ts +131 -0
  36. package/skills/arrow_pick_match_rules.aigameplay/SKILL.md +117 -0
  37. package/skills/arrow_pick_match_rules.aigameplay/manifest.json +105 -0
  38. package/skills/arrow_pick_match_rules.aigameplay/ref/pgs-schema.json +180 -0
  39. package/skills/asset_pipeline_scripts.aicomponent/SKILL.md +117 -0
  40. package/skills/asset_pipeline_scripts.aicomponent/manifest.json +17 -0
  41. package/skills/asset_pipeline_scripts.aicomponent/ref/gen-sprite.sh +105 -0
  42. package/skills/ball_sort.aigameplay/SKILL.md +109 -0
  43. package/skills/ball_sort.aigameplay/manifest.json +155 -0
  44. package/skills/ball_sort.aigameplay/ref/pgs-schema.json +192 -0
  45. package/skills/ball_sort.aigameplay/ref/reducer.template.ts +156 -0
  46. package/skills/basketball_shot.aigameplay/SKILL.md +94 -0
  47. package/skills/basketball_shot.aigameplay/manifest.json +150 -0
  48. package/skills/basketball_shot.aigameplay/ref/pgs-schema.json +229 -0
  49. package/skills/basketball_shot.aigameplay/ref/reducer.template.ts +189 -0
  50. package/skills/bg_music.aiaudio/SKILL.md +61 -0
  51. package/skills/bg_music.aiaudio/manifest.json +48 -0
  52. package/skills/bg_music.aiaudio/ref/bg.mp3 +0 -0
  53. package/skills/big_watermelon.aigameplay/SKILL.md +94 -0
  54. package/skills/big_watermelon.aigameplay/manifest.json +155 -0
  55. package/skills/big_watermelon.aigameplay/ref/pgs-schema.json +191 -0
  56. package/skills/big_watermelon.aigameplay/ref/reducer.template.ts +202 -0
  57. package/skills/block_puzzle.aigameplay/SKILL.md +121 -0
  58. package/skills/block_puzzle.aigameplay/manifest.json +154 -0
  59. package/skills/block_puzzle.aigameplay/ref/pgs-schema.json +170 -0
  60. package/skills/block_puzzle.aigameplay/ref/reducer.template.ts +182 -0
  61. package/skills/board_entity_sprite.aiimage/SKILL.md +255 -0
  62. package/skills/board_entity_sprite.aiimage/manifest.json +153 -0
  63. package/skills/board_entity_sprite.aiimage/ref/ProceduralCar.ts +357 -0
  64. package/skills/board_entity_sprite.aiimage/ref/car.png +0 -0
  65. package/skills/board_entity_sprite.aiimage/ref/car.webp +0 -0
  66. package/skills/bottom_ui_bar.aicomponent/SKILL.md +50 -0
  67. package/skills/bottom_ui_bar.aicomponent/manifest.json +31 -0
  68. package/skills/bottom_ui_bar.aicomponent/ref/GameBottomUI.ts +27 -0
  69. package/skills/bubble_shooter.aigameplay/SKILL.md +129 -0
  70. package/skills/bubble_shooter.aigameplay/manifest.json +181 -0
  71. package/skills/bubble_shooter.aigameplay/ref/pgs-schema.json +226 -0
  72. package/skills/bubble_shooter.aigameplay/ref/reducer.template.ts +228 -0
  73. package/skills/button_click_sfx.aiaudio/SKILL.md +59 -0
  74. package/skills/button_click_sfx.aiaudio/manifest.json +45 -0
  75. package/skills/button_click_sfx.aiaudio/ref/button_click.mp3 +0 -0
  76. package/skills/calm_piano.aiaudio/SKILL.md +68 -0
  77. package/skills/calm_piano.aiaudio/manifest.json +50 -0
  78. package/skills/camera_controller_3d.aicomponent/SKILL.md +100 -0
  79. package/skills/camera_controller_3d.aicomponent/manifest.json +52 -0
  80. package/skills/camera_controller_3d.aicomponent/ref/CameraController.ts +199 -0
  81. package/skills/camera_controller_3d.aicomponent/ref/OrbitControlsAdapter.ts +152 -0
  82. package/skills/candy_tile.aiimage/SKILL.md +62 -0
  83. package/skills/candy_tile.aiimage/manifest.json +49 -0
  84. package/skills/car_parking.aigameplay/SKILL.md +105 -0
  85. package/skills/car_parking.aigameplay/manifest.json +164 -0
  86. package/skills/car_parking.aigameplay/ref/pgs-schema.json +163 -0
  87. package/skills/car_parking.aigameplay/ref/reducer.template.ts +166 -0
  88. package/skills/castle.aiimage/SKILL.md +64 -0
  89. package/skills/castle.aiimage/manifest.json +48 -0
  90. package/skills/cheerful_ukulele.aiaudio/SKILL.md +72 -0
  91. package/skills/cheerful_ukulele.aiaudio/manifest.json +50 -0
  92. package/skills/click_sfx.aiaudio/SKILL.md +59 -0
  93. package/skills/click_sfx.aiaudio/manifest.json +45 -0
  94. package/skills/click_sfx.aiaudio/ref/click.mp3 +0 -0
  95. package/skills/combo_display.aicomponent/SKILL.md +45 -0
  96. package/skills/combo_display.aicomponent/manifest.json +31 -0
  97. package/skills/combo_display.aicomponent/ref/ComboManager.ts +362 -0
  98. package/skills/combo_display.aicomponent/ref/ComboSmallUI.ts +232 -0
  99. package/skills/combo_praise_text.aicomponent/SKILL.md +56 -0
  100. package/skills/combo_praise_text.aicomponent/manifest.json +34 -0
  101. package/skills/combo_praise_text.aicomponent/ref/ComboManager.ts +362 -0
  102. package/skills/countdown_timer.aicomponent/SKILL.md +44 -0
  103. package/skills/countdown_timer.aicomponent/manifest.json +35 -0
  104. package/skills/countdown_timer.aicomponent/ref/CountdownDisplay.ts +213 -0
  105. package/skills/cta_platform_config.aiconfig/SKILL.md +72 -0
  106. package/skills/cta_platform_config.aiconfig/manifest.json +56 -0
  107. package/skills/debug_overlay.aicomponent/SKILL.md +75 -0
  108. package/skills/debug_overlay.aicomponent/manifest.json +17 -0
  109. package/skills/debug_overlay.aicomponent/ref/DebugOverlay.ts +144 -0
  110. package/skills/desert.aiimage/SKILL.md +63 -0
  111. package/skills/desert.aiimage/manifest.json +49 -0
  112. package/skills/difficulty_curve_designer.aiconfig/SKILL.md +68 -0
  113. package/skills/difficulty_curve_designer.aiconfig/manifest.json +36 -0
  114. package/skills/digit_renderer.aicomponent/SKILL.md +43 -0
  115. package/skills/digit_renderer.aicomponent/manifest.json +25 -0
  116. package/skills/digit_renderer.aicomponent/ref/DigitRenderer.ts +237 -0
  117. package/skills/download_button.aicomponent/SKILL.md +44 -0
  118. package/skills/download_button.aicomponent/manifest.json +25 -0
  119. package/skills/download_button.aicomponent/ref/DownloadButton.ts +137 -0
  120. package/skills/draw_line_puzzle.aigameplay/SKILL.md +84 -0
  121. package/skills/draw_line_puzzle.aigameplay/manifest.json +152 -0
  122. package/skills/draw_line_puzzle.aigameplay/ref/pgs-schema.json +189 -0
  123. package/skills/draw_line_puzzle.aigameplay/ref/reducer.template.ts +194 -0
  124. package/skills/easy_to_hard.aiconfig/SKILL.md +52 -0
  125. package/skills/easy_to_hard.aiconfig/manifest.json +33 -0
  126. package/skills/eight_ball_pool.aigameplay/SKILL.md +104 -0
  127. package/skills/eight_ball_pool.aigameplay/manifest.json +152 -0
  128. package/skills/eight_ball_pool.aigameplay/ref/pgs-schema.json +205 -0
  129. package/skills/eight_ball_pool.aigameplay/ref/reducer.template.ts +198 -0
  130. package/skills/energetic_electronic.aiaudio/SKILL.md +69 -0
  131. package/skills/energetic_electronic.aiaudio/manifest.json +51 -0
  132. package/skills/fail_sfx.aiaudio/SKILL.md +59 -0
  133. package/skills/fail_sfx.aiaudio/manifest.json +44 -0
  134. package/skills/fail_sfx.aiaudio/ref/fail.mp3 +0 -0
  135. package/skills/figer_icon.aiimage/SKILL.md +58 -0
  136. package/skills/figer_icon.aiimage/manifest.json +48 -0
  137. package/skills/figer_icon.aiimage/ref/figer.png +0 -0
  138. package/skills/figer_icon.aiimage/ref/figer.webp +0 -0
  139. package/skills/forest.aiimage/SKILL.md +74 -0
  140. package/skills/forest.aiimage/manifest.json +48 -0
  141. package/skills/fruit_tile.aiimage/SKILL.md +68 -0
  142. package/skills/fruit_tile.aiimage/manifest.json +48 -0
  143. package/skills/game_over_panel.aicomponent/SKILL.md +47 -0
  144. package/skills/game_over_panel.aicomponent/manifest.json +61 -0
  145. package/skills/game_over_panel.aicomponent/ref/GameOverPanel.ts +74 -0
  146. package/skills/game_scene.aicomponent/SKILL.md +57 -0
  147. package/skills/game_scene.aicomponent/manifest.json +36 -0
  148. package/skills/game_scene.aicomponent/ref/Game.ts +748 -0
  149. package/skills/gameplay_balance_check.aivalidator/SKILL.md +69 -0
  150. package/skills/gameplay_balance_check.aivalidator/manifest.json +21 -0
  151. package/skills/gameplay_unit_test.aivalidator/SKILL.md +89 -0
  152. package/skills/gameplay_unit_test.aivalidator/manifest.json +17 -0
  153. package/skills/gameplay_unit_test.aivalidator/ref/gameplay.test.ts +202 -0
  154. package/skills/gameplay_unit_test.aivalidator/ref/vitest.config.ts +13 -0
  155. package/skills/grid_board_layout.aicomponent/SKILL.md +85 -0
  156. package/skills/grid_board_layout.aicomponent/manifest.json +69 -0
  157. package/skills/grid_board_layout.aicomponent/ref/BoardLayout.ts +416 -0
  158. package/skills/grid_board_layout.aicomponent/ref/BoardLayout3D.ts +125 -0
  159. package/skills/grid_board_layout.aicomponent/ref/BoardLayoutMath.ts +85 -0
  160. package/skills/grid_board_layout.aicomponent/ref/BoardRenderer3D.ts +298 -0
  161. package/skills/heart_lives.aicomponent/SKILL.md +42 -0
  162. package/skills/heart_lives.aicomponent/manifest.json +25 -0
  163. package/skills/heart_lives.aicomponent/ref/HeartDisplay.ts +96 -0
  164. package/skills/idle-breathe.aicomponent/SKILL.md +27 -0
  165. package/skills/idle-breathe.aicomponent/manifest.json +20 -0
  166. package/skills/idle-breathe.aicomponent/ref/phaser.js +25 -0
  167. package/skills/idle-breathe.aicomponent/ref/playcanvas.js +29 -0
  168. package/skills/jewel_tile.aiimage/SKILL.md +63 -0
  169. package/skills/jewel_tile.aiimage/manifest.json +49 -0
  170. package/skills/knife_hit.aigameplay/SKILL.md +103 -0
  171. package/skills/knife_hit.aigameplay/manifest.json +151 -0
  172. package/skills/knife_hit.aigameplay/ref/pgs-schema.json +202 -0
  173. package/skills/knife_hit.aigameplay/ref/reducer.template.ts +196 -0
  174. package/skills/left_right_parkour.aigameplay/SKILL.md +120 -0
  175. package/skills/left_right_parkour.aigameplay/manifest.json +165 -0
  176. package/skills/left_right_parkour.aigameplay/ref/pgs-schema.json +200 -0
  177. package/skills/left_right_parkour.aigameplay/ref/reducer.template.ts +194 -0
  178. package/skills/level_data_pack.aiconfig/SKILL.md +64 -0
  179. package/skills/level_data_pack.aiconfig/manifest.json +37 -0
  180. package/skills/level_data_validator.aivalidator/SKILL.md +85 -0
  181. package/skills/level_data_validator.aivalidator/manifest.json +17 -0
  182. package/skills/level_data_validator.aivalidator/ref/LevelValidator.ts +113 -0
  183. package/skills/level_lifecycle.aicomponent/SKILL.md +81 -0
  184. package/skills/level_lifecycle.aicomponent/manifest.json +87 -0
  185. package/skills/level_lifecycle.aicomponent/ref/LevelLifecycle.ts +235 -0
  186. package/skills/level_solvability_validator.aivalidator/SKILL.md +74 -0
  187. package/skills/level_solvability_validator.aivalidator/manifest.json +23 -0
  188. package/skills/level_solvability_validator.aivalidator/ref/LevelValidator.ts +186 -0
  189. package/skills/level_state.aicomponent/SKILL.md +55 -0
  190. package/skills/level_state.aicomponent/manifest.json +34 -0
  191. package/skills/level_state.aicomponent/ref/LevelDataManager.ts +26 -0
  192. package/skills/level_state.aicomponent/ref/LevelManager.ts +26 -0
  193. package/skills/loading_screen.aicomponent/SKILL.md +57 -0
  194. package/skills/loading_screen.aicomponent/manifest.json +43 -0
  195. package/skills/loading_screen.aicomponent/ref/LoadingUI.ts +339 -0
  196. package/skills/lose_result_panel.aiimage/SKILL.md +58 -0
  197. package/skills/lose_result_panel.aiimage/manifest.json +47 -0
  198. package/skills/lose_result_panel.aiimage/ref/lose.png +0 -0
  199. package/skills/lose_result_panel.aiimage/ref/lose.webp +0 -0
  200. package/skills/lose_sfx.aiaudio/SKILL.md +59 -0
  201. package/skills/lose_sfx.aiaudio/manifest.json +45 -0
  202. package/skills/lose_sfx.aiaudio/ref/lose.mp3 +0 -0
  203. package/skills/match-pop.aicomponent/SKILL.md +29 -0
  204. package/skills/match-pop.aicomponent/manifest.json +19 -0
  205. package/skills/match-pop.aicomponent/ref/phaser.js +30 -0
  206. package/skills/match-pop.aicomponent/ref/playcanvas.js +22 -0
  207. package/skills/match3_core.aigameplay/SKILL.md +125 -0
  208. package/skills/match3_core.aigameplay/manifest.json +107 -0
  209. package/skills/match3_core.aigameplay/ref/pgs-schema.json +154 -0
  210. package/skills/match3_core.aigameplay/ref/reducer.template.ts +191 -0
  211. package/skills/match_engine.aicomponent/SKILL.md +84 -0
  212. package/skills/match_engine.aicomponent/manifest.json +23 -0
  213. package/skills/match_engine.aicomponent/ref/MatchEngine.ts +75 -0
  214. package/skills/memory_match.aigameplay/SKILL.md +111 -0
  215. package/skills/memory_match.aigameplay/manifest.json +164 -0
  216. package/skills/memory_match.aigameplay/ref/pgs-schema.json +190 -0
  217. package/skills/memory_match.aigameplay/ref/reducer.template.ts +162 -0
  218. package/skills/merge_core.aigameplay/SKILL.md +112 -0
  219. package/skills/merge_core.aigameplay/manifest.json +154 -0
  220. package/skills/merge_core.aigameplay/ref/pgs-schema.json +202 -0
  221. package/skills/merge_core.aigameplay/ref/reducer.template.ts +179 -0
  222. package/skills/mistake_sfx.aiaudio/SKILL.md +59 -0
  223. package/skills/mistake_sfx.aiaudio/manifest.json +45 -0
  224. package/skills/mistake_sfx.aiaudio/ref/mistake.mp3 +0 -0
  225. package/skills/nomove_hint_overlay.aiimage/SKILL.md +58 -0
  226. package/skills/nomove_hint_overlay.aiimage/manifest.json +48 -0
  227. package/skills/nomove_hint_overlay.aiimage/ref/nomove_hint.png +0 -0
  228. package/skills/nomove_hint_overlay.aiimage/ref/nomove_hint.webp +0 -0
  229. package/skills/normal_dot.aiimage/SKILL.md +58 -0
  230. package/skills/normal_dot.aiimage/manifest.json +46 -0
  231. package/skills/normal_dot.aiimage/ref/normal_dot.png +0 -0
  232. package/skills/normal_dot.aiimage/ref/normal_dot.webp +0 -0
  233. package/skills/ocean.aiimage/SKILL.md +71 -0
  234. package/skills/ocean.aiimage/manifest.json +49 -0
  235. package/skills/particle-confetti.aicomponent/SKILL.md +32 -0
  236. package/skills/particle-confetti.aicomponent/manifest.json +21 -0
  237. package/skills/particle-confetti.aicomponent/ref/html5-spritesheet.js +17 -0
  238. package/skills/particle-confetti.aicomponent/ref/phaser.js +38 -0
  239. package/skills/particle-explosion.aicomponent/SKILL.md +37 -0
  240. package/skills/particle-explosion.aicomponent/manifest.json +24 -0
  241. package/skills/particle-explosion.aicomponent/ref/html5-spritesheet.js +40 -0
  242. package/skills/particle-explosion.aicomponent/ref/phaser.js +46 -0
  243. package/skills/particle-explosion.aicomponent/ref/playcanvas.js +33 -0
  244. package/skills/particle-trail.aicomponent/SKILL.md +25 -0
  245. package/skills/particle-trail.aicomponent/manifest.json +22 -0
  246. package/skills/particle-trail.aicomponent/ref/phaser.js +31 -0
  247. package/skills/path_animation.aicomponent/SKILL.md +82 -0
  248. package/skills/path_animation.aicomponent/manifest.json +77 -0
  249. package/skills/path_animation.aicomponent/ref/AnimationManager.ts +694 -0
  250. package/skills/path_animation.aicomponent/ref/AnimationManager3D.ts +317 -0
  251. package/skills/path_elimination_rules.aigameplay/SKILL.md +88 -0
  252. package/skills/path_elimination_rules.aigameplay/manifest.json +119 -0
  253. package/skills/path_elimination_rules.aigameplay/ref/pgs-schema.json +227 -0
  254. package/skills/path_input_handler.aicomponent/SKILL.md +87 -0
  255. package/skills/path_input_handler.aicomponent/manifest.json +97 -0
  256. package/skills/path_input_handler.aicomponent/ref/InputHandler.ts +714 -0
  257. package/skills/path_input_handler.aicomponent/ref/InputHandler3D.ts +204 -0
  258. package/skills/path_renderer.aicomponent/SKILL.md +101 -0
  259. package/skills/path_renderer.aicomponent/manifest.json +69 -0
  260. package/skills/path_renderer.aicomponent/ref/PathRenderer.ts +509 -0
  261. package/skills/path_renderer.aicomponent/ref/PathRenderer3D.ts +176 -0
  262. package/skills/path_renderer.aicomponent/ref/PathRenderers.ts +640 -0
  263. package/skills/phaser.aicomponent/SKILL.md +315 -0
  264. package/skills/phaser.aicomponent/manifest.json +156 -0
  265. package/skills/phaser.aicomponent/ref/BootScene.ts +29 -0
  266. package/skills/phaser.aicomponent/ref/GameConfig.ts +29 -0
  267. package/skills/phaser.aicomponent/ref/GameScene.ts +88 -0
  268. package/skills/phaser.aicomponent/ref/PreloaderScene.ts +78 -0
  269. package/skills/phaser.aicomponent/ref/SceneKeys.ts +7 -0
  270. package/skills/phaser.aicomponent/ref/SoundUtils.ts +21 -0
  271. package/skills/phaser.aicomponent/ref/UiLayout.ts +74 -0
  272. package/skills/phaser.aicomponent/ref/globals.d.ts +52 -0
  273. package/skills/phaser.aicomponent/ref/index.css +40 -0
  274. package/skills/phaser.aicomponent/ref/index.html +14 -0
  275. package/skills/phaser.aicomponent/ref/index.ts +48 -0
  276. package/skills/phaser.aicomponent/ref/main.ts +16 -0
  277. package/skills/phaser.aicomponent/ref/package.json +22 -0
  278. package/skills/phaser.aicomponent/ref/tsconfig.json +25 -0
  279. package/skills/phaser.aicomponent/ref/webpack.config.js +57 -0
  280. package/skills/phaser_scene_lifecycle.aicomponent/SKILL.md +63 -0
  281. package/skills/phaser_scene_lifecycle.aicomponent/manifest.json +33 -0
  282. package/skills/pick_and_match_rules.aigameplay/SKILL.md +113 -0
  283. package/skills/pick_and_match_rules.aigameplay/manifest.json +121 -0
  284. package/skills/pick_and_match_rules.aigameplay/ref/pgs-schema.json +354 -0
  285. package/skills/pin_pull.aigameplay/SKILL.md +110 -0
  286. package/skills/pin_pull.aigameplay/manifest.json +164 -0
  287. package/skills/pin_pull.aigameplay/ref/pgs-schema.json +201 -0
  288. package/skills/pin_pull.aigameplay/ref/reducer.template.ts +216 -0
  289. package/skills/playable_app_logo.aiimage/SKILL.md +58 -0
  290. package/skills/playable_app_logo.aiimage/manifest.json +47 -0
  291. package/skills/playable_app_logo.aiimage/ref/logo.png +0 -0
  292. package/skills/playable_app_logo.aiimage/ref/logo.webp +0 -0
  293. package/skills/playable_end_screen_layout.aicomponent/SKILL.md +75 -0
  294. package/skills/playable_end_screen_layout.aicomponent/manifest.json +24 -0
  295. package/skills/playable_guidance_layer.aicomponent/SKILL.md +89 -0
  296. package/skills/playable_guidance_layer.aicomponent/manifest.json +24 -0
  297. package/skills/playable_hud_layout.aicomponent/SKILL.md +96 -0
  298. package/skills/playable_hud_layout.aicomponent/manifest.json +24 -0
  299. package/skills/playable_scripts_build.aicomponent/SKILL.md +69 -0
  300. package/skills/playable_scripts_build.aicomponent/manifest.json +53 -0
  301. package/skills/playable_scripts_build.aicomponent/ref/builds.config.js +257 -0
  302. package/skills/playcraft-3d-flip-sprite/SKILL.md +336 -0
  303. package/skills/playcraft-3d-flip-sprite/renderer/flatten_glb.mjs +62 -0
  304. package/skills/playcraft-3d-flip-sprite/renderer/render.mjs +325 -0
  305. package/skills/playcraft-3d-flip-sprite/renderer/render_single.mjs +138 -0
  306. package/skills/playcraft-asset-management/SKILL.md +73 -0
  307. package/skills/playcraft-audio-generation/SKILL.md +126 -0
  308. package/skills/playcraft-build/SKILL.md +44 -0
  309. package/skills/playcraft-code-editor/SKILL.md +71 -0
  310. package/skills/playcraft-create-remix/SKILL.md +62 -0
  311. package/skills/playcraft-deploy/SKILL.md +59 -0
  312. package/skills/playcraft-image-generation/SKILL.md +148 -0
  313. package/skills/playcraft-image-processing/SKILL.md +216 -0
  314. package/skills/playcraft-platform-intro/SKILL.md +41 -0
  315. package/skills/playcraft-prefab/SKILL.md +98 -0
  316. package/skills/playcraft-project-management/SKILL.md +57 -0
  317. package/skills/playcraft-remix-workflow/SKILL.md +119 -0
  318. package/skills/playcraft-remix-workflow/references/xplatform.schema.json5 +31 -0
  319. package/skills/playcraft-save/SKILL.md +46 -0
  320. package/skills/playcraft-skill-recommender/SKILL.md +152 -0
  321. package/skills/playcraft-sprite-generation/SKILL.md +534 -0
  322. package/skills/playcraft-sprite-remix/SKILL.md +155 -0
  323. package/skills/playcraft-sprite-sheet/SKILL.md +97 -0
  324. package/skills/playtest_report.aivalidator/SKILL.md +103 -0
  325. package/skills/playtest_report.aivalidator/manifest.json +21 -0
  326. package/skills/preloader_scene.aicomponent/SKILL.md +58 -0
  327. package/skills/preloader_scene.aicomponent/manifest.json +43 -0
  328. package/skills/preloader_scene.aicomponent/ref/Preloader.ts +339 -0
  329. package/skills/progress_bar.aicomponent/SKILL.md +38 -0
  330. package/skills/progress_bar.aicomponent/manifest.json +25 -0
  331. package/skills/progress_bar.aicomponent/ref/ProgressDisplay.ts +140 -0
  332. package/skills/references/xplatform.schema.json5 +31 -0
  333. package/skills/responsive_2d_layout.aicomponent/SKILL.md +161 -0
  334. package/skills/responsive_2d_layout.aicomponent/manifest.json +43 -0
  335. package/skills/responsive_2d_layout.aicomponent/ref/UiLayout.ts +56 -0
  336. package/skills/run_context_state.aicomponent/SKILL.md +54 -0
  337. package/skills/run_context_state.aicomponent/manifest.json +40 -0
  338. package/skills/run_context_state.aicomponent/ref/RunContextRuntime.ts +30 -0
  339. package/skills/score-fly.aicomponent/SKILL.md +31 -0
  340. package/skills/score-fly.aicomponent/manifest.json +21 -0
  341. package/skills/score-fly.aicomponent/ref/phaser.js +26 -0
  342. package/skills/score-fly.aicomponent/ref/playcanvas.js +28 -0
  343. package/skills/score_goal.aiconfig/SKILL.md +46 -0
  344. package/skills/score_goal.aiconfig/manifest.json +33 -0
  345. package/skills/screen-flash.aicomponent/SKILL.md +30 -0
  346. package/skills/screen-flash.aicomponent/manifest.json +20 -0
  347. package/skills/screen-flash.aicomponent/ref/phaser.js +48 -0
  348. package/skills/screen-shake.aicomponent/SKILL.md +30 -0
  349. package/skills/screen-shake.aicomponent/manifest.json +19 -0
  350. package/skills/screen-shake.aicomponent/ref/phaser.js +23 -0
  351. package/skills/screen-shake.aicomponent/ref/playcanvas.js +44 -0
  352. package/skills/screw_puzzle.aigameplay/SKILL.md +116 -0
  353. package/skills/screw_puzzle.aigameplay/manifest.json +164 -0
  354. package/skills/screw_puzzle.aigameplay/ref/pgs-schema.json +235 -0
  355. package/skills/screw_puzzle.aigameplay/ref/reducer.template.ts +213 -0
  356. package/skills/settings_state.aicomponent/SKILL.md +61 -0
  357. package/skills/settings_state.aicomponent/manifest.json +33 -0
  358. package/skills/settings_state.aicomponent/ref/SettingsManager.ts +130 -0
  359. package/skills/slide_out_to_tray_animation.aicomponent/SKILL.md +64 -0
  360. package/skills/slide_out_to_tray_animation.aicomponent/manifest.json +58 -0
  361. package/skills/slide_out_to_tray_animation.aicomponent/ref/AnimationManager.ts +164 -0
  362. package/skills/slide_out_to_tray_animation.aicomponent/ref/AnimationManager3D.ts +198 -0
  363. package/skills/slide_out_to_tray_animation.aicomponent/ref/BezierUtils.ts +59 -0
  364. package/skills/slot_machine.aigameplay/SKILL.md +119 -0
  365. package/skills/slot_machine.aigameplay/manifest.json +166 -0
  366. package/skills/slot_machine.aigameplay/ref/pgs-schema.json +212 -0
  367. package/skills/slot_machine.aigameplay/ref/reducer.template.ts +212 -0
  368. package/skills/sniper_shot.aigameplay/SKILL.md +84 -0
  369. package/skills/sniper_shot.aigameplay/manifest.json +153 -0
  370. package/skills/sniper_shot.aigameplay/ref/pgs-schema.json +211 -0
  371. package/skills/sniper_shot.aigameplay/ref/reducer.template.ts +211 -0
  372. package/skills/solitaire.aigameplay/SKILL.md +101 -0
  373. package/skills/solitaire.aigameplay/manifest.json +151 -0
  374. package/skills/solitaire.aigameplay/ref/pgs-schema.json +200 -0
  375. package/skills/solitaire.aigameplay/ref/reducer.template.ts +176 -0
  376. package/skills/sound-effects/SKILL.md +46 -0
  377. package/skills/sound_utils.aicomponent/SKILL.md +52 -0
  378. package/skills/sound_utils.aicomponent/manifest.json +30 -0
  379. package/skills/sound_utils.aicomponent/ref/SoundUtils.ts +29 -0
  380. package/skills/sprite-animation-2d.aicomponent/SKILL.md +45 -0
  381. package/skills/sprite-animation-2d.aicomponent/manifest.json +28 -0
  382. package/skills/sprite-animation-2d.aicomponent/ref/html5.js +83 -0
  383. package/skills/sprite-animation-2d.aicomponent/ref/phaser.js +38 -0
  384. package/skills/sprite-animation-2d.aicomponent/ref/playcanvas.js +67 -0
  385. package/skills/sprite_entity_renderer.aicomponent/SKILL.md +148 -0
  386. package/skills/sprite_entity_renderer.aicomponent/manifest.json +17 -0
  387. package/skills/sprite_entity_renderer.aicomponent/ref/SpriteEntityRenderer.ts +126 -0
  388. package/skills/success_sfx.aiaudio/SKILL.md +59 -0
  389. package/skills/success_sfx.aiaudio/manifest.json +45 -0
  390. package/skills/success_sfx.aiaudio/ref/success.mp3 +0 -0
  391. package/skills/tap_blast.aigameplay/SKILL.md +116 -0
  392. package/skills/tap_blast.aigameplay/manifest.json +153 -0
  393. package/skills/tap_blast.aigameplay/ref/pgs-schema.json +208 -0
  394. package/skills/tap_blast.aigameplay/ref/reducer.template.ts +202 -0
  395. package/skills/theme_state.aicomponent/SKILL.md +53 -0
  396. package/skills/theme_state.aicomponent/manifest.json +33 -0
  397. package/skills/theme_state.aicomponent/ref/ThemeManager.ts +174 -0
  398. package/skills/theme_switcher_build.aicomponent/SKILL.md +62 -0
  399. package/skills/theme_switcher_build.aicomponent/manifest.json +38 -0
  400. package/skills/theme_switcher_build.aicomponent/ref/theme-index.ts +8 -0
  401. package/skills/theme_variant.aiconfig/SKILL.md +78 -0
  402. package/skills/theme_variant.aiconfig/manifest.json +39 -0
  403. package/skills/theme_variant.aiconfig/ref/ExampleTheme/index.ts +16 -0
  404. package/skills/theme_variant.aiconfig/ref/ExampleTheme/levelEasy.json +141 -0
  405. package/skills/threejs.aicomponent/SKILL.md +422 -0
  406. package/skills/threejs.aicomponent/manifest.json +166 -0
  407. package/skills/threejs.aicomponent/ref/AssetLoader.ts +158 -0
  408. package/skills/threejs.aicomponent/ref/BaseScene.ts +88 -0
  409. package/skills/threejs.aicomponent/ref/GameConfig.ts +47 -0
  410. package/skills/threejs.aicomponent/ref/MainScene.ts +170 -0
  411. package/skills/threejs.aicomponent/ref/PreloaderScene.ts +93 -0
  412. package/skills/threejs.aicomponent/ref/SceneKeys.ts +6 -0
  413. package/skills/threejs.aicomponent/ref/SceneManager.ts +69 -0
  414. package/skills/threejs.aicomponent/ref/ViewportManager.ts +62 -0
  415. package/skills/threejs.aicomponent/ref/globals.d.ts +74 -0
  416. package/skills/threejs.aicomponent/ref/index.css +80 -0
  417. package/skills/threejs.aicomponent/ref/index.html +20 -0
  418. package/skills/threejs.aicomponent/ref/index.ts +117 -0
  419. package/skills/threejs.aicomponent/ref/main.ts +10 -0
  420. package/skills/threejs.aicomponent/ref/package.json +23 -0
  421. package/skills/threejs.aicomponent/ref/tsconfig.json +24 -0
  422. package/skills/threejs.aicomponent/ref/webpack.config.js +61 -0
  423. package/skills/time_clear_goal.aiconfig/SKILL.md +46 -0
  424. package/skills/time_clear_goal.aiconfig/manifest.json +32 -0
  425. package/skills/time_icon.aiimage/SKILL.md +58 -0
  426. package/skills/time_icon.aiimage/manifest.json +47 -0
  427. package/skills/time_icon.aiimage/ref/time.png +0 -0
  428. package/skills/time_icon.aiimage/ref/time.webp +0 -0
  429. package/skills/top_ui_bar.aicomponent/SKILL.md +45 -0
  430. package/skills/top_ui_bar.aicomponent/manifest.json +27 -0
  431. package/skills/top_ui_bar.aicomponent/ref/GameTopUI.ts +229 -0
  432. package/skills/tower_defence.aigameplay/SKILL.md +117 -0
  433. package/skills/tower_defence.aigameplay/manifest.json +175 -0
  434. package/skills/tower_defence.aigameplay/ref/pgs-schema.json +247 -0
  435. package/skills/tower_defence.aigameplay/ref/reducer.template.ts +239 -0
  436. package/skills/tray_container.aicomponent/SKILL.md +143 -0
  437. package/skills/tray_container.aicomponent/manifest.json +58 -0
  438. package/skills/tray_container.aicomponent/ref/TrayRenderer.ts +155 -0
  439. package/skills/tray_container.aicomponent/ref/TrayRenderer3D.ts +281 -0
  440. package/skills/tray_container.aicomponent/ref/TrayRendererHtmlOverlay.ts +228 -0
  441. package/skills/tutorial_overlay.aicomponent/SKILL.md +46 -0
  442. package/skills/tutorial_overlay.aicomponent/manifest.json +34 -0
  443. package/skills/tutorial_overlay.aicomponent/ref/TutorialManager.ts +367 -0
  444. package/skills/tween-animation-2d.aicomponent/SKILL.md +35 -0
  445. package/skills/tween-animation-2d.aicomponent/manifest.json +28 -0
  446. package/skills/tween-animation-2d.aicomponent/ref/phaser.js +49 -0
  447. package/skills/tween-animation-2d.aicomponent/ref/playcanvas.js +36 -0
  448. package/skills/typescript_module_patterns.aicomponent/SKILL.md +209 -0
  449. package/skills/typescript_module_patterns.aicomponent/manifest.json +28 -0
  450. package/skills/typescript_module_patterns.aicomponent/ref/globals.d.ts +31 -0
  451. package/skills/ui-transition.aicomponent/SKILL.md +33 -0
  452. package/skills/ui-transition.aicomponent/manifest.json +19 -0
  453. package/skills/ui-transition.aicomponent/ref/phaser.js +45 -0
  454. package/skills/ux_flow_spec.aiconfig/SKILL.md +82 -0
  455. package/skills/ux_flow_spec.aiconfig/manifest.json +39 -0
  456. package/skills/wave_difficulty.aiconfig/SKILL.md +46 -0
  457. package/skills/wave_difficulty.aiconfig/manifest.json +33 -0
  458. package/skills/webpack_build.aicomponent/SKILL.md +204 -0
  459. package/skills/webpack_build.aicomponent/manifest.json +29 -0
  460. package/skills/webpack_build.aicomponent/ref/package.json +16 -0
  461. package/skills/webpack_build.aicomponent/ref/webpack.config.js +53 -0
  462. package/skills/win_anim_sfx.aiaudio/SKILL.md +59 -0
  463. package/skills/win_anim_sfx.aiaudio/manifest.json +46 -0
  464. package/skills/win_anim_sfx.aiaudio/ref/win_anim.mp3 +0 -0
  465. package/skills/win_dot.aiimage/SKILL.md +58 -0
  466. package/skills/win_dot.aiimage/manifest.json +47 -0
  467. package/skills/win_dot.aiimage/ref/win_dot.png +0 -0
  468. package/skills/win_dot.aiimage/ref/win_dot.webp +0 -0
  469. package/skills/win_result_panel.aiimage/SKILL.md +58 -0
  470. package/skills/win_result_panel.aiimage/manifest.json +47 -0
  471. package/skills/win_result_panel.aiimage/ref/win.png +0 -0
  472. package/skills/win_result_panel.aiimage/ref/win.webp +0 -0
  473. package/skills/word_connect.aigameplay/SKILL.md +86 -0
  474. package/skills/word_connect.aigameplay/manifest.json +154 -0
  475. package/skills/word_connect.aigameplay/ref/pgs-schema.json +212 -0
  476. package/skills/word_connect.aigameplay/ref/reducer.template.ts +186 -0
  477. package/src/index.ts +10 -0
  478. package/src/skills.loader.ts +225 -0
  479. package/src/skills.types.ts +42 -0
@@ -0,0 +1,235 @@
1
+ {
2
+ "_comment": "PGS (PlayCraft Gameplay Schema) 参考骨架 - 螺丝拆解玩法。Agent 以此为起点编写或 fork 玩法规则。",
3
+ "version": "1.0",
4
+ "gameplayType": "screw_puzzle",
5
+ "entities": {
6
+ "board": {
7
+ "type": "layered-scene",
8
+ "layers": 3,
9
+ "description": "多层场景,每层有若干固定位置的零件槽,layer 0 为最底层"
10
+ },
11
+ "screw": {
12
+ "type": "interactive-item",
13
+ "fields": {
14
+ "id": "string",
15
+ "color": "ScrewColor (red|blue|green|yellow|purple|orange)",
16
+ "itemId": "string (所属零件)",
17
+ "holeId": "string | null (当前插入的螺孔,null 表示在缓冲区)"
18
+ },
19
+ "description": "螺丝,有颜色标记,固定零件到对应螺孔;只能被移入同色螺孔"
20
+ },
21
+ "item": {
22
+ "type": "multi-cell-object",
23
+ "fields": {
24
+ "id": "string",
25
+ "layer": "number (所在层级,越小越底层)",
26
+ "screwIds": "string[] (固定此零件的螺丝列表,全部移除后零件释放)",
27
+ "state": "ItemState (fixed|releasing|released)"
28
+ },
29
+ "description": "零件/木板,占据一个或多个格子,被若干螺丝固定,所有螺丝拆除后因重力释放"
30
+ },
31
+ "screw_hole": {
32
+ "type": "slot",
33
+ "fields": {
34
+ "id": "string",
35
+ "color": "ScrewColor",
36
+ "itemId": "string (所属零件)",
37
+ "screwId": "string | null (当前插入的螺丝)"
38
+ },
39
+ "description": "螺孔(接收槽),有颜色标记,只接受同色螺丝"
40
+ },
41
+ "buffer": {
42
+ "type": "queue",
43
+ "capacity": 3,
44
+ "description": "临时缓冲区,存放已拆但尚未插入螺孔的螺丝;超出容量且无法匹配时触发失败"
45
+ }
46
+ },
47
+ "rules": {
48
+ "remove_screw": {
49
+ "description": "玩家点击螺丝 → 螺丝从当前螺孔拔出,进入缓冲区或直接移入同色空螺孔",
50
+ "trigger": "player_tap",
51
+ "steps": [
52
+ "1. 从螺孔拔出螺丝(screwHole.screwId = null)",
53
+ "2. 查找任意一个同色且为空的螺孔(非当前零件上的)",
54
+ "3. 若找到 → 螺丝直接进入该螺孔(screwHole.screwId = screwId)",
55
+ "4. 若未找到 → 螺丝进入 buffer",
56
+ "5. buffer 中的螺丝在每次操作后尝试自动匹配空螺孔(先入先出)"
57
+ ]
58
+ },
59
+ "gravity_release": {
60
+ "description": "零件上所有螺丝均被移除 → 零件释放(下落/退出场景)",
61
+ "trigger": "item.screwIds.every(id => screwNotInHole)",
62
+ "effect": "item.state = 'releasing' → 播放下落动画 → item.state = 'released' → 从场景移除"
63
+ },
64
+ "buffer_overflow": {
65
+ "description": "缓冲区满(3 个螺丝)且当前操作的螺丝无同色空螺孔时,触发失败",
66
+ "trigger": "buffer.length >= buffer.capacity AND no_matching_hole",
67
+ "effect": "gameOver = true, win = false"
68
+ },
69
+ "cascade_match": {
70
+ "description": "每次操作结束后,缓冲区内的螺丝自动尝试匹配空螺孔并插入(先入先出)",
71
+ "trigger": "after_any_action",
72
+ "effect": "auto-fill matching screw holes from buffer"
73
+ }
74
+ },
75
+ "algorithm": {
76
+ "description": "主循环:tap_screw → remove → match_hole / buffer → release_item → gravity → win/lose 检测",
77
+ "steps": [
78
+ "1. 玩家点击目标螺丝",
79
+ "2. 检查螺丝是否可拆(当前状态合法)",
80
+ "3. 将螺丝从螺孔拔出",
81
+ "4. 查找同色空螺孔(优先非当前零件),有则直接插入,无则进入 buffer",
82
+ "5. 检查 buffer 是否已满且无法匹配 → 失败",
83
+ "6. 检查 buffer 中所有螺丝,自动匹配并插入空螺孔",
84
+ "7. 检查所有零件:若某零件的全部螺丝都已被移除(不在任何螺孔),则触发释放",
85
+ "8. 对已释放零件执行重力模拟(上层零件下移)",
86
+ "9. 检测胜利条件:所有零件 state = 'released'"
87
+ ]
88
+ },
89
+ "winCondition": {
90
+ "type": "all_items_released",
91
+ "description": "所有零件 state = 'released'(已下落退出场景)"
92
+ },
93
+ "loseCondition": {
94
+ "type": "buffer_overflow",
95
+ "description": "缓冲区已满(3 个螺丝)且当前移除的螺丝无法匹配任何空螺孔"
96
+ },
97
+ "testCases": [
98
+ {
99
+ "id": "tc_basic_remove",
100
+ "description": "基础移除:点击螺丝,直接飞入同色空螺孔,缓冲区不变",
101
+ "initialState": {
102
+ "screws": [
103
+ { "id": "s1", "color": "red", "itemId": "item1", "holeId": "h1" }
104
+ ],
105
+ "screwHoles": [
106
+ { "id": "h1", "color": "red", "itemId": "item1", "screwId": "s1" },
107
+ { "id": "h2", "color": "red", "itemId": "item2", "screwId": null }
108
+ ],
109
+ "items": [
110
+ { "id": "item1", "layer": 1, "screwIds": ["s1"], "state": "fixed" },
111
+ { "id": "item2", "layer": 0, "screwIds": [], "state": "fixed" }
112
+ ],
113
+ "buffer": []
114
+ },
115
+ "actions": [
116
+ { "type": "remove_screw", "screwId": "s1" }
117
+ ],
118
+ "expectedState": {
119
+ "screws": [
120
+ { "id": "s1", "holeId": "h2" }
121
+ ],
122
+ "screwHoles": [
123
+ { "id": "h1", "screwId": null },
124
+ { "id": "h2", "screwId": "s1" }
125
+ ],
126
+ "buffer": [],
127
+ "items": [
128
+ { "id": "item1", "state": "released" }
129
+ ],
130
+ "gameOver": false,
131
+ "win": false
132
+ }
133
+ },
134
+ {
135
+ "id": "tc_gravity_release",
136
+ "description": "重力释放:移除零件所有螺丝后,零件状态变为 releasing/released",
137
+ "initialState": {
138
+ "screws": [
139
+ { "id": "s1", "color": "blue", "itemId": "item1", "holeId": "h1" },
140
+ { "id": "s2", "color": "blue", "itemId": "item1", "holeId": "h2" }
141
+ ],
142
+ "screwHoles": [
143
+ { "id": "h1", "color": "blue", "itemId": "item1", "screwId": "s1" },
144
+ { "id": "h2", "color": "blue", "itemId": "item1", "screwId": "s2" },
145
+ { "id": "h3", "color": "blue", "itemId": "item2", "screwId": null },
146
+ { "id": "h4", "color": "blue", "itemId": "item2", "screwId": null }
147
+ ],
148
+ "items": [
149
+ { "id": "item1", "layer": 1, "screwIds": ["s1", "s2"], "state": "fixed" },
150
+ { "id": "item2", "layer": 0, "screwIds": [], "state": "released" }
151
+ ],
152
+ "buffer": []
153
+ },
154
+ "actions": [
155
+ { "type": "remove_screw", "screwId": "s1" },
156
+ { "type": "remove_screw", "screwId": "s2" }
157
+ ],
158
+ "expectedState": {
159
+ "items": [
160
+ { "id": "item1", "state": "released" }
161
+ ],
162
+ "buffer": [],
163
+ "win": true,
164
+ "gameOver": true
165
+ }
166
+ },
167
+ {
168
+ "id": "tc_color_mismatch_buffer",
169
+ "description": "颜色不匹配:螺丝无法插入异色螺孔,进入缓冲区",
170
+ "initialState": {
171
+ "screws": [
172
+ { "id": "s1", "color": "red", "itemId": "item1", "holeId": "h1" }
173
+ ],
174
+ "screwHoles": [
175
+ { "id": "h1", "color": "red", "itemId": "item1", "screwId": "s1" },
176
+ { "id": "h2", "color": "blue", "itemId": "item2", "screwId": null }
177
+ ],
178
+ "items": [
179
+ { "id": "item1", "layer": 1, "screwIds": ["s1"], "state": "fixed" },
180
+ { "id": "item2", "layer": 0, "screwIds": ["s2"], "state": "fixed" }
181
+ ],
182
+ "buffer": []
183
+ },
184
+ "actions": [
185
+ { "type": "remove_screw", "screwId": "s1" }
186
+ ],
187
+ "expectedState": {
188
+ "buffer": [{ "screwId": "s1", "color": "red" }],
189
+ "screwHoles": [
190
+ { "id": "h1", "screwId": null },
191
+ { "id": "h2", "screwId": null }
192
+ ],
193
+ "gameOver": false,
194
+ "win": false
195
+ }
196
+ },
197
+ {
198
+ "id": "tc_buffer_overflow_lose",
199
+ "description": "缓冲区溢出失败:缓冲区已满3个,再拆一颗无同色空孔的螺丝 → 失败",
200
+ "initialState": {
201
+ "screws": [
202
+ { "id": "s1", "color": "red", "itemId": "item1", "holeId": "h1" },
203
+ { "id": "s2", "color": "green", "itemId": "item2", "holeId": "h2" },
204
+ { "id": "s3", "color": "yellow", "itemId": "item3", "holeId": "h3" },
205
+ { "id": "s4", "color": "purple", "itemId": "item4", "holeId": "h4" }
206
+ ],
207
+ "screwHoles": [
208
+ { "id": "h1", "color": "red", "itemId": "item1", "screwId": "s1" },
209
+ { "id": "h2", "color": "green", "itemId": "item2", "screwId": "s2" },
210
+ { "id": "h3", "color": "yellow", "itemId": "item3", "screwId": "s3" },
211
+ { "id": "h4", "color": "purple", "itemId": "item4", "screwId": "s4" }
212
+ ],
213
+ "items": [
214
+ { "id": "item1", "layer": 2, "screwIds": ["s1"], "state": "fixed" },
215
+ { "id": "item2", "layer": 2, "screwIds": ["s2"], "state": "fixed" },
216
+ { "id": "item3", "layer": 1, "screwIds": ["s3"], "state": "fixed" },
217
+ { "id": "item4", "layer": 1, "screwIds": ["s4"], "state": "fixed" }
218
+ ],
219
+ "buffer": [
220
+ { "screwId": "sx1", "color": "orange" },
221
+ { "screwId": "sx2", "color": "orange" },
222
+ { "screwId": "sx3", "color": "orange" }
223
+ ]
224
+ },
225
+ "actions": [
226
+ { "type": "remove_screw", "screwId": "s1" }
227
+ ],
228
+ "expectedState": {
229
+ "gameOver": true,
230
+ "win": false,
231
+ "reason": "buffer_overflow"
232
+ }
233
+ }
234
+ ]
235
+ }
@@ -0,0 +1,213 @@
1
+ /**
2
+ * screw_puzzle.aigameplay — reducer 接口模板
3
+ *
4
+ * Agent 生成实际 reducer 时,必须导出以下函数。
5
+ * 此文件是接口约束模板,不是可执行代码。
6
+ *
7
+ * ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
8
+ * ⚠️ 重要:渲染层(GameScene)不应直接调用 dispatch()
9
+ *
10
+ * dispatch() 是一体化接口,内部跑完整个操作链后只返回最终状态,
11
+ * 中间过程(螺丝移动轨迹、零件释放顺序、重力下落路径)全部丢失。
12
+ *
13
+ * 渲染层需要分步动画(螺丝拔出 → 飞入螺孔 → 零件下落 → 重力压缩),
14
+ * 因此必须使用下方的「分步函数」逐步驱动,每步之间插入 Tween 动画。
15
+ *
16
+ * dispatch() 的用途:无头测试、AI 模拟、快速跳过动画等场景。
17
+ * ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
18
+ */
19
+
20
+ // ─── 配置类型 ─────────────────────────────────────────────────────────────────
21
+
22
+ export type ScrewColor = 'red' | 'blue' | 'green' | 'yellow' | 'purple' | 'orange';
23
+
24
+ export type ScrewPuzzleConfig = {
25
+ /** 场景层数,默认 3 */
26
+ layers: number;
27
+ /** 缓冲区最大容量,默认 3 */
28
+ bufferCapacity: number;
29
+ /** 初始螺丝列表 */
30
+ screws: Array<{
31
+ id: string;
32
+ color: ScrewColor;
33
+ itemId: string;
34
+ holeId: string;
35
+ }>;
36
+ /** 初始零件列表 */
37
+ items: Array<{
38
+ id: string;
39
+ layer: number;
40
+ screwIds: string[];
41
+ }>;
42
+ /** 螺孔列表 */
43
+ screwHoles: Array<{
44
+ id: string;
45
+ color: ScrewColor;
46
+ itemId: string;
47
+ }>;
48
+ };
49
+
50
+ // ─── 动作类型 ─────────────────────────────────────────────────────────────────
51
+
52
+ export type ScrewPuzzleAction =
53
+ | { type: 'remove_screw'; screwId: string }
54
+ | { type: 'reset' };
55
+
56
+ // ─── 状态类型 ─────────────────────────────────────────────────────────────────
57
+
58
+ export type ItemState = 'fixed' | 'releasing' | 'released';
59
+
60
+ export type ScrewState = {
61
+ id: string;
62
+ color: ScrewColor;
63
+ itemId: string;
64
+ /** 当前所在螺孔 id,null 表示在缓冲区 */
65
+ holeId: string | null;
66
+ };
67
+
68
+ export type ItemRecord = {
69
+ id: string;
70
+ layer: number;
71
+ screwIds: string[];
72
+ state: ItemState;
73
+ };
74
+
75
+ export type ScrewHoleRecord = {
76
+ id: string;
77
+ color: ScrewColor;
78
+ itemId: string;
79
+ /** 当前插入的螺丝 id,null 表示空闲 */
80
+ screwId: string | null;
81
+ };
82
+
83
+ export type ScrewPuzzleState = {
84
+ screws: Record<string, ScrewState>;
85
+ items: Record<string, ItemRecord>;
86
+ screwHoles: Record<string, ScrewHoleRecord>;
87
+ /** 缓冲区中的螺丝 id 列表(先入先出) */
88
+ buffer: string[];
89
+ /** 游戏是否结束 */
90
+ gameOver: boolean;
91
+ /** 是否胜利 */
92
+ win: boolean;
93
+ /** 失败原因 */
94
+ loseReason?: 'buffer_overflow' | 'deadlock';
95
+ };
96
+
97
+ // ─── 分步操作返回类型 ─────────────────────────────────────────────────────────
98
+
99
+ /** 螺丝移动信息(用于驱动飞行动画) */
100
+ export type ScrewMove = {
101
+ screwId: string;
102
+ color: ScrewColor;
103
+ /** 来源螺孔 id */
104
+ fromHoleId: string;
105
+ /** 目标螺孔 id,null 表示进入缓冲区 */
106
+ toHoleId: string | null;
107
+ /** 是否直接入孔(true = 直接匹配;false = 先入缓冲再匹配) */
108
+ directMatch: boolean;
109
+ };
110
+
111
+ /** 缓冲区自动匹配结果 */
112
+ export type BufferAutoMatch = {
113
+ screwId: string;
114
+ toHoleId: string;
115
+ };
116
+
117
+ /** 零件释放信息(用于驱动下落动画) */
118
+ export type ReleasedItem = {
119
+ itemId: string;
120
+ layer: number;
121
+ };
122
+
123
+ /** 重力压缩:上方零件下移 */
124
+ export type FallMove = {
125
+ itemId: string;
126
+ fromLayer: number;
127
+ toLayer: number;
128
+ };
129
+
130
+ // ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
131
+ // 必须导出的函数
132
+ // ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
133
+
134
+ // ─── 初始化 ──────────────────────────────────────────────────────────────────
135
+
136
+ /**
137
+ * init:根据配置初始化游戏状态
138
+ */
139
+ export declare function init(config: ScrewPuzzleConfig): ScrewPuzzleState;
140
+
141
+ // ─── 一体化接口(测试/AI 模拟用) ───────────────────────────────────────────
142
+
143
+ /**
144
+ * dispatch:接收动作,返回新状态(纯函数,不得修改原 state)
145
+ * - remove_screw:移除螺丝,触发匹配、零件释放、重力(一步到位)
146
+ * - reset:重置到初始状态
147
+ *
148
+ * ⚠️ 仅用于无头测试和 AI 模拟。渲染层请使用下方分步函数。
149
+ */
150
+ export declare function dispatch(state: ScrewPuzzleState, action: ScrewPuzzleAction): ScrewPuzzleState;
151
+
152
+ /**
153
+ * getState:返回当前状态快照
154
+ */
155
+ export declare function getState(state: ScrewPuzzleState): ScrewPuzzleState;
156
+
157
+ // ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
158
+ // 分步函数(渲染层/场景层必须使用这些函数驱动动画)
159
+ // ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
160
+
161
+ /**
162
+ * canRemoveScrew:检查指定螺丝是否可以被拆除
163
+ * - 螺丝必须存在且当前插在某螺孔中(不在缓冲区)
164
+ * - 游戏未结束
165
+ *
166
+ * 场景层在玩家点击时调用:false → 播放禁止/摇晃提示
167
+ */
168
+ export declare function canRemoveScrew(state: ScrewPuzzleState, screwId: string): boolean;
169
+
170
+ /**
171
+ * removeScrew:执行螺丝拆除操作
172
+ * 返回更新后的状态及螺丝移动轨迹(含缓冲区自动匹配结果)
173
+ *
174
+ * 场景层根据 screwMove 和 bufferAutoMatches 分别播放:
175
+ * - 螺丝旋转拔出动画
176
+ * - 螺丝飞向目标螺孔或飞入缓冲区动画
177
+ * - 缓冲区螺丝自动飞入匹配螺孔动画
178
+ */
179
+ export declare function removeScrew(
180
+ state: ScrewPuzzleState,
181
+ screwId: string,
182
+ ): {
183
+ newState: ScrewPuzzleState;
184
+ screwMove: ScrewMove;
185
+ bufferAutoMatches: BufferAutoMatch[];
186
+ overflowed: boolean;
187
+ };
188
+
189
+ /**
190
+ * checkItemRelease:检查哪些零件在当前状态下满足释放条件(所有螺丝均已离开螺孔)
191
+ * 返回待释放零件列表
192
+ *
193
+ * 场景层根据 ReleasedItem[] 播放零件下落动画
194
+ */
195
+ export declare function checkItemRelease(
196
+ state: ScrewPuzzleState,
197
+ changedItemIds?: string[],
198
+ ): ReleasedItem[];
199
+
200
+ /**
201
+ * applyGravity:在若干零件释放后,计算上方零件向下压缩的位移
202
+ * 返回需要移动的零件列表
203
+ *
204
+ * 场景层根据 FallMove[] 播放零件向下移动动画
205
+ */
206
+ export declare function applyGravity(state: ScrewPuzzleState): FallMove[];
207
+
208
+ /**
209
+ * findValidMoves:返回当前所有合法可拆螺丝的 id 列表
210
+ * 场景层可用此函数高亮可操作螺丝(引导提示)
211
+ * 若返回空数组且游戏未结束,则为死锁
212
+ */
213
+ export declare function findValidMoves(state: ScrewPuzzleState): string[];
@@ -0,0 +1,61 @@
1
+ ---
2
+ name: settings_state.aicomponent
3
+ description: 用户设置状态管理器。管理音乐/音效开关和拖拽速度倍率等用户偏好,提供 get/set 接口供其他组件读取。
4
+ triggers: 需要管理用户音频设置、拖拽速度等游戏偏好设置时触发。
5
+ ---
6
+
7
+ # 用户设置状态(Settings State)
8
+
9
+ ## 说明
10
+
11
+ `SettingsManager` 管理用户偏好设置:
12
+
13
+ - `soundOn` / `musicOn`:音效/音乐开关
14
+ - `getDragSpeedMultiplier()`:拖拽棋盘速度倍率(0.5~1.5)
15
+
16
+ ## Scaffold
17
+
18
+ | 目标路径 | 来源 |
19
+ |---------|-----|
20
+ | `src/game/scenes/GameUI/SettingsManager.ts` | `ref/SettingsManager.ts` |
21
+
22
+ ## Skill Definition
23
+
24
+ ```yaml
25
+ tools:
26
+ - read_file
27
+ - write_file
28
+ inputs:
29
+ - source: src/game/scenes/GameUI/SettingsManager.ts
30
+ outputs:
31
+ - settingsManager: SettingsManager class
32
+ ```
33
+
34
+ ## Imports
35
+
36
+ - `phaser.aicomponent`(硬依赖)
37
+
38
+ ## Recipe
39
+
40
+ | 决策 | 原因 |
41
+ |------|------|
42
+ | **独立 Manager 而非分散状态** | 多个组件(SoundUtils、InputHandler)需要读取同一份偏好设置;集中在 SettingsManager 避免重复读取和不一致 |
43
+ | **轮询而非事件订阅** | 音效开关在播放时检查即可,拖拽速度在每帧输入处理时读取;轮询模式实现更简单,偏好变化低频 |
44
+
45
+ ## Adapter
46
+
47
+ - **Role**: `settingsState` — 用户偏好设置管理器(音效/音乐开关、拖拽速度)
48
+ - **Provides**: `SettingsManager` 类(`soundOn`、`musicOn`、`getDragSpeedMultiplier()`)
49
+ - **Requires**: `phaser.aicomponent`(硬依赖)
50
+ - **Consumed by**: `sound_utils.aicomponent`(检查 `soundOn` 决定是否播放)、`path_input_handler.aicomponent`(读取拖拽速度倍率)、`game_scene.aicomponent`(持有实例并传递给子系统)
51
+ - **Integration point**: `src/game/scenes/GameUI/SettingsManager.ts` —— `game_scene` 初始化后传递给需要的子系统
52
+
53
+ ## 关键接口
54
+
55
+ ```typescript
56
+ class SettingsManager {
57
+ soundOn: boolean;
58
+ musicOn: boolean;
59
+ getDragSpeedMultiplier(): number;
60
+ }
61
+ ```
@@ -0,0 +1,33 @@
1
+ {
2
+ "schemaVersion": 1,
3
+ "atomId": "settings_state.aicomponent",
4
+ "bundleType": "aicomponent",
5
+ "category": "state",
6
+ "mode": "fixed",
7
+ "label": { "zh": "用户设置状态管理", "en": "User settings state manager" },
8
+ "tags": ["state", "settings", "music", "sound", "drag-speed", "preferences"],
9
+ "bindingRoles": ["userSettings"],
10
+ "scaffold": {
11
+ "files": {
12
+ "src/game/scenes/GameUI/SettingsManager.ts": {
13
+ "source": "ref/SettingsManager.ts",
14
+ "mode": "full",
15
+ "weight": 10
16
+ }
17
+ }
18
+ },
19
+ "imports": [
20
+ { "slot": "engine", "pinAtomId": "phaser.aicomponent", "edgeKind": "requires", "bindAs": "engine" }
21
+ ],
22
+ "exports": [
23
+ { "name": "SettingsManager", "kind": "class", "location": "src/game/scenes/GameUI/SettingsManager.ts" }
24
+ ],
25
+ "neutralDescriptor": {
26
+ "geometry": "persistent user preferences store: audio toggles and drag speed multiplier",
27
+ "layers": ["state-management", "user-preferences"]
28
+ },
29
+ "files": {
30
+ "skill": "SKILL.md",
31
+ "settingsManager": "ref/SettingsManager.ts"
32
+ }
33
+ }
@@ -0,0 +1,130 @@
1
+ import * as Phaser from "phaser";
2
+ import {
3
+ DRAG_SPEED_MIN_MULTIPLIER,
4
+ DRAG_SPEED_MAX_MULTIPLIER,
5
+ } from "../../GameConfig";
6
+ import { safePlaySound } from "../../utils/SoundUtils";
7
+ import { ENABLE_BACKGROUND_MUSIC } from "../../DebugConfig";
8
+
9
+ /** 拖拽速度值类型,范围 0.0 ~ 1.0 */
10
+ export type DragSpeedValue = number;
11
+
12
+ /**
13
+ * 设置管理器(单例)。
14
+ * 管理音乐、音效开关、拖拽速度和背景音乐播放。
15
+ */
16
+ export class SettingsManager {
17
+ private static _instance: SettingsManager | null = null;
18
+
19
+ public musicOn = true;
20
+ public soundOn = true;
21
+ /** 拖拽速度:0.0 = 慢, 1.0 = 快 */
22
+ public dragSpeed: DragSpeedValue = 0.5;
23
+ private bgm: Phaser.Sound.BaseSound | null = null;
24
+ private isBgmLoading = false;
25
+
26
+ static get instance(): SettingsManager {
27
+ if (!this._instance) {
28
+ this._instance = new SettingsManager();
29
+ }
30
+ return this._instance;
31
+ }
32
+
33
+ private constructor() {}
34
+
35
+ /**
36
+ * 播放按钮点击音效。
37
+ * @param scene 当前场景
38
+ */
39
+ public playButtonClick(scene: Phaser.Scene) {
40
+ if (!this.soundOn) return;
41
+ safePlaySound(scene, "button_click", { volume: 0.8 });
42
+ }
43
+
44
+ /**
45
+ * 播放背景音乐。如果音频尚未加载,会动态加载后再播放。
46
+ * @param scene 当前场景
47
+ */
48
+ public playBgm(scene: Phaser.Scene) {
49
+ // 如果配置禁用背景音乐,直接返回
50
+ if (!ENABLE_BACKGROUND_MUSIC) {
51
+ return;
52
+ }
53
+
54
+ if (!this.musicOn) {
55
+ this.stopBgm();
56
+ return;
57
+ }
58
+
59
+ const soundManager = scene.sound;
60
+
61
+ /** 开始播放背景音乐 */
62
+ const startPlay = () => {
63
+ if (!this.musicOn) {
64
+ return;
65
+ }
66
+ if (!this.bgm) {
67
+ this.bgm = soundManager.add("bg");
68
+ }
69
+ if (!this.bgm) {
70
+ return;
71
+ }
72
+ this.bgm.stop();
73
+ this.bgm.play({ loop: true, volume: 0.45 });
74
+ };
75
+
76
+ // 如果音频已经在缓存中,直接播放
77
+ if (scene.cache.audio.exists("bg")) {
78
+ startPlay();
79
+ return;
80
+ }
81
+
82
+ // 尚未加载且已经在加载中:避免重复发起请求
83
+ if (this.isBgmLoading) {
84
+ return;
85
+ }
86
+
87
+ // 动态加载 bg.mp3,加载完成后根据当前开关决定是否播放
88
+ this.isBgmLoading = true;
89
+ scene.load.once(Phaser.Loader.Events.COMPLETE, () => {
90
+ this.isBgmLoading = false;
91
+ if (this.musicOn) {
92
+ startPlay();
93
+ }
94
+ });
95
+ scene.load.start();
96
+ }
97
+
98
+ /** 停止背景音乐 */
99
+ public stopBgm() {
100
+ if (this.bgm) {
101
+ this.bgm.stop();
102
+ }
103
+ }
104
+
105
+ /**
106
+ * 将当前的音乐/音效设置应用到指定场景的声音系统。
107
+ * 通过 mute / volume 控制整体开关。
108
+ * @param scene 当前场景
109
+ */
110
+ public applyToSceneSound(scene: Phaser.Scene) {
111
+ const soundManager = scene.sound;
112
+ // musicOn 控制全局背景音乐是否允许播放;这里用 mute 简单实现
113
+ soundManager.mute = !this.soundOn && !this.musicOn;
114
+ }
115
+
116
+ /**
117
+ * 根据 dragSpeed(0~1)返回拖拽速度倍率:
118
+ * - dragSpeed = 0 -> 最小倍率
119
+ * - dragSpeed = 0.5 -> 默认速度
120
+ * - dragSpeed = 1 -> 最大倍率
121
+ * @returns 拖拽速度倍率
122
+ */
123
+ public getDragSpeedMultiplier(): number {
124
+ const t = Phaser.Math.Clamp(this.dragSpeed, 0, 1);
125
+ const factor =
126
+ DRAG_SPEED_MIN_MULTIPLIER +
127
+ t * (DRAG_SPEED_MAX_MULTIPLIER - DRAG_SPEED_MIN_MULTIPLIER);
128
+ return factor;
129
+ }
130
+ }