Custom Dialogue System - How to access layered arrays or dictionary incrementally

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

I am developing a visual novel type game and I’m having trouble understanding how to create branching paths optimally or access to deeper parts of an array/dictionary. Like, for example dialogue choices within dialogue choices. See Example Below.

Example:
Do you like cake? “Yes”, “No”.
~Yes: What type of cake? “Strawberry”, “Chocolate”, “Whatever”
~Strawberry: Oh That’s nice… Yada Yada
~Chocolate: bla bla bla.
~Whatever: You get my point.
~No: Okey, [exit array]

…and so on.

Essentially, I want to go deeper into an array (or dictionary or anything) than the first layer using whatever method you got. I’m desperate.

All I want to do is access parts of a dialog tree incramentally, like, per click of the spacebar I would get each text part incramentally. I have an input with file_pos += 1 if I hit the spacebar but accessing an array or an array within an array is the problem.

var file_pos = 0
   
var example_file = [
	"Start",
	"Do You like cake?",
	[ # Yes
		"What type of cake?",
		[ # Strawberry
			"Oh That's nice... Yada Yada",
		],
		[ # Chocolate
			"bla bla bla.",
		],
		[ # Whatever
			"You get my point.",
		]
	],
	[ # No
		"Okey",	
	],
	"end"
]

Please help, any tips are welcome. Thank you.

:bust_in_silhouette: Reply From: SnapCracklins

Most dialogue systems like this use a State Machine of some sort. There is also a plugin called Dialogic that may be worth a look if you get frustrated.

What you probably want to use is a dictionary. You can nest arrays in dictionaries and reference like this. Here, I make an array for magic, print each one from front to back, and then make an array for weapons, print them from back to front, combine them into a dictionary and then use the keys to reference those values.

extends Node2D


var magic = ['fire', 'ice', 'lightning']


func _ready():
	print(magic[0])
	print(magic[1])
	print(magic[2])
	var weapons = ['sword', 'bow', 'staff']
	print(weapons[-1])
	print(weapons[-2])
	print(weapons[-3])
	var inventory = {'magic': magic, 'weapons': weapons}
	var icanHas = inventory.magic[2] + "\n" + inventory.weapons[-1]
	print(icanHas)

so you probably want to implement a state machine with an enum. something like:

enum State = {NOT_STARTED, STARTED, QUEST_COMPLETED}

var currentState = State.NOT_STARTED

func _process(delta):
	match currentState:
		State.READY:
			your first dialogue here, before quests start
		State.READING:
			your next...
		State.FINISHED:
			the last dialogue.

Then you can just assign whatever dialogue using the index of the dictionary and change the state to change the dialogue. This is hard coding to be sure, but I have seen some on here who are able to match up the constants of their enum with the keys of their dictionaries, which really isn’t much work besides making a consistent data and naming structure.