Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow preloaded PackedScenes as static type hints #8565

Open
HolonProduction opened this issue Dec 1, 2023 · 8 comments
Open

Allow preloaded PackedScenes as static type hints #8565

HolonProduction opened this issue Dec 1, 2023 · 8 comments

Comments

@HolonProduction
Copy link
Member

HolonProduction commented Dec 1, 2023

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:

  • the root node has an attached script: in this case the type hint will work as if that script was preloaded
  • the root node has no attached script: in this case the hint will work as if the native type of the root node was specified

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.

@Mickeon
Copy link

Mickeon commented Dec 7, 2023

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
Copy link
Member Author

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
Copy link

Mickeon commented Dec 7, 2023

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
Copy link
Member

dalexeev commented Dec 7, 2023

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
Copy link
Member Author

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
Copy link

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

@Mickeon
Copy link

Mickeon commented Jul 5, 2024

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants