unreal-engine-mcp-server 0.6.0-beta-c → 0.6.0-beta-e

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 (102) hide show
  1. package/CHANGELOG.md +148 -9
  2. package/README.md +2 -2
  3. package/dist/gateway/gateway-manifest.generated.json +838 -133
  4. package/dist/proxy/native-proxy.js +6 -5
  5. package/dist/server/gateway/gateway-execute-dispatch.js +2 -1
  6. package/dist/server/gateway/gateway-execute-envelope.js +5 -1
  7. package/dist/server/gateway/gateway-execute-lookup.js +1 -1
  8. package/dist/server/gateway/gateway-execute.js +17 -4
  9. package/dist/server/gateway/gateway-schema-validate.js +13 -2
  10. package/dist/server/gateway/gateway-task-results.d.ts +6 -0
  11. package/dist/server/gateway/gateway-task-results.js +40 -0
  12. package/dist/server/tool-registry-manage-tools.js +4 -1
  13. package/dist/tools/catalog/capabilities/generated/canonical-registry.generated.d.ts +2 -2
  14. package/dist/tools/catalog/capabilities/generated/canonical-registry.generated.js +2 -2
  15. package/dist/tools/catalog/capabilities/generated/canonical-registry.generated.json +4079 -618
  16. package/dist/tools/catalog/capabilities/generated/capability-cost-index.generated.d.ts +1 -1
  17. package/dist/tools/catalog/capabilities/generated/capability-cost-index.generated.js +18 -1
  18. package/dist/tools/catalog/capabilities/generated/parent-tool-definitions.generated.js +1546 -212
  19. package/dist/tools/catalog/capabilities/records/aggregate.d.ts +1 -1
  20. package/dist/tools/catalog/capabilities/records/aggregate.js +1 -1
  21. package/dist/tools/catalog/capabilities/records/build-environment/spline.data.js +4 -3
  22. package/dist/tools/catalog/capabilities/records/build-environment/water.data.js +8 -5
  23. package/dist/tools/catalog/capabilities/records/control-actor/advanced-records.js +29 -8
  24. package/dist/tools/catalog/capabilities/records/control-actor/search-records.js +2 -2
  25. package/dist/tools/catalog/capabilities/records/control-actor/spawn-records.js +13 -5
  26. package/dist/tools/catalog/capabilities/records/control-actor/state-records.js +2 -1
  27. package/dist/tools/catalog/capabilities/records/control-actor/transform-records.js +27 -9
  28. package/dist/tools/catalog/capabilities/records/control-editor/asset.js +4 -1
  29. package/dist/tools/catalog/capabilities/records/control-editor/camera.js +5 -1
  30. package/dist/tools/catalog/capabilities/records/control-editor/command.js +5 -1
  31. package/dist/tools/catalog/capabilities/records/control-editor/input.js +2 -1
  32. package/dist/tools/catalog/capabilities/records/control-editor/screenshot.js +2 -1
  33. package/dist/tools/catalog/capabilities/records/control-editor/session.js +8 -1
  34. package/dist/tools/catalog/capabilities/records/control-editor/timing.js +5 -3
  35. package/dist/tools/catalog/capabilities/records/core/builder.d.ts +1 -0
  36. package/dist/tools/catalog/capabilities/records/core/builder.js +1 -0
  37. package/dist/tools/catalog/capabilities/records/folds/build-environment.folds.js +2 -2
  38. package/dist/tools/catalog/capabilities/records/folds/control-actor.folds.js +2 -2
  39. package/dist/tools/catalog/capabilities/records/folds/manage-asset.folds.js +8 -8
  40. package/dist/tools/catalog/capabilities/records/folds/manage-audio.folds.js +5 -5
  41. package/dist/tools/catalog/capabilities/records/folds/manage-blueprint.folds.js +2 -2
  42. package/dist/tools/catalog/capabilities/records/folds/manage-effect.folds.js +3 -3
  43. package/dist/tools/catalog/capabilities/records/folds/manage-sequence.folds.js +6 -6
  44. package/dist/tools/catalog/capabilities/records/folds/system-control.folds.js +2 -2
  45. package/dist/tools/catalog/capabilities/records/gameplay/animation-physics/animation-properties.js +7 -5
  46. package/dist/tools/catalog/capabilities/records/gameplay/animation-physics/authoring-1.data.js +86 -1
  47. package/dist/tools/catalog/capabilities/records/gameplay/animation-physics/authoring-2.data.js +7 -2
  48. package/dist/tools/catalog/capabilities/records/gameplay/manage-effect/effect-properties.js +7 -6
  49. package/dist/tools/catalog/capabilities/records/gameplay/manage-effect/effect.data.js +38 -27
  50. package/dist/tools/catalog/capabilities/records/inspect/component-actor.data.js +1 -1
  51. package/dist/tools/catalog/capabilities/records/inspect/object-property.data.js +188 -10
  52. package/dist/tools/catalog/capabilities/records/inspect/properties.d.ts +1 -0
  53. package/dist/tools/catalog/capabilities/records/inspect/properties.js +2 -1
  54. package/dist/tools/catalog/capabilities/records/inspect/runtime.data.js +2 -1
  55. package/dist/tools/catalog/capabilities/records/inspect/stats.data.js +6 -2
  56. package/dist/tools/catalog/capabilities/records/manage-asset/asset-advanced.js +46 -0
  57. package/dist/tools/catalog/capabilities/records/manage-asset/asset-lifecycle.js +2 -2
  58. package/dist/tools/catalog/capabilities/records/manage-asset/asset-query.js +4 -3
  59. package/dist/tools/catalog/capabilities/records/manage-asset/builder.d.ts +3 -0
  60. package/dist/tools/catalog/capabilities/records/manage-asset/builder.js +3 -0
  61. package/dist/tools/catalog/capabilities/records/manage-asset/content-sources.js +3 -1
  62. package/dist/tools/catalog/capabilities/records/manage-asset/material-create.js +17 -2
  63. package/dist/tools/catalog/capabilities/records/manage-asset/material-graph.js +7 -5
  64. package/dist/tools/catalog/capabilities/records/manage-asset/material-params.js +5 -5
  65. package/dist/tools/catalog/capabilities/records/manage-audio/authoring.data.js +15 -5
  66. package/dist/tools/catalog/capabilities/records/manage-audio/runtime.data.js +1 -0
  67. package/dist/tools/catalog/capabilities/records/manage-blueprint/functions-events.js +3 -2
  68. package/dist/tools/catalog/capabilities/records/manage-blueprint/graph-batch.js +2 -2
  69. package/dist/tools/catalog/capabilities/records/manage-blueprint/graph-pins.js +6 -2
  70. package/dist/tools/catalog/capabilities/records/manage-blueprint/properties.js +4 -2
  71. package/dist/tools/catalog/capabilities/records/manage-blueprint/scs-components.js +7 -2
  72. package/dist/tools/catalog/capabilities/records/manage-blueprint/variables-metadata.js +8 -2
  73. package/dist/tools/catalog/capabilities/records/manage-blueprint/widget-animation.js +14 -4
  74. package/dist/tools/catalog/capabilities/records/manage-blueprint/widget-lifecycle.js +13 -5
  75. package/dist/tools/catalog/capabilities/records/manage-blueprint/widget-panels.js +1 -1
  76. package/dist/tools/catalog/capabilities/records/manage-sequence/cinematic.js +12 -3
  77. package/dist/tools/catalog/capabilities/records/manage-sequence/helpers.js +2 -2
  78. package/dist/tools/catalog/capabilities/records/manage-sequence/mrq.js +23 -4
  79. package/dist/tools/catalog/capabilities/records/manage-sequence/timeline-bindings.js +2 -2
  80. package/dist/tools/catalog/capabilities/records/manage-sequence/timeline-lifecycle.js +7 -2
  81. package/dist/tools/catalog/capabilities/records/manage-sequence/timeline-playback.js +9 -5
  82. package/dist/tools/catalog/capabilities/records/manage-sequence/timeline-state-ranges.js +19 -0
  83. package/dist/tools/catalog/capabilities/records/manage-sequence/timeline-tracks.js +10 -5
  84. package/dist/tools/catalog/capabilities/records/manage-tools/index.js +30 -2
  85. package/dist/tools/catalog/capabilities/records/system-control/console.js +3 -1
  86. package/dist/tools/catalog/capabilities/records/system-control/system-ops.js +122 -10
  87. package/dist/tools/catalog/capabilities/records/utility/output-glossary.js +11 -0
  88. package/dist/tools/catalog/capabilities/records/utility/utility-schema-pins.js +6 -3
  89. package/dist/tools/catalog/capabilities/records/world/manage-geometry.optimize.data.js +29 -0
  90. package/dist/tools/catalog/capabilities/records/world/manage-geometry.primitives.data.js +2 -1
  91. package/dist/tools/catalog/capabilities/records/world/properties.js +2 -2
  92. package/dist/tools/catalog/capabilities/semantic/envelope.d.ts +1 -1
  93. package/dist/tools/catalog/capabilities/semantic/errors.d.ts +1 -1
  94. package/dist/tools/catalog/unreal-gateway-definition.js +2 -2
  95. package/dist/utils/responses/gateway-reply-compaction.d.ts +6 -0
  96. package/dist/utils/responses/gateway-reply-compaction.js +264 -0
  97. package/dist/utils/responses/response-content.d.ts +0 -1
  98. package/dist/utils/responses/response-content.js +0 -172
  99. package/dist/utils/responses/response-validator.d.ts +1 -1
  100. package/dist/utils/responses/response-validator.js +39 -8
  101. package/package.json +2 -2
  102. package/server.json +2 -2
@@ -1,4 +1,4 @@
1
1
  import type { CapabilityRecord } from '../model.js';
2
- export declare const ALL_CAPABILITY_RECORD_COUNT: 393;
2
+ export declare const ALL_CAPABILITY_RECORD_COUNT: 405;
3
3
  export declare const ALL_CAPABILITY_RECORDS: readonly CapabilityRecord[];
4
4
  //# sourceMappingURL=aggregate.d.ts.map
@@ -22,7 +22,7 @@ import { SYSTEM_CONTROL_SOURCES } from './system-control/index.js';
22
22
  import { MANAGE_GEOMETRY_SOURCES } from './world/manage-geometry.index.js';
23
23
  import { MANAGE_LEVEL_STRUCTURE_SOURCES } from './world/manage-level-structure.index.js';
24
24
  import { MANAGE_PCG_SOURCES } from './world/manage-pcg.index.js';
25
- export const ALL_CAPABILITY_RECORD_COUNT = 393;
25
+ export const ALL_CAPABILITY_RECORD_COUNT = 405;
26
26
  const ALL_SOURCES = [
27
27
  ...BUILD_ENVIRONMENT_SOURCES,
28
28
  ...MANAGE_LEVEL_STRUCTURE_SOURCES,
@@ -3,6 +3,7 @@ import { P } from './properties.js';
3
3
  const F = 'spline';
4
4
  const WU = ['A spline actor or spline mesh must be created or modified.'];
5
5
  const ACTOR_PATH = { ...P.actorPath, description: 'Object path of the spline actor; used when actorName is omitted.' };
6
+ const SPLINE_POSITION = { ...P.position, description: 'Point position relative to the spline actor {x, y, z}: its local space, the location get_splines_info with actorName reports (worldLocation is where the point lies in the level).' };
6
7
  const TEMPLATE = {
7
8
  name: P.name, location: P.location, meshPath: P.meshPath, points: P.points,
8
9
  materialPath: P.materialPath, width: { ...P.width, description: 'Width of the deformed mesh ribbon in world units (default 400).' }, closedLoop: P.closedLoop,
@@ -21,7 +22,7 @@ export const SPLINE_RECORDS = [
21
22
  id: 'build_environment.add_spline_point', action: 'add_spline_point', family: F,
22
23
  summary: 'Add a point to an existing spline.',
23
24
  whenToUse: WU, whenNotToUse: ['The spline should be recreated with all points.'],
24
- inputProps: { actorName: P.actorName, actorPath: ACTOR_PATH, position: P.position, index: P.index,
25
+ inputProps: { actorName: P.actorName, actorPath: ACTOR_PATH, position: SPLINE_POSITION, index: P.index,
25
26
  arriveTangent: P.arriveTangent, leaveTangent: P.leaveTangent, pointType: P.pointType },
26
27
  required: [], effect: 'write', latency: 'interactive', resources: 'low',
27
28
  exampleInput: { action: 'add_spline_point', actorName: 'Spline_1', position: { x: 100, y: 0, z: 0 } },
@@ -38,7 +39,7 @@ export const SPLINE_RECORDS = [
38
39
  id: 'build_environment.set_spline_point_position', action: 'set_spline_point_position', family: F,
39
40
  summary: 'Set the position of a spline point by index.',
40
41
  whenToUse: WU, whenNotToUse: ['The point should be moved interactively.'],
41
- inputProps: { actorName: P.actorName, actorPath: ACTOR_PATH, pointIndex: P.pointIndex, position: P.position },
42
+ inputProps: { actorName: P.actorName, actorPath: ACTOR_PATH, pointIndex: P.pointIndex, position: SPLINE_POSITION },
42
43
  required: [], effect: 'write', behavior: { idempotency: 'idempotent' }, latency: 'interactive', resources: 'low',
43
44
  exampleInput: { action: 'set_spline_point_position', actorName: 'Spline_1', pointIndex: 0, position: { x: 0, y: 0, z: 100 } },
44
45
  }),
@@ -185,7 +186,7 @@ export const SPLINE_RECORDS = [
185
186
  buildRecord({
186
187
  id: 'build_environment.get_splines_info', action: 'get_splines_info', family: F,
187
188
  topics: ['point count and length', 'closed loop', 'world points'],
188
- summary: 'List the spline actors in the level with each one\'s point count, length and world points (first 64); with actorName, one spline\'s points and types, length and closed-loop flag.',
189
+ summary: 'List the spline actors in the level with each one\'s point count, length and world points (first 64); with actorName, one spline\'s points (location relative to the actor, the space spline edits take, and worldLocation), types, length and closed-loop flag.',
189
190
  whenToUse: ['Spline actors must be enumerated.'],
190
191
  whenNotToUse: ['A specific spline path is already known.'],
191
192
  inputProps: { actorName: P.actorName },
@@ -13,7 +13,7 @@ const TARGET = { waterBodyName: { ...P.waterBodyName, description: 'Water body t
13
13
  export const WATER_RECORDS = [
14
14
  buildRecord({
15
15
  id: 'build_environment.create_water_body_ocean', action: 'create_water_body_ocean', family: F,
16
- summary: 'Create an ocean water body actor.',
16
+ summary: 'Create an ocean water body actor with the editor\'s default ocean material and waves.',
17
17
  whenToUse: WU, whenNotToUse: ['A lake or river water body is needed.'],
18
18
  inputProps: BODY,
19
19
  required: [], effect: 'write', latency: 'interactive', resources: 'medium',
@@ -45,10 +45,13 @@ export const WATER_RECORDS = [
45
45
  }),
46
46
  buildRecord({
47
47
  id: 'build_environment.configure_water_waves', action: 'configure_water_waves', family: F,
48
- summary: 'Configure water wave settings (height, length, amplitude).',
48
+ summary: 'Give a water body Gerstner waves, the swell its surface and anything floating on it follow: height, wavelength, steepness and wind direction. The call fails when the body does not end up holding the waves.',
49
49
  whenToUse: WU, whenNotToUse: ['Default waves are sufficient.'],
50
- inputProps: { waveHeight: P.waveHeight, waveLength: P.waveLength,
51
- amplitude: P.amplitude, steepness: P.steepness, direction: P.direction, ...TARGET },
50
+ inputProps: { waveHeight: { ...P.waveHeight, description: 'Height (amplitude) of the largest wave in cm; the body\'s other waves shrink to 15% of it, as a real sea\'s do. A calm harbour is about 5-10, open sea 50 or more.' },
51
+ waveLength: { ...P.waveLength, description: 'Wavelength of the longest wave in cm, crest to crest; the shortest waves are 13% of it (a harbour is about 1500-2500).' },
52
+ amplitude: { ...P.amplitude, description: 'Same as waveHeight; waveHeight wins when both are given.' },
53
+ steepness: { ...P.steepness, description: 'Crest sharpness of the short waves, 0 (smooth swell) to 1 (peaked); the long waves take about half. Keep it under about 0.3: steep crests from many waves fold the surface over itself.' },
54
+ direction: { ...P.direction, description: 'Wind direction: its yaw sets where the waves travel.' }, ...TARGET },
52
55
  required: [], effect: 'write', behavior: { idempotency: 'idempotent' }, latency: 'interactive', resources: 'low',
53
56
  exampleInput: { action: 'configure_water_waves', waveHeight: 1.0, waveLength: 10 },
54
57
  }),
@@ -70,7 +73,7 @@ export const WATER_RECORDS = [
70
73
  }),
71
74
  buildRecord({
72
75
  id: 'build_environment.create_buoyancy_component', action: 'create_buoyancy_component', topics: ['make a boat float'], family: F,
73
- summary: 'Create a buoyancy component on an actor for water interaction.',
76
+ summary: 'Make an actor float: add a buoyancy component (pontoons in settings.BuoyancyData) to an actor whose root is a physics-simulating mesh, and let it take the water body\'s overlap at level load, so one placed already in the water floats instead of sinking. In a Blueprint, add /Script/Water.BuoyancyComponent with edit_scs and set the class default bGenerateOverlapEventsDuringLevelStreaming to true.',
74
77
  whenToUse: WU, whenNotToUse: ['Buoyancy is not needed.'],
75
78
  inputProps: { actorPath: P.actorPath, actorName: P.actorName, targetActor: P.targetActor, settings: P.settings },
76
79
  required: [], effect: 'write', latency: 'interactive', resources: 'low',
@@ -1,5 +1,6 @@
1
- import { buildCoreRecord } from '../core/builder.js';
1
+ import { ANY_EDITOR_STATE, buildCoreRecord } from '../core/builder.js';
2
2
  import { DOMAIN, P } from './properties.js';
3
+ import { bool, str, vec3 } from '../shared/schema-props.js';
3
4
  const FAMILY_ATTACH = 'attachment';
4
5
  const FAMILY_BLUEPRINT = 'blueprint';
5
6
  const FAMILY_SNAPSHOT = 'snapshot';
@@ -12,10 +13,17 @@ export const ADVANCED_RECORDS = [
12
13
  domain: DOMAIN,
13
14
  family: FAMILY_ATTACH,
14
15
  topics: ['attach actor', 'parent actor', 'attach to actor', 'child actor', 'attach to socket', 'set actor parent'],
15
- summary: 'Attach a child actor to a parent actor in the scene hierarchy.',
16
- whenToUse: ['An actor must follow another actor transform.'],
16
+ summary: 'Attach a child actor to a parent actor in the scene hierarchy, or to a bone or socket of one of its components (a weapon or a case to a hand).',
17
+ whenToUse: ['An actor must follow another actor transform.', 'A prop must ride a character\'s hand, head or other bone: socketName with snapToTarget, then tune the grip with relativeLocation/relativeRotation.'],
17
18
  whenNotToUse: ['The actor should remain independent (use detach).'],
18
- inputProps: { childActor: P.childActor, parentActor: P.parentActor },
19
+ inputProps: {
20
+ childActor: P.childActor, parentActor: P.parentActor,
21
+ componentName: str('Component of the parent actor to attach to (default its root): on a character built from several meshes, the mesh that owns the bone.'),
22
+ socketName: str('Bone or socket on that component to attach to (hand_r, weapon_r, head). Refused with SOCKET_NOT_FOUND when the component has neither.'),
23
+ snapToTarget: bool('Snap the child onto the bone or socket instead of keeping its current world placement (default false).'),
24
+ relativeLocation: vec3('With snapToTarget: offset from the bone or socket in its own space, as [x, y, z].'),
25
+ relativeRotation: vec3('With snapToTarget: rotation relative to the bone or socket, as [pitch, yaw, roll] in degrees.'),
26
+ },
19
27
  required: ['childActor', 'parentActor'],
20
28
  effect: 'write',
21
29
  costLatency: 'interactive',
@@ -80,7 +88,7 @@ export const ADVANCED_RECORDS = [
80
88
  family: FAMILY_COLLISION,
81
89
  summary: 'Enable or disable collision on an actor, or on many actors at once with actorNames, as one undoable step; normalizes to set_collision.',
82
90
  whenToUse: ['Actor collision must be toggled.', 'Many actors must have collision toggled together (actorNames does them in one call).'],
83
- whenNotToUse: ['Per-component collision is required (use set_component_property).'],
91
+ whenNotToUse: ['One component only, or a mode other than on and off (QueryOnly, PhysicsOnly): use edit_component (edit set_properties) with CollisionEnabled, which takes the ECollisionEnabled names.'],
84
92
  inputProps: {
85
93
  actorName: P.actorName,
86
94
  actorNames: { type: 'array', items: { type: 'string' }, description: 'Several actors to toggle in one call and one undo step, in place of actorName; names not found are listed back under missing, and the actors changed under affectedActors (which the receipt lists as changes, with an actor handle each).' },
@@ -95,12 +103,25 @@ export const ADVANCED_RECORDS = [
95
103
  buildCoreRecord({
96
104
  parentTool: 'control_actor',
97
105
  action: 'call_actor_function',
106
+ editorStates: ANY_EDITOR_STATE,
98
107
  domain: DOMAIN,
99
108
  family: FAMILY_FUNCTION,
100
- summary: 'Call a named function on an actor with optional arguments; normalizes to call_function.',
101
- whenToUse: ['A Blueprint or native function on an actor must be invoked.'],
109
+ summary: 'Call a named function on an actor, or while Play In Editor runs on the game\'s GameInstance, GameMode or another framework object, with optional arguments; normalizes to call_function.',
110
+ whenToUse: [
111
+ 'A Blueprint or native function on an actor must be invoked.',
112
+ 'A function of the running game\'s GameInstance (save, score, reset) must be called during Play In Editor: actorName GameInstance.',
113
+ 'A function of one of the actor\'s components must be called (a body\'s GetCenterOfMass, a movement component\'s StopMovementImmediately): componentName.',
114
+ ],
102
115
  whenNotToUse: ['The function has side effects that cannot be undone.'],
103
- inputProps: { actorName: P.actorName, functionName: P.functionName, arguments: P.arguments },
116
+ inputProps: {
117
+ actorName: {
118
+ ...P.actorName,
119
+ description: 'Target actor name in the current level; while Play In Editor runs, GameInstance, GameMode, GameState, PlayerController, PlayerPawn, PlayerState or HUD names that object of the running game (the GameInstance is no actor).',
120
+ },
121
+ componentName: str('Call the function on this component of the actor instead of on the actor itself (refused with COMPONENT_NOT_FOUND when the actor has none of that name).'),
122
+ functionName: P.functionName,
123
+ arguments: P.arguments,
124
+ },
104
125
  required: ['actorName', 'functionName'],
105
126
  outputProps: { value: P.value },
106
127
  outputRequired: [],
@@ -147,7 +147,7 @@ export const SEARCH_RECORDS = [
147
147
  summary: 'Find all actors in the level matching a Unreal class name or path.',
148
148
  whenToUse: ['All instances of a class must be located.'],
149
149
  whenNotToUse: ['A tag-based lookup is more appropriate (use find_by_tag).'],
150
- inputProps: { className: P.className, class: { type: 'string', description: 'Unreal class name or path (alias of className).' }, classPath: { type: 'string', description: 'Unreal class path (e.g. /Script/Engine.PointLight or /Game/Enemies/BP_Bug) of the actors to find (alias of className).' } },
150
+ inputProps: { className: P.className, class: { type: 'string', description: 'Unreal class name or path (alias of className).' }, classPath: { type: 'string', description: 'Unreal class path (e.g. /Script/Engine.PointLight or /Game/Enemies/BP_Enemy) of the actors to find (alias of className).' } },
151
151
  required: [],
152
152
  requiredOneOf: ['className', 'class', 'classPath'],
153
153
  outputProps: FIND_OUTPUT,
@@ -164,7 +164,7 @@ export const SEARCH_RECORDS = [
164
164
  summary: 'Alias of find_by_class. The bridge dispatches both names to the same handler.',
165
165
  whenToUse: ['Preferred when callers use the explicit find_actors_by_class verb.'],
166
166
  whenNotToUse: ['Use find_by_class to avoid alias normalization.'],
167
- inputProps: { className: P.className, class: { type: 'string', description: 'Unreal class name or path (alias of className).' }, classPath: { type: 'string', description: 'Unreal class path (e.g. /Script/Engine.PointLight or /Game/Enemies/BP_Bug) of the actors to find (alias of className).' } },
167
+ inputProps: { className: P.className, class: { type: 'string', description: 'Unreal class name or path (alias of className).' }, classPath: { type: 'string', description: 'Unreal class path (e.g. /Script/Engine.PointLight or /Game/Enemies/BP_Enemy) of the actors to find (alias of className).' } },
168
168
  required: [],
169
169
  requiredOneOf: ['className', 'class', 'classPath'],
170
170
  outputProps: FIND_OUTPUT,
@@ -1,4 +1,4 @@
1
- import { buildCoreRecord } from '../core/builder.js';
1
+ import { ANY_EDITOR_STATE, buildCoreRecord } from '../core/builder.js';
2
2
  import { bool, num, str } from '../shared/schema-props.js';
3
3
  import { DOMAIN, P } from './properties.js';
4
4
  const FAMILY_SPAWN = 'spawn';
@@ -12,7 +12,7 @@ const SPAWN_UNDO = {
12
12
  const SPAWN_PLACEMENT = {
13
13
  groundZ: num('Z of the solid surface under the actor; absent when nothing is below it.'),
14
14
  groundClearance: num('How far the bottom of the actor\'s bounds sits above that surface; negative means it is sunk into it.'),
15
- placementWarning: str('Present when the placement looks wrong: it intersects other actors, is sunk below the surface under it (the bottom of its bounds is under it, wherever its pivot is; suggestedLocation rests it), floats more than 50 units above it, or has nothing below it (an actor held up from the side is mounted, never floating: see mountedOn). Tag the actor mcp.placement.ok when that is deliberate and it is never reported.'),
15
+ placementWarning: str('Present when the placement looks wrong: it intersects other actors, is sunk below the surface under it (the bottom of its bounds is under it, wherever its pivot is; suggestedLocation rests it), floats more than 50 units above it, or has nothing below it (an actor held up from the side is mounted, never floating: see mountedOn). A water body is a surface, not a solid: an actor partly under water (a buoy, a hull, a wading pawn) is neither intersecting nor sunk, and groundZ is the water level. Tag the actor mcp.placement.ok when that is deliberate and it is never reported.'),
16
16
  mountedOn: str('The actor this one hangs on from the side (a window band flush on a hall, an awning on a facade): its bounds touch or overlap that actor\'s vertical face, so it is held up and is not reported floating or without a surface below. Present only then.'),
17
17
  overlappingActors: {
18
18
  type: 'array',
@@ -31,6 +31,7 @@ export const SPAWN_RECORDS = [
31
31
  buildCoreRecord({
32
32
  parentTool: 'control_actor',
33
33
  action: 'spawn',
34
+ editorStates: ANY_EDITOR_STATE,
34
35
  domain: DOMAIN,
35
36
  family: FAMILY_SPAWN,
36
37
  topics: ['spawn actor', 'place actor', 'add actor to level', 'create actor', 'spawn cube', 'spawn static mesh', 'instantiate class'],
@@ -70,6 +71,7 @@ export const SPAWN_RECORDS = [
70
71
  buildCoreRecord({
71
72
  parentTool: 'control_actor',
72
73
  action: 'spawn_blueprint',
74
+ editorStates: ANY_EDITOR_STATE,
73
75
  domain: DOMAIN,
74
76
  family: FAMILY_SPAWN,
75
77
  topics: ['spawn blueprint actor', 'place blueprint in level', 'instantiate blueprint'],
@@ -103,6 +105,7 @@ export const SPAWN_RECORDS = [
103
105
  buildCoreRecord({
104
106
  parentTool: 'control_actor',
105
107
  action: 'spawn_batch',
108
+ editorStates: ANY_EDITOR_STATE,
106
109
  domain: DOMAIN,
107
110
  family: FAMILY_SPAWN,
108
111
  topics: ['spawn many actors', 'batch spawn', 'place many actors', 'lay out level', 'build level layout'],
@@ -117,7 +120,8 @@ export const SPAWN_RECORDS = [
117
120
  description: 'Actors to spawn, 1-500. Each is a spawn payload: classPath, blueprintPath or meshPath, plus '
118
121
  + 'actorName, location, rotation, scale ([x, y, z] arrays). Optional per item: materialPath (applied like '
119
122
  + 'set_material; componentName/materialSlot/allComponents narrow it), variables ({name: value} Blueprint '
120
- + 'variables set on the new instance, like set_blueprint_variables), folder (outliner folder path), tags '
123
+ + 'variables set on the new instance, like set_blueprint_variables; in a running game they are set before its '
124
+ + 'BeginPlay, so it starts with them), folder (outliner folder path), tags '
121
125
  + '(actor tags; delete_by_tag removes the batch again). Items that fail are reported; the rest still spawn.',
122
126
  },
123
127
  defaults: {
@@ -144,8 +148,9 @@ export const SPAWN_RECORDS = [
144
148
  type: 'array',
145
149
  items: { type: 'object', additionalProperties: true, 'x-unreal-reflection-boundary': true },
146
150
  'x-unreal-reflection-boundary': true,
147
- description: 'Per item (only the failed ones and those with a placementWarning under report: failures): index, success, '
148
- + 'name, path, error, errorCode, variablesSet, variablesError, materialApplied, materialError, and the placement '
151
+ description: 'Per item (only the failed ones and those with a placementWarning or ignoredKeys under report: failures): '
152
+ + 'index, success, name, path, error, errorCode, variablesSet, variablesError, materialApplied, materialError, '
153
+ + 'ignoredKeys (the item\'s keys no spawn reads, such as a "label" meant as actorName), and the placement '
149
154
  + 'facts set_transform reports (groundZ, groundClearance, placementWarning, overlappingActors, suggestedLocation), '
150
155
  + 'measured after the item took its tags, variables and material, so an item tagged mcp.placement.ok is never '
151
156
  + 'reported. name is the label the item asked for, or the unique actor name when it gave no actorName.',
@@ -239,6 +244,7 @@ export const SPAWN_RECORDS = [
239
244
  buildCoreRecord({
240
245
  parentTool: 'control_actor',
241
246
  action: 'delete',
247
+ editorStates: ANY_EDITOR_STATE,
242
248
  domain: DOMAIN,
243
249
  family: FAMILY_LIFECYCLE,
244
250
  topics: ['delete actor', 'destroy actor', 'remove actor from level', 'delete selected actor', 'delete spawned actor', 'delete object'],
@@ -257,6 +263,7 @@ export const SPAWN_RECORDS = [
257
263
  buildCoreRecord({
258
264
  parentTool: 'control_actor',
259
265
  action: 'destroy_actor',
266
+ editorStates: ANY_EDITOR_STATE,
260
267
  domain: DOMAIN,
261
268
  family: FAMILY_LIFECYCLE,
262
269
  summary: 'Long-form alias for delete. The bridge dispatches both names to the same handler.',
@@ -273,6 +280,7 @@ export const SPAWN_RECORDS = [
273
280
  buildCoreRecord({
274
281
  parentTool: 'control_actor',
275
282
  action: 'delete_by_tag',
283
+ editorStates: ANY_EDITOR_STATE,
276
284
  domain: DOMAIN,
277
285
  family: FAMILY_LIFECYCLE,
278
286
  summary: 'Permanently delete every actor matching a gameplay tag, or any of several tags in one call.',
@@ -1,4 +1,4 @@
1
- import { buildCoreRecord } from '../core/builder.js';
1
+ import { ANY_EDITOR_STATE, buildCoreRecord } from '../core/builder.js';
2
2
  import { DOMAIN, P } from './properties.js';
3
3
  const FAMILY_VISIBILITY = 'visibility';
4
4
  const FAMILY_QUERY = 'query';
@@ -93,6 +93,7 @@ export const STATE_RECORDS = [
93
93
  buildCoreRecord({
94
94
  parentTool: 'control_actor',
95
95
  action: 'list',
96
+ editorStates: ANY_EDITOR_STATE,
96
97
  domain: DOMAIN,
97
98
  family: FAMILY_QUERY,
98
99
  topics: ['list actors', 'all actors in level', 'actors in scene', 'enumerate actors', 'world outliner', 'actors in level', 'level actors', 'actor positions', 'actor locations', 'actor transforms', 'level layout', 'variable values of many actors', 'how many actors', 'count actors', 'actors in the level', 'actors near point', 'count enemies'],
@@ -1,4 +1,4 @@
1
- import { buildCoreRecord } from '../core/builder.js';
1
+ import { ANY_EDITOR_STATE, buildCoreRecord } from '../core/builder.js';
2
2
  import { DOMAIN, P } from './properties.js';
3
3
  const FAMILY_TRANSFORM = 'transform';
4
4
  const FAMILY_PHYSICS = 'physics';
@@ -59,6 +59,7 @@ export const TRANSFORM_RECORDS = [
59
59
  buildCoreRecord({
60
60
  parentTool: 'control_actor',
61
61
  action: 'set_transform',
62
+ editorStates: ANY_EDITOR_STATE,
62
63
  domain: DOMAIN,
63
64
  family: FAMILY_TRANSFORM,
64
65
  topics: ['move actor', 'set actor location', 'set position', 'rotate actor', 'set rotation', 'scale actor', 'teleport actor', 'translate'],
@@ -78,6 +79,7 @@ export const TRANSFORM_RECORDS = [
78
79
  buildCoreRecord({
79
80
  parentTool: 'control_actor',
80
81
  action: 'teleport_actor',
82
+ editorStates: ANY_EDITOR_STATE,
81
83
  domain: DOMAIN,
82
84
  family: FAMILY_TRANSFORM,
83
85
  summary: 'Alias of set_transform. The bridge dispatches both names to the same handler.',
@@ -95,6 +97,7 @@ export const TRANSFORM_RECORDS = [
95
97
  buildCoreRecord({
96
98
  parentTool: 'control_actor',
97
99
  action: 'set_actor_location',
100
+ editorStates: ANY_EDITOR_STATE,
98
101
  domain: DOMAIN,
99
102
  family: FAMILY_TRANSFORM,
100
103
  summary: 'Alias of set_transform (location-only intent); normalizes to set_transform.',
@@ -112,6 +115,7 @@ export const TRANSFORM_RECORDS = [
112
115
  buildCoreRecord({
113
116
  parentTool: 'control_actor',
114
117
  action: 'set_actor_rotation',
118
+ editorStates: ANY_EDITOR_STATE,
115
119
  domain: DOMAIN,
116
120
  family: FAMILY_TRANSFORM,
117
121
  summary: 'Alias of set_transform (rotation-only intent); normalizes to set_transform.',
@@ -129,6 +133,7 @@ export const TRANSFORM_RECORDS = [
129
133
  buildCoreRecord({
130
134
  parentTool: 'control_actor',
131
135
  action: 'set_actor_scale',
136
+ editorStates: ANY_EDITOR_STATE,
132
137
  domain: DOMAIN,
133
138
  family: FAMILY_TRANSFORM,
134
139
  summary: 'Alias of set_transform (scale-only intent); normalizes to set_transform.',
@@ -146,6 +151,7 @@ export const TRANSFORM_RECORDS = [
146
151
  buildCoreRecord({
147
152
  parentTool: 'control_actor',
148
153
  action: 'get_transform',
154
+ editorStates: ANY_EDITOR_STATE,
149
155
  domain: DOMAIN,
150
156
  family: FAMILY_TRANSFORM,
151
157
  topics: ['actor location', 'actor position', 'actor rotation', 'where is the actor'],
@@ -164,14 +170,16 @@ export const TRANSFORM_RECORDS = [
164
170
  ...buildCoreRecord({
165
171
  parentTool: 'control_actor',
166
172
  action: 'sample_motion',
173
+ editorStates: ANY_EDITOR_STATE,
167
174
  domain: DOMAIN,
168
175
  family: FAMILY_TRANSFORM,
169
- topics: ['sample motion', 'record trajectory', 'track actor over time', 'watch actor move', 'jump height'],
170
- summary: 'Watch an actor over game time in Play-In-Editor and return its location, velocity and chosen properties at every interval, plus start/end and min/max extents, in one call; it can also press keys at exact game times (inputs) and wait for another actor\'s property to change before it starts (startWhen).',
176
+ topics: ['sample motion', 'record trajectory', 'track actor over time', 'watch actor move', 'jump height', 'foot sliding', 'bone position over time'],
177
+ summary: 'Watch an actor over game time in Play-In-Editor and return its location, velocity, rotation and chosen properties at every interval, plus start/end and min/max extents, in one call; it can also follow points on the actor (bones, sockets, components) with their height over the ground, press keys at exact game times (inputs) and wait for another actor\'s property to change before it starts (startWhen).',
171
178
  whenToUse: [
172
179
  'A jump, spring launch, moving platform, enemy patrol or fall must be proven in PIE without a sleep-and-poll loop.',
173
180
  'The peak height, landing point or path of a moving actor is needed.',
174
181
  'An input must land at an exact moment (jump when a platform appears): inputs and startWhen run the whole timeline inside one call, so the caller\'s own delay between calls cannot shift it.',
182
+ 'Feet must be proven to plant without sliding, sinking or floating, or a hand or muzzle must be followed: points with groundTrace measure it per point.',
175
183
  ],
176
184
  whenNotToUse: ['Only the current transform is needed (use get_transform).', 'Nothing is playing: the editor world does not simulate (start PIE with control_editor.play).'],
177
185
  inputProps: {
@@ -194,11 +202,17 @@ export const TRANSFORM_RECORDS = [
194
202
  },
195
203
  description: 'Keys pressed and released at exact game times during the run (at most 32), e.g. [{"key":"D","atSeconds":0,"holdSeconds":2},{"key":"SpaceBar","atSeconds":0.6,"holdSeconds":0.2}]. A key still held when the run ends is released.',
196
204
  },
205
+ points: {
206
+ type: 'array', items: { type: 'string' }, maxItems: 8,
207
+ description: 'Places on the actor sampled with it (at most 8): a component by its name (LegL), a bone or socket of any of its components (foot_l, hand_r), or a component\'s own socket as Component.Socket (Weapon.Muzzle). Each sample\'s points gives each one\'s world location [x, y, z]; a name the actor lacks is refused with the names it has. Fewer samples are kept with points: 400 x 2 / (2 + points).',
208
+ },
209
+ groundTrace: { type: 'boolean', description: 'With points: each sample\'s aboveGround gives each point\'s height over the first surface below it that blocks Visibility (the actor and what is attached to it ignored), negative when the point is inside that surface, and pointStats sums up its contact.' },
210
+ contactCm: { type: 'number', description: 'With groundTrace: how far above its own lowest height a point still counts as planted (default 2 cm), so an ankle bone that never reaches the floor still counts as down when the foot is.' },
197
211
  startWhen: {
198
212
  type: 'object',
199
213
  properties: {
200
214
  actorName: { type: 'string', description: 'Actor whose property starts the run.' },
201
- propertyName: { type: 'string', description: 'That actor\'s property, as propertyNames reads it (e.g. bActorEnableCollision).' },
215
+ propertyName: { type: 'string', description: 'That actor\'s property, as propertyNames reads it: bActorEnableCollision, or a component\'s as Component.Property (CharacterMovement.MovementMode starts the run on a landing when equals is MOVE_Walking).' },
202
216
  equals: { description: 'Value that starts the run, as samples show it ("True", "False", 3).' },
203
217
  waitForChange: { type: 'boolean', description: 'Default true: start only when the value BECOMES equals (a platform appearing), not while it already is.' },
204
218
  maxWaitSeconds: { type: 'number', description: 'Game seconds to wait before giving up with endedBecause startWhenTimeout (default 10, at most 30).' },
@@ -213,12 +227,12 @@ export const TRANSFORM_RECORDS = [
213
227
  actorName: { type: 'string', description: 'The actor watched.' },
214
228
  samples: {
215
229
  type: 'array', items: { type: 'object', additionalProperties: true, 'x-unreal-reflection-boundary': true },
216
- description: 'One entry per sample: t (game seconds since the start), location [x, y, z], velocity [x, y, z], properties.',
230
+ description: 'One entry per sample: t (game seconds since the start), location [x, y, z], velocity [x, y, z], rotation [pitch, yaw, roll] in degrees (on the first sample and on each one where it changed, so a sample without it still has the last one written), properties, and with points their world locations (points) and heights over the ground (aboveGround, with groundTrace; a point with nothing below it within 10 m is left out).',
217
231
  },
218
232
  sampleCount: { type: 'number', description: 'How many samples were taken.' },
219
233
  gameSeconds: { type: 'number', description: 'Game time covered.' },
220
234
  realSeconds: { type: 'number', description: 'Wall-clock time the run took.' },
221
- endedBecause: { type: 'string', description: 'duration, realTimeCap, sampleCap, actorDestroyed (a PIE death that reloads the level ends here), worldEnded (PIE stopped) or startWhenTimeout (startWhen never happened within maxWaitSeconds).' },
235
+ endedBecause: { type: 'string', description: 'duration, realTimeCap, sampleCap, actorDestroyed (a PIE death that reloads the level ends here), worldEnded (PIE stopped), startWhenTimeout (startWhen never happened within maxWaitSeconds) or gamePaused (game time stood still for 3 s: a title or pause menu holds the game; the warning says how to get past it).' },
222
236
  inputsApplied: {
223
237
  type: 'array', items: { type: 'object', additionalProperties: true, 'x-unreal-reflection-boundary': true },
224
238
  description: 'One entry per input: key, at, hold, and down/up, the game seconds since the start when it was pressed and released (up is when the run ended for a key still held).',
@@ -229,6 +243,10 @@ export const TRANSFORM_RECORDS = [
229
243
  min: { type: 'array', items: { type: 'number' }, description: 'Smallest x, y and z sampled (the lowest point is min[2]).' },
230
244
  max: { type: 'array', items: { type: 'number' }, description: 'Largest x, y and z sampled (the peak height is max[2]).' },
231
245
  missingProperties: { type: 'array', items: { type: 'string' }, description: 'propertyNames the actor\'s class does not have.' },
246
+ pointStats: {
247
+ type: 'object', additionalProperties: true, 'x-unreal-reflection-boundary': true,
248
+ description: 'Per point: min and max [x, y, z] over the run; with groundTrace also minAboveGround and maxAboveGround (a negative minimum means it sank into the surface, a large one that it never touched it), contactSeconds (time spent planted) and contactSlip (cm it moved across the ground while planted: a planted foot that slides shows here).',
249
+ },
232
250
  windowRestored: { type: 'boolean', description: 'True when the editor window was minimized: a minimized editor runs PIE at about 3 fps, so it was put back on screen, without taking focus, before the run and is minimized again when the run ends. The background CPU throttle (Use Less CPU when in Background) is off for the run only, whatever the window did.' },
233
251
  },
234
252
  outputRequired: [],
@@ -236,9 +254,9 @@ export const TRANSFORM_RECORDS = [
236
254
  costLatency: 'interactive',
237
255
  exampleInput: { action: 'sample_motion', actorName: 'PlayerPawn', durationSeconds: 1.5, propertyNames: ['bDead'] },
238
256
  exampleOutput: {
239
- success: true, message: '31 samples of BP_Mario_C_0 over 1.50 game seconds (duration)',
240
- actorName: 'BP_Mario_C_0', sampleCount: 31, gameSeconds: 1.5, realSeconds: 3.2, endedBecause: 'duration',
241
- samples: [{ t: 0, location: [8500, 0, 56.1], velocity: [0, 0, 0], properties: { bDead: 'False' } }],
257
+ success: true, message: '31 samples of BP_Hero_C_0 over 1.50 game seconds (duration)',
258
+ actorName: 'BP_Hero_C_0', sampleCount: 31, gameSeconds: 1.5, realSeconds: 3.2, endedBecause: 'duration',
259
+ samples: [{ t: 0, location: [8500, 0, 56.1], velocity: [0, 0, 0], rotation: [0, 90, 0], properties: { bDead: 'False' } }],
242
260
  start: [8500, 0, 56.1], end: [9310, 0, 130.2], min: [8500, 0, 56.1], max: [9310, 0, 302.4],
243
261
  },
244
262
  }),
@@ -106,7 +106,10 @@ export const ASSET_RECORDS = [
106
106
  assetPaths: { type: 'array', items: { type: 'string' }, description: 'Save only these assets or levels, e.g. ["/Game/UI/WBP_Menu"], and leave every other dirty package as it is; omit to save everything dirty.' },
107
107
  },
108
108
  required: [],
109
- outputProps: { compensation: COMPENSATION },
109
+ outputProps: {
110
+ compensation: COMPENSATION,
111
+ leftDirtyPackages: { type: 'array', items: { type: 'string' }, description: 'With assetPaths: the other packages that still hold unsaved changes, left as they were.' },
112
+ },
110
113
  effect: 'write',
111
114
  costLatency: 'interactive', costResources: 'medium',
112
115
  exampleInput: { action: 'save_all' },
@@ -1,10 +1,11 @@
1
- import { buildCoreRecord } from '../core/builder.js';
1
+ import { ANY_EDITOR_STATE, buildCoreRecord } from '../core/builder.js';
2
2
  import { P } from './properties.js';
3
3
  const F = 'camera';
4
4
  const D = 'editor';
5
5
  export const CAMERA_RECORDS = [
6
6
  buildCoreRecord({
7
7
  parentTool: 'control_editor', action: 'set_view_target', domain: D, family: F,
8
+ editorStates: ANY_EDITOR_STATE,
8
9
  summary: 'Set the PIE view target to a specific actor by name.',
9
10
  whenToUse: ['The camera must follow or focus on a specific actor in PIE.'],
10
11
  whenNotToUse: ['A fixed camera position is preferred (use set_camera).'],
@@ -15,6 +16,7 @@ export const CAMERA_RECORDS = [
15
16
  }),
16
17
  buildCoreRecord({
17
18
  parentTool: 'control_editor', action: 'set_game_view_target', dispatchAction: 'set_view_target',
19
+ editorStates: ANY_EDITOR_STATE,
18
20
  domain: D, family: F,
19
21
  summary: 'Set the PIE view target (alias for set_view_target).',
20
22
  whenToUse: ['The camera view target must be set using the set_game_view_target alias.'],
@@ -26,6 +28,7 @@ export const CAMERA_RECORDS = [
26
28
  }),
27
29
  buildCoreRecord({
28
30
  parentTool: 'control_editor', action: 'set_camera', domain: D, family: F,
31
+ editorStates: ANY_EDITOR_STATE,
29
32
  summary: 'Set the viewport camera position and rotation: the level viewport, or, while Play In Editor runs with the player ejected (control_editor play control=eject), the free camera the game view is drawn from.',
30
33
  whenToUse: [
31
34
  'The viewport camera must be moved to a specific position and orientation.',
@@ -49,6 +52,7 @@ export const CAMERA_RECORDS = [
49
52
  }),
50
53
  buildCoreRecord({
51
54
  parentTool: 'control_editor', action: 'set_camera_fov', domain: D, family: F,
55
+ editorStates: ANY_EDITOR_STATE,
52
56
  summary: 'Set the camera field of view of the view on screen: the level viewport, the free view of an ejected player, or while the player plays the running game\'s camera (method player_camera_manager; locked to the value until play stops).',
53
57
  whenToUse: ['The camera FOV must be adjusted for the viewport.'],
54
58
  whenNotToUse: ['The default FOV is acceptable.'],
@@ -1,4 +1,4 @@
1
- import { buildCoreRecord } from '../core/builder.js';
1
+ import { ANY_EDITOR_STATE, buildCoreRecord } from '../core/builder.js';
2
2
  import { P } from './properties.js';
3
3
  const F = 'command';
4
4
  const D = 'editor';
@@ -176,6 +176,7 @@ export const COMMAND_RECORDS = [
176
176
  }),
177
177
  buildCoreRecord({
178
178
  parentTool: 'control_editor', action: 'open_editor_tab', dispatchAction: 'control_editor',
179
+ editorStates: ANY_EDITOR_STATE,
179
180
  domain: D, family: F,
180
181
  summary: 'Open a registered editor tab by id via FGlobalTabmanager, the same path the Window menu uses. Content-source plugins register their windows globally — Bridge as "BridgeTab" — so this reaches them without depending on either plugin. Fab registers no fixed id (it numbers each tab Fab1, Fab2, ...), so tabId "Fab" opens a new Fab tab through the Fab browser API (UE 5.8+). This is also the correct way to authenticate against those services: each owns its own sign-in and persists its own session, so opening its window lets it log in on its own terms rather than reimplementing a login.',
181
182
  whenToUse: [
@@ -198,6 +199,7 @@ export const COMMAND_RECORDS = [
198
199
  }),
199
200
  buildCoreRecord({
200
201
  parentTool: 'control_editor', action: 'console_command', dispatchAction: 'console_command',
202
+ editorStates: ANY_EDITOR_STATE,
201
203
  domain: D, family: F,
202
204
  topics: ['console command', 'exec command', 'run command', 'stat fps', 'cheat command', 'type a cheat code'],
203
205
  summary: 'Execute an Unreal console command via cross-parent dispatch to the console_command bridge action.',
@@ -210,6 +212,7 @@ export const COMMAND_RECORDS = [
210
212
  }),
211
213
  buildCoreRecord({
212
214
  parentTool: 'control_editor', action: 'restore_editor_window', domain: D, family: F,
215
+ editorStates: ANY_EDITOR_STATE,
213
216
  summary: 'Restore or minimize the main editor window without giving it focus. Restoring also stops the editor throttling itself '
214
217
  + 'while in the background (a minimized editor runs Play In Editor at about 3 fps, which makes every timed test lie); '
215
218
  + 'minimize puts the window away and turns the throttle back on, so an editor kept out of the way costs the machine next to nothing.',
@@ -235,6 +238,7 @@ export const COMMAND_RECORDS = [
235
238
  }),
236
239
  buildCoreRecord({
237
240
  parentTool: 'control_editor', action: 'set_preferences', domain: D, family: F,
241
+ editorStates: ANY_EDITOR_STATE,
238
242
  summary: 'Set editor preferences for a category. Distinct from system_control set_project_setting.',
239
243
  whenToUse: ['Editor preferences must be configured for a category.'],
240
244
  whenNotToUse: ['Project settings are needed (use system_control set_project_setting).'],
@@ -1,10 +1,11 @@
1
- import { buildCoreRecord } from '../core/builder.js';
1
+ import { ANY_EDITOR_STATE, buildCoreRecord } from '../core/builder.js';
2
2
  import { P } from './properties.js';
3
3
  const F = 'input';
4
4
  const D = 'editor';
5
5
  export const INPUT_RECORDS = [
6
6
  buildCoreRecord({
7
7
  parentTool: 'control_editor', action: 'simulate_input', domain: D, family: F,
8
+ editorStates: ANY_EDITOR_STATE,
8
9
  aliases: ['control_editor.click_widget', 'control_editor.widget_click', 'control_editor.press_ui_button'],
9
10
  topics: ['click button', 'click ui button', 'click button in running game', 'check or toggle a checkbox in running game', 'press key', 'press jump key', 'simulate key press', 'drive game ui', 'test running game', 'list live widgets', 'list widgets in running game', 'widgets on screen', 'list buttons on screen', 'press space', 'press spacebar', 'hold key down', 'list open widgets in game'],
10
11
  summary: 'Simulate a keyboard or mouse input event (key_down, key_up, key_tap, mouse_click, mouse_move), or list and press the live UMG widgets of a PIE session (widget_list, widget_click).',
@@ -1,4 +1,4 @@
1
- import { buildCoreRecord } from '../core/builder.js';
1
+ import { ANY_EDITOR_STATE, buildCoreRecord } from '../core/builder.js';
2
2
  import { P } from './properties.js';
3
3
  const F = 'screenshot';
4
4
  const D = 'editor';
@@ -60,6 +60,7 @@ const SCREENSHOT_OUTPUT = {
60
60
  export const SCREENSHOT_RECORDS = [
61
61
  buildCoreRecord({
62
62
  parentTool: 'control_editor', action: 'screenshot', domain: D, family: F,
63
+ editorStates: ANY_EDITOR_STATE,
63
64
  summary: 'Capture a screenshot from the editor viewport, game viewport, or full editor window.',
64
65
  whenToUse: ['A visual snapshot of the editor or game viewport is needed.'],
65
66
  whenNotToUse: ['A real-time capture stream is needed.'],
@@ -1,10 +1,11 @@
1
- import { buildCoreRecord } from '../core/builder.js';
1
+ import { ANY_EDITOR_STATE, buildCoreRecord } from '../core/builder.js';
2
2
  import { P } from './properties.js';
3
3
  const F = 'session';
4
4
  const D = 'editor';
5
5
  export const SESSION_RECORDS = [
6
6
  buildCoreRecord({
7
7
  parentTool: 'control_editor', action: 'play', domain: D, family: F,
8
+ editorStates: ANY_EDITOR_STATE,
8
9
  topics: ['play in editor', 'pie', 'start pie', 'start game', 'run game', 'press play', 'simulate'],
9
10
  aliases: ['control_editor.start_pie'],
10
11
  summary: 'Start Play-In-Editor (PIE) session; answers once the play world has begun play.',
@@ -18,6 +19,7 @@ export const SESSION_RECORDS = [
18
19
  }),
19
20
  buildCoreRecord({
20
21
  parentTool: 'control_editor', action: 'stop', domain: D, family: F,
22
+ editorStates: ANY_EDITOR_STATE,
21
23
  topics: ['stop pie', 'stop game', 'end play', 'exit pie'],
22
24
  summary: 'Stop the running PIE session.',
23
25
  whenToUse: ['The PIE session must be terminated.'],
@@ -30,6 +32,7 @@ export const SESSION_RECORDS = [
30
32
  }),
31
33
  buildCoreRecord({
32
34
  parentTool: 'control_editor', action: 'stop_pie', dispatchAction: 'stop',
35
+ editorStates: ANY_EDITOR_STATE,
33
36
  domain: D, family: F,
34
37
  summary: 'Stop the running PIE session (alias for stop).',
35
38
  whenToUse: ['The PIE session must be terminated using the stop_pie alias.'],
@@ -42,6 +45,7 @@ export const SESSION_RECORDS = [
42
45
  }),
43
46
  buildCoreRecord({
44
47
  parentTool: 'control_editor', action: 'pause', domain: D, family: F,
48
+ editorStates: ANY_EDITOR_STATE,
45
49
  summary: 'Pause the running PIE session.',
46
50
  whenToUse: ['PIE must be paused without stopping.'],
47
51
  whenNotToUse: ['PIE is not running or already paused.'],
@@ -52,6 +56,7 @@ export const SESSION_RECORDS = [
52
56
  }),
53
57
  buildCoreRecord({
54
58
  parentTool: 'control_editor', action: 'resume', domain: D, family: F,
59
+ editorStates: ANY_EDITOR_STATE,
55
60
  summary: 'Resume a paused PIE session.',
56
61
  whenToUse: ['A paused PIE session must resume.'],
57
62
  whenNotToUse: ['PIE is not paused.'],
@@ -62,6 +67,7 @@ export const SESSION_RECORDS = [
62
67
  }),
63
68
  buildCoreRecord({
64
69
  parentTool: 'control_editor', action: 'eject', domain: D, family: F,
70
+ editorStates: ANY_EDITOR_STATE,
65
71
  summary: 'Eject the player from its pawn in PIE, as the editor\'s Eject button does: the session switches to Simulate in Editor and the view becomes a free camera that set_camera moves and screenshot photographs. Answers once the view has switched.',
66
72
  whenToUse: ['The player must detach from the possessed pawn.', 'The view of a running game must be placed for a screenshot: eject, then set_camera.'],
67
73
  whenNotToUse: ['PIE is not running (NO_ACTIVE_SESSION).', 'The game must keep playing from the pawn: an ejected player no longer drives it.'],
@@ -80,6 +86,7 @@ export const SESSION_RECORDS = [
80
86
  }),
81
87
  buildCoreRecord({
82
88
  parentTool: 'control_editor', action: 'possess', domain: D, family: F,
89
+ editorStates: ANY_EDITOR_STATE,
83
90
  summary: 'Possess a pawn in PIE: the player controller takes the pawn named by actorName. Without actorName it brings an ejected player back to its own pawn, as the editor\'s Possess button does (the way back from eject). Answers once the player is back in the game.',
84
91
  whenToUse: ['The player must take control of a specific pawn.', 'An ejected player must return to the game (no actorName).'],
85
92
  whenNotToUse: ['PIE is not running (NOT_IN_PIE).', 'The actor is not a pawn (INVALID_TARGET).'],