Variable in Autoload Being Cleared

Godot Version

v4.2.2.stable.official [15073afe3]

Question

I am trying to learn about the navigation systems, meaning my code is pretty basic at the moment. I have 2 Groups, “team1” and “team2” and have the Actors assigned to one or the other. They then find the nearest one in the other team and path to it, referring to lists held in an autoload script. This works, at least at first.

After some time, the variables holding the list of Actors keeps getting set to an empty array. The variables in question are only set in 2 places, at class level and in a refresh function which is as simple as team1 = get_tree().get_nodes_in_group("team1"). My thinking was that either the autoload is being reinitialised or the nodes are losing their Group, but testing with print the Groups remain the same and the autoload script only hits _ready() once, so I’m not sure where to go now.

Code and console output below. I’m sure I am missing something simple - any help would be appreciated!

## actors.gd

var team1: Array = []  # untyped array due to using get_nodes_in_group
var team2: Array = []

func _ready() -> void:
	refresh_team_lists()
	
func _process(delta: float) -> void:
	print_rich("VARS - team1: ", team1, "| team2:", team2)
	print_rich("GROUPS - team1: ", get_tree().get_nodes_in_group("team1"), "team2:", get_tree().get_nodes_in_group("team2"))
	
func refresh_team_lists() -> void:
	team1 = get_tree().get_nodes_in_group("team1")
	team2 = get_tree().get_nodes_in_group("team2")
	
func get_closest_actor_in_team(actor: Actor, team: String) -> Actor:
	var target_team: Array = [] # untyped array due to using get_nodes_in_group
	
	if team == "team1":
		target_team = team1
	elif team == "team2":
		target_team = team2
	else:
		push_error("Team given, ", team, ", isnt valid.")
		return
	
	if target_team.size() == 0:
		push_warning("No possible targets in ", team, ".")
		return
		
	var closest_actor: Actor = target_team.pop_back()  # pop_back as faster and dont care about order
	var current_distance: float = actor.position.distance_to(closest_actor.position) 
	
	for poss_target in target_team:
		if _is_closer(actor.position, poss_target.position, current_distance):
			closest_actor = poss_target
			current_distance = actor.position.distance_to(closest_actor.position)
	
	return closest_actor
		
func _is_closer(origin: Vector2, target: Vector2, current_distance: float) -> bool:
	return origin.distance_to(target) < current_distance 
## console
VARS - team1: [Actor:<CharacterBody2D#30500979952>, Actor2:<CharacterBody2D#30635197688>, Actor3:<CharacterBody2D#30769415424>, Actor4:<CharacterBody2D#30903633160>, Actor5:<CharacterBody2D#31037850896>, Actor6:<CharacterBody2D#31172068632>]| team2:[Actor7:<CharacterBody2D#31323063585>, Actor8:<CharacterBody2D#31457281321>, Actor9:<CharacterBody2D#31591499057>, Actor10:<CharacterBody2D#31725716793>, Actor11:<CharacterBody2D#31859934529>, Actor12:<CharacterBody2D#31994152265>]
GROUPS - team1: [Actor:<CharacterBody2D#30500979952>, Actor2:<CharacterBody2D#30635197688>, Actor3:<CharacterBody2D#30769415424>, Actor4:<CharacterBody2D#30903633160>, Actor5:<CharacterBody2D#31037850896>, Actor6:<CharacterBody2D#31172068632>]team2:[Actor7:<CharacterBody2D#31323063585>, Actor8:<CharacterBody2D#31457281321>, Actor9:<CharacterBody2D#31591499057>, Actor10:<CharacterBody2D#31725716793>, Actor11:<CharacterBody2D#31859934529>, Actor12:<CharacterBody2D#31994152265>]

[...]

VARS - team1: []| team2:[]
GROUPS - team1: [Actor:<CharacterBody2D#30500979952>, Actor2:<CharacterBody2D#30635197688>, Actor3:<CharacterBody2D#30769415424>, Actor4:<CharacterBody2D#30903633160>, Actor5:<CharacterBody2D#31037850896>, Actor6:<CharacterBody2D#31172068632>]team2:[Actor7:<CharacterBody2D#31323063585>, Actor8:<CharacterBody2D#31457281321>, Actor9:<CharacterBody2D#31591499057>, Actor10:<CharacterBody2D#31725716793>, Actor11:<CharacterBody2D#31859934529>, Actor12:<CharacterBody2D#31994152265>]

Note: Arrays are always passed by reference. To get a copy of an array that can be modified independently of the original array, use duplicate.

This means you are actually removing an entry of your team1 or team2 array at:
var closest_actor: Actor = target_team.pop_back()

Duplicating the array should fix it:
target_team = team1.duplicate()

2 Likes

Pass by ref not value? What a scrub I am! :woman_facepalming:

Legend, thank you for the quick response.