@satelliteoflove/godot-mcp 3.7.1 → 3.8.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/addon/command_router.gd +1 -0
- package/addon/command_router.gd.uid +1 -0
- package/addon/commands/animation_commands.gd.uid +1 -0
- package/addon/commands/debug_commands.gd +20 -1
- package/addon/commands/debug_commands.gd.uid +1 -0
- package/addon/commands/game_time_commands.gd +78 -0
- package/addon/commands/game_time_commands.gd.uid +1 -0
- package/addon/commands/node_commands.gd.uid +1 -0
- package/addon/commands/profiler_commands.gd.uid +1 -0
- package/addon/commands/project_commands.gd.uid +1 -0
- package/addon/commands/resource_commands.gd.uid +1 -0
- package/addon/commands/runtime_state_commands.gd.uid +1 -0
- package/addon/commands/scene3d_commands.gd.uid +1 -0
- package/addon/commands/scene_commands.gd.uid +1 -0
- package/addon/commands/screenshot_commands.gd.uid +1 -0
- package/addon/commands/script_commands.gd.uid +1 -0
- package/addon/commands/selection_commands.gd.uid +1 -0
- package/addon/commands/tilemap_commands.gd.uid +1 -0
- package/addon/core/base_command.gd.uid +1 -0
- package/addon/core/mcp_constants.gd.uid +1 -0
- package/addon/core/mcp_debugger_plugin.gd.uid +1 -0
- package/addon/core/mcp_enums.gd.uid +1 -0
- package/addon/core/mcp_logger.gd +1 -1
- package/addon/core/mcp_logger.gd.uid +1 -0
- package/addon/core/mcp_utils.gd.uid +1 -0
- package/addon/game_bridge/mcp_frame_profiler.gd.uid +1 -0
- package/addon/game_bridge/mcp_game_bridge.gd +358 -3
- package/addon/game_bridge/mcp_game_bridge.gd.uid +1 -0
- package/addon/game_bridge/mcp_runtime_state_sampler.gd.uid +1 -0
- package/addon/game_bridge/onscreen.gd.uid +1 -0
- package/addon/plugin.cfg +1 -1
- package/addon/plugin.gd.uid +1 -0
- package/addon/ui/status_panel.gd.uid +1 -0
- package/addon/websocket_server.gd.uid +1 -0
- package/dist/__tests__/tools/editor.test.js +8 -0
- package/dist/__tests__/tools/editor.test.js.map +1 -1
- package/dist/__tests__/tools/game-time.test.d.ts +2 -0
- package/dist/__tests__/tools/game-time.test.d.ts.map +1 -0
- package/dist/__tests__/tools/game-time.test.js +134 -0
- package/dist/__tests__/tools/game-time.test.js.map +1 -0
- package/dist/tools/editor.d.ts +1 -0
- package/dist/tools/editor.d.ts.map +1 -1
- package/dist/tools/editor.js +9 -2
- package/dist/tools/editor.js.map +1 -1
- package/dist/tools/game-time.d.ts +20 -0
- package/dist/tools/game-time.d.ts.map +1 -0
- package/dist/tools/game-time.js +92 -0
- package/dist/tools/game-time.js.map +1 -0
- package/dist/tools/index.d.ts +1 -0
- package/dist/tools/index.d.ts.map +1 -1
- package/dist/tools/index.js +3 -0
- package/dist/tools/index.js.map +1 -1
- package/dist/tools/input.d.ts +5 -0
- package/dist/tools/input.d.ts.map +1 -1
- package/dist/tools/input.js +1 -1
- package/dist/tools/input.js.map +1 -1
- package/package.json +1 -1
package/addon/command_router.gd
CHANGED
|
@@ -22,6 +22,7 @@ func setup(plugin: EditorPlugin) -> void:
|
|
|
22
22
|
_register_handler(MCPInputCommands.new(), plugin)
|
|
23
23
|
_register_handler(MCPProfilerCommands.new(), plugin)
|
|
24
24
|
_register_handler(MCPRuntimeStateCommands.new(), plugin)
|
|
25
|
+
_register_handler(MCPGameTimeCommands.new(), plugin)
|
|
25
26
|
|
|
26
27
|
|
|
27
28
|
func _register_handler(handler: MCPBaseCommand, plugin: EditorPlugin) -> void:
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
uid://bhjejek8ivdv8
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
uid://dg4xlid3mi2mi
|
|
@@ -3,6 +3,8 @@ extends MCPBaseCommand
|
|
|
3
3
|
class_name MCPDebugCommands
|
|
4
4
|
|
|
5
5
|
const DEBUG_OUTPUT_TIMEOUT := 5.0
|
|
6
|
+
# Keep in sync with LAUNCH_FROZEN_ENV in mcp_game_bridge.gd.
|
|
7
|
+
const LAUNCH_FROZEN_ENV := "GODOT_MCP_LAUNCH_FROZEN"
|
|
6
8
|
|
|
7
9
|
var _debug_output_result: PackedStringArray = []
|
|
8
10
|
var _debug_output_pending: bool = false
|
|
@@ -21,15 +23,32 @@ func get_commands() -> Dictionary:
|
|
|
21
23
|
|
|
22
24
|
func run_project(params: Dictionary) -> Dictionary:
|
|
23
25
|
var scene_path: String = params.get("scene_path", "")
|
|
26
|
+
var frozen: bool = params.get("frozen", false)
|
|
24
27
|
|
|
25
28
|
MCPLogger.clear()
|
|
26
29
|
|
|
30
|
+
# Launch-frozen: the spawned game inherits the editor's environment, so
|
|
31
|
+
# setting this before play makes the bridge freeze the tree in _ready —
|
|
32
|
+
# before the first process frame. Deterministic, unlike sending a freeze
|
|
33
|
+
# message after the debug session comes up (which races the game's first
|
|
34
|
+
# frames against the agent's latency).
|
|
35
|
+
if frozen:
|
|
36
|
+
OS.set_environment(LAUNCH_FROZEN_ENV, "1")
|
|
37
|
+
|
|
27
38
|
if scene_path.is_empty():
|
|
28
39
|
EditorInterface.play_main_scene()
|
|
29
40
|
else:
|
|
30
41
|
EditorInterface.play_custom_scene(scene_path)
|
|
31
42
|
|
|
32
|
-
|
|
43
|
+
if frozen:
|
|
44
|
+
# The child captured its environment at spawn; clear promptly so a
|
|
45
|
+
# manual F5 run doesn't inherit the freeze. Two frames covers a
|
|
46
|
+
# deferred spawn. (Godot has no unset; empty fails the == "1" check.)
|
|
47
|
+
await Engine.get_main_loop().process_frame
|
|
48
|
+
await Engine.get_main_loop().process_frame
|
|
49
|
+
OS.set_environment(LAUNCH_FROZEN_ENV, "")
|
|
50
|
+
|
|
51
|
+
return _success({"frozen": frozen})
|
|
33
52
|
|
|
34
53
|
|
|
35
54
|
func stop_project(_params: Dictionary) -> Dictionary:
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
uid://cquyem31g4y4b
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
@tool
|
|
2
|
+
extends MCPBaseCommand
|
|
3
|
+
class_name MCPGameTimeCommands
|
|
4
|
+
|
|
5
|
+
# Game-time control relay: freeze / step / thaw / status execute in the game
|
|
6
|
+
# bridge (see mcp_game_bridge.gd); this side only forwards over the debugger
|
|
7
|
+
# channel and waits. Timeout cascade: the step request is capped at 20s of
|
|
8
|
+
# game time and the bridge's wall budget returns by 25s, so the 28s relay
|
|
9
|
+
# timeout below fires only if the bridge is gone — and stays under the
|
|
10
|
+
# server's 30s command timeout so errors surface typed instead of generic.
|
|
11
|
+
const BASE_TIMEOUT := 10.0
|
|
12
|
+
const STEP_TIMEOUT := 28.0
|
|
13
|
+
|
|
14
|
+
var _last_error: Dictionary = {}
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
func get_commands() -> Dictionary:
|
|
18
|
+
return {
|
|
19
|
+
"game_time_freeze": game_time_freeze,
|
|
20
|
+
"game_time_step": game_time_step,
|
|
21
|
+
"game_time_thaw": game_time_thaw,
|
|
22
|
+
"game_time_status": game_time_status,
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
func game_time_freeze(params: Dictionary) -> Dictionary:
|
|
27
|
+
return await _relay("game_time_freeze", [params], BASE_TIMEOUT)
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
func game_time_step(params: Dictionary) -> Dictionary:
|
|
31
|
+
return await _relay("game_time_step", [params], STEP_TIMEOUT)
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
func game_time_thaw(params: Dictionary) -> Dictionary:
|
|
35
|
+
return await _relay("game_time_thaw", [params], BASE_TIMEOUT)
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
func game_time_status(params: Dictionary) -> Dictionary:
|
|
39
|
+
return await _relay("game_time_status", [params], BASE_TIMEOUT)
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
func _relay(msg_type: String, args: Array, timeout: float) -> Dictionary:
|
|
43
|
+
var response = await _send_and_wait(msg_type, args, timeout)
|
|
44
|
+
if response == null:
|
|
45
|
+
return _last_error
|
|
46
|
+
if response is Dictionary and response.has("error"):
|
|
47
|
+
return _error("GAME_TIME_ERROR", str(response["error"]))
|
|
48
|
+
if response is Dictionary:
|
|
49
|
+
return _success(response)
|
|
50
|
+
return _success({"data": response})
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
func _send_and_wait(msg_type: String, args: Array, timeout: float):
|
|
54
|
+
if not EditorInterface.is_playing_scene():
|
|
55
|
+
_last_error = _error("NOT_RUNNING", "No game is currently running")
|
|
56
|
+
return null
|
|
57
|
+
|
|
58
|
+
var debugger_plugin = _plugin.get_debugger_plugin() if _plugin else null
|
|
59
|
+
if debugger_plugin == null or not debugger_plugin.has_active_session():
|
|
60
|
+
_last_error = _error("NO_SESSION", "No active debug session")
|
|
61
|
+
return null
|
|
62
|
+
|
|
63
|
+
var sent: bool = debugger_plugin.send_game_message(msg_type, args)
|
|
64
|
+
if not sent:
|
|
65
|
+
_last_error = _error("SEND_FAILED", "Failed to send message to game")
|
|
66
|
+
return null
|
|
67
|
+
|
|
68
|
+
var start_time := Time.get_ticks_msec()
|
|
69
|
+
while not debugger_plugin.has_response(msg_type):
|
|
70
|
+
await Engine.get_main_loop().process_frame
|
|
71
|
+
if (Time.get_ticks_msec() - start_time) / 1000.0 > timeout:
|
|
72
|
+
debugger_plugin.clear_response(msg_type)
|
|
73
|
+
_last_error = _error("TIMEOUT", "Timed out waiting for %s response" % msg_type)
|
|
74
|
+
return null
|
|
75
|
+
|
|
76
|
+
var response = debugger_plugin.get_response(msg_type)
|
|
77
|
+
debugger_plugin.clear_response(msg_type)
|
|
78
|
+
return response
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
uid://c2pfjqe2yv0c4
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
uid://bke2rvqtw381m
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
uid://c17gnisv1uqju
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
uid://es4uegishf00
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
uid://yts2tlf0btx5
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
uid://bns7tsagruukm
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
uid://cniw11jpk5y82
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
uid://ngt4k3u88sj3
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
uid://c578gd4ovecgt
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
uid://b1om27ef4rvws
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
uid://ciy2n67gqdsla
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
uid://cietp5vxfv072
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
uid://cwqpmprsn6g2
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
uid://hkoghrp3us8j
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
uid://daogurpabpiap
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
uid://b1yx7jiol72rg
|
package/addon/core/mcp_logger.gd
CHANGED
|
@@ -34,7 +34,7 @@ func _log_error(function: String, file: String, line: int, code: String,
|
|
|
34
34
|
for backtrace in script_backtraces:
|
|
35
35
|
for i in backtrace.get_frame_count():
|
|
36
36
|
frames.append({
|
|
37
|
-
"file": backtrace.
|
|
37
|
+
"file": backtrace.get_frame_file(i),
|
|
38
38
|
"line": backtrace.get_frame_line(i),
|
|
39
39
|
"function": backtrace.get_frame_function(i),
|
|
40
40
|
})
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
uid://yv8gf1cuf48v
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
uid://dckosaj3snxdo
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
uid://cihxpb547p4du
|
|
@@ -27,8 +27,18 @@ func _ready() -> void:
|
|
|
27
27
|
_sampler = MCPRuntimeStateSampler.new()
|
|
28
28
|
add_child(_sampler)
|
|
29
29
|
EngineDebugger.register_message_capture("godot_mcp", _on_debugger_message)
|
|
30
|
+
set_physics_process(false) # only counts ticks during a step window
|
|
30
31
|
MCPLog.info("Game bridge initialized")
|
|
31
32
|
|
|
33
|
+
# Launch-frozen: the editor sets this env var just before spawning the game
|
|
34
|
+
# (godot_editor run with frozen=true), so the freeze lands before the first
|
|
35
|
+
# process frame — agent latency between run and the first input costs the
|
|
36
|
+
# game nothing. Scene _ready callbacks still run; processing does not start.
|
|
37
|
+
if OS.get_environment(LAUNCH_FROZEN_ENV) == "1":
|
|
38
|
+
_launched_frozen = true
|
|
39
|
+
_engage_freeze()
|
|
40
|
+
MCPLog.info("Game bridge: launched frozen")
|
|
41
|
+
|
|
32
42
|
|
|
33
43
|
func _exit_tree() -> void:
|
|
34
44
|
# Guaranteed cleanup: never leave an action latched when the bridge node
|
|
@@ -40,7 +50,19 @@ func _exit_tree() -> void:
|
|
|
40
50
|
EngineDebugger.unregister_profiler("mcp_frame_profiler")
|
|
41
51
|
|
|
42
52
|
|
|
43
|
-
func _process(
|
|
53
|
+
func _process(delta: float) -> void:
|
|
54
|
+
_game_time_process(delta)
|
|
55
|
+
_sequence_process()
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
# Processing is needed by three independent features; only switch it off when
|
|
59
|
+
# none of them is active (the frozen monitor must run every frame, so the old
|
|
60
|
+
# "disable after the sequence" shortcut no longer applies unconditionally).
|
|
61
|
+
func _update_processing() -> void:
|
|
62
|
+
set_process(_sequence_running or _frozen or _step_active)
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
func _sequence_process() -> void:
|
|
44
66
|
if not _sequence_running or _sequence_events.is_empty():
|
|
45
67
|
return
|
|
46
68
|
|
|
@@ -61,7 +83,7 @@ func _process(_delta: float) -> void:
|
|
|
61
83
|
|
|
62
84
|
if _sequence_events.is_empty():
|
|
63
85
|
_sequence_running = false
|
|
64
|
-
|
|
86
|
+
_update_processing()
|
|
65
87
|
EngineDebugger.send_message("godot_mcp:input_sequence_result", [{
|
|
66
88
|
"completed": true,
|
|
67
89
|
"actions_executed": _actions_completed,
|
|
@@ -142,6 +164,18 @@ func _on_debugger_message(message: String, data: Array) -> bool:
|
|
|
142
164
|
"watch_stop":
|
|
143
165
|
_handle_watch_stop()
|
|
144
166
|
return true
|
|
167
|
+
"game_time_freeze":
|
|
168
|
+
_handle_game_time_freeze(data)
|
|
169
|
+
return true
|
|
170
|
+
"game_time_step":
|
|
171
|
+
_handle_game_time_step(data)
|
|
172
|
+
return true
|
|
173
|
+
"game_time_thaw":
|
|
174
|
+
_handle_game_time_thaw(data)
|
|
175
|
+
return true
|
|
176
|
+
"game_time_status":
|
|
177
|
+
_handle_game_time_status(data)
|
|
178
|
+
return true
|
|
145
179
|
return false
|
|
146
180
|
|
|
147
181
|
|
|
@@ -965,7 +999,7 @@ func _handle_execute_input_sequence(data: Array) -> void:
|
|
|
965
999
|
|
|
966
1000
|
_sequence_start_time = Time.get_ticks_msec()
|
|
967
1001
|
_sequence_running = true
|
|
968
|
-
|
|
1002
|
+
_update_processing()
|
|
969
1003
|
|
|
970
1004
|
|
|
971
1005
|
func _handle_type_text(data: Array) -> void:
|
|
@@ -1022,3 +1056,324 @@ func _type_text_async(text: String, delay_ms: int, submit: bool) -> void:
|
|
|
1022
1056
|
"chars_typed": text.length(),
|
|
1023
1057
|
"submitted": submit,
|
|
1024
1058
|
}])
|
|
1059
|
+
|
|
1060
|
+
|
|
1061
|
+
# ---------------------------------------------------------------------------
|
|
1062
|
+
# Game-time control (freeze / step / thaw / status)
|
|
1063
|
+
#
|
|
1064
|
+
# Real-time games race ahead of high-latency agents: 10-40s of consequences
|
|
1065
|
+
# land between every observation and the action it informs. These primitives
|
|
1066
|
+
# make game time answer to the agent's clock instead: freeze the tree, think
|
|
1067
|
+
# arbitrarily long (all observation tools work while frozen — rendering
|
|
1068
|
+
# continues during pause), then step forward a bounded slice of game time
|
|
1069
|
+
# with inputs riding inside the window.
|
|
1070
|
+
#
|
|
1071
|
+
# tree.paused is a single bit that two parties now write: the game's own
|
|
1072
|
+
# pause menu and this freeze. The bridge layers them — effective state is
|
|
1073
|
+
# (game_paused OR frozen) — by observing and re-asserting: it cannot
|
|
1074
|
+
# intercept writes, but it processes every frame (PROCESS_MODE_ALWAYS, and
|
|
1075
|
+
# as an autoload it runs BEFORE the scene), so a game-code flip is caught on
|
|
1076
|
+
# the next frame, recorded as the game layer's new intent, and overridden
|
|
1077
|
+
# while frozen. step/thaw restore the game's wish, not whatever we found.
|
|
1078
|
+
#
|
|
1079
|
+
# What freeze means: exactly what runs during the game's own pause menu runs
|
|
1080
|
+
# during freeze (WHEN_PAUSED/ALWAYS nodes, process_always timers). A game
|
|
1081
|
+
# with a correct pause menu has already partitioned pause-immune from
|
|
1082
|
+
# pausable code; freeze rides that contract. Games that "pause" by writing
|
|
1083
|
+
# Engine.time_scale = 0 instead are frozen solid too, but their pause is
|
|
1084
|
+
# invisible to the layer model (it looks like gameplay state, not pause
|
|
1085
|
+
# state) — documented limitation.
|
|
1086
|
+
# ---------------------------------------------------------------------------
|
|
1087
|
+
|
|
1088
|
+
const LAUNCH_FROZEN_ENV := "GODOT_MCP_LAUNCH_FROZEN"
|
|
1089
|
+
# Timeout cascade: step request <= 20s game time, wall budget 25s, editor
|
|
1090
|
+
# relay 28s, server command timeout 30s. Each layer answers before the one
|
|
1091
|
+
# above it gives up.
|
|
1092
|
+
const STEP_MAX_MS := 20000
|
|
1093
|
+
const STEP_MAX_FRAMES := 1200
|
|
1094
|
+
const STEP_WALL_BUDGET_MS := 25000
|
|
1095
|
+
const STEP_MAX_TRANSITIONS := 50
|
|
1096
|
+
const FREEZE_CONTESTED_THRESHOLD := 10
|
|
1097
|
+
|
|
1098
|
+
var _frozen := false
|
|
1099
|
+
var _game_paused := false # the game layer's own pause intent, inferred by observation
|
|
1100
|
+
var _launched_frozen := false
|
|
1101
|
+
var _freeze_started_ticks := 0
|
|
1102
|
+
var _freeze_transition_count := 0
|
|
1103
|
+
|
|
1104
|
+
var _step_active := false
|
|
1105
|
+
var _step_finish_pending := false
|
|
1106
|
+
var _step_needs_settle := false
|
|
1107
|
+
var _step_wall_exceeded := false
|
|
1108
|
+
var _step_target_ms := 0.0
|
|
1109
|
+
var _step_target_frames := 0
|
|
1110
|
+
var _step_elapsed_ms := 0.0 # accumulated scaled delta = game time (wall-of-step, includes game-paused stretches)
|
|
1111
|
+
var _step_gameplay_ms := 0.0 # the unpaused portion: what gameplay actually experienced
|
|
1112
|
+
var _step_frames := 0
|
|
1113
|
+
var _step_physics_ticks := 0
|
|
1114
|
+
var _step_wall_start := 0
|
|
1115
|
+
var _step_events: Array = [] # in-step input timeline, scheduled on the game-time clock
|
|
1116
|
+
var _step_events_fired := 0
|
|
1117
|
+
var _step_transitions: Array = []
|
|
1118
|
+
var _step_last_tree_paused := false
|
|
1119
|
+
|
|
1120
|
+
|
|
1121
|
+
func _send_game_time_response(msg_type: String, result: Dictionary) -> void:
|
|
1122
|
+
EngineDebugger.send_message("godot_mcp:game_response", [msg_type, result])
|
|
1123
|
+
|
|
1124
|
+
|
|
1125
|
+
func _engage_freeze() -> void:
|
|
1126
|
+
if _frozen:
|
|
1127
|
+
return
|
|
1128
|
+
var tree := get_tree()
|
|
1129
|
+
_game_paused = tree.paused
|
|
1130
|
+
_frozen = true
|
|
1131
|
+
_freeze_started_ticks = Time.get_ticks_msec()
|
|
1132
|
+
_freeze_transition_count = 0
|
|
1133
|
+
tree.paused = true
|
|
1134
|
+
_update_processing()
|
|
1135
|
+
|
|
1136
|
+
|
|
1137
|
+
# Per-frame monitor: dispatches to the step runner during a window, otherwise
|
|
1138
|
+
# holds the freeze against game-code writes.
|
|
1139
|
+
func _game_time_process(delta: float) -> void:
|
|
1140
|
+
if _step_active:
|
|
1141
|
+
_step_process(delta)
|
|
1142
|
+
return
|
|
1143
|
+
if not _frozen:
|
|
1144
|
+
return
|
|
1145
|
+
var tree := get_tree()
|
|
1146
|
+
if not tree.paused:
|
|
1147
|
+
# Game code unpaused under the freeze (a WHEN_PAUSED resume button, an
|
|
1148
|
+
# auto-unpausing cutscene). Record the game layer's new intent and
|
|
1149
|
+
# re-assert — the freeze answers to the agent; the game's wish is
|
|
1150
|
+
# restored on step/thaw. Only unpause flips are observable here: while
|
|
1151
|
+
# frozen, tree.paused is already true.
|
|
1152
|
+
_game_paused = false
|
|
1153
|
+
_freeze_transition_count += 1
|
|
1154
|
+
tree.paused = true
|
|
1155
|
+
|
|
1156
|
+
|
|
1157
|
+
func _physics_process(_delta: float) -> void:
|
|
1158
|
+
if _step_active and not _step_finish_pending and not get_tree().paused:
|
|
1159
|
+
_step_physics_ticks += 1
|
|
1160
|
+
|
|
1161
|
+
|
|
1162
|
+
func _handle_game_time_freeze(_data: Array) -> void:
|
|
1163
|
+
if _step_active:
|
|
1164
|
+
_send_game_time_response("game_time_freeze", {"error": "Step in progress"})
|
|
1165
|
+
return
|
|
1166
|
+
var was_frozen := _frozen
|
|
1167
|
+
_engage_freeze()
|
|
1168
|
+
_send_game_time_response("game_time_freeze", {
|
|
1169
|
+
"frozen": true,
|
|
1170
|
+
"was_frozen": was_frozen,
|
|
1171
|
+
"game_paused": _game_paused,
|
|
1172
|
+
})
|
|
1173
|
+
|
|
1174
|
+
|
|
1175
|
+
func _handle_game_time_thaw(_data: Array) -> void:
|
|
1176
|
+
if _step_active:
|
|
1177
|
+
_send_game_time_response("game_time_thaw", {"error": "Step in progress"})
|
|
1178
|
+
return
|
|
1179
|
+
var was_frozen := _frozen
|
|
1180
|
+
var result: Dictionary = {"frozen": false, "was_frozen": was_frozen}
|
|
1181
|
+
if was_frozen:
|
|
1182
|
+
# Real wall-clock the freeze was held; game time did not advance while frozen.
|
|
1183
|
+
result["frozen_wall_ms"] = Time.get_ticks_msec() - _freeze_started_ticks
|
|
1184
|
+
_frozen = false
|
|
1185
|
+
get_tree().paused = _game_paused
|
|
1186
|
+
_update_processing()
|
|
1187
|
+
result["game_paused"] = _game_paused if was_frozen else get_tree().paused
|
|
1188
|
+
_send_game_time_response("game_time_thaw", result)
|
|
1189
|
+
|
|
1190
|
+
|
|
1191
|
+
func _handle_game_time_status(_data: Array) -> void:
|
|
1192
|
+
var tree := get_tree()
|
|
1193
|
+
var tree_paused: bool = tree.paused if tree else false
|
|
1194
|
+
var result: Dictionary = {
|
|
1195
|
+
"frozen": _frozen,
|
|
1196
|
+
"game_paused": _game_paused if _frozen else tree_paused,
|
|
1197
|
+
"tree_paused": tree_paused,
|
|
1198
|
+
"engine_time_scale": Engine.time_scale,
|
|
1199
|
+
"physics_ticks_per_second": Engine.physics_ticks_per_second,
|
|
1200
|
+
}
|
|
1201
|
+
# `frozen` is the authoritative current state. `launched_frozen` is a historical
|
|
1202
|
+
# fact (this run booted frozen via GODOT_MCP_LAUNCH_FROZEN) and stays true after
|
|
1203
|
+
# thaw, so it must not be read as the present freeze state.
|
|
1204
|
+
if _launched_frozen:
|
|
1205
|
+
result["launched_frozen"] = true
|
|
1206
|
+
if _frozen:
|
|
1207
|
+
# Real wall-clock since freeze engaged, not game time (which is stopped).
|
|
1208
|
+
result["frozen_wall_ms"] = Time.get_ticks_msec() - _freeze_started_ticks
|
|
1209
|
+
result["freeze_transitions"] = _freeze_transition_count
|
|
1210
|
+
if _freeze_transition_count >= FREEZE_CONTESTED_THRESHOLD:
|
|
1211
|
+
# Something (an ALWAYS-mode node?) is repeatedly unpausing under
|
|
1212
|
+
# the freeze. Each re-assert can leak up to one frame; report the
|
|
1213
|
+
# contest rather than pretend the freeze is airtight.
|
|
1214
|
+
result["freeze_contested"] = true
|
|
1215
|
+
if _step_active:
|
|
1216
|
+
result["step_active"] = true
|
|
1217
|
+
_send_game_time_response("game_time_status", result)
|
|
1218
|
+
|
|
1219
|
+
|
|
1220
|
+
func _handle_game_time_step(data: Array) -> void:
|
|
1221
|
+
var params: Dictionary = data[0] if data.size() > 0 and data[0] is Dictionary else {}
|
|
1222
|
+
if _step_active:
|
|
1223
|
+
_send_game_time_response("game_time_step", {"error": "Step already in progress"})
|
|
1224
|
+
return
|
|
1225
|
+
|
|
1226
|
+
var duration_ms: int = int(params.get("duration_ms", 0))
|
|
1227
|
+
var frames: int = int(params.get("frames", 0))
|
|
1228
|
+
if duration_ms <= 0 and frames <= 0:
|
|
1229
|
+
_send_game_time_response("game_time_step", {"error": "step requires duration_ms or frames"})
|
|
1230
|
+
return
|
|
1231
|
+
duration_ms = mini(duration_ms, STEP_MAX_MS)
|
|
1232
|
+
frames = mini(frames, STEP_MAX_FRAMES)
|
|
1233
|
+
|
|
1234
|
+
# Validate and schedule the in-step input timeline (start_ms is game-time
|
|
1235
|
+
# from window start). Inputs must ride inside the step: an event injected
|
|
1236
|
+
# while frozen lands on a frame gameplay never processes, so its
|
|
1237
|
+
# is_action_just_pressed edge would be silently missed.
|
|
1238
|
+
var inputs: Array = params.get("inputs", [])
|
|
1239
|
+
var events: Array = []
|
|
1240
|
+
for input in inputs:
|
|
1241
|
+
var action_name: String = input.get("action_name", "")
|
|
1242
|
+
if action_name.is_empty():
|
|
1243
|
+
continue
|
|
1244
|
+
if not InputMap.has_action(action_name):
|
|
1245
|
+
_send_game_time_response("game_time_step", {"error": "Unknown action: %s" % action_name})
|
|
1246
|
+
return
|
|
1247
|
+
var start_ms: int = int(input.get("start_ms", 0))
|
|
1248
|
+
var dur: int = int(input.get("duration_ms", 0))
|
|
1249
|
+
events.append({"time": start_ms, "action": action_name, "is_press": true})
|
|
1250
|
+
events.append({"time": start_ms + dur, "action": action_name, "is_press": false})
|
|
1251
|
+
events.sort_custom(func(a: Dictionary, b: Dictionary) -> bool:
|
|
1252
|
+
return a.time < b.time
|
|
1253
|
+
)
|
|
1254
|
+
|
|
1255
|
+
# Step from a running game is allowed — it freezes first, so "advance
|
|
1256
|
+
# 500ms then wait for me" is a single atomic call.
|
|
1257
|
+
_engage_freeze()
|
|
1258
|
+
|
|
1259
|
+
_step_target_ms = float(duration_ms)
|
|
1260
|
+
_step_target_frames = frames
|
|
1261
|
+
_step_elapsed_ms = 0.0
|
|
1262
|
+
_step_gameplay_ms = 0.0
|
|
1263
|
+
_step_frames = 0
|
|
1264
|
+
_step_physics_ticks = 0
|
|
1265
|
+
_step_events = events
|
|
1266
|
+
_step_events_fired = 0
|
|
1267
|
+
_step_transitions = []
|
|
1268
|
+
_step_needs_settle = false
|
|
1269
|
+
_step_finish_pending = false
|
|
1270
|
+
_step_wall_exceeded = false
|
|
1271
|
+
_step_wall_start = Time.get_ticks_msec()
|
|
1272
|
+
_step_active = true
|
|
1273
|
+
|
|
1274
|
+
# Open the window: restore the game layer's own pause wish for the
|
|
1275
|
+
# duration. If the game's menu is holding it paused, the window still
|
|
1276
|
+
# elapses (and reports gameplay_ms ~0) — never deadlock waiting for
|
|
1277
|
+
# gameplay time that cannot come.
|
|
1278
|
+
var tree := get_tree()
|
|
1279
|
+
tree.paused = _game_paused
|
|
1280
|
+
_step_last_tree_paused = tree.paused
|
|
1281
|
+
set_physics_process(true)
|
|
1282
|
+
_update_processing()
|
|
1283
|
+
|
|
1284
|
+
|
|
1285
|
+
func _step_process(delta: float) -> void:
|
|
1286
|
+
var tree := get_tree()
|
|
1287
|
+
|
|
1288
|
+
# The bridge processes before the scene, so a frame is counted here BEFORE
|
|
1289
|
+
# gameplay runs it. Ending the window therefore always defers one frame:
|
|
1290
|
+
# pausing in the same _process call would steal the frame just counted.
|
|
1291
|
+
if _step_finish_pending:
|
|
1292
|
+
_finish_step()
|
|
1293
|
+
return
|
|
1294
|
+
|
|
1295
|
+
# Game-layer pause flips during the window are the game's own doing (a
|
|
1296
|
+
# stepped input opened the menu, an auto-pausing cutscene). Track intent
|
|
1297
|
+
# and report; never fight it mid-window.
|
|
1298
|
+
if tree.paused != _step_last_tree_paused:
|
|
1299
|
+
_step_last_tree_paused = tree.paused
|
|
1300
|
+
_game_paused = tree.paused
|
|
1301
|
+
if _step_transitions.size() < STEP_MAX_TRANSITIONS:
|
|
1302
|
+
_step_transitions.append({"at_ms": roundi(_step_elapsed_ms), "paused": tree.paused})
|
|
1303
|
+
|
|
1304
|
+
_step_frames += 1
|
|
1305
|
+
_step_elapsed_ms += delta * 1000.0
|
|
1306
|
+
if not tree.paused:
|
|
1307
|
+
_step_gameplay_ms += delta * 1000.0
|
|
1308
|
+
|
|
1309
|
+
while _step_events.size() > 0 and _step_events[0].time <= _step_elapsed_ms:
|
|
1310
|
+
var ev: Dictionary = _step_events.pop_front()
|
|
1311
|
+
var input_event := InputEventAction.new()
|
|
1312
|
+
input_event.action = ev.action
|
|
1313
|
+
input_event.pressed = ev.is_press
|
|
1314
|
+
input_event.strength = 1.0 if ev.is_press else 0.0
|
|
1315
|
+
Input.parse_input_event(input_event)
|
|
1316
|
+
_step_events_fired += 1
|
|
1317
|
+
_step_needs_settle = true
|
|
1318
|
+
if ev.is_press:
|
|
1319
|
+
_held_actions[ev.action] = true
|
|
1320
|
+
else:
|
|
1321
|
+
_held_actions.erase(ev.action)
|
|
1322
|
+
|
|
1323
|
+
var done := false
|
|
1324
|
+
if _step_target_frames > 0:
|
|
1325
|
+
done = _step_frames >= _step_target_frames
|
|
1326
|
+
else:
|
|
1327
|
+
done = _step_elapsed_ms >= _step_target_ms
|
|
1328
|
+
if Time.get_ticks_msec() - _step_wall_start > STEP_WALL_BUDGET_MS:
|
|
1329
|
+
# Slow-mo, Engine.time_scale = 0, or a pause-held window can starve
|
|
1330
|
+
# the game-time clock; the wall budget guarantees the call returns
|
|
1331
|
+
# (partial, honestly reported) before the editor relay gives up.
|
|
1332
|
+
_step_wall_exceeded = true
|
|
1333
|
+
done = true
|
|
1334
|
+
|
|
1335
|
+
if done:
|
|
1336
|
+
if _step_needs_settle:
|
|
1337
|
+
# Injected events flush at the top of the NEXT frame; gameplay
|
|
1338
|
+
# needs that frame unpaused or the final just_pressed edge is
|
|
1339
|
+
# lost. Run exactly one settle frame, then finish.
|
|
1340
|
+
_step_needs_settle = false
|
|
1341
|
+
else:
|
|
1342
|
+
_step_finish_pending = true
|
|
1343
|
+
|
|
1344
|
+
|
|
1345
|
+
func _finish_step() -> void:
|
|
1346
|
+
# Releases are guaranteed cleanup, never queued steps: no holds survive
|
|
1347
|
+
# across the freeze boundary (cross-step holds are a deliberate non-goal).
|
|
1348
|
+
var forced := _held_actions.size()
|
|
1349
|
+
_release_held_actions()
|
|
1350
|
+
var dropped := _step_events.size()
|
|
1351
|
+
_step_events.clear()
|
|
1352
|
+
|
|
1353
|
+
get_tree().paused = true # the freeze layer re-engages
|
|
1354
|
+
_step_last_tree_paused = true
|
|
1355
|
+
_step_active = false
|
|
1356
|
+
_step_finish_pending = false
|
|
1357
|
+
set_physics_process(false)
|
|
1358
|
+
_update_processing()
|
|
1359
|
+
|
|
1360
|
+
var result: Dictionary = {
|
|
1361
|
+
"completed": true,
|
|
1362
|
+
"frozen": true,
|
|
1363
|
+
"elapsed_ms": roundi(_step_elapsed_ms),
|
|
1364
|
+
"gameplay_ms": roundi(_step_gameplay_ms),
|
|
1365
|
+
"frames": _step_frames,
|
|
1366
|
+
"physics_ticks": _step_physics_ticks,
|
|
1367
|
+
"game_paused": _game_paused,
|
|
1368
|
+
}
|
|
1369
|
+
if _step_events_fired > 0:
|
|
1370
|
+
result["events_fired"] = _step_events_fired
|
|
1371
|
+
if forced > 0:
|
|
1372
|
+
result["forced_releases"] = forced
|
|
1373
|
+
if dropped > 0:
|
|
1374
|
+
result["events_dropped"] = dropped
|
|
1375
|
+
if not _step_transitions.is_empty():
|
|
1376
|
+
result["pause_transitions"] = _step_transitions
|
|
1377
|
+
if _step_wall_exceeded:
|
|
1378
|
+
result["wall_budget_exceeded"] = true
|
|
1379
|
+
_send_game_time_response("game_time_step", result)
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
uid://dj1awl7wmpf65
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
uid://1fhae7bg8bgf
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
uid://bn5y5te1ys8sa
|
package/addon/plugin.cfg
CHANGED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
uid://ddy5vjisb0we
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
uid://ccs8jj6mvw2i7
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
uid://dcdsm34jvcwgv
|
|
@@ -53,6 +53,14 @@ describe('editor tool', () => {
|
|
|
53
53
|
.toBe('Running scene: res://test.tscn');
|
|
54
54
|
expect(await editor.execute({ action: 'stop' }, ctx)).toBe('Stopped project');
|
|
55
55
|
});
|
|
56
|
+
it('passes frozen through to run_project and says so', async () => {
|
|
57
|
+
mock.mockResponse({});
|
|
58
|
+
const ctx = createToolContext(mock);
|
|
59
|
+
const result = await editor.execute({ action: 'run', frozen: true }, ctx);
|
|
60
|
+
expect(result).toContain('frozen from frame 0');
|
|
61
|
+
expect(mock.calls[0].command).toBe('run_project');
|
|
62
|
+
expect(mock.calls[0].params.frozen).toBe(true);
|
|
63
|
+
});
|
|
56
64
|
});
|
|
57
65
|
describe('get_log_messages', () => {
|
|
58
66
|
it('returns "No log messages" when empty', async () => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"editor.test.js","sourceRoot":"","sources":["../../../src/__tests__/tools/editor.test.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"editor.test.js","sourceRoot":"","sources":["../../../src/__tests__/tools/editor.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"game-time.test.d.ts","sourceRoot":"","sources":["../../../src/__tests__/tools/game-time.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
import { describe, it, expect, beforeEach } from 'vitest';
|
|
2
|
+
import { createMockGodot, createToolContext, structuredOf } from '../helpers/mock-godot.js';
|
|
3
|
+
import { gameTime } from '../../tools/game-time.js';
|
|
4
|
+
describe('game_time tool', () => {
|
|
5
|
+
let mock;
|
|
6
|
+
beforeEach(() => {
|
|
7
|
+
mock = createMockGodot();
|
|
8
|
+
});
|
|
9
|
+
describe('schema validation', () => {
|
|
10
|
+
it('step requires exactly one of duration_ms or frames', () => {
|
|
11
|
+
expect(gameTime.schema.safeParse({ action: 'step' }).success).toBe(false);
|
|
12
|
+
expect(gameTime.schema.safeParse({ action: 'step', duration_ms: 500, frames: 10 }).success).toBe(false);
|
|
13
|
+
expect(gameTime.schema.safeParse({ action: 'step', duration_ms: 500 }).success).toBe(true);
|
|
14
|
+
expect(gameTime.schema.safeParse({ action: 'step', frames: 1 }).success).toBe(true);
|
|
15
|
+
});
|
|
16
|
+
it('step enforces the bridge-side caps', () => {
|
|
17
|
+
expect(gameTime.schema.safeParse({ action: 'step', duration_ms: 20000 }).success).toBe(true);
|
|
18
|
+
expect(gameTime.schema.safeParse({ action: 'step', duration_ms: 20001 }).success).toBe(false);
|
|
19
|
+
expect(gameTime.schema.safeParse({ action: 'step', frames: 1200 }).success).toBe(true);
|
|
20
|
+
expect(gameTime.schema.safeParse({ action: 'step', frames: 1201 }).success).toBe(false);
|
|
21
|
+
expect(gameTime.schema.safeParse({ action: 'step', duration_ms: 0 }).success).toBe(false);
|
|
22
|
+
});
|
|
23
|
+
it('step accepts an input timeline', () => {
|
|
24
|
+
expect(gameTime.schema.safeParse({
|
|
25
|
+
action: 'step',
|
|
26
|
+
duration_ms: 500,
|
|
27
|
+
inputs: [{ action_name: 'fire', start_ms: 100, duration_ms: 200 }],
|
|
28
|
+
}).success).toBe(true);
|
|
29
|
+
});
|
|
30
|
+
it('freeze, thaw, and status take no extra arguments', () => {
|
|
31
|
+
expect(gameTime.schema.safeParse({ action: 'freeze' }).success).toBe(true);
|
|
32
|
+
expect(gameTime.schema.safeParse({ action: 'thaw' }).success).toBe(true);
|
|
33
|
+
expect(gameTime.schema.safeParse({ action: 'status' }).success).toBe(true);
|
|
34
|
+
});
|
|
35
|
+
});
|
|
36
|
+
describe('freeze', () => {
|
|
37
|
+
it('reports a fresh freeze', async () => {
|
|
38
|
+
mock.mockResponse({ frozen: true, was_frozen: false, game_paused: false });
|
|
39
|
+
const ctx = createToolContext(mock);
|
|
40
|
+
const result = await gameTime.execute({ action: 'freeze' }, ctx);
|
|
41
|
+
expect(result).toContain('Frozen');
|
|
42
|
+
expect(result).not.toContain('already frozen');
|
|
43
|
+
expect(mock.calls[0].command).toBe('game_time_freeze');
|
|
44
|
+
});
|
|
45
|
+
it('notes idempotent re-freeze and an open pause menu', async () => {
|
|
46
|
+
mock.mockResponse({ frozen: true, was_frozen: true, game_paused: true });
|
|
47
|
+
const ctx = createToolContext(mock);
|
|
48
|
+
const result = await gameTime.execute({ action: 'freeze' }, ctx);
|
|
49
|
+
expect(result).toContain('already frozen');
|
|
50
|
+
expect(result).toContain('pause menu is open');
|
|
51
|
+
});
|
|
52
|
+
});
|
|
53
|
+
describe('step', () => {
|
|
54
|
+
it('forwards window parameters and inputs, returns structured result', async () => {
|
|
55
|
+
mock.mockResponse({
|
|
56
|
+
completed: true,
|
|
57
|
+
frozen: true,
|
|
58
|
+
elapsed_ms: 517,
|
|
59
|
+
gameplay_ms: 517,
|
|
60
|
+
frames: 31,
|
|
61
|
+
physics_ticks: 31,
|
|
62
|
+
game_paused: false,
|
|
63
|
+
events_fired: 2,
|
|
64
|
+
});
|
|
65
|
+
const ctx = createToolContext(mock);
|
|
66
|
+
const result = await gameTime.execute({
|
|
67
|
+
action: 'step',
|
|
68
|
+
duration_ms: 500,
|
|
69
|
+
inputs: [{ action_name: 'fire', start_ms: 0, duration_ms: 100 }],
|
|
70
|
+
}, ctx);
|
|
71
|
+
expect(mock.calls[0].command).toBe('game_time_step');
|
|
72
|
+
expect(mock.calls[0].params.duration_ms).toBe(500);
|
|
73
|
+
expect(mock.calls[0].params.inputs).toHaveLength(1);
|
|
74
|
+
const data = structuredOf(result);
|
|
75
|
+
expect(data.elapsed_ms).toBe(517);
|
|
76
|
+
expect(data.events_fired).toBe(2);
|
|
77
|
+
});
|
|
78
|
+
it('surfaces pause transitions from the game layer', async () => {
|
|
79
|
+
mock.mockResponse({
|
|
80
|
+
completed: true,
|
|
81
|
+
frozen: true,
|
|
82
|
+
elapsed_ms: 500,
|
|
83
|
+
gameplay_ms: 120,
|
|
84
|
+
frames: 30,
|
|
85
|
+
physics_ticks: 7,
|
|
86
|
+
game_paused: true,
|
|
87
|
+
pause_transitions: [{ at_ms: 120, paused: true }],
|
|
88
|
+
});
|
|
89
|
+
const ctx = createToolContext(mock);
|
|
90
|
+
const result = await gameTime.execute({ action: 'step', duration_ms: 500 }, ctx);
|
|
91
|
+
const data = structuredOf(result);
|
|
92
|
+
expect(data.pause_transitions).toHaveLength(1);
|
|
93
|
+
expect(data.game_paused).toBe(true);
|
|
94
|
+
expect(data.gameplay_ms).toBe(120);
|
|
95
|
+
});
|
|
96
|
+
});
|
|
97
|
+
describe('thaw', () => {
|
|
98
|
+
it('reports the frozen duration', async () => {
|
|
99
|
+
mock.mockResponse({ frozen: false, was_frozen: true, game_paused: false, frozen_wall_ms: 42000 });
|
|
100
|
+
const ctx = createToolContext(mock);
|
|
101
|
+
const result = await gameTime.execute({ action: 'thaw' }, ctx);
|
|
102
|
+
expect(result).toContain('42000ms');
|
|
103
|
+
expect(mock.calls[0].command).toBe('game_time_thaw');
|
|
104
|
+
});
|
|
105
|
+
it('is idempotent when not frozen', async () => {
|
|
106
|
+
mock.mockResponse({ frozen: false, was_frozen: false, game_paused: false });
|
|
107
|
+
const ctx = createToolContext(mock);
|
|
108
|
+
const result = await gameTime.execute({ action: 'thaw' }, ctx);
|
|
109
|
+
expect(result).toContain('Was not frozen');
|
|
110
|
+
});
|
|
111
|
+
});
|
|
112
|
+
describe('status', () => {
|
|
113
|
+
it('returns the structured freeze state', async () => {
|
|
114
|
+
mock.mockResponse({
|
|
115
|
+
frozen: true,
|
|
116
|
+
game_paused: false,
|
|
117
|
+
tree_paused: true,
|
|
118
|
+
engine_time_scale: 1.0,
|
|
119
|
+
physics_ticks_per_second: 60,
|
|
120
|
+
frozen_wall_ms: 12345,
|
|
121
|
+
freeze_transitions: 0,
|
|
122
|
+
launched_frozen: true,
|
|
123
|
+
});
|
|
124
|
+
const ctx = createToolContext(mock);
|
|
125
|
+
const result = await gameTime.execute({ action: 'status' }, ctx);
|
|
126
|
+
expect(mock.calls[0].command).toBe('game_time_status');
|
|
127
|
+
const data = structuredOf(result);
|
|
128
|
+
expect(data.frozen).toBe(true);
|
|
129
|
+
expect(data.frozen_wall_ms).toBe(12345);
|
|
130
|
+
expect(data.launched_frozen).toBe(true);
|
|
131
|
+
});
|
|
132
|
+
});
|
|
133
|
+
});
|
|
134
|
+
//# sourceMappingURL=game-time.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"game-time.test.js","sourceRoot":"","sources":["../../../src/__tests__/tools/game-time.test.ts"],"names":[],"mappings":"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"}
|
package/dist/tools/editor.d.ts
CHANGED
|
@@ -10,6 +10,7 @@ export declare const editor: import("../core/types.js").ToolDefinition<z.ZodDisc
|
|
|
10
10
|
}, z.core.$strip>, z.ZodObject<{
|
|
11
11
|
action: z.ZodLiteral<"run">;
|
|
12
12
|
scene_path: z.ZodOptional<z.ZodString>;
|
|
13
|
+
frozen: z.ZodOptional<z.ZodBoolean>;
|
|
13
14
|
}, z.core.$strip>, z.ZodObject<{
|
|
14
15
|
action: z.ZodLiteral<"stop">;
|
|
15
16
|
}, z.core.$strip>, z.ZodObject<{
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"editor.d.ts","sourceRoot":"","sources":["../../src/tools/editor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB,OAAO,KAAK,EAAE,iBAAiB,EAAyB,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"editor.d.ts","sourceRoot":"","sources":["../../src/tools/editor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB,OAAO,KAAK,EAAE,iBAAiB,EAAyB,MAAM,kBAAkB,CAAC;AAsGjF,eAAO,MAAM,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8BA0GjB,CAAC;AAEH,eAAO,MAAM,WAAW,EAAe,iBAAiB,EAAE,CAAC"}
|
package/dist/tools/editor.js
CHANGED
|
@@ -19,6 +19,10 @@ const EditorSchema = z
|
|
|
19
19
|
z.object({
|
|
20
20
|
action: z.literal('run').describe('Run the project'),
|
|
21
21
|
scene_path: z.string().optional().describe('Scene to run (optional, defaults to main scene)'),
|
|
22
|
+
frozen: z
|
|
23
|
+
.boolean()
|
|
24
|
+
.optional()
|
|
25
|
+
.describe('Launch with game time frozen from frame 0 (gameplay never starts racing your latency). Use godot_game_time step/thaw to advance.'),
|
|
22
26
|
}),
|
|
23
27
|
z.object({ action: z.literal('stop').describe('Stop the running project') }),
|
|
24
28
|
z.object({
|
|
@@ -72,8 +76,11 @@ export const editor = defineTool({
|
|
|
72
76
|
return `Selected node: ${args.node_path}`;
|
|
73
77
|
}
|
|
74
78
|
case 'run': {
|
|
75
|
-
await godot.sendCommand('run_project', { scene_path: args.scene_path });
|
|
76
|
-
|
|
79
|
+
await godot.sendCommand('run_project', { scene_path: args.scene_path, frozen: args.frozen });
|
|
80
|
+
const target = args.scene_path ? `scene: ${args.scene_path}` : 'project';
|
|
81
|
+
return args.frozen
|
|
82
|
+
? `Running ${target} frozen from frame 0 — use godot_game_time step/thaw to advance`
|
|
83
|
+
: `Running ${target}`;
|
|
77
84
|
}
|
|
78
85
|
case 'stop': {
|
|
79
86
|
await godot.sendCommand('stop_project');
|
package/dist/tools/editor.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"editor.js","sourceRoot":"","sources":["../../src/tools/editor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AACpD,OAAO,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AA0BnD,SAAS,cAAc,CAAC,MAAc;IACpC,OAAO;QACL,IAAI,EAAE,OAAO;QACb,IAAI,EAAE,MAAM;QACZ,QAAQ,EAAE,YAAY;KACvB,CAAC;AACJ,CAAC;AAED,MAAM,YAAY,GAAG,CAAC;KACnB,kBAAkB,CAAC,QAAQ,EAAE;IAC5B,CAAC,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC,QAAQ,CAAC,wEAAwE,CAAC,EAAE,CAAC;IAC/H,CAAC,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,OAAO,CAAC,eAAe,CAAC,CAAC,QAAQ,CAAC,kCAAkC,CAAC,EAAE,CAAC;IAC7F,CAAC,CAAC,MAAM,CAAC;QACP,MAAM,EAAE,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,QAAQ,CAAC,6BAA6B,CAAC;QACnE,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,wBAAwB,CAAC;KACzD,CAAC;IACF,CAAC,CAAC,MAAM,CAAC;QACP,MAAM,EAAE,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,QAAQ,CAAC,iBAAiB,CAAC;QACpD,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,iDAAiD,CAAC;
|
|
1
|
+
{"version":3,"file":"editor.js","sourceRoot":"","sources":["../../src/tools/editor.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import type { AnyToolDefinition } from '../core/types.js';
|
|
3
|
+
export declare const gameTime: import("../core/types.js").ToolDefinition<z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
4
|
+
action: z.ZodLiteral<"freeze">;
|
|
5
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
6
|
+
action: z.ZodLiteral<"step">;
|
|
7
|
+
duration_ms: z.ZodOptional<z.ZodNumber>;
|
|
8
|
+
frames: z.ZodOptional<z.ZodNumber>;
|
|
9
|
+
inputs: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
10
|
+
action_name: z.ZodString;
|
|
11
|
+
start_ms: z.ZodDefault<z.ZodOptional<z.ZodNumber>>;
|
|
12
|
+
duration_ms: z.ZodDefault<z.ZodOptional<z.ZodNumber>>;
|
|
13
|
+
}, z.core.$strip>>>;
|
|
14
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
15
|
+
action: z.ZodLiteral<"thaw">;
|
|
16
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
17
|
+
action: z.ZodLiteral<"status">;
|
|
18
|
+
}, z.core.$strip>], "action">>;
|
|
19
|
+
export declare const gameTimeTools: AnyToolDefinition[];
|
|
20
|
+
//# sourceMappingURL=game-time.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"game-time.d.ts","sourceRoot":"","sources":["../../src/tools/game-time.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAIxB,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAuE1D,eAAO,MAAM,QAAQ;;;;;;;;;;;;;;;8BAgDnB,CAAC;AAEH,eAAO,MAAM,aAAa,EAAiB,iBAAiB,EAAE,CAAC"}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { defineTool } from '../core/define-tool.js';
|
|
3
|
+
import { structured } from '../core/structured.js';
|
|
4
|
+
import { InputActionSchema } from './input.js';
|
|
5
|
+
// Bridge-side step caps (see mcp_game_bridge.gd). The editor relay times out
|
|
6
|
+
// at 28s and the server command timeout is 30s, so a step request must stay
|
|
7
|
+
// well inside both.
|
|
8
|
+
const STEP_MAX_MS = 20000;
|
|
9
|
+
const STEP_MAX_FRAMES = 1200;
|
|
10
|
+
const GameTimeSchema = z
|
|
11
|
+
.discriminatedUnion('action', [
|
|
12
|
+
z.object({
|
|
13
|
+
action: z
|
|
14
|
+
.literal('freeze')
|
|
15
|
+
.describe('Pause the game under agent control. All observation tools (screenshots, runtime state, find_nodes) keep working while frozen — take as long as you need.'),
|
|
16
|
+
}),
|
|
17
|
+
z.object({
|
|
18
|
+
action: z
|
|
19
|
+
.literal('step')
|
|
20
|
+
.describe('Advance a bounded slice of game time, then re-freeze. Freezes first if the game is running, so step is always a safe first call.'),
|
|
21
|
+
duration_ms: z
|
|
22
|
+
.number()
|
|
23
|
+
.int()
|
|
24
|
+
.min(1)
|
|
25
|
+
.max(STEP_MAX_MS)
|
|
26
|
+
.optional()
|
|
27
|
+
.describe(`Game time to advance in milliseconds (max ${STEP_MAX_MS}; loop steps for longer). Scaled by Engine.time_scale like normal play.`),
|
|
28
|
+
frames: z
|
|
29
|
+
.number()
|
|
30
|
+
.int()
|
|
31
|
+
.min(1)
|
|
32
|
+
.max(STEP_MAX_FRAMES)
|
|
33
|
+
.optional()
|
|
34
|
+
.describe(`Frames to advance instead of a duration (max ${STEP_MAX_FRAMES}). frames: 1 is a single-frame advance.`),
|
|
35
|
+
inputs: z
|
|
36
|
+
.array(InputActionSchema)
|
|
37
|
+
.optional()
|
|
38
|
+
.describe('Input timeline executed inside the window; start_ms is game time from window start. Inputs must ride inside the step — events injected while frozen miss their is_action_just_pressed edge. Holds are always released by window end.'),
|
|
39
|
+
}),
|
|
40
|
+
z.object({
|
|
41
|
+
action: z
|
|
42
|
+
.literal('thaw')
|
|
43
|
+
.describe('Resume real-time play, restoring the game\'s own pause state (an open pause menu stays open).'),
|
|
44
|
+
}),
|
|
45
|
+
z.object({
|
|
46
|
+
action: z
|
|
47
|
+
.literal('status')
|
|
48
|
+
.describe('Report the freeze state: `frozen` is authoritative for the current state; `frozen_wall_ms` is real wall-clock held (not game time); `launched_frozen` is a historical flag (this run booted frozen) and stays true after thaw. Also reports the game\'s own pause intent, time scale, and whether game code is contesting the freeze.'),
|
|
49
|
+
}),
|
|
50
|
+
])
|
|
51
|
+
// Constraint a discriminated union can't express on its own, so it lives here:
|
|
52
|
+
.refine((data) => (data.action === 'step' ? (data.duration_ms !== undefined) !== (data.frames !== undefined) : true), {
|
|
53
|
+
message: 'step requires exactly one of duration_ms or frames',
|
|
54
|
+
});
|
|
55
|
+
export const gameTime = defineTool({
|
|
56
|
+
name: 'godot_game_time',
|
|
57
|
+
annotations: { title: 'Game Time Control', readOnlyHint: false, destructiveHint: false, openWorldHint: false },
|
|
58
|
+
description: 'Make game time answer to your clock instead of racing ahead between tool calls: freeze the running game, observe it at leisure (screenshots and state digests work while frozen), then step forward a bounded slice of game time with inputs riding inside the window. The game\'s own pause menu is layered correctly: freezing over it, stepping under it, and thawing back to it all preserve the game\'s pause intent.',
|
|
59
|
+
schema: GameTimeSchema,
|
|
60
|
+
async execute(args, { godot }) {
|
|
61
|
+
switch (args.action) {
|
|
62
|
+
case 'freeze': {
|
|
63
|
+
const result = await godot.sendCommand('game_time_freeze');
|
|
64
|
+
const note = result.was_frozen ? ' (was already frozen)' : '';
|
|
65
|
+
const paused = result.game_paused ? ' Game\'s own pause menu is open; step will not advance gameplay until it is dismissed.' : '';
|
|
66
|
+
return `Frozen${note}. Game time is stopped; observe freely, then step or thaw.${paused}`;
|
|
67
|
+
}
|
|
68
|
+
case 'step': {
|
|
69
|
+
const result = await godot.sendCommand('game_time_step', {
|
|
70
|
+
duration_ms: args.duration_ms,
|
|
71
|
+
frames: args.frames,
|
|
72
|
+
inputs: args.inputs,
|
|
73
|
+
});
|
|
74
|
+
return structured(result);
|
|
75
|
+
}
|
|
76
|
+
case 'thaw': {
|
|
77
|
+
const result = await godot.sendCommand('game_time_thaw');
|
|
78
|
+
if (!result.was_frozen) {
|
|
79
|
+
return 'Was not frozen; game continues in real time.';
|
|
80
|
+
}
|
|
81
|
+
const pausedNote = result.game_paused ? ' (game\'s own pause menu still open)' : '';
|
|
82
|
+
return `Thawed after ${result.frozen_wall_ms}ms (wall-clock) frozen. Real-time play resumed${pausedNote}.`;
|
|
83
|
+
}
|
|
84
|
+
case 'status': {
|
|
85
|
+
const result = await godot.sendCommand('game_time_status');
|
|
86
|
+
return structured(result);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
},
|
|
90
|
+
});
|
|
91
|
+
export const gameTimeTools = [gameTime];
|
|
92
|
+
//# sourceMappingURL=game-time.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"game-time.js","sourceRoot":"","sources":["../../src/tools/game-time.ts"],"names":[],"mappings":"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"}
|
package/dist/tools/index.d.ts
CHANGED
|
@@ -11,4 +11,5 @@ export { docsTools } from './docs.js';
|
|
|
11
11
|
export { inputTools } from './input.js';
|
|
12
12
|
export { profilerTools } from './profiler.js';
|
|
13
13
|
export { runtimeStateTools } from './runtime-state.js';
|
|
14
|
+
export { gameTimeTools } from './game-time.js';
|
|
14
15
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/tools/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/tools/index.ts"],"names":[],"mappings":"AAeA,wBAAgB,gBAAgB,IAAI,IAAI,CAcvC;AAED,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AACxC,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AACtC,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC1C,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAC5C,OAAO,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAChD,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAC5C,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAC9C,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAC5C,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AACtC,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AACxC,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAC9C,OAAO,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AACvD,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC"}
|
package/dist/tools/index.js
CHANGED
|
@@ -11,6 +11,7 @@ import { docsTools } from './docs.js';
|
|
|
11
11
|
import { inputTools } from './input.js';
|
|
12
12
|
import { profilerTools } from './profiler.js';
|
|
13
13
|
import { runtimeStateTools } from './runtime-state.js';
|
|
14
|
+
import { gameTimeTools } from './game-time.js';
|
|
14
15
|
export function registerAllTools() {
|
|
15
16
|
registry.registerTools(sceneTools);
|
|
16
17
|
registry.registerTools(nodeTools);
|
|
@@ -24,6 +25,7 @@ export function registerAllTools() {
|
|
|
24
25
|
registry.registerTools(inputTools);
|
|
25
26
|
registry.registerTools(profilerTools);
|
|
26
27
|
registry.registerTools(runtimeStateTools);
|
|
28
|
+
registry.registerTools(gameTimeTools);
|
|
27
29
|
}
|
|
28
30
|
export { sceneTools } from './scene.js';
|
|
29
31
|
export { nodeTools } from './node.js';
|
|
@@ -37,4 +39,5 @@ export { docsTools } from './docs.js';
|
|
|
37
39
|
export { inputTools } from './input.js';
|
|
38
40
|
export { profilerTools } from './profiler.js';
|
|
39
41
|
export { runtimeStateTools } from './runtime-state.js';
|
|
42
|
+
export { gameTimeTools } from './game-time.js';
|
|
40
43
|
//# sourceMappingURL=index.js.map
|
package/dist/tools/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/tools/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAC/C,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AACxC,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AACtC,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC1C,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAC5C,OAAO,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAChD,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAC5C,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAC9C,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAC5C,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AACtC,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AACxC,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAC9C,OAAO,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/tools/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAC/C,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AACxC,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AACtC,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC1C,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAC5C,OAAO,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAChD,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAC5C,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAC9C,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAC5C,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AACtC,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AACxC,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAC9C,OAAO,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AACvD,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAE/C,MAAM,UAAU,gBAAgB;IAC9B,QAAQ,CAAC,aAAa,CAAC,UAAU,CAAC,CAAC;IACnC,QAAQ,CAAC,aAAa,CAAC,SAAS,CAAC,CAAC;IAClC,QAAQ,CAAC,aAAa,CAAC,WAAW,CAAC,CAAC;IACpC,QAAQ,CAAC,aAAa,CAAC,YAAY,CAAC,CAAC;IACrC,QAAQ,CAAC,aAAa,CAAC,cAAc,CAAC,CAAC;IACvC,QAAQ,CAAC,aAAa,CAAC,YAAY,CAAC,CAAC;IACrC,QAAQ,CAAC,aAAa,CAAC,aAAa,CAAC,CAAC;IACtC,QAAQ,CAAC,aAAa,CAAC,YAAY,CAAC,CAAC;IACrC,QAAQ,CAAC,aAAa,CAAC,SAAS,CAAC,CAAC;IAClC,QAAQ,CAAC,aAAa,CAAC,UAAU,CAAC,CAAC;IACnC,QAAQ,CAAC,aAAa,CAAC,aAAa,CAAC,CAAC;IACtC,QAAQ,CAAC,aAAa,CAAC,iBAAiB,CAAC,CAAC;IAC1C,QAAQ,CAAC,aAAa,CAAC,aAAa,CAAC,CAAC;AACxC,CAAC;AAED,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AACxC,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AACtC,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC1C,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAC5C,OAAO,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAChD,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAC5C,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAC9C,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAC5C,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AACtC,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AACxC,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAC9C,OAAO,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AACvD,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC"}
|
package/dist/tools/input.d.ts
CHANGED
|
@@ -1,5 +1,10 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
2
|
import type { AnyToolDefinition } from '../core/types.js';
|
|
3
|
+
export declare const InputActionSchema: z.ZodObject<{
|
|
4
|
+
action_name: z.ZodString;
|
|
5
|
+
start_ms: z.ZodDefault<z.ZodOptional<z.ZodNumber>>;
|
|
6
|
+
duration_ms: z.ZodDefault<z.ZodOptional<z.ZodNumber>>;
|
|
7
|
+
}, z.core.$strip>;
|
|
3
8
|
export declare const input: import("../core/types.js").ToolDefinition<z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
4
9
|
action: z.ZodLiteral<"get_map">;
|
|
5
10
|
}, z.core.$strip>, z.ZodObject<{
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"input.d.ts","sourceRoot":"","sources":["../../src/tools/input.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"input.d.ts","sourceRoot":"","sources":["../../src/tools/input.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAE1D,eAAO,MAAM,iBAAiB;;;;iBAI5B,CAAC;AAyCH,eAAO,MAAM,KAAK;;;;;;;;;;;;;;8BA6DhB,CAAC;AAEH,eAAO,MAAM,UAAU,EAAc,iBAAiB,EAAE,CAAC"}
|
package/dist/tools/input.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
2
|
import { defineTool } from '../core/define-tool.js';
|
|
3
|
-
const InputActionSchema = z.object({
|
|
3
|
+
export const InputActionSchema = z.object({
|
|
4
4
|
action_name: z.string().describe('The input action name from the project Input Map'),
|
|
5
5
|
start_ms: z.number().int().min(0).optional().default(0).describe('When to start the input (milliseconds from sequence start)'),
|
|
6
6
|
duration_ms: z.number().int().min(0).optional().default(0).describe('How long to hold the input (0 = instant tap)'),
|
package/dist/tools/input.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"input.js","sourceRoot":"","sources":["../../src/tools/input.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AAGpD,MAAM,iBAAiB,GAAG,CAAC,CAAC,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"input.js","sourceRoot":"","sources":["../../src/tools/input.ts"],"names":[],"mappings":"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"}
|