File permissions from the OS can get propagated with transfers. Also, I don’t know anything about any machine the problem occurs on. The only specification I know is from your video: you’re on Windows 11.
It still could be a filename issue. What is the full project path on your system? Does the project name or file structure (outside of Godot, so not the res:// but absolute path) contain any special characters, or simply any non camelCase/PascalCase characters?
Windows 10 and Windows 11 are the systems used across the machines.
The path on my current machine is: D:\Others\Godot Projects\GLO-Project
Removing the space in Godot Projectsdidn’t seem to change anything.
If this helps, here’s system info:
OS Name Microsoft Windows 11 Home
Version 10.0.26200 Build 26200
Other OS Description Not Available
OS Manufacturer Microsoft Corporation
System Name DESKTOP-SPMMDH0
System Manufacturer ASUSTeK COMPUTER INC.
System Model ROG Strix G531GT_G531GT
System Type x64-based PC
System SKU
Processor Intel(R) Core(TM) i7-9750H CPU @ 2.60GHz, 2592 Mhz, 6 Core(s), 12 Logical Processor(s)
BIOS Version/Date American Megatrends Inc. G531GT.308, 01/02/2021
SMBIOS Version 3.2
Embedded Controller Version 255.255
BIOS Mode UEFI
BaseBoard Manufacturer ASUSTeK COMPUTER INC.
BaseBoard Product G531GT
BaseBoard Version 1.0
Platform Role Mobile
Secure Boot State On
PCR7 Configuration Elevation Required to View
Windows Directory C:\WINDOWS
System Directory C:\WINDOWS\system32
Boot Device \Device\HarddiskVolume2
Locale United Kingdom
Hardware Abstraction Layer Version = "10.0.26100.1"
Time Zone W. Europe Summer Time
Installed Physical Memory (RAM) 32.0 GB
Total Physical Memory 31.9 GB
Available Physical Memory 20.0 GB
Total Virtual Memory 33.9 GB
Available Virtual Memory 21.6 GB
Page File Space 2.00 GB
Page File C:\pagefile.sys
Kernel DMA Protection Off
Virtualisation-based security Not enabled
App Control for Business policy Enforced
App Control for Business user mode policy Off
Automatic Device Encryption Support Elevation Required to View
Hyper-V - VM Monitor Mode Extensions Yes
Hyper-V - Second Level Address Translation Extensions Yes
Hyper-V - Virtualisation Enabled in Firmware Yes
Hyper-V - Data Execution Protection Yes
snake_case for folders, no caps, it can lead to problem in Windows. I’d avoid spaces also, even though they’ve been accepted on Windows for a long time, there is plenty of code out there that doesn’t
TLDR, I believe I found the problem and have a fix for you.
It’ll help you when you export your game to Windows and Mac. Without that you’d have a whole other issue of images and other assets not showing up in your exported builds.
Your issue is honestly really weird.
That’s good.
This shouldn’t be happening.
What happens if you right-click on it and use the Move or Duplicate option to move it instead? Same issue? (It shouldn’t matter, but like I said this is weird.)
This is erroring out in a really odd place. It’s the function that returns OK when loading a GDScript file. But if it doesn’t return OK, it should go onto the error section of the function.
Then trying to load res://scripts/stats/resources/puzzle_stats.gd even though it failed to open it.
This error is potentially more helpful, because it’s happening in the multi-threading code. Which begs the question: Are you making multithreading calls anywhere in your code?
Then it’s trying to load user://puzzle_data.tres and having a problem parsing line 62 of that file. Because (I think) it couldn’t find the Resource file where it was expecting to find it at res://scripts/stats/resources/puzzle_stats.gd
This is erroring out on the first line of the class definition. Again, not what you would expect. The error should be coming from lower in the file.
AFAICT, exact same problem as before, not sure why it’s happening twice.
This time the loading is failing for user://puzzle_data.tres
If you look at the code throwing these errors, they’re all in really odd places - with the exception of the multi-threading error. I do think it’s important that you’re getting three separate errors, all from the same file. All connected to this line in puzzle_data.gd:
var _resource = load(_save_file_path)
All related to failing to load this file: res://scripts/stats/resources/puzzle_stats.gd. So somewhere in your code is a hardcoded reference to that file, and based on the cyclic reference error, it’s probably in res://scripts/player_data/puzzle.gd
So what’s that script look like?
It’s also possible that this is a data mismatch that is being confused by naming conventions that are too close, and lack of strict typing. So let’s fix that and see if it solves your problem.
PuzzleDataResource
First, let’s take a look at puzzle_data_resource.gd. Naming conventions are important. This is ends with “Resource” because there’s a naming conflict - namely puzzle_data.gd. But in the comments I see the # Player data comment ahead of all of the variables in the file. So it’s the data about the puzzle, but it’s also data about the player. So it is the player’s puzzle data. Lets name it that: PlayerPuzzleData. This also gets rid of the use of Resource in a class name, which is an example of RAS syndrome.
player_puzzle_data.gd
class_name PlayerPuzzleData extends Resource
# Player data
@export var puzzle_name: String
@export var difficulty: Puzzle.PuzzleDifficulty
@export var completed: bool
@export var completion_time: int
This is a more descriptive name which helps with code readability and namespace conflicts. You’ll notice I’ve also adopted the Godot 4 convention of putting class_name and extends on the same line. (You were following the Godot 3 convention.)
You can do a replace across all your files for this name using Ctrl+Shift+R in the Godot IDE. It’s not quite the same as a Refactor option, but it should be good enough. Once you tell it what you want to replace, it’ll give you an option to select all the instances it found and de-select the ones you don’t want changing.
PuzzleStatistics
Just a few changes here. The main thing though, is naming consistency. You use stats and statistics interchangeably. And then in your code you have this line a lot:
puzzle_statistics.stats
RAS syndrome rearing its ugly head again. PuzzleStatistics is just a container of all the PlayerPuzzleData for your puzzles. We can’t name it Puzzle, because you already have a class with that name. You probably also have a Player class. But what if we call it PlayerData? Then if you want to store something about the player that needs to be stored on disk, it can be put in here too. It also solves the RAS syndrome issue.
player_data.gd
class_name PlayerData extends Resource
@export var statistics: Array[PuzzlePlayerData]
Now we have no naming conflicts. There’s nothing preventing us from naming this class, which may help in the future. Also, since the name of the save file isn’t going to change, we can make it a constant. Then, we can add static typing - which I hope will help us solve your problem. This is because I think what’s happening is you’re loading the wrong thing into the a variable - expecting one type and loading another. Either way, it’ll make your code cleaner and easier to read.
Multi-Select
Just a side-note, when I was editing your file, to replace the _save_file_path variable, I double-clicked on it, and then pressed Ctrl+D until all the options were selected.
class_name PuzzleData extends Node
const SAVE_FILE_PATH = "user://puzzle_data.tres"
var player_data: PlayerData
func _ready() -> void:
# Load data
player_data = load_data()
func save_data(data: PlayerData):
player_data.stats.push_back(data)
ResourceSaver.save(player_data, SAVE_FILE_PATH)
func load_data():
# Load save file, if it exists
if ResourceLoader.exists(SAVE_FILE_PATH):
var _resource = load(SAVE_FILE_PATH)
return _resource
var _new_resource = PlayerData.new()
return _new_resource
func count_completed(result: bool) -> int:
var _amount: int = 0
for i in player_data.stats.size():
if player_data.stats[i].completed == result:
_amount += 1
return _amount
func count_difficulties(difficulty: Puzzle.PuzzleDifficulty):
var _amount: int = 0
for i in player_data.stats.size():
if player_data.stats[i].difficulty == difficulty:
_amount += 1
return _amount
This script should solve your problem.
TLDR
Of course, you can ignore all my other advice, and just change the one line:
Now technically the path should change whenever you move the resource (test_resource.gd in this case) to another folder. This doesn’t always work. Especially if the file is saved in user:// as opposed to res://. And to make it weirder, if the variable storing a path is originally starting with res:// the issue does not appear locally, but if the save file path variable starts with user://, even when it’s changed on _ready(), the issue will still appear.
Here’s the visualization:
Solutions:
Never move the scripts saved with ResourceSaver / Resource Loader. I marked the folder with resource scripts red so it’s more obvious that this is no-touch folder.
Every time you move your resource script, you need to delete the save file, or manually change the reference path in .tres file.
Store your save file in res:// instead of user://. Change it to user:// for build. The original path needs to be res:// and then changed, not the other way around. Remember to put your save file in .gitignore if you work with other developers unless you want them to have your save file. Keep in mind that this is not intended way to save resources originally. They are normally supposed to stay in user://, but saving it this way prevents the issue for me.
I haven’t found a way how to do it, but if you’re able to compare [ext_resource path= ]from your .tres save file to the current path of your script, you could try to correct it automatically when the game starts.
Make sure to always test things like this on build, since the save files will behave differently.
About cyclic resource inclusion
So this error:
ERROR: Another resource is loaded from path 'res://folder_1/new_script.gd' (possible cyclic resource inclusion).
On 4.6.2. stable, this happens EVERY TIME you move any .gd file anywhere. Even if you make an empty project with only one .gd file and move it from folder1 to folder2. So unless you can fix Godot itself, this is a fully ignoreable issue.
Why did I try to solve it then? I assumed that this was causing the load_data() errors, because both were related to moving .gd files. But nope. This one comes with Godot itself. Seems like no one noticed it because you start ignoring it automatically after a while.
As @dragonforge-dev mentioned, this was a mix of XY issues (where the issue is something else than originally described). In this comment, I compiled all of the issues I’ve had and solutions together with explanations to them. I hope this will serve someone in the future.
I would like to thank everyone who endured my whining on this thread and still kept trying to help. This taught me a lot about Godot and version control.
I will mark this as a solution but feel free to add something that can give even more information.
I think this deserves a caveat, which is - if you want other developers to have access to your save files. Otherwise, I don’t understand why you wouldn’t always save in User, because then those files are never under version control and never cause you issues.
This only becomes an issue if you’re saving Resource files through scripts to res://and you are moving your directory structure around.
Adding scripts to a versioned plugin would also prevent this behavior.
It’s a text file. Just read it and change it.
This is not reproducible for me. I literally moved dozens of .gd files in my project yesterday with no issues. If this were that common of a problem, you wouldn’t have been the first person to report it.
Solutions
Your code still says you are trying to load a different Resource than you are saving.
Good point. Added it. The reason why it’s not in user:// is because the issue is more likely to happen and the save file becomes more tedious to delete.
Not for me. The error happens the most often when it’s saved in user:// actually.
This is weird because I was able to reproduce it on every machine and different systems: Windows 10, Windows 11, MacOS. Even on a laptop from developer who never worked on our project, and the error was present on his own projects. Even when I created empty new project the error happened.
Make sure it’s on 4.6.2. The error appears in Output and not Debugger.
Yes, but it also means that updating your project won’t wipe out whatever you were testing. And it’s easy enough to create a shortcut to the save folder and just clean it out.
This is new info. Also, it highlights what we might be doing differently. You cannot see the user:// folder in the Godot editor, so I do not see how you can move files into or out of it inside the Godot IDE.
I made a brand new project yesterday in 4.6.2. I moved a bunch of things around. This was my Output window when I loaded the project:
This is exactly it! It doesn’t happen when you run the project but every time you move anything by drag & drop, you get this output message. It doesn’t break anything as far as I’m aware but it’s still weird that everyone gets an error just by moving a file.
This is what I was trying to solve for a while until I realized that everyone has it. I thought that was causing the initial resource error. I wanted to include this in the solution so no one else is as confused as I am as to why this appears.