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

Created on 3 Sep 2017  路  27Comments  路  Source: godotengine/godot


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
bug confirmed high priority core

Most helpful comment

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.

All 27 comments

Do you see ERROR: set_path: Condition ' exists ' is true. in the console? (ERROR: set_path: Another resource is loaded from path if building after 96b205d)

cc @reduz
I'm almost sure the error above is the cause, since I get it every time I focus the editor after editing the script (be it GDScript or C#) from an external editor. In the case of GDScript the error is produced in the call to set_path() from ResourceFormatLoaderGDScript::load().

@neikeq can confirm that I get an error message using a recent custom build fb25fe0 (The Bullet physics fork from AndreaCatania)

ERROR: Resource::set_path: Condition ' exists ' is true.
   At: core\resource.cpp:78

Looks like this was fixed recently, no idea by whom. Can you confirm it?

@neikeq could you or anyone confirm?

It doesn't happen for me anymore. Not sure about @DjPale

I can reproduce this once again... It also happens when renaming a script that is attached to the root node (didn't test with its children) of an instanced scene.

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

As this is a blocker for me, I'm trying to workaround the issue by sending "reload_scripts" to the remote debugger, I tried to marshall the command to make it decodable by https://github.com/godotengine/godot/blob/34c988cfa92f19c232b65990704816ba1c7d2622/core/io/marshalls.cpp#L87 but it is not working so I must be doing something wrong.

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:)

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

I think the source for this bug is here: https://github.com/godotengine/godot/blob/master/editor/plugins/script_text_editor.cpp#L579

The variable script is the one that is already cached and use the path for the script. Then, we try to reload it but it fails because the one we want to update is already cached. I tried removing script from ResourceCache before loading the edited script (rel_script) and then re-placing script in the cache (and removing rel_script from it) but this does not seem to apply script modifications as wanted.

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.

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

Related to: https://github.com/Rybadour/NodeConnectorGodot/issues/3

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

godot plz fix!

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?

can't live edit on Atom and VS code as well on Mac os(10.14.6) in godot 2.21, 2.2, get this error all the time:
Another resource is loaded from path 'res://src/Player/Player.gd' (possible cyclic resource inclusion).

Same! Bump! VSCode

 Another resource is loaded from path 'res://src/Controllers/World/Items/ItemDb.gd' (possible cyclic resource inclusion).
 Another resource is loaded from path 'res://src/Controllers/GUI/DeathScreen/DeathScreen.gd' (possible cyclic resource inclusion).

Im using linux debian, and i have the same problem, i never use it so i just realized that it works on the builtin editor. i believe my error is the same as all linux users:

* Another resource is loaded from path 'res://[my script path]' (possible cyclic resource inclusion).
* modules/gdscript/gdscript.cpp:553 - Condition "!p_keep_state && has_instances" is true. Returned: ERR_ALREADY_IN_USE

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

Sorry to bump this as well, but given that my workflow is a bit
different, I'd like to understand how this is intended to work.

Is the intent that, if I run my game from the editor, modifying scripts
in an external editor like VSCode should trigger a reload in the game
itself?

If so, is there any way to get this functionality outside of running in
the editor? I.e. a command line flag of some sort?

Thanks.

@ndarilek you can turn off external editor, then open any script in godot code editor, then turn on external VC code editor. When you make any changes in VSc, open godot code editor and save file. That will update code in live.
Anyway, there is another problem (maybe it's only me) I can't add signal node using Atom as external code editor, meanwhile in VSc it's work.

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++


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

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.

Happy birthday bug! You are now three years old.

@ohnoimdead Please don't bump issues without contributing significant new information. Use the :+1: reaction button on the first post instead.

Was this page helpful?
1 / 5 - 1 ratings