Each system’s capabilities are different as a result.
Scenes can define how an extended class initializes, but not what its
behavior actually is. Scenes are often used in conjunction with a script so
that the scene acts as an extension of the scripts declarative code.

usingSystem;usingGodot;publicclassGame:Node{publicreadonlyScriptMyNodeScr=(Script)ResourceLoader.Load("MyNode.cs");publicreadonlyPackedSceneMySceneScn=(PackedScene)ResourceLoader.load("MyScene.tscn");publicNodeANode;publicNodeMyNode;publicNodeMyScene;publicNodeMyInheritedScene;publicGame(){ANode=newNode();MyNode=newMyNode();// Same syntaxMyScene=MySceneScn.Instance();// Different. Instantiated from a PackedSceneMyInheritedScene=MySceneScn.Instance(PackedScene.GenEditState.Main);// Create scene inheriting from MyScene}}

Also, scripts will operate a little slower than scenes due to the
speed differences between engine and script code. The larger and more complex
the node, the more reason there is to build it as a scene.

In some cases, a user can register a script as a new type within the editor
itself. This displays it as a new type in the node or resource creation dialog
with an optional icon. In these cases, the user’s ability to use the script
is much more streamlined. Rather than having to…

Know the base type of the script they would like to use.

Create an instance of that base type.

Add the script to the node.

(Drag-n-drop method)

Find the script in the FileSystem dock.

Drag and drop the script onto the node in the Scene dock.

(Property method)

Scroll down to the bottom of the Inspector to find the script property and select it.

Select “Load” from the dropdown.

Select the script from the file dialog.

With a registered script, the scripted type instead becomes a creation option
like the other nodes and resources in the system. One need not do any of the
above work. The creation dialog even has a search bar to look up the type by
name.

Engine developers must add support for languages manually (both name exposure and
runtime accessibility).

Godot 3.1+ only.

The Editor scans project folders and registers any exposed names for all
scripting languages. Each scripting language must implement its own
support for exposing this information.

Both methodologies add names to the creation dialog, but script classes, in
particular, also allow for users to access the typename without loading the
script resource. Creating instances and accessing constants or static methods
is viable from anywhere.

With features like these, one may wish their type to be a script without a
scene due to the ease of use it grants users. Those developing plugins or
creating in-house tools for designers to use will find an easier time of things
this way.

On the downside, it also means having to use largely imperative programming.

If one wishes to create a basic tool that is going to be re-used in several
different projects and which people of all skill levels will likely use
(including those who don’t label themselves as “programmers”), then chances
are that it should probably be a script, likely one with a custom name/icon.

If one wishes to create a concept that is particular to their game, then it
should always be a scene. Scenes are easier to track/edit and provide more
security than scripts.

If one would like to give a name to a scene, then they can still sort of do
this in 3.1 by declaring a script class and giving it a scene as a constant.
The script becomes, in effect, a namespace:

GDScript

# game.gdextendsReferenceclass_nameGame# extends Reference, so it won't show up in the node creation dialogconstMyScene=preload("my_scene.tscn")# main.gdextendsNodefunc_ready():add_child(Game.MyScene.instance())