unreal-engine-mcp-server 0.5.0 → 0.5.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 (188) hide show
  1. package/.env.example +1 -1
  2. package/.github/release-drafter-config.yml +51 -0
  3. package/.github/workflows/greetings.yml +5 -1
  4. package/.github/workflows/labeler.yml +2 -1
  5. package/.github/workflows/publish-mcp.yml +2 -4
  6. package/.github/workflows/release-drafter.yml +3 -2
  7. package/.github/workflows/release.yml +3 -3
  8. package/CHANGELOG.md +109 -0
  9. package/CONTRIBUTING.md +1 -1
  10. package/GEMINI.md +115 -0
  11. package/Public/Plugin_setup_guide.mp4 +0 -0
  12. package/README.md +166 -200
  13. package/dist/automation/bridge.d.ts +1 -2
  14. package/dist/automation/bridge.js +24 -23
  15. package/dist/automation/connection-manager.d.ts +1 -0
  16. package/dist/automation/connection-manager.js +10 -0
  17. package/dist/automation/message-handler.js +5 -4
  18. package/dist/automation/request-tracker.d.ts +4 -0
  19. package/dist/automation/request-tracker.js +11 -3
  20. package/dist/config.d.ts +0 -1
  21. package/dist/config.js +0 -1
  22. package/dist/constants.d.ts +4 -0
  23. package/dist/constants.js +4 -0
  24. package/dist/graphql/loaders.d.ts +64 -0
  25. package/dist/graphql/loaders.js +117 -0
  26. package/dist/graphql/resolvers.d.ts +3 -3
  27. package/dist/graphql/resolvers.js +33 -30
  28. package/dist/graphql/server.js +3 -1
  29. package/dist/graphql/types.d.ts +2 -0
  30. package/dist/index.d.ts +2 -0
  31. package/dist/index.js +13 -2
  32. package/dist/server-setup.d.ts +0 -1
  33. package/dist/server-setup.js +0 -40
  34. package/dist/tools/actors.d.ts +58 -24
  35. package/dist/tools/actors.js +22 -6
  36. package/dist/tools/assets.d.ts +19 -71
  37. package/dist/tools/assets.js +28 -22
  38. package/dist/tools/base-tool.d.ts +4 -4
  39. package/dist/tools/base-tool.js +1 -1
  40. package/dist/tools/blueprint.d.ts +45 -61
  41. package/dist/tools/blueprint.js +43 -14
  42. package/dist/tools/consolidated-tool-definitions.js +2 -1
  43. package/dist/tools/consolidated-tool-handlers.js +96 -110
  44. package/dist/tools/dynamic-handler-registry.d.ts +11 -9
  45. package/dist/tools/dynamic-handler-registry.js +17 -95
  46. package/dist/tools/editor.d.ts +19 -193
  47. package/dist/tools/editor.js +11 -2
  48. package/dist/tools/environment.d.ts +8 -14
  49. package/dist/tools/foliage.d.ts +18 -143
  50. package/dist/tools/foliage.js +4 -2
  51. package/dist/tools/handlers/actor-handlers.d.ts +1 -1
  52. package/dist/tools/handlers/actor-handlers.js +14 -13
  53. package/dist/tools/handlers/asset-handlers.js +454 -454
  54. package/dist/tools/handlers/sequence-handlers.d.ts +1 -1
  55. package/dist/tools/handlers/sequence-handlers.js +24 -13
  56. package/dist/tools/introspection.d.ts +1 -1
  57. package/dist/tools/introspection.js +1 -1
  58. package/dist/tools/landscape.d.ts +16 -116
  59. package/dist/tools/landscape.js +7 -3
  60. package/dist/tools/level.d.ts +22 -103
  61. package/dist/tools/level.js +26 -18
  62. package/dist/tools/lighting.d.ts +54 -7
  63. package/dist/tools/lighting.js +9 -5
  64. package/dist/tools/materials.d.ts +1 -1
  65. package/dist/tools/materials.js +5 -1
  66. package/dist/tools/niagara.js +37 -2
  67. package/dist/tools/performance.d.ts +0 -1
  68. package/dist/tools/performance.js +0 -1
  69. package/dist/tools/physics.js +5 -1
  70. package/dist/tools/sequence.d.ts +24 -24
  71. package/dist/tools/sequence.js +13 -0
  72. package/dist/tools/ui.d.ts +0 -2
  73. package/dist/types/automation-responses.d.ts +115 -0
  74. package/dist/types/automation-responses.js +2 -0
  75. package/dist/types/responses.d.ts +249 -0
  76. package/dist/types/responses.js +2 -0
  77. package/dist/types/tool-interfaces.d.ts +135 -135
  78. package/dist/types/tool-types.d.ts +2 -0
  79. package/dist/unreal-bridge.js +4 -4
  80. package/dist/utils/command-validator.js +7 -5
  81. package/dist/utils/error-handler.d.ts +24 -2
  82. package/dist/utils/error-handler.js +58 -23
  83. package/dist/utils/normalize.d.ts +7 -4
  84. package/dist/utils/normalize.js +12 -10
  85. package/dist/utils/path-security.d.ts +2 -0
  86. package/dist/utils/path-security.js +24 -0
  87. package/dist/utils/response-factory.d.ts +4 -4
  88. package/dist/utils/response-factory.js +15 -21
  89. package/dist/utils/response-validator.js +88 -73
  90. package/dist/utils/unreal-command-queue.d.ts +2 -0
  91. package/dist/utils/unreal-command-queue.js +8 -1
  92. package/docs/Migration-Guide-v0.5.0.md +1 -9
  93. package/docs/handler-mapping.md +4 -2
  94. package/docs/testing-guide.md +2 -2
  95. package/package.json +12 -6
  96. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridgeSubsystem.cpp +298 -33
  97. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_AnimationHandlers.cpp +7 -8
  98. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_BlueprintGraphHandlers.cpp +229 -319
  99. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_BlueprintHandlers.cpp +98 -0
  100. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_EffectHandlers.cpp +24 -0
  101. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_EnvironmentHandlers.cpp +96 -0
  102. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_LightingHandlers.cpp +52 -5
  103. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_ProcessRequest.cpp +5 -268
  104. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_SequenceHandlers.cpp +57 -2
  105. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpConnectionManager.cpp +0 -1
  106. package/scripts/run-all-tests.mjs +25 -20
  107. package/server.json +3 -2
  108. package/src/automation/bridge.ts +27 -25
  109. package/src/automation/connection-manager.ts +18 -0
  110. package/src/automation/message-handler.ts +33 -8
  111. package/src/automation/request-tracker.ts +39 -7
  112. package/src/config.ts +1 -1
  113. package/src/constants.ts +7 -0
  114. package/src/graphql/loaders.ts +244 -0
  115. package/src/graphql/resolvers.ts +47 -49
  116. package/src/graphql/server.ts +3 -1
  117. package/src/graphql/types.ts +3 -0
  118. package/src/index.ts +15 -2
  119. package/src/resources/assets.ts +5 -4
  120. package/src/server/tool-registry.ts +3 -3
  121. package/src/server-setup.ts +3 -37
  122. package/src/tools/actors.ts +77 -44
  123. package/src/tools/animation.ts +1 -0
  124. package/src/tools/assets.ts +76 -65
  125. package/src/tools/base-tool.ts +3 -3
  126. package/src/tools/blueprint.ts +170 -104
  127. package/src/tools/consolidated-tool-definitions.ts +2 -1
  128. package/src/tools/consolidated-tool-handlers.ts +129 -150
  129. package/src/tools/dynamic-handler-registry.ts +22 -140
  130. package/src/tools/editor.ts +43 -29
  131. package/src/tools/environment.ts +21 -27
  132. package/src/tools/foliage.ts +28 -25
  133. package/src/tools/handlers/actor-handlers.ts +16 -17
  134. package/src/tools/handlers/asset-handlers.ts +484 -484
  135. package/src/tools/handlers/sequence-handlers.ts +85 -62
  136. package/src/tools/introspection.ts +7 -7
  137. package/src/tools/landscape.ts +34 -28
  138. package/src/tools/level.ts +100 -80
  139. package/src/tools/lighting.ts +25 -20
  140. package/src/tools/materials.ts +9 -3
  141. package/src/tools/niagara.ts +44 -2
  142. package/src/tools/performance.ts +1 -2
  143. package/src/tools/physics.ts +7 -1
  144. package/src/tools/sequence.ts +42 -26
  145. package/src/tools/ui.ts +1 -3
  146. package/src/types/automation-responses.ts +119 -0
  147. package/src/types/responses.ts +355 -0
  148. package/src/types/tool-interfaces.ts +135 -135
  149. package/src/types/tool-types.ts +4 -0
  150. package/src/unreal-bridge.ts +71 -26
  151. package/src/utils/command-validator.ts +47 -5
  152. package/src/utils/error-handler.ts +128 -45
  153. package/src/utils/normalize.test.ts +162 -0
  154. package/src/utils/normalize.ts +38 -16
  155. package/src/utils/path-security.ts +43 -0
  156. package/src/utils/response-factory.ts +29 -24
  157. package/src/utils/response-validator.ts +103 -87
  158. package/src/utils/safe-json.test.ts +90 -0
  159. package/src/utils/unreal-command-queue.ts +13 -1
  160. package/src/utils/validation.test.ts +184 -0
  161. package/tests/test-animation.mjs +358 -33
  162. package/tests/test-asset-graph.mjs +311 -0
  163. package/tests/test-audio.mjs +314 -116
  164. package/tests/test-behavior-tree.mjs +327 -144
  165. package/tests/test-blueprint-graph.mjs +343 -12
  166. package/tests/test-control-editor.mjs +85 -53
  167. package/tests/test-graphql.mjs +58 -8
  168. package/tests/test-input.mjs +349 -0
  169. package/tests/test-inspect.mjs +291 -61
  170. package/tests/test-landscape.mjs +304 -48
  171. package/tests/test-lighting.mjs +428 -0
  172. package/tests/test-manage-level.mjs +70 -51
  173. package/tests/test-performance.mjs +539 -0
  174. package/tests/test-sequence.mjs +82 -46
  175. package/tests/test-system.mjs +72 -33
  176. package/tests/test-wasm.mjs +98 -8
  177. package/vitest.config.ts +35 -0
  178. package/.github/release-drafter.yml +0 -148
  179. package/dist/prompts/index.d.ts +0 -21
  180. package/dist/prompts/index.js +0 -217
  181. package/dist/tools/blueprint/helpers.d.ts +0 -29
  182. package/dist/tools/blueprint/helpers.js +0 -182
  183. package/src/prompts/index.ts +0 -249
  184. package/src/tools/blueprint/helpers.ts +0 -189
  185. package/tests/test-blueprint-events.mjs +0 -35
  186. package/tests/test-extra-tools.mjs +0 -38
  187. package/tests/test-render.mjs +0 -33
  188. package/tests/test-search-assets.mjs +0 -66
@@ -1,44 +1,369 @@
1
1
  #!/usr/bin/env node
2
2
  /**
3
- * Condensed Animation & Physics Test Suite (15 cases) — safe operations.
3
+ * Comprehensive Animation & Physics Test Suite
4
4
  * Tool: animation_physics
5
+ * Coverage: All 15 actions with success, error, and edge cases
5
6
  */
6
7
 
7
8
  import { runToolTests } from './test-runner.mjs';
8
9
 
10
+ // Use the tutorial skeleton that comes with UE
11
+ const tutorialSkeleton = '/Engine/Tutorial/SubEditors/TutorialAssets/Character/TutorialTPP_Skeleton';
12
+
9
13
  const testCases = [
10
- { scenario: 'Create simple animation blueprint (best-effort)', toolName: 'animation_physics', arguments: { action: 'create_animation_bp', name: 'ABP_TC', skeletonPath: '/Engine/Tutorial/SubEditors/TutorialAssets/Character/TutorialTPP_Skeleton', savePath: '/Game/Animations' }, expected: 'success or not found' },
11
- { scenario: 'Play montage (no-op safe)', toolName: 'animation_physics', arguments: { action: 'play_montage', actorName: 'SkeletalCharacter', montagePath: '/Game/Animations/AM_Test', playRate: 1.0 }, expected: 'success or not found' },
12
- { scenario: 'Setup ragdoll (best-effort)', toolName: 'animation_physics', arguments: { action: 'setup_ragdoll', skeletonPath: '/Engine/Tutorial/SubEditors/TutorialAssets/Character/TutorialTPP_Skeleton', actorName: 'RagdollCharacter', physicsAssetName: 'PA_Mannequin', blendWeight: 1.0 }, expected: 'success or not found' },
13
- { scenario: 'Create blend space (safe)', toolName: 'animation_physics', arguments: { action: 'create_blend_space', name: 'TC_Locomotion', skeletonPath: '/Engine/Tutorial/SubEditors/TutorialAssets/Character/TutorialTPP_Skeleton', horizontalAxis: { name: 'Speed', minValue: 0, maxValue: 100 }, verticalAxis: { name: 'Direction', minValue: -180, maxValue: 180 }, animations: [] }, expected: 'success - blend space created' },
14
- { scenario: 'Create state machine skeleton', toolName: 'animation_physics', arguments: { action: 'create_state_machine', machineName: 'TC_States', states: [{ name: 'Idle' }, { name: 'Run' }], transitions: [] }, expected: 'success' },
15
- { scenario: 'Create simple IK setup', toolName: 'animation_physics', arguments: { action: 'setup_ik', actorName: 'Character', chain: { rootBone: 'pelvis', endBone: 'foot_l' }, effector: { targetActor: 'TargetActor' } }, expected: 'success' },
16
- { scenario: 'Create procedural animation', toolName: 'animation_physics', arguments: { action: 'create_procedural_anim', systemName: 'TC_Procedural', baseAnimation: '/Game/Animations/BasePose', settings: {} }, expected: 'success' },
17
- { scenario: 'Create animation blueprint minimal', toolName: 'animation_physics', arguments: { action: 'create_animation_bp', blueprintName: 'TC_AnimBP', parentClass: 'AnimInstance', targetSkeleton: '/Engine/Tutorial/SubEditors/TutorialAssets/Character/TutorialTPP_Skeleton', stateMachines: [] }, expected: 'success or not found' },
18
- // { scenario: 'Activate ragdoll trigger (no-op)', toolName: 'animation_physics', arguments: { action: 'activate_ragdoll', actorName: 'Character', blendTime: 0.2 }, expected: 'success' },
19
- { scenario: 'Create blend tree', toolName: 'animation_physics', arguments: { action: 'create_blend_tree', treeName: 'TC_UpperBody', basePose: '/Game/Animations/BasePose', additiveAnimations: [] }, expected: 'success' },
20
- { scenario: 'Create simple animation asset', toolName: 'animation_physics', arguments: { action: 'create_animation_asset', name: 'ANIM_TC', skeletonPath: '/Engine/Tutorial/SubEditors/TutorialAssets/Character/TutorialTPP_Skeleton', savePath: '/Game/Animations', assetType: 'sequence' }, expected: 'success or not found' },
21
-
22
- // PRE-CLEANUP: Ensure target doesn't exist to avoid "DuplicateAsset failed"
23
- { scenario: 'Pre-cleanup Retargeted asset', toolName: 'manage_asset', arguments: { action: 'delete_asset', assetPath: '/Game/Animations/Retargeted/ANIM_TC_Retargeted' }, expected: 'success|not_found|error' },
24
-
25
- { scenario: 'Retargeting sequence (best-effort)', toolName: 'animation_physics', arguments: { action: 'setup_retargeting', sourceSkeleton: '/Engine/Tutorial/SubEditors/TutorialAssets/Character/TutorialTPP_Skeleton', targetSkeleton: '/Engine/Tutorial/SubEditors/TutorialAssets/Character/TutorialTPP_Skeleton', assets: ['/Game/Animations/ANIM_TC'], savePath: '/Game/Animations/Retargeted', overwrite: true }, expected: 'success or not connected or not found' },
26
- { scenario: 'Setup physics simulation (best-effort)', toolName: 'animation_physics', arguments: { action: 'setup_physics_simulation', skeletonPath: '/Engine/Tutorial/SubEditors/TutorialAssets/Character/TutorialTPP_Skeleton', savePath: '/Game/Physics', physicsAssetName: 'PA_TC', assignToMesh: false }, expected: 'success or not found' },
27
- { scenario: 'Play and stop a short montage (best-effort)', toolName: 'animation_physics', arguments: { action: 'play_montage', actorName: 'SkeletalCharacter', montagePath: '/Game/Animations/AM_Test', playRate: 1.0 }, expected: 'success or not found' },
28
-
29
- { scenario: 'Anim Setup - Create Montage', toolName: 'animation_physics', arguments: { action: 'create_animation_asset', name: 'AM_Setup', skeletonPath: '/Engine/Tutorial/SubEditors/TutorialAssets/Character/TutorialTPP_Skeleton', savePath: '/Game/Animations', assetType: 'montage' }, expected: 'success or not found' },
30
- { scenario: 'Anim Setup - Add Notify', toolName: 'animation_physics', arguments: { action: 'add_notify', assetPath: '/Game/Animations/AM_Setup', notifyName: 'AnimNotify_PlaySound', time: 0.5 }, expected: 'success or not found or AUTOMATION_BRIDGE_UNAVAILABLE' },
31
-
32
- // Edge cases
33
- { scenario: 'Error: Invalid skeleton path', toolName: 'animation_physics', arguments: { action: 'create_animation_asset', assetName: 'InvalidAnim', skeletonPath: '/Game/Invalid/Skeleton' }, expected: 'error|asset_not_found' },
34
- { scenario: 'Edge: Play rate 0 (pause)', toolName: 'animation_physics', arguments: { action: 'play_montage', actorName: 'SkeletalCharacter', montagePath: '/Game/Animations/AM_Setup', playRate: 0 }, expected: 'success|no_op' },
35
- { scenario: 'Border: Negative RPM vehicle', toolName: 'animation_physics', arguments: { action: 'configure_vehicle', vehicleName: 'TestVehicle', maxRPM: -1000 }, expected: 'success|clamped' },
36
- { scenario: 'Error: Empty wheels array', toolName: 'animation_physics', arguments: { action: 'configure_vehicle', vehicleName: 'TestVehicle', wheels: [] }, expected: 'success|default_wheels' },
37
- { scenario: 'Edge: No plugin deps', toolName: 'animation_physics', arguments: { action: 'configure_vehicle', vehicleName: 'TestVehicle', plugins: ['InvalidPlugin'] }, expected: 'error|plugin_missing|MISSING_ENGINE_PLUGINS' },
38
-
39
- // FINAL CLEANUP
40
- { scenario: 'Cleanup all animation artifacts', toolName: 'animation_physics', arguments: { action: 'cleanup', artifacts: ['ABP_TC', 'TC_AnimBP', 'ANIM_TC', 'AM_Setup', 'TC_Locomotion', 'PA_TC', 'TC_States', 'TC_UpperBody'] }, expected: 'success or no matching' },
41
- { scenario: 'Cleanup retargeted asset', toolName: 'manage_asset', arguments: { action: 'delete_asset', assetPath: '/Game/Animations/Retargeted/ANIM_TC_Retargeted' }, expected: 'success|not_found' }
14
+ // === PRE-CLEANUP ===
15
+ {
16
+ scenario: 'Pre-cleanup animation artifacts',
17
+ toolName: 'animation_physics',
18
+ arguments: { action: 'cleanup', filter: 'TC_*' },
19
+ expected: 'success|no matching'
20
+ },
21
+
22
+ // === CREATE ANIMATION BLUEPRINT ===
23
+ {
24
+ scenario: 'Create Animation Blueprint',
25
+ toolName: 'animation_physics',
26
+ arguments: {
27
+ action: 'create_animation_bp',
28
+ name: 'TC_ABP_Character',
29
+ skeletonPath: tutorialSkeleton,
30
+ savePath: '/Game/Animations'
31
+ },
32
+ expected: 'success or not found'
33
+ },
34
+ {
35
+ scenario: 'Create Animation Blueprint (minimal)',
36
+ toolName: 'animation_physics',
37
+ arguments: {
38
+ action: 'create_animation_bp',
39
+ name: 'TC_ABP_Minimal',
40
+ skeletonPath: tutorialSkeleton,
41
+ savePath: '/Game/Animations',
42
+ stateMachines: []
43
+ },
44
+ expected: 'success or not found'
45
+ },
46
+
47
+ // === CREATE ANIMATION ASSET ===
48
+ {
49
+ scenario: 'Create Animation Sequence',
50
+ toolName: 'animation_physics',
51
+ arguments: {
52
+ action: 'create_animation_asset',
53
+ name: 'TC_Anim_Sequence',
54
+ skeletonPath: tutorialSkeleton,
55
+ savePath: '/Game/Animations',
56
+ assetType: 'sequence'
57
+ },
58
+ expected: 'success or not found'
59
+ },
60
+ {
61
+ scenario: 'Create Animation Montage',
62
+ toolName: 'animation_physics',
63
+ arguments: {
64
+ action: 'create_animation_asset',
65
+ name: 'TC_Anim_Montage',
66
+ skeletonPath: tutorialSkeleton,
67
+ savePath: '/Game/Animations',
68
+ assetType: 'montage'
69
+ },
70
+ expected: 'success or not found'
71
+ },
72
+
73
+ // === ADD NOTIFY ===
74
+ {
75
+ scenario: 'Add Notify to Montage',
76
+ toolName: 'animation_physics',
77
+ arguments: {
78
+ action: 'add_notify',
79
+ assetPath: '/Game/Animations/TC_Anim_Montage',
80
+ notifyName: 'AnimNotify_PlaySound',
81
+ time: 0.5
82
+ },
83
+ expected: 'success or not found or AUTOMATION_BRIDGE_UNAVAILABLE'
84
+ },
85
+ {
86
+ scenario: 'Add Second Notify',
87
+ toolName: 'animation_physics',
88
+ arguments: {
89
+ action: 'add_notify',
90
+ assetPath: '/Game/Animations/TC_Anim_Montage',
91
+ notifyName: 'AnimNotify_PlayParticleEffect',
92
+ time: 1.0
93
+ },
94
+ expected: 'success or not found'
95
+ },
96
+
97
+ // === PLAY MONTAGE ===
98
+ {
99
+ scenario: 'Play Montage',
100
+ toolName: 'animation_physics',
101
+ arguments: {
102
+ action: 'play_montage',
103
+ actorName: 'SkeletalCharacter',
104
+ montagePath: '/Game/Animations/TC_Anim_Montage',
105
+ playRate: 1.0
106
+ },
107
+ expected: 'success or not found'
108
+ },
109
+ {
110
+ scenario: 'Play Montage (slow)',
111
+ toolName: 'animation_physics',
112
+ arguments: {
113
+ action: 'play_montage',
114
+ actorName: 'SkeletalCharacter',
115
+ montagePath: '/Game/Animations/TC_Anim_Montage',
116
+ playRate: 0.5
117
+ },
118
+ expected: 'success or not found'
119
+ },
120
+
121
+ // === CREATE BLEND SPACE ===
122
+ {
123
+ scenario: 'Create Blend Space 1D',
124
+ toolName: 'animation_physics',
125
+ arguments: {
126
+ action: 'create_blend_space',
127
+ name: 'TC_BS_Locomotion',
128
+ skeletonPath: tutorialSkeleton,
129
+ savePath: '/Game/Animations',
130
+ horizontalAxis: { name: 'Speed', minValue: 0, maxValue: 600 },
131
+ animations: []
132
+ },
133
+ expected: 'success - blend space created'
134
+ },
135
+ {
136
+ scenario: 'Create Blend Space 2D',
137
+ toolName: 'animation_physics',
138
+ arguments: {
139
+ action: 'create_blend_space',
140
+ name: 'TC_BS_Movement',
141
+ skeletonPath: tutorialSkeleton,
142
+ savePath: '/Game/Animations',
143
+ horizontalAxis: { name: 'Speed', minValue: 0, maxValue: 600 },
144
+ verticalAxis: { name: 'Direction', minValue: -180, maxValue: 180 },
145
+ animations: []
146
+ },
147
+ expected: 'success'
148
+ },
149
+
150
+ // === CREATE STATE MACHINE ===
151
+ {
152
+ scenario: 'Create State Machine',
153
+ toolName: 'animation_physics',
154
+ arguments: {
155
+ action: 'create_state_machine',
156
+ machineName: 'TC_StateMachine',
157
+ states: [{ name: 'Idle' }, { name: 'Walk' }, { name: 'Run' }, { name: 'Jump' }],
158
+ transitions: []
159
+ },
160
+ expected: 'success'
161
+ },
162
+
163
+ // === CREATE BLEND TREE ===
164
+ {
165
+ scenario: 'Create Blend Tree',
166
+ toolName: 'animation_physics',
167
+ arguments: {
168
+ action: 'create_blend_tree',
169
+ treeName: 'TC_BlendTree',
170
+ basePose: '/Game/Animations/TC_Anim_Sequence',
171
+ additiveAnimations: []
172
+ },
173
+ expected: 'success'
174
+ },
175
+
176
+ // === SETUP IK ===
177
+ {
178
+ scenario: 'Setup IK (Foot)',
179
+ toolName: 'animation_physics',
180
+ arguments: {
181
+ action: 'setup_ik',
182
+ actorName: 'Character',
183
+ chain: { rootBone: 'pelvis', endBone: 'foot_l' },
184
+ effector: { targetActor: 'TargetActor' }
185
+ },
186
+ expected: 'success'
187
+ },
188
+ {
189
+ scenario: 'Setup IK (Hand)',
190
+ toolName: 'animation_physics',
191
+ arguments: {
192
+ action: 'setup_ik',
193
+ actorName: 'Character',
194
+ chain: { rootBone: 'spine_01', endBone: 'hand_r' },
195
+ effector: { targetActor: 'HandTarget' }
196
+ },
197
+ expected: 'success'
198
+ },
199
+
200
+ // === CREATE PROCEDURAL ANIM ===
201
+ {
202
+ scenario: 'Create Procedural Animation',
203
+ toolName: 'animation_physics',
204
+ arguments: {
205
+ action: 'create_procedural_anim',
206
+ systemName: 'TC_ProceduralAnim',
207
+ baseAnimation: '/Game/Animations/TC_Anim_Sequence',
208
+ settings: {}
209
+ },
210
+ expected: 'success'
211
+ },
212
+
213
+ // === RAGDOLL ===
214
+ {
215
+ scenario: 'Setup Ragdoll',
216
+ toolName: 'animation_physics',
217
+ arguments: {
218
+ action: 'setup_ragdoll',
219
+ skeletonPath: tutorialSkeleton,
220
+ actorName: 'RagdollCharacter',
221
+ physicsAssetName: 'TC_PhysicsAsset',
222
+ blendWeight: 1.0
223
+ },
224
+ expected: 'success or not found'
225
+ },
226
+ {
227
+ scenario: 'Activate Ragdoll',
228
+ toolName: 'animation_physics',
229
+ arguments: {
230
+ action: 'activate_ragdoll',
231
+ actorName: 'RagdollCharacter',
232
+ blendTime: 0.2
233
+ },
234
+ expected: 'success|not_found'
235
+ },
236
+
237
+ // === PHYSICS SIMULATION ===
238
+ {
239
+ scenario: 'Setup Physics Simulation',
240
+ toolName: 'animation_physics',
241
+ arguments: {
242
+ action: 'setup_physics_simulation',
243
+ skeletonPath: tutorialSkeleton,
244
+ savePath: '/Game/Physics',
245
+ physicsAssetName: 'TC_PhysAsset',
246
+ assignToMesh: false
247
+ },
248
+ expected: 'success or not found'
249
+ },
250
+
251
+ // === CONFIGURE VEHICLE ===
252
+ {
253
+ scenario: 'Configure Vehicle (4 wheels)',
254
+ toolName: 'animation_physics',
255
+ arguments: {
256
+ action: 'configure_vehicle',
257
+ vehicleName: 'TC_Vehicle',
258
+ vehicleType: 'FourWheel'
259
+ },
260
+ expected: 'success|handled'
261
+ },
262
+ {
263
+ scenario: 'Configure Vehicle (custom)',
264
+ toolName: 'animation_physics',
265
+ arguments: {
266
+ action: 'configure_vehicle',
267
+ vehicleName: 'TC_Vehicle',
268
+ maxRPM: 6000,
269
+ wheels: []
270
+ },
271
+ expected: 'success|default_wheels'
272
+ },
273
+
274
+ // === RETARGETING ===
275
+ {
276
+ scenario: 'Pre-cleanup Retargeted asset',
277
+ toolName: 'manage_asset',
278
+ arguments: { action: 'delete', assetPaths: ['/Game/Animations/Retargeted/TC_Anim_Retargeted'] },
279
+ expected: 'success|not_found|error'
280
+ },
281
+ {
282
+ scenario: 'Setup Retargeting',
283
+ toolName: 'animation_physics',
284
+ arguments: {
285
+ action: 'setup_retargeting',
286
+ sourceSkeleton: tutorialSkeleton,
287
+ targetSkeleton: tutorialSkeleton,
288
+ assets: ['/Game/Animations/TC_Anim_Sequence'],
289
+ savePath: '/Game/Animations/Retargeted',
290
+ overwrite: true
291
+ },
292
+ expected: 'success or not connected or not found'
293
+ },
294
+
295
+ // === ERROR CASES ===
296
+ {
297
+ scenario: 'Error: Invalid skeleton path',
298
+ toolName: 'animation_physics',
299
+ arguments: {
300
+ action: 'create_animation_asset',
301
+ name: 'InvalidAnim',
302
+ skeletonPath: '/Game/Invalid/Skeleton',
303
+ assetType: 'sequence'
304
+ },
305
+ expected: 'error|asset_not_found'
306
+ },
307
+ {
308
+ scenario: 'Error: Play rate 0 (pause)',
309
+ toolName: 'animation_physics',
310
+ arguments: {
311
+ action: 'play_montage',
312
+ actorName: 'SkeletalCharacter',
313
+ montagePath: '/Game/Animations/TC_Anim_Montage',
314
+ playRate: 0
315
+ },
316
+ expected: 'success|no_op'
317
+ },
318
+ {
319
+ scenario: 'Error: Negative RPM vehicle',
320
+ toolName: 'animation_physics',
321
+ arguments: {
322
+ action: 'configure_vehicle',
323
+ vehicleName: 'TestVehicle',
324
+ maxRPM: -1000
325
+ },
326
+ expected: 'success|clamped'
327
+ },
328
+ {
329
+ scenario: 'Error: Invalid plugin deps',
330
+ toolName: 'animation_physics',
331
+ arguments: {
332
+ action: 'configure_vehicle',
333
+ vehicleName: 'TestVehicle',
334
+ plugins: ['InvalidPlugin']
335
+ },
336
+ expected: 'error|plugin_missing|MISSING_ENGINE_PLUGINS'
337
+ },
338
+
339
+ // === CLEANUP ===
340
+ {
341
+ scenario: 'Cleanup all animation artifacts',
342
+ toolName: 'animation_physics',
343
+ arguments: {
344
+ action: 'cleanup',
345
+ filter: 'TC_*'
346
+ },
347
+ expected: 'success or no matching'
348
+ },
349
+ {
350
+ scenario: 'Cleanup animation assets',
351
+ toolName: 'manage_asset',
352
+ arguments: {
353
+ action: 'delete',
354
+ assetPaths: [
355
+ '/Game/Animations/TC_ABP_Character',
356
+ '/Game/Animations/TC_ABP_Minimal',
357
+ '/Game/Animations/TC_Anim_Sequence',
358
+ '/Game/Animations/TC_Anim_Montage',
359
+ '/Game/Animations/TC_BS_Locomotion',
360
+ '/Game/Animations/TC_BS_Movement',
361
+ '/Game/Animations/Retargeted',
362
+ '/Game/Physics/TC_PhysAsset'
363
+ ]
364
+ },
365
+ expected: 'success|not_found'
366
+ }
42
367
  ];
43
368
 
44
369
  await runToolTests('Animation & Physics', testCases);