Skill Information Not Updating

Godot Version

v4.5.1.stable

Question

Hello, I’m working on a system where the player has a skills menu and that talking to certain NPCs will add new skills to the menu. The system’s spread across a few scenes, but I’ve used print statements to make sure the process is working. It works when I ask them to print things like “yes” but also if I get it to print out the skill name, meaning the code is working and the information about the skill is being passed on, just not put onto the skill menu screen.

Here’s the full code for the final part of the process - the skill slot scene. When a new skill is being added, I want a new skill slot to appear in the menu with updated text reflecting the skill’s name and effects. The “set_empty” function works too, setting the default skill slots to having no text.

@tool # lets things be visibly changing in the game and in the editor I think?
extends Control

# define item properties
@export var skill_signal = ""
@export var skill_name = ""
@export var skill_description = ""
@export var skill_logo: Texture
var scene_path = "res://Scenes/skill.tscn"

# Node references
@onready var icon = $innerborder/skillicon
@onready var Skill_name = $innerborder/name
@onready var Skill_description = $innerborder/description
@onready var usage_panel = $"Usage Panel"
@onready var button = $innerborder/Button

# slot skill
var skill = null
var current_skill = null

# adding the skill, skill dictionary
func add_skill():
	skill = {
		"skill_signal" : skill_signal,
		"skill_name" : skill_name,
		"skill_description" : skill_description,
		"skill_logo" : skill_logo,
		"scene_path" : scene_path,
	}
	if Global.player_node:
		Global.add_skill(skill)

# shows usage 
func _on_button_pressed():
#	if skill != null:
		usage_panel.visible = !usage_panel.visible

		
# create empty slots with no values
func set_empty():
	icon.texture = null
	Skill_description.text = ""
	Skill_name.text = ""
	
# add new skill with stuff from dictionary
func set_skill(new_skill):
	skill = new_skill
	icon.texture = new_skill["skill_logo"]
	Skill_name.text = str(skill["skill_name"])
	Skill_description.text = str(skill["skill_description"])
	print(Skill_description.text)
		
# if you don't use that skill
func _on_no_button_pressed():
	usage_panel.visible = false

# if you do want the skill
func _on_yes_button_pressed():
	current_skill = skill["skill_signal"]

It’s probably something really obvious, any input is appreciated!

Im just guessing you want it to update on yes button pressed?

Why dont you call set_skill() from there?

Right now you just stored the skill in a variable but dont seem to do anything with it.

No sorry, the yes button is part of the menu ui. When that’s pressed, it’s supposed to send a signal to another scene (maybe the player) so I can code what those skills do. I haven’t finished this bit yet.

The process is meant to be:

The skill’s details (name, effect etc.) are set in the NPC scene. After the conversation with that NPC finishes, it instantiates one of the skill_slot scenes and uses the “add_skill” function, calling the global “add_skill” function too.

The global “add_skill” goes through the menu checking for an empty slot and sends the “update_skills” signal to the ui, calling this function:

# update skill ui
func _on_skills_updated():
	clear_grid_container()
	# add slots for each inventory position
	for skill in Global.SkillSet:
		var slot = Global.skill_slot_scene.instantiate()
		gridcontain.add_child(slot)
	# check if the slot has an item, create empty or populate
		if skill != null:
			slot.set_skill(skill)
		else:
			slot.set_empty()

Which then calls “set_skill” in the original script I sent.

All of this seems to work, since the print statements work, but I want “set_skill” to replace the labels on the skill slot ui and print the skill’s skill_signal when the yes_button is pressed. For some reason this isn’t happening even though I know the skill is being successfully passed between the scenes.

I would do like this just to make sure that you dont accidentally finish everything with a set_empty().

else:

    Print("calling set_empty() for ", skill)

    slot.set_empty()

But i do think it is a bit unlikely to be the problem.

Are you sure you call the UI update after everything else is already available for it to work with?

Do any skills at all show up? E.g. only the first picked skill?

Thank you, I tried that and at it looks like the set empty and set skill are working correctly, the size of the skill menu is 10, so it sets the skill in the first position and sets the other 9 to empty:

"Bert" being the skill description I think

When you load up the game and after you receive a new skill, the menu shows one empty skill slot:

Though the size of the menu is 10, it looks like it only shows one (the last) skill in the menu, it has been setting the skill correctly, just not showing it. I changed the menu size to 1 and it showed the skill as it was supposed to:

So I suppose the question is now why does the skill menu only show the last of its ten skill slots?

Is Global.SkillSet a dictionary or an array?

If you use a dictionary often the entries can be jumbled when retrieved. For example dictionary.get_values() returns an array of the values sorted alphabetically. An array would return them in indexed order. Since you say bob is last but for some reason shows up first.

Could also be that they are all on top of eachother. Is gridcontain still a grid container or have you changed its type somewhere along the way?

I think it’s an array, it’s defined in the global script by

var SkillSet = []

I think the menu screen is only showing the last skill in the array. When you get given a new skill it replaces the first null value, so if I have more than one spot in the array, the new skill will never be shown on the menu. I checked by adding a second NPC who gives a skill and the second skill is put into the second space in the array, not overwriting the first.

It is still a grid container, but only has one column. Is there a way to control position/size of rows independently or is that just determined by the size of the children?

I think I’ve found the issue, I hadn’t defined the sizes of the children properly, so they weren’t sorting nicely in the grid. Thanks so much for the help!