Autocomplete on variable returned by factory method of singleton

Godot Version

4.2.2

Question

Hi there, I am new and a little confused.

tl;dr: I should have autocomplete / intellisense in a specific scenario, but I dont. Why?

I have a script like this:

extends Node

const prefab_gate = preload("res://Scenes/gate.tscn")
const GateData = preload("res://Scripts/gate.gd").GateData

func create_gate(data: GateData) -> Gate:
	var gate = prefab_gate.instantiate()
	gate.init(data)
	
	return gate

This script is registered to autoload, it’s called entity_factory. I then have this other script, where I call the create_gate function:

extends Node2D

func spawn_gate():
    var gate_data = get_data() # i am leaving this function out since it's unnecessary complexity, but trust me it works
	var gate = EntityFactory.create_gate(gate_data)
    gate. # No autocomplete / intellisense here

I’d expect to have autocomplete open a few options for me to choose from here, but nothing happens (re-triggering it with Ctrl + Space does nothing as well). Why is that? It works if the EntityFactory returns a Node2D instead. But I want access to the functions that Gate has, and inside the create_gate function I do get autocomplete of the Gate functions.

This is what the Gate script looks like:

class_name Gate
extends Node2D

#region Resource Classes
class GateData extends Resource:
	var level: int
	var energy: int
	var spawn_in: float
	var break_in: float
	var enemies: Array[PackedScene]
	
	func _init(_level: int, _energy: int, _spawn_in: float, _break_in: float):
		level = _level
		energy = _energy
		spawn_in = _spawn_in
		break_in = _break_in
#endregion

func demo():
    return "Test String"

Just do it like this:

func create_gate(data: GateData) -> Gate:
	var gate = prefab_gate.instantiate() as GateData

I did almost exactly the same as you - copied over your functions (just simplified a couple of things so I don’t have to set up the whole scene) and I have the auto completion.
image

I’m not sure why you wouldn’t get it.

1 Like

@wchc interesting. What Godot version are you using? And what OS are you on?

I’m on 4.4dev7, Windows 11.

func spawn_gate():
    var gate_data = get_data() # i am leaving this function out since it's unnecessary complexity, but trust me it works
	var gate = EntityFactory.create_gate(gate_data) as GateData
...
1 Like

@saulocoexi this works. Do you know why I need this (in my eyes redundant) specification?

You need to do it like this because gdscript is dynamically typed.

@saulocoexi Which should (and usually also does, for instance inside the spawn_gate function it does) mean, that gdscript will infer the type based on what the function returns. It also seems to reliably do so for wchc

gdscript understands that even if the function returns something, that something may be null or empty. Therefore, you have to use the alias in front so the editor understands the type for auto complete :slight_smile:

4.2.2 specifically has a lot of inferred autocomplete issues.

Have you tried declare the type explicitly, or even just typing it?

func spawn_gate():
	# Inferred type by `:=`
	var gate_data := get_data()
	# Explicit type by `: Gate =`
	var gate: Gate = EntityFactory.create_gate(gate_data)
1 Like

@gertkeno I actually tried these, and they did not work. However, using as to specify the type did work.

If 4.2.2 has some issues in that regard, i will try updating to the latest version

2 Likes

@gertkeno update: I have updated to Godot 4.3, and it now works even without any explicit declaration. Thanks everyone!

1 Like