Well, I have a scene that has a puzzle that, when solved, inserts a value into an array that other objects in my game "activate" once it is present. The puzzle works but every time I change the scene the array suddenly dumps the value - i know this because i have a debug function that checks this array. I've even tried building in an exit tree function to make sure the value stays there but no matter what, even when the value is there, the scene change causes it to dump out of the array! What could be causing this? (it's not the scene changer, it has no array manipulation). I will include relevant code below. Been combing through it for an hour and about to lose my mind.

In case any ask: the puzzle merely requires you to flip all the breakers. When they are on, value is added, when they are off, it is gone. My debug showed no errors here. It is only after the scene changes. There is a randomizer function so it's different every time you play but once again.... don't think this is doing it.

extends Node2D

## containers for groups/flywheel
var _breakers = []
var _flips = []
## solved state
var _solved = false
## event key to trigger hvac
const _resultEventKey = "acon"

## amp total and result goal
var _ampJar = 0
const _ampResult = 12


func _ready(): ## load arrays at open
	_breakers = get_tree().get_nodes_in_group("breakers")
	_flips = get_tree().get_nodes_in_group("flips")
		
	for _f in _flips:
		_f.connect("pressed",self,"_button_press_cue")
			

	if !DirectorNode._lightsArray.has(_resultEventKey):
		randomize() ## randomize event
		
		for _b in _breakers: ## flip breakers on coin flip each
			var _roll = randf()
			var _button = _b.get_child(0)
			if _roll < 0.5:
				_b.play("on")
				_button.pressed = true
			else:
				_b.play("off")
				_button.pressed = false
			_buttonCheck()

	
		_solved = false ## set default to unsolved to avoid bugs
		
	else:
		$Ambience.play()
		_ampJar = _ampResult


func _buttonCheck():
	_ampJar = 0 ## always reset value before looping

	for _f in _flips: ## update value to loop
		if _f.pressed == false:
			_ampJar+=1
			if _ampJar == _ampResult: ## if not solved, update array
				if !DirectorNode._lightsArray.has(_resultEventKey):
					DirectorNode._lightsArray.append(_resultEventKey)
					_solved = true
			if _ampJar != _ampResult: ## if total drops, event undone
				if DirectorNode._lightsArray.has(_resultEventKey):
					DirectorNode._lightsArray.erase(_resultEventKey)
					_solved = false



	if DirectorNode._lightsArray.has(_resultEventKey): ## keep results locked if solved
		_ampJar = _ampResult
		_solved = true
	else:
		_solved = false


## button press events trigger flicks (toggle state in process)
func _button_press_cue():
	$Cue.play() ## flick noise
	if $Ambience.playing: ## general ambience if not triggered
		$Ambience.stop()
	
	_buttonCheck() ## check buttons and update values
	

	if _ampJar == _ampResult: ## extra sound cues for on and off
		$Warmup.play()
		$Shutdown.stop()
	if _ampJar != _ampResult and !_solved:
		$Warmup.stop()
		$Shutdown.play()


func _process(_delta): ## update breaker graphics, check answer every frame
	_animationCheck()
	_debug()
	_solutionCheck()


func _debug():
	if Input.is_action_just_pressed("_debug"):
		print("Current amps: "+str(_ampJar))
		print("Is ac on? "+str(DirectorNode._lightsArray.has(_resultEventKey)))


func _solutionCheck():
	if _solved or _ampJar == _ampResult:
		if !DirectorNode._lightsArray.has(_resultEventKey):
			DirectorNode._lightsArray.append(_resultEventKey)
	if !_solved or _ampJar != _ampResult:
		if DirectorNode._lightsArray.has(_resultEventKey):
			DirectorNode._lightsArray.erase(_resultEventKey)
  • Well. That was annoying. Of course I figured it out right after I post. Will post solution for anyone else. My value was being input on the button check in the loop rather than on the button press and I guess godot didn't like that? Anyhow it's solved. If anyone knows why this happened, I'd love some enlightenment. The docs are pretty light on autoload hiccups besides making a scene changer.

    SOLVED (Solution check now a separate function and moved):

    func _buttonCheck():
    	_ampJar = 0 ## always reset value before looping
    
    	for _f in _flips: ## update value to loop
    		if _f.pressed == false:
    			_ampJar+=1
    
    
    
    	if DirectorNode._lightsArray.has(_resultEventKey): ## keep results locked if solved
    		_ampJar = _ampResult
    		_solved = true
    	else:
    		_solved = false
    
    
    ## button press events trigger flicks (toggle state in process)
    func _button_press_cue():
    	$Cue.play() ## flick noise
    	if $Ambience.playing: ## general ambience if not triggered
    		$Ambience.stop()
    	
    	_buttonCheck() ## check buttons and update values
    	_solutionCheck() ## MUST UPDATE GLOBAL HERE!!!
    
    	if _ampJar == _ampResult: ## extra sound cues for on and off
    		$Warmup.play()
    		$Shutdown.stop()
    	if _ampJar != _ampResult and !_solved:
    		$Warmup.stop()
    		$Shutdown.play()
    
    
    func _process(_delta): ## update breaker graphics every frame
    	_animationCheck()
    	_debug()
    
    
    func _solutionCheck():
    	if _ampJar == _ampResult: ## if not solved, update array
    		if !DirectorNode._lightsArray.has(_resultEventKey):
    			DirectorNode._lightsArray.append(_resultEventKey)
    			_solved = true
    	if _ampJar != _ampResult: ## if total drops, event undone
    		if DirectorNode._lightsArray.has(_resultEventKey):
    			DirectorNode._lightsArray.erase(_resultEventKey)
    			_solved = false

Well. That was annoying. Of course I figured it out right after I post. Will post solution for anyone else. My value was being input on the button check in the loop rather than on the button press and I guess godot didn't like that? Anyhow it's solved. If anyone knows why this happened, I'd love some enlightenment. The docs are pretty light on autoload hiccups besides making a scene changer.

SOLVED (Solution check now a separate function and moved):

func _buttonCheck():
	_ampJar = 0 ## always reset value before looping

	for _f in _flips: ## update value to loop
		if _f.pressed == false:
			_ampJar+=1



	if DirectorNode._lightsArray.has(_resultEventKey): ## keep results locked if solved
		_ampJar = _ampResult
		_solved = true
	else:
		_solved = false


## button press events trigger flicks (toggle state in process)
func _button_press_cue():
	$Cue.play() ## flick noise
	if $Ambience.playing: ## general ambience if not triggered
		$Ambience.stop()
	
	_buttonCheck() ## check buttons and update values
	_solutionCheck() ## MUST UPDATE GLOBAL HERE!!!

	if _ampJar == _ampResult: ## extra sound cues for on and off
		$Warmup.play()
		$Shutdown.stop()
	if _ampJar != _ampResult and !_solved:
		$Warmup.stop()
		$Shutdown.play()


func _process(_delta): ## update breaker graphics every frame
	_animationCheck()
	_debug()


func _solutionCheck():
	if _ampJar == _ampResult: ## if not solved, update array
		if !DirectorNode._lightsArray.has(_resultEventKey):
			DirectorNode._lightsArray.append(_resultEventKey)
			_solved = true
	if _ampJar != _ampResult: ## if total drops, event undone
		if DirectorNode._lightsArray.has(_resultEventKey):
			DirectorNode._lightsArray.erase(_resultEventKey)
			_solved = false