Assigning any dictionary key to a variable

Godot Version

Godot 4

Question

I am trying to create a dialogue system similar to the Chrono Trigger games, in which I am using dictionary pairs to manipulate the dialogue box I have instanced. I have the key of the dictionary as the speaker’s name and the value as the dialogue for that character. All of the dialogue is contained within a seperate standalone gdscript file on autoload so that I can call it when needed.
Though, I am not sure how to apply these dictionaries to my dialogue box, in which the key will be the name in the dialogue box and the value will be the dialogue. I also am unsure of how to iterate the dictionary so that every click will skip to the next dialogue. Is there any specific syntax for this type of thing?

For ordered data which you know you will be iterating through, an Array is appropriate. In this case, your dictionary key can be the name of the speaker, and the dictionary’s value is the Array containing the lines of dialog.

var dialog_dictionary := {
  "Marle": [
    "Crono?",
    "What a nice name!",
    "Pleased to meet you!",
    #And so on and so forth...
  ],
}

In ordering your data in this way, you can access lines of dialog using the syntax dialog_dictionary["Marle"][1], with the number being the line number of dialog you’d like to use.

In doing so, you can use something like the following for loop to iterate through the data.

for line in dialog_dictionary["Marle"]:
	print(line) #This will print all of Marle's lines.

# Alternatively, if you want to print out Marle's name with each line:

for line in dialog_dictionary["Marle"]:
	print("{character_name}: {dialog}".format({
		"character_name": "Marle",
		"dialog": line,
	}))

# Of course, if we want to substitute the speaker's name with a variable

var speaker = "Marle"
for line in dialog_dictionary[speaker]:
	print("{character_name}: {dialog}".format({
		"character_name": speaker,
		"dialog": line,
	}))

These are all ways to access the contents of a dictionary containing an array using various levels of indirection.

With all of that being said, for the purposes of dialog, using a dictionary containing the names of characters as keys and their dialog as values is a naive implementation, but it may suit your particular use case, depending on what you need. If you need something more robust, I would recommend creating a class with the speaker’s name and dialog as attributes.

class CharacterDialog:
  var speaker: String
  var dialog: Array[String]

  func _init(p_speaker: String, p_dialog: Array[String]) -> void:
    speaker = p_speaker
    dialog = p_dialog

  func print_lines() -> void:
    for line in dialog:
      print("{speaker}: {line}".format({
        "speaker": speaker,
        "line": line,
      }))

The idea above could be abstracted even further out into a resource which could be modified in the editor using @export, but this is beyond the scope of the example; left as an exercise for the reader.

I hope that these examples help to inform you in achieving what you seek to do with your dialog system.

Regards,

1 Like

Thanks for the help. Just asking; what is the syntax for calling only the key or only the value of a dictionary? Is it similar to Python?

You can see all the operations on dictionary in the Dictionary reference on the docs.

Dictionary.find_key(value) might be what you’re looking for if you’re trying to pull a key from a value, but it’s non-deterministic as to which key you’ll pull if there’s multiple identical values.

As for getting a value from a key, Dictionary.get(key), Dictionary.key or Dictionary["key"] are all valid ways to access the value of a key.

If you’re looking for an array of all keys or all values Dictionary.keys() and Dictionary.values() are both ways to access lists of all the keys or values of the Dictionary.

If you want to iterate through all the keys in a dictionary, you can do so using a for loop as follows.

for key in dictionary.keys():
  print(key, dictionary[key]) #Prints every key, value pair

If you need any further assistance, please feel free to reach out.

Regards,

1 Like

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.