Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

C# scripts get reset/cleared/reverted by godot in certain circumstances #50163

Closed
Flavelius opened this issue Jul 4, 2021 · 37 comments · Fixed by #82113
Closed

C# scripts get reset/cleared/reverted by godot in certain circumstances #50163

Flavelius opened this issue Jul 4, 2021 · 37 comments · Fixed by #82113

Comments

@Flavelius
Copy link
Contributor

Flavelius commented Jul 4, 2021


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


Godot version

3.3.2.stable.mono.official

System information

Windows 10

Issue description

As the title says, sometimes, godot resets/reverts/clears c# script file contents for reasons unknown.
It's hard to pinpoint exactly where or why it happened (not the first time i experienced this), but i recorded for a while and tried to reproduce it and 'luckily' caught it 2 times in a row - See video:

GodotTrashingScripts.mp4

Here it seems to have been triggered by opening the project, using the 'Build' option, then doing a 'Save All' (ctrl-s).
In my case rider (IDE) then reloaded the changed file from disk, so i reverted it (undo) to reclaim my missing script content (but it's not related to rider as i can see the content vanishing even from other editors as well).

Steps to reproduce

Not sure, in my case here 3 specific files seemed affected but no other script. These are used in resources and are toolscripts, maybe that matters somehow, but others that are also used in resources didn't seem to be affected. And i found no steps to reliably trigger it, but it happens somewhat frequently.
I'll try a bit more to see if i can find a reliable MRP

Minimal reproduction project

No response

@Carbone13
Copy link

Confirming that it is also happening on my projects, I use the same godot version.
I also have no idea what triggers it :(

@Flavelius
Copy link
Contributor Author

After testing a bit further, the SourceCode property of the script resource in question becomes empty when this issue arises. So it seems the editor is actually persisting this empty SourceCode property into the file, while it shouldn't.

@Calinou
Copy link
Member

Calinou commented Jul 4, 2021

Can you reproduce this in previous Godot versions such as 3.2.3?

@Flavelius
Copy link
Contributor Author

Yes (3.2.3), it seems to happen quite frequently when building, then saving all.

@nongvantinh
Copy link
Contributor

It happens with you when moving files between folders. And do the deletes files.

@Flavelius
Copy link
Contributor Author

Still an issue in 3.3.4

@cgbeutler
Copy link

cgbeutler commented Jan 13, 2022

Still occurs in 3.4.2 when moving a script in the editor.
A simple workaround for that is to always work outside the editor when it comes to CSharp stuff. I have only hit this bug twice in my 6 months of work.

Steps to reproduce (I think reliably?? NOTE: Do not deviate! Do not set up any project stuff.)

  1. Start the editor and create a brand new project.
  2. Create folders res://a/ and res://b/
  3. In the editor, create a new CSharp script at res://a/MyScript.cs.
  4. Open res://a/MyScript.cs in VSCode and replace the contents of the class with a comment like // Now you see me
  5. Return to Godot Editor and build.
  6. In the Editor's FileSystem move res://a/MyScript.cs to folder res://b/.
  7. The project should still not have any scenes set. Click Node2D in the Scene dock and then save the scene as Main.tscn
  8. Hit ctrl-s to save all.
  9. Return to the script and see that it's contents are replaced by the default stub.

It has taken a while to find that set of steps. It seems even a little deviation will make it not happen. This bug triggers in the most random ways... fun. Hopefully it's just one bug and not something that needs to be fixed in a dozen different locations.

@MikeSchulze
Copy link

I encounter an equivalent problem by generate c# classes over my GdUnit3 c# TestSuite builder

I do as save by using the script editor to save possible changes before extending an existing script script_editor._menu_option(EDITOR_ACTIONS.FILE_SAVE)

My code works fine to generate the new scrip but the editor shows still the old content.

After comment out the save action the script is "reload" correctly.

So seams to be the save action is not syncronzed and is overlapping with external script changes.

@Iceball457
Copy link

Iceball457 commented Dec 7, 2022

The worst part of this is that it also devours the local history for the file, making it impossible to recover with Undo/Redo in VSCode. Bumping this because I lost 5 hours of C# after moving a cs file from "res://Scenes/" to "res://Scripts" because Scenes is Godot's favorite directory to put new scripts for some reason.
EDIT: It is possible with VSCode to recover your work! Move the file back to where it came from, then open the local history panel and copy/paste to somewhere safe!
image
Pictured: The timeline is in the bottom left, and has access to all edits made at that exact path.

@natefoldan
Copy link

natefoldan commented Mar 14, 2023

This is still happening in 4.0

To clarify, this will still happen even when not moving a file.

@willthehuman
Copy link

This happened to me in 4.0 without even moving the file. I will try to reproduce it.

@nongvantinh
Copy link
Contributor

I believe that it has something to do with "state." because when I close the engine and reopen it in another process, The bug does not happen anymore.

@yosimba2000
Copy link

yosimba2000 commented Jul 24, 2023

Still happening on 4.1.1 .Net version

I don't know how to make the issue START to happen, but once it happens, it is persistent and is 100% predictable.

I am using Win10 22H2, C# with VSCode

Here's how it happens:

  1. Open your Godot project
  2. Double click source code from Godot file explorer.
  3. Make any change to source code and save your source code in the code editor
  4. Go back to Godot, and just Save the project. You don't even need to compile. Just save.
  5. Go back to source code, and find that your change has been undone.
  6. Press Ctrl-Z in source code to bring back your change, then re-save source code.
  7. Go back to Godot and save.
  8. Go back to the code editor and see that your code change stayed. Good!

So here's what I've gathered from this, and I have observed this pattern 100% of the time.

  1. Issue only happens the first time you save the project in any Godot session. A Godot session begins when you open the project file, and ends when you close it.
  2. If Godot settings are set to Save first before Run (should be by default), then this issue occurs the first time you run the project in that Godot session because it saves the project first before running.
  3. Issue does not happen if you make a new Godot project (at least until that project gets infected some how).

EDIT
I found the culprit, but I don't understand why it causes the issue.

  1. Inside the root of your game project folder, navigate to .Godot -> Editor
  2. There are a bunch of config files. Look for files along the lines of {myScriptName}.cs-folding-aLongStringHere.cfg
  3. You may have multiple. You'll have to remove them and test your project to find which file is the culprit. For me, the culprit was called "Game.cs-folding-04c57d74a5067c4e8f7056d760dc179c.cfg"
  4. Below is the full code within the .CFG that is causing the issue. I don't know how to use the code formatter on GitHub.
    "[folding]
    sections_unfolded=PackedStringArray("Resource")
    "
    https://pastebin.com/4gNMrqLe
  5. I have tested, and removing the line where it says "sections_unfolded..." resolves the code undo issue. Alternatively, just delete the whole file and it resolves as well. Alternatively, delete all content inside .Godot (except for the editor-layout.cfg to keep custom editor layouts) and it will resolve as well.

@shayneoneill
Copy link

shayneoneill commented Aug 10, 2023

I'm still getting this in 4.1 w/ Rider. I havent yet divined the cause of it, but its super frusturating.

I havent moved any files. I dont really understand why saving in godot overwrites the file if I havent got it open in Godot. That seems like some sort of cache whackiness.

I'd move to V Studio but I cant get that to work for the mac (It doesnt seem to understand the solution files. Visual Studio code opens fine, but the code completion seems less than desirable, and I rather do enjoy IntelliJs IDEs.

edit: Damn, reading the comments, it isnt an IDE problem but a Godot problem.

Can this bug be prioritized please, its a show stopper and its deeply frusturating to have a bug wipe your work out.

@nongvantinh
Copy link
Contributor

nongvantinh commented Aug 14, 2023

It could be fixed if someone managed to reproduce the steps to trigger this bug. In the past, I have tried to locate it, but it only occurs under certain conditions. Due to this instability, no one knows how it has happened, which is why it hasn't been resolved yet. My personal idea is to add a debug trace that throws an exception and catch it when the function performs the cleanup; then, we can write the stack trace to a file and report it here.

My second idea is to compile the Godot Engine from its source code. While developing our game, we can utilize the debugging features in Visual Studio. This way, if the reset/clear bug occurs, we'll be able to set a breakpoint and begin debugging promptly to capture the issue. As for me, I'm currently busy with a full-time job and studying AI-related topics to incorporate into my game, so I won't be significantly involved in working with Godot, at least until next year. However, you can take the lead.

You can find the script to build the Godot Engine from source, enabling C# support and generating a Visual Studio Project, in this link. To run it, use PowerShell: Shift + right-click and choose Open PowerShell window here. Note that using other shells won't work and will fail at the dotnet nuget add source stage. After placing the script inside the godot folder, execute it using the following command: python3 mono_compile.py. Remember, the purpose of this script is to allow you to quickly execute these commands without having to copy and paste them every time you pull the latest code from upstream. It has only been tested on Windows 10, 64-bit.

@Cutremo
Copy link

Cutremo commented Sep 16, 2023

Can confirm It happens constantly using Rider & Godot .Net 4.1 . It is pretty frustating.

@yosimba2000
Copy link

I have been hit by the bug again, and I was again able to resolve it by clearing out all the files inside the \.godot\editor folder, except for editor_layout.cfg in order to preserve the editor layout.

@shayneoneill
Copy link

There are precisely zero circumstances where the godot engine should EVER be writing to those C# sciptts if you are using an IDE. Start with that.....

@guoboism
Copy link

Happened on Godot 4.1, twice
Code revert to some random old version hours ago
Not sure what cause it exacly, I have renamed the file around to test how godot handles script renaming

I just think that the editor should not have the access or cache the script anyhow.
This bug should be marked top priority:

  • easily destroy hours of work
  • violate the common sense that only myself and git can mess with my code
  • still not fixed and even not replicatable from 3.x

which means that simple opening the project somehow could ruin your code
totally not acceptable and kills the "so far so good" atmosphere for a Unity switcher

@guoboism
Copy link

It could be fixed if someone managed to reproduce the steps to trigger this bug. In the past, I have tried to locate it, but it only occurs under certain conditions. Due to this instability, no one knows how it has happened, which is why it hasn't been resolved yet. My personal idea is to add a debug trace that throws an exception and catch it when the function performs the cleanup; then, we can write the stack trace to a file and report it here.

My second idea is to compile the Godot Engine from its source code. While developing our game, we can utilize the debugging features in Visual Studio. This way, if the reset/clear bug occurs, we'll be able to set a breakpoint and begin debugging promptly to capture the issue. As for me, I'm currently busy with a full-time job and studying AI-related topics to incorporate into my game, so I won't be significantly involved in working with Godot, at least until next year. However, you can take the lead.

You can find the script to build the Godot Engine from source, enabling C# support and generating a Visual Studio Project, in this link. To run it, use PowerShell: Shift + right-click and choose Open PowerShell window here. Note that using other shells won't work and will fail at the dotnet nuget add source stage. After placing the script inside the godot folder, execute it using the following command: python3 mono_compile.py. Remember, the purpose of this script is to allow you to quickly execute these commands without having to copy and paste them every time you pull the latest code from upstream. It has only been tested on Windows 10, 64-bit.

If user dont intent to use the embeded script editor, can you simple provide an option to not allow any writing to code files overall? So that only external applications can make changes to the code files. That can prevent the damage before actually locating the actual cause

@nongvantinh
Copy link
Contributor

Hi @guoboism,

I share your concerns about this bug. However, I'm not certain if randomly adding code to the codebase will resolve this issue since we don't know its root cause. This bug seems to occur when moving a file and for others when they save their work. It appears to be related to resource saving, but the exact cause remains unknown.

My current workaround for this bug is to use Visual Studio Code. When it occurs, I can simply press Ctrl + Shift + P -> Local History: Find Entry to Restore to recover the previously saved data.

Additionally, I have developed a practice of periodically closing and reopening the engine after the editor displays some errors that could potentially cause state changes. This is because I never encounter this bug when the editor is freshly opened. This practice helps ensure that I don't encounter the bug, which could potentially erase all of my work.

@guoboism
Copy link

@nongvantinh
Exactly because it is hard to locate the acual cause of the bug. What I suggested is to allow turning off the godot's access to writing to code files so that user can safely use the other part of the engine, espeically for those who dont use the embeded script editor at all.

Think about this: if there is no embeded script editor, what on earth does Godot need to modify the code files for? An engine should only read, compile and run the code.

@nongvantinh
Copy link
Contributor

Hi @guoboism,

It's actually more than just a C# script; the editor can save various types of files, including Resource files (.res), Scenes (.tscn), Import data (*.import), and more. They all use the same saving mechanism.

When I work with Godot 4.1-stable, I sometimes encounter the editor wiping all the custom data I've set for the *.res files. However, when I close it and reopen it, that data comes back as if nothing has happened.

We need more people to dive into the source code to gain a deeper insight into this issue so that we can identify the possible root cause. Given the current state of the engine, which has recently undergone a massive rewrite, we shouldn't expect too much. The core team members have a lot of work to do, and they don't have enough resources to allocate to this particular problem. Just keep in mind the workaround I provided above, and you won't be held back by this bug.

@nongvantinh
Copy link
Contributor

nongvantinh commented Sep 18, 2023

Hi @guoboism,

After dragging and dropping the C# file:

It performs a lot of operations that include getting a list of files, which will have new paths as a result of this operation. Then it calls the DirAccess:rename method to perform the move operation. After that, it emits a signal for anyone registered to this signal that the file has been moved. Then it _update_resource_paths_after_move, _update_dependencies_after_move, _update_project_settings_after_move, and _update_favorites_list_after_move. I suspect that FileSystemDock::_update_resource_paths_after_move is causing the bug because it works with cached resources, as others have mentioned above.

godot.Debugging.-.Microsoft.Visual.Studio.2023-09-18.17-59-08.mp4

For scene saving (Ctrl + S), it calls EditorNode::_menu_option_confirm, which leads to EditorNode::_save_scene. It saves the default environment, _save_editor_states, and then _save_external_resources, which also works with cached data. However, the bug does not occur, so I cannot say anything about this. But this is how things are actually done.

godot.Debugging.-.Microsoft.Visual.Studio.2023-09-18.18-08-01.mp4

image
fix-50163.zip

The problem with Ctrl + S is that it retrieves data from the cache and saves that data again. This action could potentially override the changes you just made and cause the script to clear, reset, or revert.

@guoboism
Copy link

@nongvantinh
This is really some deep through investigation!
But resource managing ( and this caching mechanism) looks a core part of the engine and deal with everything user created, in which case, modifications should be very cautious.

So what is the plan?
Is this something you can attempt to fix alone? Or it has to be fixed by the core team members?

@nongvantinh
Copy link
Contributor

Hi @guoboism,

It can be fixed by anyone, and they can contribute by creating a pull request for others to benefit from their fix. However, the code I showed above is the way the engine works, and it may not be the root cause. The bug may be elsewhere, where the engine cannot detect that the file has changed and needs to update the cache resource accordingly.

@Flavelius
Copy link
Contributor Author

#43990
I dont know if this issue is still there in 4.0 but this could be one of those wrongly 'valid' cases from the viewpoint of the engine that may cascade into other actions that would otherwise be completely expected and valid.

@evmoius
Copy link

evmoius commented Sep 19, 2023

It's happening with me as well trying to do the first steps tutorials on 4.1.1. Pretty frustrating. I've been enjoying Godot so far, but this is a showstopper. If the editor can just wipe out my code in an external editor (VS) then this makes Godot a no go for serious production work.

Prioritize this bug ASAP. With the amount of attention Godot is getting right now from experienced Unity developers looking for a new path forward, having issues like this is a quick way to kill the goodwill and interest.

@nongvantinh
Copy link
Contributor

It's happening with me as well trying to do the first steps tutorials on 4.1.1. Pretty frustrating. I've been enjoying Godot so far, but this is a showstopper. If the editor can just wipe out my code in an external editor (VS) then this makes Godot a no go for serious production work.

Prioritize this bug ASAP. With the amount of attention Godot is getting right now from experienced Unity developers looking for a new path forward, having issues like this is a quick way to kill the goodwill and interest.

Since you have only followed the first steps of the tutorials, your project is considered a minimal reproduction project. Could you please try to reproduce the step that causes the bug to occur? Because without that, I would have no clue where to look.

@evmoius
Copy link

evmoius commented Sep 20, 2023

It's happening with me as well trying to do the first steps tutorials on 4.1.1. Pretty frustrating. I've been enjoying Godot so far, but this is a showstopper. If the editor can just wipe out my code in an external editor (VS) then this makes Godot a no go for serious production work.
Prioritize this bug ASAP. With the amount of attention Godot is getting right now from experienced Unity developers looking for a new path forward, having issues like this is a quick way to kill the goodwill and interest.

Since you have only followed the first steps of the tutorials, your project is considered a minimal reproduction project. Could you please try to reproduce the step that causes the bug to occur? Because without that, I would have no clue where to look.

Thanks for the quick response! I've been trying to figure out what was causing it but haven't been able to reproduce it reliably. Sometimes it happens after clicking the script icon when VS isn't open. Instead of loading the work you've done, VS will load a script in whatever form you selected when creating it. I've also had it happen after saving via Ctrl + S and then switching window focus back to VS. You can see your code disappear and the script revert to a newly created one.

What I've also noticed is that once it happens during a session, it tends to happen a lot more. I've been working through the 3D tutorial and it's been fine for a few hours now. If I can find a way to reliably reproduce it I'll let you know.

@guoboism
Copy link

Played with a nealy empty project with one script, happened once but can not replicate.
Meanwhile, I found switching the "local to scene" on and off under resource will definitly trigger it. What does setting local is supposed to mean for a C# script here anyway?
image

@nongvantinh
Copy link
Contributor

nongvantinh commented Sep 20, 2023

Hi @guoboism ,

Would you mind taking some more time to describe the details of each step you take? Alternatively, a short video recording of what you do may suffice.

Edit: I can reproduce it now. If the following step is as you described above, then just a thumbs-up is enough.

  1. Create a new project.
  2. Add a Node3D to the scene as the root node.
  3. In the FileSystem, right-click and create a new script. Choose C# as the language, give it whatever name you prefer, and click "Create."
  4. Attach the newly created script to the Node3D mentioned earlier.
  5. Press Ctrl + S to save the scene. Giving it the default name "node_3d.tscn" is sufficient.
  6. Open the "new_script.cs" file you just created in VS Code.
  7. Add a new line to the _Ready() method: GD.Print("Hello World!");
  8. In VS Code, press Ctrl + S to save the script.
  9. In the Editor, double-click on the "new_script.cs" file. In the inspector panel, open the Resource Export group, check "Local to Scene," and then uncheck it again.
  10. While still in the editor, press Ctrl + S. Switch to VS Code and notice that the newly added line in the _Ready method disappears.
  11. Still in VS Code, press Ctrl + Z to revert the changes back, and save the file.

The following is for further analysis of the issue:

Try with external editing:

  1. Fully close the editor (both Godot and its terminal).
  2. Reopen this project and then repeat steps 9 to 10.
  3. Look at the script; the GD.Print("Hello World!"); line should still be there.

Try with Internal editing:

  1. Fully close the editor (both Godot and its terminal).
  2. Reopen this project and go to Editor -> Editor Settings -> Dotnet -> External Editor: Disable.
  3. Double-click on the "new_script.cs." The internal editor will be switched, and you can add this line to the _Ready method: // Here we go!!
  4. File -> Save.
  5. Repeat step 9-10 again. But this time, the newly added code is still there.

I reenabled the external editor, Visual Studio Code, again. However, this time, the internal editor still opened the "new_script.cs." Then I opened the "new_script.cs" in VS Code, made changes, saved it, and came back to repeat steps 9 to 10 while the internal editor was still open. This time, the added code was still there. I'll try to take more time to trace the flow of the code in each scenario to see what happens and try to fix it if it is within my skill.

@AaronTaube
Copy link

I will also try to keep an eye out for the circumstances that caused it on my end, but last night I ran into the exact same issue while going through the 3D tutorial. Happened a couple of times but don't yet know my exact sequence of events, mainly ran into it while trying to see if there was any way to get the signal code to write itself in C# when hooking up a signal to a node.

@nongvantinh
Copy link
Contributor

nongvantinh commented Sep 21, 2023

It is confirmed that the guess I gave above is correct. The cache system does not recognize the changes made outside the editor. Because of this, it overrides the modified C# file with the cached data.
Screenshot (4)

I'll dig deeper into the case to understand why. The Pull Request will come in 2-3 days.

@lightfinesthour
Copy link

lightfinesthour commented Apr 21, 2024

in v4.2.2.stable.official [15073af] :

Godot resets entire script and code file when connecting a node signal to a function in an existing script file.

Why would it even touch the script when i'm connecting it INTO a script that has functions already?

I'm using visual studio code for editing the Godot script files.
This destroyed quite a bit of work, as it removes all code from a file.

I'll change to 4.3 milestone, to see if that helps
/edit: This specific bug is better in 4.3, not the entire script gets wiped when connecting a node signal to a script.
/edit: In v4.3.dev5.official [89f70e9] I found a different [Bug/Feature]

@lightfinesthour
Copy link

In v4.3.dev5.official [89f70e9]

When running the application and changing a script when the app is still running, the script will be reverted back to older state if the app is running into an error.

If i should know better than to edit scripts when the app is running, never mind this comment.
If it sounds like a bug, I can get more specific.

@raulsntos
Copy link
Member

@lightfinesthour The fix for this issue should be included in Godot 4.3 dev 6. Try it out and if you still have issues with scripts reverting their content, please open a new issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.