@uemcp/server 1.10.0 → 1.12.0
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/README.md +63 -1
- package/dist/index.mjs +1983 -50
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -362,6 +362,18 @@ const TOOL_METADATA = {
|
|
|
362
362
|
"source",
|
|
363
363
|
"build.cs"
|
|
364
364
|
]),
|
|
365
|
+
add_nav_link: mutates("level", "add_nav_link", [
|
|
366
|
+
"navmesh",
|
|
367
|
+
"navigation",
|
|
368
|
+
"nav link",
|
|
369
|
+
"jump"
|
|
370
|
+
]),
|
|
371
|
+
add_nav_modifier_volume: mutates("level", "add_nav_modifier_volume", [
|
|
372
|
+
"navmesh",
|
|
373
|
+
"navigation",
|
|
374
|
+
"nav area",
|
|
375
|
+
"block"
|
|
376
|
+
]),
|
|
365
377
|
add_post_process_material: mutates("fx", "add_post_process_material"),
|
|
366
378
|
add_reflected_member: mutates("build", void 0, [
|
|
367
379
|
"uproperty",
|
|
@@ -372,6 +384,11 @@ const TOOL_METADATA = {
|
|
|
372
384
|
add_sequence_binding: mutates("sequence", "add_sequence_binding"),
|
|
373
385
|
add_sequence_keys: mutates("sequence", "add_sequence_keys"),
|
|
374
386
|
add_sequence_track: mutates("sequence", "add_sequence_track"),
|
|
387
|
+
add_smart_object_component: idempotentMutates("ai", "add_smart_object_component", [
|
|
388
|
+
"smart object",
|
|
389
|
+
"slot",
|
|
390
|
+
"claim"
|
|
391
|
+
]),
|
|
375
392
|
add_state_tree_component: mutates("ai", "add_state_tree_component"),
|
|
376
393
|
add_state_tree_state: mutates("ai", "add_state_tree_state"),
|
|
377
394
|
add_stimuli_source: mutates("ai", "add_stimuli_source", [
|
|
@@ -477,10 +494,27 @@ const TOOL_METADATA = {
|
|
|
477
494
|
create_landscape: mutates("level", "create_landscape"),
|
|
478
495
|
create_level_sequence: mutates("sequence", "create_level_sequence"),
|
|
479
496
|
create_material_instance: mutates("fx", "create_material_instance"),
|
|
497
|
+
create_mass_entity_config: mutates("ai", "create_mass_entity_config", [
|
|
498
|
+
"mass",
|
|
499
|
+
"crowd",
|
|
500
|
+
"entity config",
|
|
501
|
+
"trait"
|
|
502
|
+
]),
|
|
480
503
|
create_metasound: mutates("audio", "create_metasound"),
|
|
481
504
|
create_montage: mutates("anim", "create_montage"),
|
|
482
505
|
create_pcg_graph: mutates("fx", "create_pcg_graph"),
|
|
506
|
+
create_nav_area: mutates("level", "create_nav_area", [
|
|
507
|
+
"navmesh",
|
|
508
|
+
"navigation",
|
|
509
|
+
"nav area",
|
|
510
|
+
"cost"
|
|
511
|
+
]),
|
|
483
512
|
create_post_process_volume: mutates("fx", "create_post_process_volume"),
|
|
513
|
+
create_smart_object_definition: mutates("ai", "create_smart_object_definition", [
|
|
514
|
+
"smart object",
|
|
515
|
+
"slot",
|
|
516
|
+
"activity"
|
|
517
|
+
]),
|
|
484
518
|
create_sound_cue: mutates("audio", "create_sound_cue"),
|
|
485
519
|
create_state_tree: mutates("ai", "create_state_tree"),
|
|
486
520
|
create_struct: mutates("blueprint", "create_struct"),
|
|
@@ -494,6 +528,13 @@ const TOOL_METADATA = {
|
|
|
494
528
|
delete_asset: destroys("asset", "delete_asset"),
|
|
495
529
|
delete_data_table: destroys("asset", "delete_data_table"),
|
|
496
530
|
destroy_actor: destroys("level", "destroy_actor"),
|
|
531
|
+
diagnose_navmesh: readOnly("level", "diagnose_navmesh", [
|
|
532
|
+
"navmesh",
|
|
533
|
+
"navigation",
|
|
534
|
+
"island",
|
|
535
|
+
"spawn",
|
|
536
|
+
"reachable"
|
|
537
|
+
]),
|
|
497
538
|
disconnect_pins: mutates("blueprint", "disconnect_pins"),
|
|
498
539
|
doctor: readOnly("core", void 0, [
|
|
499
540
|
"diagnose",
|
|
@@ -509,6 +550,12 @@ const TOOL_METADATA = {
|
|
|
509
550
|
"generator",
|
|
510
551
|
"score"
|
|
511
552
|
]),
|
|
553
|
+
edit_mass_entity_config: mutates("ai", "edit_mass_entity_config", [
|
|
554
|
+
"mass",
|
|
555
|
+
"crowd",
|
|
556
|
+
"entity config",
|
|
557
|
+
"trait"
|
|
558
|
+
]),
|
|
512
559
|
enable_toolset: idempotentMutates("core", void 0, [
|
|
513
560
|
"toolset",
|
|
514
561
|
"tools",
|
|
@@ -532,6 +579,13 @@ const TOOL_METADATA = {
|
|
|
532
579
|
"registry"
|
|
533
580
|
]),
|
|
534
581
|
find_blueprint_references: readOnly("blueprint", "find_blueprint_references"),
|
|
582
|
+
find_path: readOnly("level", "find_path", [
|
|
583
|
+
"navmesh",
|
|
584
|
+
"navigation",
|
|
585
|
+
"path",
|
|
586
|
+
"pathfinding",
|
|
587
|
+
"reachable"
|
|
588
|
+
]),
|
|
535
589
|
find_symbol: readOnly("build", void 0, [
|
|
536
590
|
"symbol",
|
|
537
591
|
"definition",
|
|
@@ -595,6 +649,12 @@ const TOOL_METADATA = {
|
|
|
595
649
|
get_editor_state: readOnly("core", "get_editor_state"),
|
|
596
650
|
get_eqs_query: readOnly("ai", "get_eqs_query"),
|
|
597
651
|
get_import_job_status: readOnly("asset", "get_import_job_status"),
|
|
652
|
+
get_mass_entity_config: readOnly("ai", "get_mass_entity_config", [
|
|
653
|
+
"mass",
|
|
654
|
+
"crowd",
|
|
655
|
+
"entity config",
|
|
656
|
+
"trait"
|
|
657
|
+
]),
|
|
598
658
|
get_net_stats: readOnly("test", "get_net_stats", [
|
|
599
659
|
"network",
|
|
600
660
|
"multiplayer",
|
|
@@ -606,6 +666,7 @@ const TOOL_METADATA = {
|
|
|
606
666
|
get_pie_status: readOnly("test", "get_pie_status"),
|
|
607
667
|
get_project_id: readOnly("core", void 0, ["projectid", "identity"]),
|
|
608
668
|
get_render_job_status: readOnly("sequence", "get_render_job_status"),
|
|
669
|
+
get_smart_object_definition: readOnly("ai", "get_smart_object_definition", ["smart object", "slot"]),
|
|
609
670
|
get_source_control_job_status: readOnly("asset", "get_source_control_job_status"),
|
|
610
671
|
get_source_control_status: readOnly("asset", "get_source_control_status"),
|
|
611
672
|
get_state_tree: readOnly("ai", "get_state_tree"),
|
|
@@ -629,6 +690,12 @@ const TOOL_METADATA = {
|
|
|
629
690
|
"enhanced input"
|
|
630
691
|
]),
|
|
631
692
|
launch_on_device: reachesOutside("test", false, "launch_on_device"),
|
|
693
|
+
layout_graph: idempotentMutates("blueprint", "layout_graph", [
|
|
694
|
+
"arrange",
|
|
695
|
+
"tidy",
|
|
696
|
+
"overlap",
|
|
697
|
+
"format"
|
|
698
|
+
]),
|
|
632
699
|
link_state_tree_state: mutates("ai", "link_state_tree_state", ["subtree", "linked"]),
|
|
633
700
|
list_actors: readOnly("core", "list_actors"),
|
|
634
701
|
list_asset_factories: readOnly("asset", "list_asset_factories"),
|
|
@@ -674,6 +741,11 @@ const TOOL_METADATA = {
|
|
|
674
741
|
refresh_source_control_status: idempotentMutates("asset", "refresh_source_control_status"),
|
|
675
742
|
reimport_asset: reachesOutside("asset", false, "reimport_asset"),
|
|
676
743
|
remove_graph_node: destroys("blueprint", "remove_graph_node"),
|
|
744
|
+
remove_state_tree_elements: destroys("ai", "remove_state_tree_elements", [
|
|
745
|
+
"delete",
|
|
746
|
+
"state",
|
|
747
|
+
"transition"
|
|
748
|
+
]),
|
|
677
749
|
rename_asset: mutates("asset", "rename_asset"),
|
|
678
750
|
rename_data_table: mutates("asset", "rename_data_table"),
|
|
679
751
|
rename_data_table_row: mutates("asset", "rename_data_table_row"),
|
|
@@ -720,7 +792,25 @@ const TOOL_METADATA = {
|
|
|
720
792
|
set_import_settings: idempotentMutates("asset", "set_import_settings"),
|
|
721
793
|
set_material_params: idempotentMutates("fx", "set_material_params"),
|
|
722
794
|
set_metasound_graph: idempotentMutates("audio", "set_metasound_graph"),
|
|
795
|
+
set_crowd_settings: idempotentMutates("level", "set_crowd_settings", [
|
|
796
|
+
"crowd",
|
|
797
|
+
"avoidance",
|
|
798
|
+
"rvo",
|
|
799
|
+
"detour"
|
|
800
|
+
]),
|
|
723
801
|
set_montage_sections: idempotentMutates("anim", "set_montage_sections"),
|
|
802
|
+
set_nav_agents: idempotentMutates("level", "set_nav_agents", [
|
|
803
|
+
"navmesh",
|
|
804
|
+
"navigation",
|
|
805
|
+
"agent",
|
|
806
|
+
"radius"
|
|
807
|
+
]),
|
|
808
|
+
set_navmesh_settings: idempotentMutates("level", "set_navmesh_settings", [
|
|
809
|
+
"navmesh",
|
|
810
|
+
"navigation",
|
|
811
|
+
"recast",
|
|
812
|
+
"cell size"
|
|
813
|
+
]),
|
|
724
814
|
set_niagara_params: idempotentMutates("fx", "set_niagara_params"),
|
|
725
815
|
set_pin_default: idempotentMutates("blueprint", "set_pin_default"),
|
|
726
816
|
set_post_process_settings: idempotentMutates("fx", "set_post_process_settings"),
|
|
@@ -751,6 +841,12 @@ const TOOL_METADATA = {
|
|
|
751
841
|
"output",
|
|
752
842
|
"tail"
|
|
753
843
|
]),
|
|
844
|
+
test_reachability: readOnly("level", "test_reachability", [
|
|
845
|
+
"navmesh",
|
|
846
|
+
"navigation",
|
|
847
|
+
"reachable",
|
|
848
|
+
"sweep"
|
|
849
|
+
]),
|
|
754
850
|
toggle_show_flags: idempotentMutates("level", "toggle_show_flags"),
|
|
755
851
|
trace_state_tree: mutates("ai", "trace_state_tree", [
|
|
756
852
|
"pie",
|
|
@@ -760,6 +856,17 @@ const TOOL_METADATA = {
|
|
|
760
856
|
trigger_hot_reload: mutates("build", "start_hot_reload"),
|
|
761
857
|
trigger_live_compile: mutates("build", "start_live_compile", ["live coding", "recompile"]),
|
|
762
858
|
undo: mutates("core", "undo"),
|
|
859
|
+
validate_mass_entity_config: readOnly("ai", "validate_mass_entity_config", [
|
|
860
|
+
"mass",
|
|
861
|
+
"crowd",
|
|
862
|
+
"entity config",
|
|
863
|
+
"trait"
|
|
864
|
+
]),
|
|
865
|
+
update_state_tree_elements: mutates("ai", "update_state_tree_elements", [
|
|
866
|
+
"edit",
|
|
867
|
+
"rename",
|
|
868
|
+
"retarget"
|
|
869
|
+
]),
|
|
763
870
|
wait_for_job: readOnly("core", void 0, [
|
|
764
871
|
"poll",
|
|
765
872
|
"block",
|
|
@@ -1352,6 +1459,10 @@ const bridgeBlueprintNodeSchema = z.object({
|
|
|
1352
1459
|
nodeId: z.string(),
|
|
1353
1460
|
pinCount: z.number().int().min(0),
|
|
1354
1461
|
pins: z.array(bridgeBlueprintPinSchema),
|
|
1462
|
+
position: z.object({
|
|
1463
|
+
x: z.number().int(),
|
|
1464
|
+
y: z.number().int()
|
|
1465
|
+
}).optional(),
|
|
1355
1466
|
title: z.string()
|
|
1356
1467
|
});
|
|
1357
1468
|
const bridgeErrorResponseSchema = z.object({
|
|
@@ -2575,6 +2686,7 @@ const BRIDGE_CONNECT_PINS_REQUEST_TYPE = "connect_pins";
|
|
|
2575
2686
|
const BRIDGE_DISCONNECT_PINS_REQUEST_TYPE = "disconnect_pins";
|
|
2576
2687
|
const BRIDGE_SET_PIN_DEFAULT_REQUEST_TYPE = "set_pin_default";
|
|
2577
2688
|
const BRIDGE_LIST_AVAILABLE_NODES_REQUEST_TYPE = "list_available_nodes";
|
|
2689
|
+
const BRIDGE_LAYOUT_GRAPH_REQUEST_TYPE = "layout_graph";
|
|
2578
2690
|
const BRIDGE_GRAPH_PIN_VALUE_MAX_CHARS = 4096;
|
|
2579
2691
|
const BRIDGE_GRAPH_NODE_POSITION_LIMIT = 1e6;
|
|
2580
2692
|
const BRIDGE_GRAPH_NODE_KINDS = [
|
|
@@ -2592,6 +2704,10 @@ const graphNodePositionSchema = z.object({
|
|
|
2592
2704
|
x: z.number().int().min(-1e6).max(BRIDGE_GRAPH_NODE_POSITION_LIMIT).default(0),
|
|
2593
2705
|
y: z.number().int().min(-1e6).max(BRIDGE_GRAPH_NODE_POSITION_LIMIT).default(0)
|
|
2594
2706
|
});
|
|
2707
|
+
const graphNodePlacedPositionSchema = z.object({
|
|
2708
|
+
x: z.number().int(),
|
|
2709
|
+
y: z.number().int()
|
|
2710
|
+
});
|
|
2595
2711
|
const bridgeListGraphNodesRequestSchema = z.object({
|
|
2596
2712
|
assetPath: assetPathSchema,
|
|
2597
2713
|
cursor: assetCursorSchema.optional(),
|
|
@@ -2604,6 +2720,7 @@ const bridgeListGraphNodesRequestSchema = z.object({
|
|
|
2604
2720
|
});
|
|
2605
2721
|
const bridgeAddGraphNodeRequestFieldsSchema = z.object({
|
|
2606
2722
|
assetPath: assetPathSchema,
|
|
2723
|
+
autoLayout: z.boolean().optional(),
|
|
2607
2724
|
graphName: graphNameSchema,
|
|
2608
2725
|
nodeClass: assetPathSchema.optional(),
|
|
2609
2726
|
kind: graphNodeKindSchema,
|
|
@@ -2655,6 +2772,13 @@ const bridgeSetPinDefaultRequestSchema = z.object({
|
|
|
2655
2772
|
value: graphPinValueSchema,
|
|
2656
2773
|
version: z.literal(2)
|
|
2657
2774
|
});
|
|
2775
|
+
const bridgeLayoutGraphRequestSchema = z.object({
|
|
2776
|
+
assetPath: assetPathSchema,
|
|
2777
|
+
graphName: graphNameSchema,
|
|
2778
|
+
requestId: requestIdSchema,
|
|
2779
|
+
type: z.literal(BRIDGE_LAYOUT_GRAPH_REQUEST_TYPE),
|
|
2780
|
+
version: z.literal(2)
|
|
2781
|
+
});
|
|
2658
2782
|
const bridgeListAvailableNodesRequestSchema = z.object({
|
|
2659
2783
|
assetPath: assetPathSchema,
|
|
2660
2784
|
cursor: assetCursorSchema.optional(),
|
|
@@ -2683,6 +2807,7 @@ const bridgeAddGraphNodeSuccessResponseSchema = z.object({
|
|
|
2683
2807
|
message: nonEmptyStringSchema.optional(),
|
|
2684
2808
|
node: bridgeBlueprintNodeSchema,
|
|
2685
2809
|
ok: z.literal(true),
|
|
2810
|
+
position: graphNodePlacedPositionSchema.optional(),
|
|
2686
2811
|
requestId: requestIdSchema,
|
|
2687
2812
|
state: creativeEditStateSchema,
|
|
2688
2813
|
type: z.literal(BRIDGE_ADD_GRAPH_NODE_REQUEST_TYPE),
|
|
@@ -2758,6 +2883,20 @@ const bridgeListAvailableNodesSuccessResponseSchema = z.object({
|
|
|
2758
2883
|
type: z.literal(BRIDGE_LIST_AVAILABLE_NODES_REQUEST_TYPE),
|
|
2759
2884
|
version: z.literal(2)
|
|
2760
2885
|
});
|
|
2886
|
+
const bridgeLayoutGraphSuccessResponseSchema = z.object({
|
|
2887
|
+
assetPath: z.string(),
|
|
2888
|
+
graphName: z.string(),
|
|
2889
|
+
layerCount: z.number().int().min(0),
|
|
2890
|
+
message: nonEmptyStringSchema.optional(),
|
|
2891
|
+
movedCount: z.number().int().min(0),
|
|
2892
|
+
nodeCount: z.number().int().min(0),
|
|
2893
|
+
ok: z.literal(true),
|
|
2894
|
+
requestId: requestIdSchema,
|
|
2895
|
+
skippedCount: z.number().int().min(0),
|
|
2896
|
+
state: creativeEditStateSchema,
|
|
2897
|
+
type: z.literal(BRIDGE_LAYOUT_GRAPH_REQUEST_TYPE),
|
|
2898
|
+
version: z.literal(2)
|
|
2899
|
+
});
|
|
2761
2900
|
const bridgeListGraphNodesResponseSchema = z.union([bridgeListGraphNodesSuccessResponseSchema, bridgeErrorResponseSchema]);
|
|
2762
2901
|
const bridgeAddGraphNodeResponseSchema = z.union([bridgeAddGraphNodeSuccessResponseSchema, bridgeErrorResponseSchema]);
|
|
2763
2902
|
const bridgeRemoveGraphNodeResponseSchema = z.union([bridgeRemoveGraphNodeSuccessResponseSchema, bridgeErrorResponseSchema]);
|
|
@@ -2765,6 +2904,7 @@ const bridgeConnectPinsResponseSchema = z.union([bridgeConnectPinsSuccessRespons
|
|
|
2765
2904
|
const bridgeDisconnectPinsResponseSchema = z.union([bridgeDisconnectPinsSuccessResponseSchema, bridgeErrorResponseSchema]);
|
|
2766
2905
|
const bridgeSetPinDefaultResponseSchema = z.union([bridgeSetPinDefaultSuccessResponseSchema, bridgeErrorResponseSchema]);
|
|
2767
2906
|
const bridgeListAvailableNodesResponseSchema = z.union([bridgeListAvailableNodesSuccessResponseSchema, bridgeErrorResponseSchema]);
|
|
2907
|
+
const bridgeLayoutGraphResponseSchema = z.union([bridgeLayoutGraphSuccessResponseSchema, bridgeErrorResponseSchema]);
|
|
2768
2908
|
function createBridgeListGraphNodesRequest(assetPath, graphName, options = {}, requestId = randomUUID()) {
|
|
2769
2909
|
return bridgeListGraphNodesRequestSchema.parse({
|
|
2770
2910
|
assetPath,
|
|
@@ -2780,6 +2920,7 @@ function createBridgeListGraphNodesRequest(assetPath, graphName, options = {}, r
|
|
|
2780
2920
|
function createBridgeAddGraphNodeRequest(assetPath, graphName, kind, options = {}, requestId = randomUUID()) {
|
|
2781
2921
|
return bridgeAddGraphNodeRequestSchema.parse({
|
|
2782
2922
|
assetPath,
|
|
2923
|
+
autoLayout: options.autoLayout,
|
|
2783
2924
|
graphName,
|
|
2784
2925
|
kind,
|
|
2785
2926
|
memberName: options.memberName,
|
|
@@ -2852,6 +2993,15 @@ function createBridgeListAvailableNodesRequest(assetPath, graphName, options = {
|
|
|
2852
2993
|
version: 2
|
|
2853
2994
|
});
|
|
2854
2995
|
}
|
|
2996
|
+
function createBridgeLayoutGraphRequest(assetPath, graphName, requestId = randomUUID()) {
|
|
2997
|
+
return bridgeLayoutGraphRequestSchema.parse({
|
|
2998
|
+
assetPath,
|
|
2999
|
+
graphName,
|
|
3000
|
+
requestId,
|
|
3001
|
+
type: BRIDGE_LAYOUT_GRAPH_REQUEST_TYPE,
|
|
3002
|
+
version: 2
|
|
3003
|
+
});
|
|
3004
|
+
}
|
|
2855
3005
|
//#endregion
|
|
2856
3006
|
//#region src/protocol/debugger.ts
|
|
2857
3007
|
const BRIDGE_SET_BLUEPRINT_BREAKPOINT_REQUEST_TYPE = "set_blueprint_breakpoint";
|
|
@@ -3300,11 +3450,11 @@ const createClassJobIdSchema = z.string().trim().min(1);
|
|
|
3300
3450
|
const classNameSchema = z.string().trim().min(1).max(128).regex(/^[A-Za-z_][A-Za-z0-9_]*$/);
|
|
3301
3451
|
const parentClassSchema = z.string().trim().min(1).max(128);
|
|
3302
3452
|
const moduleNameSchema = z.string().trim().min(1).max(128);
|
|
3303
|
-
const classPathSchema = z.string().trim().min(1).max(512);
|
|
3453
|
+
const classPathSchema$1 = z.string().trim().min(1).max(512);
|
|
3304
3454
|
const sourceFilePathSchema = z.string().trim().min(1);
|
|
3305
3455
|
const bridgeCreateCppClassRequestSchema = z.object({
|
|
3306
3456
|
className: classNameSchema,
|
|
3307
|
-
classPath: classPathSchema.optional(),
|
|
3457
|
+
classPath: classPathSchema$1.optional(),
|
|
3308
3458
|
moduleName: moduleNameSchema.optional(),
|
|
3309
3459
|
parentClass: parentClassSchema,
|
|
3310
3460
|
requestId: requestIdSchema,
|
|
@@ -7392,6 +7542,7 @@ const bridgeStateTreeNodeReportSchema = z.object({
|
|
|
7392
7542
|
const bridgeStateTreeTransitionReportSchema = z.object({
|
|
7393
7543
|
eventTag: z.string().optional(),
|
|
7394
7544
|
id: z.string(),
|
|
7545
|
+
targetStateId: z.string().optional(),
|
|
7395
7546
|
targetStateName: z.string().optional(),
|
|
7396
7547
|
targetType: z.string(),
|
|
7397
7548
|
trigger: z.string()
|
|
@@ -7639,6 +7790,141 @@ function createBridgeTraceStateTreeRequest(action, options = {}, requestId = ran
|
|
|
7639
7790
|
version: 2
|
|
7640
7791
|
});
|
|
7641
7792
|
}
|
|
7793
|
+
const BRIDGE_UPDATE_STATE_TREE_ELEMENTS_REQUEST_TYPE = "update_state_tree_elements";
|
|
7794
|
+
const BRIDGE_REMOVE_STATE_TREE_ELEMENTS_REQUEST_TYPE = "remove_state_tree_elements";
|
|
7795
|
+
const BRIDGE_STATE_TREE_ELEMENT_KINDS = [
|
|
7796
|
+
"state",
|
|
7797
|
+
"task",
|
|
7798
|
+
"transition"
|
|
7799
|
+
];
|
|
7800
|
+
const BRIDGE_STATE_TREE_EDITABLE_STATE_TYPES = [
|
|
7801
|
+
"state",
|
|
7802
|
+
"group",
|
|
7803
|
+
"subtree"
|
|
7804
|
+
];
|
|
7805
|
+
const BRIDGE_STATE_TREE_TRANSITION_TARGET_TYPES = [
|
|
7806
|
+
"none",
|
|
7807
|
+
"succeeded",
|
|
7808
|
+
"failed",
|
|
7809
|
+
"next_state",
|
|
7810
|
+
"goto_state"
|
|
7811
|
+
];
|
|
7812
|
+
const stateTreeElementIdSchema = z.string().trim().regex(/^[{(]?[0-9A-Fa-f]{8}-?[0-9A-Fa-f]{4}-?[0-9A-Fa-f]{4}-?[0-9A-Fa-f]{4}-?[0-9A-Fa-f]{12}[)}]?$/);
|
|
7813
|
+
const stateTreeElementKindSchema = z.enum(BRIDGE_STATE_TREE_ELEMENT_KINDS);
|
|
7814
|
+
const stateTreeEditableStateTypeSchema = z.enum(BRIDGE_STATE_TREE_EDITABLE_STATE_TYPES);
|
|
7815
|
+
const stateTreeTransitionTargetTypeSchema = z.enum(BRIDGE_STATE_TREE_TRANSITION_TARGET_TYPES);
|
|
7816
|
+
const stateTreeEditableTriggerSchema = z.enum(BRIDGE_STATE_TREE_TRANSITION_TRIGGERS);
|
|
7817
|
+
const bridgeStateTreeElementUpdateSchema = z.discriminatedUnion("kind", [
|
|
7818
|
+
z.object({
|
|
7819
|
+
enabled: z.boolean().optional(),
|
|
7820
|
+
id: stateTreeElementIdSchema,
|
|
7821
|
+
kind: z.literal("state"),
|
|
7822
|
+
name: userTypeIdentifierSchema.optional(),
|
|
7823
|
+
selectionBehavior: stateTreeSelectionBehaviorSchema.optional(),
|
|
7824
|
+
stateType: stateTreeEditableStateTypeSchema.optional()
|
|
7825
|
+
}),
|
|
7826
|
+
z.object({
|
|
7827
|
+
id: stateTreeElementIdSchema,
|
|
7828
|
+
kind: z.literal("task"),
|
|
7829
|
+
params: eqsParamsSchema
|
|
7830
|
+
}),
|
|
7831
|
+
z.object({
|
|
7832
|
+
enabled: z.boolean().optional(),
|
|
7833
|
+
eventTag: boundedStringSchema.optional(),
|
|
7834
|
+
id: stateTreeElementIdSchema,
|
|
7835
|
+
kind: z.literal("transition"),
|
|
7836
|
+
targetStateId: stateTreeElementIdSchema.optional(),
|
|
7837
|
+
targetType: stateTreeTransitionTargetTypeSchema.optional(),
|
|
7838
|
+
trigger: stateTreeEditableTriggerSchema.optional()
|
|
7839
|
+
})
|
|
7840
|
+
]).superRefine((update, ctx) => {
|
|
7841
|
+
if (update.kind === "task") {
|
|
7842
|
+
if (Object.keys(update.params).length === 0) ctx.addIssue({
|
|
7843
|
+
code: z.ZodIssueCode.custom,
|
|
7844
|
+
message: "A task update must set at least one param.",
|
|
7845
|
+
path: ["params"]
|
|
7846
|
+
});
|
|
7847
|
+
return;
|
|
7848
|
+
}
|
|
7849
|
+
const { id: _id, kind: _kind, ...fields } = update;
|
|
7850
|
+
if (Object.values(fields).every((value) => value === void 0)) ctx.addIssue({
|
|
7851
|
+
code: z.ZodIssueCode.custom,
|
|
7852
|
+
message: `A ${update.kind} update must change at least one field.`
|
|
7853
|
+
});
|
|
7854
|
+
if (update.kind !== "transition") return;
|
|
7855
|
+
if (update.targetType === "goto_state" && update.targetStateId === void 0) ctx.addIssue({
|
|
7856
|
+
code: z.ZodIssueCode.custom,
|
|
7857
|
+
message: "A 'goto_state' transition must name its targetStateId.",
|
|
7858
|
+
path: ["targetStateId"]
|
|
7859
|
+
});
|
|
7860
|
+
if (update.targetStateId !== void 0 && update.targetType !== void 0 && update.targetType !== "goto_state") ctx.addIssue({
|
|
7861
|
+
code: z.ZodIssueCode.custom,
|
|
7862
|
+
message: "Only a 'goto_state' transition names a targetStateId.",
|
|
7863
|
+
path: ["targetStateId"]
|
|
7864
|
+
});
|
|
7865
|
+
});
|
|
7866
|
+
const bridgeUpdateStateTreeElementsRequestSchema = z.object({
|
|
7867
|
+
assetPath: assetPathSchema,
|
|
7868
|
+
compile: z.boolean().default(true),
|
|
7869
|
+
requestId: requestIdSchema,
|
|
7870
|
+
type: z.literal(BRIDGE_UPDATE_STATE_TREE_ELEMENTS_REQUEST_TYPE),
|
|
7871
|
+
updates: z.array(bridgeStateTreeElementUpdateSchema).min(1).max(32),
|
|
7872
|
+
version: z.literal(2)
|
|
7873
|
+
});
|
|
7874
|
+
const bridgeUpdateStateTreeElementsSuccessResponseSchema = z.object({
|
|
7875
|
+
...authoringBatchResponseFields,
|
|
7876
|
+
compileMessages: z.array(z.string()).max(25),
|
|
7877
|
+
compiled: z.boolean(),
|
|
7878
|
+
type: z.literal(BRIDGE_UPDATE_STATE_TREE_ELEMENTS_REQUEST_TYPE)
|
|
7879
|
+
});
|
|
7880
|
+
const bridgeStateTreeElementRemovalSchema = z.object({
|
|
7881
|
+
id: stateTreeElementIdSchema,
|
|
7882
|
+
kind: stateTreeElementKindSchema
|
|
7883
|
+
});
|
|
7884
|
+
const bridgeRemoveStateTreeElementsRequestSchema = z.object({
|
|
7885
|
+
assetPath: assetPathSchema,
|
|
7886
|
+
compile: z.boolean().default(true),
|
|
7887
|
+
removals: z.array(bridgeStateTreeElementRemovalSchema).min(1).max(32),
|
|
7888
|
+
requestId: requestIdSchema,
|
|
7889
|
+
type: z.literal(BRIDGE_REMOVE_STATE_TREE_ELEMENTS_REQUEST_TYPE),
|
|
7890
|
+
version: z.literal(2)
|
|
7891
|
+
});
|
|
7892
|
+
const bridgeStateTreeRemovedTransitionSchema = z.object({
|
|
7893
|
+
id: z.string(),
|
|
7894
|
+
ownerStateId: z.string(),
|
|
7895
|
+
ownerStateName: z.string(),
|
|
7896
|
+
targetStateName: z.string()
|
|
7897
|
+
});
|
|
7898
|
+
const bridgeRemoveStateTreeElementsSuccessResponseSchema = z.object({
|
|
7899
|
+
...authoringBatchResponseFields,
|
|
7900
|
+
compileMessages: z.array(z.string()).max(25),
|
|
7901
|
+
compiled: z.boolean(),
|
|
7902
|
+
removedTransitionCount: z.number().int().min(0),
|
|
7903
|
+
removedTransitions: z.array(bridgeStateTreeRemovedTransitionSchema).max(128),
|
|
7904
|
+
type: z.literal(BRIDGE_REMOVE_STATE_TREE_ELEMENTS_REQUEST_TYPE)
|
|
7905
|
+
});
|
|
7906
|
+
const bridgeUpdateStateTreeElementsResponseSchema = z.union([bridgeUpdateStateTreeElementsSuccessResponseSchema, bridgeErrorResponseSchema]);
|
|
7907
|
+
const bridgeRemoveStateTreeElementsResponseSchema = z.union([bridgeRemoveStateTreeElementsSuccessResponseSchema, bridgeErrorResponseSchema]);
|
|
7908
|
+
function createBridgeUpdateStateTreeElementsRequest(assetPath, updates, options = {}, requestId = randomUUID()) {
|
|
7909
|
+
return bridgeUpdateStateTreeElementsRequestSchema.parse({
|
|
7910
|
+
assetPath,
|
|
7911
|
+
compile: options.compile,
|
|
7912
|
+
requestId,
|
|
7913
|
+
type: BRIDGE_UPDATE_STATE_TREE_ELEMENTS_REQUEST_TYPE,
|
|
7914
|
+
updates,
|
|
7915
|
+
version: 2
|
|
7916
|
+
});
|
|
7917
|
+
}
|
|
7918
|
+
function createBridgeRemoveStateTreeElementsRequest(assetPath, removals, options = {}, requestId = randomUUID()) {
|
|
7919
|
+
return bridgeRemoveStateTreeElementsRequestSchema.parse({
|
|
7920
|
+
assetPath,
|
|
7921
|
+
compile: options.compile,
|
|
7922
|
+
removals,
|
|
7923
|
+
requestId,
|
|
7924
|
+
type: BRIDGE_REMOVE_STATE_TREE_ELEMENTS_REQUEST_TYPE,
|
|
7925
|
+
version: 2
|
|
7926
|
+
});
|
|
7927
|
+
}
|
|
7642
7928
|
//#endregion
|
|
7643
7929
|
//#region src/protocol/perception.ts
|
|
7644
7930
|
const BRIDGE_CREATE_AI_CONTROLLER_REQUEST_TYPE = "create_ai_controller";
|
|
@@ -10461,30 +10747,871 @@ function createBridgeSetProjectSettingsRequest(options = {}, requestId = randomU
|
|
|
10461
10747
|
return bridgeSetProjectSettingsRequestSchema.parse({
|
|
10462
10748
|
properties: options.properties,
|
|
10463
10749
|
requestId,
|
|
10464
|
-
sectionName: options.sectionName,
|
|
10465
|
-
type: BRIDGE_SET_PROJECT_SETTINGS_REQUEST_TYPE,
|
|
10750
|
+
sectionName: options.sectionName,
|
|
10751
|
+
type: BRIDGE_SET_PROJECT_SETTINGS_REQUEST_TYPE,
|
|
10752
|
+
version: 2
|
|
10753
|
+
});
|
|
10754
|
+
}
|
|
10755
|
+
function createBridgeSetDefaultGamemodeRequest(scope, gameModePath, options = {}, requestId = randomUUID()) {
|
|
10756
|
+
return bridgeSetDefaultGamemodeRequestSchema.parse({
|
|
10757
|
+
defaultPawnClassPath: options.defaultPawnClassPath,
|
|
10758
|
+
gameModePath,
|
|
10759
|
+
gameStateClassPath: options.gameStateClassPath,
|
|
10760
|
+
hudClassPath: options.hudClassPath,
|
|
10761
|
+
levelPath: options.levelPath,
|
|
10762
|
+
playerControllerClassPath: options.playerControllerClassPath,
|
|
10763
|
+
playerStateClassPath: options.playerStateClassPath,
|
|
10764
|
+
requestId,
|
|
10765
|
+
scope,
|
|
10766
|
+
startupMapPath: options.startupMapPath,
|
|
10767
|
+
type: BRIDGE_SET_DEFAULT_GAMEMODE_REQUEST_TYPE,
|
|
10768
|
+
version: 2
|
|
10769
|
+
});
|
|
10770
|
+
}
|
|
10771
|
+
//#endregion
|
|
10772
|
+
//#region src/protocol/navigation.ts
|
|
10773
|
+
const classPathSchema = z.string().trim().min(1).max(512);
|
|
10774
|
+
const BRIDGE_SET_NAVMESH_SETTINGS_REQUEST_TYPE = "set_navmesh_settings";
|
|
10775
|
+
const BRIDGE_SET_NAV_AGENTS_REQUEST_TYPE = "set_nav_agents";
|
|
10776
|
+
const BRIDGE_SET_CROWD_SETTINGS_REQUEST_TYPE = "set_crowd_settings";
|
|
10777
|
+
const BRIDGE_CREATE_NAV_AREA_REQUEST_TYPE = "create_nav_area";
|
|
10778
|
+
const BRIDGE_ADD_NAV_MODIFIER_VOLUME_REQUEST_TYPE = "add_nav_modifier_volume";
|
|
10779
|
+
const BRIDGE_ADD_NAV_LINK_REQUEST_TYPE = "add_nav_link";
|
|
10780
|
+
const BRIDGE_FIND_PATH_REQUEST_TYPE = "find_path";
|
|
10781
|
+
const BRIDGE_TEST_REACHABILITY_REQUEST_TYPE = "test_reachability";
|
|
10782
|
+
const BRIDGE_NAV_RUNTIME_GENERATION_MODES = [
|
|
10783
|
+
"static",
|
|
10784
|
+
"dynamic_modifiers_only",
|
|
10785
|
+
"dynamic"
|
|
10786
|
+
];
|
|
10787
|
+
const BRIDGE_NAV_DATA_RESOLUTIONS = [
|
|
10788
|
+
"low",
|
|
10789
|
+
"default",
|
|
10790
|
+
"high"
|
|
10791
|
+
];
|
|
10792
|
+
const BRIDGE_NAV_LINK_DIRECTIONS = [
|
|
10793
|
+
"both_ways",
|
|
10794
|
+
"left_to_right",
|
|
10795
|
+
"right_to_left"
|
|
10796
|
+
];
|
|
10797
|
+
const BRIDGE_NAV_QUERY_RESULTS = [
|
|
10798
|
+
"invalid",
|
|
10799
|
+
"error",
|
|
10800
|
+
"fail",
|
|
10801
|
+
"success"
|
|
10802
|
+
];
|
|
10803
|
+
const BRIDGE_NAV_QUERY_STATES = ["reported", "unsupported"];
|
|
10804
|
+
const BRIDGE_NAV_MAX_AGENT_SIZE = 1e5;
|
|
10805
|
+
const BRIDGE_NAV_MAX_CELL_SIZE = 1024;
|
|
10806
|
+
const BRIDGE_NAV_MAX_TILE_SIZE = 1e5;
|
|
10807
|
+
const BRIDGE_NAV_MAX_REGION_SIZE = 1e7;
|
|
10808
|
+
const BRIDGE_NAV_MAX_AREA_COST = 1e6;
|
|
10809
|
+
const navRuntimeGenerationSchema = z.enum(BRIDGE_NAV_RUNTIME_GENERATION_MODES);
|
|
10810
|
+
const navDataResolutionSchema = z.enum(BRIDGE_NAV_DATA_RESOLUTIONS);
|
|
10811
|
+
const navLinkDirectionSchema = z.enum(BRIDGE_NAV_LINK_DIRECTIONS);
|
|
10812
|
+
const navQueryResultSchema = z.enum(BRIDGE_NAV_QUERY_RESULTS);
|
|
10813
|
+
const navQueryStateSchema = z.enum(BRIDGE_NAV_QUERY_STATES);
|
|
10814
|
+
const navPointSchema = z.object({
|
|
10815
|
+
x: z.number(),
|
|
10816
|
+
y: z.number(),
|
|
10817
|
+
z: z.number()
|
|
10818
|
+
});
|
|
10819
|
+
const navAgentSizeSchema = z.number().min(0).max(BRIDGE_NAV_MAX_AGENT_SIZE);
|
|
10820
|
+
const navCellSchema = z.number().min(1).max(BRIDGE_NAV_MAX_CELL_SIZE);
|
|
10821
|
+
const navRegionSizeSchema = z.number().min(0).max(BRIDGE_NAV_MAX_REGION_SIZE);
|
|
10822
|
+
const navAreaCostSchema = z.number().min(0).max(BRIDGE_NAV_MAX_AREA_COST);
|
|
10823
|
+
const navStepHeightSchema = z.number().min(0).max(1e4);
|
|
10824
|
+
const navColorChannelSchema = z.number().int().min(0).max(255);
|
|
10825
|
+
const navColorSchema = z.object({
|
|
10826
|
+
a: navColorChannelSchema.default(255),
|
|
10827
|
+
b: navColorChannelSchema,
|
|
10828
|
+
g: navColorChannelSchema,
|
|
10829
|
+
r: navColorChannelSchema
|
|
10830
|
+
});
|
|
10831
|
+
const navColorResponseSchema = z.object({
|
|
10832
|
+
a: navColorChannelSchema,
|
|
10833
|
+
b: navColorChannelSchema,
|
|
10834
|
+
g: navColorChannelSchema,
|
|
10835
|
+
r: navColorChannelSchema
|
|
10836
|
+
});
|
|
10837
|
+
const navExtentSchema = z.object({
|
|
10838
|
+
x: z.number().positive().default(200),
|
|
10839
|
+
y: z.number().positive().default(200),
|
|
10840
|
+
z: z.number().positive().default(200)
|
|
10841
|
+
});
|
|
10842
|
+
const bridgeSetNavmeshSettingsRequestFieldsSchema = z.object({
|
|
10843
|
+
agentHeight: navAgentSizeSchema.optional(),
|
|
10844
|
+
agentMaxSlope: z.number().min(0).max(89).optional(),
|
|
10845
|
+
agentMaxStepHeight: navStepHeightSchema.optional(),
|
|
10846
|
+
agentRadius: navAgentSizeSchema.optional(),
|
|
10847
|
+
cellHeight: navCellSchema.optional(),
|
|
10848
|
+
cellSize: navCellSchema.optional(),
|
|
10849
|
+
mergeRegionSize: navRegionSizeSchema.optional(),
|
|
10850
|
+
minRegionArea: navRegionSizeSchema.optional(),
|
|
10851
|
+
navMeshActorPath: actorPathSchema.optional(),
|
|
10852
|
+
requestId: requestIdSchema,
|
|
10853
|
+
resolution: navDataResolutionSchema.default("default"),
|
|
10854
|
+
runtimeGeneration: navRuntimeGenerationSchema.optional(),
|
|
10855
|
+
tileSizeUU: z.number().min(300).max(BRIDGE_NAV_MAX_TILE_SIZE).optional(),
|
|
10856
|
+
type: z.literal(BRIDGE_SET_NAVMESH_SETTINGS_REQUEST_TYPE),
|
|
10857
|
+
version: z.literal(2)
|
|
10858
|
+
});
|
|
10859
|
+
const bridgeSetNavmeshSettingsRequestSchema = bridgeSetNavmeshSettingsRequestFieldsSchema.refine((request) => request.agentHeight !== void 0 || request.agentMaxSlope !== void 0 || request.agentMaxStepHeight !== void 0 || request.agentRadius !== void 0 || request.cellHeight !== void 0 || request.cellSize !== void 0 || request.mergeRegionSize !== void 0 || request.minRegionArea !== void 0 || request.runtimeGeneration !== void 0 || request.tileSizeUU !== void 0, { message: "A set_navmesh_settings request must carry at least one setting to write." });
|
|
10860
|
+
const bridgeNavAgentSchema = z.object({
|
|
10861
|
+
height: navAgentSizeSchema,
|
|
10862
|
+
maxStepHeight: navStepHeightSchema.optional(),
|
|
10863
|
+
name: requiredBoundedStringSchema,
|
|
10864
|
+
navDataClass: classPathSchema.optional(),
|
|
10865
|
+
radius: navAgentSizeSchema
|
|
10866
|
+
});
|
|
10867
|
+
const bridgeSetNavAgentsRequestSchema = z.object({
|
|
10868
|
+
agents: z.array(bridgeNavAgentSchema).min(1).max(16),
|
|
10869
|
+
requestId: requestIdSchema,
|
|
10870
|
+
type: z.literal(BRIDGE_SET_NAV_AGENTS_REQUEST_TYPE),
|
|
10871
|
+
version: z.literal(2)
|
|
10872
|
+
});
|
|
10873
|
+
const bridgeCrowdSettingsSchema = z.object({
|
|
10874
|
+
maxAgentRadius: z.number().min(0).max(1e4).optional(),
|
|
10875
|
+
maxAgents: z.number().int().min(1).max(1e4).optional(),
|
|
10876
|
+
maxAvoidedAgents: z.number().int().min(0).max(64).optional(),
|
|
10877
|
+
maxAvoidedWalls: z.number().int().min(0).max(64).optional(),
|
|
10878
|
+
navmeshCheckInterval: z.number().min(0).max(60).optional(),
|
|
10879
|
+
pathOffsetRadiusMultiplier: z.number().min(0).max(100).optional(),
|
|
10880
|
+
pathOptimizationInterval: z.number().min(0).max(60).optional(),
|
|
10881
|
+
resolveCollisions: z.boolean().optional(),
|
|
10882
|
+
separationDirClamp: z.number().min(-1).max(1).optional()
|
|
10883
|
+
});
|
|
10884
|
+
const bridgeRvoSettingsSchema = z.object({
|
|
10885
|
+
artificialRadiusExpansion: z.number().min(0).max(100).optional(),
|
|
10886
|
+
defaultTimeToLive: z.number().min(0).max(600).optional(),
|
|
10887
|
+
deltaTimeToPredict: z.number().min(0).max(60).optional(),
|
|
10888
|
+
heightCheckMargin: z.number().min(0).max(1e3).optional(),
|
|
10889
|
+
lockTimeAfterAvoid: z.number().min(0).max(60).optional(),
|
|
10890
|
+
lockTimeAfterClean: z.number().min(0).max(60).optional()
|
|
10891
|
+
});
|
|
10892
|
+
const bridgeSetCrowdSettingsRequestFieldsSchema = z.object({
|
|
10893
|
+
crowd: bridgeCrowdSettingsSchema.optional(),
|
|
10894
|
+
requestId: requestIdSchema,
|
|
10895
|
+
rvo: bridgeRvoSettingsSchema.optional(),
|
|
10896
|
+
type: z.literal(BRIDGE_SET_CROWD_SETTINGS_REQUEST_TYPE),
|
|
10897
|
+
version: z.literal(2)
|
|
10898
|
+
});
|
|
10899
|
+
const bridgeSetCrowdSettingsRequestSchema = bridgeSetCrowdSettingsRequestFieldsSchema.refine((request) => Object.values(request.crowd ?? {}).some((value) => value !== void 0) || Object.values(request.rvo ?? {}).some((value) => value !== void 0), { message: "A set_crowd_settings request must carry at least one crowd or rvo setting." });
|
|
10900
|
+
const bridgeCreateNavAreaRequestSchema = z.object({
|
|
10901
|
+
assetName: requiredBoundedStringSchema,
|
|
10902
|
+
defaultCost: navAreaCostSchema.optional(),
|
|
10903
|
+
drawColor: navColorSchema.optional(),
|
|
10904
|
+
fixedAreaEnteringCost: navAreaCostSchema.optional(),
|
|
10905
|
+
packagePath: requiredBoundedStringSchema,
|
|
10906
|
+
parentClass: classPathSchema.default("NavArea"),
|
|
10907
|
+
requestId: requestIdSchema,
|
|
10908
|
+
type: z.literal(BRIDGE_CREATE_NAV_AREA_REQUEST_TYPE),
|
|
10909
|
+
version: z.literal(2)
|
|
10910
|
+
});
|
|
10911
|
+
const bridgeAddNavModifierVolumeRequestSchema = z.object({
|
|
10912
|
+
actorLabel: boundedStringSchema.optional(),
|
|
10913
|
+
areaClass: classPathSchema,
|
|
10914
|
+
areaClassToReplace: classPathSchema.optional(),
|
|
10915
|
+
extent: navExtentSchema.default({
|
|
10916
|
+
x: 200,
|
|
10917
|
+
y: 200,
|
|
10918
|
+
z: 200
|
|
10919
|
+
}),
|
|
10920
|
+
folderPath: boundedStringSchema.optional(),
|
|
10921
|
+
location: vectorInputSchema.default({
|
|
10922
|
+
x: 0,
|
|
10923
|
+
y: 0,
|
|
10924
|
+
z: 0
|
|
10925
|
+
}),
|
|
10926
|
+
requestId: requestIdSchema,
|
|
10927
|
+
rotation: rotatorInputSchema.default({
|
|
10928
|
+
pitch: 0,
|
|
10929
|
+
roll: 0,
|
|
10930
|
+
yaw: 0
|
|
10931
|
+
}),
|
|
10932
|
+
type: z.literal(BRIDGE_ADD_NAV_MODIFIER_VOLUME_REQUEST_TYPE),
|
|
10933
|
+
version: z.literal(2)
|
|
10934
|
+
});
|
|
10935
|
+
const bridgeNavLinkSchema = z.object({
|
|
10936
|
+
areaClass: classPathSchema.optional(),
|
|
10937
|
+
description: boundedStringSchema.optional(),
|
|
10938
|
+
direction: navLinkDirectionSchema.default("both_ways"),
|
|
10939
|
+
left: vectorInputSchema.default({
|
|
10940
|
+
x: 0,
|
|
10941
|
+
y: -50,
|
|
10942
|
+
z: 0
|
|
10943
|
+
}),
|
|
10944
|
+
leftProjectHeight: z.number().min(0).max(1e4).optional(),
|
|
10945
|
+
maxFallDownLength: z.number().min(0).max(1e4).optional(),
|
|
10946
|
+
right: vectorInputSchema.default({
|
|
10947
|
+
x: 0,
|
|
10948
|
+
y: 50,
|
|
10949
|
+
z: 0
|
|
10950
|
+
}),
|
|
10951
|
+
snapHeight: z.number().min(1).max(1e4).optional(),
|
|
10952
|
+
snapRadius: z.number().min(1).max(1e4).optional()
|
|
10953
|
+
});
|
|
10954
|
+
const bridgeAddNavLinkRequestSchema = z.object({
|
|
10955
|
+
actorLabel: boundedStringSchema.optional(),
|
|
10956
|
+
folderPath: boundedStringSchema.optional(),
|
|
10957
|
+
links: z.array(bridgeNavLinkSchema).min(1).max(16),
|
|
10958
|
+
location: vectorInputSchema.default({
|
|
10959
|
+
x: 0,
|
|
10960
|
+
y: 0,
|
|
10961
|
+
z: 0
|
|
10962
|
+
}),
|
|
10963
|
+
requestId: requestIdSchema,
|
|
10964
|
+
rotation: rotatorInputSchema.default({
|
|
10965
|
+
pitch: 0,
|
|
10966
|
+
roll: 0,
|
|
10967
|
+
yaw: 0
|
|
10968
|
+
}),
|
|
10969
|
+
smartLinkEnabled: z.boolean().default(false),
|
|
10970
|
+
type: z.literal(BRIDGE_ADD_NAV_LINK_REQUEST_TYPE),
|
|
10971
|
+
version: z.literal(2)
|
|
10972
|
+
});
|
|
10973
|
+
const navEndpointFields = {
|
|
10974
|
+
end: navPointSchema.optional(),
|
|
10975
|
+
endActorPath: actorPathSchema.optional(),
|
|
10976
|
+
start: navPointSchema.optional(),
|
|
10977
|
+
startActorPath: actorPathSchema.optional()
|
|
10978
|
+
};
|
|
10979
|
+
const addNavEndpointIssues = (endpoints, ctx, pathPrefix) => {
|
|
10980
|
+
if (endpoints.start === void 0 === (endpoints.startActorPath === void 0)) ctx.addIssue({
|
|
10981
|
+
code: z.ZodIssueCode.custom,
|
|
10982
|
+
message: "Give exactly one of start or startActorPath.",
|
|
10983
|
+
path: [...pathPrefix, "start"]
|
|
10984
|
+
});
|
|
10985
|
+
if (endpoints.end === void 0 === (endpoints.endActorPath === void 0)) ctx.addIssue({
|
|
10986
|
+
code: z.ZodIssueCode.custom,
|
|
10987
|
+
message: "Give exactly one of end or endActorPath.",
|
|
10988
|
+
path: [...pathPrefix, "end"]
|
|
10989
|
+
});
|
|
10990
|
+
};
|
|
10991
|
+
const bridgeFindPathRequestFieldsSchema = z.object({
|
|
10992
|
+
...navEndpointFields,
|
|
10993
|
+
allowPartial: z.boolean().default(true),
|
|
10994
|
+
maxPathPoints: z.number().int().min(1).max(256).default(64),
|
|
10995
|
+
navMeshActorPath: actorPathSchema.optional(),
|
|
10996
|
+
requestId: requestIdSchema,
|
|
10997
|
+
type: z.literal(BRIDGE_FIND_PATH_REQUEST_TYPE),
|
|
10998
|
+
version: z.literal(2)
|
|
10999
|
+
});
|
|
11000
|
+
const bridgeFindPathRequestSchema = bridgeFindPathRequestFieldsSchema.superRefine((request, ctx) => {
|
|
11001
|
+
addNavEndpointIssues(request, ctx, []);
|
|
11002
|
+
});
|
|
11003
|
+
const bridgeReachabilityPairSchema = z.object(navEndpointFields);
|
|
11004
|
+
const bridgeTestReachabilityRequestFieldsSchema = z.object({
|
|
11005
|
+
allowPartial: z.boolean().default(false),
|
|
11006
|
+
navMeshActorPath: actorPathSchema.optional(),
|
|
11007
|
+
pairs: z.array(bridgeReachabilityPairSchema).min(1).max(64),
|
|
11008
|
+
requestId: requestIdSchema,
|
|
11009
|
+
type: z.literal(BRIDGE_TEST_REACHABILITY_REQUEST_TYPE),
|
|
11010
|
+
version: z.literal(2)
|
|
11011
|
+
});
|
|
11012
|
+
const bridgeTestReachabilityRequestSchema = bridgeTestReachabilityRequestFieldsSchema.superRefine((request, ctx) => {
|
|
11013
|
+
request.pairs.forEach((pair, index) => {
|
|
11014
|
+
addNavEndpointIssues(pair, ctx, ["pairs", index]);
|
|
11015
|
+
});
|
|
11016
|
+
});
|
|
11017
|
+
const bridgeSetNavmeshSettingsSuccessResponseSchema = z.object({
|
|
11018
|
+
agentHeight: z.number(),
|
|
11019
|
+
agentMaxSlope: z.number(),
|
|
11020
|
+
agentMaxStepHeight: z.number(),
|
|
11021
|
+
agentRadius: z.number(),
|
|
11022
|
+
appliedSettings: z.array(z.string()).max(32),
|
|
11023
|
+
cellHeight: z.number(),
|
|
11024
|
+
cellSize: z.number(),
|
|
11025
|
+
mergeRegionSize: z.number(),
|
|
11026
|
+
message: nonEmptyStringSchema.optional(),
|
|
11027
|
+
minRegionArea: z.number(),
|
|
11028
|
+
navMeshActorPath: z.string(),
|
|
11029
|
+
ok: z.literal(true),
|
|
11030
|
+
packageDirty: z.boolean(),
|
|
11031
|
+
rebuildRequired: z.boolean(),
|
|
11032
|
+
requestId: requestIdSchema,
|
|
11033
|
+
resolution: navDataResolutionSchema,
|
|
11034
|
+
runtimeGeneration: navRuntimeGenerationSchema,
|
|
11035
|
+
state: creativeEditStateSchema,
|
|
11036
|
+
tileSizeUU: z.number(),
|
|
11037
|
+
type: z.literal(BRIDGE_SET_NAVMESH_SETTINGS_REQUEST_TYPE),
|
|
11038
|
+
version: z.literal(2)
|
|
11039
|
+
});
|
|
11040
|
+
const bridgeSetNavAgentsSuccessResponseSchema = z.object({
|
|
11041
|
+
agentCount: z.number().int().min(0),
|
|
11042
|
+
agents: z.array(z.object({
|
|
11043
|
+
height: z.number(),
|
|
11044
|
+
name: z.string(),
|
|
11045
|
+
radius: z.number()
|
|
11046
|
+
})).max(16),
|
|
11047
|
+
configFilePath: z.string(),
|
|
11048
|
+
message: nonEmptyStringSchema.optional(),
|
|
11049
|
+
ok: z.literal(true),
|
|
11050
|
+
requestId: requestIdSchema,
|
|
11051
|
+
restartRequired: z.boolean(),
|
|
11052
|
+
state: creativeEditStateSchema,
|
|
11053
|
+
type: z.literal(BRIDGE_SET_NAV_AGENTS_REQUEST_TYPE),
|
|
11054
|
+
version: z.literal(2)
|
|
11055
|
+
});
|
|
11056
|
+
const bridgeSetCrowdSettingsSuccessResponseSchema = z.object({
|
|
11057
|
+
appliedCount: z.number().int().min(0),
|
|
11058
|
+
configFilePaths: z.array(z.string()).max(2),
|
|
11059
|
+
failureCount: z.number().int().min(0),
|
|
11060
|
+
items: z.array(bridgeAuthoringItemResultSchema).max(32),
|
|
11061
|
+
message: nonEmptyStringSchema.optional(),
|
|
11062
|
+
ok: z.literal(true),
|
|
11063
|
+
packageDirty: z.boolean(),
|
|
11064
|
+
requestId: requestIdSchema,
|
|
11065
|
+
restartRequired: z.boolean(),
|
|
11066
|
+
state: creativeEditStateSchema,
|
|
11067
|
+
type: z.literal(BRIDGE_SET_CROWD_SETTINGS_REQUEST_TYPE),
|
|
11068
|
+
version: z.literal(2)
|
|
11069
|
+
});
|
|
11070
|
+
const bridgeCreateNavAreaSuccessResponseSchema = z.object({
|
|
11071
|
+
...createdUserAssetResponseFields,
|
|
11072
|
+
defaultCost: z.number(),
|
|
11073
|
+
drawColor: navColorResponseSchema,
|
|
11074
|
+
fixedAreaEnteringCost: z.number(),
|
|
11075
|
+
generatedClassPath: z.string(),
|
|
11076
|
+
parentClass: z.string(),
|
|
11077
|
+
type: z.literal(BRIDGE_CREATE_NAV_AREA_REQUEST_TYPE)
|
|
11078
|
+
});
|
|
11079
|
+
const bridgeAddNavModifierVolumeSuccessResponseSchema = z.object({
|
|
11080
|
+
actorPath: z.string(),
|
|
11081
|
+
areaClass: z.string(),
|
|
11082
|
+
areaClassToReplace: z.string().optional(),
|
|
11083
|
+
extent: navPointSchema,
|
|
11084
|
+
location: navPointSchema,
|
|
11085
|
+
message: nonEmptyStringSchema.optional(),
|
|
11086
|
+
ok: z.literal(true),
|
|
11087
|
+
packageDirty: z.boolean(),
|
|
11088
|
+
rebuildRequired: z.boolean(),
|
|
11089
|
+
requestId: requestIdSchema,
|
|
11090
|
+
state: creativeEditStateSchema,
|
|
11091
|
+
type: z.literal(BRIDGE_ADD_NAV_MODIFIER_VOLUME_REQUEST_TYPE),
|
|
11092
|
+
version: z.literal(2)
|
|
11093
|
+
});
|
|
11094
|
+
const bridgeAddNavLinkSuccessResponseSchema = z.object({
|
|
11095
|
+
actorPath: z.string(),
|
|
11096
|
+
linkCount: z.number().int().min(0),
|
|
11097
|
+
links: z.array(z.object({
|
|
11098
|
+
direction: navLinkDirectionSchema,
|
|
11099
|
+
left: navPointSchema,
|
|
11100
|
+
right: navPointSchema
|
|
11101
|
+
})).max(16),
|
|
11102
|
+
message: nonEmptyStringSchema.optional(),
|
|
11103
|
+
ok: z.literal(true),
|
|
11104
|
+
packageDirty: z.boolean(),
|
|
11105
|
+
rebuildRequired: z.boolean(),
|
|
11106
|
+
requestId: requestIdSchema,
|
|
11107
|
+
smartLinkEnabled: z.boolean(),
|
|
11108
|
+
state: creativeEditStateSchema,
|
|
11109
|
+
type: z.literal(BRIDGE_ADD_NAV_LINK_REQUEST_TYPE),
|
|
11110
|
+
version: z.literal(2)
|
|
11111
|
+
});
|
|
11112
|
+
const bridgeFindPathSuccessResponseSchema = z.object({
|
|
11113
|
+
endLocation: navPointSchema,
|
|
11114
|
+
message: nonEmptyStringSchema.optional(),
|
|
11115
|
+
ok: z.literal(true),
|
|
11116
|
+
partial: z.boolean(),
|
|
11117
|
+
pathCost: z.number(),
|
|
11118
|
+
pathLength: z.number(),
|
|
11119
|
+
pathPointCount: z.number().int().min(0),
|
|
11120
|
+
pathPoints: z.array(navPointSchema).max(256),
|
|
11121
|
+
queryResult: navQueryResultSchema,
|
|
11122
|
+
reachable: z.boolean(),
|
|
11123
|
+
requestId: requestIdSchema,
|
|
11124
|
+
startLocation: navPointSchema,
|
|
11125
|
+
state: navQueryStateSchema,
|
|
11126
|
+
truncated: z.boolean(),
|
|
11127
|
+
type: z.literal(BRIDGE_FIND_PATH_REQUEST_TYPE),
|
|
11128
|
+
version: z.literal(2)
|
|
11129
|
+
});
|
|
11130
|
+
const bridgeTestReachabilitySuccessResponseSchema = z.object({
|
|
11131
|
+
message: nonEmptyStringSchema.optional(),
|
|
11132
|
+
ok: z.literal(true),
|
|
11133
|
+
pairs: z.array(z.object({
|
|
11134
|
+
error: z.string().optional(),
|
|
11135
|
+
index: z.number().int().min(0),
|
|
11136
|
+
partial: z.boolean(),
|
|
11137
|
+
pathLength: z.number(),
|
|
11138
|
+
reachable: z.boolean()
|
|
11139
|
+
})).max(64),
|
|
11140
|
+
reachableCount: z.number().int().min(0),
|
|
11141
|
+
requestId: requestIdSchema,
|
|
11142
|
+
state: navQueryStateSchema,
|
|
11143
|
+
type: z.literal(BRIDGE_TEST_REACHABILITY_REQUEST_TYPE),
|
|
11144
|
+
unreachableCount: z.number().int().min(0),
|
|
11145
|
+
version: z.literal(2)
|
|
11146
|
+
});
|
|
11147
|
+
const bridgeSetNavmeshSettingsResponseSchema = z.union([bridgeSetNavmeshSettingsSuccessResponseSchema, bridgeErrorResponseSchema]);
|
|
11148
|
+
const bridgeSetNavAgentsResponseSchema = z.union([bridgeSetNavAgentsSuccessResponseSchema, bridgeErrorResponseSchema]);
|
|
11149
|
+
const bridgeSetCrowdSettingsResponseSchema = z.union([bridgeSetCrowdSettingsSuccessResponseSchema, bridgeErrorResponseSchema]);
|
|
11150
|
+
const bridgeCreateNavAreaResponseSchema = z.union([bridgeCreateNavAreaSuccessResponseSchema, bridgeErrorResponseSchema]);
|
|
11151
|
+
const bridgeAddNavModifierVolumeResponseSchema = z.union([bridgeAddNavModifierVolumeSuccessResponseSchema, bridgeErrorResponseSchema]);
|
|
11152
|
+
const bridgeAddNavLinkResponseSchema = z.union([bridgeAddNavLinkSuccessResponseSchema, bridgeErrorResponseSchema]);
|
|
11153
|
+
const bridgeFindPathResponseSchema = z.union([bridgeFindPathSuccessResponseSchema, bridgeErrorResponseSchema]);
|
|
11154
|
+
const bridgeTestReachabilityResponseSchema = z.union([bridgeTestReachabilitySuccessResponseSchema, bridgeErrorResponseSchema]);
|
|
11155
|
+
function createBridgeSetNavmeshSettingsRequest(options = {}, requestId = randomUUID()) {
|
|
11156
|
+
return bridgeSetNavmeshSettingsRequestSchema.parse({
|
|
11157
|
+
agentHeight: options.agentHeight,
|
|
11158
|
+
agentMaxSlope: options.agentMaxSlope,
|
|
11159
|
+
agentMaxStepHeight: options.agentMaxStepHeight,
|
|
11160
|
+
agentRadius: options.agentRadius,
|
|
11161
|
+
cellHeight: options.cellHeight,
|
|
11162
|
+
cellSize: options.cellSize,
|
|
11163
|
+
mergeRegionSize: options.mergeRegionSize,
|
|
11164
|
+
minRegionArea: options.minRegionArea,
|
|
11165
|
+
navMeshActorPath: options.navMeshActorPath,
|
|
11166
|
+
requestId,
|
|
11167
|
+
resolution: options.resolution,
|
|
11168
|
+
runtimeGeneration: options.runtimeGeneration,
|
|
11169
|
+
tileSizeUU: options.tileSizeUU,
|
|
11170
|
+
type: BRIDGE_SET_NAVMESH_SETTINGS_REQUEST_TYPE,
|
|
11171
|
+
version: 2
|
|
11172
|
+
});
|
|
11173
|
+
}
|
|
11174
|
+
function createBridgeSetNavAgentsRequest(agents, requestId = randomUUID()) {
|
|
11175
|
+
return bridgeSetNavAgentsRequestSchema.parse({
|
|
11176
|
+
agents,
|
|
11177
|
+
requestId,
|
|
11178
|
+
type: BRIDGE_SET_NAV_AGENTS_REQUEST_TYPE,
|
|
11179
|
+
version: 2
|
|
11180
|
+
});
|
|
11181
|
+
}
|
|
11182
|
+
function createBridgeSetCrowdSettingsRequest(options = {}, requestId = randomUUID()) {
|
|
11183
|
+
return bridgeSetCrowdSettingsRequestSchema.parse({
|
|
11184
|
+
crowd: options.crowd,
|
|
11185
|
+
requestId,
|
|
11186
|
+
rvo: options.rvo,
|
|
11187
|
+
type: BRIDGE_SET_CROWD_SETTINGS_REQUEST_TYPE,
|
|
11188
|
+
version: 2
|
|
11189
|
+
});
|
|
11190
|
+
}
|
|
11191
|
+
function createBridgeCreateNavAreaRequest(assetName, packagePath, options = {}, requestId = randomUUID()) {
|
|
11192
|
+
return bridgeCreateNavAreaRequestSchema.parse({
|
|
11193
|
+
assetName,
|
|
11194
|
+
defaultCost: options.defaultCost,
|
|
11195
|
+
drawColor: options.drawColor,
|
|
11196
|
+
fixedAreaEnteringCost: options.fixedAreaEnteringCost,
|
|
11197
|
+
packagePath,
|
|
11198
|
+
parentClass: options.parentClass,
|
|
11199
|
+
requestId,
|
|
11200
|
+
type: BRIDGE_CREATE_NAV_AREA_REQUEST_TYPE,
|
|
11201
|
+
version: 2
|
|
11202
|
+
});
|
|
11203
|
+
}
|
|
11204
|
+
function createBridgeAddNavModifierVolumeRequest(areaClass, options = {}, requestId = randomUUID()) {
|
|
11205
|
+
return bridgeAddNavModifierVolumeRequestSchema.parse({
|
|
11206
|
+
actorLabel: options.actorLabel,
|
|
11207
|
+
areaClass,
|
|
11208
|
+
areaClassToReplace: options.areaClassToReplace,
|
|
11209
|
+
extent: options.extent,
|
|
11210
|
+
folderPath: options.folderPath,
|
|
11211
|
+
location: options.location,
|
|
11212
|
+
requestId,
|
|
11213
|
+
rotation: options.rotation,
|
|
11214
|
+
type: BRIDGE_ADD_NAV_MODIFIER_VOLUME_REQUEST_TYPE,
|
|
11215
|
+
version: 2
|
|
11216
|
+
});
|
|
11217
|
+
}
|
|
11218
|
+
function createBridgeAddNavLinkRequest(links, options = {}, requestId = randomUUID()) {
|
|
11219
|
+
return bridgeAddNavLinkRequestSchema.parse({
|
|
11220
|
+
actorLabel: options.actorLabel,
|
|
11221
|
+
folderPath: options.folderPath,
|
|
11222
|
+
links,
|
|
11223
|
+
location: options.location,
|
|
11224
|
+
requestId,
|
|
11225
|
+
rotation: options.rotation,
|
|
11226
|
+
smartLinkEnabled: options.smartLinkEnabled,
|
|
11227
|
+
type: BRIDGE_ADD_NAV_LINK_REQUEST_TYPE,
|
|
11228
|
+
version: 2
|
|
11229
|
+
});
|
|
11230
|
+
}
|
|
11231
|
+
function createBridgeFindPathRequest(endpoints, options = {}, requestId = randomUUID()) {
|
|
11232
|
+
return bridgeFindPathRequestSchema.parse({
|
|
11233
|
+
allowPartial: options.allowPartial,
|
|
11234
|
+
end: endpoints.end,
|
|
11235
|
+
endActorPath: endpoints.endActorPath,
|
|
11236
|
+
maxPathPoints: options.maxPathPoints,
|
|
11237
|
+
navMeshActorPath: options.navMeshActorPath,
|
|
11238
|
+
requestId,
|
|
11239
|
+
start: endpoints.start,
|
|
11240
|
+
startActorPath: endpoints.startActorPath,
|
|
11241
|
+
type: BRIDGE_FIND_PATH_REQUEST_TYPE,
|
|
11242
|
+
version: 2
|
|
11243
|
+
});
|
|
11244
|
+
}
|
|
11245
|
+
function createBridgeTestReachabilityRequest(pairs, options = {}, requestId = randomUUID()) {
|
|
11246
|
+
return bridgeTestReachabilityRequestSchema.parse({
|
|
11247
|
+
allowPartial: options.allowPartial,
|
|
11248
|
+
navMeshActorPath: options.navMeshActorPath,
|
|
11249
|
+
pairs,
|
|
11250
|
+
requestId,
|
|
11251
|
+
type: BRIDGE_TEST_REACHABILITY_REQUEST_TYPE,
|
|
11252
|
+
version: 2
|
|
11253
|
+
});
|
|
11254
|
+
}
|
|
11255
|
+
const BRIDGE_DIAGNOSE_NAVMESH_REQUEST_TYPE = "diagnose_navmesh";
|
|
11256
|
+
const BRIDGE_NAV_DIAGNOSTIC_ISSUE_CODES = [
|
|
11257
|
+
"missing_nav_bounds",
|
|
11258
|
+
"nav_bounds_empty",
|
|
11259
|
+
"no_navigation_data",
|
|
11260
|
+
"navmesh_empty",
|
|
11261
|
+
"no_spawn_points",
|
|
11262
|
+
"island_without_spawn",
|
|
11263
|
+
"spawn_not_found",
|
|
11264
|
+
"spawn_off_navmesh",
|
|
11265
|
+
"spawn_unreachable"
|
|
11266
|
+
];
|
|
11267
|
+
const BRIDGE_NAV_SPAWN_POINT_KINDS = ["player_start", "actor"];
|
|
11268
|
+
const bridgeDiagnoseNavmeshRequestSchema = z.object({
|
|
11269
|
+
includePlayerStarts: z.boolean().default(true),
|
|
11270
|
+
maxIslands: z.number().int().min(1).max(64).default(16),
|
|
11271
|
+
navMeshActorPath: actorPathSchema.optional(),
|
|
11272
|
+
requestId: requestIdSchema,
|
|
11273
|
+
spawnActorPaths: z.array(actorPathSchema).max(64).default([]),
|
|
11274
|
+
type: z.literal(BRIDGE_DIAGNOSE_NAVMESH_REQUEST_TYPE),
|
|
11275
|
+
version: z.literal(2)
|
|
11276
|
+
});
|
|
11277
|
+
const navDiagnosticIslandSchema = z.object({
|
|
11278
|
+
area: z.number().min(0),
|
|
11279
|
+
bounds: z.object({
|
|
11280
|
+
max: navPointSchema,
|
|
11281
|
+
min: navPointSchema
|
|
11282
|
+
}),
|
|
11283
|
+
index: z.number().int().min(0),
|
|
11284
|
+
polyCount: z.number().int().min(0),
|
|
11285
|
+
spawnPointCount: z.number().int().min(0)
|
|
11286
|
+
});
|
|
11287
|
+
const navDiagnosticSpawnPointSchema = z.object({
|
|
11288
|
+
actorPath: z.string(),
|
|
11289
|
+
error: z.string().optional(),
|
|
11290
|
+
islandIndex: z.number().int().min(0).optional(),
|
|
11291
|
+
kind: z.enum(BRIDGE_NAV_SPAWN_POINT_KINDS),
|
|
11292
|
+
location: navPointSchema,
|
|
11293
|
+
onNavMesh: z.boolean(),
|
|
11294
|
+
pathLength: z.number().optional(),
|
|
11295
|
+
projectedLocation: navPointSchema.optional(),
|
|
11296
|
+
reachableFromAnchor: z.boolean()
|
|
11297
|
+
});
|
|
11298
|
+
const navDiagnosticIssueSchema = z.object({
|
|
11299
|
+
actorPath: z.string().optional(),
|
|
11300
|
+
code: z.enum(BRIDGE_NAV_DIAGNOSTIC_ISSUE_CODES),
|
|
11301
|
+
islandIndex: z.number().int().min(0).optional(),
|
|
11302
|
+
message: z.string()
|
|
11303
|
+
});
|
|
11304
|
+
const bridgeDiagnoseNavmeshSuccessResponseSchema = z.object({
|
|
11305
|
+
anchorActorPath: z.string().optional(),
|
|
11306
|
+
healthy: z.boolean(),
|
|
11307
|
+
islandCount: z.number().int().min(0),
|
|
11308
|
+
islands: z.array(navDiagnosticIslandSchema).max(64),
|
|
11309
|
+
islandsTruncated: z.boolean(),
|
|
11310
|
+
issueCount: z.number().int().min(0),
|
|
11311
|
+
issues: z.array(navDiagnosticIssueSchema).max(64),
|
|
11312
|
+
issuesTruncated: z.boolean(),
|
|
11313
|
+
message: nonEmptyStringSchema.optional(),
|
|
11314
|
+
navBoundsVolumeCount: z.number().int().min(0),
|
|
11315
|
+
navMeshActorPath: z.string(),
|
|
11316
|
+
ok: z.literal(true),
|
|
11317
|
+
polyCount: z.number().int().min(0),
|
|
11318
|
+
requestId: requestIdSchema,
|
|
11319
|
+
spawnPointCount: z.number().int().min(0),
|
|
11320
|
+
spawnPoints: z.array(navDiagnosticSpawnPointSchema).max(64),
|
|
11321
|
+
spawnPointsTruncated: z.boolean(),
|
|
11322
|
+
state: navQueryStateSchema,
|
|
11323
|
+
type: z.literal(BRIDGE_DIAGNOSE_NAVMESH_REQUEST_TYPE),
|
|
11324
|
+
version: z.literal(2)
|
|
11325
|
+
});
|
|
11326
|
+
const bridgeDiagnoseNavmeshResponseSchema = z.union([bridgeDiagnoseNavmeshSuccessResponseSchema, bridgeErrorResponseSchema]);
|
|
11327
|
+
function createBridgeDiagnoseNavmeshRequest(options = {}, requestId = randomUUID()) {
|
|
11328
|
+
return bridgeDiagnoseNavmeshRequestSchema.parse({
|
|
11329
|
+
includePlayerStarts: options.includePlayerStarts,
|
|
11330
|
+
maxIslands: options.maxIslands,
|
|
11331
|
+
navMeshActorPath: options.navMeshActorPath,
|
|
11332
|
+
requestId,
|
|
11333
|
+
spawnActorPaths: options.spawnActorPaths,
|
|
11334
|
+
type: BRIDGE_DIAGNOSE_NAVMESH_REQUEST_TYPE,
|
|
11335
|
+
version: 2
|
|
11336
|
+
});
|
|
11337
|
+
}
|
|
11338
|
+
//#endregion
|
|
11339
|
+
//#region src/protocol/smartObjects.ts
|
|
11340
|
+
const BRIDGE_CREATE_SMART_OBJECT_DEFINITION_REQUEST_TYPE = "create_smart_object_definition";
|
|
11341
|
+
const BRIDGE_GET_SMART_OBJECT_DEFINITION_REQUEST_TYPE = "get_smart_object_definition";
|
|
11342
|
+
const BRIDGE_ADD_SMART_OBJECT_COMPONENT_REQUEST_TYPE = "add_smart_object_component";
|
|
11343
|
+
const BRIDGE_SMART_OBJECT_COMPONENT_TARGETS = ["blueprint", "actor"];
|
|
11344
|
+
const bridgeSmartObjectBehaviorDefinitionSchema = z.object({
|
|
11345
|
+
behaviorClass: assetPathSchema,
|
|
11346
|
+
params: instancedObjectParamsSchema
|
|
11347
|
+
});
|
|
11348
|
+
const activityTagsSchema = z.array(gameplayTagNameSchema).max(16).default([]);
|
|
11349
|
+
const behaviorDefinitionsSchema = z.array(bridgeSmartObjectBehaviorDefinitionSchema).max(8).default([]);
|
|
11350
|
+
const bridgeSmartObjectSlotSchema = z.object({
|
|
11351
|
+
activityTags: activityTagsSchema,
|
|
11352
|
+
behaviorDefinitions: behaviorDefinitionsSchema,
|
|
11353
|
+
enabled: z.boolean().default(true),
|
|
11354
|
+
name: requiredBoundedStringSchema.optional(),
|
|
11355
|
+
offset: bridgeVectorSchema.optional(),
|
|
11356
|
+
rotation: bridgeRotatorSchema.optional()
|
|
11357
|
+
});
|
|
11358
|
+
const bridgeCreateSmartObjectDefinitionRequestSchema = z.object({
|
|
11359
|
+
activityTags: activityTagsSchema,
|
|
11360
|
+
assetName: assetNameSchema,
|
|
11361
|
+
defaultBehaviorDefinitions: behaviorDefinitionsSchema,
|
|
11362
|
+
packagePath: contentPathSchema,
|
|
11363
|
+
requestId: requestIdSchema,
|
|
11364
|
+
slots: z.array(bridgeSmartObjectSlotSchema).min(1).max(32),
|
|
11365
|
+
type: z.literal(BRIDGE_CREATE_SMART_OBJECT_DEFINITION_REQUEST_TYPE),
|
|
11366
|
+
version: z.literal(2)
|
|
11367
|
+
});
|
|
11368
|
+
const bridgeGetSmartObjectDefinitionRequestSchema = z.object({
|
|
11369
|
+
assetPath: assetPathSchema,
|
|
11370
|
+
requestId: requestIdSchema,
|
|
11371
|
+
type: z.literal(BRIDGE_GET_SMART_OBJECT_DEFINITION_REQUEST_TYPE),
|
|
11372
|
+
version: z.literal(2)
|
|
11373
|
+
});
|
|
11374
|
+
const bridgeAddSmartObjectComponentRequestFieldsSchema = z.object({
|
|
11375
|
+
actorPath: actorPathSchema.optional(),
|
|
11376
|
+
blueprintPath: assetPathSchema.optional(),
|
|
11377
|
+
componentName: requiredBoundedStringSchema.optional(),
|
|
11378
|
+
definitionPath: assetPathSchema,
|
|
11379
|
+
requestId: requestIdSchema,
|
|
11380
|
+
type: z.literal(BRIDGE_ADD_SMART_OBJECT_COMPONENT_REQUEST_TYPE),
|
|
11381
|
+
version: z.literal(2)
|
|
11382
|
+
});
|
|
11383
|
+
const bridgeAddSmartObjectComponentRequestSchema = bridgeAddSmartObjectComponentRequestFieldsSchema.refine((request) => request.actorPath === void 0 !== (request.blueprintPath === void 0), {
|
|
11384
|
+
message: "An add_smart_object_component request names exactly one of blueprintPath or actorPath.",
|
|
11385
|
+
path: ["blueprintPath"]
|
|
11386
|
+
});
|
|
11387
|
+
const bridgeSmartObjectSlotReportSchema = z.object({
|
|
11388
|
+
activityTags: z.array(z.string()).max(16),
|
|
11389
|
+
behaviorDefinitions: z.array(z.string()).max(8),
|
|
11390
|
+
enabled: z.boolean(),
|
|
11391
|
+
index: z.number().int().min(0),
|
|
11392
|
+
name: z.string(),
|
|
11393
|
+
offset: bridgeVectorSchema,
|
|
11394
|
+
rotation: bridgeRotatorSchema
|
|
11395
|
+
});
|
|
11396
|
+
const smartObjectDefinitionReportFields = {
|
|
11397
|
+
activityTags: z.array(z.string()).max(16),
|
|
11398
|
+
defaultBehaviorDefinitions: z.array(z.string()).max(8),
|
|
11399
|
+
slots: z.array(bridgeSmartObjectSlotReportSchema).max(32),
|
|
11400
|
+
valid: z.boolean(),
|
|
11401
|
+
validationMessages: z.array(z.string()).max(32)
|
|
11402
|
+
};
|
|
11403
|
+
const bridgeCreateSmartObjectDefinitionSuccessResponseSchema = z.object({
|
|
11404
|
+
...createdUserAssetResponseFields,
|
|
11405
|
+
...smartObjectDefinitionReportFields,
|
|
11406
|
+
type: z.literal(BRIDGE_CREATE_SMART_OBJECT_DEFINITION_REQUEST_TYPE)
|
|
11407
|
+
});
|
|
11408
|
+
const bridgeGetSmartObjectDefinitionSuccessResponseSchema = z.object({
|
|
11409
|
+
...smartObjectDefinitionReportFields,
|
|
11410
|
+
assetPath: z.string(),
|
|
11411
|
+
message: nonEmptyStringSchema.optional(),
|
|
11412
|
+
ok: z.literal(true),
|
|
11413
|
+
requestId: requestIdSchema,
|
|
11414
|
+
state: aiReportStateSchema,
|
|
11415
|
+
type: z.literal(BRIDGE_GET_SMART_OBJECT_DEFINITION_REQUEST_TYPE),
|
|
11416
|
+
version: z.literal(2)
|
|
11417
|
+
});
|
|
11418
|
+
const bridgeAddSmartObjectComponentSuccessResponseSchema = z.object({
|
|
11419
|
+
componentName: z.string(),
|
|
11420
|
+
created: z.boolean(),
|
|
11421
|
+
definitionPath: z.string(),
|
|
11422
|
+
definitionValid: z.boolean(),
|
|
11423
|
+
message: nonEmptyStringSchema.optional(),
|
|
11424
|
+
ok: z.literal(true),
|
|
11425
|
+
packageDirty: z.boolean(),
|
|
11426
|
+
requestId: requestIdSchema,
|
|
11427
|
+
state: creativeEditStateSchema,
|
|
11428
|
+
target: z.enum(BRIDGE_SMART_OBJECT_COMPONENT_TARGETS),
|
|
11429
|
+
targetPath: z.string(),
|
|
11430
|
+
type: z.literal(BRIDGE_ADD_SMART_OBJECT_COMPONENT_REQUEST_TYPE),
|
|
11431
|
+
version: z.literal(2)
|
|
11432
|
+
});
|
|
11433
|
+
const bridgeCreateSmartObjectDefinitionResponseSchema = z.union([bridgeCreateSmartObjectDefinitionSuccessResponseSchema, bridgeErrorResponseSchema]);
|
|
11434
|
+
const bridgeGetSmartObjectDefinitionResponseSchema = z.union([bridgeGetSmartObjectDefinitionSuccessResponseSchema, bridgeErrorResponseSchema]);
|
|
11435
|
+
const bridgeAddSmartObjectComponentResponseSchema = z.union([bridgeAddSmartObjectComponentSuccessResponseSchema, bridgeErrorResponseSchema]);
|
|
11436
|
+
function createBridgeCreateSmartObjectDefinitionRequest(assetName, packagePath, slots, options = {}, requestId = randomUUID()) {
|
|
11437
|
+
return bridgeCreateSmartObjectDefinitionRequestSchema.parse({
|
|
11438
|
+
activityTags: options.activityTags,
|
|
11439
|
+
assetName,
|
|
11440
|
+
defaultBehaviorDefinitions: options.defaultBehaviorDefinitions,
|
|
11441
|
+
packagePath,
|
|
11442
|
+
requestId,
|
|
11443
|
+
slots,
|
|
11444
|
+
type: BRIDGE_CREATE_SMART_OBJECT_DEFINITION_REQUEST_TYPE,
|
|
11445
|
+
version: 2
|
|
11446
|
+
});
|
|
11447
|
+
}
|
|
11448
|
+
function createBridgeGetSmartObjectDefinitionRequest(assetPath, requestId = randomUUID()) {
|
|
11449
|
+
return bridgeGetSmartObjectDefinitionRequestSchema.parse({
|
|
11450
|
+
assetPath,
|
|
11451
|
+
requestId,
|
|
11452
|
+
type: BRIDGE_GET_SMART_OBJECT_DEFINITION_REQUEST_TYPE,
|
|
11453
|
+
version: 2
|
|
11454
|
+
});
|
|
11455
|
+
}
|
|
11456
|
+
function createBridgeAddSmartObjectComponentRequest(definitionPath, target, options = {}, requestId = randomUUID()) {
|
|
11457
|
+
return bridgeAddSmartObjectComponentRequestSchema.parse({
|
|
11458
|
+
actorPath: target.actorPath,
|
|
11459
|
+
blueprintPath: target.blueprintPath,
|
|
11460
|
+
componentName: options.componentName,
|
|
11461
|
+
definitionPath,
|
|
11462
|
+
requestId,
|
|
11463
|
+
type: BRIDGE_ADD_SMART_OBJECT_COMPONENT_REQUEST_TYPE,
|
|
11464
|
+
version: 2
|
|
11465
|
+
});
|
|
11466
|
+
}
|
|
11467
|
+
//#endregion
|
|
11468
|
+
//#region src/protocol/mass.ts
|
|
11469
|
+
const BRIDGE_CREATE_MASS_ENTITY_CONFIG_REQUEST_TYPE = "create_mass_entity_config";
|
|
11470
|
+
const BRIDGE_EDIT_MASS_ENTITY_CONFIG_REQUEST_TYPE = "edit_mass_entity_config";
|
|
11471
|
+
const BRIDGE_GET_MASS_ENTITY_CONFIG_REQUEST_TYPE = "get_mass_entity_config";
|
|
11472
|
+
const BRIDGE_VALIDATE_MASS_ENTITY_CONFIG_REQUEST_TYPE = "validate_mass_entity_config";
|
|
11473
|
+
const BRIDGE_MASS_TRAIT_OPERATIONS = [
|
|
11474
|
+
"add",
|
|
11475
|
+
"remove",
|
|
11476
|
+
"set"
|
|
11477
|
+
];
|
|
11478
|
+
const BRIDGE_MASS_READ_STATES = ["reported", "unsupported"];
|
|
11479
|
+
const BRIDGE_MASS_VALIDATION_SEVERITIES = ["error", "warning"];
|
|
11480
|
+
const massReadStateSchema = z.enum(BRIDGE_MASS_READ_STATES);
|
|
11481
|
+
const traitClassSchema = z.string().trim().min(1).max(512);
|
|
11482
|
+
const bridgeMassTraitEditSchema = z.object({
|
|
11483
|
+
operation: z.enum(BRIDGE_MASS_TRAIT_OPERATIONS),
|
|
11484
|
+
properties: z.array(bridgeAssetPropertyEntrySchema).max(32).optional(),
|
|
11485
|
+
traitClass: traitClassSchema
|
|
11486
|
+
}).superRefine((edit, context) => {
|
|
11487
|
+
const count = edit.properties?.length ?? 0;
|
|
11488
|
+
if (edit.operation === "set" && count === 0) context.addIssue({
|
|
11489
|
+
code: z.ZodIssueCode.custom,
|
|
11490
|
+
message: "A 'set' trait edit must carry at least one property.",
|
|
11491
|
+
path: ["properties"]
|
|
11492
|
+
});
|
|
11493
|
+
if (edit.operation === "remove" && count > 0) context.addIssue({
|
|
11494
|
+
code: z.ZodIssueCode.custom,
|
|
11495
|
+
message: "A 'remove' trait edit cannot carry properties.",
|
|
11496
|
+
path: ["properties"]
|
|
11497
|
+
});
|
|
11498
|
+
});
|
|
11499
|
+
const bridgeCreateMassEntityConfigRequestSchema = z.object({
|
|
11500
|
+
assetName: assetNameSchema,
|
|
11501
|
+
packagePath: contentPathSchema,
|
|
11502
|
+
parentConfigPath: assetPathSchema.optional(),
|
|
11503
|
+
requestId: requestIdSchema,
|
|
11504
|
+
type: z.literal(BRIDGE_CREATE_MASS_ENTITY_CONFIG_REQUEST_TYPE),
|
|
11505
|
+
version: z.literal(2)
|
|
11506
|
+
});
|
|
11507
|
+
const bridgeEditMassEntityConfigRequestSchema = z.object({
|
|
11508
|
+
assetPath: assetPathSchema,
|
|
11509
|
+
edits: z.array(bridgeMassTraitEditSchema).min(1).max(16),
|
|
11510
|
+
requestId: requestIdSchema,
|
|
11511
|
+
type: z.literal(BRIDGE_EDIT_MASS_ENTITY_CONFIG_REQUEST_TYPE),
|
|
11512
|
+
version: z.literal(2)
|
|
11513
|
+
});
|
|
11514
|
+
const bridgeGetMassEntityConfigRequestSchema = z.object({
|
|
11515
|
+
assetPath: assetPathSchema,
|
|
11516
|
+
requestId: requestIdSchema,
|
|
11517
|
+
type: z.literal(BRIDGE_GET_MASS_ENTITY_CONFIG_REQUEST_TYPE),
|
|
11518
|
+
version: z.literal(2)
|
|
11519
|
+
});
|
|
11520
|
+
const bridgeValidateMassEntityConfigRequestSchema = z.object({
|
|
11521
|
+
assetPath: assetPathSchema,
|
|
11522
|
+
requestId: requestIdSchema,
|
|
11523
|
+
type: z.literal(BRIDGE_VALIDATE_MASS_ENTITY_CONFIG_REQUEST_TYPE),
|
|
11524
|
+
version: z.literal(2)
|
|
11525
|
+
});
|
|
11526
|
+
const bridgeCreateMassEntityConfigSuccessResponseSchema = z.object({
|
|
11527
|
+
...createdUserAssetResponseFields,
|
|
11528
|
+
parentConfigPath: z.string().optional(),
|
|
11529
|
+
type: z.literal(BRIDGE_CREATE_MASS_ENTITY_CONFIG_REQUEST_TYPE)
|
|
11530
|
+
});
|
|
11531
|
+
const bridgeEditMassEntityConfigSuccessResponseSchema = z.object({
|
|
11532
|
+
...authoringBatchResponseFields,
|
|
11533
|
+
traits: z.array(z.string()).max(64),
|
|
11534
|
+
type: z.literal(BRIDGE_EDIT_MASS_ENTITY_CONFIG_REQUEST_TYPE)
|
|
11535
|
+
});
|
|
11536
|
+
const bridgeMassTraitReportSchema = z.object({
|
|
11537
|
+
index: z.number().int().min(0),
|
|
11538
|
+
properties: z.record(z.string(), z.string()),
|
|
11539
|
+
traitClass: z.string(),
|
|
11540
|
+
traitName: z.string()
|
|
11541
|
+
});
|
|
11542
|
+
const bridgeGetMassEntityConfigSuccessResponseSchema = z.object({
|
|
11543
|
+
assetPath: z.string(),
|
|
11544
|
+
message: nonEmptyStringSchema.optional(),
|
|
11545
|
+
ok: z.literal(true),
|
|
11546
|
+
parentConfigPath: z.string().optional(),
|
|
11547
|
+
requestId: requestIdSchema,
|
|
11548
|
+
state: massReadStateSchema,
|
|
11549
|
+
traits: z.array(bridgeMassTraitReportSchema).max(64),
|
|
11550
|
+
truncated: z.boolean(),
|
|
11551
|
+
type: z.literal(BRIDGE_GET_MASS_ENTITY_CONFIG_REQUEST_TYPE),
|
|
11552
|
+
version: z.literal(2)
|
|
11553
|
+
});
|
|
11554
|
+
const bridgeMassValidationMessageSchema = z.object({
|
|
11555
|
+
category: z.string(),
|
|
11556
|
+
severity: z.enum(BRIDGE_MASS_VALIDATION_SEVERITIES),
|
|
11557
|
+
text: z.string()
|
|
11558
|
+
});
|
|
11559
|
+
const bridgeValidateMassEntityConfigSuccessResponseSchema = z.object({
|
|
11560
|
+
assetPath: z.string(),
|
|
11561
|
+
errorCount: z.number().int().min(0),
|
|
11562
|
+
message: nonEmptyStringSchema.optional(),
|
|
11563
|
+
messages: z.array(bridgeMassValidationMessageSchema).max(32),
|
|
11564
|
+
ok: z.literal(true),
|
|
11565
|
+
requestId: requestIdSchema,
|
|
11566
|
+
state: massReadStateSchema,
|
|
11567
|
+
truncated: z.boolean(),
|
|
11568
|
+
type: z.literal(BRIDGE_VALIDATE_MASS_ENTITY_CONFIG_REQUEST_TYPE),
|
|
11569
|
+
valid: z.boolean(),
|
|
11570
|
+
version: z.literal(2),
|
|
11571
|
+
warningCount: z.number().int().min(0)
|
|
11572
|
+
});
|
|
11573
|
+
const bridgeCreateMassEntityConfigResponseSchema = z.union([bridgeCreateMassEntityConfigSuccessResponseSchema, bridgeErrorResponseSchema]);
|
|
11574
|
+
const bridgeEditMassEntityConfigResponseSchema = z.union([bridgeEditMassEntityConfigSuccessResponseSchema, bridgeErrorResponseSchema]);
|
|
11575
|
+
const bridgeGetMassEntityConfigResponseSchema = z.union([bridgeGetMassEntityConfigSuccessResponseSchema, bridgeErrorResponseSchema]);
|
|
11576
|
+
const bridgeValidateMassEntityConfigResponseSchema = z.union([bridgeValidateMassEntityConfigSuccessResponseSchema, bridgeErrorResponseSchema]);
|
|
11577
|
+
function createBridgeCreateMassEntityConfigRequest(assetName, packagePath, options = {}, requestId = randomUUID()) {
|
|
11578
|
+
return bridgeCreateMassEntityConfigRequestSchema.parse({
|
|
11579
|
+
assetName,
|
|
11580
|
+
packagePath,
|
|
11581
|
+
parentConfigPath: options.parentConfigPath,
|
|
11582
|
+
requestId,
|
|
11583
|
+
type: BRIDGE_CREATE_MASS_ENTITY_CONFIG_REQUEST_TYPE,
|
|
11584
|
+
version: 2
|
|
11585
|
+
});
|
|
11586
|
+
}
|
|
11587
|
+
function createBridgeEditMassEntityConfigRequest(assetPath, edits, requestId = randomUUID()) {
|
|
11588
|
+
return bridgeEditMassEntityConfigRequestSchema.parse({
|
|
11589
|
+
assetPath,
|
|
11590
|
+
edits,
|
|
11591
|
+
requestId,
|
|
11592
|
+
type: BRIDGE_EDIT_MASS_ENTITY_CONFIG_REQUEST_TYPE,
|
|
11593
|
+
version: 2
|
|
11594
|
+
});
|
|
11595
|
+
}
|
|
11596
|
+
function createBridgeGetMassEntityConfigRequest(assetPath, requestId = randomUUID()) {
|
|
11597
|
+
return bridgeGetMassEntityConfigRequestSchema.parse({
|
|
11598
|
+
assetPath,
|
|
11599
|
+
requestId,
|
|
11600
|
+
type: BRIDGE_GET_MASS_ENTITY_CONFIG_REQUEST_TYPE,
|
|
10466
11601
|
version: 2
|
|
10467
11602
|
});
|
|
10468
11603
|
}
|
|
10469
|
-
function
|
|
10470
|
-
return
|
|
10471
|
-
|
|
10472
|
-
gameModePath,
|
|
10473
|
-
gameStateClassPath: options.gameStateClassPath,
|
|
10474
|
-
hudClassPath: options.hudClassPath,
|
|
10475
|
-
levelPath: options.levelPath,
|
|
10476
|
-
playerControllerClassPath: options.playerControllerClassPath,
|
|
10477
|
-
playerStateClassPath: options.playerStateClassPath,
|
|
11604
|
+
function createBridgeValidateMassEntityConfigRequest(assetPath, requestId = randomUUID()) {
|
|
11605
|
+
return bridgeValidateMassEntityConfigRequestSchema.parse({
|
|
11606
|
+
assetPath,
|
|
10478
11607
|
requestId,
|
|
10479
|
-
|
|
10480
|
-
startupMapPath: options.startupMapPath,
|
|
10481
|
-
type: BRIDGE_SET_DEFAULT_GAMEMODE_REQUEST_TYPE,
|
|
11608
|
+
type: BRIDGE_VALIDATE_MASS_ENTITY_CONFIG_REQUEST_TYPE,
|
|
10482
11609
|
version: 2
|
|
10483
11610
|
});
|
|
10484
11611
|
}
|
|
10485
11612
|
//#endregion
|
|
10486
11613
|
//#region src/version.ts
|
|
10487
|
-
const SERVER_VERSION = "1.
|
|
11614
|
+
const SERVER_VERSION = "1.12.0";
|
|
10488
11615
|
//#endregion
|
|
10489
11616
|
//#region src/bridgeSocketClient.ts
|
|
10490
11617
|
var BridgeSocketError = class extends Error {
|
|
@@ -10720,6 +11847,9 @@ async function sendBridgeSetPinDefaultRequest(request, options) {
|
|
|
10720
11847
|
async function sendBridgeListAvailableNodesRequest(request, options) {
|
|
10721
11848
|
return parseBridgeResponse(await exchangeBridgeMessage(encodeBridgeFrame(request), options), bridgeListAvailableNodesResponseSchema, request.requestId);
|
|
10722
11849
|
}
|
|
11850
|
+
async function sendBridgeLayoutGraphRequest(request, options) {
|
|
11851
|
+
return parseBridgeResponse(await exchangeBridgeMessage(encodeBridgeFrame(request), options), bridgeLayoutGraphResponseSchema, request.requestId);
|
|
11852
|
+
}
|
|
10723
11853
|
async function sendBridgeSetViewportCameraRequest(request, options) {
|
|
10724
11854
|
return parseBridgeResponse(await exchangeBridgeMessage(encodeBridgeFrame(request), options), bridgeSetViewportCameraResponseSchema, request.requestId);
|
|
10725
11855
|
}
|
|
@@ -11416,6 +12546,60 @@ async function sendBridgeSetStateTreeGlobalsRequest(request, options) {
|
|
|
11416
12546
|
async function sendBridgeTraceStateTreeRequest(request, options) {
|
|
11417
12547
|
return parseBridgeResponse(await exchangeBridgeMessage(encodeBridgeFrame(request), options), bridgeTraceStateTreeResponseSchema, request.requestId);
|
|
11418
12548
|
}
|
|
12549
|
+
async function sendBridgeSetNavmeshSettingsRequest(request, options) {
|
|
12550
|
+
return parseBridgeResponse(await exchangeBridgeMessage(encodeBridgeFrame(request), options), bridgeSetNavmeshSettingsResponseSchema, request.requestId);
|
|
12551
|
+
}
|
|
12552
|
+
async function sendBridgeSetNavAgentsRequest(request, options) {
|
|
12553
|
+
return parseBridgeResponse(await exchangeBridgeMessage(encodeBridgeFrame(request), options), bridgeSetNavAgentsResponseSchema, request.requestId);
|
|
12554
|
+
}
|
|
12555
|
+
async function sendBridgeSetCrowdSettingsRequest(request, options) {
|
|
12556
|
+
return parseBridgeResponse(await exchangeBridgeMessage(encodeBridgeFrame(request), options), bridgeSetCrowdSettingsResponseSchema, request.requestId);
|
|
12557
|
+
}
|
|
12558
|
+
async function sendBridgeCreateNavAreaRequest(request, options) {
|
|
12559
|
+
return parseBridgeResponse(await exchangeBridgeMessage(encodeBridgeFrame(request), options), bridgeCreateNavAreaResponseSchema, request.requestId);
|
|
12560
|
+
}
|
|
12561
|
+
async function sendBridgeAddNavModifierVolumeRequest(request, options) {
|
|
12562
|
+
return parseBridgeResponse(await exchangeBridgeMessage(encodeBridgeFrame(request), options), bridgeAddNavModifierVolumeResponseSchema, request.requestId);
|
|
12563
|
+
}
|
|
12564
|
+
async function sendBridgeAddNavLinkRequest(request, options) {
|
|
12565
|
+
return parseBridgeResponse(await exchangeBridgeMessage(encodeBridgeFrame(request), options), bridgeAddNavLinkResponseSchema, request.requestId);
|
|
12566
|
+
}
|
|
12567
|
+
async function sendBridgeFindPathRequest(request, options) {
|
|
12568
|
+
return parseBridgeResponse(await exchangeBridgeMessage(encodeBridgeFrame(request), options), bridgeFindPathResponseSchema, request.requestId);
|
|
12569
|
+
}
|
|
12570
|
+
async function sendBridgeTestReachabilityRequest(request, options) {
|
|
12571
|
+
return parseBridgeResponse(await exchangeBridgeMessage(encodeBridgeFrame(request), options), bridgeTestReachabilityResponseSchema, request.requestId);
|
|
12572
|
+
}
|
|
12573
|
+
async function sendBridgeCreateSmartObjectDefinitionRequest(request, options) {
|
|
12574
|
+
return parseBridgeResponse(await exchangeBridgeMessage(encodeBridgeFrame(request), options), bridgeCreateSmartObjectDefinitionResponseSchema, request.requestId);
|
|
12575
|
+
}
|
|
12576
|
+
async function sendBridgeGetSmartObjectDefinitionRequest(request, options) {
|
|
12577
|
+
return parseBridgeResponse(await exchangeBridgeMessage(encodeBridgeFrame(request), options), bridgeGetSmartObjectDefinitionResponseSchema, request.requestId);
|
|
12578
|
+
}
|
|
12579
|
+
async function sendBridgeAddSmartObjectComponentRequest(request, options) {
|
|
12580
|
+
return parseBridgeResponse(await exchangeBridgeMessage(encodeBridgeFrame(request), options), bridgeAddSmartObjectComponentResponseSchema, request.requestId);
|
|
12581
|
+
}
|
|
12582
|
+
async function sendBridgeCreateMassEntityConfigRequest(request, options) {
|
|
12583
|
+
return parseBridgeResponse(await exchangeBridgeMessage(encodeBridgeFrame(request), options), bridgeCreateMassEntityConfigResponseSchema, request.requestId);
|
|
12584
|
+
}
|
|
12585
|
+
async function sendBridgeEditMassEntityConfigRequest(request, options) {
|
|
12586
|
+
return parseBridgeResponse(await exchangeBridgeMessage(encodeBridgeFrame(request), options), bridgeEditMassEntityConfigResponseSchema, request.requestId);
|
|
12587
|
+
}
|
|
12588
|
+
async function sendBridgeGetMassEntityConfigRequest(request, options) {
|
|
12589
|
+
return parseBridgeResponse(await exchangeBridgeMessage(encodeBridgeFrame(request), options), bridgeGetMassEntityConfigResponseSchema, request.requestId);
|
|
12590
|
+
}
|
|
12591
|
+
async function sendBridgeValidateMassEntityConfigRequest(request, options) {
|
|
12592
|
+
return parseBridgeResponse(await exchangeBridgeMessage(encodeBridgeFrame(request), options), bridgeValidateMassEntityConfigResponseSchema, request.requestId);
|
|
12593
|
+
}
|
|
12594
|
+
async function sendBridgeDiagnoseNavmeshRequest(request, options) {
|
|
12595
|
+
return parseBridgeResponse(await exchangeBridgeMessage(encodeBridgeFrame(request), options), bridgeDiagnoseNavmeshResponseSchema, request.requestId);
|
|
12596
|
+
}
|
|
12597
|
+
async function sendBridgeUpdateStateTreeElementsRequest(request, options) {
|
|
12598
|
+
return parseBridgeResponse(await exchangeBridgeMessage(encodeBridgeFrame(request), options), bridgeUpdateStateTreeElementsResponseSchema, request.requestId);
|
|
12599
|
+
}
|
|
12600
|
+
async function sendBridgeRemoveStateTreeElementsRequest(request, options) {
|
|
12601
|
+
return parseBridgeResponse(await exchangeBridgeMessage(encodeBridgeFrame(request), options), bridgeRemoveStateTreeElementsResponseSchema, request.requestId);
|
|
12602
|
+
}
|
|
11419
12603
|
//#endregion
|
|
11420
12604
|
//#region src/enginePing.ts
|
|
11421
12605
|
async function pingRegistryEntry$1(entry, options) {
|
|
@@ -18242,6 +19426,7 @@ const debuggerToolDomain = {
|
|
|
18242
19426
|
};
|
|
18243
19427
|
//#endregion
|
|
18244
19428
|
//#region src/traceAnalysis.ts
|
|
19429
|
+
const LLM_TAG_COUNTER_PATTERN = "STAT_*LLM";
|
|
18245
19430
|
const SECONDS_TO_MS = 1e3;
|
|
18246
19431
|
const FRAME_ROOT_TIMER_NAMES = /* @__PURE__ */ new Set(["FEngineLoop::Tick"]);
|
|
18247
19432
|
function parseCsvRows(text) {
|
|
@@ -18334,6 +19519,9 @@ function summarizeTimerStatistics(rows, maxScopes) {
|
|
|
18334
19519
|
if (count !== void 0) scope.count = count;
|
|
18335
19520
|
scopes.push(scope);
|
|
18336
19521
|
}
|
|
19522
|
+
return rankScopes(scopes, maxScopes);
|
|
19523
|
+
}
|
|
19524
|
+
function rankScopes(scopes, maxScopes) {
|
|
18337
19525
|
const byInclusiveTime = [...scopes].sort((left, right) => right.inclusiveTimeMs - left.inclusiveTimeMs);
|
|
18338
19526
|
return {
|
|
18339
19527
|
byExclusiveTime: [...scopes].sort((left, right) => right.exclusiveTimeMs - left.exclusiveTimeMs).slice(0, maxScopes),
|
|
@@ -18345,18 +19533,20 @@ function summarizeTimerStatistics(rows, maxScopes) {
|
|
|
18345
19533
|
function isGpuThread(threadName) {
|
|
18346
19534
|
return threadName.toUpperCase().includes("GPU");
|
|
18347
19535
|
}
|
|
18348
|
-
async function
|
|
19536
|
+
async function forEachTimingEvent(lines, visit) {
|
|
18349
19537
|
let headers;
|
|
18350
19538
|
let threadIndex = -1;
|
|
18351
19539
|
let timerIndex = -1;
|
|
18352
19540
|
let durationIndex = -1;
|
|
18353
19541
|
let startIndex = -1;
|
|
18354
19542
|
let depthIndex = -1;
|
|
18355
|
-
|
|
18356
|
-
|
|
18357
|
-
|
|
18358
|
-
|
|
18359
|
-
|
|
19543
|
+
const event = {
|
|
19544
|
+
depth: 0,
|
|
19545
|
+
durationMs: 0,
|
|
19546
|
+
startTimeMs: 0,
|
|
19547
|
+
threadName: "",
|
|
19548
|
+
timerName: ""
|
|
19549
|
+
};
|
|
18360
19550
|
for await (const rawLine of lines) {
|
|
18361
19551
|
const line = rawLine.trim();
|
|
18362
19552
|
if (line.length === 0) continue;
|
|
@@ -18369,36 +19559,160 @@ async function summarizeTimingEventStream(lines, options) {
|
|
|
18369
19559
|
durationIndex = columnIndex(headers, findColumn(headerRow, "Duration", "InclusiveTime"));
|
|
18370
19560
|
startIndex = columnIndex(headers, findColumn(headerRow, "StartTime", "Start"));
|
|
18371
19561
|
depthIndex = columnIndex(headers, findColumn(headerRow, "Depth"));
|
|
18372
|
-
if (threadIndex < 0 || durationIndex < 0)
|
|
19562
|
+
if (threadIndex < 0 || durationIndex < 0) return;
|
|
18373
19563
|
continue;
|
|
18374
19564
|
}
|
|
18375
19565
|
const duration = readNumber(values[durationIndex]);
|
|
18376
19566
|
const threadName = values[threadIndex];
|
|
18377
19567
|
if (duration === void 0 || threadName === void 0) continue;
|
|
18378
|
-
|
|
18379
|
-
|
|
18380
|
-
|
|
18381
|
-
|
|
18382
|
-
|
|
19568
|
+
event.depth = depthIndex < 0 ? 0 : readNumber(values[depthIndex]) ?? 0;
|
|
19569
|
+
event.durationMs = duration * SECONDS_TO_MS;
|
|
19570
|
+
event.startTimeMs = (startIndex < 0 ? 0 : readNumber(values[startIndex]) ?? 0) * SECONDS_TO_MS;
|
|
19571
|
+
event.threadName = threadName;
|
|
19572
|
+
event.timerName = timerIndex < 0 ? "" : values[timerIndex] ?? "";
|
|
19573
|
+
visit(event);
|
|
19574
|
+
}
|
|
19575
|
+
}
|
|
19576
|
+
var ScopeAncestry = class {
|
|
19577
|
+
names = [];
|
|
19578
|
+
threadName;
|
|
19579
|
+
enter(event) {
|
|
19580
|
+
if (event.threadName !== this.threadName) {
|
|
19581
|
+
this.threadName = event.threadName;
|
|
19582
|
+
this.names.length = 0;
|
|
19583
|
+
}
|
|
19584
|
+
this.names.length = Math.min(this.names.length, event.depth);
|
|
19585
|
+
const parentName = event.depth > 0 ? this.names[event.depth - 1] : void 0;
|
|
19586
|
+
this.names[event.depth] = event.timerName;
|
|
19587
|
+
return parentName;
|
|
19588
|
+
}
|
|
19589
|
+
hasOpenAncestorNamed(event) {
|
|
19590
|
+
return this.names.slice(0, event.depth).includes(event.timerName);
|
|
19591
|
+
}
|
|
19592
|
+
};
|
|
19593
|
+
async function summarizeTimingEventStream(lines, options) {
|
|
19594
|
+
let cpuTimeMs = 0;
|
|
19595
|
+
let gpuTimeMs = 0;
|
|
19596
|
+
const frameDurationsMs = [];
|
|
19597
|
+
const worstHitches = [];
|
|
19598
|
+
let hitchCount = 0;
|
|
19599
|
+
const gpuScopeTotals = /* @__PURE__ */ new Map();
|
|
19600
|
+
const gpuAncestry = new ScopeAncestry();
|
|
19601
|
+
await forEachTimingEvent(lines, (event) => {
|
|
19602
|
+
if (isGpuThread(event.threadName)) {
|
|
19603
|
+
accumulateGpuScope(gpuScopeTotals, gpuAncestry, event);
|
|
19604
|
+
if (event.depth === 0) gpuTimeMs += event.durationMs;
|
|
19605
|
+
return;
|
|
18383
19606
|
}
|
|
18384
|
-
|
|
18385
|
-
|
|
18386
|
-
|
|
18387
|
-
|
|
19607
|
+
if (event.depth !== 0) return;
|
|
19608
|
+
cpuTimeMs += event.durationMs;
|
|
19609
|
+
if (!FRAME_ROOT_TIMER_NAMES.has(event.timerName)) return;
|
|
19610
|
+
frameDurationsMs.push(event.durationMs);
|
|
19611
|
+
if (event.durationMs < options.hitchThresholdMs) return;
|
|
18388
19612
|
hitchCount += 1;
|
|
18389
19613
|
retainWorstHitch(worstHitches, options.maxHitches, {
|
|
18390
|
-
durationMs,
|
|
18391
|
-
startTimeMs:
|
|
19614
|
+
durationMs: event.durationMs,
|
|
19615
|
+
startTimeMs: event.startTimeMs,
|
|
19616
|
+
topScopes: []
|
|
18392
19617
|
});
|
|
18393
|
-
}
|
|
19618
|
+
});
|
|
18394
19619
|
return {
|
|
18395
19620
|
frames: summarizeFrameDurations(frameDurationsMs, worstHitches, hitchCount, options),
|
|
19621
|
+
gpuScopes: rankScopeTotals(gpuScopeTotals, options.maxScopes),
|
|
18396
19622
|
threads: {
|
|
18397
19623
|
cpuTimeMs,
|
|
18398
19624
|
gpuTimeMs
|
|
18399
19625
|
}
|
|
18400
19626
|
};
|
|
18401
19627
|
}
|
|
19628
|
+
function accumulateGpuScope(totals, ancestry, event) {
|
|
19629
|
+
const parentName = ancestry.enter(event);
|
|
19630
|
+
const scope = scopeTotalsFor(totals, event.timerName);
|
|
19631
|
+
scope.count += 1;
|
|
19632
|
+
scope.exclusiveTimeMs += event.durationMs;
|
|
19633
|
+
if (!ancestry.hasOpenAncestorNamed(event)) scope.inclusiveTimeMs += event.durationMs;
|
|
19634
|
+
if (parentName !== void 0) scopeTotalsFor(totals, parentName).exclusiveTimeMs -= event.durationMs;
|
|
19635
|
+
}
|
|
19636
|
+
function scopeTotalsFor(totals, name) {
|
|
19637
|
+
const existing = totals.get(name);
|
|
19638
|
+
if (existing !== void 0) return existing;
|
|
19639
|
+
const created = {
|
|
19640
|
+
count: 0,
|
|
19641
|
+
exclusiveTimeMs: 0,
|
|
19642
|
+
inclusiveTimeMs: 0
|
|
19643
|
+
};
|
|
19644
|
+
totals.set(name, created);
|
|
19645
|
+
return created;
|
|
19646
|
+
}
|
|
19647
|
+
function rankScopeTotals(totals, maxScopes) {
|
|
19648
|
+
return rankScopes([...totals].map(([name, scope]) => ({
|
|
19649
|
+
count: scope.count,
|
|
19650
|
+
exclusiveTimeMs: scope.exclusiveTimeMs,
|
|
19651
|
+
inclusiveTimeMs: scope.inclusiveTimeMs,
|
|
19652
|
+
name
|
|
19653
|
+
})), maxScopes);
|
|
19654
|
+
}
|
|
19655
|
+
const SCOPE_KEY_SEPARATOR = "\0";
|
|
19656
|
+
const IDLE_TIMER_NAMES = /* @__PURE__ */ new Set(["TaskWorkerIsLookingForWork", "WaitForTasks"]);
|
|
19657
|
+
async function attributeHitchScopes(lines, hitches, maxScopesPerHitch) {
|
|
19658
|
+
if (hitches.length === 0) return [];
|
|
19659
|
+
const windows = hitches.map((hitch) => ({
|
|
19660
|
+
endTimeMs: hitch.startTimeMs + hitch.durationMs,
|
|
19661
|
+
exclusiveByScope: /* @__PURE__ */ new Map(),
|
|
19662
|
+
hitch,
|
|
19663
|
+
startTimeMs: hitch.startTimeMs
|
|
19664
|
+
})).sort((left, right) => left.startTimeMs - right.startTimeMs);
|
|
19665
|
+
const ancestry = new ScopeAncestry();
|
|
19666
|
+
await forEachTimingEvent(lines, (event) => {
|
|
19667
|
+
if (isGpuThread(event.threadName)) return;
|
|
19668
|
+
const parentName = ancestry.enter(event);
|
|
19669
|
+
const eventEndMs = event.startTimeMs + event.durationMs;
|
|
19670
|
+
for (let index = firstWindowEndingAfter(windows, event.startTimeMs); index < windows.length && (windows[index]?.startTimeMs ?? Number.POSITIVE_INFINITY) < eventEndMs; index += 1) {
|
|
19671
|
+
const window = windows[index];
|
|
19672
|
+
if (window === void 0) break;
|
|
19673
|
+
const overlapMs = Math.min(eventEndMs, window.endTimeMs) - Math.max(event.startTimeMs, window.startTimeMs);
|
|
19674
|
+
if (overlapMs <= 0) continue;
|
|
19675
|
+
addScopeTime(window.exclusiveByScope, event.threadName, event.timerName, overlapMs);
|
|
19676
|
+
if (parentName !== void 0) addScopeTime(window.exclusiveByScope, event.threadName, parentName, -overlapMs);
|
|
19677
|
+
}
|
|
19678
|
+
});
|
|
19679
|
+
return hitches.map((hitch) => {
|
|
19680
|
+
const window = windows.find((candidate) => candidate.hitch === hitch);
|
|
19681
|
+
return {
|
|
19682
|
+
...hitch,
|
|
19683
|
+
topScopes: window === void 0 ? [] : topHitchScopes(window, maxScopesPerHitch)
|
|
19684
|
+
};
|
|
19685
|
+
});
|
|
19686
|
+
}
|
|
19687
|
+
function firstWindowEndingAfter(windows, timeMs) {
|
|
19688
|
+
let low = 0;
|
|
19689
|
+
let high = windows.length;
|
|
19690
|
+
while (low < high) {
|
|
19691
|
+
const middle = low + high >>> 1;
|
|
19692
|
+
if ((windows[middle]?.endTimeMs ?? Number.POSITIVE_INFINITY) <= timeMs) low = middle + 1;
|
|
19693
|
+
else high = middle;
|
|
19694
|
+
}
|
|
19695
|
+
return low;
|
|
19696
|
+
}
|
|
19697
|
+
function addScopeTime(exclusiveByScope, threadName, timerName, ms) {
|
|
19698
|
+
const key = `${threadName}${SCOPE_KEY_SEPARATOR}${timerName}`;
|
|
19699
|
+
exclusiveByScope.set(key, (exclusiveByScope.get(key) ?? 0) + ms);
|
|
19700
|
+
}
|
|
19701
|
+
function topHitchScopes(window, maxScopes) {
|
|
19702
|
+
const scopes = [];
|
|
19703
|
+
for (const [key, exclusiveTimeMs] of window.exclusiveByScope) {
|
|
19704
|
+
if (exclusiveTimeMs <= 1e-6) continue;
|
|
19705
|
+
const separatorAt = key.indexOf(SCOPE_KEY_SEPARATOR);
|
|
19706
|
+
const name = key.slice(separatorAt + 1);
|
|
19707
|
+
if (IDLE_TIMER_NAMES.has(name)) continue;
|
|
19708
|
+
scopes.push({
|
|
19709
|
+
exclusiveTimeMs,
|
|
19710
|
+
name,
|
|
19711
|
+
threadName: key.slice(0, separatorAt)
|
|
19712
|
+
});
|
|
19713
|
+
}
|
|
19714
|
+
return scopes.sort((left, right) => right.exclusiveTimeMs - left.exclusiveTimeMs).slice(0, maxScopes);
|
|
19715
|
+
}
|
|
18402
19716
|
function retainWorstHitch(worstHitches, maxHitches, hitch) {
|
|
18403
19717
|
if (worstHitches.length >= maxHitches) {
|
|
18404
19718
|
const weakest = worstHitches[worstHitches.length - 1];
|
|
@@ -18434,16 +19748,53 @@ function percentile(sortedValues, fraction) {
|
|
|
18434
19748
|
if (sortedValues.length === 0) return 0;
|
|
18435
19749
|
return sortedValues[Math.min(sortedValues.length - 1, Math.max(0, Math.ceil(fraction * sortedValues.length) - 1))] ?? 0;
|
|
18436
19750
|
}
|
|
19751
|
+
function llmTagNameFromCounter(counterName) {
|
|
19752
|
+
return counterName.replace(/^STAT_/u, "").replace(/LLM$/u, "");
|
|
19753
|
+
}
|
|
19754
|
+
async function summarizeMemoryTagCounter(name, lines) {
|
|
19755
|
+
let valueIndex = -1;
|
|
19756
|
+
let finalBytes;
|
|
19757
|
+
let peakBytes = Number.NEGATIVE_INFINITY;
|
|
19758
|
+
let sawHeader = false;
|
|
19759
|
+
for await (const rawLine of lines) {
|
|
19760
|
+
const line = rawLine.trim();
|
|
19761
|
+
if (line.length === 0) continue;
|
|
19762
|
+
const values = parseCsvLine(line);
|
|
19763
|
+
if (!sawHeader) {
|
|
19764
|
+
sawHeader = true;
|
|
19765
|
+
valueIndex = values.findIndex((header) => header.toLowerCase() === "value");
|
|
19766
|
+
if (valueIndex < 0) return;
|
|
19767
|
+
continue;
|
|
19768
|
+
}
|
|
19769
|
+
const value = readNumber(values[valueIndex]);
|
|
19770
|
+
if (value === void 0) continue;
|
|
19771
|
+
finalBytes = value;
|
|
19772
|
+
peakBytes = Math.max(peakBytes, value);
|
|
19773
|
+
}
|
|
19774
|
+
return finalBytes === void 0 ? void 0 : {
|
|
19775
|
+
finalBytes,
|
|
19776
|
+
name,
|
|
19777
|
+
peakBytes
|
|
19778
|
+
};
|
|
19779
|
+
}
|
|
19780
|
+
function rankMemoryTags(tags, maxTags) {
|
|
19781
|
+
return {
|
|
19782
|
+
tags: [...tags].sort((left, right) => right.peakBytes - left.peakBytes).slice(0, maxTags),
|
|
19783
|
+
totalTagCount: tags.length,
|
|
19784
|
+
truncated: tags.length > maxTags
|
|
19785
|
+
};
|
|
19786
|
+
}
|
|
18437
19787
|
//#endregion
|
|
18438
19788
|
//#region src/tools/diagnostics.ts
|
|
18439
19789
|
const ANALYZE_TRACE_DEFAULT_TIMEOUT_MS = 6e5;
|
|
18440
19790
|
const ANALYZE_TRACE_DEFAULT_HITCH_THRESHOLD_MS = 33.4;
|
|
18441
19791
|
const ANALYZE_TRACE_MAX_RESPONSE_BYTES = 32768;
|
|
19792
|
+
const LLM_COUNTER_FILE_PREFIX = "llm-";
|
|
18442
19793
|
const analyzeTraceInputSchema = {
|
|
18443
19794
|
engineVersion: engineVersionSchema,
|
|
18444
19795
|
hitchThresholdMs: z.number().min(1).max(1e4).optional().describe(`Frame duration at or above which a frame counts as a hitch (default ${String(ANALYZE_TRACE_DEFAULT_HITCH_THRESHOLD_MS)}ms, about two frames at 60Hz).`),
|
|
18445
19796
|
maxHitches: z.number().int().min(1).max(50).optional().describe(`Maximum worst-hitch entries to return (default ${String(10)}, max ${String(50)}).`),
|
|
18446
|
-
maxScopes: z.number().int().min(1).max(100).optional().describe(`Maximum timing scopes to return per ranking (default ${String(20)}, max ${String(100)}).`),
|
|
19797
|
+
maxScopes: z.number().int().min(1).max(100).optional().describe(`Maximum timing scopes, GPU scopes and memory tags to return per ranking (default ${String(20)}, max ${String(100)}).`),
|
|
18447
19798
|
projectPath: z.string().trim().min(1).optional().describe("Project whose EngineAssociation selects the analyzer engine. Omit when engineVersion is given."),
|
|
18448
19799
|
timeoutMs: z.number().int().min(1e3).max(MAX_PROCESS_TIMEOUT_MS).optional().describe(`Hard timeout in milliseconds for the analyzer run (default ${String(ANALYZE_TRACE_DEFAULT_TIMEOUT_MS)}).`),
|
|
18449
19800
|
tracePath: z.string().trim().min(1).describe("Path to the .utrace file produced by stop_insights_trace.")
|
|
@@ -18459,8 +19810,10 @@ async function analyzeTrace(input, dependencies, context = createEngineToolchain
|
|
|
18459
19810
|
engineVersion: engine.engineVersion,
|
|
18460
19811
|
hitchThresholdMs,
|
|
18461
19812
|
hitches: [],
|
|
19813
|
+
memoryTags: [],
|
|
18462
19814
|
reason: `UnrealInsights was not found under ${path.join(engine.engineRoot, "Engine", "Binaries")}; the installed UE ${engine.engineVersion} does not ship the trace analyzer for this host.`,
|
|
18463
19815
|
state: "unsupported",
|
|
19816
|
+
topGpuScopes: [],
|
|
18464
19817
|
topScopesByExclusiveTime: [],
|
|
18465
19818
|
topScopesByInclusiveTime: [],
|
|
18466
19819
|
tracePath,
|
|
@@ -18472,7 +19825,11 @@ async function analyzeTrace(input, dependencies, context = createEngineToolchain
|
|
|
18472
19825
|
const timingEventsPath = path.join(exportDirectory, "timing-events.csv");
|
|
18473
19826
|
const commandFilePath = path.join(exportDirectory, "export.rsp");
|
|
18474
19827
|
try {
|
|
18475
|
-
await context.writeFile(commandFilePath, [
|
|
19828
|
+
await context.writeFile(commandFilePath, [
|
|
19829
|
+
`TimingInsights.ExportTimerStatistics ${quoteConsoleArgument(timerStatisticsPath)}`,
|
|
19830
|
+
`TimingInsights.ExportTimingEvents ${quoteConsoleArgument(timingEventsPath)} -columns=ThreadName,TimerName,StartTime,Duration,Depth`,
|
|
19831
|
+
`TimingInsights.ExportCounterValues ${quoteConsoleArgument(path.join(exportDirectory, `${LLM_COUNTER_FILE_PREFIX}{counter}.csv`))} -counter=${LLM_TAG_COUNTER_PATTERN}`
|
|
19832
|
+
].join("\n"));
|
|
18476
19833
|
dependencies.logger.info({
|
|
18477
19834
|
engineVersion: engine.engineVersion,
|
|
18478
19835
|
tracePath
|
|
@@ -18492,16 +19849,24 @@ async function analyzeTrace(input, dependencies, context = createEngineToolchain
|
|
|
18492
19849
|
});
|
|
18493
19850
|
if (run.timedOut) throw new EngineToolchainError(`Unreal Insights did not finish analyzing ${tracePath} within ${String(timeoutMs)}ms; raise timeoutMs or trim the trace.`);
|
|
18494
19851
|
if (run.exitCode !== 0) throw new EngineToolchainError(`Unreal Insights exited with code ${String(run.exitCode)} while analyzing ${tracePath}: ${run.combinedOutput.slice(-1e3).trim()}`);
|
|
18495
|
-
const
|
|
18496
|
-
const
|
|
19852
|
+
const maxScopes = input.maxScopes ?? 20;
|
|
19853
|
+
const scopeSummaries = summarizeTimerStatistics(await readCsvRows(timerStatisticsPath, context), maxScopes);
|
|
19854
|
+
const hasTimingEvents = await context.fileExists(timingEventsPath);
|
|
19855
|
+
const readTimingEventLines = () => hasTimingEvents ? context.readTextLines(timingEventsPath) : emptyTextLines();
|
|
19856
|
+
const timingEvents = await summarizeTimingEventStream(readTimingEventLines(), {
|
|
18497
19857
|
hitchThresholdMs,
|
|
18498
|
-
maxHitches: input.maxHitches ?? 10
|
|
19858
|
+
maxHitches: input.maxHitches ?? 10,
|
|
19859
|
+
maxScopes
|
|
18499
19860
|
});
|
|
18500
19861
|
const frames = timingEvents.frames;
|
|
18501
19862
|
const threadTimes = timingEvents.threads;
|
|
19863
|
+
const hitches = await attributeHitchScopes(readTimingEventLines(), frames.hitches, 5);
|
|
19864
|
+
const memoryTags = await summarizeMemoryTags(exportDirectory, maxScopes, context);
|
|
18502
19865
|
const truncated = [];
|
|
18503
19866
|
if (scopeSummaries.truncated) truncated.push("topScopes");
|
|
18504
19867
|
if (frames.hitchesTruncated) truncated.push("hitches");
|
|
19868
|
+
if (timingEvents.gpuScopes.truncated) truncated.push("topGpuScopes");
|
|
19869
|
+
if (memoryTags.truncated) truncated.push("memoryTags");
|
|
18505
19870
|
const result = {
|
|
18506
19871
|
analyzerPath,
|
|
18507
19872
|
cpuTimeMs: threadTimes.cpuTimeMs,
|
|
@@ -18511,10 +19876,14 @@ async function analyzeTrace(input, dependencies, context = createEngineToolchain
|
|
|
18511
19876
|
frameCount: frames.frameCount,
|
|
18512
19877
|
gpuTimeMs: threadTimes.gpuTimeMs,
|
|
18513
19878
|
hitchThresholdMs,
|
|
18514
|
-
hitches
|
|
19879
|
+
hitches,
|
|
19880
|
+
memoryTags: memoryTags.tags,
|
|
18515
19881
|
state: "analyzed",
|
|
19882
|
+
topGpuScopes: timingEvents.gpuScopes.byExclusiveTime,
|
|
18516
19883
|
topScopesByExclusiveTime: scopeSummaries.byExclusiveTime,
|
|
18517
19884
|
topScopesByInclusiveTime: scopeSummaries.byInclusiveTime,
|
|
19885
|
+
totalGpuScopeCount: timingEvents.gpuScopes.totalScopeCount,
|
|
19886
|
+
totalMemoryTagCount: memoryTags.totalTagCount,
|
|
18518
19887
|
totalScopeCount: scopeSummaries.totalScopeCount,
|
|
18519
19888
|
tracePath,
|
|
18520
19889
|
truncated
|
|
@@ -18560,22 +19929,42 @@ function boundAnalyzeTraceResult(result) {
|
|
|
18560
19929
|
truncated: [...result.truncated]
|
|
18561
19930
|
};
|
|
18562
19931
|
while (JSON.stringify(bounded).length > ANALYZE_TRACE_MAX_RESPONSE_BYTES) {
|
|
18563
|
-
const
|
|
19932
|
+
const topScopesLength = Math.max(bounded.topScopesByInclusiveTime.length, bounded.topScopesByExclusiveTime.length);
|
|
19933
|
+
const longestListLength = Math.max(topScopesLength, bounded.hitches.length, bounded.topGpuScopes.length, bounded.memoryTags.length);
|
|
18564
19934
|
if (longestListLength <= 1) {
|
|
18565
19935
|
addTruncationReason(bounded, "responseBytesExceeded");
|
|
18566
19936
|
return bounded;
|
|
18567
19937
|
}
|
|
18568
|
-
if (
|
|
19938
|
+
if (topScopesLength === longestListLength) {
|
|
18569
19939
|
bounded.topScopesByInclusiveTime = bounded.topScopesByInclusiveTime.slice(0, longestListLength - 1);
|
|
18570
19940
|
bounded.topScopesByExclusiveTime = bounded.topScopesByExclusiveTime.slice(0, longestListLength - 1);
|
|
18571
19941
|
addTruncationReason(bounded, "topScopes");
|
|
18572
19942
|
continue;
|
|
18573
19943
|
}
|
|
19944
|
+
if (bounded.topGpuScopes.length === longestListLength) {
|
|
19945
|
+
bounded.topGpuScopes = bounded.topGpuScopes.slice(0, longestListLength - 1);
|
|
19946
|
+
addTruncationReason(bounded, "topGpuScopes");
|
|
19947
|
+
continue;
|
|
19948
|
+
}
|
|
19949
|
+
if (bounded.memoryTags.length === longestListLength) {
|
|
19950
|
+
bounded.memoryTags = bounded.memoryTags.slice(0, longestListLength - 1);
|
|
19951
|
+
addTruncationReason(bounded, "memoryTags");
|
|
19952
|
+
continue;
|
|
19953
|
+
}
|
|
18574
19954
|
bounded.hitches = bounded.hitches.slice(0, bounded.hitches.length - 1);
|
|
18575
19955
|
addTruncationReason(bounded, "hitches");
|
|
18576
19956
|
}
|
|
18577
19957
|
return bounded;
|
|
18578
19958
|
}
|
|
19959
|
+
async function summarizeMemoryTags(exportDirectory, maxTags, context) {
|
|
19960
|
+
const counterFiles = (await context.listDirectory(exportDirectory)).filter((fileName) => fileName.startsWith(LLM_COUNTER_FILE_PREFIX) && fileName.endsWith(".csv"));
|
|
19961
|
+
const tags = [];
|
|
19962
|
+
for (const fileName of counterFiles) {
|
|
19963
|
+
const tag = await summarizeMemoryTagCounter(llmTagNameFromCounter(fileName.slice(4, -4)), context.readTextLines(path.join(exportDirectory, fileName)));
|
|
19964
|
+
if (tag !== void 0) tags.push(tag);
|
|
19965
|
+
}
|
|
19966
|
+
return rankMemoryTags(tags, maxTags);
|
|
19967
|
+
}
|
|
18579
19968
|
function addTruncationReason(result, reason) {
|
|
18580
19969
|
if (!result.truncated.includes(reason)) result.truncated.push(reason);
|
|
18581
19970
|
}
|
|
@@ -18713,7 +20102,7 @@ function registerDiagnosticsTools(server, dependencies) {
|
|
|
18713
20102
|
}, dependencies));
|
|
18714
20103
|
});
|
|
18715
20104
|
server.registerTool("analyze_trace", {
|
|
18716
|
-
description: "Analyze a completed .utrace (the path stop_insights_trace returns) headlessly with the engine's Unreal Insights analyzer and return a bounded, readable summary: frame-time p50/p90/p99, the worst N hitches with timestamps, a CPU vs GPU time split,
|
|
20105
|
+
description: "Analyze a completed .utrace (the path stop_insights_trace returns) headlessly with the engine's Unreal Insights analyzer and return a bounded, readable summary: frame-time p50/p90/p99, the worst N hitches with timestamps and each hitch's top 5 CPU scopes by exclusive time inside its window (with thread names, task-system idle waits left out), a CPU vs GPU time split, top-N timing scopes by inclusive and exclusive time, top-N GPU scopes by exclusive time, and LLM memory tags with their final and peak bytes. Memory tags are only present when the trace was captured with LLM enabled (-llm) and the stats channel. Resolve the engine with engineVersion or projectPath. Every list is top-N and the response is byte-capped, with truncated naming what was shortened. Returns state 'unsupported' when the installed engine ships no Insights analyzer for this host.",
|
|
18717
20106
|
inputSchema: analyzeTraceInputSchema,
|
|
18718
20107
|
title: "Analyze Trace"
|
|
18719
20108
|
}, async (input) => {
|
|
@@ -19554,6 +20943,7 @@ const listGraphNodesInputSchema = {
|
|
|
19554
20943
|
};
|
|
19555
20944
|
const addGraphNodeInputSchema = {
|
|
19556
20945
|
assetPath: bridgeAddGraphNodeRequestFieldsSchema.shape.assetPath.describe("Package name or object path of the asset owning the graph."),
|
|
20946
|
+
autoLayout: bridgeAddGraphNodeRequestFieldsSchema.shape.autoLayout.describe("Move the new node clear of the graph's existing nodes. Starts from position when given (sliding down until it overlaps nothing), otherwise from just right of the graph's current nodes. Only the new node moves; call layout_graph to rearrange the whole graph."),
|
|
19557
20947
|
graphName: bridgeAddGraphNodeRequestFieldsSchema.shape.graphName.describe("Graph to add the node to."),
|
|
19558
20948
|
kind: bridgeAddGraphNodeRequestFieldsSchema.shape.kind.describe("How the node is named: 'class' places a node type directly, 'function' places a call, 'variable_get' / 'variable_set' place a variable accessor."),
|
|
19559
20949
|
memberName: bridgeAddGraphNodeRequestFieldsSchema.shape.memberName.describe("Function or variable name, required for every kind except 'class'."),
|
|
@@ -19595,6 +20985,11 @@ const setPinDefaultInputSchema = {
|
|
|
19595
20985
|
projectId: creativeProjectIdSchema,
|
|
19596
20986
|
value: bridgeSetPinDefaultRequestSchema.shape.value.describe("ExportText value, the same format get_actor_details emits and set_actor_property accepts.")
|
|
19597
20987
|
};
|
|
20988
|
+
const layoutGraphInputSchema = {
|
|
20989
|
+
assetPath: bridgeLayoutGraphRequestSchema.shape.assetPath.describe("Package name or object path of the Blueprint owning the graph."),
|
|
20990
|
+
graphName: bridgeLayoutGraphRequestSchema.shape.graphName.describe("Graph to arrange, as get_blueprint_summary reports it (e.g. 'EventGraph')."),
|
|
20991
|
+
projectId: creativeProjectIdSchema
|
|
20992
|
+
};
|
|
19598
20993
|
const listAvailableNodesInputSchema = {
|
|
19599
20994
|
assetPath: bridgeListAvailableNodesRequestSchema.shape.assetPath.describe("Package name or object path of the asset owning the graph."),
|
|
19600
20995
|
cursor: bridgeListAvailableNodesRequestSchema.shape.cursor.describe("nextCursor from a previous response, to fetch the following page."),
|
|
@@ -19612,6 +21007,7 @@ async function listGraphNodes(input, dependencies) {
|
|
|
19612
21007
|
}
|
|
19613
21008
|
async function addGraphNode(input, dependencies) {
|
|
19614
21009
|
return await exchangeCreativeRequest(createBridgeAddGraphNodeRequest(input.assetPath, input.graphName, input.kind, {
|
|
21010
|
+
autoLayout: input.autoLayout,
|
|
19615
21011
|
memberName: input.memberName,
|
|
19616
21012
|
memberParentClass: input.memberParentClass,
|
|
19617
21013
|
nodeClass: input.nodeClass,
|
|
@@ -19650,6 +21046,9 @@ async function listAvailableNodes(input, dependencies) {
|
|
|
19650
21046
|
nameFilter: input.nameFilter
|
|
19651
21047
|
}), sendBridgeListAvailableNodesRequest, BRIDGE_LIST_AVAILABLE_NODES_REQUEST_TYPE, projectIdSchema.parse(input.projectId), dependencies);
|
|
19652
21048
|
}
|
|
21049
|
+
async function layoutGraph(input, dependencies) {
|
|
21050
|
+
return await exchangeCreativeRequest(createBridgeLayoutGraphRequest(input.assetPath, input.graphName), sendBridgeLayoutGraphRequest, BRIDGE_LAYOUT_GRAPH_REQUEST_TYPE, projectIdSchema.parse(input.projectId), dependencies);
|
|
21051
|
+
}
|
|
19653
21052
|
function registerGraphTools(server, dependencies) {
|
|
19654
21053
|
server.registerTool("list_graph_nodes", {
|
|
19655
21054
|
description: "List the nodes in any UEdGraph — a Blueprint event graph or function, an Animation Blueprint AnimGraph, a Material graph, a Behavior Tree — with each node's GUID, class, title and pins. The GUID is what every other graph tool addresses a node by; it survives adding and removing other nodes, which an index does not. Results are paged by nextCursor.",
|
|
@@ -19666,12 +21065,13 @@ function registerGraphTools(server, dependencies) {
|
|
|
19666
21065
|
}, dependencies));
|
|
19667
21066
|
});
|
|
19668
21067
|
server.registerTool("add_graph_node", {
|
|
19669
|
-
description: "Add a node to a UEdGraph and return it with its pins, so it can be wired without a follow-up read. kind 'class' places a node type directly (K2Node_IfThenElse for a Branch); 'function' places a call to memberName on memberParentClass; 'variable_get' / 'variable_set' place a variable accessor. Use list_available_nodes to discover what this graph's schema accepts rather than guessing class names. pinDefaults configures the node in the same call. The Blueprint is marked structurally modified, so compile_blueprint afterwards picks the change up.",
|
|
21068
|
+
description: "Add a node to a UEdGraph and return it with its pins, so it can be wired without a follow-up read. kind 'class' places a node type directly (K2Node_IfThenElse for a Branch); 'function' places a call to memberName on memberParentClass; 'variable_get' / 'variable_set' place a variable accessor. Use list_available_nodes to discover what this graph's schema accepts rather than guessing class names. pinDefaults configures the node in the same call. autoLayout moves only the new node clear of the existing ones and reports where it landed in position; layout_graph rearranges the whole graph. The Blueprint is marked structurally modified, so compile_blueprint afterwards picks the change up.",
|
|
19670
21069
|
inputSchema: addGraphNodeInputSchema,
|
|
19671
21070
|
title: "Add Graph Node"
|
|
19672
|
-
}, async ({ assetPath, graphName, kind, memberName, memberParentClass, nodeClass, pinDefaults, position, projectId }) => {
|
|
21071
|
+
}, async ({ assetPath, autoLayout, graphName, kind, memberName, memberParentClass, nodeClass, pinDefaults, position, projectId }) => {
|
|
19673
21072
|
return toToolSuccess(await addGraphNode({
|
|
19674
21073
|
assetPath,
|
|
21074
|
+
autoLayout,
|
|
19675
21075
|
graphName,
|
|
19676
21076
|
kind,
|
|
19677
21077
|
memberName,
|
|
@@ -19752,6 +21152,17 @@ function registerGraphTools(server, dependencies) {
|
|
|
19752
21152
|
projectId
|
|
19753
21153
|
}, dependencies));
|
|
19754
21154
|
});
|
|
21155
|
+
server.registerTool("layout_graph", {
|
|
21156
|
+
description: "Auto-arrange a Blueprint graph so no two nodes overlap: exec flow is layered left to right from each event, branches fan out downward, and pure (data) nodes sit in the column left of the node that consumes them. Comment boxes stay where they are. Node sizes are estimated from title and pin count, since an editor without the graph open has no rendered widget to measure. The whole rearrangement is one undo step. Use it after building a graph with add_graph_node; Material graphs are not supported.",
|
|
21157
|
+
inputSchema: layoutGraphInputSchema,
|
|
21158
|
+
title: "Layout Graph"
|
|
21159
|
+
}, async ({ assetPath, graphName, projectId }) => {
|
|
21160
|
+
return toToolSuccess(await layoutGraph({
|
|
21161
|
+
assetPath,
|
|
21162
|
+
graphName,
|
|
21163
|
+
projectId
|
|
21164
|
+
}, dependencies));
|
|
21165
|
+
});
|
|
19755
21166
|
}
|
|
19756
21167
|
const graphToolDomain = {
|
|
19757
21168
|
domain: "graph",
|
|
@@ -19763,7 +21174,8 @@ const graphToolDomain = {
|
|
|
19763
21174
|
"connect_pins",
|
|
19764
21175
|
"disconnect_pins",
|
|
19765
21176
|
"set_pin_default",
|
|
19766
|
-
"list_available_nodes"
|
|
21177
|
+
"list_available_nodes",
|
|
21178
|
+
"layout_graph"
|
|
19767
21179
|
]
|
|
19768
21180
|
};
|
|
19769
21181
|
//#endregion
|
|
@@ -22275,6 +23687,95 @@ const logsToolDomain = {
|
|
|
22275
23687
|
]
|
|
22276
23688
|
};
|
|
22277
23689
|
//#endregion
|
|
23690
|
+
//#region src/tools/mass.ts
|
|
23691
|
+
const MASS_TRAIT_HINT = "Traits are named by class: 'MassMovementTrait' or 'MassSimpleMovementTrait' (movement), 'MassLODCollectorTrait' or 'MassSimulationLODTrait' (LOD), 'MassVisualizationTrait' or 'MassMovableVisualizationTrait' (representation), 'MassStateTreeTrait' (StateTree behaviour, needs the MassAI plugin), or a '/Script/Module.Class' path.";
|
|
23692
|
+
const createMassEntityConfigInputSchema = {
|
|
23693
|
+
assetName: bridgeCreateMassEntityConfigRequestSchema.shape.assetName.describe("Name of the new MassEntityConfig asset, e.g. 'DA_CrowdAgent'."),
|
|
23694
|
+
packagePath: bridgeCreateMassEntityConfigRequestSchema.shape.packagePath.describe("Content folder to create the config in, e.g. /Game/Mass."),
|
|
23695
|
+
parentConfigPath: bridgeCreateMassEntityConfigRequestSchema.shape.parentConfigPath.describe("Optional MassEntityConfig to inherit traits from; this config overrides any trait of the same class."),
|
|
23696
|
+
projectId: creativeProjectIdSchema
|
|
23697
|
+
};
|
|
23698
|
+
const editMassEntityConfigInputSchema = {
|
|
23699
|
+
assetPath: bridgeEditMassEntityConfigRequestSchema.shape.assetPath.describe("MassEntityConfig asset to edit."),
|
|
23700
|
+
edits: bridgeEditMassEntityConfigRequestSchema.shape.edits.describe(`Trait edits applied in order. 'add' adds the trait (or configures the existing one of that class) and may carry properties; 'set' writes properties on a trait the config owns; 'remove' drops it. properties are { propertyPath, value } pairs in exported-text form, e.g. { propertyPath: 'Movement.MaxSpeed', value: '300' }. ${MASS_TRAIT_HINT}`),
|
|
23701
|
+
projectId: creativeProjectIdSchema
|
|
23702
|
+
};
|
|
23703
|
+
const getMassEntityConfigInputSchema = {
|
|
23704
|
+
assetPath: bridgeGetMassEntityConfigRequestSchema.shape.assetPath.describe("MassEntityConfig asset to read."),
|
|
23705
|
+
projectId: creativeProjectIdSchema
|
|
23706
|
+
};
|
|
23707
|
+
const validateMassEntityConfigInputSchema = {
|
|
23708
|
+
assetPath: bridgeValidateMassEntityConfigRequestSchema.shape.assetPath.describe("MassEntityConfig asset to validate."),
|
|
23709
|
+
projectId: creativeProjectIdSchema
|
|
23710
|
+
};
|
|
23711
|
+
async function createMassEntityConfig(input, dependencies) {
|
|
23712
|
+
return await exchangeCreativeRequest(createBridgeCreateMassEntityConfigRequest(input.assetName, input.packagePath, { parentConfigPath: input.parentConfigPath }), sendBridgeCreateMassEntityConfigRequest, BRIDGE_CREATE_MASS_ENTITY_CONFIG_REQUEST_TYPE, projectIdSchema.parse(input.projectId), dependencies);
|
|
23713
|
+
}
|
|
23714
|
+
async function editMassEntityConfig(input, dependencies) {
|
|
23715
|
+
return await exchangeCreativeRequest(createBridgeEditMassEntityConfigRequest(input.assetPath, input.edits), sendBridgeEditMassEntityConfigRequest, BRIDGE_EDIT_MASS_ENTITY_CONFIG_REQUEST_TYPE, projectIdSchema.parse(input.projectId), dependencies);
|
|
23716
|
+
}
|
|
23717
|
+
async function getMassEntityConfig(input, dependencies) {
|
|
23718
|
+
return await exchangeCreativeRequest(createBridgeGetMassEntityConfigRequest(input.assetPath), sendBridgeGetMassEntityConfigRequest, BRIDGE_GET_MASS_ENTITY_CONFIG_REQUEST_TYPE, projectIdSchema.parse(input.projectId), dependencies);
|
|
23719
|
+
}
|
|
23720
|
+
async function validateMassEntityConfig(input, dependencies) {
|
|
23721
|
+
return await exchangeCreativeRequest(createBridgeValidateMassEntityConfigRequest(input.assetPath), sendBridgeValidateMassEntityConfigRequest, BRIDGE_VALIDATE_MASS_ENTITY_CONFIG_REQUEST_TYPE, projectIdSchema.parse(input.projectId), dependencies);
|
|
23722
|
+
}
|
|
23723
|
+
function registerMassTools(server, dependencies) {
|
|
23724
|
+
server.registerTool("create_mass_entity_config", {
|
|
23725
|
+
description: "Create a MassEntityConfig data asset — the trait list a Mass crowd agent is spawned from — optionally inheriting from a parent config. Add traits with edit_mass_entity_config. Returns state 'unsupported' with a reason when the Mass plugins are not loaded.",
|
|
23726
|
+
inputSchema: createMassEntityConfigInputSchema,
|
|
23727
|
+
title: "Create Mass Entity Config"
|
|
23728
|
+
}, async ({ assetName, packagePath, parentConfigPath, projectId }) => {
|
|
23729
|
+
return toToolSuccess(await createMassEntityConfig({
|
|
23730
|
+
assetName,
|
|
23731
|
+
packagePath,
|
|
23732
|
+
parentConfigPath,
|
|
23733
|
+
projectId
|
|
23734
|
+
}, dependencies));
|
|
23735
|
+
});
|
|
23736
|
+
server.registerTool("edit_mass_entity_config", {
|
|
23737
|
+
description: "Add, remove and configure the traits of a MassEntityConfig (movement, LOD, representation, StateTree and any other Mass trait). Each edit reports its own outcome, and traits lists the config's own trait classes afterwards. The package is left dirty; save it with save_dirty_packages. Run validate_mass_entity_config to check the result.",
|
|
23738
|
+
inputSchema: editMassEntityConfigInputSchema,
|
|
23739
|
+
title: "Edit Mass Entity Config"
|
|
23740
|
+
}, async ({ assetPath, edits, projectId }) => {
|
|
23741
|
+
return toToolSuccess(await editMassEntityConfig({
|
|
23742
|
+
assetPath,
|
|
23743
|
+
edits,
|
|
23744
|
+
projectId
|
|
23745
|
+
}, dependencies));
|
|
23746
|
+
});
|
|
23747
|
+
server.registerTool("get_mass_entity_config", {
|
|
23748
|
+
description: "Read a MassEntityConfig back: its parent config and each of its own traits with the trait's editable properties as exported text, which edit_mass_entity_config accepts unchanged.",
|
|
23749
|
+
inputSchema: getMassEntityConfigInputSchema,
|
|
23750
|
+
title: "Get Mass Entity Config"
|
|
23751
|
+
}, async ({ assetPath, projectId }) => {
|
|
23752
|
+
return toToolSuccess(await getMassEntityConfig({
|
|
23753
|
+
assetPath,
|
|
23754
|
+
projectId
|
|
23755
|
+
}, dependencies));
|
|
23756
|
+
});
|
|
23757
|
+
server.registerTool("validate_mass_entity_config", {
|
|
23758
|
+
description: "Build the config's entity template the way the asset editor's Validate button does and report whether it is valid, with the engine's own error and warning lines verbatim (for example a trait missing a fragment another trait must provide).",
|
|
23759
|
+
inputSchema: validateMassEntityConfigInputSchema,
|
|
23760
|
+
title: "Validate Mass Entity Config"
|
|
23761
|
+
}, async ({ assetPath, projectId }) => {
|
|
23762
|
+
return toToolSuccess(await validateMassEntityConfig({
|
|
23763
|
+
assetPath,
|
|
23764
|
+
projectId
|
|
23765
|
+
}, dependencies));
|
|
23766
|
+
});
|
|
23767
|
+
}
|
|
23768
|
+
const massToolDomain = {
|
|
23769
|
+
domain: "mass",
|
|
23770
|
+
register: registerMassTools,
|
|
23771
|
+
toolNames: [
|
|
23772
|
+
"create_mass_entity_config",
|
|
23773
|
+
"edit_mass_entity_config",
|
|
23774
|
+
"get_mass_entity_config",
|
|
23775
|
+
"validate_mass_entity_config"
|
|
23776
|
+
]
|
|
23777
|
+
};
|
|
23778
|
+
//#endregion
|
|
22278
23779
|
//#region src/tools/material.ts
|
|
22279
23780
|
const createMaterialInstanceInputSchema = {
|
|
22280
23781
|
assetName: bridgeCreateMaterialInstanceRequestSchema.shape.assetName.describe("Name of the new instance, e.g. 'MI_Rock_Mossy'."),
|
|
@@ -22476,6 +23977,307 @@ const meshToolDomain = {
|
|
|
22476
23977
|
]
|
|
22477
23978
|
};
|
|
22478
23979
|
//#endregion
|
|
23980
|
+
//#region src/tools/navigation.ts
|
|
23981
|
+
const setNavmeshSettingsInputSchema = {
|
|
23982
|
+
agentHeight: bridgeSetNavmeshSettingsRequestFieldsSchema.shape.agentHeight.describe("Height of the tallest agent that will path on this navmesh, in cm."),
|
|
23983
|
+
agentMaxSlope: bridgeSetNavmeshSettingsRequestFieldsSchema.shape.agentMaxSlope.describe("Steepest ground an agent can walk, in degrees from horizontal (0-89)."),
|
|
23984
|
+
agentMaxStepHeight: bridgeSetNavmeshSettingsRequestFieldsSchema.shape.agentMaxStepHeight.describe("Tallest step an agent can climb, in cm. Written into the resolution named by resolution."),
|
|
23985
|
+
agentRadius: bridgeSetNavmeshSettingsRequestFieldsSchema.shape.agentRadius.describe("Radius of the smallest agent that will path on this navmesh, in cm. Widening it pulls the navmesh further from every wall."),
|
|
23986
|
+
cellHeight: bridgeSetNavmeshSettingsRequestFieldsSchema.shape.cellHeight.describe("Vertical voxel size, in cm. Written into the resolution named by resolution."),
|
|
23987
|
+
cellSize: bridgeSetNavmeshSettingsRequestFieldsSchema.shape.cellSize.describe("Horizontal voxel size, in cm. Smaller is more precise and much slower to build."),
|
|
23988
|
+
mergeRegionSize: bridgeSetNavmeshSettingsRequestFieldsSchema.shape.mergeRegionSize.describe("Regions up to this size are merged into a bigger neighbour (watershed partitioning only)."),
|
|
23989
|
+
minRegionArea: bridgeSetNavmeshSettingsRequestFieldsSchema.shape.minRegionArea.describe("Islands smaller than this are discarded instead of becoming unreachable navmesh."),
|
|
23990
|
+
navMeshActorPath: bridgeSetNavmeshSettingsRequestFieldsSchema.shape.navMeshActorPath.describe("Actor path of the RecastNavMesh to write. Omit to use the level's main navigation data."),
|
|
23991
|
+
projectId: creativeProjectIdSchema,
|
|
23992
|
+
resolution: bridgeSetNavmeshSettingsRequestFieldsSchema.shape.resolution.describe("Which resolution's voxel parameters cellSize, cellHeight and agentMaxStepHeight are written into. Defaults to 'default'."),
|
|
23993
|
+
runtimeGeneration: bridgeSetNavmeshSettingsRequestFieldsSchema.shape.runtimeGeneration.describe("'static' bakes once, 'dynamic_modifiers_only' rebuilds for nav modifiers, 'dynamic' rebuilds for geometry changes too."),
|
|
23994
|
+
tileSizeUU: bridgeSetNavmeshSettingsRequestFieldsSchema.shape.tileSizeUU.describe("Side of one navmesh tile, in cm. Smaller tiles rebuild faster but cost more memory.")
|
|
23995
|
+
};
|
|
23996
|
+
const setNavAgentsInputSchema = {
|
|
23997
|
+
agents: bridgeSetNavAgentsRequestSchema.shape.agents.describe(`Supported agent types, each { name, radius, height, maxStepHeight?, navDataClass? } (max ${String(16)}). This replaces the project's whole list.`),
|
|
23998
|
+
projectId: creativeProjectIdSchema
|
|
23999
|
+
};
|
|
24000
|
+
const setCrowdSettingsInputSchema = {
|
|
24001
|
+
crowd: bridgeSetCrowdSettingsRequestFieldsSchema.shape.crowd.describe("Detour crowd manager settings: maxAgents, maxAgentRadius, maxAvoidedAgents, maxAvoidedWalls, navmeshCheckInterval, pathOptimizationInterval, separationDirClamp, pathOffsetRadiusMultiplier, resolveCollisions."),
|
|
24002
|
+
projectId: creativeProjectIdSchema,
|
|
24003
|
+
rvo: bridgeSetCrowdSettingsRequestFieldsSchema.shape.rvo.describe("RVO avoidance manager settings: defaultTimeToLive, lockTimeAfterAvoid, lockTimeAfterClean, deltaTimeToPredict, artificialRadiusExpansion, heightCheckMargin.")
|
|
24004
|
+
};
|
|
24005
|
+
const createNavAreaInputSchema = {
|
|
24006
|
+
assetName: bridgeCreateNavAreaRequestSchema.shape.assetName.describe("Name of the new nav area, e.g. 'NA_Mud'."),
|
|
24007
|
+
defaultCost: bridgeCreateNavAreaRequestSchema.shape.defaultCost.describe("Travel cost multiplier for distance through this area. 1 is neutral; higher makes pathfinding avoid it."),
|
|
24008
|
+
drawColor: bridgeCreateNavAreaRequestSchema.shape.drawColor.describe("Colour this area is drawn in the navigation view, as { r, g, b, a? } 0-255."),
|
|
24009
|
+
fixedAreaEnteringCost: bridgeCreateNavAreaRequestSchema.shape.fixedAreaEnteringCost.describe("Flat cost paid once on entering the area, independent of how far the path runs through it."),
|
|
24010
|
+
packagePath: bridgeCreateNavAreaRequestSchema.shape.packagePath.describe("Content folder to create the nav area Blueprint in."),
|
|
24011
|
+
parentClass: bridgeCreateNavAreaRequestSchema.shape.parentClass.describe("Nav area class to derive from: 'NavArea' (default), 'NavArea_Null', 'NavArea_Obstacle', 'NavArea_LowHeight', or the class path of another one."),
|
|
24012
|
+
projectId: creativeProjectIdSchema
|
|
24013
|
+
};
|
|
24014
|
+
const addNavModifierVolumeInputSchema = {
|
|
24015
|
+
actorLabel: bridgeAddNavModifierVolumeRequestSchema.shape.actorLabel.describe("Display label for the placed volume."),
|
|
24016
|
+
areaClass: bridgeAddNavModifierVolumeRequestSchema.shape.areaClass.describe("Nav area to apply inside the volume — 'NavArea_Null' to cut the navmesh away, 'NavArea_Obstacle' to make it expensive, or a class path from create_nav_area."),
|
|
24017
|
+
areaClassToReplace: bridgeAddNavModifierVolumeRequestSchema.shape.areaClassToReplace.describe("When given, only surfaces already marked with this area are replaced by areaClass instead of everything inside the volume."),
|
|
24018
|
+
extent: bridgeAddNavModifierVolumeRequestSchema.shape.extent.describe("Box half-extent of the volume in cm. Every axis must be positive."),
|
|
24019
|
+
folderPath: bridgeAddNavModifierVolumeRequestSchema.shape.folderPath.describe("World Outliner folder to place the volume in."),
|
|
24020
|
+
location: bridgeAddNavModifierVolumeRequestSchema.shape.location.describe("World location of the volume centre."),
|
|
24021
|
+
projectId: creativeProjectIdSchema,
|
|
24022
|
+
rotation: bridgeAddNavModifierVolumeRequestSchema.shape.rotation.describe("World rotation of the volume.")
|
|
24023
|
+
};
|
|
24024
|
+
const addNavLinkInputSchema = {
|
|
24025
|
+
actorLabel: bridgeAddNavLinkRequestSchema.shape.actorLabel.describe("Display label for the placed link actor."),
|
|
24026
|
+
folderPath: bridgeAddNavLinkRequestSchema.shape.folderPath.describe("World Outliner folder to place the link actor in."),
|
|
24027
|
+
links: bridgeAddNavLinkRequestSchema.shape.links.describe(`Point links carried by this actor (max ${String(16)}), each { left, right, direction?, snapRadius?, snapHeight?, leftProjectHeight?, maxFallDownLength?, areaClass?, description? }. left and right are offsets from the actor, not world positions.`),
|
|
24028
|
+
location: bridgeAddNavLinkRequestSchema.shape.location.describe("World location of the link actor."),
|
|
24029
|
+
projectId: creativeProjectIdSchema,
|
|
24030
|
+
rotation: bridgeAddNavLinkRequestSchema.shape.rotation.describe("World rotation of the link actor."),
|
|
24031
|
+
smartLinkEnabled: bridgeAddNavLinkRequestSchema.shape.smartLinkEnabled.describe("Mark the smart link component on this actor navigation-relevant, so it can be toggled at runtime without a rebuild.")
|
|
24032
|
+
};
|
|
24033
|
+
const findPathInputSchema = {
|
|
24034
|
+
allowPartial: bridgeFindPathRequestFieldsSchema.shape.allowPartial.describe("Accept a path that stops short of the goal. Defaults to true, so a blocked destination reports partial rather than nothing."),
|
|
24035
|
+
end: bridgeFindPathRequestFieldsSchema.shape.end.describe("World location to path to. Give this or endActorPath."),
|
|
24036
|
+
endActorPath: bridgeFindPathRequestFieldsSchema.shape.endActorPath.describe("Actor whose location is the goal. Give this or end."),
|
|
24037
|
+
maxPathPoints: bridgeFindPathRequestFieldsSchema.shape.maxPathPoints.describe(`Maximum path points to return (1-${String(256)}). pathPointCount stays the full count and truncated says whether the list was cut.`),
|
|
24038
|
+
navMeshActorPath: bridgeFindPathRequestFieldsSchema.shape.navMeshActorPath.describe("Actor path of the RecastNavMesh to query. Omit to use the level's main navigation data."),
|
|
24039
|
+
projectId: creativeProjectIdSchema,
|
|
24040
|
+
start: bridgeFindPathRequestFieldsSchema.shape.start.describe("World location to path from. Give this or startActorPath."),
|
|
24041
|
+
startActorPath: bridgeFindPathRequestFieldsSchema.shape.startActorPath.describe("Actor whose location is the start. Give this or start.")
|
|
24042
|
+
};
|
|
24043
|
+
const testReachabilityInputSchema = {
|
|
24044
|
+
allowPartial: bridgeTestReachabilityRequestFieldsSchema.shape.allowPartial.describe("Report how far an unreachable pair got, as pathLength on a partial path. Defaults to false. A partial path is reported unreachable either way."),
|
|
24045
|
+
navMeshActorPath: bridgeTestReachabilityRequestFieldsSchema.shape.navMeshActorPath.describe("Actor path of the RecastNavMesh to query. Omit to use the level's main navigation data."),
|
|
24046
|
+
pairs: bridgeTestReachabilityRequestFieldsSchema.shape.pairs.describe(`Start/end pairs to test (max ${String(64)}), each naming exactly one of start/startActorPath and one of end/endActorPath.`),
|
|
24047
|
+
projectId: creativeProjectIdSchema
|
|
24048
|
+
};
|
|
24049
|
+
const diagnoseNavmeshInputSchema = {
|
|
24050
|
+
includePlayerStarts: bridgeDiagnoseNavmeshRequestSchema.shape.includePlayerStarts.describe("Check every PlayerStart in the level as a spawn point. Defaults to true."),
|
|
24051
|
+
maxIslands: bridgeDiagnoseNavmeshRequestSchema.shape.maxIslands.describe(`Most islands to list, largest area first (1-${String(64)}). islandCount stays the full count.`),
|
|
24052
|
+
navMeshActorPath: bridgeDiagnoseNavmeshRequestSchema.shape.navMeshActorPath.describe("Actor path of the RecastNavMesh to inspect. Omit to use the level's main navigation data."),
|
|
24053
|
+
projectId: creativeProjectIdSchema,
|
|
24054
|
+
spawnActorPaths: bridgeDiagnoseNavmeshRequestSchema.shape.spawnActorPaths.describe(`Extra spawn actors to check alongside the player starts, such as AI spawners (max ${String(64)}).`)
|
|
24055
|
+
};
|
|
24056
|
+
async function setNavmeshSettings(input, dependencies) {
|
|
24057
|
+
return await exchangeCreativeRequest(createBridgeSetNavmeshSettingsRequest({
|
|
24058
|
+
agentHeight: input.agentHeight,
|
|
24059
|
+
agentMaxSlope: input.agentMaxSlope,
|
|
24060
|
+
agentMaxStepHeight: input.agentMaxStepHeight,
|
|
24061
|
+
agentRadius: input.agentRadius,
|
|
24062
|
+
cellHeight: input.cellHeight,
|
|
24063
|
+
cellSize: input.cellSize,
|
|
24064
|
+
mergeRegionSize: input.mergeRegionSize,
|
|
24065
|
+
minRegionArea: input.minRegionArea,
|
|
24066
|
+
navMeshActorPath: input.navMeshActorPath,
|
|
24067
|
+
resolution: input.resolution,
|
|
24068
|
+
runtimeGeneration: input.runtimeGeneration,
|
|
24069
|
+
tileSizeUU: input.tileSizeUU
|
|
24070
|
+
}), sendBridgeSetNavmeshSettingsRequest, BRIDGE_SET_NAVMESH_SETTINGS_REQUEST_TYPE, projectIdSchema.parse(input.projectId), dependencies);
|
|
24071
|
+
}
|
|
24072
|
+
async function setNavAgents(input, dependencies) {
|
|
24073
|
+
return await exchangeCreativeRequest(createBridgeSetNavAgentsRequest(input.agents), sendBridgeSetNavAgentsRequest, BRIDGE_SET_NAV_AGENTS_REQUEST_TYPE, projectIdSchema.parse(input.projectId), dependencies);
|
|
24074
|
+
}
|
|
24075
|
+
async function setCrowdSettings(input, dependencies) {
|
|
24076
|
+
return await exchangeCreativeRequest(createBridgeSetCrowdSettingsRequest({
|
|
24077
|
+
crowd: input.crowd,
|
|
24078
|
+
rvo: input.rvo
|
|
24079
|
+
}), sendBridgeSetCrowdSettingsRequest, BRIDGE_SET_CROWD_SETTINGS_REQUEST_TYPE, projectIdSchema.parse(input.projectId), dependencies);
|
|
24080
|
+
}
|
|
24081
|
+
async function createNavArea(input, dependencies) {
|
|
24082
|
+
return await exchangeCreativeRequest(createBridgeCreateNavAreaRequest(input.assetName, input.packagePath, {
|
|
24083
|
+
defaultCost: input.defaultCost,
|
|
24084
|
+
drawColor: input.drawColor,
|
|
24085
|
+
fixedAreaEnteringCost: input.fixedAreaEnteringCost,
|
|
24086
|
+
parentClass: input.parentClass
|
|
24087
|
+
}), sendBridgeCreateNavAreaRequest, BRIDGE_CREATE_NAV_AREA_REQUEST_TYPE, projectIdSchema.parse(input.projectId), dependencies);
|
|
24088
|
+
}
|
|
24089
|
+
async function addNavModifierVolume(input, dependencies) {
|
|
24090
|
+
return await exchangeCreativeRequest(createBridgeAddNavModifierVolumeRequest(input.areaClass, {
|
|
24091
|
+
actorLabel: input.actorLabel,
|
|
24092
|
+
areaClassToReplace: input.areaClassToReplace,
|
|
24093
|
+
extent: input.extent,
|
|
24094
|
+
folderPath: input.folderPath,
|
|
24095
|
+
location: input.location,
|
|
24096
|
+
rotation: input.rotation
|
|
24097
|
+
}), sendBridgeAddNavModifierVolumeRequest, BRIDGE_ADD_NAV_MODIFIER_VOLUME_REQUEST_TYPE, projectIdSchema.parse(input.projectId), dependencies);
|
|
24098
|
+
}
|
|
24099
|
+
async function addNavLink(input, dependencies) {
|
|
24100
|
+
return await exchangeCreativeRequest(createBridgeAddNavLinkRequest(input.links, {
|
|
24101
|
+
actorLabel: input.actorLabel,
|
|
24102
|
+
folderPath: input.folderPath,
|
|
24103
|
+
location: input.location,
|
|
24104
|
+
rotation: input.rotation,
|
|
24105
|
+
smartLinkEnabled: input.smartLinkEnabled
|
|
24106
|
+
}), sendBridgeAddNavLinkRequest, BRIDGE_ADD_NAV_LINK_REQUEST_TYPE, projectIdSchema.parse(input.projectId), dependencies);
|
|
24107
|
+
}
|
|
24108
|
+
async function findPath(input, dependencies) {
|
|
24109
|
+
return await exchangeCreativeRequest(createBridgeFindPathRequest({
|
|
24110
|
+
end: input.end,
|
|
24111
|
+
endActorPath: input.endActorPath,
|
|
24112
|
+
start: input.start,
|
|
24113
|
+
startActorPath: input.startActorPath
|
|
24114
|
+
}, {
|
|
24115
|
+
allowPartial: input.allowPartial,
|
|
24116
|
+
maxPathPoints: input.maxPathPoints,
|
|
24117
|
+
navMeshActorPath: input.navMeshActorPath
|
|
24118
|
+
}), sendBridgeFindPathRequest, BRIDGE_FIND_PATH_REQUEST_TYPE, projectIdSchema.parse(input.projectId), dependencies);
|
|
24119
|
+
}
|
|
24120
|
+
async function testReachability(input, dependencies) {
|
|
24121
|
+
return await exchangeCreativeRequest(createBridgeTestReachabilityRequest(input.pairs, {
|
|
24122
|
+
allowPartial: input.allowPartial,
|
|
24123
|
+
navMeshActorPath: input.navMeshActorPath
|
|
24124
|
+
}), sendBridgeTestReachabilityRequest, BRIDGE_TEST_REACHABILITY_REQUEST_TYPE, projectIdSchema.parse(input.projectId), dependencies);
|
|
24125
|
+
}
|
|
24126
|
+
async function diagnoseNavmesh(input, dependencies) {
|
|
24127
|
+
return await exchangeCreativeRequest(createBridgeDiagnoseNavmeshRequest({
|
|
24128
|
+
includePlayerStarts: input.includePlayerStarts,
|
|
24129
|
+
maxIslands: input.maxIslands,
|
|
24130
|
+
navMeshActorPath: input.navMeshActorPath,
|
|
24131
|
+
spawnActorPaths: input.spawnActorPaths
|
|
24132
|
+
}), sendBridgeDiagnoseNavmeshRequest, BRIDGE_DIAGNOSE_NAVMESH_REQUEST_TYPE, projectIdSchema.parse(input.projectId), dependencies);
|
|
24133
|
+
}
|
|
24134
|
+
function registerNavigationTools(server, dependencies) {
|
|
24135
|
+
server.registerTool("set_navmesh_settings", {
|
|
24136
|
+
description: "Write the level's navmesh generation settings — agent radius and height, max slope and step height, voxel cell size, tile size and runtime generation mode. The values only reach the navmesh on the next build, so follow this with build_navigation. Returns every setting as it stands after the write, so a clamped value is visible.",
|
|
24137
|
+
inputSchema: setNavmeshSettingsInputSchema,
|
|
24138
|
+
title: "Set Navmesh Settings"
|
|
24139
|
+
}, async ({ agentHeight, agentMaxSlope, agentMaxStepHeight, agentRadius, cellHeight, cellSize, mergeRegionSize, minRegionArea, navMeshActorPath, projectId, resolution, runtimeGeneration, tileSizeUU }) => {
|
|
24140
|
+
return toToolSuccess(await setNavmeshSettings({
|
|
24141
|
+
agentHeight,
|
|
24142
|
+
agentMaxSlope,
|
|
24143
|
+
agentMaxStepHeight,
|
|
24144
|
+
agentRadius,
|
|
24145
|
+
cellHeight,
|
|
24146
|
+
cellSize,
|
|
24147
|
+
mergeRegionSize,
|
|
24148
|
+
minRegionArea,
|
|
24149
|
+
navMeshActorPath,
|
|
24150
|
+
projectId,
|
|
24151
|
+
resolution,
|
|
24152
|
+
runtimeGeneration,
|
|
24153
|
+
tileSizeUU
|
|
24154
|
+
}, dependencies));
|
|
24155
|
+
});
|
|
24156
|
+
server.registerTool("set_nav_agents", {
|
|
24157
|
+
description: "Replace the project's list of supported navigation agents, each with its own radius, height and step height. One navmesh is generated per agent type, so this is how a level gets separate navigation for, say, a human and a vehicle. Written to DefaultEngine.ini and read once at startup, so it reports restartRequired.",
|
|
24158
|
+
inputSchema: setNavAgentsInputSchema,
|
|
24159
|
+
title: "Set Nav Agents"
|
|
24160
|
+
}, async ({ agents, projectId }) => {
|
|
24161
|
+
return toToolSuccess(await setNavAgents({
|
|
24162
|
+
agents,
|
|
24163
|
+
projectId
|
|
24164
|
+
}, dependencies));
|
|
24165
|
+
});
|
|
24166
|
+
server.registerTool("set_crowd_settings", {
|
|
24167
|
+
description: "Write the project-wide Detour crowd manager and RVO avoidance settings that decide how AI agents steer around each other. Both are config defaults read at startup, so the response reports restartRequired rather than pretending a running crowd picked them up.",
|
|
24168
|
+
inputSchema: setCrowdSettingsInputSchema,
|
|
24169
|
+
title: "Set Crowd Settings"
|
|
24170
|
+
}, async ({ crowd, projectId, rvo }) => {
|
|
24171
|
+
return toToolSuccess(await setCrowdSettings({
|
|
24172
|
+
crowd,
|
|
24173
|
+
projectId,
|
|
24174
|
+
rvo
|
|
24175
|
+
}, dependencies));
|
|
24176
|
+
});
|
|
24177
|
+
server.registerTool("create_nav_area", {
|
|
24178
|
+
description: "Create a nav area Blueprint with its own travel cost, entering cost and debug colour. Returns generatedClassPath, which is what add_nav_modifier_volume and add_nav_link take to reference the area.",
|
|
24179
|
+
inputSchema: createNavAreaInputSchema,
|
|
24180
|
+
title: "Create Nav Area"
|
|
24181
|
+
}, async ({ assetName, defaultCost, drawColor, fixedAreaEnteringCost, packagePath, parentClass, projectId }) => {
|
|
24182
|
+
return toToolSuccess(await createNavArea({
|
|
24183
|
+
assetName,
|
|
24184
|
+
defaultCost,
|
|
24185
|
+
drawColor,
|
|
24186
|
+
fixedAreaEnteringCost,
|
|
24187
|
+
packagePath,
|
|
24188
|
+
parentClass,
|
|
24189
|
+
projectId
|
|
24190
|
+
}, dependencies));
|
|
24191
|
+
});
|
|
24192
|
+
server.registerTool("add_nav_modifier_volume", {
|
|
24193
|
+
description: "Place a nav modifier volume that applies a nav area to whatever navmesh falls inside it — NavArea_Null to carve a hole an agent will never path through, or a custom area to make the ground expensive rather than impassable. Takes effect on the next build_navigation.",
|
|
24194
|
+
inputSchema: addNavModifierVolumeInputSchema,
|
|
24195
|
+
title: "Add Nav Modifier Volume"
|
|
24196
|
+
}, async ({ actorLabel, areaClass, areaClassToReplace, extent, folderPath, location, projectId, rotation }) => {
|
|
24197
|
+
return toToolSuccess(await addNavModifierVolume({
|
|
24198
|
+
actorLabel,
|
|
24199
|
+
areaClass,
|
|
24200
|
+
areaClassToReplace,
|
|
24201
|
+
extent,
|
|
24202
|
+
folderPath,
|
|
24203
|
+
location,
|
|
24204
|
+
projectId,
|
|
24205
|
+
rotation
|
|
24206
|
+
}, dependencies));
|
|
24207
|
+
});
|
|
24208
|
+
server.registerTool("add_nav_link", {
|
|
24209
|
+
description: "Place a nav link proxy carrying one or more point links, which is what lets an agent jump or drop between navmesh islands that do not touch. Each link names its two ends as offsets from the actor plus a direction; the response reports them in world space. Takes effect on the next build_navigation.",
|
|
24210
|
+
inputSchema: addNavLinkInputSchema,
|
|
24211
|
+
title: "Add Nav Link"
|
|
24212
|
+
}, async ({ actorLabel, folderPath, links, location, projectId, rotation, smartLinkEnabled }) => {
|
|
24213
|
+
return toToolSuccess(await addNavLink({
|
|
24214
|
+
actorLabel,
|
|
24215
|
+
folderPath,
|
|
24216
|
+
links,
|
|
24217
|
+
location,
|
|
24218
|
+
projectId,
|
|
24219
|
+
rotation,
|
|
24220
|
+
smartLinkEnabled
|
|
24221
|
+
}, dependencies));
|
|
24222
|
+
});
|
|
24223
|
+
server.registerTool("find_path", {
|
|
24224
|
+
description: "Run a synchronous navmesh path query in the editor world between two points or actors, returning the path points, its length and cost, and whether it reached the goal. A destination nothing can reach comes back with reachable false and a partial path rather than an error, so this is the way to prove a level is traversable before shipping it.",
|
|
24225
|
+
inputSchema: findPathInputSchema,
|
|
24226
|
+
title: "Find Path"
|
|
24227
|
+
}, async ({ allowPartial, end, endActorPath, maxPathPoints, navMeshActorPath, projectId, start, startActorPath }) => {
|
|
24228
|
+
return toToolSuccess(await findPath({
|
|
24229
|
+
allowPartial,
|
|
24230
|
+
end,
|
|
24231
|
+
endActorPath,
|
|
24232
|
+
maxPathPoints,
|
|
24233
|
+
navMeshActorPath,
|
|
24234
|
+
projectId,
|
|
24235
|
+
start,
|
|
24236
|
+
startActorPath
|
|
24237
|
+
}, dependencies));
|
|
24238
|
+
});
|
|
24239
|
+
server.registerTool("test_reachability", {
|
|
24240
|
+
description: "Answer reachable / not reachable for a batch of start-end pairs in one call, without returning any path geometry. Use it to sweep spawn points against objectives; use find_path when the route itself matters.",
|
|
24241
|
+
inputSchema: testReachabilityInputSchema,
|
|
24242
|
+
title: "Test Reachability"
|
|
24243
|
+
}, async ({ allowPartial, navMeshActorPath, pairs, projectId }) => {
|
|
24244
|
+
return toToolSuccess(await testReachability({
|
|
24245
|
+
allowPartial,
|
|
24246
|
+
navMeshActorPath,
|
|
24247
|
+
pairs,
|
|
24248
|
+
projectId
|
|
24249
|
+
}, dependencies));
|
|
24250
|
+
});
|
|
24251
|
+
server.registerTool("diagnose_navmesh", {
|
|
24252
|
+
description: "Audit the editor level's navmesh without changing it: missing nav bounds, an empty navmesh, disconnected islands (poly count, area and bounds, largest area first), and player starts or named AI spawn actors that sit off the navmesh or cannot path to the first spawn point. Each finding is listed in issues with a code; healthy is true when there are none.",
|
|
24253
|
+
inputSchema: diagnoseNavmeshInputSchema,
|
|
24254
|
+
title: "Diagnose Navmesh"
|
|
24255
|
+
}, async ({ includePlayerStarts, maxIslands, navMeshActorPath, projectId, spawnActorPaths }) => {
|
|
24256
|
+
return toToolSuccess(await diagnoseNavmesh({
|
|
24257
|
+
includePlayerStarts,
|
|
24258
|
+
maxIslands,
|
|
24259
|
+
navMeshActorPath,
|
|
24260
|
+
projectId,
|
|
24261
|
+
spawnActorPaths
|
|
24262
|
+
}, dependencies));
|
|
24263
|
+
});
|
|
24264
|
+
}
|
|
24265
|
+
const navigationToolDomain = {
|
|
24266
|
+
domain: "navigation",
|
|
24267
|
+
register: registerNavigationTools,
|
|
24268
|
+
toolNames: [
|
|
24269
|
+
"set_navmesh_settings",
|
|
24270
|
+
"set_nav_agents",
|
|
24271
|
+
"set_crowd_settings",
|
|
24272
|
+
"create_nav_area",
|
|
24273
|
+
"add_nav_modifier_volume",
|
|
24274
|
+
"add_nav_link",
|
|
24275
|
+
"find_path",
|
|
24276
|
+
"test_reachability",
|
|
24277
|
+
"diagnose_navmesh"
|
|
24278
|
+
]
|
|
24279
|
+
};
|
|
24280
|
+
//#endregion
|
|
22479
24281
|
//#region src/tools/pcg.ts
|
|
22480
24282
|
const createPcgGraphInputSchema = {
|
|
22481
24283
|
assetName: bridgeCreatePcgGraphRequestFieldsSchema.shape.assetName.describe("Name of the new PCG graph, e.g. 'PCG_Forest'."),
|
|
@@ -23389,6 +25191,90 @@ const sequencerToolDomain = {
|
|
|
23389
25191
|
]
|
|
23390
25192
|
};
|
|
23391
25193
|
//#endregion
|
|
25194
|
+
//#region src/tools/smartObjects.ts
|
|
25195
|
+
const createSmartObjectDefinitionInputSchema = {
|
|
25196
|
+
activityTags: bridgeCreateSmartObjectDefinitionRequestSchema.shape.activityTags.describe("Gameplay tags describing what the whole object offers, e.g. 'Activity.Sit'. Every tag must already be registered."),
|
|
25197
|
+
assetName: bridgeCreateSmartObjectDefinitionRequestSchema.shape.assetName.describe("Name of the new Smart Object definition, e.g. 'SOD_Bench'."),
|
|
25198
|
+
defaultBehaviorDefinitions: bridgeCreateSmartObjectDefinitionRequestSchema.shape.defaultBehaviorDefinitions.describe("Behavior definitions every slot without its own falls back to, each { behaviorClass, params? }. behaviorClass names a concrete USmartObjectBehaviorDefinition subclass, e.g. '/Script/GameplayBehaviorSmartObjectsModule.GameplayBehaviorSmartObjectBehaviorDefinition'. A slot with no behavior and no default leaves the definition invalid, and an invalid definition never registers."),
|
|
25199
|
+
packagePath: bridgeCreateSmartObjectDefinitionRequestSchema.shape.packagePath.describe("Content folder to create the definition in."),
|
|
25200
|
+
projectId: creativeProjectIdSchema,
|
|
25201
|
+
slots: bridgeCreateSmartObjectDefinitionRequestSchema.shape.slots.describe("Slots users claim, each { name?, offset?: {x,y,z}, rotation?: {pitch,yaw,roll}, enabled?, activityTags?, behaviorDefinitions? }. Offset and rotation are relative to the owning actor.")
|
|
25202
|
+
};
|
|
25203
|
+
const getSmartObjectDefinitionInputSchema = {
|
|
25204
|
+
assetPath: bridgeGetSmartObjectDefinitionRequestSchema.shape.assetPath.describe("Object path of the Smart Object definition to read."),
|
|
25205
|
+
projectId: creativeProjectIdSchema
|
|
25206
|
+
};
|
|
25207
|
+
const addSmartObjectComponentInputSchema = {
|
|
25208
|
+
actorPath: bridgeAddSmartObjectComponentRequestFieldsSchema.shape.actorPath.describe("Placed actor in the editor level to add the component to. Give this or blueprintPath, not both."),
|
|
25209
|
+
blueprintPath: bridgeAddSmartObjectComponentRequestFieldsSchema.shape.blueprintPath.describe("Actor Blueprint to add the component to; the Blueprint is recompiled. Give this or actorPath, not both."),
|
|
25210
|
+
componentName: bridgeAddSmartObjectComponentRequestFieldsSchema.shape.componentName.describe("Name of the component. Omitted reuses the existing Smart Object component, or names a new one SmartObject."),
|
|
25211
|
+
definitionPath: bridgeAddSmartObjectComponentRequestFieldsSchema.shape.definitionPath.describe("Smart Object definition the component points at."),
|
|
25212
|
+
projectId: creativeProjectIdSchema
|
|
25213
|
+
};
|
|
25214
|
+
async function createSmartObjectDefinition(input, dependencies) {
|
|
25215
|
+
return await exchangeCreativeRequest(createBridgeCreateSmartObjectDefinitionRequest(input.assetName, input.packagePath, input.slots, {
|
|
25216
|
+
activityTags: input.activityTags,
|
|
25217
|
+
defaultBehaviorDefinitions: input.defaultBehaviorDefinitions
|
|
25218
|
+
}), sendBridgeCreateSmartObjectDefinitionRequest, BRIDGE_CREATE_SMART_OBJECT_DEFINITION_REQUEST_TYPE, projectIdSchema.parse(input.projectId), dependencies);
|
|
25219
|
+
}
|
|
25220
|
+
async function getSmartObjectDefinition(input, dependencies) {
|
|
25221
|
+
return await exchangeCreativeRequest(createBridgeGetSmartObjectDefinitionRequest(input.assetPath), sendBridgeGetSmartObjectDefinitionRequest, BRIDGE_GET_SMART_OBJECT_DEFINITION_REQUEST_TYPE, projectIdSchema.parse(input.projectId), dependencies);
|
|
25222
|
+
}
|
|
25223
|
+
async function addSmartObjectComponent(input, dependencies) {
|
|
25224
|
+
return await exchangeCreativeRequest(createBridgeAddSmartObjectComponentRequest(input.definitionPath, {
|
|
25225
|
+
actorPath: input.actorPath,
|
|
25226
|
+
blueprintPath: input.blueprintPath
|
|
25227
|
+
}, { componentName: input.componentName }), sendBridgeAddSmartObjectComponentRequest, BRIDGE_ADD_SMART_OBJECT_COMPONENT_REQUEST_TYPE, projectIdSchema.parse(input.projectId), dependencies);
|
|
25228
|
+
}
|
|
25229
|
+
function registerSmartObjectsTools(server, dependencies) {
|
|
25230
|
+
server.registerTool("create_smart_object_definition", {
|
|
25231
|
+
description: "Create a Smart Object definition with its slots — offsets, rotations, activity tags and behavior definitions — and read back what the asset holds, including whether it passes the engine's validation. An invalid definition never registers, so check 'valid' before placing it. Returns state 'unsupported' when the SmartObjects plugin is not loaded.",
|
|
25232
|
+
inputSchema: createSmartObjectDefinitionInputSchema,
|
|
25233
|
+
title: "Create Smart Object Definition"
|
|
25234
|
+
}, async ({ activityTags, assetName, defaultBehaviorDefinitions, packagePath, projectId, slots }) => {
|
|
25235
|
+
return toToolSuccess(await createSmartObjectDefinition({
|
|
25236
|
+
activityTags,
|
|
25237
|
+
assetName,
|
|
25238
|
+
defaultBehaviorDefinitions,
|
|
25239
|
+
packagePath,
|
|
25240
|
+
projectId,
|
|
25241
|
+
slots
|
|
25242
|
+
}, dependencies));
|
|
25243
|
+
});
|
|
25244
|
+
server.registerTool("get_smart_object_definition", {
|
|
25245
|
+
description: "Read a Smart Object definition: its slots, activity tags, behavior definitions and validation result. Returns state 'unsupported' when the SmartObjects plugin is not loaded.",
|
|
25246
|
+
inputSchema: getSmartObjectDefinitionInputSchema,
|
|
25247
|
+
title: "Get Smart Object Definition"
|
|
25248
|
+
}, async ({ assetPath, projectId }) => {
|
|
25249
|
+
return toToolSuccess(await getSmartObjectDefinition({
|
|
25250
|
+
assetPath,
|
|
25251
|
+
projectId
|
|
25252
|
+
}, dependencies));
|
|
25253
|
+
});
|
|
25254
|
+
server.registerTool("add_smart_object_component", {
|
|
25255
|
+
description: "Add a Smart Object component pointing at a definition to an actor Blueprint or a placed actor, or repoint the one already there. The component registers with the Smart Object subsystem when play begins, which needs a valid definition — 'definitionValid' says whether it will. Returns state 'unsupported' when the SmartObjects plugin is not loaded.",
|
|
25256
|
+
inputSchema: addSmartObjectComponentInputSchema,
|
|
25257
|
+
title: "Add Smart Object Component"
|
|
25258
|
+
}, async ({ actorPath, blueprintPath, componentName, definitionPath, projectId }) => {
|
|
25259
|
+
return toToolSuccess(await addSmartObjectComponent({
|
|
25260
|
+
actorPath,
|
|
25261
|
+
blueprintPath,
|
|
25262
|
+
componentName,
|
|
25263
|
+
definitionPath,
|
|
25264
|
+
projectId
|
|
25265
|
+
}, dependencies));
|
|
25266
|
+
});
|
|
25267
|
+
}
|
|
25268
|
+
const smartObjectsToolDomain = {
|
|
25269
|
+
domain: "smartObjects",
|
|
25270
|
+
register: registerSmartObjectsTools,
|
|
25271
|
+
toolNames: [
|
|
25272
|
+
"create_smart_object_definition",
|
|
25273
|
+
"get_smart_object_definition",
|
|
25274
|
+
"add_smart_object_component"
|
|
25275
|
+
]
|
|
25276
|
+
};
|
|
25277
|
+
//#endregion
|
|
23392
25278
|
//#region src/tools/stateTree.ts
|
|
23393
25279
|
const getStateTreeInputSchema = {
|
|
23394
25280
|
assetPath: bridgeGetStateTreeRequestSchema.shape.assetPath.describe("Object path of the StateTree asset to read."),
|
|
@@ -23427,6 +25313,18 @@ const traceStateTreeInputSchema = {
|
|
|
23427
25313
|
maxEvents: bridgeTraceStateTreeRequestSchema.shape.maxEvents.describe("Maximum events to return in one poll (1-200, default 50)."),
|
|
23428
25314
|
projectId: creativeProjectIdSchema
|
|
23429
25315
|
};
|
|
25316
|
+
const updateStateTreeElementsInputSchema = {
|
|
25317
|
+
assetPath: bridgeUpdateStateTreeElementsRequestSchema.shape.assetPath.describe("Object path of the StateTree asset to edit."),
|
|
25318
|
+
compile: bridgeUpdateStateTreeElementsRequestSchema.shape.compile.describe("Run the StateTree compiler after the edits. Defaults true; its messages come back verbatim in compileMessages."),
|
|
25319
|
+
projectId: creativeProjectIdSchema,
|
|
25320
|
+
updates: bridgeUpdateStateTreeElementsRequestSchema.shape.updates.describe("Edits addressed by the ids get_state_tree reports. { kind: 'state', id, name?, stateType?, selectionBehavior?, enabled? } renames or retypes a state (renaming keeps transitions pointing at it); { kind: 'task', id, params } writes ExportText values onto a task; { kind: 'transition', id, trigger?, targetType?, targetStateId?, eventTag?, enabled? } points a transition at a new target or trigger. A targetStateId alone implies targetType 'goto_state'.")
|
|
25321
|
+
};
|
|
25322
|
+
const removeStateTreeElementsInputSchema = {
|
|
25323
|
+
assetPath: bridgeRemoveStateTreeElementsRequestSchema.shape.assetPath.describe("Object path of the StateTree asset to edit."),
|
|
25324
|
+
compile: bridgeRemoveStateTreeElementsRequestSchema.shape.compile.describe("Run the StateTree compiler after the removals. Defaults true; its messages come back verbatim in compileMessages."),
|
|
25325
|
+
projectId: creativeProjectIdSchema,
|
|
25326
|
+
removals: bridgeRemoveStateTreeElementsRequestSchema.shape.removals.describe("Elements to remove, each { kind, id } with kind 'state', 'task' or 'transition' and the id get_state_tree reports. Removing a state removes its children too.")
|
|
25327
|
+
};
|
|
23430
25328
|
async function getStateTree(input, dependencies) {
|
|
23431
25329
|
return await exchangeCreativeRequest(createBridgeGetStateTreeRequest(input.assetPath), sendBridgeGetStateTreeRequest, BRIDGE_GET_STATE_TREE_REQUEST_TYPE, projectIdSchema.parse(input.projectId), dependencies);
|
|
23432
25330
|
}
|
|
@@ -23455,6 +25353,12 @@ async function traceStateTree(input, dependencies) {
|
|
|
23455
25353
|
maxEvents: input.maxEvents
|
|
23456
25354
|
}), sendBridgeTraceStateTreeRequest, BRIDGE_TRACE_STATE_TREE_REQUEST_TYPE, projectIdSchema.parse(input.projectId), dependencies);
|
|
23457
25355
|
}
|
|
25356
|
+
async function updateStateTreeElements(input, dependencies) {
|
|
25357
|
+
return await exchangeCreativeRequest(createBridgeUpdateStateTreeElementsRequest(input.assetPath, input.updates, { compile: input.compile }), sendBridgeUpdateStateTreeElementsRequest, BRIDGE_UPDATE_STATE_TREE_ELEMENTS_REQUEST_TYPE, projectIdSchema.parse(input.projectId), dependencies);
|
|
25358
|
+
}
|
|
25359
|
+
async function removeStateTreeElements(input, dependencies) {
|
|
25360
|
+
return await exchangeCreativeRequest(createBridgeRemoveStateTreeElementsRequest(input.assetPath, input.removals, { compile: input.compile }), sendBridgeRemoveStateTreeElementsRequest, BRIDGE_REMOVE_STATE_TREE_ELEMENTS_REQUEST_TYPE, projectIdSchema.parse(input.projectId), dependencies);
|
|
25361
|
+
}
|
|
23458
25362
|
function registerStateTreeTools(server, dependencies) {
|
|
23459
25363
|
server.registerTool("get_state_tree", {
|
|
23460
25364
|
description: "Read a StateTree back: its schema, parameters, evaluators, global tasks and the full state hierarchy with each state's tasks, enter conditions and transitions. Every state and node carries the id the edit tools address it by, so this is the call to make before editing a tree you did not author. compiled reports whether the asset carries runtime data — a tree that reads back correctly with compiled false is authored but will not run.",
|
|
@@ -23529,6 +25433,30 @@ function registerStateTreeTools(server, dependencies) {
|
|
|
23529
25433
|
projectId
|
|
23530
25434
|
}, dependencies));
|
|
23531
25435
|
});
|
|
25436
|
+
server.registerTool("update_state_tree_elements", {
|
|
25437
|
+
description: "Edit existing StateTree states, tasks and transitions by the ids get_state_tree reports: rename or retype a state, toggle it, change its selection behaviour; set a task's params; retarget, retrigger or toggle a transition. Each edit is reported per item, and the tree is recompiled by default with the compiler's own messages returned verbatim.",
|
|
25438
|
+
inputSchema: updateStateTreeElementsInputSchema,
|
|
25439
|
+
title: "Update StateTree Elements"
|
|
25440
|
+
}, async ({ assetPath, compile, projectId, updates }) => {
|
|
25441
|
+
return toToolSuccess(await updateStateTreeElements({
|
|
25442
|
+
assetPath,
|
|
25443
|
+
compile,
|
|
25444
|
+
projectId,
|
|
25445
|
+
updates
|
|
25446
|
+
}, dependencies));
|
|
25447
|
+
});
|
|
25448
|
+
server.registerTool("remove_state_tree_elements", {
|
|
25449
|
+
description: "Remove StateTree states, tasks and transitions by the ids get_state_tree reports. Removing a state removes its children and every transition elsewhere in the tree that targeted it; those transitions are listed in removedTransitions. The tree is recompiled by default with the compiler's own messages returned verbatim.",
|
|
25450
|
+
inputSchema: removeStateTreeElementsInputSchema,
|
|
25451
|
+
title: "Remove StateTree Elements"
|
|
25452
|
+
}, async ({ assetPath, compile, projectId, removals }) => {
|
|
25453
|
+
return toToolSuccess(await removeStateTreeElements({
|
|
25454
|
+
assetPath,
|
|
25455
|
+
compile,
|
|
25456
|
+
projectId,
|
|
25457
|
+
removals
|
|
25458
|
+
}, dependencies));
|
|
25459
|
+
});
|
|
23532
25460
|
}
|
|
23533
25461
|
const stateTreeToolDomain = {
|
|
23534
25462
|
domain: "stateTree",
|
|
@@ -23539,7 +25467,9 @@ const stateTreeToolDomain = {
|
|
|
23539
25467
|
"set_state_tree_considerations",
|
|
23540
25468
|
"link_state_tree_state",
|
|
23541
25469
|
"add_state_tree_component",
|
|
23542
|
-
"trace_state_tree"
|
|
25470
|
+
"trace_state_tree",
|
|
25471
|
+
"update_state_tree_elements",
|
|
25472
|
+
"remove_state_tree_elements"
|
|
23543
25473
|
]
|
|
23544
25474
|
};
|
|
23545
25475
|
//#endregion
|
|
@@ -24464,7 +26394,10 @@ const TOOL_CATALOG = [
|
|
|
24464
26394
|
renderToolDomain,
|
|
24465
26395
|
vfxToolDomain,
|
|
24466
26396
|
pcgToolDomain,
|
|
24467
|
-
projectSettingsToolDomain
|
|
26397
|
+
projectSettingsToolDomain,
|
|
26398
|
+
navigationToolDomain,
|
|
26399
|
+
smartObjectsToolDomain,
|
|
26400
|
+
massToolDomain
|
|
24468
26401
|
];
|
|
24469
26402
|
//#endregion
|
|
24470
26403
|
//#region src/mcpTools.ts
|