How can i call functions from non-tool classes with tools?

Godot Version

4.2.1

Question

i am trying to make a level editor. i have two classes, a grid (the level, with a regular script) and a grid_editor (the editor, with a @tool script).

the grid has a bunch of internal functions to edit itself, things like clearing the grid or setting tiles within the grid. all of these work perfectly at runtime.

the grid_editor is a @tool script with a reference to my grid. i am using @export variables to call functions within my script, and that works great, ie

@export var _foo = false
	set(x):
		print("hello world")

where clicking on the _foo checkbox in the editor in the grid_editor’s inspector calls the print and prints “hello world” to the console. all of this works perfectly.

my problem is i want to make tool functions to edit my grid, ie i want to be able to call functions like grid.setTile(x,y,z) from the grid editor. when i try to write this in the script, it compiles just fine with no errors, since it is accessing a function from a script.
image

the newTile function definition in grid.gd

image

calling newTile from grid_editor.gd, where 'grid' is a valid reference to my scene node with a grid.gd script on it

all of this looks fine, but when i click on the checkbox to try running this function, i get this error

res://grid_editor.gd:8 - Invalid call. Nonexistent function 'newTile' in base 'Node3D (grid)'.

now this certainly isn’t true. there is obviously a newTile function in grid.gd, and at runtime i can call it just fine. am i referencing this function wrong? i am also unable to set variables manually, with a similar error. how can i access variables and functions from other scripts with a @tool script? it seems that tools wouldn’t be at all useful if they can’t do that.

You might want to split your grid into a data class (likely a Resource) and a logic class (your Node3D) that @exports the data class as a property - that way you can edit the tiles without having to run the entire grid as a tool script. The node grid set function can then just call to one on the resource grid to manipulate the data, and your tool code can also manipulate the data directly.

i do have two different classes, grid and grid_editor. grid_editor is a tool, but also a node (it doesn’t have to be a node really), my problem is that seemingly i cannot manipulate or even read information from my grid node. is this just not possible to do in the editor?

If you make grid itself a tool it will work, but that may be a bit messy. Give it a try and see if anything goes wrong with how you’ve set it up.