Global Var Issue

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By ACatThatPrograms

I’m having a really odd issue with a singleton set-up for storing some data…Appreciate any help

I have a function called use_food() being called from a connect signal, but when it runs it doesn’t update the global variables in this file.

use_food() uses sent item data and sends a custom parsing code to a text parser, and at parsing [item_heal] the signal for item_heal() is connected to this singleton and triggered.

Basically the idea is to set up the recovery globally in this file to wait on the signal from the dialogue to then heal the player, but the global vars aren’t being updated. The to_rec vars are to hold the calculated values that will be used to modify player hp/pp

The text box will wait at [wait] before the [item_heal] but as soon as I press the continue key and item_heal is called, it prints that those vars are still null and 0

if I run set_up_heal_target("player", 5, 5) in delta time on the singleton it updates, it just seems not to update in this specific sequence.

I’m not sure of the inner machination of godot but I am not pausing updates or using any internal loops other than delta while waiting to press continue, so I don’t understand why this variable isn’t being updated by the function set_up_heal_target() inside use_food()

Keep in mind even after the code has run past that frame these vars will not update, so I also don’t think it is a timing issue of executed code.

Here’s the snippet for the item_heal parsing code:

ITEM_HEAL: #This is called when [item_heal] is parsed
    connect("item_heal", item, "item_heal", [], 4)
    emit_signal("item_heal")

Here’s the code snippet of the singleton ‘item’:

[wait] pauses parsing but does not halt frames, so this should not be an inner loop issue

I filled out a few more comments to nullify any common question that may pop up

var hp_to_rec = 0
var pp_to_rec = 0
var heal_target = "Null"

func use_food(item, user, target, calling_entity):
    ## Directly editing hp_to_rec here also will not update
    calling_entity.switch_state("inactive") ## Switches focus away from item_menu to text_box
    if game_data.party_size == 1: ## This is true and this code runs ##
        var hp_rec = 0 ## Local vars for holding data before updating globally...
        var pp_rec = 0 ## I have changed these to global vars and experienced the same issues
    
    ... ### CALCULATE hp_rec, pp_rec ### ...
    
        set_up_heal_target(target, hp_rec, pp_rec) ## Everything passed as an argument successfully
            
        ## Wait in this command is where parse pausing happens until continue is pressed

        var command =  "%s ate the %s. [sfx] [0] [wait] [break] [item_heal] %s recovered %s HP.
        [sfx] [1] [wait] [end]" % [user.character_name, item.DATA["NAME"], user.character_name, 
        hp_rec]
    
        text_box.connect("text_done", text_box, "_text_done_close_caller", [calling_entity], 4)
    
        text_box.load_command(command)
        text_box.read_command()
        	
    else:
        print("Code item-target select") ## This is for party targeting, didn't get that far yet
    
func set_up_heal_target(target, hp, pp):
    # I can print here and all arguments will print correctly #
    ## These will not update globals when called from within item_use()
    heal_target = target
    hp_to_rec = hp 
    pp_to_rec = pp
    ## print(heal_target, hp_to_rec, pp_to_rec) will print correctly here, like they are local

func item_heal():
    ## This line prints non-updated globals
    print("ITEM HEAL CALLED :", heal_target, hp_to_rec, pp_to_rec)

Edits for formatting and other findings.

My main thought is that maybe global variables are passed into function on call, meaning use_food gets called and is passed the global functions pre-update, within this function set_up_heal is called and updates them, but also within this function is where the call to item_heal is being made.

However item_heal being an outer function to use_item(), I would be under the guise that it would receive updates to global variables immediately on calling it, and it’s positioning within other functions shouldn’t affect its ability to perceive change to global vars.

:bust_in_silhouette: Reply From: ACatThatPrograms

Solved:

For anyone that may stumble across this, make sure you keep track of instancing. I have other items that inherit from item(The singleton)

This was a silly error and I’ll explain for those curious:

item is a singleton, and I was passing the singleton item rather than the food_item instance itself in the connect function. So the variable was updating within the instance of the food_item that inherits from the singleton and I was checking the singleton’s variables instead of the correct instance.

I’m actually going to re-write this and move the data I needed via singleton pattern to a different game_data singleton. When I planned this out I thought I would need the item class to preload but it doesn’t appear to be true.

Thanks for all the input, just reading it over and over helps and any nudge in any direction I wasn’t looking helps.