Quick answer: Mark Resource subclasses with [GlobalClass]. Build before opening scenes that reference them. Don’t rename or move the script while .tres files reference it; rename via the editor’s rename refactoring if you must.
You add a namespace to your EnemyDef class. Rebuild. All your enemy.tres files now have a missing script reference and inspector blanks. Without [GlobalClass] the path changed.
The Symptom
Resource fields show as “[script broken]” or null after a build. Reverting the script change restores them. Or new resources appear fine but old ones broken.
The Fix
using Godot;
[GlobalClass]
public partial class EnemyDef : Resource
{
[Export] public int Health { get; set; } = 100;
[Export] public string DisplayName { get; set; }
}
[GlobalClass] registers the type by name. Resources serialize using the name; renaming the namespace doesn’t break things.
Editor Workflow
- Add or modify the C# class.
- Build (Ctrl+B).
- Reopen the scene if it was open during the build.
- Save.
Skipping the build leaves the editor with the previous DLL; references may resolve incorrectly.
Renaming Scripts Safely
If you must rename the class, use the editor’s built-in rename so the old path stays as an alias temporarily. Rebuild and re-save scenes. After verification, drop the alias.
Verifying
Add [GlobalClass]. Build. Old .tres files referencing the class re-resolve. If still broken, the resources still hold the old path string — open the .tres in a text editor, fix the script_class line, save.
“[GlobalClass]. Build first. Edits don’t lose references.”
Related Issues
For C# Export Array, see Export Array. For UID collision, see UID collision.
[GlobalClass]. Build. References hold.