godot: External script editing does not trigger reload of running game


Bugsquad edit: This bug has been confirmed several times already. No need to confirm it further.


Windows 10 Godot 3.0 v3.0.alpha.custom_build.af97525

Issue description: Editing script file in external file editor with Sync Script Changes does not trigger reload

Steps to reproduce:

  • Create a scene and attach a new script file which prints something every second
  • Enable Sync Script Changes
  • Change message from normal editor - Godot reloads
  • Open external editor (for example VSCode) and edit it.
  • The file reloads in the Godot file editor if opened, but doesn’t reload the project

About this issue

  • Original URL
  • State: closed
  • Created 7 years ago
  • Reactions: 80
  • Comments: 29 (10 by maintainers)

Commits related to this issue

Most upvoted comments

Just to have a really clear (and simple) repro: (v3.2.2.stable.official on macOS 10.15.5)

  • Create new project
  • Create new node
  • Create new GD script (FileSystem -> right click -> New Script)
  • Attach script to node
  • Double click script to edit in Godot
  • Make any edit to the script file with any external editor (I added a comment)
image

Configuring an external editor is not required to repro.

The error doesn’t seem to cause any other issues.

@ohnoimdead Please don’t bump issues without contributing significant new information. Use the 👍 reaction button on the first post instead.

We’ve had enough confirmations of this bug (more than 5 recently), no need to keep bumping the issue.

I am getting: core/resource.cpp:79 - Condition ' exists ' is true. and ERROR: Another resource is loaded from path: res://scripts/entity.gd (possible cyclic resource inclusion) At: core/resource.cpp:79

as soon as I save a script file with VSCode and focus Godot while the game is running. The running game is not updated with the changed script.

VSCode is properly setup as external editor in Godot’s settings.

so… is live coding with external editors not usable since 2017 (if it ever has been working) and it has been pushed to milestone 4.0? that hampers my motivations to use Godot severely as live coding is a major selling point for me.

Happy birthday bug! You are now three years old.

I’m having the same bug. All I have to do is just save the file in the external editor and then click on the godot editor and the error shows up. I’ve cloned the repo and debugged the code. I see it go into resource.cpp:78

It seems to protect resources from being loaded from two different threads I think? Shouldn’t there be an exception to the rule for when the external_editor option is true? Or some way to detect if the resource is loaded from the external editor and not give an error?

I wanted to see if I could fix it but I don’t know the code well enough and I’d probably just introduce another bug.

This is me trying multiple scripts. (plugin, root node script, child node script)

ERROR: Another resource is loaded from path: res://addons/Aseprite/aseprite.gd (possible cyclic resource inclusion) At: core\resource.cpp:78 ERROR: Another resource is loaded from path: res://main.gd (possible cyclic resource inclusion) At: core\resource.cpp:78 running cmdline: “C:/Program Files/Microsoft VS Code/Code.exe” “C:/Users/Willy/repos/memory-puzzle” “–goto” “C:/Users/Willy/repos/memory-puzzle/Node2D.gd:0:0”

ERROR: Another resource is loaded from path: res://Node2D.gd (possible cyclic resource inclusion) At: core\resource.cpp:78 MUST RELOAD? 0 ERROR: Another resource is loaded from path: res://Node2D.gd (possible cyclic resource inclusion) At: core\resource.cpp:78 ERROR: Resource::set_path: Condition ’ exists ’ is true. At: core\resource.cpp:78

Using Godot 3.0.2.stable under linux.

I have the same issue with this error printed:

  • Another resource is loaded from path: res://scripts/bamboo.gd (possible cyclic resource inclusion)
  • modules/gdscript/gdscript.cpp:560 - Condition ’ !p_keep_state && has_instances ’ is true. returned: ERR_ALREADY_IN_USE

After tinkering more and reading how the wire protocol worked, I was able to make it work.

I wrote the following ruby script:

require 'socket'
require 'listen'

cmd = "\x20\x00\x00\x00\x13\x00\x00\x00\x01\x00\x00\x00\x04\x00\x00\x00\x0e\x00\x00\x00reload_scripts\x00\x00"

server = TCPServer.open 6008

puts "Listening on port 6008"

loop do
  client = server.accept
  listener = Listen.to('scripts') do |modified|
    if modified
      puts "File modified: #{modified}"
      client.write(cmd)
    end
  end
  listener.start
  # Read content to avoid using kernel memory
  while line = client.recv(1024)
    next if line.length < 10
    # Debug data packets
    #puts "###"
    #puts line.each_byte.map { |b| b.to_s(16).rjust(2, '0') }.join(':')
  end
end

(You need the listen gem and ruby >2.2)

Then start the scene with:

godot -d --remote-debug 127.0.0.1:6008 

It will not work with the editor, it will run the game by itself. But it fill my use case which is to be able to see the changes made to a script generating procedural geometry immediately. Of course it works with the built in editor, but I can’t use anything else than vim for coding:)

My situation is slightly different, I’m making an importer that translates one language to GDScript directly. Any time I click Reimport, I get the error message: Another resource is loaded from path 'res://<file>' (possible cyclic resource inclusion).

I create a GDScript object and modify its source code, and then use ResourceSaver to save it to a gd file. Even with a script.reload() the error remains

Tested with Godot v3.2.2 beta4

As of build 3fb9c776ff53fbdd656b648e05101eaeaa39c908, whenever I return to the editor after external script editing I usually get the error below, and have to change something and resave the script for it to reload successfully.

ERROR: Another resource is loaded from path 'res://main.gd' (possible cyclic resource inclusion).
   At: core\resource.cpp:82

The stack looks like:

godot.windows.tools.64.exe!_err_print_error(const char * p_function, const char * p_file, int p_line, const char * p_error, const char * p_message, ErrorHandlerType p_type) Line 83	C++
godot.windows.tools.64.exe!_err_print_error(const char * p_function, const char * p_file, int p_line, const char * p_error, const String & p_message, ErrorHandlerType p_type) Line 99	C++
godot.windows.tools.64.exe!Resource::set_path(const String & p_path, bool p_take_over) Line 82	C++
godot.windows.tools.64.exe!ResourceFormatLoaderGDScript::load(const String & p_path, const String & p_original_path, Error * r_error) Line 2290	C++
godot.windows.tools.64.exe!ResourceLoader::_load(const String & p_path, const String & p_original_path, const String & p_type_hint, bool p_no_cache, Error * r_error) Line 270	C++
godot.windows.tools.64.exe!ResourceLoader::load(const String & p_path, const String & p_type_hint, bool p_no_cache, Error * r_error) Line 401	C++
godot.windows.tools.64.exe!ScriptEditor::_reload_scripts() Line 791	C++
godot.windows.tools.64.exe!ScriptEditor::_test_script_times_on_disk(Ref<Resource> p_for_script) Line 889	C++
godot.windows.tools.64.exe!ScriptEditor::edit(const Ref<Resource> & p_resource, int p_line, int p_col, bool p_grab_focus) Line 2202	C++
godot.windows.tools.64.exe!ScriptEditor::edit(const Ref<Resource> & p_resource, bool p_grab_focus) Line 428	C++
godot.windows.tools.64.exe!ScriptEditorPlugin::edit(Object * p_object) Line 3518	C++
godot.windows.tools.64.exe!EditorNode::_edit_current() Line 1928	C++
godot.windows.tools.64.exe!EditorNode::push_item(Object * p_object, const String & p_property, bool p_inspector_only) Line 1709	C++
godot.windows.tools.64.exe!InspectorDock::_resource_selected(const Ref<Resource> & p_res, const String & p_property) Line 287	C++
godot.windows.tools.64.exe!InspectorDock::edit_resource(const Ref<Resource> & p_resource) Line 371	C++
godot.windows.tools.64.exe!EditorNode::edit_resource(const Ref<Resource> & p_resource) Line 703	C++
godot.windows.tools.64.exe!SceneTreeDock::_script_open_request(const Ref<Script> & p_script) Line 1200	C++
godot.windows.tools.64.exe!MethodBind1<SceneTreeDock,Ref<Script> const &>::call(Object * p_object, const Variant * * p_args, int p_arg_count, Variant::CallError & r_error) Line 867	C++
godot.windows.tools.64.exe!Object::call(const StringName & p_method, const Variant * * p_args, int p_argcount, Variant::CallError & r_error) Line 922	C++
godot.windows.tools.64.exe!Object::emit_signal(const StringName & p_name, const Variant * * p_args, int p_argcount) Line 1249	C++
godot.windows.tools.64.exe!Object::emit_signal(const StringName & p_name, const Variant & p_arg1, const Variant & p_arg2, const Variant & p_arg3, const Variant & p_arg4, const Variant & p_arg5) Line 1307	C++
godot.windows.tools.64.exe!SceneTreeEditor::_cell_button_pressed(Object * p_item, int p_column, int p_id) Line 76	C++
godot.windows.tools.64.exe!MethodBind3<SceneTreeEditor,Object *,int,int>::call(Object * p_object, const Variant * * p_args, int p_arg_count, Variant::CallError & r_error) Line 2403	C++
godot.windows.tools.64.exe!Object::call(const StringName & p_method, const Variant * * p_args, int p_argcount, Variant::CallError & r_error) Line 922	C++
godot.windows.tools.64.exe!Object::emit_signal(const StringName & p_name, const Variant * * p_args, int p_argcount) Line 1249	C++
godot.windows.tools.64.exe!Object::emit_signal(const StringName & p_name, const Variant & p_arg1, const Variant & p_arg2, const Variant & p_arg3, const Variant & p_arg4, const Variant & p_arg5) Line 1307	C++
godot.windows.tools.64.exe!Tree::_gui_input(Ref<InputEvent> p_event) Line 2622	C++
godot.windows.tools.64.exe!MethodBind1<Tree,Ref<InputEvent>>::call(Object * p_object, const Variant * * p_args, int p_arg_count, Variant::CallError & r_error) Line 867	C++
godot.windows.tools.64.exe!Object::call_multilevel(const StringName & p_method, const Variant * * p_args, int p_argcount) Line 764	C++
godot.windows.tools.64.exe!Object::call_multilevel(const StringName & p_name, const Variant & p_arg1, const Variant & p_arg2, const Variant & p_arg3, const Variant & p_arg4, const Variant & p_arg5) Line 865	C++
godot.windows.tools.64.exe!Viewport::_gui_call_input(Control * p_control, const Ref<InputEvent> & p_input) Line 1669	C++
godot.windows.tools.64.exe!Viewport::_gui_input_event(Ref<InputEvent> p_event) Line 2049	C++
godot.windows.tools.64.exe!Viewport::input(const Ref<InputEvent> & p_event) Line 2828	C++
godot.windows.tools.64.exe!Viewport::_vp_input(const Ref<InputEvent> & p_ev) Line 1446	C++
godot.windows.tools.64.exe!MethodBind1<Viewport,Ref<InputEvent> const &>::call(Object * p_object, const Variant * * p_args, int p_arg_count, Variant::CallError & r_error) Line 867	C++
godot.windows.tools.64.exe!Object::call(const StringName & p_method, const Variant * * p_args, int p_argcount, Variant::CallError & r_error) Line 922	C++
godot.windows.tools.64.exe!Object::call(const StringName & p_name, const Variant & p_arg1, const Variant & p_arg2, const Variant & p_arg3, const Variant & p_arg4, const Variant & p_arg5) Line 848	C++
godot.windows.tools.64.exe!SceneTree::call_group_flags(unsigned int p_call_flags, const StringName & p_group, const StringName & p_function, const Variant & p_arg1, const Variant & p_arg2, const Variant & p_arg3, const Variant & p_arg4, const Variant & p_arg5) Line 275	C++
godot.windows.tools.64.exe!SceneTree::input_event(const Ref<InputEvent> & p_event) Line 431	C++
godot.windows.tools.64.exe!InputDefault::_parse_input_event_impl(const Ref<InputEvent> & p_event, bool p_is_emulated) Line 442	C++
godot.windows.tools.64.exe!InputDefault::parse_input_event(const Ref<InputEvent> & p_event) Line 260	C++
godot.windows.tools.64.exe!InputDefault::flush_accumulated_events() Line 679	C++
godot.windows.tools.64.exe!OS_Windows::process_events() Line 2578	C++
godot.windows.tools.64.exe!OS_Windows::run() Line 3280	C++
godot.windows.tools.64.exe!widechar_main(int argc, wchar_t * * argv) Line 162	C++
godot.windows.tools.64.exe!_main() Line 184	C++
godot.windows.tools.64.exe!main(int _argc, char * * _argv) Line 196	C++


Related to: Rybadour/NodeConnectorGodot#3

this plugin modifies the script and the user needs to close/open godot to see changes

This as well, not sure if the linked issue is exactly related but I do have to tell users to unfocus the editor window in order for the modifications to the script to show up. Can we add a mechanism to allow plugins to invalidate the cache that represents an edited script?

I also have update issues with godot and vscode but on macos 10.15 and godot 3.2. Everything is proper installed. script syncing is enabled and I get the error message Another resource is loaded from path 'res://levels/wall_tool.gd' (possible cyclic resource inclusion). script only updates by restarting godot or randomly