When should you use Resource VS Node + script with @export var?

I know how to use custom resources but I can’t really wrap my head around WHY I should use it over a script attached to a node with some @export var.

I often find myself making a scene which has a script attached to its root Node with some @export vars in it and I then create inherited scenes which extend from this one and tweak these values in the inspector.
Resources do the same job IMO but you have to create additional resources files.

The only advantage I see for resources compared to nodes is when you don’t want to instantiate a scene to it (which can contain at least one script) and just use a resource which instead won’t be added to the scene tree.

For example a scene ItemWorld could be the representation of an item which the player can see and it would use the ItemData resource.
ItemInventory could be a UI element which uses the ItemData resource as well.
So no scene instance required in that case just to grab some data.

If you don’t need to use the features the Node class has I think it can be one reason to use it.

Are there any other reasons to use it VS scene + script?

And it’s a pretty big reason, scene tree operations are some of the most expensive!

Resources can be saved easily with ResourceSaver.save where a scene must be packed and then saved as a resource.

You can share resources across Nodes and Scenes where exported variables of Instantiated nodes are unique (unless they are resources).

1 Like

Indeed if you don’t need all the properties a node has then using a resource seems to be more interesting compared to saving an entire packed scene since it’s less intensive.

What do you mean by that?

A common issue first time Godot users run into is their 3D models use the same material, they change the color of one object and all of the other objects change color too. They are sharing the resource, this uses less memory, and can be quite advantageous. A @export is not shared, though one can point to Resources which are shared.

1 Like

So if I create a base scene LevelSwitcher which is just a button with a script with
@export var scene_file_path: String = "" and some code to switch scene on button press…

Then create an inherited scene LevelSwitcherLevel1, modifiy the exported value in the inspector to: “res://level_1.tscn”
Then create another inherited scene LevelSwitcherLevel2, modify the exported value in the inspector to: “res://level_2.tscn”

And instantiate these 2 scenes (or more with the exact same process) in a UI scene to select levels…

Assuming I could have much more values in this script which I want to change via the inspector on each saved inherited scene is it worth using a resource instead?

You would not need to create an inherited scene to edit the @export, each instance has it’s own value for such exported properties. By the sounds of it a LevelSwitcher will modify the scene tree so a Resource is a bad fit.

I extend resources for enemy wave information in a tower defense game. Each wave is a resource with information about which enemies to spawn and when. I can share this blob of data between maps by serving the easy.tres, normal.tres, or hard.tres wave resource file.

Good point for the instance own values.

Thanks for sharing the use case! :slightly_smiling_face:
So if I understand correctly the main difference is:

Scene + @export var duplicated in the scene tree = 1 instance of the scene with its own values (even if the values are not modified?) which can’t be shared across other similar scenes
VS
Resource is shared across “anything” pointing to it.