godotengine / godot-proposals

Godot Improvement Proposals (GIPs)
MIT License
1.1k stars 69 forks source link

Allow preloaded `PackedScenes` as static type hints #8565

Open HolonProduction opened 8 months ago

HolonProduction commented 8 months ago

Describe the project you are working on

Prototypes

Describe the problem or limitation you are having in your project

In Godot it is quite common to split a game into multiple scenes. Lately I ran into a situation were I had a scene for a unit, that was managed by a board game controller. The unit also has some methods for invoking animations.

To get proper autocompletion I use static typing for the unit inside of the game controller. I am no fan of global class_names, so I usually preload the script and use the constant as type hint. In this case however the board game controller also needed to add new units to the board. To do this also have to preload the scene.

Now I have two preloaded constants. Naming them is inconvenient, since both basically contain the same "information". Also having two preloads for this tasks seems overly complicated which in turn discourages adoption of static typing.

Describe the feature / enhancement and how it helps to overcome the problem or limitation

The problem would be solved, if a preloaded scene could be used as static type hint inside of GDScript.

Describe how your proposal will work, with code, pseudo-code, mock-ups, and/or diagrams

For a constant preloaded scene it should be possible to obtain information about the root node.

When such a constant is used as type hint, there are two cases:

If this enhancement will not be used often, can it be worked around with a few lines of script?

I currently use the following construction to prevent having two constants with similar names:

# unit.gd

const Self := preload("unit.gd")
const Scene := preload("unit.tscn")

static func instantiate() -> Self:
    return Scene.instantiate()
# board_game_controller.gd

const Unit := preload("unit.gd")

func _ready():
    add_child(Unit.instantiate())

Which moves the two preloads two the unit were naming them is easier. But adding this boilerplate to many scripts, can be quite tedious.

Is there a reason why this should be core and not an add-on in the asset library?

Can't be solved through an addon.

dalexeev commented 8 months ago

Related:

See also:

Mickeon commented 8 months ago

If PackedScenes were able to be typed (e.g. PackedScene[Node3D]) it would solve this issue and many more similar burdens, but that would be opening a whole other can of worms...

HolonProduction commented 8 months ago

If PackedScenes were able to be typed (e.g. PackedScene[Node3D]) it would solve this issue and many more similar burdens, but that would be opening a whole other can of worms...

It would be a great thing. But it would still require preloading the type and the scene, right?

Mickeon commented 8 months ago

Yes. I basically agree with the proposal. I was suggesting a solution that could be applied more broadly, because it would solve more than one nuisance without making a special exception for preloaded scenes.

dalexeev commented 8 months ago

But it would still require preloading the type and the scene, right?

Yes, if you want to specify the type explicitly. Not, if you use type inference.

const MY_SCENE = preload("./my_scene.tscn") # `MY_SCENE` is `PackedScene[MyNode]`.
# PackedScene[T].instantiate() -> T
var my_node := MY_SCENE.instantiate() # `my_node` is `MyNode`.

The problem is that PackedScene belongs to one specific branch of the class hierarchy, and it would be incorrect to use it as a type specifier for other branches. We discussed this in #1935, #1909 or one of the related proposals.

HolonProduction commented 8 months ago

I see. If it is well integrated with type interference it is probably the better/cleaner solution. Can't give those other proposals a full read right now. But will do when I have time.

megonemad1 commented 3 months ago

I am aware this might be a necro thread but I am currently looking for similar behaviour was there any solution implemented?

Mickeon commented 1 month ago

There's no such thing as a "necro thread" in here. Unfortunately, there's no solution for this in the plans. Not until a more robust system for types is implemented, first.