unreal-engine-mcp-server 0.4.4 → 0.4.6
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.
- package/.env.production +1 -1
- package/.github/workflows/smithery-build.yml +29 -0
- package/CHANGELOG.md +32 -0
- package/README.md +13 -2
- package/claude_desktop_config_example.json +2 -1
- package/dist/index.d.ts +46 -1
- package/dist/index.js +40 -14
- package/dist/tools/consolidated-tool-definitions.d.ts +43 -0
- package/dist/tools/consolidated-tool-definitions.js +126 -116
- package/dist/tools/landscape.js +77 -15
- package/dist/unreal-bridge.d.ts +8 -3
- package/dist/unreal-bridge.js +25 -35
- package/dist/utils/error-handler.d.ts +40 -0
- package/dist/utils/error-handler.js +75 -0
- package/dist/utils/http.js +80 -3
- package/dist/utils/response-validator.js +70 -10
- package/docs/unreal-tool-test-cases.md +572 -0
- package/eslint.config.mjs +68 -0
- package/package.json +18 -9
- package/server.json +8 -2
- package/smithery.yaml +29 -0
- package/src/index.ts +37 -14
- package/src/tools/consolidated-tool-definitions.ts +126 -116
- package/src/tools/landscape.ts +77 -15
- package/src/unreal-bridge.ts +28 -31
- package/src/utils/error-handler.ts +113 -1
- package/src/utils/http.ts +102 -3
- package/src/utils/response-validator.ts +74 -10
- package/tsconfig.json +36 -13
|
@@ -20,13 +20,13 @@ Supported actions: list, import, create_material.`,
|
|
|
20
20
|
description: 'Action to perform'
|
|
21
21
|
},
|
|
22
22
|
// For list
|
|
23
|
-
directory: { type: 'string', description: 'Directory path to list (shows immediate children only)' },
|
|
23
|
+
directory: { type: 'string', description: 'Directory path to list (shows immediate children only). Automatically maps /Content to /Game. Example: "/Game/MyAssets"' },
|
|
24
24
|
// For import
|
|
25
|
-
sourcePath: { type: 'string', description: 'Source file path' },
|
|
26
|
-
destinationPath: { type: 'string', description: 'Destination path' },
|
|
25
|
+
sourcePath: { type: 'string', description: 'Source file path on disk to import (FBX, PNG, WAV, EXR supported). Example: "C:/MyAssets/mesh.fbx"' },
|
|
26
|
+
destinationPath: { type: 'string', description: 'Destination path in project content where asset will be imported. Example: "/Game/ImportedAssets"' },
|
|
27
27
|
// For create_material
|
|
28
|
-
name: { type: 'string', description: '
|
|
29
|
-
path: { type: 'string', description: '
|
|
28
|
+
name: { type: 'string', description: 'Name for the new material asset. Example: "MyMaterial"' },
|
|
29
|
+
path: { type: 'string', description: 'Content path where material will be saved. Example: "/Game/Materials"' }
|
|
30
30
|
},
|
|
31
31
|
required: ['action']
|
|
32
32
|
},
|
|
@@ -74,35 +74,38 @@ Supported actions: spawn, delete, apply_force.`,
|
|
|
74
74
|
description: 'Action to perform'
|
|
75
75
|
},
|
|
76
76
|
// Common
|
|
77
|
-
actorName: { type: 'string', description: 'Actor name (optional for spawn, auto-generated if not provided)' },
|
|
77
|
+
actorName: { type: 'string', description: 'Actor label/name (optional for spawn, auto-generated if not provided; required for delete). Case-insensitive for delete action.' },
|
|
78
78
|
classPath: {
|
|
79
79
|
type: 'string',
|
|
80
|
-
description: 'Actor class (e.g., "StaticMeshActor", "CameraActor") OR asset path (e.g., "/Engine/BasicShapes/Cube", "/Game/MyMesh"). Asset paths will automatically spawn as StaticMeshActor with the mesh applied'
|
|
80
|
+
description: 'Actor class (e.g., "StaticMeshActor", "CameraActor") OR asset path (e.g., "/Engine/BasicShapes/Cube", "/Game/MyMesh"). Asset paths will automatically spawn as StaticMeshActor with the mesh applied. Required for spawn action.'
|
|
81
81
|
},
|
|
82
82
|
// Transform
|
|
83
83
|
location: {
|
|
84
84
|
type: 'object',
|
|
85
|
+
description: 'World space location in centimeters (Unreal units). Optional for spawn, defaults to origin.',
|
|
85
86
|
properties: {
|
|
86
|
-
x: { type: 'number' },
|
|
87
|
-
y: { type: 'number' },
|
|
88
|
-
z: { type: 'number' }
|
|
87
|
+
x: { type: 'number', description: 'X coordinate (forward axis in Unreal)' },
|
|
88
|
+
y: { type: 'number', description: 'Y coordinate (right axis in Unreal)' },
|
|
89
|
+
z: { type: 'number', description: 'Z coordinate (up axis in Unreal)' }
|
|
89
90
|
}
|
|
90
91
|
},
|
|
91
92
|
rotation: {
|
|
92
93
|
type: 'object',
|
|
94
|
+
description: 'World space rotation in degrees. Optional for spawn, defaults to zero rotation.',
|
|
93
95
|
properties: {
|
|
94
|
-
pitch: { type: 'number' },
|
|
95
|
-
yaw: { type: 'number' },
|
|
96
|
-
roll: { type: 'number' }
|
|
96
|
+
pitch: { type: 'number', description: 'Pitch rotation in degrees (Y-axis rotation)' },
|
|
97
|
+
yaw: { type: 'number', description: 'Yaw rotation in degrees (Z-axis rotation)' },
|
|
98
|
+
roll: { type: 'number', description: 'Roll rotation in degrees (X-axis rotation)' }
|
|
97
99
|
}
|
|
98
100
|
},
|
|
99
101
|
// Physics
|
|
100
102
|
force: {
|
|
101
103
|
type: 'object',
|
|
104
|
+
description: 'Force vector to apply in Newtons. Required for apply_force action. Actor must have physics simulation enabled.',
|
|
102
105
|
properties: {
|
|
103
|
-
x: { type: 'number' },
|
|
104
|
-
y: { type: 'number' },
|
|
105
|
-
z: { type: 'number' }
|
|
106
|
+
x: { type: 'number', description: 'Force magnitude along X-axis' },
|
|
107
|
+
y: { type: 'number', description: 'Force magnitude along Y-axis' },
|
|
108
|
+
z: { type: 'number', description: 'Force magnitude along Z-axis' }
|
|
106
109
|
}
|
|
107
110
|
}
|
|
108
111
|
},
|
|
@@ -142,24 +145,26 @@ Supported actions: play, stop, set_camera, set_view_mode (with validation).`,
|
|
|
142
145
|
// Camera
|
|
143
146
|
location: {
|
|
144
147
|
type: 'object',
|
|
148
|
+
description: 'World space camera location for set_camera action. All coordinates required.',
|
|
145
149
|
properties: {
|
|
146
|
-
x: { type: 'number' },
|
|
147
|
-
y: { type: 'number' },
|
|
148
|
-
z: { type: 'number' }
|
|
150
|
+
x: { type: 'number', description: 'X coordinate in centimeters' },
|
|
151
|
+
y: { type: 'number', description: 'Y coordinate in centimeters' },
|
|
152
|
+
z: { type: 'number', description: 'Z coordinate in centimeters' }
|
|
149
153
|
}
|
|
150
154
|
},
|
|
151
155
|
rotation: {
|
|
152
156
|
type: 'object',
|
|
157
|
+
description: 'Camera rotation for set_camera action. All rotation components required.',
|
|
153
158
|
properties: {
|
|
154
|
-
pitch: { type: 'number' },
|
|
155
|
-
yaw: { type: 'number' },
|
|
156
|
-
roll: { type: 'number' }
|
|
159
|
+
pitch: { type: 'number', description: 'Pitch in degrees' },
|
|
160
|
+
yaw: { type: 'number', description: 'Yaw in degrees' },
|
|
161
|
+
roll: { type: 'number', description: 'Roll in degrees' }
|
|
157
162
|
}
|
|
158
163
|
},
|
|
159
164
|
// View mode
|
|
160
165
|
viewMode: {
|
|
161
166
|
type: 'string',
|
|
162
|
-
description: 'View mode
|
|
167
|
+
description: 'View mode for set_view_mode action. Supported: Lit, Unlit, Wireframe, DetailLighting, LightingOnly, LightComplexity, ShaderComplexity. Required for set_view_mode.'
|
|
163
168
|
}
|
|
164
169
|
},
|
|
165
170
|
required: ['action']
|
|
@@ -205,31 +210,32 @@ Supported actions: load, save, stream, create_light, build_lighting.`,
|
|
|
205
210
|
description: 'Level action'
|
|
206
211
|
},
|
|
207
212
|
// Level
|
|
208
|
-
levelPath: { type: 'string', description: '
|
|
209
|
-
levelName: { type: 'string', description: 'Level name' },
|
|
210
|
-
streaming: { type: 'boolean', description: '
|
|
211
|
-
shouldBeLoaded: { type: 'boolean', description: '
|
|
212
|
-
shouldBeVisible: { type: 'boolean', description: '
|
|
213
|
+
levelPath: { type: 'string', description: 'Full content path to level asset (e.g., "/Game/Maps/MyLevel"). Required for load action.' },
|
|
214
|
+
levelName: { type: 'string', description: 'Level name for streaming operations. Required for stream action.' },
|
|
215
|
+
streaming: { type: 'boolean', description: 'Whether to use streaming load (true) or direct load (false). Optional for load action.' },
|
|
216
|
+
shouldBeLoaded: { type: 'boolean', description: 'Whether to load (true) or unload (false) the streaming level. Required for stream action.' },
|
|
217
|
+
shouldBeVisible: { type: 'boolean', description: 'Whether the streaming level should be visible after loading. Optional for stream action.' },
|
|
213
218
|
// Lighting
|
|
214
219
|
lightType: {
|
|
215
220
|
type: 'string',
|
|
216
221
|
enum: ['Directional', 'Point', 'Spot', 'Rect'],
|
|
217
|
-
description: '
|
|
222
|
+
description: 'Type of light to create. Directional for sun-like lighting, Point for omni-directional, Spot for cone-shaped, Rect for area lighting. Required for create_light.'
|
|
218
223
|
},
|
|
219
|
-
name: { type: 'string', description: '
|
|
224
|
+
name: { type: 'string', description: 'Name for the spawned light actor. Optional, auto-generated if not provided.' },
|
|
220
225
|
location: {
|
|
221
226
|
type: 'object',
|
|
227
|
+
description: 'World space location for light placement in centimeters. Optional for create_light, defaults to origin.',
|
|
222
228
|
properties: {
|
|
223
|
-
x: { type: 'number' },
|
|
224
|
-
y: { type: 'number' },
|
|
225
|
-
z: { type: 'number' }
|
|
229
|
+
x: { type: 'number', description: 'X coordinate' },
|
|
230
|
+
y: { type: 'number', description: 'Y coordinate' },
|
|
231
|
+
z: { type: 'number', description: 'Z coordinate' }
|
|
226
232
|
}
|
|
227
233
|
},
|
|
228
|
-
intensity: { type: 'number', description: 'Light intensity' },
|
|
234
|
+
intensity: { type: 'number', description: 'Light intensity value in lumens (for Point/Spot) or lux (for Directional). Typical range: 1000-10000. Optional for create_light.' },
|
|
229
235
|
quality: {
|
|
230
236
|
type: 'string',
|
|
231
237
|
enum: ['Preview', 'Medium', 'High', 'Production'],
|
|
232
|
-
description: '
|
|
238
|
+
description: 'Lighting build quality level. Preview is fastest, Production is highest quality. Required for build_lighting action.'
|
|
233
239
|
}
|
|
234
240
|
},
|
|
235
241
|
required: ['action']
|
|
@@ -267,17 +273,17 @@ Supported actions: create_animation_bp, play_montage, setup_ragdoll.`,
|
|
|
267
273
|
description: 'Action type'
|
|
268
274
|
},
|
|
269
275
|
// Common
|
|
270
|
-
name: { type: 'string', description: '
|
|
271
|
-
actorName: { type: 'string', description: 'Actor name' },
|
|
276
|
+
name: { type: 'string', description: 'Name for the created animation blueprint asset. Required for create_animation_bp action.' },
|
|
277
|
+
actorName: { type: 'string', description: 'Actor label/name in the level to apply animation to. Required for play_montage and setup_ragdoll actions.' },
|
|
272
278
|
// Animation
|
|
273
|
-
skeletonPath: { type: 'string', description: '
|
|
274
|
-
montagePath: { type: 'string', description: '
|
|
275
|
-
animationPath: { type: 'string', description: '
|
|
276
|
-
playRate: { type: 'number', description: '
|
|
279
|
+
skeletonPath: { type: 'string', description: 'Content path to skeleton asset (e.g., "/Game/Characters/MySkeleton"). Required for create_animation_bp action.' },
|
|
280
|
+
montagePath: { type: 'string', description: 'Content path to animation montage asset to play. Required for play_montage if animationPath not provided.' },
|
|
281
|
+
animationPath: { type: 'string', description: 'Content path to animation sequence asset to play. Alternative to montagePath for play_montage action.' },
|
|
282
|
+
playRate: { type: 'number', description: 'Animation playback speed multiplier. 1.0 is normal speed, 2.0 is double speed, 0.5 is half speed. Optional, defaults to 1.0.' },
|
|
277
283
|
// Physics
|
|
278
|
-
physicsAssetName: { type: 'string', description: '
|
|
279
|
-
blendWeight: { type: 'number', description: 'Blend weight' },
|
|
280
|
-
savePath: { type: 'string', description: '
|
|
284
|
+
physicsAssetName: { type: 'string', description: 'Name or path to physics asset for ragdoll simulation. Required for setup_ragdoll action.' },
|
|
285
|
+
blendWeight: { type: 'number', description: 'Blend weight between animated and ragdoll physics (0.0 to 1.0). 0.0 is fully animated, 1.0 is fully ragdoll. Optional, defaults to 1.0.' },
|
|
286
|
+
savePath: { type: 'string', description: 'Content path where animation blueprint will be saved (e.g., "/Game/Animations"). Required for create_animation_bp action.' }
|
|
281
287
|
},
|
|
282
288
|
required: ['action']
|
|
283
289
|
},
|
|
@@ -313,34 +319,35 @@ Supported actions: niagara, particle, debug_shape.`,
|
|
|
313
319
|
description: 'Effect type'
|
|
314
320
|
},
|
|
315
321
|
// Common
|
|
316
|
-
name: { type: 'string', description: '
|
|
322
|
+
name: { type: 'string', description: 'Name for the spawned effect actor. Optional, auto-generated if not provided.' },
|
|
317
323
|
location: {
|
|
318
324
|
type: 'object',
|
|
325
|
+
description: 'World space location where effect will be spawned in centimeters. Optional, defaults to origin.',
|
|
319
326
|
properties: {
|
|
320
|
-
x: { type: 'number' },
|
|
321
|
-
y: { type: 'number' },
|
|
322
|
-
z: { type: 'number' }
|
|
327
|
+
x: { type: 'number', description: 'X coordinate' },
|
|
328
|
+
y: { type: 'number', description: 'Y coordinate' },
|
|
329
|
+
z: { type: 'number', description: 'Z coordinate' }
|
|
323
330
|
}
|
|
324
331
|
},
|
|
325
332
|
// Particles
|
|
326
333
|
effectType: {
|
|
327
334
|
type: 'string',
|
|
328
|
-
description: '
|
|
335
|
+
description: 'Preset particle effect type (Fire, Smoke, Water, Explosion, etc.). Used for particle action to spawn common effects.'
|
|
329
336
|
},
|
|
330
|
-
systemPath: { type: 'string', description: 'Niagara system
|
|
331
|
-
scale: { type: 'number', description: '
|
|
337
|
+
systemPath: { type: 'string', description: 'Content path to Niagara system asset (e.g., "/Game/Effects/MyNiagaraSystem"). Required for niagara action.' },
|
|
338
|
+
scale: { type: 'number', description: 'Uniform scale multiplier for Niagara effect. 1.0 is normal size. Optional, defaults to 1.0.' },
|
|
332
339
|
// Debug
|
|
333
340
|
shape: {
|
|
334
341
|
type: 'string',
|
|
335
|
-
description: 'Debug shape (Line, Box, Sphere,
|
|
342
|
+
description: 'Debug shape type to draw (Line, Box, Sphere, Capsule, Cone, Cylinder, Arrow). Required for debug_shape action.'
|
|
336
343
|
},
|
|
337
|
-
size: { type: 'number', description: 'Size/radius' },
|
|
344
|
+
size: { type: 'number', description: 'Size/radius of debug shape in centimeters. For Line, this is thickness. For shapes, this is radius/extent. Optional, defaults vary by shape.' },
|
|
338
345
|
color: {
|
|
339
346
|
type: 'array',
|
|
340
347
|
items: { type: 'number' },
|
|
341
|
-
description: 'RGBA color'
|
|
348
|
+
description: 'RGBA color array with values 0-255 (e.g., [255, 0, 0, 255] for red). Optional, defaults to white.'
|
|
342
349
|
},
|
|
343
|
-
duration: { type: 'number', description: '
|
|
350
|
+
duration: { type: 'number', description: 'How long debug shape persists in seconds. 0 means one frame, -1 means permanent until cleared. Optional, defaults to 0.' }
|
|
344
351
|
},
|
|
345
352
|
required: ['action']
|
|
346
353
|
},
|
|
@@ -378,14 +385,14 @@ Supported actions: create, add_component.`,
|
|
|
378
385
|
enum: ['create', 'add_component'],
|
|
379
386
|
description: 'Blueprint action'
|
|
380
387
|
},
|
|
381
|
-
name: { type: 'string', description: '
|
|
388
|
+
name: { type: 'string', description: 'Name for the blueprint asset. Required for create action. For add_component, this is the blueprint asset name or path.' },
|
|
382
389
|
blueprintType: {
|
|
383
390
|
type: 'string',
|
|
384
|
-
description: '
|
|
391
|
+
description: 'Base class type for blueprint (Actor, Pawn, Character, Object, ActorComponent, SceneComponent, etc.). Required for create action.'
|
|
385
392
|
},
|
|
386
|
-
componentType: { type: 'string', description: 'Component
|
|
387
|
-
componentName: { type: 'string', description: '
|
|
388
|
-
savePath: { type: 'string', description: '
|
|
393
|
+
componentType: { type: 'string', description: 'Component class to add (StaticMeshComponent, SkeletalMeshComponent, CameraComponent, etc.). Required for add_component action.' },
|
|
394
|
+
componentName: { type: 'string', description: 'Unique name for the component instance within the blueprint. Required for add_component action.' },
|
|
395
|
+
savePath: { type: 'string', description: 'Content path where blueprint will be saved (e.g., "/Game/Blueprints"). Required for create action.' }
|
|
389
396
|
},
|
|
390
397
|
required: ['action', 'name']
|
|
391
398
|
},
|
|
@@ -421,22 +428,23 @@ Supported actions: create_landscape, sculpt, add_foliage, paint_foliage, create_
|
|
|
421
428
|
description: 'Environment action'
|
|
422
429
|
},
|
|
423
430
|
// Common
|
|
424
|
-
name: { type: 'string', description: '
|
|
431
|
+
name: { type: 'string', description: 'Name for landscape, foliage type, or grass type actor. Optional for most actions, auto-generated if not provided.' },
|
|
425
432
|
// Landscape
|
|
426
|
-
sizeX: { type: 'number', description: 'Landscape
|
|
427
|
-
sizeY: { type: 'number', description: 'Landscape
|
|
433
|
+
sizeX: { type: 'number', description: 'Landscape width in components. Each component is typically 63 quads. Required for create_landscape action.' },
|
|
434
|
+
sizeY: { type: 'number', description: 'Landscape height in components. Each component is typically 63 quads. Required for create_landscape action.' },
|
|
428
435
|
tool: {
|
|
429
436
|
type: 'string',
|
|
430
|
-
description: '
|
|
437
|
+
description: 'Landscape sculpt tool to use (Sculpt, Smooth, Flatten, Ramp, Erosion, Hydro, Noise). Required for sculpt action.'
|
|
431
438
|
},
|
|
432
439
|
// Advanced: procedural terrain
|
|
433
440
|
location: {
|
|
434
441
|
type: 'object',
|
|
435
|
-
|
|
442
|
+
description: 'World space location for terrain placement. Required for create_procedural_terrain.',
|
|
443
|
+
properties: { x: { type: 'number', description: 'X coordinate' }, y: { type: 'number', description: 'Y coordinate' }, z: { type: 'number', description: 'Z coordinate' } }
|
|
436
444
|
},
|
|
437
|
-
subdivisions: { type: 'number' },
|
|
438
|
-
heightFunction: { type: 'string' },
|
|
439
|
-
materialPath: { type: 'string' },
|
|
445
|
+
subdivisions: { type: 'number', description: 'Number of subdivisions for procedural terrain mesh. Higher values create more detailed terrain. Optional for create_procedural_terrain.' },
|
|
446
|
+
heightFunction: { type: 'string', description: 'Mathematical function or algorithm for terrain height generation (e.g., "perlin", "simplex", custom formula). Optional for create_procedural_terrain.' },
|
|
447
|
+
materialPath: { type: 'string', description: 'Content path to material for terrain/landscape (e.g., "/Game/Materials/TerrainMat"). Optional.' },
|
|
440
448
|
// Advanced: procedural foliage
|
|
441
449
|
bounds: {
|
|
442
450
|
type: 'object',
|
|
@@ -474,19 +482,20 @@ Supported actions: create_landscape, sculpt, add_foliage, paint_foliage, create_
|
|
|
474
482
|
}
|
|
475
483
|
},
|
|
476
484
|
// Foliage (for add_foliage)
|
|
477
|
-
meshPath: { type: 'string', description: '
|
|
478
|
-
density: { type: 'number', description: '
|
|
485
|
+
meshPath: { type: 'string', description: 'Content path to static mesh for foliage (e.g., "/Game/Foliage/TreeMesh"). Required for add_foliage action.' },
|
|
486
|
+
density: { type: 'number', description: 'Foliage placement density (instances per unit area). Typical range: 0.1 to 10.0. Required for add_foliage and affects procedural foliage.' },
|
|
479
487
|
// Painting
|
|
480
488
|
position: {
|
|
481
489
|
type: 'object',
|
|
490
|
+
description: 'World space position for foliage paint brush center. Required for paint_foliage action.',
|
|
482
491
|
properties: {
|
|
483
|
-
x: { type: 'number' },
|
|
484
|
-
y: { type: 'number' },
|
|
485
|
-
z: { type: 'number' }
|
|
492
|
+
x: { type: 'number', description: 'X coordinate' },
|
|
493
|
+
y: { type: 'number', description: 'Y coordinate' },
|
|
494
|
+
z: { type: 'number', description: 'Z coordinate' }
|
|
486
495
|
}
|
|
487
496
|
},
|
|
488
|
-
brushSize: { type: 'number', description: '
|
|
489
|
-
strength: { type: 'number', description: '
|
|
497
|
+
brushSize: { type: 'number', description: 'Radius of foliage paint brush in centimeters. Typical range: 500-5000. Required for paint_foliage action.' },
|
|
498
|
+
strength: { type: 'number', description: 'Paint tool strength/intensity (0.0 to 1.0). Higher values place more instances. Optional for paint_foliage, defaults to 0.5.' }
|
|
490
499
|
},
|
|
491
500
|
required: ['action']
|
|
492
501
|
},
|
|
@@ -525,39 +534,40 @@ Supported actions: profile, show_fps, set_quality, play_sound, create_widget, sh
|
|
|
525
534
|
// Performance
|
|
526
535
|
profileType: {
|
|
527
536
|
type: 'string',
|
|
528
|
-
description: '
|
|
537
|
+
description: 'Type of profiling to enable: CPU (stat cpu), GPU (stat gpu), Memory (stat memory), FPS (stat fps), Unit (stat unit). Required for profile action.'
|
|
529
538
|
},
|
|
530
539
|
category: {
|
|
531
540
|
type: 'string',
|
|
532
|
-
description: '
|
|
541
|
+
description: 'Scalability quality category to adjust: ViewDistance, AntiAliasing, Shadow/Shadows, PostProcess/PostProcessing, Texture/Textures, Effects, Foliage, Shading. Required for set_quality action.'
|
|
533
542
|
},
|
|
534
|
-
level: { type: 'number', description: 'Quality level (0
|
|
535
|
-
enabled: { type: 'boolean', description: 'Enable/
|
|
536
|
-
verbose: { type: 'boolean', description: '
|
|
543
|
+
level: { type: 'number', description: 'Quality level (0=Low, 1=Medium, 2=High, 3=Epic, 4=Cinematic). Required for set_quality action.' },
|
|
544
|
+
enabled: { type: 'boolean', description: 'Enable (true) or disable (false) profiling/FPS display. Required for profile and show_fps actions.' },
|
|
545
|
+
verbose: { type: 'boolean', description: 'Show verbose profiling output with additional details. Optional for profile action.' },
|
|
537
546
|
// Audio
|
|
538
|
-
soundPath: { type: 'string', description: '
|
|
547
|
+
soundPath: { type: 'string', description: 'Content path to sound asset (SoundCue or SoundWave, e.g., "/Game/Audio/MySound"). Required for play_sound action.' },
|
|
539
548
|
location: {
|
|
540
549
|
type: 'object',
|
|
550
|
+
description: 'World space location for 3D sound playback. Required if is3D is true for play_sound action.',
|
|
541
551
|
properties: {
|
|
542
|
-
x: { type: 'number' },
|
|
543
|
-
y: { type: 'number' },
|
|
544
|
-
z: { type: 'number' }
|
|
552
|
+
x: { type: 'number', description: 'X coordinate' },
|
|
553
|
+
y: { type: 'number', description: 'Y coordinate' },
|
|
554
|
+
z: { type: 'number', description: 'Z coordinate' }
|
|
545
555
|
}
|
|
546
556
|
},
|
|
547
|
-
volume: { type: 'number', description: 'Volume (0
|
|
548
|
-
is3D: { type: 'boolean', description: '3D
|
|
557
|
+
volume: { type: 'number', description: 'Volume multiplier (0.0=silent, 1.0=full volume). Optional for play_sound, defaults to 1.0.' },
|
|
558
|
+
is3D: { type: 'boolean', description: 'Whether sound should be played as 3D positional audio (true) or 2D (false). Optional for play_sound, defaults to false.' },
|
|
549
559
|
// UI
|
|
550
|
-
widgetName: { type: 'string', description: '
|
|
560
|
+
widgetName: { type: 'string', description: 'Name for widget asset or instance. Required for create_widget and show_widget actions.' },
|
|
551
561
|
widgetType: {
|
|
552
562
|
type: 'string',
|
|
553
|
-
description: 'Widget type (HUD, Menu, etc.)'
|
|
563
|
+
description: 'Widget blueprint type or category (HUD, Menu, Dialog, Notification, etc.). Optional for create_widget, helps categorize the widget.'
|
|
554
564
|
},
|
|
555
|
-
visible: { type: 'boolean', description: '
|
|
565
|
+
visible: { type: 'boolean', description: 'Whether widget should be visible (true) or hidden (false). Required for show_widget action.' },
|
|
556
566
|
// Screenshot
|
|
557
|
-
resolution: { type: 'string', description: 'e.g.
|
|
567
|
+
resolution: { type: 'string', description: 'Screenshot resolution in WIDTHxHEIGHT format (e.g., "1920x1080", "3840x2160"). Optional for screenshot action, uses viewport size if not specified.' },
|
|
558
568
|
// Engine lifecycle
|
|
559
|
-
projectPath: { type: 'string', description: '
|
|
560
|
-
editorExe: { type: 'string', description: '
|
|
569
|
+
projectPath: { type: 'string', description: 'Absolute path to .uproject file (e.g., "C:/Projects/MyGame/MyGame.uproject"). Required for engine_start unless UE_PROJECT_PATH environment variable is set.' },
|
|
570
|
+
editorExe: { type: 'string', description: 'Absolute path to Unreal Editor executable (e.g., "C:/UnrealEngine/Engine/Binaries/Win64/UnrealEditor.exe"). Required for engine_start unless UE_EDITOR_EXE environment variable is set.' }
|
|
561
571
|
},
|
|
562
572
|
required: ['action']
|
|
563
573
|
},
|
|
@@ -588,7 +598,7 @@ Use it when higher-level tools don't cover the console tweak you need. Hazardous
|
|
|
588
598
|
inputSchema: {
|
|
589
599
|
type: 'object',
|
|
590
600
|
properties: {
|
|
591
|
-
command: { type: 'string', description: 'Console command to execute' }
|
|
601
|
+
command: { type: 'string', description: 'Console command to execute in Unreal Engine (e.g., "stat fps", "r.SetRes 1920x1080", "viewmode lit"). Dangerous commands like quit/exit and crash triggers are blocked. Required.' }
|
|
592
602
|
},
|
|
593
603
|
required: ['command']
|
|
594
604
|
},
|
|
@@ -624,13 +634,13 @@ Supported actions: create_preset, expose_actor, expose_property, list_fields, se
|
|
|
624
634
|
enum: ['create_preset', 'expose_actor', 'expose_property', 'list_fields', 'set_property', 'get_property'],
|
|
625
635
|
description: 'RC action'
|
|
626
636
|
},
|
|
627
|
-
name: { type: 'string', description: '
|
|
628
|
-
path: { type: 'string', description: '
|
|
629
|
-
presetPath: { type: 'string', description: '
|
|
630
|
-
actorName: { type: 'string', description: 'Actor label/name to expose' },
|
|
631
|
-
objectPath: { type: 'string', description: '
|
|
632
|
-
propertyName: { type: 'string', description: '
|
|
633
|
-
value: { description: '
|
|
637
|
+
name: { type: 'string', description: 'Name for Remote Control preset asset. Required for create_preset action.' },
|
|
638
|
+
path: { type: 'string', description: 'Content path where preset will be saved (e.g., "/Game/RCPresets"). Required for create_preset action.' },
|
|
639
|
+
presetPath: { type: 'string', description: 'Full content path to existing Remote Control preset asset (e.g., "/Game/RCPresets/MyPreset"). Required for expose_actor, expose_property, list_fields, set_property, and get_property actions.' },
|
|
640
|
+
actorName: { type: 'string', description: 'Actor label/name in level to expose to Remote Control preset. Required for expose_actor action.' },
|
|
641
|
+
objectPath: { type: 'string', description: 'Full object path for property operations (e.g., "/Game/Maps/Level.Level:PersistentLevel.StaticMeshActor_0"). Required for expose_property, set_property, and get_property actions.' },
|
|
642
|
+
propertyName: { type: 'string', description: 'Name of the property to expose, get, or set (e.g., "RelativeLocation", "Intensity", "bHidden"). Required for expose_property, set_property, and get_property actions.' },
|
|
643
|
+
value: { description: 'New value to set for property. Must be JSON-serializable and compatible with property type (e.g., {"X":100,"Y":200,"Z":300} for location, true/false for bool, number for numeric types). Required for set_property action.' }
|
|
634
644
|
},
|
|
635
645
|
required: ['action']
|
|
636
646
|
},
|
|
@@ -670,18 +680,18 @@ Supported actions: create, open, add_camera, add_actor, add_actors, remove_actor
|
|
|
670
680
|
],
|
|
671
681
|
description: 'Sequence action'
|
|
672
682
|
},
|
|
673
|
-
name: { type: 'string', description: 'Sequence
|
|
674
|
-
path: { type: 'string', description: '
|
|
675
|
-
actorName: { type: 'string', description: 'Actor name to add as possessable' },
|
|
676
|
-
actorNames: { type: 'array', items: { type: 'string' }, description: '
|
|
677
|
-
className: { type: 'string', description: '
|
|
678
|
-
spawnable: { type: 'boolean', description: 'If true, camera is spawnable' },
|
|
679
|
-
frameRate: { type: 'number', description: '
|
|
680
|
-
lengthInFrames: { type: 'number', description: 'Total length in frames' },
|
|
681
|
-
playbackStart: { type: 'number', description: '
|
|
682
|
-
playbackEnd: { type: 'number', description: '
|
|
683
|
-
speed: { type: 'number', description: 'Playback speed multiplier' },
|
|
684
|
-
loopMode: { type: 'string', enum: ['once', 'loop', 'pingpong'], description: '
|
|
683
|
+
name: { type: 'string', description: 'Name for new Level Sequence asset. Required for create action.' },
|
|
684
|
+
path: { type: 'string', description: 'Content path - for create action: save location (e.g., "/Game/Cinematics"); for open/operations: full asset path (e.g., "/Game/Cinematics/MySequence"). Required for create and open actions.' },
|
|
685
|
+
actorName: { type: 'string', description: 'Actor label/name in level to add as possessable binding to sequence. Required for add_actor action.' },
|
|
686
|
+
actorNames: { type: 'array', items: { type: 'string' }, description: 'Array of actor labels/names for batch add or remove operations. Required for add_actors and remove_actors actions.' },
|
|
687
|
+
className: { type: 'string', description: 'Unreal class name for spawnable actor (e.g., "StaticMeshActor", "CineCameraActor", "SkeletalMeshActor"). Required for add_spawnable_from_class action.' },
|
|
688
|
+
spawnable: { type: 'boolean', description: 'If true, camera is spawnable (owned by sequence); if false, camera is possessable (references level actor). Optional for add_camera, defaults to true.' },
|
|
689
|
+
frameRate: { type: 'number', description: 'Sequence frame rate in frames per second (e.g., 24, 30, 60). Required for set_properties when changing frame rate.' },
|
|
690
|
+
lengthInFrames: { type: 'number', description: 'Total sequence length measured in frames. Required for set_properties when changing duration.' },
|
|
691
|
+
playbackStart: { type: 'number', description: 'First frame of playback range (inclusive). Optional for set_properties.' },
|
|
692
|
+
playbackEnd: { type: 'number', description: 'Last frame of playback range (inclusive). Optional for set_properties.' },
|
|
693
|
+
speed: { type: 'number', description: 'Playback speed multiplier. 1.0 is normal speed, 2.0 is double speed, 0.5 is half speed. Required for set_playback_speed action.' },
|
|
694
|
+
loopMode: { type: 'string', enum: ['once', 'loop', 'pingpong'], description: 'How sequence loops: "once" plays once and stops, "loop" repeats from start, "pingpong" plays forward then backward. Optional for set_properties.' }
|
|
685
695
|
},
|
|
686
696
|
required: ['action']
|
|
687
697
|
},
|
|
@@ -719,10 +729,10 @@ Supported actions: inspect_object, set_property.`,
|
|
|
719
729
|
inputSchema: {
|
|
720
730
|
type: 'object',
|
|
721
731
|
properties: {
|
|
722
|
-
action: { type: 'string', enum: ['inspect_object', 'set_property'], description: '
|
|
723
|
-
objectPath: { type: 'string', description: '
|
|
724
|
-
propertyName: { type: 'string', description: '
|
|
725
|
-
value: { description: '
|
|
732
|
+
action: { type: 'string', enum: ['inspect_object', 'set_property'], description: 'Introspection action: "inspect_object" retrieves all properties, "set_property" modifies a specific property. Required.' },
|
|
733
|
+
objectPath: { type: 'string', description: 'Full object path in Unreal format (e.g., "/Game/Maps/Level.Level:PersistentLevel.StaticMeshActor_0" or "/Script/Engine.Default__StaticMeshActor" for CDO). Required for both actions.' },
|
|
734
|
+
propertyName: { type: 'string', description: 'Name of the property to modify (e.g., "RelativeLocation", "Mobility", "bHidden"). Required for set_property action.' },
|
|
735
|
+
value: { description: 'New property value. Must be JSON-serializable and compatible with property type (e.g., {"X":100,"Y":0,"Z":0} for vectors, 5.0 for floats, true for bools, "Value" for strings). Required for set_property action.' }
|
|
726
736
|
},
|
|
727
737
|
required: ['action']
|
|
728
738
|
},
|
package/dist/tools/landscape.js
CHANGED
|
@@ -65,14 +65,40 @@ try:
|
|
|
65
65
|
editor_subsystem = unreal.get_editor_subsystem(unreal.UnrealEditorSubsystem)
|
|
66
66
|
world = editor_subsystem.get_editor_world() if editor_subsystem and hasattr(editor_subsystem, 'get_editor_world') else None
|
|
67
67
|
data_layer_manager = None
|
|
68
|
+
world_partition = None
|
|
68
69
|
if world:
|
|
70
|
+
# Try multiple methods to access World Partition (UE 5.6+)
|
|
69
71
|
try:
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
72
|
+
# Method 1: Try get_world_partition() if it exists
|
|
73
|
+
if hasattr(world, 'get_world_partition'):
|
|
74
|
+
world_partition = world.get_world_partition()
|
|
75
|
+
except (AttributeError, Exception):
|
|
76
|
+
pass
|
|
77
|
+
|
|
78
|
+
if not world_partition:
|
|
79
|
+
try:
|
|
80
|
+
# Method 2: Try WorldPartitionSubsystem
|
|
81
|
+
wp_subsystem = unreal.get_editor_subsystem(unreal.WorldPartitionSubsystem)
|
|
82
|
+
if wp_subsystem:
|
|
83
|
+
world_partition = wp_subsystem.get_world_partition(world)
|
|
84
|
+
except (AttributeError, Exception):
|
|
85
|
+
pass
|
|
86
|
+
|
|
87
|
+
if not world_partition:
|
|
88
|
+
try:
|
|
89
|
+
# Method 3: Check if world has world_partition property
|
|
90
|
+
if hasattr(world, 'world_partition'):
|
|
91
|
+
world_partition = world.world_partition
|
|
92
|
+
except (AttributeError, Exception):
|
|
93
|
+
pass
|
|
94
|
+
|
|
95
|
+
result["worldPartition"] = world_partition is not None
|
|
96
|
+
|
|
97
|
+
if result["worldPartition"] and hasattr(unreal, "WorldPartitionBlueprintLibrary"):
|
|
98
|
+
try:
|
|
73
99
|
data_layer_manager = unreal.WorldPartitionBlueprintLibrary.get_data_layer_manager(world)
|
|
74
|
-
|
|
75
|
-
|
|
100
|
+
except Exception as dlm_error:
|
|
101
|
+
result["warnings"].append(f"Data layer manager unavailable: {dlm_error}")
|
|
76
102
|
|
|
77
103
|
actor_subsystem = unreal.get_editor_subsystem(unreal.EditorActorSubsystem)
|
|
78
104
|
if not actor_subsystem:
|
|
@@ -106,12 +132,33 @@ try:
|
|
|
106
132
|
if not landscape_actor:
|
|
107
133
|
result["error"] = "Failed to spawn landscape actor"
|
|
108
134
|
else:
|
|
135
|
+
# Set label first
|
|
109
136
|
try:
|
|
110
137
|
landscape_actor.set_actor_label("${escapedName}", True)
|
|
111
138
|
except TypeError:
|
|
112
139
|
landscape_actor.set_actor_label("${escapedName}")
|
|
113
140
|
except Exception as label_error:
|
|
114
141
|
result["warnings"].append(f"Failed to set landscape label: {label_error}")
|
|
142
|
+
|
|
143
|
+
# Fix component registration by forcing re-registration
|
|
144
|
+
# This addresses the "RegisterComponentWithWorld: Trying to register component with IsValid() == false" warning
|
|
145
|
+
try:
|
|
146
|
+
# Get landscape components and re-register them
|
|
147
|
+
landscape_components = landscape_actor.get_components_by_class(unreal.LandscapeComponent)
|
|
148
|
+
if landscape_components:
|
|
149
|
+
for component in landscape_components:
|
|
150
|
+
if hasattr(component, 'register_component'):
|
|
151
|
+
try:
|
|
152
|
+
component.register_component()
|
|
153
|
+
except Exception:
|
|
154
|
+
pass
|
|
155
|
+
else:
|
|
156
|
+
# If no components yet, this is expected for LandscapePlaceholder
|
|
157
|
+
# The landscape needs to be "finalized" via editor tools or console commands
|
|
158
|
+
result["details"].append("Landscape placeholder created - finalize via editor for full functionality")
|
|
159
|
+
except Exception as comp_error:
|
|
160
|
+
# Component registration is best-effort; not critical
|
|
161
|
+
result["details"].append(f"Component registration attempted (editor finalization may be needed)")
|
|
115
162
|
|
|
116
163
|
try:
|
|
117
164
|
landscape_actor.set_actor_scale3d(unreal.Vector(${scaleX.toFixed(4)}, ${scaleY.toFixed(4)}, 1.0))
|
|
@@ -119,19 +166,34 @@ try:
|
|
|
119
166
|
except Exception as scale_error:
|
|
120
167
|
result["warnings"].append(f"Failed to set landscape scale: {scale_error}")
|
|
121
168
|
|
|
122
|
-
|
|
169
|
+
# Workaround for LandscapeEditorSubsystem Python API limitation
|
|
170
|
+
# Use direct property manipulation instead
|
|
171
|
+
landscape_configured = False
|
|
123
172
|
try:
|
|
173
|
+
# Try LandscapeEditorSubsystem if available (may not be in Python API)
|
|
124
174
|
landscape_editor = unreal.get_editor_subsystem(unreal.LandscapeEditorSubsystem)
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
175
|
+
if landscape_editor:
|
|
176
|
+
try:
|
|
177
|
+
landscape_editor.set_component_size(${sectionsPerComponent}, ${quadsPerSection})
|
|
178
|
+
landscape_editor.set_component_count(${componentCount}, ${componentCount})
|
|
179
|
+
result["details"].append(f"Component size ${sectionsPerComponent}x${quadsPerSection}, count ${componentCount}x${componentCount}")
|
|
180
|
+
landscape_configured = True
|
|
181
|
+
except Exception as config_error:
|
|
182
|
+
result["details"].append(f"LandscapeEditorSubsystem method limited: {config_error}")
|
|
183
|
+
except (AttributeError, Exception):
|
|
184
|
+
# Expected - LandscapeEditorSubsystem not available in Python API
|
|
185
|
+
pass
|
|
186
|
+
|
|
187
|
+
# Fallback: Configure via properties if subsystem not available
|
|
188
|
+
if not landscape_configured:
|
|
129
189
|
try:
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
190
|
+
# Set component properties directly
|
|
191
|
+
if hasattr(landscape_actor, 'set_editor_property'):
|
|
192
|
+
# Note: These properties may not be directly editable post-spawn
|
|
193
|
+
# This is documented UE limitation - landscape config is best done via editor tools
|
|
194
|
+
result["details"].append(f"Landscape spawned (config via editor tools recommended for ${sectionsPerComponent}x${quadsPerSection} components)")
|
|
195
|
+
except Exception:
|
|
196
|
+
pass
|
|
135
197
|
|
|
136
198
|
${escapedMaterial ? `try:
|
|
137
199
|
material = unreal.EditorAssetLibrary.load_asset("${escapedMaterial}")
|
package/dist/unreal-bridge.d.ts
CHANGED
|
@@ -17,6 +17,10 @@ export declare class UnrealBridge {
|
|
|
17
17
|
private autoReconnectEnabled;
|
|
18
18
|
private engineVersionCache?;
|
|
19
19
|
private readonly ENGINE_VERSION_TTL_MS;
|
|
20
|
+
private lastPongReceived;
|
|
21
|
+
private pingInterval?;
|
|
22
|
+
private readonly PING_INTERVAL_MS;
|
|
23
|
+
private readonly PONG_TIMEOUT_MS;
|
|
20
24
|
private commandQueue;
|
|
21
25
|
private isProcessing;
|
|
22
26
|
private readonly MIN_COMMAND_DELAY;
|
|
@@ -34,11 +38,12 @@ export declare class UnrealBridge {
|
|
|
34
38
|
private readonly PYTHON_TEMPLATES;
|
|
35
39
|
get isConnected(): boolean;
|
|
36
40
|
/**
|
|
37
|
-
* Attempt to connect with
|
|
41
|
+
* Attempt to connect with exponential backoff retry strategy
|
|
42
|
+
* Uses optimized retry pattern from TypeScript best practices
|
|
38
43
|
* @param maxAttempts Maximum number of connection attempts
|
|
39
44
|
* @param timeoutMs Timeout for each connection attempt in milliseconds
|
|
40
|
-
* @param retryDelayMs
|
|
41
|
-
* @returns Promise that resolves
|
|
45
|
+
* @param retryDelayMs Initial delay between retry attempts in milliseconds
|
|
46
|
+
* @returns Promise that resolves to true if connected, false otherwise
|
|
42
47
|
*/
|
|
43
48
|
private connectPromise?;
|
|
44
49
|
tryConnect(maxAttempts?: number, timeoutMs?: number, retryDelayMs?: number): Promise<boolean>;
|