NPC Dialogues, anyone know cleaner methods?

Does anyone know an organized method of making a dialogue system? All I can think of is something along the lines of this:

local NPCs = {
	["Tom"] = {
		Dialogues = {
			OpeningDialogue = {
				Message = "How are you doing?";
				Answers = {"Good", "Fine", "Bad"}; -- If good then tom says great, if fine then tom says okay
			},
			Answers = {
				["Good"] = {
					Message = "Nice to know you are doing good.";
					Answers = {"Thanks"};
				};
				["Fine"] = {
					Message = "Oh, i'm doing fine too.";
					Answers = {"Awesome"};
				};
				["Awesome"] = {
					Message = "I know right?"
				};
				["Thanks"] = {
					Message = "You're welcome!"
				};
			}
		}
	}
}

The way I’d do this is any string in the answers table that doesn’t have ‘Answers’ inside of them would just be a dialogue that prompts you to end the interaction after the text displays.

1 Like

Your approach will quickly become unmanageable as the number of messages in a conversation grows, because the tables become very deeply nested which is hard to read/understand, and even hard to see because of indentation. It’s also limited because you can’t have cycles in the dialogue tree, or branches that combine (two different choices can never lead to the same response).

You could come up with different schemes, but IMO you’ll end up with something that’s annoying and error-prone to edit no matter what. I’d use a dialogue editor instead, only trouble is finding one that exports to Lua. Here’s a reddit thread with a bunch of suggestions: Reddit - Dive into anything

I haven’t used it, but Yarn seems to be quite good: GitHub - YarnSpinnerTool/YarnEditor: Forwarding repository for @blurymind/YarnClassic

If you don’t want to deal with external tools, I’d use a structure like this:

local Messages = {
    --Tom
    [1] = {
        Text = "How are you doing?",
        Answers = {2, 3, 4},
    },
    [5] = {
        Text = "Nice to know you're doing good",
        Answers = {8},
    },
    [6] = {
        Text = "Oh, I'm doing fine too",
    },
    [7] = {
        Text = "I know right?!",
    },
    --Player, speaking with Tom
    [2] = {
        Text = "Good",
        Answers = {5},
    },
    [3] = {
        Text = "Fine",
        Answers = {6},
    },
    [4] = {
        Text = "Awesome",
        Answers = {7},
    },
    [8] = {
        Text = "Thanks",
    }
}

Using descriptive IDs rather than just numbers quickly becomes very hard, and slows down the editing process. Explicitly giving each message a numeric ID rather than just using their order in the table means you can move things around (you can probably see that’s exactly what I did). You’re not limited to using only numbers either, you can choose strings for a select few options you want to describe, and numbers for the rest.

1 Like

Sounds neat, is it really that much more organized though since it’s numbers? Strings are a bit easier to figure out what’s going on when you get back into studio and take a look at things. Texts are good for labeling things to make sure you don’t lose track of where you left off.