Using variables in csv files

Godot Version

Godot 4.3.stable

Question

I’m trying to get the name of my player in a dialogue.
I have an script called “GlobalVar” which contains a variable “player”, making me able to access the string used to store the player’s name in gdscript using GlobalVar.player.playername.

I also have a csv file that looks like this:

Column 1 Column 2 Column 3
keys en fr
MY_MESSAGE My name is %s. Je m’appelle %s.

I now want to display this message in game. I know that it can be done via gdscript by doing something like message_box.text = MY_MESSAGE % GlobalVar.player.playername.
I also know that I could use the String.format method.

However, both of those solutions require me to specify the variable I want to use in a .gd file. Is there a way to do it by specifying the variable I want to use in my csv file directly? I know that having a csv file that looks like

Column 1 Column 2 Column 3
keys en fr
MY_MESSAGE My name is %s. % GlobalVar.player.playername Je m’appelle %s. % GlobalVar.player.playername
doesn’t work, so if you have a solution, I’d be happy to hear it. Thanks in advance.

I don’t think the translation system was supposed to work like that, but a fast workaround i can imagine is you create a custom function to deal with that:

en fr
MY_MESSAGE My name is %s.[/]playername Je m’appelle %s.[/]playername

In your GlobalVar create a dictionary, as example for this post would be:

variables_dict := {"playername": "the player name"}


And create a function somewhere like that:

func get_translation_custom(p_translation_key):
	# Get the phrase from translation system
	var raw_translation = tr(p_translation_key)
	# Get an array with two indexes, the first one with the translated 
	# phrase and the second with the variable name to search
	var splited_translation = raw_translation.split("[/]")
	# Return the final phrase with the value from variables_dict added
	return splited_translation[0] %GlobalVar.variables_dict[splited_translation[1]] 
1 Like

You could use get_indexed on your GlobalVars, of course the full implementation will require splitting like @matheusmdx has, rather than the hard-coded string "player:playername"

MY_MESSAGE % GlobalVar.get_indexed("player:playername")
1 Like

Surely you are already in a script in order to get the translation in the first place?

I had a look at gettext for you too, but they do not allow dynamic content in that way either. In fairness, it is probably a bad idea to do so, no matter how convenient it may seem.

1 Like

How I did it with ProjectSettings:
my custom global singleton has var locale

var locale:Object:
	get:
		if locale==null:locale=load('res://locales/'+ProjectSettings.get_setting('global/locale')+'.gd').new()
		return locale

in locale file there var text:={} with String ids and a value as localized text
And when I need localized text just get it by
button.text=GlobalData.locale.text['MENU_NEW_GAME']