Invalid call, Nonexistent function

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By crotron

I have a scene, “Map.tscn”, made up of a TileMap node. Attached to this node is a script, “Map.gd”. The code inside this script looks something like the following:

extends TileMap

func _init(tiles, width, height):
	# etc etc

Basically, I made my own function inside this script to facilitate its initialization, since I expect there to be many more variables that I’ll have to initialize with later on.

Then, in my game, I have some code that does the following:

onready var map_class = preload("res://Map.tscn")

func _ready():
	# some code to determine tiles, width, height
	var new_map = map_class.instance()
	new_map._init(tiles,width,height)

I expected that this would create my Map scene with my Map script attached to it and call the _init function I defined in that script. Instead, it crashes and tells me “Invalid call. Nonexistent function ‘_init’ in base ‘TileMap’.”

What am I doing wrong?

If I recall, the base nodes can’t be called in that fashion. It may be better creating a class, and putting the initialization function in there.

Ertain | 2018-09-08 05:02

:bust_in_silhouette: Reply From: 2D

My initial thought, which most people will encounter at some point, was this could be fixed with node.call_deferred() as mentioned here and here.

However, I believe your issue is that you are trying to overload the built in init() function with one that has arguments and GDScript doesn’t like that. The easiest solution for you is to just create a custom method in your tile map class (e.g. init_map(a, b, c)) and plug that in to your code above. Also, don’t forget to add your map as a child =)

For example:

extends TileMap
    
func init_map(tiles,width,height):
   	# etc etc

and

extends Node2D

var map_class = preload("res://Map.tscn")

func _ready():
# some code to determine tiles, width, height
	var new_map = map_class.instance()
	new_map.init_map(tiles,width,height)
	add_child(new_map)

Thanks! This worked fine.

crotron | 2018-09-09 04:07

:bust_in_silhouette: Reply From: jandrewlong

Since you overloaded the _init function, you need to pass the same number of arguments when you call instance on the class.

So:

extends TileMap

func _init(tiles, width, height):
    # etc etc

and:

extends Node2D

var map_class = preload("res://Map.tscn")

func _ready():
    # some code to determine tiles, width, height
    var new_map = map_class.instance(tiles,width,height)

Unfortunately, this won’t work with a PackedScene. If it was just a class (Map.gd), then map_class.new(tiles, width, height) would work like a champ.

2D||!2D | 2018-09-10 15:49

You are correct. I had not realized there was a difference.

jandrewlong | 2018-09-10 16:05

:bust_in_silhouette: Reply From: Aristonaut

For those getting the “Invalid call, Nonexistent function” error while working on plugin stuff for the editor, this error could mean that your script doesn’t have “tool” at the top of it.

Your answer has saved me twice in one week - I forgot about it the second time. Thanks for sharing it - you’ve saved me hours of headaches.

Rollie | 2021-02-04 16:08

What’s weird is I called has_method and it returned true even though I forgot tool ?!?

furroy | 2023-04-06 20:28

1 Like

THANK you this is exactly what was going wrong for me as well.