0 votes

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.

Godot version 4, beta 8
in Engine by (24 points)

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...

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

1 Answer

+1 vote
Best answer

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.

by (372 points)
selected by
Welcome to Godot Engine Q&A, where you can ask questions and receive answers from other members of the community.

Please make sure to read Frequently asked questions and How to use this Q&A? before posting your first questions.
Social login is currently unavailable. If you've previously logged in with a Facebook or GitHub account, use the I forgot my password link in the login box to set a password for your account. If you still can't access your account, send an email to [email protected] with your username.