Node isn't imbued with properties present on script extended from another script

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

First of all, apologies for the wordy title. I will try to explain this in simple terms.

I have a script (BotState.gd) which extends another (StateMachine.gd) to gain access to a variable called state_machine.
I am creating nodes programmatically and using set_script() on each node to set their script to BotState.gd. Unfortunately, the nodes do not appear to take on the variables present in StateMachine.gd.

@onready var bot_script = preload("res://Scripts/BotState.gd").new()

for node in range(global_vars.bot_count):
	var new_bot_script = bot_script.duplicate()

    print(str('state_machine' in new_bot_script)) # returns true

	new_bot_script.key = node + 1
	var bot_node = Node.new()
	bot_node.set_script(new_bot_script)

    print(str('state_machine' in bot_node)) # returns false

	var string_num = node + 1
	bot_node.name = "Bot" + str(string_num) + "State"

I’m at a bit of a loss here, so any help is much appreciated. If I can provide more information, I will gladly do so.

Cheers.

I don’t have an answer, but I do notice that if you look at the bot_node instance in the debugger after you’ve made the set_script() call, the Script property is still <empty>. So, that’s the problem, but I’m not sure why…

jgodfrey | 2022-12-14 22:28

That’s correct, actually. This is the contents of the script, FWIW:

# BotState.gd
extends GameState

@onready var global_vars = get_node('/root/GlobalVariables')
var key = 0

func enter(_msg := {}) -> void:
	global_vars.active_player = str(global_vars.ActivePlayer.keys()[key])
	$'../../RollButton'.visible = true
	$'../../RollButton'.disabled = false

	game.participant_node.hand = game.players["BOT" + key]
	game.participant_node.name = global_vars.active_player

	$'../../Labels/ActivePlayerLabel'.text = global_vars.active_bot

func exit() -> void:
	$'../../EndTurnButton'.visible = false
	$'../../EndTurnButton'.disabled = true

yerbestpal | 2022-12-14 23:04

:bust_in_silhouette: Reply From: LeslieS

The new() on this line:

@onready var bot_script = preload("res://Scripts/BotState.gd").new()   

creates an instance of the BotState script; that is an object and not a script.
This line:

var new_bot_script = bot_script.duplicate()

simply creates a duplicate instance of the object (again not a script).
This line:

bot_node.set_script(new_bot_script)

I am surprised isn’t erroring out on you.

Remove the new() from the variable definition line and remove new_bot_script and just

bot_node.set_script(bot_script)
bot_node.key = node + 1

However, it is my opinion that the approach here is awkward.
I recommend creating a single bot node with attached script and then where and when you need a bot, create new instances of it. Those will come with their script already attached.