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

Plugins & Autoloaded scripts breaks project if classes missing from global_script_class_cache.cfg #75388

Closed
TokisanGames opened this issue Mar 27, 2023 · 7 comments · Fixed by #92303

Comments

@TokisanGames
Copy link
Contributor

TokisanGames commented Mar 27, 2023

Godot version

4.0, 4.0.1

System information

Windows 11/64, RTX 3070, Vulkan

Issue description

This will break our game and give hundreds of errors without our workarounds. It appears that autoloaded scripts are loaded before global_script_class_cache.cfg is populated, yet Godot only loads class names from that file. So, if a class isn't registered in the file, the autoload fails.

# ItemDB.gd:  <- Autoloaded
extends Node

var stats: Stats

func _ready():
	Util.test()
# Stats.gd
class_name Stats
extends Resource
# Util.gd
class_name Util

static func test():
	pass

Autoload ItemDB.gd, then close Godot, delete global_script_class_cache.cfg and reload. It will break with these errors:

SCRIPT ERROR: Parse Error: Could not find type "Stats" in the current scope.
          at: GDScript::reload (res://ItemDB.gd:3)
SCRIPT ERROR: Parse Error: Identifier "Util" not declared in the current scope.
          at: GDScript::reload (res://ItemDB.gd:6)
ERROR: Script does not inherit from Node: res://ItemDB.gd.
   at: (editor/editor_autoload_settings.cpp:423)

Stats and Util are two examples of the same problem. They can be tested independently. It is also an issue with any derivative classes. If ItemDB has an Item, which has a Stats, which is our set up, this also causes the issue.

It's not just a problem with an empty cache file. If someone on a team makes a change to these classes and saves the new class locally, those changes will not get to other team members via git, because Godot does not generate the new cache properly. We have some autoloaded base classes, so when this breaks, we get hundreds of error messages across many scripts.

Workarounds include:

  • Manually open each gdscript file in Godot and resave without changes, one at a time. This will populate the local global_script_class_cache.cfg. Opening all, then saving all does not do it.
  • Copy global_script_class_cache.cfg from another computer
  • Store global_script_class_cache.cfg in git. In spite of the name, it is NOT a cache. We ended up doing this to work around this bug.

This bug has been present for a long while. We worked around it for a while, but finally discovered the exact circumstances today.

In my game, I have received this error message, though I don't get it in the MRP or while debugging. It may provide a clue:

ERROR: Condition "!base->is_valid() && !base->reloading" is true. Returning: ERR_BUG
   at: _populate_class_members (modules/gdscript/gdscript_compiler.cpp:2318)

The script cache can be added to .gitignore without adding the whole directory with this

/project/.godot/*
!/project/.godot/global_script_class_cache.cfg

Minimal reproduction project

test_gdscript_cache.zip

Bugsquad edit: used syntax highlighting for example gdscript code

@TokisanGames TokisanGames changed the title global_script_class_cache.cfg does not populate properly before Autoload Autoloaded script breaks project if classes missing from global_script_class_cache.cfg Mar 27, 2023
@mhilbrunner mhilbrunner added this to the 4.x milestone Apr 24, 2023
@TokisanGames
Copy link
Contributor Author

In 4.0.2 I'm often running into this when changing branches with a lot of modifications. I open up Godot to a lot of errors of broken scripts. I go to git and see global_script_class_cache.cfg has changed, revert it, restart Godot and it comes right up.

I'm surprised more people aren't running into classes being randomly dropped from global_script_class_cache.cfg.

@richard-gebbia
Copy link

richard-gebbia commented May 25, 2023

I've also run into this a ton, even on 4.0.3.stable. Thank you for reporting. I'm also surprised to see more people not having issues with this.

@TokisanGames
Copy link
Contributor Author

TokisanGames commented Jul 15, 2023

This can also break gdscript plugins with custom class names and makes it very difficult to provide a smooth user experience when providing plugins with typed code.

Custom classes are not recognized until they are in the script cache. Installing a new plugin means a user commenting out code until the script cache is populated, then those lines can be uncommented.

In order to fix it, my plugin gdscript files cannot have class_names and I have to specify variables of those types as the built in type it extends. GDExtension class names are fine, so it's just a problem with the gdscript cache.

@TokisanGames TokisanGames changed the title Autoloaded script breaks project if classes missing from global_script_class_cache.cfg Plugins & Autoloaded scripts breaks project if classes missing from global_script_class_cache.cfg Jul 15, 2023
@warent
Copy link

warent commented Nov 11, 2023

Sigh... yes this has basically just completely broken my project. Going to start tracking changes on global_script_class_cache.cfg and reverting as needed. Until then, time to open all my files 😩

@BrysonMcI
Copy link

Hit this on 4.1.stable when my disk filled while editing scripts. Not only did that nuke the current script I was working on and emptied two scene files, but it triggered this same corruption for every class_name in my code and plugin code. Instead of opening every file and saving it to regenerate it, you can also just delete every file and restore it from your trash bin as that seems to trigger a mass "reindex".

@mihe
Copy link
Contributor

mihe commented May 17, 2024

Anyone who takes a crack at fixing this issue likely ought to consider #92054 as well, which is similar to this issue in that you end up with scripts that are parsed before global_script_class_cache.cfg is updated, but which doesn't need to involve autoloads or plugins.

@donn-xx
Copy link

donn-xx commented May 23, 2024

Many similar reports here: #76380 (comment)

class_name is really not working as expected.

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.

9 participants