Global variable set by lineEdit and returned in another global script returning 'null'.

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

I would really appreciate some help with a little interactive fiction game I’m making (个_个)

So, I have an autoloaded script file where I’m storing my global variables such as:

var player_name
var player_gender

and another autoloaded script file where the pages for the story are:

var scene1 = {
	"P0001" : "Page one text",
	"P0002" : "Page two's text!" + "\n" + "Hello " + str(global.player_name) + "!",
	"P0003" : "Page three text",
	"P0004" : "Page four text",
	"P0005" : "Page five text"

And the value for the player_name is being set in my lineEdit node’s script:

func _process(_delta):
	if global.currentPage == "I0001":
		if $confirmButton.pressed == true:
			global.player_name = $Sprite/MarginContainer/VBoxContainer/LineEdit.text
			global.currentPage = "C0001"

When I run the game, instead of player_name showing as the inputted name, instead it’s returning as ‘Null’

Hello Null!

I feel like I’m either making a little silly mistake that I can’t see or I’m just going about this all wrong.

Any help would be really appreciated, and thank you for your time!

:bust_in_silhouette: Reply From: Zylann

Your code made a copy of the name in the second autoload and never updated it. Variables (especially null ones) don’t behave like references.

So here is what happened:
Your game starts. The first autoload is initialized (assuming it is first in the list of autoloads!).
Then the second autoload initializes, by creating its dictionary and copying the name found in the first autoload, which is null.
Then your first scene is loaded. You input the player name, which modifies globals.player_name. But the text for the second scene was already built with null, it has no reason to change magically.
The second scene starts and you’ll see null.

To fix this, a few options:

  • Don’t copy the the name and do something like .replace("<player>", global.player_name) on the string to show when you actually display it

  • Don’t make your scene text an autoload. Make it initialize when the scene actually loads (in _ready for example), this way the name will be up to date if you set it before loading it.

Thanks a lot for the help, and sorry for the late reply!
And sorry to bother you again, but I can’t seem to get replace() to work… (・_・ヾ

I’ve added a ‘var playerName’ variable to my page script and changed ‘str(global.player_name)’ to ‘str(playerName)’ and then I added a line of code to this section

if $confirmButton.pressed == true:
    global.player_name = $Sprite/MarginContainer/VBoxContainer/LineEdit.text
    page.scene1.P0002.replace("playerName", global.player_name)
    global.currentPage = "C0001"

…that’s still just returning ‘null’ and I’m 100% sure I’m doing it completely wrong - I’ve also tried writing it out a few different ways.

I can’t really find anything in the docs or other places online on how to properly use replace() ( ̄▽ ̄*)ゞ

Could you possibly help me out with this? Again, sorry for the late response and thank you!

Clamarii | 2020-09-23 06:23

You didnt choose the easiest option tho^^

That extra code you added still does not work because replace does NOT modify a string, instead it returns a modified copy, so you would have to write this instead:

page.scene1.P0002 = page.scene1.P0002.replace("playerName", global.player_name)

Zylann | 2020-09-24 12:44

Thanks for replying again!

This isn’t causing any errors, but it’s still returning ‘null’.

I thought that maybe I was placing it in the wrong script so I tried placing it in my in ‘func _process(delta)’ but it returns the error ‘Invalid type in function ‘replace’ in base ‘String’. Cannot convert argument 2 from Nil to String.’ …So I’m just… not going to do that. ( o > o)

Yeah - I think I should probably just add the pages to _ready.

Clamarii | 2020-09-25 02:44