How to preload or otherwise include one script in another, without type warnings or errors?

Godot Version

v4.2.1.stable.mono.official [b09f793f5]

Question

I’m trying to write a plugin that has a few different classes. I have my project GDScript settings configured to warn and error on typing issues, because this is extremely helpful for spotting mistakes early. I do not consider turning off or suppressing typing errors outright to be a productive solution.

Here’s an example where I’m trying to refer to a class defined in another file from my plugin.gd, and the typing errors I’m getting:

When defined like this (type inferred):

const Mt3DEditorManager := preload("res://addons/MonsterTerrain3D/editor/Mt3DEditorManager.gd")

And later referenced like this in the plugin’s _ready function:

var manager: Mt3DEditorManager = Mt3DEditorManager.new()

I get this odd error:

res://addons/MonsterTerrain3D/plugin.gd:28 - Parse Error: Value of type "res://addons/MonsterTerrain3D/editor/Mt3DEditorManager.gd" cannot be assigned to a variable of type "res://addons/MonsterTerrain3D/./editor/Mt3DEditorManager.gd".

I’ve also tried defining it like this (typed as Script):

const Mt3DEditorManager: Script = preload("res://addons/MonsterTerrain3D/editor/Mt3DEditorManager.gd")

In which case I get this different warning (configured to give an error):

res://addons/MonsterTerrain3D/plugin.gd:28 - Parse Error: The method "new()" is not present on the inferred type "Script" (but may be present on a subtype). (Warning treated as error.)

One thing I have been able to do is change the variable assignment like this, and then it works without errors. The problem is that I then seemingly have no valid way to refer to the type of this variable, if for example I needed to define a function that accepts this type as an argument:

var manager := Mt3DEditorManager.new()

How can I fix this?

(Related: How do I "Include" a Script Into Another Script? - #2 by system)

You need to define manager as the class name of your gd script. Not the class of the resource.

Mt3DEditorManager is a script Resource.
Manager is whatever your script class is.

The Mt3DEditorManager script doesn’t have a class_name. It is intended to be internal to the plugin, not to be globally available.

1 Like

This paths mentioned is the strangest thing

res://addons/MonsterTerrain3D/plugin.gd:28 - Parse Error: Value of type "res://addons/MonsterTerrain3D/editor/Mt3DEditorManager.gd" cannot be assigned to a variable of type "res://addons/MonsterTerrain3D/./editor/Mt3DEditorManager.gd".
  • res://addons/MonsterTerrain3D/./editor/Mt3DEditorManager.gd
  • res://addons/MonsterTerrain3D/editor/Mt3DEditorManager.gd

Is there any reason there are different paths? Maybe searching for ./editor will reveal something?


You can use preload as a type, as mentioned in the docs on static typing. :+1:

Yeah I noticed that. I tried with preload("res://addons/MonsterTerrain3D/editor/Mt3DEditorManager.gd"), preload("editor/Mt3DEditorManager.gd"), preload("./editor/Mt3DEditorManager.gd"), and even preload("res://addons/MonsterTerrain3D/./editor/Mt3DEditorManager.gd"). None of them made any difference to that error I was getting. I have no idea what could be causing that.

I’m also noticing that I don’t seem to run into this same problem in other places where I try preloading a class from a script. So far it’s just this class. Which itself has no GDScript errors and isn’t doing anything unusual.

Have you tried declaring the type without a type hint? No :

const Mt3DEditorManager = preload("res://addons/MonsterTerrain3D/editor/Mt3DEditorManager.gd")

I am also grasping at straws, seems like an engine bug caching the wrong path. maybe updating to 4.2.2 could help, that fixed a ton of type related issues.

Nope, no difference.

Ahh I’ve been waiting for 4.3 stable before going to the trouble of updating but at this point maybe I should just go ahead. If I do that, I’ll report back on if it fixes this or not.

What is the gd script extend from?

The same behavior has happened for both extends Object and extends Node

My point is this:

const Mt3DEditorManager = preload("res://addons/MonsterTerrain3D/editor/Mt3DEditorManager.gd")

var o:Node:=Mt3DEditorManager.new()

That should work if your .gd extends from Node.

or

const Mt3DEditorManager = preload("res://addons/MonsterTerrain3D/editor/Mt3DEditorManager.gd")

var o:Object:=Mt3DEditorManager.new()

4.2.2 did not fix it. But, happening to take a look at my current git diffs, I found the culprit!

Earlier in making the plugin I had defined the manager class as an autoload. Somehow, this never got cleaned up in the end. I removed these lines from my project.godot and now I’m not getting that error anymore:

[autoload]

Mt3DEditorManager="*res://addons/MonsterTerrain3D/./editor/Mt3DEditorManager.gd"
1 Like