unreal-engine-mcp-server 0.5.0 → 0.5.1

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 (139) 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 +1 -0
  6. package/.github/workflows/release-drafter.yml +1 -1
  7. package/.github/workflows/release.yml +3 -3
  8. package/CHANGELOG.md +71 -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/config.d.ts +0 -1
  14. package/dist/config.js +0 -1
  15. package/dist/constants.d.ts +4 -0
  16. package/dist/constants.js +4 -0
  17. package/dist/graphql/loaders.d.ts +64 -0
  18. package/dist/graphql/loaders.js +117 -0
  19. package/dist/graphql/resolvers.d.ts +3 -3
  20. package/dist/graphql/resolvers.js +33 -30
  21. package/dist/graphql/server.js +3 -1
  22. package/dist/graphql/types.d.ts +2 -0
  23. package/dist/index.d.ts +2 -0
  24. package/dist/index.js +13 -2
  25. package/dist/server-setup.d.ts +0 -1
  26. package/dist/server-setup.js +0 -40
  27. package/dist/tools/actors.d.ts +40 -24
  28. package/dist/tools/actors.js +8 -2
  29. package/dist/tools/assets.d.ts +19 -71
  30. package/dist/tools/assets.js +28 -22
  31. package/dist/tools/base-tool.d.ts +4 -4
  32. package/dist/tools/base-tool.js +1 -1
  33. package/dist/tools/blueprint.d.ts +33 -61
  34. package/dist/tools/consolidated-tool-handlers.js +96 -110
  35. package/dist/tools/dynamic-handler-registry.d.ts +11 -9
  36. package/dist/tools/dynamic-handler-registry.js +17 -95
  37. package/dist/tools/editor.d.ts +19 -193
  38. package/dist/tools/editor.js +8 -0
  39. package/dist/tools/environment.d.ts +8 -14
  40. package/dist/tools/foliage.d.ts +18 -143
  41. package/dist/tools/foliage.js +4 -2
  42. package/dist/tools/handlers/actor-handlers.js +0 -5
  43. package/dist/tools/handlers/asset-handlers.js +454 -454
  44. package/dist/tools/landscape.d.ts +16 -116
  45. package/dist/tools/landscape.js +7 -3
  46. package/dist/tools/level.d.ts +22 -103
  47. package/dist/tools/level.js +24 -16
  48. package/dist/tools/lighting.js +5 -1
  49. package/dist/tools/materials.js +5 -1
  50. package/dist/tools/niagara.js +37 -2
  51. package/dist/tools/performance.d.ts +0 -1
  52. package/dist/tools/performance.js +0 -1
  53. package/dist/tools/physics.js +5 -1
  54. package/dist/tools/sequence.d.ts +24 -24
  55. package/dist/tools/sequence.js +13 -0
  56. package/dist/tools/ui.d.ts +0 -2
  57. package/dist/types/automation-responses.d.ts +115 -0
  58. package/dist/types/automation-responses.js +2 -0
  59. package/dist/types/responses.d.ts +249 -0
  60. package/dist/types/responses.js +2 -0
  61. package/dist/types/tool-interfaces.d.ts +135 -135
  62. package/dist/utils/command-validator.js +3 -2
  63. package/dist/utils/path-security.d.ts +2 -0
  64. package/dist/utils/path-security.js +24 -0
  65. package/dist/utils/response-factory.d.ts +4 -4
  66. package/dist/utils/response-factory.js +15 -21
  67. package/docs/Migration-Guide-v0.5.0.md +1 -9
  68. package/docs/testing-guide.md +2 -2
  69. package/package.json +12 -6
  70. package/scripts/run-all-tests.mjs +25 -20
  71. package/server.json +3 -2
  72. package/src/config.ts +1 -1
  73. package/src/constants.ts +7 -0
  74. package/src/graphql/loaders.ts +244 -0
  75. package/src/graphql/resolvers.ts +47 -49
  76. package/src/graphql/server.ts +3 -1
  77. package/src/graphql/types.ts +3 -0
  78. package/src/index.ts +15 -2
  79. package/src/resources/assets.ts +5 -4
  80. package/src/server-setup.ts +3 -37
  81. package/src/tools/actors.ts +36 -28
  82. package/src/tools/animation.ts +1 -0
  83. package/src/tools/assets.ts +74 -63
  84. package/src/tools/base-tool.ts +3 -3
  85. package/src/tools/blueprint.ts +59 -59
  86. package/src/tools/consolidated-tool-handlers.ts +129 -150
  87. package/src/tools/dynamic-handler-registry.ts +22 -140
  88. package/src/tools/editor.ts +39 -26
  89. package/src/tools/environment.ts +21 -27
  90. package/src/tools/foliage.ts +28 -25
  91. package/src/tools/handlers/actor-handlers.ts +2 -8
  92. package/src/tools/handlers/asset-handlers.ts +484 -484
  93. package/src/tools/handlers/sequence-handlers.ts +1 -1
  94. package/src/tools/landscape.ts +34 -28
  95. package/src/tools/level.ts +96 -76
  96. package/src/tools/lighting.ts +6 -1
  97. package/src/tools/materials.ts +8 -2
  98. package/src/tools/niagara.ts +44 -2
  99. package/src/tools/performance.ts +1 -2
  100. package/src/tools/physics.ts +7 -1
  101. package/src/tools/sequence.ts +41 -25
  102. package/src/tools/ui.ts +0 -2
  103. package/src/types/automation-responses.ts +119 -0
  104. package/src/types/responses.ts +355 -0
  105. package/src/types/tool-interfaces.ts +135 -135
  106. package/src/utils/command-validator.ts +3 -2
  107. package/src/utils/normalize.test.ts +162 -0
  108. package/src/utils/path-security.ts +43 -0
  109. package/src/utils/response-factory.ts +29 -24
  110. package/src/utils/safe-json.test.ts +90 -0
  111. package/src/utils/validation.test.ts +184 -0
  112. package/tests/test-animation.mjs +358 -33
  113. package/tests/test-asset-graph.mjs +311 -0
  114. package/tests/test-audio.mjs +314 -116
  115. package/tests/test-behavior-tree.mjs +327 -144
  116. package/tests/test-blueprint-graph.mjs +343 -12
  117. package/tests/test-control-editor.mjs +85 -53
  118. package/tests/test-graphql.mjs +58 -8
  119. package/tests/test-input.mjs +349 -0
  120. package/tests/test-inspect.mjs +291 -61
  121. package/tests/test-landscape.mjs +304 -48
  122. package/tests/test-lighting.mjs +428 -0
  123. package/tests/test-manage-level.mjs +70 -51
  124. package/tests/test-performance.mjs +539 -0
  125. package/tests/test-sequence.mjs +82 -46
  126. package/tests/test-system.mjs +72 -33
  127. package/tests/test-wasm.mjs +98 -8
  128. package/vitest.config.ts +35 -0
  129. package/.github/release-drafter.yml +0 -148
  130. package/dist/prompts/index.d.ts +0 -21
  131. package/dist/prompts/index.js +0 -217
  132. package/dist/tools/blueprint/helpers.d.ts +0 -29
  133. package/dist/tools/blueprint/helpers.js +0 -182
  134. package/src/prompts/index.ts +0 -249
  135. package/src/tools/blueprint/helpers.ts +0 -189
  136. package/tests/test-blueprint-events.mjs +0 -35
  137. package/tests/test-extra-tools.mjs +0 -38
  138. package/tests/test-render.mjs +0 -33
  139. package/tests/test-search-assets.mjs +0 -66
@@ -0,0 +1,428 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Comprehensive Lighting Management Test Suite
4
+ * Tool: manage_lighting
5
+ * Coverage: All 14 actions with success, error, and edge cases
6
+ */
7
+
8
+ import { runToolTests } from './test-runner.mjs';
9
+
10
+ const testCases = [
11
+ // === PRE-CLEANUP ===
12
+ {
13
+ scenario: 'Pre-cleanup test actors',
14
+ toolName: 'control_actor',
15
+ arguments: { action: 'delete_by_tag', tag: 'TC_Lighting' },
16
+ expected: 'success|not_found'
17
+ },
18
+
19
+ // === SPAWN LIGHTS (spawn_light, create_light) ===
20
+ {
21
+ scenario: 'Spawn Point Light',
22
+ toolName: 'manage_lighting',
23
+ arguments: {
24
+ action: 'spawn_light',
25
+ lightType: 'Point',
26
+ name: 'TC_PointLight_1',
27
+ location: { x: 0, y: 0, z: 200 },
28
+ intensity: 5000,
29
+ color: [1, 1, 1]
30
+ },
31
+ expected: 'success'
32
+ },
33
+ {
34
+ scenario: 'Create Point Light (alias)',
35
+ toolName: 'manage_lighting',
36
+ arguments: {
37
+ action: 'create_light',
38
+ lightType: 'Point',
39
+ name: 'TC_PointLight_2',
40
+ location: { x: 200, y: 0, z: 200 },
41
+ intensity: 8000,
42
+ radius: 1000
43
+ },
44
+ expected: 'success'
45
+ },
46
+ {
47
+ scenario: 'Spawn Directional Light',
48
+ toolName: 'manage_lighting',
49
+ arguments: {
50
+ action: 'spawn_light',
51
+ lightType: 'Directional',
52
+ name: 'TC_DirLight',
53
+ rotation: { pitch: -45, yaw: 0, roll: 0 },
54
+ intensity: 3.0,
55
+ useAsAtmosphereSunLight: true
56
+ },
57
+ expected: 'success'
58
+ },
59
+ {
60
+ scenario: 'Spawn Spot Light',
61
+ toolName: 'manage_lighting',
62
+ arguments: {
63
+ action: 'spawn_light',
64
+ lightType: 'Spot',
65
+ name: 'TC_SpotLight',
66
+ location: { x: 0, y: 200, z: 300 },
67
+ rotation: { pitch: -90, yaw: 0, roll: 0 },
68
+ intensity: 10000,
69
+ innerCone: 22,
70
+ outerCone: 45
71
+ },
72
+ expected: 'success'
73
+ },
74
+ {
75
+ scenario: 'Spawn Rect Light',
76
+ toolName: 'manage_lighting',
77
+ arguments: {
78
+ action: 'spawn_light',
79
+ lightType: 'Rect',
80
+ name: 'TC_RectLight',
81
+ location: { x: 100, y: 100, z: 200 },
82
+ intensity: 15000,
83
+ width: 100,
84
+ height: 50
85
+ },
86
+ expected: 'success'
87
+ },
88
+
89
+ // === SKY LIGHTS (spawn_sky_light, create_sky_light, ensure_single_sky_light) ===
90
+ {
91
+ scenario: 'Spawn Sky Light',
92
+ toolName: 'manage_lighting',
93
+ arguments: {
94
+ action: 'spawn_sky_light',
95
+ name: 'TC_SkyLight_1',
96
+ location: { x: 0, y: 0, z: 500 },
97
+ intensity: 1.0,
98
+ sourceType: 'CapturedScene'
99
+ },
100
+ expected: 'success'
101
+ },
102
+ {
103
+ scenario: 'Create Sky Light (alias)',
104
+ toolName: 'manage_lighting',
105
+ arguments: {
106
+ action: 'create_sky_light',
107
+ name: 'TC_SkyLight_2',
108
+ intensity: 0.8,
109
+ recapture: true
110
+ },
111
+ expected: 'success'
112
+ },
113
+ {
114
+ scenario: 'Ensure Single Sky Light',
115
+ toolName: 'manage_lighting',
116
+ arguments: {
117
+ action: 'ensure_single_sky_light',
118
+ intensity: 1.2
119
+ },
120
+ expected: 'success'
121
+ },
122
+
123
+ // === VOLUMES (create_lightmass_volume) ===
124
+ {
125
+ scenario: 'Create Lightmass Volume',
126
+ toolName: 'manage_lighting',
127
+ arguments: {
128
+ action: 'create_lightmass_volume',
129
+ name: 'TC_LightmassVolume',
130
+ location: { x: 0, y: 0, z: 0 },
131
+ size: { x: 2000, y: 2000, z: 1000 }
132
+ },
133
+ expected: 'success'
134
+ },
135
+
136
+ // === LEVEL SETUP (create_lighting_enabled_level, create_dynamic_light) ===
137
+ {
138
+ scenario: 'Create Lighting Enabled Level',
139
+ toolName: 'manage_lighting',
140
+ arguments: {
141
+ action: 'create_lighting_enabled_level',
142
+ levelName: 'TC_LightingLevel',
143
+ useTemplate: true
144
+ },
145
+ expected: 'success'
146
+ },
147
+ {
148
+ scenario: 'Create Dynamic Light',
149
+ toolName: 'manage_lighting',
150
+ arguments: {
151
+ action: 'create_dynamic_light',
152
+ name: 'TC_DynamicLight',
153
+ lightType: 'Point',
154
+ location: { x: 300, y: 300, z: 150 },
155
+ intensity: 7000,
156
+ castShadows: true
157
+ },
158
+ expected: 'success'
159
+ },
160
+
161
+ // === GLOBAL ILLUMINATION (setup_global_illumination) ===
162
+ {
163
+ scenario: 'Setup GI - Lumen',
164
+ toolName: 'manage_lighting',
165
+ arguments: {
166
+ action: 'setup_global_illumination',
167
+ method: 'LumenGI',
168
+ bounces: 3,
169
+ indirectLightingIntensity: 1.2
170
+ },
171
+ expected: 'success'
172
+ },
173
+ {
174
+ scenario: 'Setup GI - Lightmass',
175
+ toolName: 'manage_lighting',
176
+ arguments: {
177
+ action: 'setup_global_illumination',
178
+ method: 'Lightmass',
179
+ bounces: 2
180
+ },
181
+ expected: 'success'
182
+ },
183
+ {
184
+ scenario: 'Setup GI - Screen Space',
185
+ toolName: 'manage_lighting',
186
+ arguments: {
187
+ action: 'setup_global_illumination',
188
+ method: 'ScreenSpace'
189
+ },
190
+ expected: 'success'
191
+ },
192
+
193
+ // === SHADOWS (configure_shadows) ===
194
+ {
195
+ scenario: 'Configure Shadows - High Quality',
196
+ toolName: 'manage_lighting',
197
+ arguments: {
198
+ action: 'configure_shadows',
199
+ shadowQuality: 'High',
200
+ cascadedShadows: true,
201
+ contactShadows: true,
202
+ rayTracedShadows: false
203
+ },
204
+ expected: 'success'
205
+ },
206
+ {
207
+ scenario: 'Configure Shadows - Ray Traced',
208
+ toolName: 'manage_lighting',
209
+ arguments: {
210
+ action: 'configure_shadows',
211
+ rayTracedShadows: true,
212
+ shadowDistance: 5000
213
+ },
214
+ expected: 'success|not_supported'
215
+ },
216
+
217
+ // === EXPOSURE (set_exposure) ===
218
+ {
219
+ scenario: 'Set Exposure Auto',
220
+ toolName: 'manage_lighting',
221
+ arguments: {
222
+ action: 'set_exposure',
223
+ minBrightness: 0.5,
224
+ maxBrightness: 2.0,
225
+ compensationValue: 0
226
+ },
227
+ expected: 'success'
228
+ },
229
+ {
230
+ scenario: 'Set Exposure Manual',
231
+ toolName: 'manage_lighting',
232
+ arguments: {
233
+ action: 'set_exposure',
234
+ minBrightness: 1.0,
235
+ maxBrightness: 1.0,
236
+ compensationValue: 1.5
237
+ },
238
+ expected: 'success'
239
+ },
240
+
241
+ // === AMBIENT OCCLUSION (set_ambient_occlusion) ===
242
+ {
243
+ scenario: 'Enable Ambient Occlusion',
244
+ toolName: 'manage_lighting',
245
+ arguments: {
246
+ action: 'set_ambient_occlusion',
247
+ enabled: true
248
+ },
249
+ expected: 'success'
250
+ },
251
+ {
252
+ scenario: 'Disable Ambient Occlusion',
253
+ toolName: 'manage_lighting',
254
+ arguments: {
255
+ action: 'set_ambient_occlusion',
256
+ enabled: false
257
+ },
258
+ expected: 'success'
259
+ },
260
+
261
+ // === VOLUMETRIC FOG (setup_volumetric_fog) ===
262
+ {
263
+ scenario: 'Setup Volumetric Fog',
264
+ toolName: 'manage_lighting',
265
+ arguments: {
266
+ action: 'setup_volumetric_fog',
267
+ enabled: true,
268
+ density: 0.02,
269
+ scatteringIntensity: 0.5,
270
+ fogHeight: 500
271
+ },
272
+ expected: 'success'
273
+ },
274
+ {
275
+ scenario: 'Disable Volumetric Fog',
276
+ toolName: 'manage_lighting',
277
+ arguments: {
278
+ action: 'setup_volumetric_fog',
279
+ enabled: false
280
+ },
281
+ expected: 'success'
282
+ },
283
+
284
+ // === BUILD LIGHTING ===
285
+ {
286
+ scenario: 'Build Lighting - Preview',
287
+ toolName: 'manage_lighting',
288
+ arguments: {
289
+ action: 'build_lighting',
290
+ quality: 'Preview'
291
+ },
292
+ expected: 'success'
293
+ },
294
+ {
295
+ scenario: 'Build Lighting - Medium',
296
+ toolName: 'manage_lighting',
297
+ arguments: {
298
+ action: 'build_lighting',
299
+ quality: 'Medium',
300
+ buildOnlySelected: false
301
+ },
302
+ expected: 'success'
303
+ },
304
+
305
+ // === REAL-WORLD SCENARIO: Day/Night Setup ===
306
+ {
307
+ scenario: 'Scene Setup - Create Sun',
308
+ toolName: 'manage_lighting',
309
+ arguments: {
310
+ action: 'spawn_light',
311
+ lightType: 'Directional',
312
+ name: 'TC_Sun',
313
+ rotation: { pitch: -60, yaw: 45, roll: 0 },
314
+ intensity: 5.0,
315
+ temperature: 6500,
316
+ useAsAtmosphereSunLight: true
317
+ },
318
+ expected: 'success'
319
+ },
320
+ {
321
+ scenario: 'Scene Setup - Create Sky',
322
+ toolName: 'manage_lighting',
323
+ arguments: {
324
+ action: 'ensure_single_sky_light',
325
+ intensity: 1.0
326
+ },
327
+ expected: 'success'
328
+ },
329
+ {
330
+ scenario: 'Scene Setup - Configure GI',
331
+ toolName: 'manage_lighting',
332
+ arguments: {
333
+ action: 'setup_global_illumination',
334
+ method: 'LumenGI',
335
+ bounces: 2
336
+ },
337
+ expected: 'success'
338
+ },
339
+
340
+ // === ERROR CASES ===
341
+ {
342
+ scenario: 'Error: Invalid Light Type',
343
+ toolName: 'manage_lighting',
344
+ arguments: {
345
+ action: 'spawn_light',
346
+ lightType: 'InvalidLightType',
347
+ name: 'TC_InvalidLight'
348
+ },
349
+ expected: 'error|unknown_type'
350
+ },
351
+ {
352
+ scenario: 'Error: Invalid GI Method',
353
+ toolName: 'manage_lighting',
354
+ arguments: {
355
+ action: 'setup_global_illumination',
356
+ method: 'InvalidMethod'
357
+ },
358
+ expected: 'error|unknown_method'
359
+ },
360
+ {
361
+ scenario: 'Error: Invalid Build Quality',
362
+ toolName: 'manage_lighting',
363
+ arguments: {
364
+ action: 'build_lighting',
365
+ quality: 'InvalidQuality'
366
+ },
367
+ expected: 'error|unknown_quality'
368
+ },
369
+
370
+ // === EDGE CASES ===
371
+ {
372
+ scenario: 'Edge: Zero Intensity Light',
373
+ toolName: 'manage_lighting',
374
+ arguments: {
375
+ action: 'spawn_light',
376
+ lightType: 'Point',
377
+ name: 'TC_ZeroIntensity',
378
+ location: { x: 0, y: 0, z: 0 },
379
+ intensity: 0
380
+ },
381
+ expected: 'success'
382
+ },
383
+ {
384
+ scenario: 'Edge: Negative Intensity Light',
385
+ toolName: 'manage_lighting',
386
+ arguments: {
387
+ action: 'spawn_light',
388
+ lightType: 'Point',
389
+ name: 'TC_NegIntensity',
390
+ intensity: -1000
391
+ },
392
+ expected: 'success|handled'
393
+ },
394
+ {
395
+ scenario: 'Edge: Very High Intensity',
396
+ toolName: 'manage_lighting',
397
+ arguments: {
398
+ action: 'spawn_light',
399
+ lightType: 'Point',
400
+ name: 'TC_HighIntensity',
401
+ intensity: 1000000
402
+ },
403
+ expected: 'success'
404
+ },
405
+
406
+ // === CLEANUP ===
407
+ {
408
+ scenario: 'Cleanup - Delete test lights',
409
+ toolName: 'control_actor',
410
+ arguments: {
411
+ action: 'delete',
412
+ actorNames: [
413
+ 'TC_PointLight_1', 'TC_PointLight_2', 'TC_DirLight', 'TC_SpotLight',
414
+ 'TC_RectLight', 'TC_SkyLight_1', 'TC_SkyLight_2', 'TC_LightmassVolume',
415
+ 'TC_DynamicLight', 'TC_Sun', 'TC_ZeroIntensity', 'TC_NegIntensity', 'TC_HighIntensity'
416
+ ]
417
+ },
418
+ expected: 'success|not_found'
419
+ },
420
+ {
421
+ scenario: 'Cleanup - Delete lighting level',
422
+ toolName: 'manage_level',
423
+ arguments: { action: 'delete', levelPath: '/Game/Maps/TC_LightingLevel' },
424
+ expected: 'success|not_found'
425
+ }
426
+ ];
427
+
428
+ await runToolTests('Lighting Management', testCases);
@@ -1,70 +1,89 @@
1
1
  #!/usr/bin/env node
2
2
  /**
3
- * Condensed Level Management Test Suite (15 cases) — safe for real Editor runs.
3
+ * Comprehensive Level Management Test Suite
4
4
  * Tool: manage_level
5
+ * Coverage: All 18 actions with success, error, and edge cases
5
6
  */
6
7
 
7
8
  import { runToolTests } from './test-runner.mjs';
8
9
 
9
10
  const testCases = [
11
+ // === PRE-CLEANUP ===
12
+ {
13
+ scenario: 'Pre-cleanup: Remove Invalid Data Layers',
14
+ toolName: 'manage_level',
15
+ arguments: { action: 'cleanup_invalid_datalayers' },
16
+ expected: 'success'
17
+ },
18
+
19
+ // === SAVE (save, save_as, save_level_as) ===
10
20
  { scenario: 'Save current level', toolName: 'manage_level', arguments: { action: 'save' }, expected: 'success' },
11
- { scenario: 'Create test level (best-effort)', toolName: 'manage_level', arguments: { action: 'create_level', levelName: 'TC_TestLevel', streaming: false }, expected: 'success - level created' },
12
- { scenario: 'Load test level', toolName: 'manage_level', arguments: { action: 'load', levelPath: '/Engine/Maps/Entry' }, expected: 'success - level loaded' },
13
- { scenario: 'Stream sublevel (create then stream)', toolName: 'manage_level', arguments: { action: 'create_level', levelName: 'TC_SubLevel', streaming: true }, expected: 'success - command executed' },
14
- { scenario: 'Stream sublevel (make visible)', toolName: 'manage_level', arguments: { action: 'stream', levelPath: '/Game/Maps/TC_SubLevel', shouldBeLoaded: true, shouldBeVisible: true }, expected: 'success - sublevel streamed' },
15
- { scenario: 'Create point light', toolName: 'manage_level', arguments: { action: 'create_light', lightType: 'Point', location: { x: 200, y: 200, z: 100 }, intensity: 5000.0 }, expected: 'success - light spawned' },
16
- { scenario: 'Create directional light', toolName: 'manage_level', arguments: { action: 'create_light', lightType: 'Directional', rotation: { pitch: -45, yaw: 0, roll: 0 }, intensity: 3.0 }, expected: 'success - light spawned' },
17
- { scenario: 'Quick build lighting (preview)', toolName: 'manage_level', arguments: { action: 'build_lighting', quality: 'Preview' }, expected: 'success - lighting built' },
18
- { scenario: 'Export level to package', toolName: 'manage_level', arguments: { action: 'export_level', levelPath: '/Engine/Maps/Entry', outputPath: './tests/reports/tc_testlevel_export' }, expected: 'success' },
19
- { scenario: 'Import level', toolName: 'manage_level', arguments: { action: 'import_level', filePath: './tests/reports/tc_testlevel_export' }, expected: 'success' },
21
+ { scenario: 'Save level as new', toolName: 'manage_level', arguments: { action: 'save_as', savePath: '/Game/Maps/TC_SaveAs_Test' }, expected: 'success' },
22
+ { scenario: 'Save level as (alias)', toolName: 'manage_level', arguments: { action: 'save_level_as', savePath: '/Game/Maps/TC_SaveLevelAs_Test' }, expected: 'success' },
23
+
24
+ // === CREATE / LOAD / DELETE ===
25
+ { scenario: 'Create test level', toolName: 'manage_level', arguments: { action: 'create_level', levelName: 'TC_TestLevel', streaming: false }, expected: 'success - level created' },
26
+ { scenario: 'Create streaming sublevel', toolName: 'manage_level', arguments: { action: 'create_level', levelName: 'TC_SubLevel', streaming: true }, expected: 'success' },
27
+ { scenario: 'Load engine entry level', toolName: 'manage_level', arguments: { action: 'load', levelPath: '/Engine/Maps/Entry' }, expected: 'success - level loaded' },
20
28
  { scenario: 'List open levels', toolName: 'manage_level', arguments: { action: 'list_levels' }, expected: 'success' },
21
29
  { scenario: 'Get level summary', toolName: 'manage_level', arguments: { action: 'get_summary', levelPath: '/Engine/Maps/Entry' }, expected: 'success' },
22
- { scenario: 'Save level as new', toolName: 'manage_level', arguments: { action: 'save_level_as', savePath: '/Game/Maps/TC_TestLevel_SavedAs' }, expected: 'success' },
23
- { scenario: 'Unload streaming level', toolName: 'manage_level', arguments: { action: 'stream', levelPath: '/Game/Maps/TC_SubLevel', shouldBeLoaded: false }, expected: 'success - sublevel unloaded' },
24
- { scenario: 'Delete test levels', toolName: 'manage_level', arguments: { action: 'delete', levelPath: '/Game/Maps/TC_TestLevel_SavedAs' }, expected: 'success' },
25
- // Additional
26
- // Real-World Scenario: Lighting Setup
30
+
31
+ // === STREAMING (stream, add_sublevel) ===
32
+ { scenario: 'Stream sublevel (load + visible)', toolName: 'manage_level', arguments: { action: 'stream', levelPath: '/Game/Maps/TC_SubLevel', shouldBeLoaded: true, shouldBeVisible: true }, expected: 'success - sublevel streamed' },
33
+ { scenario: 'Stream sublevel (unload)', toolName: 'manage_level', arguments: { action: 'stream', levelPath: '/Game/Maps/TC_SubLevel', shouldBeLoaded: false }, expected: 'success' },
34
+ { scenario: 'Add sublevel to parent', toolName: 'manage_level', arguments: { action: 'add_sublevel', parentLevel: '/Game/Maps/TC_TestLevel', subLevelPath: '/Game/Maps/TC_SubLevel' }, expected: 'success' },
35
+
36
+ // === LIGHTS (create_light) ===
37
+ { scenario: 'Create point light', toolName: 'manage_level', arguments: { action: 'create_light', lightType: 'Point', location: { x: 200, y: 200, z: 100 }, intensity: 5000.0 }, expected: 'success - light spawned' },
38
+ { scenario: 'Create directional light', toolName: 'manage_level', arguments: { action: 'create_light', lightType: 'Directional', rotation: { pitch: -45, yaw: 0, roll: 0 }, intensity: 3.0 }, expected: 'success - light spawned' },
39
+ { scenario: 'Create spot light', toolName: 'manage_level', arguments: { action: 'create_light', lightType: 'Spot', location: { x: 0, y: 0, z: 300 }, intensity: 8000.0 }, expected: 'success' },
40
+ { scenario: 'Create rect light', toolName: 'manage_level', arguments: { action: 'create_light', lightType: 'Rect', location: { x: 100, y: 100, z: 200 }, intensity: 10000.0 }, expected: 'success' },
41
+
42
+ // === LIGHTING BUILD ===
43
+ { scenario: 'Build lighting (Preview)', toolName: 'manage_level', arguments: { action: 'build_lighting', quality: 'Preview' }, expected: 'success - lighting built' },
44
+ { scenario: 'Build lighting (Medium)', toolName: 'manage_level', arguments: { action: 'build_lighting', quality: 'Medium' }, expected: 'success' },
45
+
46
+ // === METADATA ===
47
+ { scenario: 'Set level metadata', toolName: 'manage_level', arguments: { action: 'set_metadata', levelPath: '/Game/Maps/TC_TestLevel', note: 'Test level created by automation' }, expected: 'success' },
48
+
49
+ // === WORLD PARTITION (load_cells, set_datalayer) ===
50
+ { scenario: 'Load world partition cells', toolName: 'manage_level', arguments: { action: 'load_cells', min: [0, 0, 0], max: [1000, 1000, 1000] }, expected: 'success|handled' },
51
+ { scenario: 'Set data layer', toolName: 'manage_level', arguments: { action: 'set_datalayer', dataLayerLabel: 'TC_DataLayer', dataLayerState: 'Activated' }, expected: 'success|handled' },
52
+
53
+ // === EXPORT / IMPORT ===
54
+ { scenario: 'Export level', toolName: 'manage_level', arguments: { action: 'export_level', levelPath: '/Engine/Maps/Entry', exportPath: './tests/reports/tc_testlevel_export' }, expected: 'success' },
55
+ { scenario: 'Import level', toolName: 'manage_level', arguments: { action: 'import_level', filePath: './tests/reports/tc_testlevel_export' }, expected: 'success|handled' },
56
+
57
+ // === VALIDATION ===
58
+ { scenario: 'Validate level', toolName: 'manage_level', arguments: { action: 'validate_level', levelPath: '/Game/Maps/TC_TestLevel' }, expected: 'success|not_found' },
59
+
60
+ // === REAL-WORLD SCENARIO: Lighting Setup ===
27
61
  { scenario: 'Lighting - Create Sky Light', toolName: 'manage_level', arguments: { action: 'create_light', lightType: 'Sky', intensity: 1.0 }, expected: 'success' },
28
- { scenario: 'Lighting - Build (Preview)', toolName: 'manage_level', arguments: { action: 'build_lighting', quality: 'Preview' }, expected: 'success' },
62
+ { scenario: 'Lighting - Build Preview', toolName: 'manage_level', arguments: { action: 'build_lighting', quality: 'Preview' }, expected: 'success' },
29
63
 
30
- // Real-World Scenario: Level Streaming
64
+ // === REAL-WORLD SCENARIO: Day/Night Streaming ===
31
65
  { scenario: 'Streaming - Create Night Variant', toolName: 'manage_level', arguments: { action: 'create_level', levelName: 'TC_SubLevel_Night', streaming: true }, expected: 'success' },
32
66
  { scenario: 'Streaming - Load Night', toolName: 'manage_level', arguments: { action: 'stream', levelPath: '/Game/Maps/TC_SubLevel_Night', shouldBeLoaded: true, shouldBeVisible: true }, expected: 'success' },
33
- { scenario: 'Streaming - Unload Day (TC_SubLevel)', toolName: 'manage_level', arguments: { action: 'stream', levelPath: '/Game/Maps/TC_SubLevel', shouldBeLoaded: false }, expected: 'success' },
67
+ { scenario: 'Streaming - Unload Day', toolName: 'manage_level', arguments: { action: 'stream', levelPath: '/Game/Maps/TC_SubLevel', shouldBeLoaded: false }, expected: 'success' },
68
+ { scenario: 'Streaming - Unload Night', toolName: 'manage_level', arguments: { action: 'stream', levelPath: '/Game/Maps/TC_SubLevel_Night', shouldBeLoaded: false }, expected: 'success' },
34
69
 
35
- // Cleanup
36
- { scenario: 'Cleanup - Unload Night', toolName: 'manage_level', arguments: { action: 'stream', levelPath: '/Game/Maps/TC_SubLevel_Night', shouldBeLoaded: false }, expected: 'success' },
37
- { scenario: 'Validate level', toolName: 'manage_level', arguments: { action: 'validate_level', levelPath: '/Game/Maps/TC_TestLevel_Renamed' }, expected: 'success' },
38
- {
39
- scenario: "Error: Invalid lighting quality",
40
- toolName: "manage_level",
41
- arguments: { action: "build_lighting", quality: "InvalidQuality" },
42
- expected: "error|unknown_quality"
43
- },
44
- {
45
- scenario: "Edge: Zero intensity light",
46
- toolName: "manage_level",
47
- arguments: { action: "create_light", lightType: "Point", intensity: 0 },
48
- expected: "success"
49
- },
50
- {
51
- scenario: "Border: Invalid level path",
52
- toolName: "manage_level",
53
- arguments: { action: "load", levelPath: "/Game/InvalidLevel" },
54
- expected: "not_found|error"
55
- },
56
- {
57
- scenario: "Edge: Stream unloaded level",
58
- toolName: "manage_level",
59
- arguments: { action: "stream", levelName: "NonLoadedLevel", shouldBeLoaded: true },
60
- expected: "success|handled"
61
- },
62
- {
63
- scenario: "Error: Missing action param",
64
- toolName: "manage_level",
65
- arguments: {},
66
- expected: "validation_error"
67
- }
70
+ // === ERROR CASES ===
71
+ { scenario: 'Error: Invalid lighting quality', toolName: 'manage_level', arguments: { action: 'build_lighting', quality: 'InvalidQuality' }, expected: 'error|unknown_quality' },
72
+ { scenario: 'Error: Invalid level path', toolName: 'manage_level', arguments: { action: 'load', levelPath: '/Game/InvalidLevel' }, expected: 'not_found|error' },
73
+ { scenario: 'Error: Missing action param', toolName: 'manage_level', arguments: {}, expected: 'validation_error' },
74
+ { scenario: 'Error: Delete non-existent level', toolName: 'manage_level', arguments: { action: 'delete', levelPath: '/Game/Maps/NonExistentLevel' }, expected: 'success|not_found' },
75
+ { scenario: 'Error: Load non-existent sublevel', toolName: 'manage_level', arguments: { action: 'stream', levelPath: '/Game/Maps/NonExistentSublevel', shouldBeLoaded: true }, expected: 'error|not_found' },
76
+
77
+ // === EDGE CASES ===
78
+ { scenario: 'Edge: Zero intensity light', toolName: 'manage_level', arguments: { action: 'create_light', lightType: 'Point', intensity: 0 }, expected: 'success' },
79
+ { scenario: 'Edge: Negative intensity light', toolName: 'manage_level', arguments: { action: 'create_light', lightType: 'Point', intensity: -1000 }, expected: 'success|handled' },
80
+ { scenario: 'Edge: Empty level name', toolName: 'manage_level', arguments: { action: 'create_level', levelName: '' }, expected: 'error|validation' },
81
+
82
+ // === CLEANUP ===
83
+ { scenario: 'Cleanup - Delete test levels', toolName: 'manage_level', arguments: { action: 'delete', levelPath: '/Game/Maps/TC_TestLevel' }, expected: 'success|not_found' },
84
+ { scenario: 'Cleanup - Delete sublevel', toolName: 'manage_level', arguments: { action: 'delete', levelPath: '/Game/Maps/TC_SubLevel' }, expected: 'success|not_found' },
85
+ { scenario: 'Cleanup - Delete night sublevel', toolName: 'manage_level', arguments: { action: 'delete', levelPath: '/Game/Maps/TC_SubLevel_Night' }, expected: 'success|not_found' },
86
+ { scenario: 'Cleanup - Delete saved levels', toolName: 'manage_asset', arguments: { action: 'delete', assetPaths: ['/Game/Maps/TC_SaveAs_Test', '/Game/Maps/TC_SaveLevelAs_Test'] }, expected: 'success|not_found' }
68
87
  ];
69
88
 
70
89
  await runToolTests('Manage Level', testCases);