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

  1. Add or modify the C# class.
  2. Build (Ctrl+B).
  3. Reopen the scene if it was open during the build.
  4. 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.