Help with understanding how to pass variable between scripts

Godot Version

4.3

Question

I’m relatively new and I’m struggling to understand the best (or any) way to share information between different scenes and scripts via either the editor or code.

My current conundrum is this:
For context I’m working on a board-game style game.

I have a scene board which is the board layout made up of a squares. The squares come in three types player_squares, interloc_squares, and central_squares. It has a script attached called board.gd

In that script I have a function called space_pos_array() that creates an array of the position of each type of square, then returns all of these arrays as a tuple. The return looks like this:

[[(890, 300), (740, 350), (580, 300)], [(10, 300), (160, 250), (320, 300)], [(450, 300)]]

The above order being [player_squares], [interlock_squares], and [centre_squares]

Next I call this function to divide out the tuple into separate arrays so they can be called as needed:

var spaces = space_pos_array()
var player_space_list : Array = spaces[0]
var interloc_space_list : Array = spaces[1]
var centre_space_list : Array = spaces[2]

Now I want to access the player_space_list array in another script called player_blocks.gd which is attached to the parent node of a scene called player_block

How do I do this?

I’ve tried to research this myself and have read about globals/autoloads/singletons, signals, instantiation, etc. I’m feeling a bit overwhelmed and stuck in tutorial hell. I’m not sure what is the best way to do what I need, and anything I try doesn’t seem to work as I expect.

I’d suggest making a global script for the board; follow the instructions for creating a global script, and give it a name like Board. Note that I don’t mean the filename; in the global script setup you also give it a name that’s its namespace. So you can then call Board.some_func() from anywhere, or refer to Board.some_variable.

Alternately, if you can find a path to the Board node you have:

var board = get_node("path/to/board")

board.do_thing(board.some_var)

Personally, I find putting the core game logic in a global game data file seems to work best for me; it lets me call into it from anywhere without worrying about node paths or the like.

1 Like

for this particular case you want a node to manage the game, one that can also be accessed by any node in the game. so use a singleton.

go to project settings, create a new autoload, give it a name in snake_case, like board or game_manager.
the engine will convert it to PascalCase for use within any node:

Board
GameManager

you can now access any variable by calling their names in PascalCase:

GameManager.score += 1

text = str(GameManager.score)

1 Like

@jesusemora @hexgrid
Thanks both for the response. I’ll attempt to implement a global game manager script and see if that works for me.

Thanks again.

I’ve made the board.gd a global which seems to work but it has introduced a new bug. I’m sure it has to do with how or the order in which things are loaded but I’m not sure where to start.

My board.gd code is:

and the output to the console is:

whole tuple: [[], [], []]
first array of tuple: []
whole tuple: [[(890, 300), (740, 350), (580, 300)], [(10, 300), (160, 250), (320, 300)], [(450, 300)]]
first array of tuple: [(890, 300), (740, 350), (580, 300)]
--- Debugging process stopped ---

From what I can tell while debugging is that the space_pos_array function happens first but there are no child nodes for it to find, so it returns empty arrays. Then it runs again, I don’t know why, finds the children, and adds them to the array. Which then print as I would expect.

What am I missing here? Why does the function run twice with different results?

When you add a global it makes a new node at /root/YourGlobalName, I think you added it as a .gd script, which only creates the root node, it does not know how you want the scene or it’s children set up, so it doesn’t add any children. If you added the .tscn scene as a global then it would add the children. You would still have another copy running in your scene though so make sure to delete the instance in your main scene.

1 Like

That’s exactly what I did. Thank you!!