godotengine / godotengine/godot
Moving Files via Script Does Not Update Resources in Scene
- Dominant language
- C++
- Stars
- 117k
- Forks
- 26.8k
- PR merge metrics
- PR metrics pending
Description
### Tested versions
Tested in v4.3.stable.mono.official [77dcf97d8]
### System information
Windows 11, RX 6600, Intel 10400 CPU
### Issue description
## TL;DR: `DirAccess.Rename()` and `DirAccess.RenameAbsolute()` do not update resource paths when scene.tscn files are moved from A to B
Moving files via code will break the resources in scenes. Have a look at "Steps to Reproduce" and the attached MRP below for more info.
> [!IMPORTANT]
> Manually dragging the resource files directly in the Godot editor will auto update the resource paths with no issues.
Although manually clicking "Fix Dependencies" on the scene when opening it will fix all resource paths *(that is after moving the files via script)*
Perhaps something like `.FixDependencies()` should be called whenever `directory.Rename(...)` is executed. Maybe this could also be done if a developer does something like `System.File.IO.Move(...)` instead of using the Godot methods.
I have tried searching for a similar already submitted issue to this and I could not find anything.
## Why do I need this?
Look at the "Caution" note I put in the README of this repo [here](https://github.com/ValksGodotTools/Template?tab=readme-ov-file#four-double-click-on-the-main-scene-in-resscenesyour_scenetscn) *(if the link isn't taking you to the correct spot in the readme because of all the media that loads in, the caution note I'm referring to is under "Setup Guide" right after Step 4)*
### Steps to reproduce
1. Create a new scene "sub" inside the main scene "main" with a script attached inside "sub"
2. Create a new script in `res://Scripts` and attach this script to be inside the "sub" scene
3. Create a new script in "main" that moves the "sub" script from `res://Scripts` to `res://`
```cs
using DirAccess dir = DirAccess.Open(ProjectSettings.GlobalizePath("res://"));
// this "Player.cs" script is the "sub" script I'm referring to
Error error = dir.Rename("Scripts/Player.cs", "Player.cs");
if (error != Error.Ok)
GD.Print(error); // no error will be printed because it will move the file with no issues
```
5. Run the game
6. Click on the console output so it updates or close the game to update console output and you will notice errors similar to this

> [!NOTE]
> Please use the MRP attached below instead of trying to re-create this scenario I've described above.
### Minimal reproduction project (MRP)
1. Press `F5` to run the game and `res://Scripts/Player.cs` will be moved to `res://Player.cs`
2. Close the game and the following errors will appear in console

https://github.com/user-attachments/assets/8576de8f-962a-4fee-9022-c0134b3ad0f0
> [!NOTE]
> MRP: [filemovetest.zip](https://github.com/user-attachments/files/16715888/filemovetest.zip) *(requires v4.3.stable.mono.official [77dcf97d8] to run)*
Contributor guide
Research direction
Start with the attached MRP and trace the DirAccess.Rename() and DirAccess.RenameAbsolute() paths, then compare them with the editor's Fix Dependencies behavior. Reproduce the move from res://Scripts/Player.cs to res://Player.cs and verify that scene resource references remain valid without manual repair.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- cpp, csharp
- Domain
- game-dev
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100